Skip to content

Latest commit

 

History

History
61 lines (42 loc) · 5.2 KB

LDM-2024-07-15.md

File metadata and controls

61 lines (42 loc) · 5.2 KB

C# Language Design Meeting for July 15th, 2024

Agenda

Quote of the Day

  • "Obviously what the data means is that after we make field a keyword, usage of it as the name of a field will skyrocket, because that's what correlation means, right?"

Discussion

field keyword

Champion issue: #140
Specification: https://github.com/dotnet/csharplang/blob/e44ebf7095e462ef5f9bbd869386a70cbd85e6d0/proposals/field-keyword.md#syntax-locations-for-keywords
Usage data

We started today by looking at real world usage data for field and value as keywords, to allow us to evaluate how breaking of a change we are looking at. Our current strategy, making both field and value keywords within property accessors, even when used as a nested expression, turns out to be extremely breaking. Internal repos show hundreds of errors, with more waiting further in the build process; the errors stopped the build in root projects, which would have to be fixed up to then allow the build to progress further. Surprisingly (to the LDM, at least), value is actually more breaking than field is, and by a pretty big order of magnitude: our analyses find that, across various sources, value is used in a way that would break with this proposal 8-12 times more than field is. We're pretty concerned by the level of break here, even with fixers, for a couple of reasons:

  • A decent amount of the break was in generated (either through a separate tool or through a Roslyn source generator) code. Even with a fixer, that generated code would likely just be overwritten the next time the generator runs.
  • Our original supposition that, because value already has special meaning in property bodies it would be fairly simple to unify with field, turns out to be completely false.

Given these issues, we have a few proposals on how to deal with this, scaling back the break to have less of an impact:

  1. Accept the break, exactly as shown.
  2. Scale back the keyword recognition to only consider primary_expressions. For value, this fixes a lot of the errors; in Roslyn at least, it only results in a single build error, where value was used in a lambda inside the getter body.
  3. 2, but separate out value entirely, and leave it alone. Just make the breaking change for field, and only in the primary_expression scenario.

To tackle this question, we started by looking at the two separate parts: should we scope the break down, and should we remove any breaks on value? Our first pass here was maximally breaking, as we wanted to see how bad the reality actually would be. It turns out to be unacceptably breaking, so we are in strong agreement to scope down the break to just primary_expressions. Next, we took a second look at value. While scoping down the break would eliminate a very large percentage of the real-world breaks that we see here, it wouldn't eliminate them; Roslyn itself would break, just as the very first example. Our breaking change philosophy was that any breaking changes need to be well-motivated, and looking at the actual data in comparison to our original suppositions, we now think that we don't have enough motivation to take a change to value. Even though changing value would make it more consistent with field, we don't think we have enough justification to make it worth it. Therefore, we go with option 3.

Conclusion

field will only be recognized as a keyword when used as a primary_expression within an accessor body. Any changes to value will be removed from this proposal and its behavior will continue unaffected.

First-Class Spans Open Question

Champion issue: #7905
Specification: https://github.com/dotnet/csharplang/blob/4578db732a7d4aece52a07d1c822846b381f40b2/proposals/first-class-span-types.md#delegate-extension-receiver-break

Finally today, we took a look at a potential breaking change that could be caused first-class spans, and the proposed mitigation for it. This is a somewhat complicated case: the main issue is that because method group resolution of an extension method called in extension form can actually apply a conversion to the receiver, that conversion could potentially be something that can't be boxed. This isn't really a problem today, because the only conversions allowed here are identity, reference, or boxing conversions; these are all things that are already on the heap, so capturing the receiver into the method closure is perfectly fine. Spans, though, cannot be captured into the method group closure, so if there is ever a method group converted to a delegate type, and it uses a span conversion on the receiver, that will be an error. Since these conversions can be prioritized, it means that currently valid code will become an error, particularly as the BCL adds new Span-taking overloads. Given the 100% error rate of the scenario, we are fine with adding a special rule to exclude Span conversions when doing method group overload resolution on an extension method called in extension form.

Conclusion

Mitigation is approved.