-
Notifications
You must be signed in to change notification settings - Fork 4.2k
Open
Labels
Milestone
Description
class Program
{
static void Main()
{
System.Console.Write(Test2(new C()));
}
static bool Test2(C u)
{
return u is var (_ , (i, _)) && (int)i == 10;
}
static void Test3(C c, int i)
{
var (a, b) = c;
var (u, v) = i;
}
}
public struct C
{
}
static class Extensions
{
public static void Deconstruct(this object o, out int x, out int y)
{
x = 10;
y = 2;
}
}
PEVerify output:
Microsoft (R) .NET Framework PE Verifier. Version 4.0.30319.0
Copyright (c) Microsoft Corporation. All rights reserved.
[IL]: Error: [Program::Test2][offset 0x00000006][found value 'C'][expected ref 'System.Object'] Unexpected type on the stack.
[IL]: Error: [Program::Test2][offset 0x00000011][found Int32][expected ref 'System.Object'] Unexpected type on the stack.
2 Error(s)
Here is IL for Test2 (note value type receivers for Deconstruct aren't boxed):
.method private hidebysig static bool Test2(valuetype C u) cil managed
{
// Code size 35 (0x23)
.maxstack 3
.locals init (int32 V_0,
int32 V_1,
int32 V_2,
int32 V_3,
bool V_4)
IL_0000: nop
IL_0001: ldarg.0
IL_0002: ldloca.s V_1
IL_0004: ldloca.s V_2
IL_0006: call void Extensions::Deconstruct(object,
int32&,
int32&)
IL_000b: nop
IL_000c: ldloc.2
IL_000d: ldloca.s V_0
IL_000f: ldloca.s V_3
IL_0011: call void Extensions::Deconstruct(object,
int32&,
int32&)
IL_0016: nop
IL_0017: ldloc.0
IL_0018: ldc.i4.s 10
IL_001a: ceq
IL_001c: stloc.s V_4
IL_001e: br.s IL_0020
IL_0020: ldloc.s V_4
IL_0022: ret
} // end of method Program::Test2
It looks like regular Deconstruction emits correct IL (i.e. with boxing for value type receivers):
.method private hidebysig static void Test3(valuetype C c,
int32 i) cil managed
{
// Code size 46 (0x2e)
.maxstack 3
.locals init (int32 V_0,
int32 V_1,
int32 V_2,
int32 V_3,
int32 V_4,
int32 V_5)
IL_0000: nop
IL_0001: ldarg.0
IL_0002: box C
IL_0007: ldloca.s V_4
IL_0009: ldloca.s V_5
IL_000b: call void Extensions::Deconstruct(object,
int32&,
int32&)
IL_0010: nop
IL_0011: ldloc.s V_4
IL_0013: stloc.0
IL_0014: ldloc.s V_5
IL_0016: stloc.1
IL_0017: ldarg.1
IL_0018: box [mscorlib]System.Int32
IL_001d: ldloca.s V_5
IL_001f: ldloca.s V_4
IL_0021: call void Extensions::Deconstruct(object,
int32&,
int32&)
IL_0026: nop
IL_0027: ldloc.s V_5
IL_0029: stloc.2
IL_002a: ldloc.s V_4
IL_002c: stloc.3
IL_002d: ret
} // end of method Program::Test3
Should also check other scenarios where pattern matching can use extension methods/properties.