C# compiles enums in lambda expressions differently; consequence of overload resolution improvements? #3292

Closed
RonNewcomb opened this Issue Jun 3, 2015 · 3 comments

Projects

None yet

4 participants

@RonNewcomb

While trying out the Visual Studio 2015 RC, I received a run-time error on previously working code. Given the lambda (x => x.CustomerStatusID == CustomerStatuses.Active) which was passed to a function as an Expression<>, the debugger shows a difference in the expression tree. Formerly it compiled as this:

.Lambda #Lambda1<System.Func`2[Services.DataClasses.CustomerDC,System.Boolean]>(Services.DataClasses.CustomerDC $x)
{
(System.Int32)$x.CustomerStatusID == 0
}
But in C# 6.0 it now compiles as

.Lambda #Lambda1<System.Func`2[Services.DataClasses.CustomerDC,System.Boolean]>(Services.DataClasses.CustomerDC $x)
{
(System.Int32)$x.CustomerStatusID == (System.Int32).Constant<Services.DataClasses.CustomerStatuses>(Active)
}
Although the fix to my tree-traversing code was straightforward and the additional detail is appreciated, does anyone know of any other gotchas floating around like this?

Alternately, does anyone have a link to information on the specifics of how overload resolution was improved? I cannot find any.

@gafter gafter added this to the Unknown milestone Jun 4, 2015
@JoshVarty
Member
@gafter
Member
gafter commented Jun 23, 2015

This has nothing to do with overload resolution. The previous compiler prematurely optimized the right-hand-side of the comparison, thereby omitting the code corresponding to the source expression.

@gafter
Member
gafter commented Aug 13, 2015

@VSadov I think you were looking at this issue?

@gafter gafter modified the milestone: 1.1, Unknown Aug 13, 2015
@VSadov VSadov was assigned by gafter Aug 13, 2015
@VSadov VSadov added the 3 - Working label Aug 14, 2015
@VSadov VSadov added a commit to VSadov/roslyn that referenced this issue Aug 15, 2015
@VSadov VSadov Make expression trees involving enum literals to look like produced b…
…y native compiler

Native compiler exposes results of constant folding in the expression trees.
In particular, conversion from an enum literal to an underlying type is fairly consistently folded by the native compiler as it can be observed in the expression trees.

Roslyn, on the other hand, was not very consistent here.
Some cases like explicitly converted literals were folded - Ex:  IntTakingMethod((int)E1.a)
Other cases like implicit conversions to underlying type introduced in the processs of type promotion in binary expressions were not.

This fixes known differences in this behavior.

Fixes #4085
Fixes #3292
5a2d963
@VSadov VSadov added a commit to VSadov/roslyn that referenced this issue Aug 15, 2015
@VSadov VSadov Make expression trees involving enum literals to look like produced b…
…y native compiler

Native compiler exposes results of constant folding in the expression trees.
In particular, conversion from an enum literal to an underlying type is fairly consistently folded by the native compiler as it can be observed in the expression trees.

Roslyn, on the other hand, was not very consistent here.
Some cases like explicitly converted literals were folded - Ex:  IntTakingMethod((int)E1.a)
Other cases like implicit conversions to underlying type introduced in the processs of type promotion in binary expressions were not.

This fixes known differences in this behavior.

Fixes #4085
Fixes #3292
75befe7
@VSadov VSadov closed this in #4574 Aug 15, 2015
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment