4.5 KiB
C# Language Design Meeting for September 18th, 2019
Agenda
Triage:
-
Proposals with complete designs:
- https://github.com/dotnet/csharplang/issues/1888 Champion "Permit attributes on local functions"
- https://github.com/dotnet/csharplang/issues/100 Champion "Target-typed new expression"
-
Target typing and best-common-type features:
- https://github.com/dotnet/csharplang/issues/2473 Proposal: Target typed null coalescing (??) expression
- https://github.com/dotnet/csharplang/issues/2460 Champion: target-typed conditional expression
- https://github.com/dotnet/csharplang/issues/881 Permit ternary operation with int? and double operands
- https://github.com/dotnet/csharplang/issues/33 Champion "Nullable-enhanced common type"
Discussion
Attributes on local functions
Issue #1888
The only major concern about the feature is whether or not the attributes are guaranteed to be emitted to the lowered method, assuming there is a lowered method. For all current lowering strategies, there is a specific place to put the attributes. The proposal is that we always emit attributes for our current scenarios, but don't guarantee in the language that all attributes will survive rewriting.
There is one exception to the above, which is static local functions. Static local functions are specified to always emit a static method with the same signature as the local function (although there are bugs about this today). Attributes on static local function would have a similar guarantee, meaning that they are always emitted to the lowered methods, on the exact same parameters they were applied to.
Conclusion
Proposal accepted, attributes will be allowed on local functions. extern
will also be allowed on
static local functions, and will be a valid P/Invoke target.
Target-typed new
Issue #100
We like the feature and already have a design. However, we want to do a quick review that we still like the design, taking into account all the changes we've made to the language since it was proposed.
Conclusion
Accepted, pending review.
Target-typed conditional expression and nullable-enhanced common type
Issue #2460 and issue #33
The main problem is that providing a target-typing for the switch expression may have made issue #33 a breaking change. In general, additional target-typing (on top of a natural type) works by calculating the target type if there is no viable natural type. By allowing more natural types, it reduces the ability to use target-typing, which may allow more resulting types than the natural type inference.
Overload resolution is a good example. If you have two methods
void M(int? x) { ... }
void M(short? y) { ... }
and a call M(e switch { ... => 1, ... => null })
, when we do overload resolution
we consider the target type for the switch
, which consists of the target type
for each of the candidates. For target type, short
is a better target for int
.
If we improved the natural type, then the natural type of 1
would be int
. Then,
if we improve the natural type of e switch { ... => 1, ... => null}
to be int?
,
then a different overload (M(int? x)
) will be chosen.
There's also a pretty clear trade-off here. Target-typing may allow more viable
types, but it falls over in the presence of type inference or if the target is
so broad as to be useless (like if the target-type is object
).
Additionally, the proposal for target-typing the conditional expression (?:
) will have
different semantics from the target-typing for the switch expression, to avoid a breaking change.
It may be desirable to unify the behavior of things like ?:
and switch expression, even if that
means that the switch expression would be more limited, due to the backwards compatibility
constraints of ?:
.
Conclusion
Let's do some work to see if we can alter the interaction of target-typing and common type inference to add the proposed new common types without introducing breaking changes with target-typing. The hope is that such a rule could be general enough to apply to other potential breaks in the future (in case we find more potential improvements to common type).
In addition, we would like to know the effect of changing switch expressions to prefer the common type, if one exists. We hope that any difference would be uncommon in practice, but it would be useful to know if there are common instances where this would break. This would be used to decide if we would adjust the behavior of the switch expression to match the proposed behavior for the conditional expression.