Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
lwm1986
roslyn
提交
b18cb030
R
roslyn
项目概览
lwm1986
/
roslyn
与 Fork 源项目一致
从无法访问的项目Fork
通知
1
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
R
roslyn
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
未验证
提交
b18cb030
编写于
4月 17, 2020
作者:
F
Fred Silberberg
提交者:
GitHub
4月 17, 2020
浏览文件
操作
浏览文件
下载
差异文件
Merge pull request #42807 from YairHalberstadt/fix-ltr-semantics-async
上级
0c847a1c
f5bc26dc
变更
6
隐藏空白更改
内联
并排
Showing
6 changed file
with
4861 addition
and
187 deletion
+4861
-187
src/Compilers/CSharp/Portable/Lowering/SpillSequenceSpiller.cs
...ompilers/CSharp/Portable/Lowering/SpillSequenceSpiller.cs
+50
-5
src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenAsyncSpillTests.cs
...pilers/CSharp/Test/Emit/CodeGen/CodeGenAsyncSpillTests.cs
+2432
-1
src/Compilers/VisualBasic/Portable/Lowering/AsyncRewriter/AsyncRewriter.AsyncMethodToClassRewriter.Expressions.vb
...r/AsyncRewriter.AsyncMethodToClassRewriter.Expressions.vb
+3
-3
src/Compilers/VisualBasic/Portable/Lowering/AsyncRewriter/AsyncRewriter.AsyncMethodToClassRewriter.Spilling.vb
...iter/AsyncRewriter.AsyncMethodToClassRewriter.Spilling.vb
+25
-12
src/Compilers/VisualBasic/Test/Emit/CodeGen/CodeGenAsyncTests.vb
...pilers/VisualBasic/Test/Emit/CodeGen/CodeGenAsyncTests.vb
+2268
-79
src/Compilers/VisualBasic/Test/Emit/PDB/PDBAsyncTests.vb
src/Compilers/VisualBasic/Test/Emit/PDB/PDBAsyncTests.vb
+83
-87
未找到文件。
src/Compilers/CSharp/Portable/Lowering/SpillSequenceSpiller.cs
浏览文件 @
b18cb030
...
...
@@ -677,17 +677,15 @@ public override BoundNode VisitAssignmentOperator(BoundAssignmentOperator node)
if
(
field
.
FieldSymbol
.
IsStatic
)
break
;
// instance fields are directly assignable, but receiver is pushed, so need to spill that.
var
receiver
=
VisitExpression
(
ref
leftBuilder
,
field
.
ReceiverOpt
);
receiver
=
Spill
(
builder
,
receiver
,
field
.
FieldSymbol
.
ContainingType
.
IsValueType
?
RefKind
.
Ref
:
RefKind
.
None
);
left
=
field
.
Update
(
receiver
,
field
.
FieldSymbol
,
field
.
ConstantValueOpt
,
field
.
ResultKind
,
field
.
Type
);
left
=
fieldWithSpilledReceiver
(
field
,
ref
leftBuilder
,
isAssignmentTarget
:
true
);
break
;
case
BoundKind
.
ArrayAccess
:
var
arrayAccess
=
(
BoundArrayAccess
)
left
;
// array and indices are pushed on stack so need to spill that
var
expression
=
VisitExpression
(
ref
leftBuilder
,
arrayAccess
.
Expression
);
expression
=
Spill
(
b
uilder
,
expression
,
RefKind
.
None
);
var
indices
=
this
.
VisitExpressionList
(
ref
b
uilder
,
arrayAccess
.
Indices
,
forceSpill
:
true
);
expression
=
Spill
(
leftB
uilder
,
expression
,
RefKind
.
None
);
var
indices
=
this
.
VisitExpressionList
(
ref
leftB
uilder
,
arrayAccess
.
Indices
,
forceSpill
:
true
);
left
=
arrayAccess
.
Update
(
expression
,
indices
,
arrayAccess
.
Type
);
break
;
...
...
@@ -710,6 +708,53 @@ public override BoundNode VisitAssignmentOperator(BoundAssignmentOperator node)
}
return
UpdateExpression
(
builder
,
node
.
Update
(
left
,
right
,
node
.
IsRef
,
node
.
Type
));
BoundExpression
fieldWithSpilledReceiver
(
BoundFieldAccess
field
,
ref
BoundSpillSequenceBuilder
leftBuilder
,
bool
isAssignmentTarget
)
{
BoundExpression
receiver
;
var
generateDummyFieldAccess
=
false
;
if
(
field
.
FieldSymbol
.
ContainingType
.
IsReferenceType
)
{
// a reference type can always live across await so Spill using leftBuilder
receiver
=
Spill
(
leftBuilder
,
VisitExpression
(
ref
leftBuilder
,
field
.
ReceiverOpt
));
// dummy field access to trigger NRE
// a.b = c will trigger a NRE if a is null on assignment,
// but a.b.c = d will trigger a NRE if a is null before evaluating d
// so check whether we assign to the field directly
generateDummyFieldAccess
=
!
isAssignmentTarget
;
}
else
if
(
field
.
ReceiverOpt
is
BoundArrayAccess
arrayAccess
)
{
// an arrayAccess returns a ref so can only be called after the await, but spill expression and indices
var
expression
=
VisitExpression
(
ref
leftBuilder
,
arrayAccess
.
Expression
);
expression
=
Spill
(
leftBuilder
,
expression
,
RefKind
.
None
);
var
indices
=
this
.
VisitExpressionList
(
ref
leftBuilder
,
arrayAccess
.
Indices
,
forceSpill
:
true
);
receiver
=
arrayAccess
.
Update
(
expression
,
indices
,
arrayAccess
.
Type
);
// dummy array access to trigger IndexOutRangeException or NRE
// we only need this if the array access is a receiver since
// a[0] = b triggers a NRE/IORE on assignment
// but a[0].b = c triggers an NRE/IORE before evaluating c
Spill
(
leftBuilder
,
receiver
,
sideEffectsOnly
:
true
);
}
else
if
(
field
.
ReceiverOpt
is
BoundFieldAccess
receiverField
)
{
receiver
=
fieldWithSpilledReceiver
(
receiverField
,
ref
leftBuilder
,
isAssignmentTarget
:
false
);
}
else
{
receiver
=
Spill
(
leftBuilder
,
VisitExpression
(
ref
leftBuilder
,
field
.
ReceiverOpt
),
RefKind
.
Ref
);
}
field
=
field
.
Update
(
receiver
,
field
.
FieldSymbol
,
field
.
ConstantValueOpt
,
field
.
ResultKind
,
field
.
Type
);
if
(
generateDummyFieldAccess
)
{
Spill
(
leftBuilder
,
field
,
sideEffectsOnly
:
true
);
}
return
field
;
}
}
public
override
BoundNode
VisitBadExpression
(
BoundBadExpression
node
)
...
...
src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenAsyncSpillTests.cs
浏览文件 @
b18cb030
...
...
@@ -5,7 +5,6 @@
using
System
;
using
System.Collections.Generic
;
using
System.Linq
;
using
System.Threading.Tasks
;
using
Microsoft.CodeAnalysis.CSharp.Test.Utilities
;
using
Microsoft.CodeAnalysis.Test.Utilities
;
using
Roslyn.Test.Utilities
;
...
...
@@ -3888,5 +3887,2437 @@ class AltBoolean
CompileAndVerify
(
source
,
expectedOutput
:
"True"
,
options
:
TestOptions
.
DebugExe
);
CompileAndVerify
(
source
,
expectedOutput
:
"True"
,
options
:
TestOptions
.
ReleaseExe
);
}
[
Fact
]
[
WorkItem
(
42755
,
"https://github.com/dotnet/roslyn/issues/42755"
)]
public
void
KeepLtrSemantics_ClassFieldAccessOnProperty
()
{
var
source
=
@"
using System;
using System.Threading.Tasks;
class Program
{
static async Task Assign(A a)
{
a.B.x = await Write(""RHS"");
}
static async Task Main(string[] args)
{
await TestPropertyAccessThrows();
await TestFieldAccessThrows();
await TestPropertyAccessSucceeds();
}
static async Task TestPropertyAccessThrows()
{
Console.WriteLine(nameof(TestPropertyAccessThrows));
A a = null;
Console.WriteLine(""Before Assignment"");
try
{
await Assign(a);
}
catch (NullReferenceException)
{
Console.WriteLine(""Caught NullReferenceException"");
}
}
static async Task TestFieldAccessThrows()
{
Console.WriteLine(nameof(TestFieldAccessThrows));
var a = new A();
Console.WriteLine(""Before Assignment"");
try
{
await Assign(a);
}
catch (NullReferenceException)
{
Console.WriteLine(""Caught NullReferenceException"");
}
}
static async Task TestPropertyAccessSucceeds()
{
Console.WriteLine(nameof(TestPropertyAccessSucceeds));
var a = new A{ B = new B() };
Console.WriteLine(""Before Assignment a.B.x is: "" + a.B.x);
await Assign(a);
Console.WriteLine(""After Assignment a.B.x is: "" + a.B.x);
}
static async Task<int> Write(string s)
{
await Task.Yield();
Console.WriteLine(s);
return 42;
}
}
class A
{
public B B { get; set; }
}
class B
{
public int x;
}"
;
var
comp
=
CreateCompilation
(
source
,
options
:
TestOptions
.
ReleaseExe
);
CompileAndVerify
(
comp
,
expectedOutput
:
@"TestPropertyAccessThrows
Before Assignment
Caught NullReferenceException
TestFieldAccessThrows
Before Assignment
RHS
Caught NullReferenceException
TestPropertyAccessSucceeds
Before Assignment a.B.x is: 0
RHS
After Assignment a.B.x is: 42"
)
.
VerifyIL
(
"Program.<Assign>d__0.System.Runtime.CompilerServices.IAsyncStateMachine.MoveNext"
,
@"
{
// Code size 184 (0xb8)
.maxstack 3
.locals init (int V_0,
int V_1,
System.Runtime.CompilerServices.TaskAwaiter<int> V_2,
System.Exception V_3)
IL_0000: ldarg.0
IL_0001: ldfld ""int Program.<Assign>d__0.<>1__state""
IL_0006: stloc.0
.try
{
IL_0007: ldloc.0
IL_0008: brfalse.s IL_0054
IL_000a: ldarg.0
IL_000b: ldarg.0
IL_000c: ldfld ""A Program.<Assign>d__0.a""
IL_0011: callvirt ""B A.B.get""
IL_0016: stfld ""B Program.<Assign>d__0.<>7__wrap1""
IL_001b: ldstr ""RHS""
IL_0020: call ""System.Threading.Tasks.Task<int> Program.Write(string)""
IL_0025: callvirt ""System.Runtime.CompilerServices.TaskAwaiter<int> System.Threading.Tasks.Task<int>.GetAwaiter()""
IL_002a: stloc.2
IL_002b: ldloca.s V_2
IL_002d: call ""bool System.Runtime.CompilerServices.TaskAwaiter<int>.IsCompleted.get""
IL_0032: brtrue.s IL_0070
IL_0034: ldarg.0
IL_0035: ldc.i4.0
IL_0036: dup
IL_0037: stloc.0
IL_0038: stfld ""int Program.<Assign>d__0.<>1__state""
IL_003d: ldarg.0
IL_003e: ldloc.2
IL_003f: stfld ""System.Runtime.CompilerServices.TaskAwaiter<int> Program.<Assign>d__0.<>u__1""
IL_0044: ldarg.0
IL_0045: ldflda ""System.Runtime.CompilerServices.AsyncTaskMethodBuilder Program.<Assign>d__0.<>t__builder""
IL_004a: ldloca.s V_2
IL_004c: ldarg.0
IL_004d: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.AwaitUnsafeOnCompleted<System.Runtime.CompilerServices.TaskAwaiter<int>, Program.<Assign>d__0>(ref System.Runtime.CompilerServices.TaskAwaiter<int>, ref Program.<Assign>d__0)""
IL_0052: leave.s IL_00b7
IL_0054: ldarg.0
IL_0055: ldfld ""System.Runtime.CompilerServices.TaskAwaiter<int> Program.<Assign>d__0.<>u__1""
IL_005a: stloc.2
IL_005b: ldarg.0
IL_005c: ldflda ""System.Runtime.CompilerServices.TaskAwaiter<int> Program.<Assign>d__0.<>u__1""
IL_0061: initobj ""System.Runtime.CompilerServices.TaskAwaiter<int>""
IL_0067: ldarg.0
IL_0068: ldc.i4.m1
IL_0069: dup
IL_006a: stloc.0
IL_006b: stfld ""int Program.<Assign>d__0.<>1__state""
IL_0070: ldloca.s V_2
IL_0072: call ""int System.Runtime.CompilerServices.TaskAwaiter<int>.GetResult()""
IL_0077: stloc.1
IL_0078: ldarg.0
IL_0079: ldfld ""B Program.<Assign>d__0.<>7__wrap1""
IL_007e: ldloc.1
IL_007f: stfld ""int B.x""
IL_0084: ldarg.0
IL_0085: ldnull
IL_0086: stfld ""B Program.<Assign>d__0.<>7__wrap1""
IL_008b: leave.s IL_00a4
}
catch System.Exception
{
IL_008d: stloc.3
IL_008e: ldarg.0
IL_008f: ldc.i4.s -2
IL_0091: stfld ""int Program.<Assign>d__0.<>1__state""
IL_0096: ldarg.0
IL_0097: ldflda ""System.Runtime.CompilerServices.AsyncTaskMethodBuilder Program.<Assign>d__0.<>t__builder""
IL_009c: ldloc.3
IL_009d: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.SetException(System.Exception)""
IL_00a2: leave.s IL_00b7
}
IL_00a4: ldarg.0
IL_00a5: ldc.i4.s -2
IL_00a7: stfld ""int Program.<Assign>d__0.<>1__state""
IL_00ac: ldarg.0
IL_00ad: ldflda ""System.Runtime.CompilerServices.AsyncTaskMethodBuilder Program.<Assign>d__0.<>t__builder""
IL_00b2: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.SetResult()""
IL_00b7: ret
}"
);
}
[
Fact
]
[
WorkItem
(
42755
,
"https://github.com/dotnet/roslyn/issues/42755"
)]
public
void
KeepLtrSemantics_ClassFieldAccessOnArray
()
{
var
source
=
@"
using System;
using System.Threading.Tasks;
class Program
{
static async Task Assign(A[] arr)
{
arr[0].x = await Write(""RHS"");
}
static async Task Main(string[] args)
{
await TestIndexerThrows();
await TestAssignmentThrows();
await TestIndexerSucceeds();
await TestReassignsArrayAndIndexerDuringAwait();
await TestReassignsTargetDuringAwait();
}
static async Task TestIndexerThrows()
{
Console.WriteLine(nameof(TestIndexerThrows));
var arr = new A[0];
Console.WriteLine(""Before Assignment"");
try
{
await Assign(arr);
}
catch (IndexOutOfRangeException)
{
Console.WriteLine(""Caught IndexOutOfRangeException"");
}
}
static async Task TestAssignmentThrows()
{
Console.WriteLine(nameof(TestAssignmentThrows));
var arr = new A[1];
Console.WriteLine(""Before Assignment"");
try
{
await Assign(arr);
}
catch (NullReferenceException)
{
Console.WriteLine(""Caught NullReferenceException"");
}
}
static async Task TestIndexerSucceeds()
{
Console.WriteLine(nameof(TestIndexerSucceeds));
var arr = new A[1]{ new A() };
Console.WriteLine(""Before Assignment arr[0].x is: "" + arr[0].x);
await Assign(arr);
Console.WriteLine(""After Assignment arr[0].x is: "" + arr[0].x);
}
static async Task TestReassignsArrayAndIndexerDuringAwait()
{
Console.WriteLine(nameof(TestReassignsArrayAndIndexerDuringAwait));
var a = new A();
var arr = new A[1]{ a };
var index = 0;
Console.WriteLine(""Before Assignment arr.Length is: "" + arr.Length);
Console.WriteLine(""Before Assignment a.x is: "" + a.x);
arr[index].x = await WriteAndReassign(""RHS"");
Console.WriteLine(""After Assignment arr.Length is: "" + arr.Length);
Console.WriteLine(""After Assignment a.x is: "" + a.x);
async Task<int> WriteAndReassign(string s)
{
await Task.Yield();
arr = new A[0];
index = 1;
Console.WriteLine(s);
return 42;
}
}
static async Task TestReassignsTargetDuringAwait()
{
Console.WriteLine(nameof(TestReassignsTargetDuringAwait));
var a = new A();
var arr = new A[1]{ a };
Console.WriteLine(""Before Assignment arr[0].x is: "" + arr[0].x);
Console.WriteLine(""Before Assignment arr[0].y is: "" + arr[0].y);
Console.WriteLine(""Before Assignment a.x is: "" + a.x);
arr[0].x = await WriteAndReassign(""RHS"");
Console.WriteLine(""After Assignment arr[0].x is: "" + arr[0].x);
Console.WriteLine(""After Assignment arr[0].y is: "" + arr[0].y);
Console.WriteLine(""After Assignment a.x is: "" + a.x);
async Task<int> WriteAndReassign(string s)
{
await Task.Yield();
arr[0] = new A{ y = true };
Console.WriteLine(s);
return 42;
}
}
static async Task<int> Write(string s)
{
await Task.Yield();
Console.WriteLine(s);
return 42;
}
}
class A
{
public int x;
public bool y;
}"
;
var
comp
=
CreateCompilation
(
source
,
options
:
TestOptions
.
ReleaseExe
);
CompileAndVerify
(
comp
,
expectedOutput
:
@"TestIndexerThrows
Before Assignment
Caught IndexOutOfRangeException
TestAssignmentThrows
Before Assignment
RHS
Caught NullReferenceException
TestIndexerSucceeds
Before Assignment arr[0].x is: 0
RHS
After Assignment arr[0].x is: 42
TestReassignsArrayAndIndexerDuringAwait
Before Assignment arr.Length is: 1
Before Assignment a.x is: 0
RHS
After Assignment arr.Length is: 0
After Assignment a.x is: 42
TestReassignsTargetDuringAwait
Before Assignment arr[0].x is: 0
Before Assignment arr[0].y is: False
Before Assignment a.x is: 0
RHS
After Assignment arr[0].x is: 0
After Assignment arr[0].y is: True
After Assignment a.x is: 42"
)
.
VerifyIL
(
"Program.<Assign>d__0.System.Runtime.CompilerServices.IAsyncStateMachine.MoveNext"
,
@"
{
// Code size 181 (0xb5)
.maxstack 3
.locals init (int V_0,
int V_1,
System.Runtime.CompilerServices.TaskAwaiter<int> V_2,
System.Exception V_3)
IL_0000: ldarg.0
IL_0001: ldfld ""int Program.<Assign>d__0.<>1__state""
IL_0006: stloc.0
.try
{
IL_0007: ldloc.0
IL_0008: brfalse.s IL_0051
IL_000a: ldarg.0
IL_000b: ldarg.0
IL_000c: ldfld ""A[] Program.<Assign>d__0.arr""
IL_0011: ldc.i4.0
IL_0012: ldelem.ref
IL_0013: stfld ""A Program.<Assign>d__0.<>7__wrap1""
IL_0018: ldstr ""RHS""
IL_001d: call ""System.Threading.Tasks.Task<int> Program.Write(string)""
IL_0022: callvirt ""System.Runtime.CompilerServices.TaskAwaiter<int> System.Threading.Tasks.Task<int>.GetAwaiter()""
IL_0027: stloc.2
IL_0028: ldloca.s V_2
IL_002a: call ""bool System.Runtime.CompilerServices.TaskAwaiter<int>.IsCompleted.get""
IL_002f: brtrue.s IL_006d
IL_0031: ldarg.0
IL_0032: ldc.i4.0
IL_0033: dup
IL_0034: stloc.0
IL_0035: stfld ""int Program.<Assign>d__0.<>1__state""
IL_003a: ldarg.0
IL_003b: ldloc.2
IL_003c: stfld ""System.Runtime.CompilerServices.TaskAwaiter<int> Program.<Assign>d__0.<>u__1""
IL_0041: ldarg.0
IL_0042: ldflda ""System.Runtime.CompilerServices.AsyncTaskMethodBuilder Program.<Assign>d__0.<>t__builder""
IL_0047: ldloca.s V_2
IL_0049: ldarg.0
IL_004a: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.AwaitUnsafeOnCompleted<System.Runtime.CompilerServices.TaskAwaiter<int>, Program.<Assign>d__0>(ref System.Runtime.CompilerServices.TaskAwaiter<int>, ref Program.<Assign>d__0)""
IL_004f: leave.s IL_00b4
IL_0051: ldarg.0
IL_0052: ldfld ""System.Runtime.CompilerServices.TaskAwaiter<int> Program.<Assign>d__0.<>u__1""
IL_0057: stloc.2
IL_0058: ldarg.0
IL_0059: ldflda ""System.Runtime.CompilerServices.TaskAwaiter<int> Program.<Assign>d__0.<>u__1""
IL_005e: initobj ""System.Runtime.CompilerServices.TaskAwaiter<int>""
IL_0064: ldarg.0
IL_0065: ldc.i4.m1
IL_0066: dup
IL_0067: stloc.0
IL_0068: stfld ""int Program.<Assign>d__0.<>1__state""
IL_006d: ldloca.s V_2
IL_006f: call ""int System.Runtime.CompilerServices.TaskAwaiter<int>.GetResult()""
IL_0074: stloc.1
IL_0075: ldarg.0
IL_0076: ldfld ""A Program.<Assign>d__0.<>7__wrap1""
IL_007b: ldloc.1
IL_007c: stfld ""int A.x""
IL_0081: ldarg.0
IL_0082: ldnull
IL_0083: stfld ""A Program.<Assign>d__0.<>7__wrap1""
IL_0088: leave.s IL_00a1
}
catch System.Exception
{
IL_008a: stloc.3
IL_008b: ldarg.0
IL_008c: ldc.i4.s -2
IL_008e: stfld ""int Program.<Assign>d__0.<>1__state""
IL_0093: ldarg.0
IL_0094: ldflda ""System.Runtime.CompilerServices.AsyncTaskMethodBuilder Program.<Assign>d__0.<>t__builder""
IL_0099: ldloc.3
IL_009a: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.SetException(System.Exception)""
IL_009f: leave.s IL_00b4
}
IL_00a1: ldarg.0
IL_00a2: ldc.i4.s -2
IL_00a4: stfld ""int Program.<Assign>d__0.<>1__state""
IL_00a9: ldarg.0
IL_00aa: ldflda ""System.Runtime.CompilerServices.AsyncTaskMethodBuilder Program.<Assign>d__0.<>t__builder""
IL_00af: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.SetResult()""
IL_00b4: ret
}"
);
}
[
Fact
]
[
WorkItem
(
42755
,
"https://github.com/dotnet/roslyn/issues/42755"
)]
public
void
KeepLtrSemantics_StructFieldAccessOnArray
()
{
var
source
=
@"
using System;
using System.Threading.Tasks;
class Program
{
static async Task Assign(A[] arr)
{
arr[0].x = await Write(""RHS"");
}
static async Task Main(string[] args)
{
await TestIndexerThrows();
await TestIndexerSucceeds();
await TestReassignsArrayAndIndexerDuringAwait();
await TestReassignsTargetDuringAwait();
}
static async Task TestIndexerThrows()
{
Console.WriteLine(nameof(TestIndexerThrows));
var arr = new A[0];
Console.WriteLine(""Before Assignment"");
try
{
await Assign(arr);
}
catch (IndexOutOfRangeException)
{
Console.WriteLine(""Caught IndexOutOfRangeException"");
}
}
static async Task TestIndexerSucceeds()
{
Console.WriteLine(nameof(TestIndexerSucceeds));
var arr = new A[1];
Console.WriteLine(""Before Assignment arr[0].x is: "" + arr[0].x);
await Assign(arr);
Console.WriteLine(""After Assignment arr[0].x is: "" + arr[0].x);
}
static async Task TestReassignsArrayAndIndexerDuringAwait()
{
Console.WriteLine(nameof(TestReassignsArrayAndIndexerDuringAwait));
var arr = new A[1];
var arrCopy = arr;
var index = 0;
Console.WriteLine(""Before Assignment arr.Length is: "" + arr.Length);
Console.WriteLine(""Before Assignment arrCopy[0].x is: "" + arrCopy[0].x);
arr[index].x = await WriteAndReassign(""RHS"");
Console.WriteLine(""After Assignment arr.Length is: "" + arr.Length);
Console.WriteLine(""After Assignment arrCopy[0].x is: "" + arrCopy[0].x);
async Task<int> WriteAndReassign(string s)
{
await Task.Yield();
arr = new A[0];
index = 1;
Console.WriteLine(s);
return 42;
}
}
static async Task TestReassignsTargetDuringAwait()
{
Console.WriteLine(nameof(TestReassignsTargetDuringAwait));
var arr = new A[1];
Console.WriteLine(""Before Assignment arr[0].x is: "" + arr[0].x);
Console.WriteLine(""Before Assignment arr[0].y is: "" + arr[0].y);
arr[0].x = await WriteAndReassign(""RHS"");
Console.WriteLine(""After Assignment arr[0].x is: "" + arr[0].x);
Console.WriteLine(""Before Assignment arr[0].y is: "" + arr[0].y);
async Task<int> WriteAndReassign(string s)
{
await Task.Yield();
arr[0] = new A{y = true };
Console.WriteLine(s);
return 42;
}
}
static async Task<int> Write(string s)
{
await Task.Yield();
Console.WriteLine(s);
return 42;
}
}
struct A
{
public int x;
public bool y;
}"
;
var
comp
=
CreateCompilation
(
source
,
options
:
TestOptions
.
ReleaseExe
);
CompileAndVerify
(
comp
,
expectedOutput
:
@"TestIndexerThrows
Before Assignment
Caught IndexOutOfRangeException
TestIndexerSucceeds
Before Assignment arr[0].x is: 0
RHS
After Assignment arr[0].x is: 42
TestReassignsArrayAndIndexerDuringAwait
Before Assignment arr.Length is: 1
Before Assignment arrCopy[0].x is: 0
RHS
After Assignment arr.Length is: 0
After Assignment arrCopy[0].x is: 42
TestReassignsTargetDuringAwait
Before Assignment arr[0].x is: 0
Before Assignment arr[0].y is: False
RHS
After Assignment arr[0].x is: 42
Before Assignment arr[0].y is: True"
)
.
VerifyIL
(
"Program.<Assign>d__0.System.Runtime.CompilerServices.IAsyncStateMachine.MoveNext"
,
@"
{
// Code size 198 (0xc6)
.maxstack 3
.locals init (int V_0,
int V_1,
System.Runtime.CompilerServices.TaskAwaiter<int> V_2,
System.Exception V_3)
IL_0000: ldarg.0
IL_0001: ldfld ""int Program.<Assign>d__0.<>1__state""
IL_0006: stloc.0
.try
{
IL_0007: ldloc.0
IL_0008: brfalse.s IL_005c
IL_000a: ldarg.0
IL_000b: ldarg.0
IL_000c: ldfld ""A[] Program.<Assign>d__0.arr""
IL_0011: stfld ""A[] Program.<Assign>d__0.<>7__wrap1""
IL_0016: ldarg.0
IL_0017: ldfld ""A[] Program.<Assign>d__0.<>7__wrap1""
IL_001c: ldc.i4.0
IL_001d: ldelema ""A""
IL_0022: pop
IL_0023: ldstr ""RHS""
IL_0028: call ""System.Threading.Tasks.Task<int> Program.Write(string)""
IL_002d: callvirt ""System.Runtime.CompilerServices.TaskAwaiter<int> System.Threading.Tasks.Task<int>.GetAwaiter()""
IL_0032: stloc.2
IL_0033: ldloca.s V_2
IL_0035: call ""bool System.Runtime.CompilerServices.TaskAwaiter<int>.IsCompleted.get""
IL_003a: brtrue.s IL_0078
IL_003c: ldarg.0
IL_003d: ldc.i4.0
IL_003e: dup
IL_003f: stloc.0
IL_0040: stfld ""int Program.<Assign>d__0.<>1__state""
IL_0045: ldarg.0
IL_0046: ldloc.2
IL_0047: stfld ""System.Runtime.CompilerServices.TaskAwaiter<int> Program.<Assign>d__0.<>u__1""
IL_004c: ldarg.0
IL_004d: ldflda ""System.Runtime.CompilerServices.AsyncTaskMethodBuilder Program.<Assign>d__0.<>t__builder""
IL_0052: ldloca.s V_2
IL_0054: ldarg.0
IL_0055: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.AwaitUnsafeOnCompleted<System.Runtime.CompilerServices.TaskAwaiter<int>, Program.<Assign>d__0>(ref System.Runtime.CompilerServices.TaskAwaiter<int>, ref Program.<Assign>d__0)""
IL_005a: leave.s IL_00c5
IL_005c: ldarg.0
IL_005d: ldfld ""System.Runtime.CompilerServices.TaskAwaiter<int> Program.<Assign>d__0.<>u__1""
IL_0062: stloc.2
IL_0063: ldarg.0
IL_0064: ldflda ""System.Runtime.CompilerServices.TaskAwaiter<int> Program.<Assign>d__0.<>u__1""
IL_0069: initobj ""System.Runtime.CompilerServices.TaskAwaiter<int>""
IL_006f: ldarg.0
IL_0070: ldc.i4.m1
IL_0071: dup
IL_0072: stloc.0
IL_0073: stfld ""int Program.<Assign>d__0.<>1__state""
IL_0078: ldloca.s V_2
IL_007a: call ""int System.Runtime.CompilerServices.TaskAwaiter<int>.GetResult()""
IL_007f: stloc.1
IL_0080: ldarg.0
IL_0081: ldfld ""A[] Program.<Assign>d__0.<>7__wrap1""
IL_0086: ldc.i4.0
IL_0087: ldelema ""A""
IL_008c: ldloc.1
IL_008d: stfld ""int A.x""
IL_0092: ldarg.0
IL_0093: ldnull
IL_0094: stfld ""A[] Program.<Assign>d__0.<>7__wrap1""
IL_0099: leave.s IL_00b2
}
catch System.Exception
{
IL_009b: stloc.3
IL_009c: ldarg.0
IL_009d: ldc.i4.s -2
IL_009f: stfld ""int Program.<Assign>d__0.<>1__state""
IL_00a4: ldarg.0
IL_00a5: ldflda ""System.Runtime.CompilerServices.AsyncTaskMethodBuilder Program.<Assign>d__0.<>t__builder""
IL_00aa: ldloc.3
IL_00ab: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.SetException(System.Exception)""
IL_00b0: leave.s IL_00c5
}
IL_00b2: ldarg.0
IL_00b3: ldc.i4.s -2
IL_00b5: stfld ""int Program.<Assign>d__0.<>1__state""
IL_00ba: ldarg.0
IL_00bb: ldflda ""System.Runtime.CompilerServices.AsyncTaskMethodBuilder Program.<Assign>d__0.<>t__builder""
IL_00c0: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.SetResult()""
IL_00c5: ret
}"
);
}
[
Fact
]
[
WorkItem
(
42755
,
"https://github.com/dotnet/roslyn/issues/42755"
)]
public
void
KeepLtrSemantics_AssignmentToArray
()
{
var
source
=
@"
using System;
using System.Threading.Tasks;
class Program
{
static async Task Assign(int[] arr)
{
arr[0] = await Write(""RHS"");
}
static async Task Main(string[] args)
{
await TestIndexerThrows();
await TestIndexerSucceeds();
await TestReassignsArrayAndIndexerDuringAwait();
}
static async Task TestIndexerThrows()
{
Console.WriteLine(nameof(TestIndexerThrows));
var arr = new int[0];
Console.WriteLine(""Before Assignment"");
try
{
await Assign(arr);
}
catch (IndexOutOfRangeException)
{
Console.WriteLine(""Caught IndexOutOfRangeException"");
}
}
static async Task TestIndexerSucceeds()
{
Console.WriteLine(nameof(TestIndexerSucceeds));
var arr = new int[1];
Console.WriteLine(""Before Assignment arr[0] is: "" + arr[0]);
await Assign(arr);
Console.WriteLine(""After Assignment arr[0] is: "" + arr[0]);
}
static async Task TestReassignsArrayAndIndexerDuringAwait()
{
Console.WriteLine(nameof(TestReassignsArrayAndIndexerDuringAwait));
var arr = new int[1];
var arrCopy = arr;
var index = 0;
Console.WriteLine(""Before Assignment arr.Length is: "" + arr.Length);
Console.WriteLine(""Before Assignment arrCopy[0] is: "" + arrCopy[0]);
arr[index] = await WriteAndReassign(""RHS"");
Console.WriteLine(""After Assignment arr.Length is: "" + arr.Length);
Console.WriteLine(""After Assignment arrCopy[0] is: "" + arrCopy[0]);
async Task<int> WriteAndReassign(string s)
{
await Task.Yield();
arr = new int[0];
index = 1;
Console.WriteLine(s);
return 42;
}
}
static async Task<int> Write(string s)
{
await Task.Yield();
Console.WriteLine(s);
return 42;
}
}"
;
var
comp
=
CreateCompilation
(
source
,
options
:
TestOptions
.
ReleaseExe
);
CompileAndVerify
(
comp
,
expectedOutput
:
@"TestIndexerThrows
Before Assignment
RHS
Caught IndexOutOfRangeException
TestIndexerSucceeds
Before Assignment arr[0] is: 0
RHS
After Assignment arr[0] is: 42
TestReassignsArrayAndIndexerDuringAwait
Before Assignment arr.Length is: 1
Before Assignment arrCopy[0] is: 0
RHS
After Assignment arr.Length is: 0
After Assignment arrCopy[0] is: 42"
)
.
VerifyIL
(
"Program.<Assign>d__0.System.Runtime.CompilerServices.IAsyncStateMachine.MoveNext"
,
@"
{
// Code size 176 (0xb0)
.maxstack 3
.locals init (int V_0,
int V_1,
System.Runtime.CompilerServices.TaskAwaiter<int> V_2,
System.Exception V_3)
IL_0000: ldarg.0
IL_0001: ldfld ""int Program.<Assign>d__0.<>1__state""
IL_0006: stloc.0
.try
{
IL_0007: ldloc.0
IL_0008: brfalse.s IL_004f
IL_000a: ldarg.0
IL_000b: ldarg.0
IL_000c: ldfld ""int[] Program.<Assign>d__0.arr""
IL_0011: stfld ""int[] Program.<Assign>d__0.<>7__wrap1""
IL_0016: ldstr ""RHS""
IL_001b: call ""System.Threading.Tasks.Task<int> Program.Write(string)""
IL_0020: callvirt ""System.Runtime.CompilerServices.TaskAwaiter<int> System.Threading.Tasks.Task<int>.GetAwaiter()""
IL_0025: stloc.2
IL_0026: ldloca.s V_2
IL_0028: call ""bool System.Runtime.CompilerServices.TaskAwaiter<int>.IsCompleted.get""
IL_002d: brtrue.s IL_006b
IL_002f: ldarg.0
IL_0030: ldc.i4.0
IL_0031: dup
IL_0032: stloc.0
IL_0033: stfld ""int Program.<Assign>d__0.<>1__state""
IL_0038: ldarg.0
IL_0039: ldloc.2
IL_003a: stfld ""System.Runtime.CompilerServices.TaskAwaiter<int> Program.<Assign>d__0.<>u__1""
IL_003f: ldarg.0
IL_0040: ldflda ""System.Runtime.CompilerServices.AsyncTaskMethodBuilder Program.<Assign>d__0.<>t__builder""
IL_0045: ldloca.s V_2
IL_0047: ldarg.0
IL_0048: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.AwaitUnsafeOnCompleted<System.Runtime.CompilerServices.TaskAwaiter<int>, Program.<Assign>d__0>(ref System.Runtime.CompilerServices.TaskAwaiter<int>, ref Program.<Assign>d__0)""
IL_004d: leave.s IL_00af
IL_004f: ldarg.0
IL_0050: ldfld ""System.Runtime.CompilerServices.TaskAwaiter<int> Program.<Assign>d__0.<>u__1""
IL_0055: stloc.2
IL_0056: ldarg.0
IL_0057: ldflda ""System.Runtime.CompilerServices.TaskAwaiter<int> Program.<Assign>d__0.<>u__1""
IL_005c: initobj ""System.Runtime.CompilerServices.TaskAwaiter<int>""
IL_0062: ldarg.0
IL_0063: ldc.i4.m1
IL_0064: dup
IL_0065: stloc.0
IL_0066: stfld ""int Program.<Assign>d__0.<>1__state""
IL_006b: ldloca.s V_2
IL_006d: call ""int System.Runtime.CompilerServices.TaskAwaiter<int>.GetResult()""
IL_0072: stloc.1
IL_0073: ldarg.0
IL_0074: ldfld ""int[] Program.<Assign>d__0.<>7__wrap1""
IL_0079: ldc.i4.0
IL_007a: ldloc.1
IL_007b: stelem.i4
IL_007c: ldarg.0
IL_007d: ldnull
IL_007e: stfld ""int[] Program.<Assign>d__0.<>7__wrap1""
IL_0083: leave.s IL_009c
}
catch System.Exception
{
IL_0085: stloc.3
IL_0086: ldarg.0
IL_0087: ldc.i4.s -2
IL_0089: stfld ""int Program.<Assign>d__0.<>1__state""
IL_008e: ldarg.0
IL_008f: ldflda ""System.Runtime.CompilerServices.AsyncTaskMethodBuilder Program.<Assign>d__0.<>t__builder""
IL_0094: ldloc.3
IL_0095: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.SetException(System.Exception)""
IL_009a: leave.s IL_00af
}
IL_009c: ldarg.0
IL_009d: ldc.i4.s -2
IL_009f: stfld ""int Program.<Assign>d__0.<>1__state""
IL_00a4: ldarg.0
IL_00a5: ldflda ""System.Runtime.CompilerServices.AsyncTaskMethodBuilder Program.<Assign>d__0.<>t__builder""
IL_00aa: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.SetResult()""
IL_00af: ret
}"
);
}
[
Fact
]
[
WorkItem
(
42755
,
"https://github.com/dotnet/roslyn/issues/42755"
)]
public
void
KeepLtrSemantics_StructFieldAccessOnStructFieldAccessOnClassField
()
{
var
source
=
@"
using System;
using System.Threading.Tasks;
class Program
{
static async Task Assign(A a)
{
a.b.c.x = await Write(""RHS"");
}
static async Task Main(string[] args)
{
await TestAIsNull();
await TestAIsNotNull();
await ReassignADuringAssignment();
}
static async Task TestAIsNull()
{
Console.WriteLine(nameof(TestAIsNull));
A a = null;
Console.WriteLine(""Before Assignment"");
try
{
await Assign(a);
}
catch (NullReferenceException)
{
Console.WriteLine(""Caught NullReferenceException"");
}
}
static async Task TestAIsNotNull()
{
Console.WriteLine(nameof(TestAIsNotNull));
var a = new A();
Console.WriteLine(""Before Assignment a.b.c.x is: "" + a.b.c.x);
await Assign(a);
Console.WriteLine(""After Assignment a.b.c.x is: "" + a.b.c.x);
}
static async Task ReassignADuringAssignment()
{
Console.WriteLine(nameof(ReassignADuringAssignment));
var a = new A();
var aCopy = a;
Console.WriteLine(""Before Assignment a is null == "" + (a is null));
Console.WriteLine(""Before Assignment aCopy.b.c.x is: "" + aCopy.b.c.x);
a.b.c.x = await WriteAndReassign(""RHS"");
Console.WriteLine(""After Assignment a is null == "" + (a is null));
Console.WriteLine(""After Assignment aCopy.b.c.x is: "" + aCopy.b.c.x);
async Task<int> WriteAndReassign(string s)
{
await Task.Yield();
a = null;
Console.WriteLine(s);
return 42;
}
}
static async Task<int> Write(string s)
{
await Task.Yield();
Console.WriteLine(s);
return 42;
}
}
class A
{
public B b;
}
struct B
{
public C c;
}
struct C
{
public int x;
}"
;
var
comp
=
CreateCompilation
(
source
,
options
:
TestOptions
.
ReleaseExe
);
CompileAndVerify
(
comp
,
expectedOutput
:
@"TestAIsNull
Before Assignment
Caught NullReferenceException
TestAIsNotNull
Before Assignment a.b.c.x is: 0
RHS
After Assignment a.b.c.x is: 42
ReassignADuringAssignment
Before Assignment a is null == False
Before Assignment aCopy.b.c.x is: 0
RHS
After Assignment a is null == True
After Assignment aCopy.b.c.x is: 42"
)
.
VerifyIL
(
"Program.<Assign>d__0.System.Runtime.CompilerServices.IAsyncStateMachine.MoveNext"
,
@"
{
// Code size 201 (0xc9)
.maxstack 3
.locals init (int V_0,
int V_1,
System.Runtime.CompilerServices.TaskAwaiter<int> V_2,
System.Exception V_3)
IL_0000: ldarg.0
IL_0001: ldfld ""int Program.<Assign>d__0.<>1__state""
IL_0006: stloc.0
.try
{
IL_0007: ldloc.0
IL_0008: brfalse.s IL_005b
IL_000a: ldarg.0
IL_000b: ldarg.0
IL_000c: ldfld ""A Program.<Assign>d__0.a""
IL_0011: stfld ""A Program.<Assign>d__0.<>7__wrap1""
IL_0016: ldarg.0
IL_0017: ldfld ""A Program.<Assign>d__0.<>7__wrap1""
IL_001c: ldfld ""B A.b""
IL_0021: pop
IL_0022: ldstr ""RHS""
IL_0027: call ""System.Threading.Tasks.Task<int> Program.Write(string)""
IL_002c: callvirt ""System.Runtime.CompilerServices.TaskAwaiter<int> System.Threading.Tasks.Task<int>.GetAwaiter()""
IL_0031: stloc.2
IL_0032: ldloca.s V_2
IL_0034: call ""bool System.Runtime.CompilerServices.TaskAwaiter<int>.IsCompleted.get""
IL_0039: brtrue.s IL_0077
IL_003b: ldarg.0
IL_003c: ldc.i4.0
IL_003d: dup
IL_003e: stloc.0
IL_003f: stfld ""int Program.<Assign>d__0.<>1__state""
IL_0044: ldarg.0
IL_0045: ldloc.2
IL_0046: stfld ""System.Runtime.CompilerServices.TaskAwaiter<int> Program.<Assign>d__0.<>u__1""
IL_004b: ldarg.0
IL_004c: ldflda ""System.Runtime.CompilerServices.AsyncTaskMethodBuilder Program.<Assign>d__0.<>t__builder""
IL_0051: ldloca.s V_2
IL_0053: ldarg.0
IL_0054: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.AwaitUnsafeOnCompleted<System.Runtime.CompilerServices.TaskAwaiter<int>, Program.<Assign>d__0>(ref System.Runtime.CompilerServices.TaskAwaiter<int>, ref Program.<Assign>d__0)""
IL_0059: leave.s IL_00c8
IL_005b: ldarg.0
IL_005c: ldfld ""System.Runtime.CompilerServices.TaskAwaiter<int> Program.<Assign>d__0.<>u__1""
IL_0061: stloc.2
IL_0062: ldarg.0
IL_0063: ldflda ""System.Runtime.CompilerServices.TaskAwaiter<int> Program.<Assign>d__0.<>u__1""
IL_0068: initobj ""System.Runtime.CompilerServices.TaskAwaiter<int>""
IL_006e: ldarg.0
IL_006f: ldc.i4.m1
IL_0070: dup
IL_0071: stloc.0
IL_0072: stfld ""int Program.<Assign>d__0.<>1__state""
IL_0077: ldloca.s V_2
IL_0079: call ""int System.Runtime.CompilerServices.TaskAwaiter<int>.GetResult()""
IL_007e: stloc.1
IL_007f: ldarg.0
IL_0080: ldfld ""A Program.<Assign>d__0.<>7__wrap1""
IL_0085: ldflda ""B A.b""
IL_008a: ldflda ""C B.c""
IL_008f: ldloc.1
IL_0090: stfld ""int C.x""
IL_0095: ldarg.0
IL_0096: ldnull
IL_0097: stfld ""A Program.<Assign>d__0.<>7__wrap1""
IL_009c: leave.s IL_00b5
}
catch System.Exception
{
IL_009e: stloc.3
IL_009f: ldarg.0
IL_00a0: ldc.i4.s -2
IL_00a2: stfld ""int Program.<Assign>d__0.<>1__state""
IL_00a7: ldarg.0
IL_00a8: ldflda ""System.Runtime.CompilerServices.AsyncTaskMethodBuilder Program.<Assign>d__0.<>t__builder""
IL_00ad: ldloc.3
IL_00ae: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.SetException(System.Exception)""
IL_00b3: leave.s IL_00c8
}
IL_00b5: ldarg.0
IL_00b6: ldc.i4.s -2
IL_00b8: stfld ""int Program.<Assign>d__0.<>1__state""
IL_00bd: ldarg.0
IL_00be: ldflda ""System.Runtime.CompilerServices.AsyncTaskMethodBuilder Program.<Assign>d__0.<>t__builder""
IL_00c3: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.SetResult()""
IL_00c8: ret
}"
);
}
[
Fact
]
[
WorkItem
(
42755
,
"https://github.com/dotnet/roslyn/issues/42755"
)]
public
void
KeepLtrSemantics_ClassPropertyAssignmentOnClassProperty
()
{
var
source
=
@"
using System;
using System.Threading.Tasks;
class Program
{
static async Task Assign(A a)
{
a.b.x = await Write(""RHS"");
}
static async Task Main(string[] args)
{
await TestAIsNull();
await TestAIsNotNull();
await ReassignADuringAssignment();
}
static async Task TestAIsNull()
{
Console.WriteLine(nameof(TestAIsNull));
A a = null;
Console.WriteLine(""Before Assignment"");
try
{
await Assign(a);
}
catch (NullReferenceException)
{
Console.WriteLine(""Caught NullReferenceException"");
}
}
static async Task TestAIsNotNull()
{
Console.WriteLine(nameof(TestAIsNotNull));
var a = new A{ _b = new B() };
Console.WriteLine(""Before Assignment a._b._x is: "" + a._b._x);
await Assign(a);
Console.WriteLine(""After Assignment a._b._x is: "" + a._b._x);
}
static async Task ReassignADuringAssignment()
{
Console.WriteLine(nameof(ReassignADuringAssignment));
var a = new A{ _b = new B() };
var aCopy = a;
Console.WriteLine(""Before Assignment a is null == "" + (a is null));
Console.WriteLine(""Before Assignment aCopy._b._x is: "" + aCopy._b._x);
a.b.x = await WriteAndReassign(""RHS"");
Console.WriteLine(""After Assignment a is null == "" + (a is null));
Console.WriteLine(""After Assignment aCopy._b._x is: "" + aCopy._b._x);
async Task<int> WriteAndReassign(string s)
{
await Task.Yield();
a = null;
Console.WriteLine(s);
return 42;
}
}
static async Task<int> Write(string s)
{
await Task.Yield();
Console.WriteLine(s);
return 42;
}
}
class A
{
public B _b;
public B b { get { Console.WriteLine(""GetB""); return _b; } set { Console.WriteLine(""SetB""); _b = value; }}
}
class B
{
public int _x;
public int x { get { Console.WriteLine(""GetX""); return _x; } set { Console.WriteLine(""SetX""); _x = value; } }
}"
;
var
comp
=
CreateCompilation
(
source
,
options
:
TestOptions
.
ReleaseExe
);
CompileAndVerify
(
comp
,
expectedOutput
:
@"TestAIsNull
Before Assignment
Caught NullReferenceException
TestAIsNotNull
Before Assignment a._b._x is: 0
GetB
RHS
SetX
After Assignment a._b._x is: 42
ReassignADuringAssignment
Before Assignment a is null == False
Before Assignment aCopy._b._x is: 0
GetB
RHS
SetX
After Assignment a is null == True
After Assignment aCopy._b._x is: 42"
)
.
VerifyIL
(
"Program.<Assign>d__0.System.Runtime.CompilerServices.IAsyncStateMachine.MoveNext"
,
@"
{
// Code size 184 (0xb8)
.maxstack 3
.locals init (int V_0,
int V_1,
System.Runtime.CompilerServices.TaskAwaiter<int> V_2,
System.Exception V_3)
IL_0000: ldarg.0
IL_0001: ldfld ""int Program.<Assign>d__0.<>1__state""
IL_0006: stloc.0
.try
{
IL_0007: ldloc.0
IL_0008: brfalse.s IL_0054
IL_000a: ldarg.0
IL_000b: ldarg.0
IL_000c: ldfld ""A Program.<Assign>d__0.a""
IL_0011: callvirt ""B A.b.get""
IL_0016: stfld ""B Program.<Assign>d__0.<>7__wrap1""
IL_001b: ldstr ""RHS""
IL_0020: call ""System.Threading.Tasks.Task<int> Program.Write(string)""
IL_0025: callvirt ""System.Runtime.CompilerServices.TaskAwaiter<int> System.Threading.Tasks.Task<int>.GetAwaiter()""
IL_002a: stloc.2
IL_002b: ldloca.s V_2
IL_002d: call ""bool System.Runtime.CompilerServices.TaskAwaiter<int>.IsCompleted.get""
IL_0032: brtrue.s IL_0070
IL_0034: ldarg.0
IL_0035: ldc.i4.0
IL_0036: dup
IL_0037: stloc.0
IL_0038: stfld ""int Program.<Assign>d__0.<>1__state""
IL_003d: ldarg.0
IL_003e: ldloc.2
IL_003f: stfld ""System.Runtime.CompilerServices.TaskAwaiter<int> Program.<Assign>d__0.<>u__1""
IL_0044: ldarg.0
IL_0045: ldflda ""System.Runtime.CompilerServices.AsyncTaskMethodBuilder Program.<Assign>d__0.<>t__builder""
IL_004a: ldloca.s V_2
IL_004c: ldarg.0
IL_004d: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.AwaitUnsafeOnCompleted<System.Runtime.CompilerServices.TaskAwaiter<int>, Program.<Assign>d__0>(ref System.Runtime.CompilerServices.TaskAwaiter<int>, ref Program.<Assign>d__0)""
IL_0052: leave.s IL_00b7
IL_0054: ldarg.0
IL_0055: ldfld ""System.Runtime.CompilerServices.TaskAwaiter<int> Program.<Assign>d__0.<>u__1""
IL_005a: stloc.2
IL_005b: ldarg.0
IL_005c: ldflda ""System.Runtime.CompilerServices.TaskAwaiter<int> Program.<Assign>d__0.<>u__1""
IL_0061: initobj ""System.Runtime.CompilerServices.TaskAwaiter<int>""
IL_0067: ldarg.0
IL_0068: ldc.i4.m1
IL_0069: dup
IL_006a: stloc.0
IL_006b: stfld ""int Program.<Assign>d__0.<>1__state""
IL_0070: ldloca.s V_2
IL_0072: call ""int System.Runtime.CompilerServices.TaskAwaiter<int>.GetResult()""
IL_0077: stloc.1
IL_0078: ldarg.0
IL_0079: ldfld ""B Program.<Assign>d__0.<>7__wrap1""
IL_007e: ldloc.1
IL_007f: callvirt ""void B.x.set""
IL_0084: ldarg.0
IL_0085: ldnull
IL_0086: stfld ""B Program.<Assign>d__0.<>7__wrap1""
IL_008b: leave.s IL_00a4
}
catch System.Exception
{
IL_008d: stloc.3
IL_008e: ldarg.0
IL_008f: ldc.i4.s -2
IL_0091: stfld ""int Program.<Assign>d__0.<>1__state""
IL_0096: ldarg.0
IL_0097: ldflda ""System.Runtime.CompilerServices.AsyncTaskMethodBuilder Program.<Assign>d__0.<>t__builder""
IL_009c: ldloc.3
IL_009d: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.SetException(System.Exception)""
IL_00a2: leave.s IL_00b7
}
IL_00a4: ldarg.0
IL_00a5: ldc.i4.s -2
IL_00a7: stfld ""int Program.<Assign>d__0.<>1__state""
IL_00ac: ldarg.0
IL_00ad: ldflda ""System.Runtime.CompilerServices.AsyncTaskMethodBuilder Program.<Assign>d__0.<>t__builder""
IL_00b2: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.SetResult()""
IL_00b7: ret
}"
);
}
[
WorkItem
(
19609
,
"https://github.com/dotnet/roslyn/issues/19609"
)]
[
Fact
]
public
void
KeepLtrSemantics_FieldAccessOnClass
()
{
var
source
=
@"
using System;
using System.Threading.Tasks;
class Program
{
static async Task Assign(A a)
{
a.x = await Write(""RHS"");
}
static async Task Main(string[] args)
{
await TestAIsNull();
await TestAIsNotNull();
await ReassignADuringAssignment();
}
static async Task TestAIsNull()
{
Console.WriteLine(nameof(TestAIsNull));
A a = null;
Console.WriteLine(""Before Assignment"");
try
{
await Assign(a);
}
catch (NullReferenceException)
{
Console.WriteLine(""Caught NullReferenceException"");
}
}
static async Task TestAIsNotNull()
{
Console.WriteLine(nameof(TestAIsNotNull));
var a = new A();
Console.WriteLine(""Before Assignment a.x is: "" + a.x);
await Assign(a);
Console.WriteLine(""After Assignment a.x is: "" + a.x);
}
static async Task ReassignADuringAssignment()
{
Console.WriteLine(nameof(ReassignADuringAssignment));
var a = new A();
var aCopy = a;
Console.WriteLine(""Before Assignment a is null == "" + (a is null));
Console.WriteLine(""Before Assignment aCopy.x is: "" + aCopy.x);
a.x = await WriteAndReassign(""RHS"");
Console.WriteLine(""After Assignment a is null == "" + (a is null));
Console.WriteLine(""After Assignment aCopy.x is: "" + aCopy.x);
async Task<int> WriteAndReassign(string s)
{
await Task.Yield();
a = null;
Console.WriteLine(s);
return 42;
}
}
static async Task<int> Write(string s)
{
await Task.Yield();
Console.WriteLine(s);
return 42;
}
}
class A
{
public int x;
}"
;
var
comp
=
CreateCompilation
(
source
,
options
:
TestOptions
.
ReleaseExe
);
CompileAndVerify
(
comp
,
expectedOutput
:
@"TestAIsNull
Before Assignment
RHS
Caught NullReferenceException
TestAIsNotNull
Before Assignment a.x is: 0
RHS
After Assignment a.x is: 42
ReassignADuringAssignment
Before Assignment a is null == False
Before Assignment aCopy.x is: 0
RHS
After Assignment a is null == True
After Assignment aCopy.x is: 42"
)
.
VerifyIL
(
"Program.<Assign>d__0.System.Runtime.CompilerServices.IAsyncStateMachine.MoveNext"
,
@"
{
// Code size 179 (0xb3)
.maxstack 3
.locals init (int V_0,
int V_1,
System.Runtime.CompilerServices.TaskAwaiter<int> V_2,
System.Exception V_3)
IL_0000: ldarg.0
IL_0001: ldfld ""int Program.<Assign>d__0.<>1__state""
IL_0006: stloc.0
.try
{
IL_0007: ldloc.0
IL_0008: brfalse.s IL_004f
IL_000a: ldarg.0
IL_000b: ldarg.0
IL_000c: ldfld ""A Program.<Assign>d__0.a""
IL_0011: stfld ""A Program.<Assign>d__0.<>7__wrap1""
IL_0016: ldstr ""RHS""
IL_001b: call ""System.Threading.Tasks.Task<int> Program.Write(string)""
IL_0020: callvirt ""System.Runtime.CompilerServices.TaskAwaiter<int> System.Threading.Tasks.Task<int>.GetAwaiter()""
IL_0025: stloc.2
IL_0026: ldloca.s V_2
IL_0028: call ""bool System.Runtime.CompilerServices.TaskAwaiter<int>.IsCompleted.get""
IL_002d: brtrue.s IL_006b
IL_002f: ldarg.0
IL_0030: ldc.i4.0
IL_0031: dup
IL_0032: stloc.0
IL_0033: stfld ""int Program.<Assign>d__0.<>1__state""
IL_0038: ldarg.0
IL_0039: ldloc.2
IL_003a: stfld ""System.Runtime.CompilerServices.TaskAwaiter<int> Program.<Assign>d__0.<>u__1""
IL_003f: ldarg.0
IL_0040: ldflda ""System.Runtime.CompilerServices.AsyncTaskMethodBuilder Program.<Assign>d__0.<>t__builder""
IL_0045: ldloca.s V_2
IL_0047: ldarg.0
IL_0048: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.AwaitUnsafeOnCompleted<System.Runtime.CompilerServices.TaskAwaiter<int>, Program.<Assign>d__0>(ref System.Runtime.CompilerServices.TaskAwaiter<int>, ref Program.<Assign>d__0)""
IL_004d: leave.s IL_00b2
IL_004f: ldarg.0
IL_0050: ldfld ""System.Runtime.CompilerServices.TaskAwaiter<int> Program.<Assign>d__0.<>u__1""
IL_0055: stloc.2
IL_0056: ldarg.0
IL_0057: ldflda ""System.Runtime.CompilerServices.TaskAwaiter<int> Program.<Assign>d__0.<>u__1""
IL_005c: initobj ""System.Runtime.CompilerServices.TaskAwaiter<int>""
IL_0062: ldarg.0
IL_0063: ldc.i4.m1
IL_0064: dup
IL_0065: stloc.0
IL_0066: stfld ""int Program.<Assign>d__0.<>1__state""
IL_006b: ldloca.s V_2
IL_006d: call ""int System.Runtime.CompilerServices.TaskAwaiter<int>.GetResult()""
IL_0072: stloc.1
IL_0073: ldarg.0
IL_0074: ldfld ""A Program.<Assign>d__0.<>7__wrap1""
IL_0079: ldloc.1
IL_007a: stfld ""int A.x""
IL_007f: ldarg.0
IL_0080: ldnull
IL_0081: stfld ""A Program.<Assign>d__0.<>7__wrap1""
IL_0086: leave.s IL_009f
}
catch System.Exception
{
IL_0088: stloc.3
IL_0089: ldarg.0
IL_008a: ldc.i4.s -2
IL_008c: stfld ""int Program.<Assign>d__0.<>1__state""
IL_0091: ldarg.0
IL_0092: ldflda ""System.Runtime.CompilerServices.AsyncTaskMethodBuilder Program.<Assign>d__0.<>t__builder""
IL_0097: ldloc.3
IL_0098: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.SetException(System.Exception)""
IL_009d: leave.s IL_00b2
}
IL_009f: ldarg.0
IL_00a0: ldc.i4.s -2
IL_00a2: stfld ""int Program.<Assign>d__0.<>1__state""
IL_00a7: ldarg.0
IL_00a8: ldflda ""System.Runtime.CompilerServices.AsyncTaskMethodBuilder Program.<Assign>d__0.<>t__builder""
IL_00ad: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.SetResult()""
IL_00b2: ret
}"
);
}
[
Fact
]
[
WorkItem
(
42755
,
"https://github.com/dotnet/roslyn/issues/42755"
)]
public
void
KeepLtrSemantics_CompoundAssignment
()
{
var
source
=
@"
using System;
using System.Threading.Tasks;
class Program
{
static async Task Assign(A a)
{
a.x += await Write(""RHS"");
}
static async Task Main(string[] args)
{
await TestAIsNull();
await TestAIsNotNull();
await ReassignADuringAssignment();
await ReassignXDuringAssignment();
}
static async Task TestAIsNull()
{
Console.WriteLine(nameof(TestAIsNull));
A a = null;
Console.WriteLine(""Before Assignment"");
try
{
await Assign(a);
}
catch (NullReferenceException)
{
Console.WriteLine(""Caught NullReferenceException"");
}
}
static async Task TestAIsNotNull()
{
Console.WriteLine(nameof(TestAIsNotNull));
var a = new A(){ x = 1 };
Console.WriteLine(""Before Assignment a.x is: "" + a.x);
await Assign(a);
Console.WriteLine(""After Assignment a.x is: "" + a.x);
}
static async Task ReassignADuringAssignment()
{
Console.WriteLine(nameof(ReassignADuringAssignment));
var a = new A(){ x = 1 };
var aCopy = a;
Console.WriteLine(""Before Assignment a is null == "" + (a is null));
Console.WriteLine(""Before Assignment aCopy.x is: "" + aCopy.x);
a.x += await WriteAndReassign(""RHS"");
Console.WriteLine(""After Assignment a is null == "" + (a is null));
Console.WriteLine(""After Assignment aCopy.x is: "" + aCopy.x);
async Task<int> WriteAndReassign(string s)
{
await Task.Yield();
a = null;
Console.WriteLine(s);
return 42;
}
}
static async Task ReassignXDuringAssignment()
{
Console.WriteLine(nameof(ReassignXDuringAssignment));
var a = new A(){ x = 1 };
Console.WriteLine(""Before Assignment a.x is: "" + a.x);
a.x += await WriteAndReassign(""RHS"");
Console.WriteLine(""After Assignment a.x is: "" + a.x);
async Task<int> WriteAndReassign(string s)
{
await Task.Yield();
a.x = 100;
Console.WriteLine(s);
return 42;
}
}
static async Task<int> Write(string s)
{
await Task.Yield();
Console.WriteLine(s);
return 42;
}
}
class A
{
public int x;
}"
;
var
comp
=
CreateCompilation
(
source
,
options
:
TestOptions
.
ReleaseExe
);
CompileAndVerify
(
comp
,
expectedOutput
:
@"TestAIsNull
Before Assignment
Caught NullReferenceException
TestAIsNotNull
Before Assignment a.x is: 1
RHS
After Assignment a.x is: 43
ReassignADuringAssignment
Before Assignment a is null == False
Before Assignment aCopy.x is: 1
RHS
After Assignment a is null == True
After Assignment aCopy.x is: 43
ReassignXDuringAssignment
Before Assignment a.x is: 1
RHS
After Assignment a.x is: 43"
)
.
VerifyIL
(
"Program.<Assign>d__0.System.Runtime.CompilerServices.IAsyncStateMachine.MoveNext"
,
@"
{
// Code size 202 (0xca)
.maxstack 3
.locals init (int V_0,
A V_1,
int V_2,
System.Runtime.CompilerServices.TaskAwaiter<int> V_3,
System.Exception V_4)
IL_0000: ldarg.0
IL_0001: ldfld ""int Program.<Assign>d__0.<>1__state""
IL_0006: stloc.0
.try
{
IL_0007: ldloc.0
IL_0008: brfalse.s IL_005d
IL_000a: ldarg.0
IL_000b: ldfld ""A Program.<Assign>d__0.a""
IL_0010: stloc.1
IL_0011: ldarg.0
IL_0012: ldloc.1
IL_0013: stfld ""A Program.<Assign>d__0.<>7__wrap1""
IL_0018: ldarg.0
IL_0019: ldloc.1
IL_001a: ldfld ""int A.x""
IL_001f: stfld ""int Program.<Assign>d__0.<>7__wrap2""
IL_0024: ldstr ""RHS""
IL_0029: call ""System.Threading.Tasks.Task<int> Program.Write(string)""
IL_002e: callvirt ""System.Runtime.CompilerServices.TaskAwaiter<int> System.Threading.Tasks.Task<int>.GetAwaiter()""
IL_0033: stloc.3
IL_0034: ldloca.s V_3
IL_0036: call ""bool System.Runtime.CompilerServices.TaskAwaiter<int>.IsCompleted.get""
IL_003b: brtrue.s IL_0079
IL_003d: ldarg.0
IL_003e: ldc.i4.0
IL_003f: dup
IL_0040: stloc.0
IL_0041: stfld ""int Program.<Assign>d__0.<>1__state""
IL_0046: ldarg.0
IL_0047: ldloc.3
IL_0048: stfld ""System.Runtime.CompilerServices.TaskAwaiter<int> Program.<Assign>d__0.<>u__1""
IL_004d: ldarg.0
IL_004e: ldflda ""System.Runtime.CompilerServices.AsyncTaskMethodBuilder Program.<Assign>d__0.<>t__builder""
IL_0053: ldloca.s V_3
IL_0055: ldarg.0
IL_0056: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.AwaitUnsafeOnCompleted<System.Runtime.CompilerServices.TaskAwaiter<int>, Program.<Assign>d__0>(ref System.Runtime.CompilerServices.TaskAwaiter<int>, ref Program.<Assign>d__0)""
IL_005b: leave.s IL_00c9
IL_005d: ldarg.0
IL_005e: ldfld ""System.Runtime.CompilerServices.TaskAwaiter<int> Program.<Assign>d__0.<>u__1""
IL_0063: stloc.3
IL_0064: ldarg.0
IL_0065: ldflda ""System.Runtime.CompilerServices.TaskAwaiter<int> Program.<Assign>d__0.<>u__1""
IL_006a: initobj ""System.Runtime.CompilerServices.TaskAwaiter<int>""
IL_0070: ldarg.0
IL_0071: ldc.i4.m1
IL_0072: dup
IL_0073: stloc.0
IL_0074: stfld ""int Program.<Assign>d__0.<>1__state""
IL_0079: ldloca.s V_3
IL_007b: call ""int System.Runtime.CompilerServices.TaskAwaiter<int>.GetResult()""
IL_0080: stloc.2
IL_0081: ldarg.0
IL_0082: ldfld ""A Program.<Assign>d__0.<>7__wrap1""
IL_0087: ldarg.0
IL_0088: ldfld ""int Program.<Assign>d__0.<>7__wrap2""
IL_008d: ldloc.2
IL_008e: add
IL_008f: stfld ""int A.x""
IL_0094: ldarg.0
IL_0095: ldnull
IL_0096: stfld ""A Program.<Assign>d__0.<>7__wrap1""
IL_009b: leave.s IL_00b6
}
catch System.Exception
{
IL_009d: stloc.s V_4
IL_009f: ldarg.0
IL_00a0: ldc.i4.s -2
IL_00a2: stfld ""int Program.<Assign>d__0.<>1__state""
IL_00a7: ldarg.0
IL_00a8: ldflda ""System.Runtime.CompilerServices.AsyncTaskMethodBuilder Program.<Assign>d__0.<>t__builder""
IL_00ad: ldloc.s V_4
IL_00af: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.SetException(System.Exception)""
IL_00b4: leave.s IL_00c9
}
IL_00b6: ldarg.0
IL_00b7: ldc.i4.s -2
IL_00b9: stfld ""int Program.<Assign>d__0.<>1__state""
IL_00be: ldarg.0
IL_00bf: ldflda ""System.Runtime.CompilerServices.AsyncTaskMethodBuilder Program.<Assign>d__0.<>t__builder""
IL_00c4: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.SetResult()""
IL_00c9: ret
}"
);
}
[
Fact
]
[
WorkItem
(
42755
,
"https://github.com/dotnet/roslyn/issues/42755"
)]
public
void
KeepLtrSemantics_CompoundAssignmentProperties
()
{
var
source
=
@"
using System;
using System.Threading.Tasks;
class Program
{
static async Task Assign(A a)
{
a.x += await Write(""RHS"");
}
static async Task Main(string[] args)
{
await TestAIsNull();
await TestAIsNotNull();
await ReassignADuringAssignment();
await ReassignXDuringAssignment();
}
static async Task TestAIsNull()
{
Console.WriteLine(nameof(TestAIsNull));
A a = null;
Console.WriteLine(""Before Assignment"");
try
{
await Assign(a);
}
catch (NullReferenceException)
{
Console.WriteLine(""Caught NullReferenceException"");
}
}
static async Task TestAIsNotNull()
{
Console.WriteLine(nameof(TestAIsNotNull));
var a = new A(){ _x = 1 };
Console.WriteLine(""Before Assignment a._x is: "" + a._x);
await Assign(a);
Console.WriteLine(""After Assignment a._x is: "" + a._x);
}
static async Task ReassignADuringAssignment()
{
Console.WriteLine(nameof(ReassignADuringAssignment));
var a = new A(){ _x = 1 };
var aCopy = a;
Console.WriteLine(""Before Assignment a is null == "" + (a is null));
Console.WriteLine(""Before Assignment aCopy._x is: "" + aCopy._x);
a.x += await WriteAndReassign(""RHS"");
Console.WriteLine(""After Assignment a is null == "" + (a is null));
Console.WriteLine(""After Assignment aCopy._x is: "" + aCopy._x);
async Task<int> WriteAndReassign(string s)
{
await Task.Yield();
a = null;
Console.WriteLine(s);
return 42;
}
}
static async Task ReassignXDuringAssignment()
{
Console.WriteLine(nameof(ReassignXDuringAssignment));
var a = new A(){ _x = 1 };
Console.WriteLine(""Before Assignment a._x is: "" + a._x);
a.x += await WriteAndReassign(""RHS"");
Console.WriteLine(""After Assignment a._x is: "" + a._x);
async Task<int> WriteAndReassign(string s)
{
await Task.Yield();
a._x = 100;
Console.WriteLine(s);
return 42;
}
}
static async Task<int> Write(string s)
{
await Task.Yield();
Console.WriteLine(s);
return 42;
}
}
class A
{
public int _x;
public int x { get { Console.WriteLine(""GetX""); return _x; } set { Console.WriteLine(""SetX""); _x = value; } }
}"
;
var
comp
=
CreateCompilation
(
source
,
options
:
TestOptions
.
ReleaseExe
);
CompileAndVerify
(
comp
,
expectedOutput
:
@"TestAIsNull
Before Assignment
Caught NullReferenceException
TestAIsNotNull
Before Assignment a._x is: 1
GetX
RHS
SetX
After Assignment a._x is: 43
ReassignADuringAssignment
Before Assignment a is null == False
Before Assignment aCopy._x is: 1
GetX
RHS
SetX
After Assignment a is null == True
After Assignment aCopy._x is: 43
ReassignXDuringAssignment
Before Assignment a._x is: 1
GetX
RHS
SetX
After Assignment a._x is: 43"
)
.
VerifyIL
(
"Program.<Assign>d__0.System.Runtime.CompilerServices.IAsyncStateMachine.MoveNext"
,
@"
{
// Code size 202 (0xca)
.maxstack 3
.locals init (int V_0,
A V_1,
int V_2,
System.Runtime.CompilerServices.TaskAwaiter<int> V_3,
System.Exception V_4)
IL_0000: ldarg.0
IL_0001: ldfld ""int Program.<Assign>d__0.<>1__state""
IL_0006: stloc.0
.try
{
IL_0007: ldloc.0
IL_0008: brfalse.s IL_005d
IL_000a: ldarg.0
IL_000b: ldfld ""A Program.<Assign>d__0.a""
IL_0010: stloc.1
IL_0011: ldarg.0
IL_0012: ldloc.1
IL_0013: stfld ""A Program.<Assign>d__0.<>7__wrap1""
IL_0018: ldarg.0
IL_0019: ldloc.1
IL_001a: callvirt ""int A.x.get""
IL_001f: stfld ""int Program.<Assign>d__0.<>7__wrap2""
IL_0024: ldstr ""RHS""
IL_0029: call ""System.Threading.Tasks.Task<int> Program.Write(string)""
IL_002e: callvirt ""System.Runtime.CompilerServices.TaskAwaiter<int> System.Threading.Tasks.Task<int>.GetAwaiter()""
IL_0033: stloc.3
IL_0034: ldloca.s V_3
IL_0036: call ""bool System.Runtime.CompilerServices.TaskAwaiter<int>.IsCompleted.get""
IL_003b: brtrue.s IL_0079
IL_003d: ldarg.0
IL_003e: ldc.i4.0
IL_003f: dup
IL_0040: stloc.0
IL_0041: stfld ""int Program.<Assign>d__0.<>1__state""
IL_0046: ldarg.0
IL_0047: ldloc.3
IL_0048: stfld ""System.Runtime.CompilerServices.TaskAwaiter<int> Program.<Assign>d__0.<>u__1""
IL_004d: ldarg.0
IL_004e: ldflda ""System.Runtime.CompilerServices.AsyncTaskMethodBuilder Program.<Assign>d__0.<>t__builder""
IL_0053: ldloca.s V_3
IL_0055: ldarg.0
IL_0056: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.AwaitUnsafeOnCompleted<System.Runtime.CompilerServices.TaskAwaiter<int>, Program.<Assign>d__0>(ref System.Runtime.CompilerServices.TaskAwaiter<int>, ref Program.<Assign>d__0)""
IL_005b: leave.s IL_00c9
IL_005d: ldarg.0
IL_005e: ldfld ""System.Runtime.CompilerServices.TaskAwaiter<int> Program.<Assign>d__0.<>u__1""
IL_0063: stloc.3
IL_0064: ldarg.0
IL_0065: ldflda ""System.Runtime.CompilerServices.TaskAwaiter<int> Program.<Assign>d__0.<>u__1""
IL_006a: initobj ""System.Runtime.CompilerServices.TaskAwaiter<int>""
IL_0070: ldarg.0
IL_0071: ldc.i4.m1
IL_0072: dup
IL_0073: stloc.0
IL_0074: stfld ""int Program.<Assign>d__0.<>1__state""
IL_0079: ldloca.s V_3
IL_007b: call ""int System.Runtime.CompilerServices.TaskAwaiter<int>.GetResult()""
IL_0080: stloc.2
IL_0081: ldarg.0
IL_0082: ldfld ""A Program.<Assign>d__0.<>7__wrap1""
IL_0087: ldarg.0
IL_0088: ldfld ""int Program.<Assign>d__0.<>7__wrap2""
IL_008d: ldloc.2
IL_008e: add
IL_008f: callvirt ""void A.x.set""
IL_0094: ldarg.0
IL_0095: ldnull
IL_0096: stfld ""A Program.<Assign>d__0.<>7__wrap1""
IL_009b: leave.s IL_00b6
}
catch System.Exception
{
IL_009d: stloc.s V_4
IL_009f: ldarg.0
IL_00a0: ldc.i4.s -2
IL_00a2: stfld ""int Program.<Assign>d__0.<>1__state""
IL_00a7: ldarg.0
IL_00a8: ldflda ""System.Runtime.CompilerServices.AsyncTaskMethodBuilder Program.<Assign>d__0.<>t__builder""
IL_00ad: ldloc.s V_4
IL_00af: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.SetException(System.Exception)""
IL_00b4: leave.s IL_00c9
}
IL_00b6: ldarg.0
IL_00b7: ldc.i4.s -2
IL_00b9: stfld ""int Program.<Assign>d__0.<>1__state""
IL_00be: ldarg.0
IL_00bf: ldflda ""System.Runtime.CompilerServices.AsyncTaskMethodBuilder Program.<Assign>d__0.<>t__builder""
IL_00c4: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.SetResult()""
IL_00c9: ret
}"
);
}
[
WorkItem
(
19609
,
"https://github.com/dotnet/roslyn/issues/19609"
)]
[
Fact
]
public
void
KeepLtrSemantics_AssignmentToAssignment
()
{
var
source
=
@"
using System;
using System.Threading.Tasks;
class Program
{
static async Task Assign(A a, B b)
{
a.b.x = b.x = await Write(""RHS"");
}
static async Task Main(string[] args)
{
await TestAIsNullBIsNull();
await TestAIsNullBIsNotNull();
await TestAIsNotNullBIsNull();
await TestADotBIsNullBIsNotNull();
await TestADotBIsNotNullBIsNotNull();
}
static async Task TestAIsNullBIsNull()
{
Console.WriteLine(nameof(TestAIsNullBIsNull));
A a = null;
B b = null;
Console.WriteLine(""Before Assignment"");
try
{
await Assign(a, b);
}
catch (NullReferenceException)
{
Console.WriteLine(""Caught NullReferenceException"");
}
}
static async Task TestAIsNullBIsNotNull()
{
Console.WriteLine(nameof(TestAIsNullBIsNotNull));
A a = null;
B b = new B();
Console.WriteLine(""Before Assignment"");
try
{
await Assign(a, b);
}
catch (NullReferenceException)
{
Console.WriteLine(""Caught NullReferenceException"");
}
}
static async Task TestAIsNotNullBIsNull()
{
Console.WriteLine(nameof(TestAIsNotNullBIsNull));
A a = new A{ b = new B() };
B b = null;
Console.WriteLine(""Before Assignment"");
try
{
await Assign(a, b);
}
catch (NullReferenceException)
{
Console.WriteLine(""Caught NullReferenceException"");
}
}
static async Task TestADotBIsNullBIsNotNull()
{
Console.WriteLine(nameof(TestADotBIsNullBIsNotNull));
A a = new A();
B b = new B();
Console.WriteLine(""Before Assignment"");
try
{
await Assign(a, b);
}
catch (NullReferenceException)
{
Console.WriteLine(""Caught NullReferenceException"");
}
}
static async Task TestADotBIsNotNullBIsNotNull()
{
Console.WriteLine(nameof(TestADotBIsNotNullBIsNotNull));
A a = new A{ b = new B() };
B b = new B();
Console.WriteLine(""Before Assignment a.b.x is: "" + a.b.x);
Console.WriteLine(""Before Assignment b.x is: "" + b.x);
await Assign(a, b);
Console.WriteLine(""After Assignment a.b.x is: "" + a.b.x);
Console.WriteLine(""After Assignment b.x is: "" + b.x);
}
static async Task<int> Write(string s)
{
await Task.Yield();
Console.WriteLine(s);
return 42;
}
}
class A
{
public B b;
}
class B
{
public int x;
}"
;
var
comp
=
CreateCompilation
(
source
,
options
:
TestOptions
.
ReleaseExe
);
CompileAndVerify
(
comp
,
expectedOutput
:
@"TestAIsNullBIsNull
Before Assignment
Caught NullReferenceException
TestAIsNullBIsNotNull
Before Assignment
Caught NullReferenceException
TestAIsNotNullBIsNull
Before Assignment
RHS
Caught NullReferenceException
TestADotBIsNullBIsNotNull
Before Assignment
RHS
Caught NullReferenceException
TestADotBIsNotNullBIsNotNull
Before Assignment a.b.x is: 0
Before Assignment b.x is: 0
RHS
After Assignment a.b.x is: 42
After Assignment b.x is: 42"
)
.
VerifyIL
(
"Program.<Assign>d__0.System.Runtime.CompilerServices.IAsyncStateMachine.MoveNext"
,
@"
{
// Code size 219 (0xdb)
.maxstack 4
.locals init (int V_0,
int V_1,
System.Runtime.CompilerServices.TaskAwaiter<int> V_2,
int V_3,
System.Exception V_4)
IL_0000: ldarg.0
IL_0001: ldfld ""int Program.<Assign>d__0.<>1__state""
IL_0006: stloc.0
.try
{
IL_0007: ldloc.0
IL_0008: brfalse.s IL_0060
IL_000a: ldarg.0
IL_000b: ldarg.0
IL_000c: ldfld ""A Program.<Assign>d__0.a""
IL_0011: ldfld ""B A.b""
IL_0016: stfld ""B Program.<Assign>d__0.<>7__wrap1""
IL_001b: ldarg.0
IL_001c: ldarg.0
IL_001d: ldfld ""B Program.<Assign>d__0.b""
IL_0022: stfld ""B Program.<Assign>d__0.<>7__wrap2""
IL_0027: ldstr ""RHS""
IL_002c: call ""System.Threading.Tasks.Task<int> Program.Write(string)""
IL_0031: callvirt ""System.Runtime.CompilerServices.TaskAwaiter<int> System.Threading.Tasks.Task<int>.GetAwaiter()""
IL_0036: stloc.2
IL_0037: ldloca.s V_2
IL_0039: call ""bool System.Runtime.CompilerServices.TaskAwaiter<int>.IsCompleted.get""
IL_003e: brtrue.s IL_007c
IL_0040: ldarg.0
IL_0041: ldc.i4.0
IL_0042: dup
IL_0043: stloc.0
IL_0044: stfld ""int Program.<Assign>d__0.<>1__state""
IL_0049: ldarg.0
IL_004a: ldloc.2
IL_004b: stfld ""System.Runtime.CompilerServices.TaskAwaiter<int> Program.<Assign>d__0.<>u__1""
IL_0050: ldarg.0
IL_0051: ldflda ""System.Runtime.CompilerServices.AsyncTaskMethodBuilder Program.<Assign>d__0.<>t__builder""
IL_0056: ldloca.s V_2
IL_0058: ldarg.0
IL_0059: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.AwaitUnsafeOnCompleted<System.Runtime.CompilerServices.TaskAwaiter<int>, Program.<Assign>d__0>(ref System.Runtime.CompilerServices.TaskAwaiter<int>, ref Program.<Assign>d__0)""
IL_005e: leave.s IL_00da
IL_0060: ldarg.0
IL_0061: ldfld ""System.Runtime.CompilerServices.TaskAwaiter<int> Program.<Assign>d__0.<>u__1""
IL_0066: stloc.2
IL_0067: ldarg.0
IL_0068: ldflda ""System.Runtime.CompilerServices.TaskAwaiter<int> Program.<Assign>d__0.<>u__1""
IL_006d: initobj ""System.Runtime.CompilerServices.TaskAwaiter<int>""
IL_0073: ldarg.0
IL_0074: ldc.i4.m1
IL_0075: dup
IL_0076: stloc.0
IL_0077: stfld ""int Program.<Assign>d__0.<>1__state""
IL_007c: ldloca.s V_2
IL_007e: call ""int System.Runtime.CompilerServices.TaskAwaiter<int>.GetResult()""
IL_0083: stloc.1
IL_0084: ldarg.0
IL_0085: ldfld ""B Program.<Assign>d__0.<>7__wrap1""
IL_008a: ldarg.0
IL_008b: ldfld ""B Program.<Assign>d__0.<>7__wrap2""
IL_0090: ldloc.1
IL_0091: dup
IL_0092: stloc.3
IL_0093: stfld ""int B.x""
IL_0098: ldloc.3
IL_0099: stfld ""int B.x""
IL_009e: ldarg.0
IL_009f: ldnull
IL_00a0: stfld ""B Program.<Assign>d__0.<>7__wrap1""
IL_00a5: ldarg.0
IL_00a6: ldnull
IL_00a7: stfld ""B Program.<Assign>d__0.<>7__wrap2""
IL_00ac: leave.s IL_00c7
}
catch System.Exception
{
IL_00ae: stloc.s V_4
IL_00b0: ldarg.0
IL_00b1: ldc.i4.s -2
IL_00b3: stfld ""int Program.<Assign>d__0.<>1__state""
IL_00b8: ldarg.0
IL_00b9: ldflda ""System.Runtime.CompilerServices.AsyncTaskMethodBuilder Program.<Assign>d__0.<>t__builder""
IL_00be: ldloc.s V_4
IL_00c0: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.SetException(System.Exception)""
IL_00c5: leave.s IL_00da
}
IL_00c7: ldarg.0
IL_00c8: ldc.i4.s -2
IL_00ca: stfld ""int Program.<Assign>d__0.<>1__state""
IL_00cf: ldarg.0
IL_00d0: ldflda ""System.Runtime.CompilerServices.AsyncTaskMethodBuilder Program.<Assign>d__0.<>t__builder""
IL_00d5: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.SetResult()""
IL_00da: ret
}"
);
}
[
WorkItem
(
19609
,
"https://github.com/dotnet/roslyn/issues/19609"
)]
[
Fact
]
public
void
KeepLtrSemantics_AssignmentToAssignmentProperties
()
{
var
source
=
@"
using System;
using System.Threading.Tasks;
class Program
{
static async Task Assign(A a, B b)
{
a.b.x = b.x = await Write(""RHS"");
}
static async Task Main(string[] args)
{
await TestAIsNullBIsNull();
await TestAIsNullBIsNotNull();
await TestAIsNotNullBIsNull();
await TestADotBIsNullBIsNotNull();
await TestADotBIsNotNullBIsNotNull();
}
static async Task TestAIsNullBIsNull()
{
Console.WriteLine(nameof(TestAIsNullBIsNull));
A a = null;
B b = null;
Console.WriteLine(""Before Assignment"");
try
{
await Assign(a, b);
}
catch (NullReferenceException)
{
Console.WriteLine(""Caught NullReferenceException"");
}
}
static async Task TestAIsNullBIsNotNull()
{
Console.WriteLine(nameof(TestAIsNullBIsNotNull));
A a = null;
B b = new B();
Console.WriteLine(""Before Assignment"");
try
{
await Assign(a, b);
}
catch (NullReferenceException)
{
Console.WriteLine(""Caught NullReferenceException"");
}
}
static async Task TestAIsNotNullBIsNull()
{
Console.WriteLine(nameof(TestAIsNotNullBIsNull));
A a = new A{ _b = new B() };
B b = null;
Console.WriteLine(""Before Assignment"");
try
{
await Assign(a, b);
}
catch (NullReferenceException)
{
Console.WriteLine(""Caught NullReferenceException"");
}
}
static async Task TestADotBIsNullBIsNotNull()
{
Console.WriteLine(nameof(TestADotBIsNullBIsNotNull));
A a = new A();
B b = new B();
Console.WriteLine(""Before Assignment"");
try
{
await Assign(a, b);
}
catch (NullReferenceException)
{
Console.WriteLine(""Caught NullReferenceException"");
}
}
static async Task TestADotBIsNotNullBIsNotNull()
{
Console.WriteLine(nameof(TestADotBIsNotNullBIsNotNull));
A a = new A{ _b = new B() };
B b = new B();
Console.WriteLine(""Before Assignment a._b._x is: "" + a._b._x);
Console.WriteLine(""Before Assignment b._x is: "" + b._x);
await Assign(a, b);
Console.WriteLine(""After Assignment a._b._x is: "" + a._b._x);
Console.WriteLine(""After Assignment b._x is: "" + b._x);
}
static async Task<int> Write(string s)
{
await Task.Yield();
Console.WriteLine(s);
return 42;
}
}
class A
{
public B _b;
public B b { get { Console.WriteLine(""GetB""); return _b; } set { Console.WriteLine(""SetB""); _b = value; }}
}
class B
{
public int _x;
public int x { get { Console.WriteLine(""GetX""); return _x; } set { Console.WriteLine(""SetX""); _x = value; } }
}"
;
var
comp
=
CreateCompilation
(
source
,
options
:
TestOptions
.
ReleaseExe
);
CompileAndVerify
(
comp
,
expectedOutput
:
@"TestAIsNullBIsNull
Before Assignment
Caught NullReferenceException
TestAIsNullBIsNotNull
Before Assignment
Caught NullReferenceException
TestAIsNotNullBIsNull
Before Assignment
GetB
RHS
Caught NullReferenceException
TestADotBIsNullBIsNotNull
Before Assignment
GetB
RHS
SetX
Caught NullReferenceException
TestADotBIsNotNullBIsNotNull
Before Assignment a._b._x is: 0
Before Assignment b._x is: 0
GetB
RHS
SetX
SetX
After Assignment a._b._x is: 42
After Assignment b._x is: 42"
)
.
VerifyIL
(
"Program.<Assign>d__0.System.Runtime.CompilerServices.IAsyncStateMachine.MoveNext"
,
@"
{
// Code size 219 (0xdb)
.maxstack 3
.locals init (int V_0,
int V_1,
int V_2,
System.Runtime.CompilerServices.TaskAwaiter<int> V_3,
System.Exception V_4)
IL_0000: ldarg.0
IL_0001: ldfld ""int Program.<Assign>d__0.<>1__state""
IL_0006: stloc.0
.try
{
IL_0007: ldloc.0
IL_0008: brfalse.s IL_0060
IL_000a: ldarg.0
IL_000b: ldarg.0
IL_000c: ldfld ""A Program.<Assign>d__0.a""
IL_0011: callvirt ""B A.b.get""
IL_0016: stfld ""B Program.<Assign>d__0.<>7__wrap1""
IL_001b: ldarg.0
IL_001c: ldarg.0
IL_001d: ldfld ""B Program.<Assign>d__0.b""
IL_0022: stfld ""B Program.<Assign>d__0.<>7__wrap2""
IL_0027: ldstr ""RHS""
IL_002c: call ""System.Threading.Tasks.Task<int> Program.Write(string)""
IL_0031: callvirt ""System.Runtime.CompilerServices.TaskAwaiter<int> System.Threading.Tasks.Task<int>.GetAwaiter()""
IL_0036: stloc.3
IL_0037: ldloca.s V_3
IL_0039: call ""bool System.Runtime.CompilerServices.TaskAwaiter<int>.IsCompleted.get""
IL_003e: brtrue.s IL_007c
IL_0040: ldarg.0
IL_0041: ldc.i4.0
IL_0042: dup
IL_0043: stloc.0
IL_0044: stfld ""int Program.<Assign>d__0.<>1__state""
IL_0049: ldarg.0
IL_004a: ldloc.3
IL_004b: stfld ""System.Runtime.CompilerServices.TaskAwaiter<int> Program.<Assign>d__0.<>u__1""
IL_0050: ldarg.0
IL_0051: ldflda ""System.Runtime.CompilerServices.AsyncTaskMethodBuilder Program.<Assign>d__0.<>t__builder""
IL_0056: ldloca.s V_3
IL_0058: ldarg.0
IL_0059: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.AwaitUnsafeOnCompleted<System.Runtime.CompilerServices.TaskAwaiter<int>, Program.<Assign>d__0>(ref System.Runtime.CompilerServices.TaskAwaiter<int>, ref Program.<Assign>d__0)""
IL_005e: leave.s IL_00da
IL_0060: ldarg.0
IL_0061: ldfld ""System.Runtime.CompilerServices.TaskAwaiter<int> Program.<Assign>d__0.<>u__1""
IL_0066: stloc.3
IL_0067: ldarg.0
IL_0068: ldflda ""System.Runtime.CompilerServices.TaskAwaiter<int> Program.<Assign>d__0.<>u__1""
IL_006d: initobj ""System.Runtime.CompilerServices.TaskAwaiter<int>""
IL_0073: ldarg.0
IL_0074: ldc.i4.m1
IL_0075: dup
IL_0076: stloc.0
IL_0077: stfld ""int Program.<Assign>d__0.<>1__state""
IL_007c: ldloca.s V_3
IL_007e: call ""int System.Runtime.CompilerServices.TaskAwaiter<int>.GetResult()""
IL_0083: stloc.1
IL_0084: ldarg.0
IL_0085: ldfld ""B Program.<Assign>d__0.<>7__wrap2""
IL_008a: ldloc.1
IL_008b: dup
IL_008c: stloc.2
IL_008d: callvirt ""void B.x.set""
IL_0092: ldarg.0
IL_0093: ldfld ""B Program.<Assign>d__0.<>7__wrap1""
IL_0098: ldloc.2
IL_0099: callvirt ""void B.x.set""
IL_009e: ldarg.0
IL_009f: ldnull
IL_00a0: stfld ""B Program.<Assign>d__0.<>7__wrap1""
IL_00a5: ldarg.0
IL_00a6: ldnull
IL_00a7: stfld ""B Program.<Assign>d__0.<>7__wrap2""
IL_00ac: leave.s IL_00c7
}
catch System.Exception
{
IL_00ae: stloc.s V_4
IL_00b0: ldarg.0
IL_00b1: ldc.i4.s -2
IL_00b3: stfld ""int Program.<Assign>d__0.<>1__state""
IL_00b8: ldarg.0
IL_00b9: ldflda ""System.Runtime.CompilerServices.AsyncTaskMethodBuilder Program.<Assign>d__0.<>t__builder""
IL_00be: ldloc.s V_4
IL_00c0: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.SetException(System.Exception)""
IL_00c5: leave.s IL_00da
}
IL_00c7: ldarg.0
IL_00c8: ldc.i4.s -2
IL_00ca: stfld ""int Program.<Assign>d__0.<>1__state""
IL_00cf: ldarg.0
IL_00d0: ldflda ""System.Runtime.CompilerServices.AsyncTaskMethodBuilder Program.<Assign>d__0.<>t__builder""
IL_00d5: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.SetResult()""
IL_00da: ret
}"
);
}
[
Fact
]
[
WorkItem
(
42755
,
"https://github.com/dotnet/roslyn/issues/42755"
)]
public
void
AssignmentToFieldOfStaticFieldOfStruct
()
{
var
source
=
@"
using System;
using System.Threading.Tasks;
class Program
{
static async Task Assign()
{
A.b.x = await Write(""RHS"");
}
static async Task<int> Write(string s)
{
await Task.Yield();
Console.WriteLine(s);
return 42;
}
static async Task Main(string[] args)
{
Console.WriteLine(""Before Assignment A.b.x is: "" + A.b.x);
await Assign();
Console.WriteLine(""After Assignment A.b.x is: "" + A.b.x);
}
}
struct A
{
public static B b;
}
struct B
{
public int x;
}"
;
var
comp
=
CreateCompilation
(
source
,
options
:
TestOptions
.
ReleaseExe
);
CompileAndVerify
(
comp
,
expectedOutput
:
@"Before Assignment A.b.x is: 0
RHS
After Assignment A.b.x is: 42"
)
.
VerifyIL
(
"Program.<Assign>d__0.System.Runtime.CompilerServices.IAsyncStateMachine.MoveNext"
,
@"
{
// Code size 159 (0x9f)
.maxstack 3
.locals init (int V_0,
int V_1,
System.Runtime.CompilerServices.TaskAwaiter<int> V_2,
System.Exception V_3)
IL_0000: ldarg.0
IL_0001: ldfld ""int Program.<Assign>d__0.<>1__state""
IL_0006: stloc.0
.try
{
IL_0007: ldloc.0
IL_0008: brfalse.s IL_0043
IL_000a: ldstr ""RHS""
IL_000f: call ""System.Threading.Tasks.Task<int> Program.Write(string)""
IL_0014: callvirt ""System.Runtime.CompilerServices.TaskAwaiter<int> System.Threading.Tasks.Task<int>.GetAwaiter()""
IL_0019: stloc.2
IL_001a: ldloca.s V_2
IL_001c: call ""bool System.Runtime.CompilerServices.TaskAwaiter<int>.IsCompleted.get""
IL_0021: brtrue.s IL_005f
IL_0023: ldarg.0
IL_0024: ldc.i4.0
IL_0025: dup
IL_0026: stloc.0
IL_0027: stfld ""int Program.<Assign>d__0.<>1__state""
IL_002c: ldarg.0
IL_002d: ldloc.2
IL_002e: stfld ""System.Runtime.CompilerServices.TaskAwaiter<int> Program.<Assign>d__0.<>u__1""
IL_0033: ldarg.0
IL_0034: ldflda ""System.Runtime.CompilerServices.AsyncTaskMethodBuilder Program.<Assign>d__0.<>t__builder""
IL_0039: ldloca.s V_2
IL_003b: ldarg.0
IL_003c: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.AwaitUnsafeOnCompleted<System.Runtime.CompilerServices.TaskAwaiter<int>, Program.<Assign>d__0>(ref System.Runtime.CompilerServices.TaskAwaiter<int>, ref Program.<Assign>d__0)""
IL_0041: leave.s IL_009e
IL_0043: ldarg.0
IL_0044: ldfld ""System.Runtime.CompilerServices.TaskAwaiter<int> Program.<Assign>d__0.<>u__1""
IL_0049: stloc.2
IL_004a: ldarg.0
IL_004b: ldflda ""System.Runtime.CompilerServices.TaskAwaiter<int> Program.<Assign>d__0.<>u__1""
IL_0050: initobj ""System.Runtime.CompilerServices.TaskAwaiter<int>""
IL_0056: ldarg.0
IL_0057: ldc.i4.m1
IL_0058: dup
IL_0059: stloc.0
IL_005a: stfld ""int Program.<Assign>d__0.<>1__state""
IL_005f: ldloca.s V_2
IL_0061: call ""int System.Runtime.CompilerServices.TaskAwaiter<int>.GetResult()""
IL_0066: stloc.1
IL_0067: ldsflda ""B A.b""
IL_006c: ldloc.1
IL_006d: stfld ""int B.x""
IL_0072: leave.s IL_008b
}
catch System.Exception
{
IL_0074: stloc.3
IL_0075: ldarg.0
IL_0076: ldc.i4.s -2
IL_0078: stfld ""int Program.<Assign>d__0.<>1__state""
IL_007d: ldarg.0
IL_007e: ldflda ""System.Runtime.CompilerServices.AsyncTaskMethodBuilder Program.<Assign>d__0.<>t__builder""
IL_0083: ldloc.3
IL_0084: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.SetException(System.Exception)""
IL_0089: leave.s IL_009e
}
IL_008b: ldarg.0
IL_008c: ldc.i4.s -2
IL_008e: stfld ""int Program.<Assign>d__0.<>1__state""
IL_0093: ldarg.0
IL_0094: ldflda ""System.Runtime.CompilerServices.AsyncTaskMethodBuilder Program.<Assign>d__0.<>t__builder""
IL_0099: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.SetResult()""
IL_009e: ret
}"
);
}
}
}
src/Compilers/VisualBasic/Portable/Lowering/AsyncRewriter/AsyncRewriter.AsyncMethodToClassRewriter.Expressions.vb
浏览文件 @
b18cb030
...
...
@@ -235,7 +235,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic
Dim
builder
As
New
SpillBuilder
()
Debug
.
Assert
(
left
.
IsLValue
)
Dim
spilledLeft
As
BoundExpression
=
SpillLValue
(
left
,
isReceiver
:
=
False
,
builder
:
=
builder
)
Dim
spilledLeft
As
BoundExpression
=
SpillLValue
(
left
,
isReceiver
:
=
False
,
evaluateSideEffects
:
=
True
,
builder
:
=
builder
,
isAssignmentTarget
:
=
True
)
Dim
rightAsSpillSequence
=
DirectCast
(
right
,
BoundSpillSequence
)
builder
.
AddSpill
(
rightAsSpillSequence
)
...
...
@@ -565,7 +565,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic
' to enforce order of evaluation and to decrease the size of the code that we will duplicate (1 - receiver evaluation during capture,
' 2 - value type receiver evaluation).
If
Not
receiver
.
Type
.
IsReferenceType
Then
receiver
=
SpillValue
(
receiver
,
isReceiver
:
=
True
,
builder
:
=
builder
)
receiver
=
SpillValue
(
receiver
,
isReceiver
:
=
True
,
evaluateSideEffects
:
=
True
,
builder
:
=
builder
)
End
If
' If receiver is not spilled, we can use a local to capture receiver's value. If receiver is spilled, use SpillRValue to accomplish this
...
...
@@ -600,7 +600,7 @@ Namespace Microsoft.CodeAnalysis.VisualBasic
End
If
Else
Debug
.
Assert
(
conditionalAccessReceiverPlaceholderReplacementInfo
.
IsSpilled
)
placeholderReplacement
=
SpillValue
(
receiver
,
isReceiver
:
=
True
,
builder
:
=
builder
)
placeholderReplacement
=
SpillValue
(
receiver
,
isReceiver
:
=
True
,
evaluateSideEffects
:
=
True
,
builder
:
=
builder
)
nullCheckTarget
=
placeholderReplacement
.
MakeRValue
()
End
If
Else
...
...
src/Compilers/VisualBasic/Portable/Lowering/AsyncRewriter/AsyncRewriter.AsyncMethodToClassRewriter.Spilling.vb
浏览文件 @
b18cb030
...
...
@@ -218,7 +218,10 @@ Namespace Microsoft.CodeAnalysis.VisualBasic
End
If
Else
' We are to the left of an await-containing expression. Spill the arg.
newExpression
=
SpillValue
(
arg
,
isReceiver
:
=
(
index
=
0
AndAlso
firstArgumentIsAReceiverOfAMethodCall
),
builder
:
=
builder
)
newExpression
=
SpillValue
(
arg
,
isReceiver
:
=
(
index
=
0
AndAlso
firstArgumentIsAReceiverOfAMethodCall
),
evaluateSideEffects
:
=
True
,
builder
:
=
builder
)
End
If
newArgs
(
index
)
=
newExpression
...
...
@@ -232,22 +235,22 @@ Namespace Microsoft.CodeAnalysis.VisualBasic
End
Function
Private
Function
SpillValue
(
expr
As
BoundExpression
,
<
[
In
]
,
Out
>
ByRef
builder
As
SpillBuilder
)
As
BoundExpression
Return
SpillValue
(
expr
,
isReceiver
:
=
False
,
builder
:
=
builder
)
Return
SpillValue
(
expr
,
isReceiver
:
=
False
,
evaluateSideEffects
:
=
True
,
builder
:
=
builder
)
End
Function
Private
Function
SpillValue
(
expr
As
BoundExpression
,
isReceiver
As
Boolean
,
<
[
In
]
,
Out
>
ByRef
builder
As
SpillBuilder
)
As
BoundExpression
Private
Function
SpillValue
(
expr
As
BoundExpression
,
isReceiver
As
Boolean
,
evaluateSideEffects
As
Boolean
,
<
[
In
]
,
Out
>
ByRef
builder
As
SpillBuilder
)
As
BoundExpression
If
Unspillable
(
expr
)
Then
Return
expr
ElseIf
isReceiver
OrElse
expr
.
IsLValue
Then
Return
SpillLValue
(
expr
,
isReceiver
,
builder
)
Return
SpillLValue
(
expr
,
isReceiver
,
evaluateSideEffects
,
builder
)
Else
Return
SpillRValue
(
expr
,
builder
)
End
If
End
Function
Private
Function
SpillLValue
(
expr
As
BoundExpression
,
isReceiver
As
Boolean
,
<
[
In
]
,
Out
>
ByRef
builder
As
SpillBuilder
)
As
BoundExpression
Private
Function
SpillLValue
(
expr
As
BoundExpression
,
isReceiver
As
Boolean
,
evaluateSideEffects
As
Boolean
,
<
[
In
]
,
Out
>
ByRef
builder
As
SpillBuilder
,
Optional
isAssignmentTarget
As
Boolean
=
False
)
As
BoundExpression
Debug
.
Assert
(
expr
IsNot
Nothing
)
Debug
.
Assert
(
isReceiver
OrElse
expr
.
IsLValue
)
...
...
@@ -277,13 +280,13 @@ Namespace Microsoft.CodeAnalysis.VisualBasic
Next
End
If
Return
SpillLValue
(
sequence
.
ValueOpt
,
isReceiver
,
builder
)
Return
SpillLValue
(
sequence
.
ValueOpt
,
evaluateSideEffects
,
isReceiver
,
builder
)
Case
BoundKind
.
SpillSequence
Dim
spill
=
DirectCast
(
expr
,
BoundSpillSequence
)
builder
.
AddSpill
(
spill
)
Debug
.
Assert
(
spill
.
ValueOpt
IsNot
Nothing
)
Return
SpillLValue
(
spill
.
ValueOpt
,
isReceiver
,
builder
)
Return
SpillLValue
(
spill
.
ValueOpt
,
isReceiver
,
evaluateSideEffects
,
builder
)
Case
BoundKind
.
ArrayAccess
Dim
array
=
DirectCast
(
expr
,
BoundArrayAccess
)
...
...
@@ -298,8 +301,10 @@ Namespace Microsoft.CodeAnalysis.VisualBasic
array
=
array
.
Update
(
spilledExpression
,
spilledIndices
.
AsImmutableOrNull
,
array
.
IsLValue
,
array
.
Type
)
' Make sure side effects are checked
builder
.
AddStatement
(
Me
.
F
.
ExpressionStatement
(
array
))
' An assignment target is only evaluated on write, so don't evaluate it's side effects
If
evaluateSideEffects
And
Not
isAssignmentTarget
Then
builder
.
AddStatement
(
Me
.
F
.
ExpressionStatement
(
array
))
End
If
Return
array
...
...
@@ -310,7 +315,14 @@ Namespace Microsoft.CodeAnalysis.VisualBasic
Return
fieldAccess
End
If
Dim
newReceiver
As
BoundExpression
=
SpillValue
(
fieldAccess
.
ReceiverOpt
,
isReceiver
:
=
True
,
builder
:
=
builder
)
' An assignment target is only evaluated on write, so don't evaluate it's side effects, but do evaluate side effects of the reciever expression
' Evaluating a field of a struct has no side effects, so only evaluate side effects of the reciever expression
Dim
evaluateSideEffectsHere
=
evaluateSideEffects
And
Not
isAssignmentTarget
And
fieldAccess
.
FieldSymbol
.
ContainingType
.
IsReferenceType
Dim
newReceiver
As
BoundExpression
=
SpillValue
(
fieldAccess
.
ReceiverOpt
,
isReceiver
:
=
True
,
evaluateSideEffects
:
=
evaluateSideEffects
And
Not
evaluateSideEffectsHere
,
builder
:
=
builder
)
fieldAccess
=
fieldAccess
.
Update
(
newReceiver
,
fieldAccess
.
FieldSymbol
,
...
...
@@ -319,8 +331,9 @@ Namespace Microsoft.CodeAnalysis.VisualBasic
fieldAccess
.
ConstantsInProgressOpt
,
fieldAccess
.
Type
)
' Make sure side effects are checked
builder
.
AddStatement
(
Me
.
F
.
ExpressionStatement
(
fieldAccess
))
If
evaluateSideEffectsHere
Then
builder
.
AddStatement
(
Me
.
F
.
ExpressionStatement
(
fieldAccess
))
End
If
Return
fieldAccess
...
...
src/Compilers/VisualBasic/Test/Emit/CodeGen/CodeGenAsyncTests.vb
浏览文件 @
b18cb030
...
...
@@ -2497,7 +2497,7 @@ End Module
c.VerifyIL("
Form1
.
VB
$
StateMachine_1_Test
.
MoveNext
",
<![CDATA[
{
// Code size 3
69 (0x171
)
// Code size 3
45 (0x159
)
.maxstack 4
.locals init (Integer V_0,
Integer V_1,
...
...
@@ -2510,7 +2510,7 @@ End Module
.try
{
IL_0007: ldloc.1
IL_0008: brfalse IL_00
e0
IL_0008: brfalse IL_00
c8
IL_000d: ldc.i4.2
IL_000e: ldc.i4.2
IL_000f: newobj "
Form1
.
S
(
*
,
*
).
.
ctor
"
...
...
@@ -2562,89 +2562,81 @@ End Module
IL_0086: ldfld "
Form1
.
VB
$
StateMachine_1_Test
.
$
U3
As
Integer
"
IL_008b: call "
Form1
.
S
(
*
,
*
).
Get
"
IL_0090: pop
IL_0091: ldarg.0
IL_0092: ldfld "
Form1
.
VB
$
StateMachine_1_Test
.
$
U1
As
Form1
.
S
(,)
"
IL_0097: ldarg.0
IL_0098: ldfld "
Form1
.
VB
$
StateMachine_1_Test
.
$
U2
As
Integer
"
IL_009d: ldarg.0
IL_009e: ldfld "
Form1
.
VB
$
StateMachine_1_Test
.
$
U3
As
Integer
"
IL_00a3: call "
Form1
.
S
(
*
,
*
).
Get
"
IL_00a8: pop
IL_00a9: call "
Function
Form1
.
F
()
As
System
.
Threading
.
Tasks
.
Task
(
Of
Integer
)
"
IL_00ae: callvirt "
Function
System
.
Threading
.
Tasks
.
Task
(
Of
Integer
).
GetAwaiter
()
As
System
.
Runtime
.
CompilerServices
.
TaskAwaiter
(
Of
Integer
)
"
IL_00b3: stloc.3
IL_00b4: ldloca.s V_3
IL_00b6: call "
Function
System
.
Runtime
.
CompilerServices
.
TaskAwaiter
(
Of
Integer
).
get_IsCompleted
()
As
Boolean
"
IL_00bb: brtrue.s IL_00fc
IL_0091: call "
Function
Form1
.
F
()
As
System
.
Threading
.
Tasks
.
Task
(
Of
Integer
)
"
IL_0096: callvirt "
Function
System
.
Threading
.
Tasks
.
Task
(
Of
Integer
).
GetAwaiter
()
As
System
.
Runtime
.
CompilerServices
.
TaskAwaiter
(
Of
Integer
)
"
IL_009b: stloc.3
IL_009c: ldloca.s V_3
IL_009e: call "
Function
System
.
Runtime
.
CompilerServices
.
TaskAwaiter
(
Of
Integer
).
get_IsCompleted
()
As
Boolean
"
IL_00a3: brtrue.s IL_00e4
IL_00a5: ldarg.0
IL_00a6: ldc.i4.0
IL_00a7: dup
IL_00a8: stloc.1
IL_00a9: stfld "
Form1
.
VB
$
StateMachine_1_Test
.
$
State
As
Integer
"
IL_00ae: ldarg.0
IL_00af: ldloc.3
IL_00b0: stfld "
Form1
.
VB
$
StateMachine_1_Test
.
$
A0
As
System
.
Runtime
.
CompilerServices
.
TaskAwaiter
(
Of
Integer
)
"
IL_00b5: ldarg.0
IL_00b6: ldflda "
Form1
.
VB
$
StateMachine_1_Test
.
$
Builder
As
System
.
Runtime
.
CompilerServices
.
AsyncTaskMethodBuilder
(
Of
Integer
)
"
IL_00bb: ldloca.s V_3
IL_00bd: ldarg.0
IL_00be: ldc.i4.0
IL_00bf: dup
IL_00c0: stloc.1
IL_00c1: stfld "
Form1
.
VB
$
StateMachine_1_Test
.
$
State
As
Integer
"
IL_00c6: ldarg.0
IL_00c7: ldloc.3
IL_00c8: stfld "
Form1
.
VB
$
StateMachine_1_Test
.
$
A0
As
System
.
Runtime
.
CompilerServices
.
TaskAwaiter
(
Of
Integer
)
"
IL_00cd: ldarg.0
IL_00ce: ldflda "
Form1
.
VB
$
StateMachine_1_Test
.
$
Builder
As
System
.
Runtime
.
CompilerServices
.
AsyncTaskMethodBuilder
(
Of
Integer
)
"
IL_00d3: ldloca.s V_3
IL_00d5: ldarg.0
IL_00d6: call "
Sub
System
.
Runtime
.
CompilerServices
.
AsyncTaskMethodBuilder
(
Of
Integer
).
AwaitUnsafeOnCompleted
(
Of
System
.
Runtime
.
CompilerServices
.
TaskAwaiter
(
Of
Integer
),
Form1
.
VB
$
StateMachine_1_Test
)(
ByRef
System
.
Runtime
.
CompilerServices
.
TaskAwaiter
(
Of
Integer
),
ByRef
Form1
.
VB
$
StateMachine_1_Test
)
"
IL_00db: leave IL_0170
IL_00e0: ldarg.0
IL_00e1: ldc.i4.m1
IL_00e2: dup
IL_00e3: stloc.1
IL_00e4: stfld "
Form1
.
VB
$
StateMachine_1_Test
.
$
State
As
Integer
"
IL_00e9: ldarg.0
IL_00ea: ldfld "
Form1
.
VB
$
StateMachine_1_Test
.
$
A0
As
System
.
Runtime
.
CompilerServices
.
TaskAwaiter
(
Of
Integer
)
"
IL_00ef: stloc.3
IL_00be: call "
Sub
System
.
Runtime
.
CompilerServices
.
AsyncTaskMethodBuilder
(
Of
Integer
).
AwaitUnsafeOnCompleted
(
Of
System
.
Runtime
.
CompilerServices
.
TaskAwaiter
(
Of
Integer
),
Form1
.
VB
$
StateMachine_1_Test
)(
ByRef
System
.
Runtime
.
CompilerServices
.
TaskAwaiter
(
Of
Integer
),
ByRef
Form1
.
VB
$
StateMachine_1_Test
)
"
IL_00c3: leave IL_0158
IL_00c8: ldarg.0
IL_00c9: ldc.i4.m1
IL_00ca: dup
IL_00cb: stloc.1
IL_00cc: stfld "
Form1
.
VB
$
StateMachine_1_Test
.
$
State
As
Integer
"
IL_00d1: ldarg.0
IL_00d2: ldfld "
Form1
.
VB
$
StateMachine_1_Test
.
$
A0
As
System
.
Runtime
.
CompilerServices
.
TaskAwaiter
(
Of
Integer
)
"
IL_00d7: stloc.3
IL_00d8: ldarg.0
IL_00d9: ldflda "
Form1
.
VB
$
StateMachine_1_Test
.
$
A0
As
System
.
Runtime
.
CompilerServices
.
TaskAwaiter
(
Of
Integer
)
"
IL_00de: initobj "
System
.
Runtime
.
CompilerServices
.
TaskAwaiter
(
Of
Integer
)
"
IL_00e4: ldarg.0
IL_00e5: ldfld "
Form1
.
VB
$
StateMachine_1_Test
.
$
U1
As
Form1
.
S
(,)
"
IL_00ea: ldarg.0
IL_00eb: ldfld "
Form1
.
VB
$
StateMachine_1_Test
.
$
U2
As
Integer
"
IL_00f0: ldarg.0
IL_00f1: ldflda "
Form1
.
VB
$
StateMachine_1_Test
.
$
A0
As
System
.
Runtime
.
CompilerServices
.
TaskAwaiter
(
Of
Integer
)
"
IL_00f6: initobj "
System
.
Runtime
.
CompilerServices
.
TaskAwaiter
(
Of
Integer
)
"
IL_00fc: ldarg.0
IL_00fd: ldfld "
Form1
.
VB
$
StateMachine_1_Test
.
$
U1
As
Form1
.
S
(,)
"
IL_0102: ldarg.0
IL_0103: ldfld "
Form1
.
VB
$
StateMachine_1_Test
.
$
U2
As
Integer
"
IL_0108: ldarg.0
IL_0109: ldfld "
Form1
.
VB
$
StateMachine_1_Test
.
$
U3
As
Integer
"
IL_010e: call "
Form1
.
S
(
*
,
*
).
Address
"
IL_0113: ldflda "
Form1
.
S
.
I
As
Integer
"
IL_0118: ldloca.s V_3
IL_011a: call "
Function
System
.
Runtime
.
CompilerServices
.
TaskAwaiter
(
Of
Integer
).
GetResult
()
As
Integer
"
IL_011f: ldloca.s V_3
IL_0121: initobj "
System
.
Runtime
.
CompilerServices
.
TaskAwaiter
(
Of
Integer
)
"
IL_0127: call "
Function
Form1
.
M
(
ByRef
Integer
,
Integer
)
As
Integer
"
IL_012c: stloc.0
IL_012d: ldarg.0
IL_012e: ldnull
IL_012f: stfld "
Form1
.
VB
$
StateMachine_1_Test
.
$
U1
As
Form1
.
S
(,)
"
IL_0134: leave.s IL_015a
IL_00f1: ldfld "
Form1
.
VB
$
StateMachine_1_Test
.
$
U3
As
Integer
"
IL_00f6: call "
Form1
.
S
(
*
,
*
).
Address
"
IL_00fb: ldflda "
Form1
.
S
.
I
As
Integer
"
IL_0100: ldloca.s V_3
IL_0102: call "
Function
System
.
Runtime
.
CompilerServices
.
TaskAwaiter
(
Of
Integer
).
GetResult
()
As
Integer
"
IL_0107: ldloca.s V_3
IL_0109: initobj "
System
.
Runtime
.
CompilerServices
.
TaskAwaiter
(
Of
Integer
)
"
IL_010f: call "
Function
Form1
.
M
(
ByRef
Integer
,
Integer
)
As
Integer
"
IL_0114: stloc.0
IL_0115: ldarg.0
IL_0116: ldnull
IL_0117: stfld "
Form1
.
VB
$
StateMachine_1_Test
.
$
U1
As
Form1
.
S
(,)
"
IL_011c: leave.s IL_0142
}
catch System.Exception
{
IL_01
36
: dup
IL_01
37
: call "
Sub
Microsoft
.
VisualBasic
.
CompilerServices
.
ProjectData
.
SetProjectError
(
System
.
Exception
)
"
IL_01
3c
: stloc.s V_4
IL_01
3e
: ldarg.0
IL_01
3f
: ldc.i4.s -2
IL_01
41
: stfld "
Form1
.
VB
$
StateMachine_1_Test
.
$
State
As
Integer
"
IL_01
46
: ldarg.0
IL_01
47
: ldflda "
Form1
.
VB
$
StateMachine_1_Test
.
$
Builder
As
System
.
Runtime
.
CompilerServices
.
AsyncTaskMethodBuilder
(
Of
Integer
)
"
IL_01
4c
: ldloc.s V_4
IL_01
4e
: call "
Sub
System
.
Runtime
.
CompilerServices
.
AsyncTaskMethodBuilder
(
Of
Integer
).
SetException
(
System
.
Exception
)
"
IL_01
53
: call "
Sub
Microsoft
.
VisualBasic
.
CompilerServices
.
ProjectData
.
ClearProjectError
()
"
IL_01
58: leave.s IL_0170
IL_01
1e
: dup
IL_01
1f
: call "
Sub
Microsoft
.
VisualBasic
.
CompilerServices
.
ProjectData
.
SetProjectError
(
System
.
Exception
)
"
IL_01
24
: stloc.s V_4
IL_01
26
: ldarg.0
IL_01
27
: ldc.i4.s -2
IL_01
29
: stfld "
Form1
.
VB
$
StateMachine_1_Test
.
$
State
As
Integer
"
IL_01
2e
: ldarg.0
IL_01
2f
: ldflda "
Form1
.
VB
$
StateMachine_1_Test
.
$
Builder
As
System
.
Runtime
.
CompilerServices
.
AsyncTaskMethodBuilder
(
Of
Integer
)
"
IL_01
34
: ldloc.s V_4
IL_01
36
: call "
Sub
System
.
Runtime
.
CompilerServices
.
AsyncTaskMethodBuilder
(
Of
Integer
).
SetException
(
System
.
Exception
)
"
IL_01
3b
: call "
Sub
Microsoft
.
VisualBasic
.
CompilerServices
.
ProjectData
.
ClearProjectError
()
"
IL_01
40: leave.s IL_0158
}
IL_01
5a
: ldarg.0
IL_01
5b
: ldc.i4.s -2
IL_01
5d
: dup
IL_01
5e
: stloc.1
IL_01
5f
: stfld "
Form1
.
VB
$
StateMachine_1_Test
.
$
State
As
Integer
"
IL_01
64
: ldarg.0
IL_01
65
: ldflda "
Form1
.
VB
$
StateMachine_1_Test
.
$
Builder
As
System
.
Runtime
.
CompilerServices
.
AsyncTaskMethodBuilder
(
Of
Integer
)
"
IL_01
6a
: ldloc.0
IL_01
6b
: call "
Sub
System
.
Runtime
.
CompilerServices
.
AsyncTaskMethodBuilder
(
Of
Integer
).
SetResult
(
Integer
)
"
IL_01
70
: ret
IL_01
42
: ldarg.0
IL_01
43
: ldc.i4.s -2
IL_01
45
: dup
IL_01
46
: stloc.1
IL_01
47
: stfld "
Form1
.
VB
$
StateMachine_1_Test
.
$
State
As
Integer
"
IL_01
4c
: ldarg.0
IL_01
4d
: ldflda "
Form1
.
VB
$
StateMachine_1_Test
.
$
Builder
As
System
.
Runtime
.
CompilerServices
.
AsyncTaskMethodBuilder
(
Of
Integer
)
"
IL_01
52
: ldloc.0
IL_01
53
: call "
Sub
System
.
Runtime
.
CompilerServices
.
AsyncTaskMethodBuilder
(
Of
Integer
).
SetResult
(
Integer
)
"
IL_01
58
: ret
}
]]>)
End Sub
...
...
@@ -9251,6 +9243,2203 @@ End Module"
Dim compilation = CreateCompilation(source, options:=TestOptions.ReleaseExe)
CompileAndVerify(compilation, expectedOutput:="
StructAwaitable
")
End Sub
<Fact>
<WorkItem(42755, "
https
:
//
github
.
com
/
dotnet
/
roslyn
/
issues
/
42755
")>
Public Sub KeepLtrSemantics_ClassFieldAccessOnProperty()
Dim source =
"
Imports
System
Imports
System.Threading.Tasks
Module
Program
Private
Async
Function
Assign
(
ByVal
a
As
A
)
As
Task
a
.
B
.
x
=
Await
Write
(
""
RHS
""
)
End
Function
Public
Sub
Main
(
ByVal
args
As
String
())
TestPropertyAccessThrows
().
Wait
()
TestFieldAccessThrows
().
Wait
()
TestPropertyAccessSucceeds
().
Wait
()
End
Sub
Private
Async
Function
TestPropertyAccessThrows
()
As
Task
Console
.
WriteLine
(
NameOf
(
Program
.
TestPropertyAccessThrows
))
Dim
a
As
A
=
Nothing
Console
.
WriteLine
(
""
Before
Assignment
""
)
Try
Await
Assign
(
a
)
Catch
__
As
NullReferenceException
Console
.
WriteLine
(
""C
aught
NullReferenceException
""
)
End
Try
End
Function
Private
Async
Function
TestFieldAccessThrows
()
As
Task
Console
.
WriteLine
(
NameOf
(
Program
.
TestFieldAccessThrows
))
Dim
a
=
New
A
()
Console
.
WriteLine
(
""
Before
Assignment
""
)
Try
Await
Assign
(
a
)
Catch
__
As
NullReferenceException
Console
.
WriteLine
(
""C
aught
NullReferenceException
""
)
End
Try
End
Function
Private
Async
Function
TestPropertyAccessSucceeds
()
As
Task
Console
.
WriteLine
(
NameOf
(
Program
.
TestPropertyAccessSucceeds
))
Dim
a
=
New
A
With
{
.
B
=
New
B
()
}
Console
.
WriteLine
(
""
Before
Assignment
a
.
B
.
x
is
:
""
&
a
.
B
.
x
)
Await
Assign
(
a
)
Console
.
WriteLine
(
""
After
Assignment
a
.
B
.
x
is
:
""
&
a
.
B
.
x
)
End
Function
Private
Async
Function
Write
(
ByVal
s
As
String
)
As
Task
(
Of
Integer
)
Await
Task
.
Yield
()
Console
.
WriteLine
(
s
)
Return
42
End
Function
End
Module
Class
A
Public
Property
B
As
B
End
Class
Class
B
Public
x
As
Integer
End
Class
"
Dim comp = CreateCompilation(source, options:=TestOptions.ReleaseExe)
CompileAndVerify(comp, expectedOutput:="
TestPropertyAccessThrows
Before
Assignment
Caught
NullReferenceException
TestFieldAccessThrows
Before
Assignment
RHS
Caught
NullReferenceException
TestPropertyAccessSucceeds
Before
Assignment
a
.
B
.
x
is
:
0
RHS
After
Assignment
a
.
B
.
x
is
:
42
").VerifyIL("
Program
.
VB
$
StateMachine_0_Assign
.
MoveNext
", "
{
//
Code
size
203
(
0
xcb
)
.
maxstack
3
.
locals
init
(
Integer
V_0
,
System
.
Runtime
.
CompilerServices
.
TaskAwaiter
(
Of
Integer
)
V_1
,
System
.
Exception
V_2
)
IL_0000
:
ldarg
.
0
IL_0001
:
ldfld
""
Program
.
VB
$
StateMachine_0_Assign
.
$
State
As
Integer
""
IL_0006
:
stloc
.
0
.
try
{
IL_0007
:
ldloc
.
0
IL_0008
:
brfalse
.
s
IL_0054
IL_000a
:
ldarg
.
0
IL_000b
:
ldarg
.
0
IL_000c
:
ldfld
""
Program
.
VB
$
StateMachine_0_Assign
.
$
VB
$
Local_a
As
A
""
IL_0011
:
callvirt
""
Function
A
.
get_B
()
As
B
""
IL_0016
:
stfld
""
Program
.
VB
$
StateMachine_0_Assign
.
$
U1
As
B
""
IL_001b
:
ldstr
""
RHS
""
IL_0020
:
call
""
Function
Program
.
Write
(
String
)
As
System
.
Threading
.
Tasks
.
Task
(
Of
Integer
)
""
IL_0025
:
callvirt
""
Function
System
.
Threading
.
Tasks
.
Task
(
Of
Integer
).
GetAwaiter
()
As
System
.
Runtime
.
CompilerServices
.
TaskAwaiter
(
Of
Integer
)
""
IL_002a
:
stloc
.
1
IL_002b
:
ldloca
.
s
V_1
IL_002d
:
call
""
Function
System
.
Runtime
.
CompilerServices
.
TaskAwaiter
(
Of
Integer
).
get_IsCompleted
()
As
Boolean
""
IL_0032
:
brtrue
.
s
IL_0070
IL_0034
:
ldarg
.
0
IL_0035
:
ldc
.
i4
.
0
IL_0036
:
dup
IL_0037
:
stloc
.
0
IL_0038
:
stfld
""
Program
.
VB
$
StateMachine_0_Assign
.
$
State
As
Integer
""
IL_003d
:
ldarg
.
0
IL_003e
:
ldloc
.
1
IL_003f
:
stfld
""
Program
.
VB
$
StateMachine_0_Assign
.
$
A0
As
System
.
Runtime
.
CompilerServices
.
TaskAwaiter
(
Of
Integer
)
""
IL_0044
:
ldarg
.
0
IL_0045
:
ldflda
""
Program
.
VB
$
StateMachine_0_Assign
.
$
Builder
As
System
.
Runtime
.
CompilerServices
.
AsyncTaskMethodBuilder
""
IL_004a
:
ldloca
.
s
V_1
IL_004c
:
ldarg
.
0
IL_004d
:
call
""
Sub
System
.
Runtime
.
CompilerServices
.
AsyncTaskMethodBuilder
.
AwaitUnsafeOnCompleted
(
Of
System
.
Runtime
.
CompilerServices
.
TaskAwaiter
(
Of
Integer
),
Program
.
VB
$
StateMachine_0_Assign
)(
ByRef
System
.
Runtime
.
CompilerServices
.
TaskAwaiter
(
Of
Integer
),
ByRef
Program
.
VB
$
StateMachine_0_Assign
)
""
IL_0052
:
leave
.
s
IL_00ca
IL_0054
:
ldarg
.
0
IL_0055
:
ldc
.
i4
.
m1
IL_0056
:
dup
IL_0057
:
stloc
.
0
IL_0058
:
stfld
""
Program
.
VB
$
StateMachine_0_Assign
.
$
State
As
Integer
""
IL_005d
:
ldarg
.
0
IL_005e
:
ldfld
""
Program
.
VB
$
StateMachine_0_Assign
.
$
A0
As
System
.
Runtime
.
CompilerServices
.
TaskAwaiter
(
Of
Integer
)
""
IL_0063
:
stloc
.
1
IL_0064
:
ldarg
.
0
IL_0065
:
ldflda
""
Program
.
VB
$
StateMachine_0_Assign
.
$
A0
As
System
.
Runtime
.
CompilerServices
.
TaskAwaiter
(
Of
Integer
)
""
IL_006a
:
initobj
""
System
.
Runtime
.
CompilerServices
.
TaskAwaiter
(
Of
Integer
)
""
IL_0070
:
ldarg
.
0
IL_0071
:
ldfld
""
Program
.
VB
$
StateMachine_0_Assign
.
$
U1
As
B
""
IL_0076
:
ldloca
.
s
V_1
IL_0078
:
call
""
Function
System
.
Runtime
.
CompilerServices
.
TaskAwaiter
(
Of
Integer
).
GetResult
()
As
Integer
""
IL_007d
:
ldloca
.
s
V_1
IL_007f
:
initobj
""
System
.
Runtime
.
CompilerServices
.
TaskAwaiter
(
Of
Integer
)
""
IL_0085
:
stfld
""
B
.
x
As
Integer
""
IL_008a
:
ldarg
.
0
IL_008b
:
ldnull
IL_008c
:
stfld
""
Program
.
VB
$
StateMachine_0_Assign
.
$
U1
As
B
""
IL_0091
:
leave
.
s
IL_00b5
}
catch
System
.
Exception
{
IL_0093
:
dup
IL_0094
:
call
""
Sub
Microsoft
.
VisualBasic
.
CompilerServices
.
ProjectData
.
SetProjectError
(
System
.
Exception
)
""
IL_0099
:
stloc
.
2
IL_009a
:
ldarg
.
0
IL_009b
:
ldc
.
i4
.
s
-
2
IL_009d
:
stfld
""
Program
.
VB
$
StateMachine_0_Assign
.
$
State
As
Integer
""
IL_00a2
:
ldarg
.
0
IL_00a3
:
ldflda
""
Program
.
VB
$
StateMachine_0_Assign
.
$
Builder
As
System
.
Runtime
.
CompilerServices
.
AsyncTaskMethodBuilder
""
IL_00a8
:
ldloc
.
2
IL_00a9
:
call
""
Sub
System
.
Runtime
.
CompilerServices
.
AsyncTaskMethodBuilder
.
SetException
(
System
.
Exception
)
""
IL_00ae
:
call
""
Sub
Microsoft
.
VisualBasic
.
CompilerServices
.
ProjectData
.
ClearProjectError
()
""
IL_00b3
:
leave
.
s
IL_00ca
}
IL_00b5
:
ldarg
.
0
IL_00b6
:
ldc
.
i4
.
s
-
2
IL_00b8
:
dup
IL_00b9
:
stloc
.
0
IL_00ba
:
stfld
""
Program
.
VB
$
StateMachine_0_Assign
.
$
State
As
Integer
""
IL_00bf
:
ldarg
.
0
IL_00c0
:
ldflda
""
Program
.
VB
$
StateMachine_0_Assign
.
$
Builder
As
System
.
Runtime
.
CompilerServices
.
AsyncTaskMethodBuilder
""
IL_00c5
:
call
""
Sub
System
.
Runtime
.
CompilerServices
.
AsyncTaskMethodBuilder
.
SetResult
()
""
IL_00ca
:
ret
}
")
End Sub
<Fact>
<WorkItem(42755, "
https
:
//
github
.
com
/
dotnet
/
roslyn
/
issues
/
42755
")>
Public Sub KeepLtrSemantics_ClassFieldAccessOnArray()
Dim source =
"
Imports
System
Imports
System.Threading.Tasks
Module
Program
Private
Async
Function
Assign
(
ByVal
arr
As
A
())
As
Task
arr
(
0
).
x
=
Await
Write
(
""
RHS
""
)
End
Function
Public
Sub
Main
(
ByVal
args
As
String
())
TestIndexerThrows
().
Wait
()
TestAssignmentThrows
().
Wait
()
TestIndexerSucceeds
().
Wait
()
TestReassignsArrayAndIndexerDuringAwait
().
Wait
()
TestReassignsTargetDuringAwait
().
Wait
()
End
Sub
Private
Async
Function
TestIndexerThrows
()
As
Task
Console
.
WriteLine
(
NameOf
(
Program
.
TestIndexerThrows
))
Dim
arr
=
New
A
(
-
1
)
{}
Console
.
WriteLine
(
""
Before
Assignment
""
)
Try
Await
Assign
(
arr
)
Catch
__unusedIndexOutOfRangeException1__
As
IndexOutOfRangeException
Console
.
WriteLine
(
""C
aught
IndexOutOfRangeException
""
)
End
Try
End
Function
Private
Async
Function
TestAssignmentThrows
()
As
Task
Console
.
WriteLine
(
NameOf
(
Program
.
TestAssignmentThrows
))
Dim
arr
=
New
A
(
0
)
{}
Console
.
WriteLine
(
""
Before
Assignment
""
)
Try
Await
Assign
(
arr
)
Catch
__
As
NullReferenceException
Console
.
WriteLine
(
""C
aught
NullReferenceException
""
)
End
Try
End
Function
Private
Async
Function
TestIndexerSucceeds
()
As
Task
Console
.
WriteLine
(
NameOf
(
Program
.
TestIndexerSucceeds
))
Dim
arr
=
New
A
(
0
)
{
New
A
()}
Console
.
WriteLine
(
""
Before
Assignment
arr
[
0
]
.
x
is
:
""
&
arr
(
0
).
x
)
Await
Assign
(
arr
)
Console
.
WriteLine
(
""
After
Assignment
arr
[
0
]
.
x
is
:
""
&
arr
(
0
).
x
)
End
Function
Private
Async
Function
TestReassignsArrayAndIndexerDuringAwait
()
As
Task
Console
.
WriteLine
(
NameOf
(
Program
.
TestReassignsArrayAndIndexerDuringAwait
))
Dim
a
=
New
A
()
Dim
arr
=
New
A
(
0
)
{
a
}
Dim
index
=
0
Console
.
WriteLine
(
""
Before
Assignment
arr
.
Length
is
:
""
&
arr
.
Length
)
Console
.
WriteLine
(
""
Before
Assignment
a
.
x
is
:
""
&
a
.
x
)
Dim
WriteAndReassign
As
Func
(
Of
String
,
Task
(
Of
Integer
))
=
Async
Function
(
ByVal
s
As
String
)
Await
Task
.
Yield
()
arr
=
New
A
(
-
1
)
{}
index
=
1
Console
.
WriteLine
(
s
)
Return
42
End
Function
arr
(
index
).
x
=
Await
WriteAndReassign
(
""
RHS
""
)
Console
.
WriteLine
(
""
After
Assignment
arr
.
Length
is
:
""
&
arr
.
Length
)
Console
.
WriteLine
(
""
After
Assignment
a
.
x
is
:
""
&
a
.
x
)
End
Function
Private
Async
Function
TestReassignsTargetDuringAwait
()
As
Task
Console
.
WriteLine
(
NameOf
(
Program
.
TestReassignsTargetDuringAwait
))
Dim
a
=
New
A
()
Dim
arr
=
New
A
(
0
)
{
a
}
Console
.
WriteLine
(
""
Before
Assignment
arr
[
0
]
.
x
is
:
""
&
arr
(
0
).
x
)
Console
.
WriteLine
(
""
Before
Assignment
arr
[
0
]
.
y
is
:
""
&
arr
(
0
).
y
)
Console
.
WriteLine
(
""
Before
Assignment
a
.
x
is
:
""
&
a
.
x
)
Dim
WriteAndReassign
As
Func
(
Of
String
,
Task
(
Of
Integer
))
=
Async
Function
(
ByVal
s
As
String
)
Await
Task
.
Yield
()
arr
(
0
)
=
New
A
With
{
.
y
=
True
}
Console
.
WriteLine
(
s
)
Return
42
End
Function
arr
(
0
).
x
=
Await
WriteAndReassign
(
""
RHS
""
)
Console
.
WriteLine
(
""
After
Assignment
arr
[
0
]
.
x
is
:
""
&
arr
(
0
).
x
)
Console
.
WriteLine
(
""
After
Assignment
arr
[
0
]
.
y
is
:
""
&
arr
(
0
).
y
)
Console
.
WriteLine
(
""
After
Assignment
a
.
x
is
:
""
&
a
.
x
)
End
Function
Private
Async
Function
Write
(
ByVal
s
As
String
)
As
Task
(
Of
Integer
)
Await
Task
.
Yield
()
Console
.
WriteLine
(
s
)
Return
42
End
Function
End
Module
Class
A
Public
x
As
Integer
Public
y
As
Boolean
End
Class
"
Dim comp = CreateCompilation(source, options:=TestOptions.ReleaseExe)
CompileAndVerify(comp, expectedOutput:="
TestIndexerThrows
Before
Assignment
Caught
IndexOutOfRangeException
TestAssignmentThrows
Before
Assignment
RHS
Caught
NullReferenceException
TestIndexerSucceeds
Before
Assignment
arr
[
0
]
.
x
is
:
0
RHS
After
Assignment
arr
[
0
]
.
x
is
:
42
TestReassignsArrayAndIndexerDuringAwait
Before
Assignment
arr
.
Length
is
:
1
Before
Assignment
a
.
x
is
:
0
RHS
After
Assignment
arr
.
Length
is
:
0
After
Assignment
a
.
x
is
:
42
TestReassignsTargetDuringAwait
Before
Assignment
arr
[
0
]
.
x
is
:
0
Before
Assignment
arr
[
0
]
.
y
is
:
False
Before
Assignment
a
.
x
is
:
0
RHS
After
Assignment
arr
[
0
]
.
x
is
:
0
After
Assignment
arr
[
0
]
.
y
is
:
True
After
Assignment
a
.
x
is
:
42
").VerifyIL("
Program
.
VB
$
StateMachine_0_Assign
.
MoveNext
", "
{
//
Code
size
200
(
0
xc8
)
.
maxstack
3
.
locals
init
(
Integer
V_0
,
System
.
Runtime
.
CompilerServices
.
TaskAwaiter
(
Of
Integer
)
V_1
,
System
.
Exception
V_2
)
IL_0000
:
ldarg
.
0
IL_0001
:
ldfld
""
Program
.
VB
$
StateMachine_0_Assign
.
$
State
As
Integer
""
IL_0006
:
stloc
.
0
.
try
{
IL_0007
:
ldloc
.
0
IL_0008
:
brfalse
.
s
IL_0051
IL_000a
:
ldarg
.
0
IL_000b
:
ldarg
.
0
IL_000c
:
ldfld
""
Program
.
VB
$
StateMachine_0_Assign
.
$
VB
$
Local_arr
As
A
()
""
IL_0011
:
ldc
.
i4
.
0
IL_0012
:
ldelem
.
ref
IL_0013
:
stfld
""
Program
.
VB
$
StateMachine_0_Assign
.
$
U1
As
A
""
IL_0018
:
ldstr
""
RHS
""
IL_001d
:
call
""
Function
Program
.
Write
(
String
)
As
System
.
Threading
.
Tasks
.
Task
(
Of
Integer
)
""
IL_0022
:
callvirt
""
Function
System
.
Threading
.
Tasks
.
Task
(
Of
Integer
).
GetAwaiter
()
As
System
.
Runtime
.
CompilerServices
.
TaskAwaiter
(
Of
Integer
)
""
IL_0027
:
stloc
.
1
IL_0028
:
ldloca
.
s
V_1
IL_002a
:
call
""
Function
System
.
Runtime
.
CompilerServices
.
TaskAwaiter
(
Of
Integer
).
get_IsCompleted
()
As
Boolean
""
IL_002f
:
brtrue
.
s
IL_006d
IL_0031
:
ldarg
.
0
IL_0032
:
ldc
.
i4
.
0
IL_0033
:
dup
IL_0034
:
stloc
.
0
IL_0035
:
stfld
""
Program
.
VB
$
StateMachine_0_Assign
.
$
State
As
Integer
""
IL_003a
:
ldarg
.
0
IL_003b
:
ldloc
.
1
IL_003c
:
stfld
""
Program
.
VB
$
StateMachine_0_Assign
.
$
A0
As
System
.
Runtime
.
CompilerServices
.
TaskAwaiter
(
Of
Integer
)
""
IL_0041
:
ldarg
.
0
IL_0042
:
ldflda
""
Program
.
VB
$
StateMachine_0_Assign
.
$
Builder
As
System
.
Runtime
.
CompilerServices
.
AsyncTaskMethodBuilder
""
IL_0047
:
ldloca
.
s
V_1
IL_0049
:
ldarg
.
0
IL_004a
:
call
""
Sub
System
.
Runtime
.
CompilerServices
.
AsyncTaskMethodBuilder
.
AwaitUnsafeOnCompleted
(
Of
System
.
Runtime
.
CompilerServices
.
TaskAwaiter
(
Of
Integer
),
Program
.
VB
$
StateMachine_0_Assign
)(
ByRef
System
.
Runtime
.
CompilerServices
.
TaskAwaiter
(
Of
Integer
),
ByRef
Program
.
VB
$
StateMachine_0_Assign
)
""
IL_004f
:
leave
.
s
IL_00c7
IL_0051
:
ldarg
.
0
IL_0052
:
ldc
.
i4
.
m1
IL_0053
:
dup
IL_0054
:
stloc
.
0
IL_0055
:
stfld
""
Program
.
VB
$
StateMachine_0_Assign
.
$
State
As
Integer
""
IL_005a
:
ldarg
.
0
IL_005b
:
ldfld
""
Program
.
VB
$
StateMachine_0_Assign
.
$
A0
As
System
.
Runtime
.
CompilerServices
.
TaskAwaiter
(
Of
Integer
)
""
IL_0060
:
stloc
.
1
IL_0061
:
ldarg
.
0
IL_0062
:
ldflda
""
Program
.
VB
$
StateMachine_0_Assign
.
$
A0
As
System
.
Runtime
.
CompilerServices
.
TaskAwaiter
(
Of
Integer
)
""
IL_0067
:
initobj
""
System
.
Runtime
.
CompilerServices
.
TaskAwaiter
(
Of
Integer
)
""
IL_006d
:
ldarg
.
0
IL_006e
:
ldfld
""
Program
.
VB
$
StateMachine_0_Assign
.
$
U1
As
A
""
IL_0073
:
ldloca
.
s
V_1
IL_0075
:
call
""
Function
System
.
Runtime
.
CompilerServices
.
TaskAwaiter
(
Of
Integer
).
GetResult
()
As
Integer
""
IL_007a
:
ldloca
.
s
V_1
IL_007c
:
initobj
""
System
.
Runtime
.
CompilerServices
.
TaskAwaiter
(
Of
Integer
)
""
IL_0082
:
stfld
""
A
.
x
As
Integer
""
IL_0087
:
ldarg
.
0
IL_0088
:
ldnull
IL_0089
:
stfld
""
Program
.
VB
$
StateMachine_0_Assign
.
$
U1
As
A
""
IL_008e
:
leave
.
s
IL_00b2
}
catch
System
.
Exception
{
IL_0090
:
dup
IL_0091
:
call
""
Sub
Microsoft
.
VisualBasic
.
CompilerServices
.
ProjectData
.
SetProjectError
(
System
.
Exception
)
""
IL_0096
:
stloc
.
2
IL_0097
:
ldarg
.
0
IL_0098
:
ldc
.
i4
.
s
-
2
IL_009a
:
stfld
""
Program
.
VB
$
StateMachine_0_Assign
.
$
State
As
Integer
""
IL_009f
:
ldarg
.
0
IL_00a0
:
ldflda
""
Program
.
VB
$
StateMachine_0_Assign
.
$
Builder
As
System
.
Runtime
.
CompilerServices
.
AsyncTaskMethodBuilder
""
IL_00a5
:
ldloc
.
2
IL_00a6
:
call
""
Sub
System
.
Runtime
.
CompilerServices
.
AsyncTaskMethodBuilder
.
SetException
(
System
.
Exception
)
""
IL_00ab
:
call
""
Sub
Microsoft
.
VisualBasic
.
CompilerServices
.
ProjectData
.
ClearProjectError
()
""
IL_00b0
:
leave
.
s
IL_00c7
}
IL_00b2
:
ldarg
.
0
IL_00b3
:
ldc
.
i4
.
s
-
2
IL_00b5
:
dup
IL_00b6
:
stloc
.
0
IL_00b7
:
stfld
""
Program
.
VB
$
StateMachine_0_Assign
.
$
State
As
Integer
""
IL_00bc
:
ldarg
.
0
IL_00bd
:
ldflda
""
Program
.
VB
$
StateMachine_0_Assign
.
$
Builder
As
System
.
Runtime
.
CompilerServices
.
AsyncTaskMethodBuilder
""
IL_00c2
:
call
""
Sub
System
.
Runtime
.
CompilerServices
.
AsyncTaskMethodBuilder
.
SetResult
()
""
IL_00c7
:
ret
}
")
End Sub
<Fact>
<WorkItem(42755, "
https
:
//
github
.
com
/
dotnet
/
roslyn
/
issues
/
42755
")>
Public Sub KeepLtrSemantics_StructFieldAccessOnArray()
Dim source = "
Imports
System
Imports
System.Threading.Tasks
Module
Program
Private
Async
Function
Assign
(
ByVal
arr
As
A
())
As
Task
arr
(
0
).
x
=
Await
Write
(
""
RHS
""
)
End
Function
Public
Sub
Main
(
ByVal
args
As
String
())
TestIndexerThrows
().
Wait
()
TestIndexerSucceeds
().
Wait
()
TestReassignsArrayAndIndexerDuringAwait
().
Wait
()
TestReassignsTargetDuringAwait
().
Wait
()
End
Sub
Private
Async
Function
TestIndexerThrows
()
As
Task
Console
.
WriteLine
(
NameOf
(
Program
.
TestIndexerThrows
))
Dim
arr
=
New
A
(
-
1
)
{}
Console
.
WriteLine
(
""
Before
Assignment
""
)
Try
Await
Assign
(
arr
)
Catch
__unusedIndexOutOfRangeException1__
As
IndexOutOfRangeException
Console
.
WriteLine
(
""C
aught
IndexOutOfRangeException
""
)
End
Try
End
Function
Private
Async
Function
TestIndexerSucceeds
()
As
Task
Console
.
WriteLine
(
NameOf
(
Program
.
TestIndexerSucceeds
))
Dim
arr
=
New
A
(
0
)
{}
Console
.
WriteLine
(
""
Before
Assignment
arr
[
0
]
.
x
is
:
""
&
arr
(
0
).
x
)
Await
Assign
(
arr
)
Console
.
WriteLine
(
""
After
Assignment
arr
[
0
]
.
x
is
:
""
&
arr
(
0
).
x
)
End
Function
Private
Async
Function
TestReassignsArrayAndIndexerDuringAwait
()
As
Task
Console
.
WriteLine
(
NameOf
(
Program
.
TestReassignsArrayAndIndexerDuringAwait
))
Dim
arr
=
New
A
(
0
)
{}
Dim
arrCopy
=
arr
Dim
index
=
0
Console
.
WriteLine
(
""
Before
Assignment
arr
.
Length
is
:
""
&
arr
.
Length
)
Console
.
WriteLine
(
""
Before
Assignment
arrCopy
[
0
]
.
x
is
:
""
&
arrCopy
(
0
).
x
)
Dim
WriteAndReassign
As
Func
(
Of
String
,
Task
(
Of
Integer
))
=
Async
Function
(
ByVal
s
As
String
)
Await
Task
.
Yield
()
arr
=
New
A
(
-
1
)
{}
index
=
1
Console
.
WriteLine
(
s
)
Return
42
End
Function
arr
(
index
).
x
=
Await
WriteAndReassign
(
""
RHS
""
)
Console
.
WriteLine
(
""
After
Assignment
arr
.
Length
is
:
""
&
arr
.
Length
)
Console
.
WriteLine
(
""
After
Assignment
arrCopy
[
0
]
.
x
is
:
""
&
arrCopy
(
0
).
x
)
End
Function
Private
Async
Function
TestReassignsTargetDuringAwait
()
As
Task
Console
.
WriteLine
(
NameOf
(
Program
.
TestReassignsTargetDuringAwait
))
Dim
arr
=
New
A
(
0
)
{}
Console
.
WriteLine
(
""
Before
Assignment
arr
[
0
]
.
x
is
:
""
&
arr
(
0
).
x
)
Console
.
WriteLine
(
""
Before
Assignment
arr
[
0
]
.
y
is
:
""
&
arr
(
0
).
y
)
Dim
WriteAndReassign
As
Func
(
Of
String
,
Task
(
Of
Integer
))
=
Async
Function
(
ByVal
s
As
String
)
Await
Task
.
Yield
()
arr
(
0
)
=
New
A
With
{
.
y
=
True
}
Console
.
WriteLine
(
s
)
Return
42
End
Function
arr
(
0
).
x
=
Await
WriteAndReassign
(
""
RHS
""
)
Console
.
WriteLine
(
""
After
Assignment
arr
[
0
]
.
x
is
:
""
&
arr
(
0
).
x
)
Console
.
WriteLine
(
""
Before
Assignment
arr
[
0
]
.
y
is
:
""
&
arr
(
0
).
y
)
End
Function
Private
Async
Function
Write
(
ByVal
s
As
String
)
As
Task
(
Of
Integer
)
Await
Task
.
Yield
()
Console
.
WriteLine
(
s
)
Return
42
End
Function
End
Module
Structure
A
Public
x
As
Integer
Public
y
As
Boolean
End
Structure
"
Dim comp = CreateCompilation(source, options:=TestOptions.ReleaseExe)
CompileAndVerify(comp, expectedOutput:="
TestIndexerThrows
Before
Assignment
Caught
IndexOutOfRangeException
TestIndexerSucceeds
Before
Assignment
arr
[
0
]
.
x
is
:
0
RHS
After
Assignment
arr
[
0
]
.
x
is
:
42
TestReassignsArrayAndIndexerDuringAwait
Before
Assignment
arr
.
Length
is
:
1
Before
Assignment
arrCopy
[
0
]
.
x
is
:
0
RHS
After
Assignment
arr
.
Length
is
:
0
After
Assignment
arrCopy
[
0
]
.
x
is
:
42
TestReassignsTargetDuringAwait
Before
Assignment
arr
[
0
]
.
x
is
:
0
Before
Assignment
arr
[
0
]
.
y
is
:
False
RHS
After
Assignment
arr
[
0
]
.
x
is
:
42
Before
Assignment
arr
[
0
]
.
y
is
:
True
").VerifyIL("
Program
.
VB
$
StateMachine_0_Assign
.
MoveNext
", "
{
//
Code
size
217
(
0
xd9
)
.
maxstack
3
.
locals
init
(
Integer
V_0
,
System
.
Runtime
.
CompilerServices
.
TaskAwaiter
(
Of
Integer
)
V_1
,
System
.
Exception
V_2
)
IL_0000
:
ldarg
.
0
IL_0001
:
ldfld
""
Program
.
VB
$
StateMachine_0_Assign
.
$
State
As
Integer
""
IL_0006
:
stloc
.
0
.
try
{
IL_0007
:
ldloc
.
0
IL_0008
:
brfalse
.
s
IL_005c
IL_000a
:
ldarg
.
0
IL_000b
:
ldarg
.
0
IL_000c
:
ldfld
""
Program
.
VB
$
StateMachine_0_Assign
.
$
VB
$
Local_arr
As
A
()
""
IL_0011
:
stfld
""
Program
.
VB
$
StateMachine_0_Assign
.
$
U1
As
A
()
""
IL_0016
:
ldarg
.
0
IL_0017
:
ldfld
""
Program
.
VB
$
StateMachine_0_Assign
.
$
U1
As
A
()
""
IL_001c
:
ldc
.
i4
.
0
IL_001d
:
ldelema
""
A
""
IL_0022
:
pop
IL_0023
:
ldstr
""
RHS
""
IL_0028
:
call
""
Function
Program
.
Write
(
String
)
As
System
.
Threading
.
Tasks
.
Task
(
Of
Integer
)
""
IL_002d
:
callvirt
""
Function
System
.
Threading
.
Tasks
.
Task
(
Of
Integer
).
GetAwaiter
()
As
System
.
Runtime
.
CompilerServices
.
TaskAwaiter
(
Of
Integer
)
""
IL_0032
:
stloc
.
1
IL_0033
:
ldloca
.
s
V_1
IL_0035
:
call
""
Function
System
.
Runtime
.
CompilerServices
.
TaskAwaiter
(
Of
Integer
).
get_IsCompleted
()
As
Boolean
""
IL_003a
:
brtrue
.
s
IL_0078
IL_003c
:
ldarg
.
0
IL_003d
:
ldc
.
i4
.
0
IL_003e
:
dup
IL_003f
:
stloc
.
0
IL_0040
:
stfld
""
Program
.
VB
$
StateMachine_0_Assign
.
$
State
As
Integer
""
IL_0045
:
ldarg
.
0
IL_0046
:
ldloc
.
1
IL_0047
:
stfld
""
Program
.
VB
$
StateMachine_0_Assign
.
$
A0
As
System
.
Runtime
.
CompilerServices
.
TaskAwaiter
(
Of
Integer
)
""
IL_004c
:
ldarg
.
0
IL_004d
:
ldflda
""
Program
.
VB
$
StateMachine_0_Assign
.
$
Builder
As
System
.
Runtime
.
CompilerServices
.
AsyncTaskMethodBuilder
""
IL_0052
:
ldloca
.
s
V_1
IL_0054
:
ldarg
.
0
IL_0055
:
call
""
Sub
System
.
Runtime
.
CompilerServices
.
AsyncTaskMethodBuilder
.
AwaitUnsafeOnCompleted
(
Of
System
.
Runtime
.
CompilerServices
.
TaskAwaiter
(
Of
Integer
),
Program
.
VB
$
StateMachine_0_Assign
)(
ByRef
System
.
Runtime
.
CompilerServices
.
TaskAwaiter
(
Of
Integer
),
ByRef
Program
.
VB
$
StateMachine_0_Assign
)
""
IL_005a
:
leave
.
s
IL_00d8
IL_005c
:
ldarg
.
0
IL_005d
:
ldc
.
i4
.
m1
IL_005e
:
dup
IL_005f
:
stloc
.
0
IL_0060
:
stfld
""
Program
.
VB
$
StateMachine_0_Assign
.
$
State
As
Integer
""
IL_0065
:
ldarg
.
0
IL_0066
:
ldfld
""
Program
.
VB
$
StateMachine_0_Assign
.
$
A0
As
System
.
Runtime
.
CompilerServices
.
TaskAwaiter
(
Of
Integer
)
""
IL_006b
:
stloc
.
1
IL_006c
:
ldarg
.
0
IL_006d
:
ldflda
""
Program
.
VB
$
StateMachine_0_Assign
.
$
A0
As
System
.
Runtime
.
CompilerServices
.
TaskAwaiter
(
Of
Integer
)
""
IL_0072
:
initobj
""
System
.
Runtime
.
CompilerServices
.
TaskAwaiter
(
Of
Integer
)
""
IL_0078
:
ldarg
.
0
IL_0079
:
ldfld
""
Program
.
VB
$
StateMachine_0_Assign
.
$
U1
As
A
()
""
IL_007e
:
ldc
.
i4
.
0
IL_007f
:
ldelema
""
A
""
IL_0084
:
ldloca
.
s
V_1
IL_0086
:
call
""
Function
System
.
Runtime
.
CompilerServices
.
TaskAwaiter
(
Of
Integer
).
GetResult
()
As
Integer
""
IL_008b
:
ldloca
.
s
V_1
IL_008d
:
initobj
""
System
.
Runtime
.
CompilerServices
.
TaskAwaiter
(
Of
Integer
)
""
IL_0093
:
stfld
""
A
.
x
As
Integer
""
IL_0098
:
ldarg
.
0
IL_0099
:
ldnull
IL_009a
:
stfld
""
Program
.
VB
$
StateMachine_0_Assign
.
$
U1
As
A
()
""
IL_009f
:
leave
.
s
IL_00c3
}
catch
System
.
Exception
{
IL_00a1
:
dup
IL_00a2
:
call
""
Sub
Microsoft
.
VisualBasic
.
CompilerServices
.
ProjectData
.
SetProjectError
(
System
.
Exception
)
""
IL_00a7
:
stloc
.
2
IL_00a8
:
ldarg
.
0
IL_00a9
:
ldc
.
i4
.
s
-
2
IL_00ab
:
stfld
""
Program
.
VB
$
StateMachine_0_Assign
.
$
State
As
Integer
""
IL_00b0
:
ldarg
.
0
IL_00b1
:
ldflda
""
Program
.
VB
$
StateMachine_0_Assign
.
$
Builder
As
System
.
Runtime
.
CompilerServices
.
AsyncTaskMethodBuilder
""
IL_00b6
:
ldloc
.
2
IL_00b7
:
call
""
Sub
System
.
Runtime
.
CompilerServices
.
AsyncTaskMethodBuilder
.
SetException
(
System
.
Exception
)
""
IL_00bc
:
call
""
Sub
Microsoft
.
VisualBasic
.
CompilerServices
.
ProjectData
.
ClearProjectError
()
""
IL_00c1
:
leave
.
s
IL_00d8
}
IL_00c3
:
ldarg
.
0
IL_00c4
:
ldc
.
i4
.
s
-
2
IL_00c6
:
dup
IL_00c7
:
stloc
.
0
IL_00c8
:
stfld
""
Program
.
VB
$
StateMachine_0_Assign
.
$
State
As
Integer
""
IL_00cd
:
ldarg
.
0
IL_00ce
:
ldflda
""
Program
.
VB
$
StateMachine_0_Assign
.
$
Builder
As
System
.
Runtime
.
CompilerServices
.
AsyncTaskMethodBuilder
""
IL_00d3
:
call
""
Sub
System
.
Runtime
.
CompilerServices
.
AsyncTaskMethodBuilder
.
SetResult
()
""
IL_00d8
:
ret
}
")
End Sub
<Fact>
<WorkItem(42755, "
https
:
//
github
.
com
/
dotnet
/
roslyn
/
issues
/
42755
")>
Public Sub KeepLtrSemantics_AssignmentToArray()
Dim source = "
Imports
System
Imports
System.Threading.Tasks
Module
Program
Private
Async
Function
Assign
(
ByVal
arr
As
Integer
())
As
Task
arr
(
0
)
=
Await
Write
(
""
RHS
""
)
End
Function
Public
Sub
Main
(
ByVal
args
As
String
())
TestIndexerThrows
().
Wait
()
TestIndexerSucceeds
().
Wait
()
TestReassignsArrayAndIndexerDuringAwait
().
Wait
()
End
Sub
Private
Async
Function
TestIndexerThrows
()
As
Task
Console
.
WriteLine
(
NameOf
(
Program
.
TestIndexerThrows
))
Dim
arr
=
New
Integer
(
-
1
)
{}
Console
.
WriteLine
(
""
Before
Assignment
""
)
Try
Await
Assign
(
arr
)
Catch
__unusedIndexOutOfRangeException1__
As
IndexOutOfRangeException
Console
.
WriteLine
(
""C
aught
IndexOutOfRangeException
""
)
End
Try
End
Function
Private
Async
Function
TestIndexerSucceeds
()
As
Task
Console
.
WriteLine
(
NameOf
(
Program
.
TestIndexerSucceeds
))
Dim
arr
=
New
Integer
(
0
)
{}
Console
.
WriteLine
(
""
Before
Assignment
arr
[
0
]
is
:
""
&
arr
(
0
))
Await
Assign
(
arr
)
Console
.
WriteLine
(
""
After
Assignment
arr
[
0
]
is
:
""
&
arr
(
0
))
End
Function
Private
Async
Function
TestReassignsArrayAndIndexerDuringAwait
()
As
Task
Console
.
WriteLine
(
NameOf
(
Program
.
TestReassignsArrayAndIndexerDuringAwait
))
Dim
arr
=
New
Integer
(
0
)
{}
Dim
arrCopy
=
arr
Dim
index
=
0
Console
.
WriteLine
(
""
Before
Assignment
arr
.
Length
is
:
""
&
arr
.
Length
)
Console
.
WriteLine
(
""
Before
Assignment
arrCopy
[
0
]
is
:
""
&
arrCopy
(
0
))
Dim
WriteAndReassign
As
Func
(
Of
String
,
Task
(
Of
Integer
))
=
Async
Function
(
ByVal
s
As
String
)
Await
Task
.
Yield
()
arr
=
New
Integer
(
-
1
)
{}
index
=
1
Console
.
WriteLine
(
s
)
Return
42
End
Function
arr
(
index
)
=
Await
WriteAndReassign
(
""
RHS
""
)
Console
.
WriteLine
(
""
After
Assignment
arr
.
Length
is
:
""
&
arr
.
Length
)
Console
.
WriteLine
(
""
After
Assignment
arrCopy
[
0
]
is
:
""
&
arrCopy
(
0
))
End
Function
Private
Async
Function
Write
(
ByVal
s
As
String
)
As
Task
(
Of
Integer
)
Await
Task
.
Yield
()
Console
.
WriteLine
(
s
)
Return
42
End
Function
End
Module
"
Dim comp = CreateCompilation(source, options:=TestOptions.ReleaseExe)
CompileAndVerify(comp, expectedOutput:="
TestIndexerThrows
Before
Assignment
RHS
Caught
IndexOutOfRangeException
TestIndexerSucceeds
Before
Assignment
arr
[
0
]
is
:
0
RHS
After
Assignment
arr
[
0
]
is
:
42
TestReassignsArrayAndIndexerDuringAwait
Before
Assignment
arr
.
Length
is
:
1
Before
Assignment
arrCopy
[
0
]
is
:
0
RHS
After
Assignment
arr
.
Length
is
:
0
After
Assignment
arrCopy
[
0
]
is
:
42
").VerifyIL("
Program
.
VB
$
StateMachine_0_Assign
.
MoveNext
", "
{
//
Code
size
195
(
0
xc3
)
.
maxstack
4
.
locals
init
(
Integer
V_0
,
System
.
Runtime
.
CompilerServices
.
TaskAwaiter
(
Of
Integer
)
V_1
,
System
.
Exception
V_2
)
IL_0000
:
ldarg
.
0
IL_0001
:
ldfld
""
Program
.
VB
$
StateMachine_0_Assign
.
$
State
As
Integer
""
IL_0006
:
stloc
.
0
.
try
{
IL_0007
:
ldloc
.
0
IL_0008
:
brfalse
.
s
IL_004f
IL_000a
:
ldarg
.
0
IL_000b
:
ldarg
.
0
IL_000c
:
ldfld
""
Program
.
VB
$
StateMachine_0_Assign
.
$
VB
$
Local_arr
As
Integer
()
""
IL_0011
:
stfld
""
Program
.
VB
$
StateMachine_0_Assign
.
$
U1
As
Integer
()
""
IL_0016
:
ldstr
""
RHS
""
IL_001b
:
call
""
Function
Program
.
Write
(
String
)
As
System
.
Threading
.
Tasks
.
Task
(
Of
Integer
)
""
IL_0020
:
callvirt
""
Function
System
.
Threading
.
Tasks
.
Task
(
Of
Integer
).
GetAwaiter
()
As
System
.
Runtime
.
CompilerServices
.
TaskAwaiter
(
Of
Integer
)
""
IL_0025
:
stloc
.
1
IL_0026
:
ldloca
.
s
V_1
IL_0028
:
call
""
Function
System
.
Runtime
.
CompilerServices
.
TaskAwaiter
(
Of
Integer
).
get_IsCompleted
()
As
Boolean
""
IL_002d
:
brtrue
.
s
IL_006b
IL_002f
:
ldarg
.
0
IL_0030
:
ldc
.
i4
.
0
IL_0031
:
dup
IL_0032
:
stloc
.
0
IL_0033
:
stfld
""
Program
.
VB
$
StateMachine_0_Assign
.
$
State
As
Integer
""
IL_0038
:
ldarg
.
0
IL_0039
:
ldloc
.
1
IL_003a
:
stfld
""
Program
.
VB
$
StateMachine_0_Assign
.
$
A0
As
System
.
Runtime
.
CompilerServices
.
TaskAwaiter
(
Of
Integer
)
""
IL_003f
:
ldarg
.
0
IL_0040
:
ldflda
""
Program
.
VB
$
StateMachine_0_Assign
.
$
Builder
As
System
.
Runtime
.
CompilerServices
.
AsyncTaskMethodBuilder
""
IL_0045
:
ldloca
.
s
V_1
IL_0047
:
ldarg
.
0
IL_0048
:
call
""
Sub
System
.
Runtime
.
CompilerServices
.
AsyncTaskMethodBuilder
.
AwaitUnsafeOnCompleted
(
Of
System
.
Runtime
.
CompilerServices
.
TaskAwaiter
(
Of
Integer
),
Program
.
VB
$
StateMachine_0_Assign
)(
ByRef
System
.
Runtime
.
CompilerServices
.
TaskAwaiter
(
Of
Integer
),
ByRef
Program
.
VB
$
StateMachine_0_Assign
)
""
IL_004d
:
leave
.
s
IL_00c2
IL_004f
:
ldarg
.
0
IL_0050
:
ldc
.
i4
.
m1
IL_0051
:
dup
IL_0052
:
stloc
.
0
IL_0053
:
stfld
""
Program
.
VB
$
StateMachine_0_Assign
.
$
State
As
Integer
""
IL_0058
:
ldarg
.
0
IL_0059
:
ldfld
""
Program
.
VB
$
StateMachine_0_Assign
.
$
A0
As
System
.
Runtime
.
CompilerServices
.
TaskAwaiter
(
Of
Integer
)
""
IL_005e
:
stloc
.
1
IL_005f
:
ldarg
.
0
IL_0060
:
ldflda
""
Program
.
VB
$
StateMachine_0_Assign
.
$
A0
As
System
.
Runtime
.
CompilerServices
.
TaskAwaiter
(
Of
Integer
)
""
IL_0065
:
initobj
""
System
.
Runtime
.
CompilerServices
.
TaskAwaiter
(
Of
Integer
)
""
IL_006b
:
ldarg
.
0
IL_006c
:
ldfld
""
Program
.
VB
$
StateMachine_0_Assign
.
$
U1
As
Integer
()
""
IL_0071
:
ldc
.
i4
.
0
IL_0072
:
ldloca
.
s
V_1
IL_0074
:
call
""
Function
System
.
Runtime
.
CompilerServices
.
TaskAwaiter
(
Of
Integer
).
GetResult
()
As
Integer
""
IL_0079
:
ldloca
.
s
V_1
IL_007b
:
initobj
""
System
.
Runtime
.
CompilerServices
.
TaskAwaiter
(
Of
Integer
)
""
IL_0081
:
stelem
.
i4
IL_0082
:
ldarg
.
0
IL_0083
:
ldnull
IL_0084
:
stfld
""
Program
.
VB
$
StateMachine_0_Assign
.
$
U1
As
Integer
()
""
IL_0089
:
leave
.
s
IL_00ad
}
catch
System
.
Exception
{
IL_008b
:
dup
IL_008c
:
call
""
Sub
Microsoft
.
VisualBasic
.
CompilerServices
.
ProjectData
.
SetProjectError
(
System
.
Exception
)
""
IL_0091
:
stloc
.
2
IL_0092
:
ldarg
.
0
IL_0093
:
ldc
.
i4
.
s
-
2
IL_0095
:
stfld
""
Program
.
VB
$
StateMachine_0_Assign
.
$
State
As
Integer
""
IL_009a
:
ldarg
.
0
IL_009b
:
ldflda
""
Program
.
VB
$
StateMachine_0_Assign
.
$
Builder
As
System
.
Runtime
.
CompilerServices
.
AsyncTaskMethodBuilder
""
IL_00a0
:
ldloc
.
2
IL_00a1
:
call
""
Sub
System
.
Runtime
.
CompilerServices
.
AsyncTaskMethodBuilder
.
SetException
(
System
.
Exception
)
""
IL_00a6
:
call
""
Sub
Microsoft
.
VisualBasic
.
CompilerServices
.
ProjectData
.
ClearProjectError
()
""
IL_00ab
:
leave
.
s
IL_00c2
}
IL_00ad
:
ldarg
.
0
IL_00ae
:
ldc
.
i4
.
s
-
2
IL_00b0
:
dup
IL_00b1
:
stloc
.
0
IL_00b2
:
stfld
""
Program
.
VB
$
StateMachine_0_Assign
.
$
State
As
Integer
""
IL_00b7
:
ldarg
.
0
IL_00b8
:
ldflda
""
Program
.
VB
$
StateMachine_0_Assign
.
$
Builder
As
System
.
Runtime
.
CompilerServices
.
AsyncTaskMethodBuilder
""
IL_00bd
:
call
""
Sub
System
.
Runtime
.
CompilerServices
.
AsyncTaskMethodBuilder
.
SetResult
()
""
IL_00c2
:
ret
}
")
End Sub
<Fact>
<WorkItem(42755, "
https
:
//
github
.
com
/
dotnet
/
roslyn
/
issues
/
42755
")>
Public Sub KeepLtrSemantics_StructFieldAccessOnStructFieldAccessOnClassField()
Dim source = "
Imports
System
Imports
System.Threading.Tasks
Module
Program
Private
Async
Function
Assign
(
ByVal
a
As
A
)
As
Task
a
.
b
.
c
.
x
=
Await
Write
(
""
RHS
""
)
End
Function
Public
Sub
Main
(
ByVal
args
As
String
())
TestAIsNull
().
Wait
()
TestAIsNotNull
().
Wait
()
ReassignADuringAssignment
().
Wait
()
End
Sub
Private
Async
Function
TestAIsNull
()
As
Task
Console
.
WriteLine
(
NameOf
(
Program
.
TestAIsNull
))
Dim
a
As
A
=
Nothing
Console
.
WriteLine
(
""
Before
Assignment
""
)
Try
Await
Assign
(
a
)
Catch
__
As
NullReferenceException
Console
.
WriteLine
(
""C
aught
NullReferenceException
""
)
End
Try
End
Function
Private
Async
Function
TestAIsNotNull
()
As
Task
Console
.
WriteLine
(
NameOf
(
Program
.
TestAIsNotNull
))
Dim
a
=
New
A
()
Console
.
WriteLine
(
""
Before
Assignment
a
.
b
.
c
.
x
is
:
""
&
a
.
b
.
c
.
x
)
Await
Assign
(
a
)
Console
.
WriteLine
(
""
After
Assignment
a
.
b
.
c
.
x
is
:
""
&
a
.
b
.
c
.
x
)
End
Function
Private
Async
Function
ReassignADuringAssignment
()
As
Task
Console
.
WriteLine
(
NameOf
(
Program
.
ReassignADuringAssignment
))
Dim
a
=
New
A
()
Dim
aCopy
=
a
Console
.
WriteLine
(
""
Before
Assignment
a
is
null
==
""
&
(
a
Is
Nothing
))
Console
.
WriteLine
(
""
Before
Assignment
aCopy
.
b
.
c
.
x
is
:
""
&
aCopy
.
b
.
c
.
x
)
Dim
WriteAndReassign
As
Func
(
Of
String
,
Task
(
Of
Integer
))
=
Async
Function
(
ByVal
s
As
String
)
Await
Task
.
Yield
()
a
=
Nothing
Console
.
WriteLine
(
s
)
Return
42
End
Function
a
.
b
.
c
.
x
=
Await
WriteAndReassign
(
""
RHS
""
)
Console
.
WriteLine
(
""
After
Assignment
a
is
null
==
""
&
(
a
Is
Nothing
))
Console
.
WriteLine
(
""
After
Assignment
aCopy
.
b
.
c
.
x
is
:
""
&
aCopy
.
b
.
c
.
x
)
End
Function
Private
Async
Function
Write
(
ByVal
s
As
String
)
As
Task
(
Of
Integer
)
Await
Task
.
Yield
()
Console
.
WriteLine
(
s
)
Return
42
End
Function
End
Module
Class
A
Public
b
As
B
End
Class
Structure
B
Public
c
As
C
End
Structure
Structure
C
Public
x
As
Integer
End
Structure
"
Dim comp = CreateCompilation(source, options:=TestOptions.ReleaseExe)
CompileAndVerify(comp, expectedOutput:="
TestAIsNull
Before
Assignment
Caught
NullReferenceException
TestAIsNotNull
Before
Assignment
a
.
b
.
c
.
x
is
:
0
RHS
After
Assignment
a
.
b
.
c
.
x
is
:
42
ReassignADuringAssignment
Before
Assignment
a
is
null
==
False
Before
Assignment
aCopy
.
b
.
c
.
x
is
:
0
RHS
After
Assignment
a
is
null
==
True
After
Assignment
aCopy
.
b
.
c
.
x
is
:
42
").VerifyIL("
Program
.
VB
$
StateMachine_0_Assign
.
MoveNext
", "
{
//
Code
size
223
(
0
xdf
)
.
maxstack
3
.
locals
init
(
Integer
V_0
,
System
.
Runtime
.
CompilerServices
.
TaskAwaiter
(
Of
Integer
)
V_1
,
System
.
Exception
V_2
)
IL_0000
:
ldarg
.
0
IL_0001
:
ldfld
""
Program
.
VB
$
StateMachine_0_Assign
.
$
State
As
Integer
""
IL_0006
:
stloc
.
0
.
try
{
IL_0007
:
ldloc
.
0
IL_0008
:
brfalse
.
s
IL_005e
IL_000a
:
ldarg
.
0
IL_000b
:
ldarg
.
0
IL_000c
:
ldfld
""
Program
.
VB
$
StateMachine_0_Assign
.
$
VB
$
Local_a
As
A
""
IL_0011
:
stfld
""
Program
.
VB
$
StateMachine_0_Assign
.
$
U1
As
A
""
IL_0016
:
ldarg
.
0
IL_0017
:
ldfld
""
Program
.
VB
$
StateMachine_0_Assign
.
$
U1
As
A
""
IL_001c
:
ldfld
""
A
.
b
As
B
""
IL_0021
:
pop
IL_0022
:
ldstr
""
RHS
""
IL_0027
:
call
""
Function
Program
.
Write
(
String
)
As
System
.
Threading
.
Tasks
.
Task
(
Of
Integer
)
""
IL_002c
:
callvirt
""
Function
System
.
Threading
.
Tasks
.
Task
(
Of
Integer
).
GetAwaiter
()
As
System
.
Runtime
.
CompilerServices
.
TaskAwaiter
(
Of
Integer
)
""
IL_0031
:
stloc
.
1
IL_0032
:
ldloca
.
s
V_1
IL_0034
:
call
""
Function
System
.
Runtime
.
CompilerServices
.
TaskAwaiter
(
Of
Integer
).
get_IsCompleted
()
As
Boolean
""
IL_0039
:
brtrue
.
s
IL_007a
IL_003b
:
ldarg
.
0
IL_003c
:
ldc
.
i4
.
0
IL_003d
:
dup
IL_003e
:
stloc
.
0
IL_003f
:
stfld
""
Program
.
VB
$
StateMachine_0_Assign
.
$
State
As
Integer
""
IL_0044
:
ldarg
.
0
IL_0045
:
ldloc
.
1
IL_0046
:
stfld
""
Program
.
VB
$
StateMachine_0_Assign
.
$
A0
As
System
.
Runtime
.
CompilerServices
.
TaskAwaiter
(
Of
Integer
)
""
IL_004b
:
ldarg
.
0
IL_004c
:
ldflda
""
Program
.
VB
$
StateMachine_0_Assign
.
$
Builder
As
System
.
Runtime
.
CompilerServices
.
AsyncTaskMethodBuilder
""
IL_0051
:
ldloca
.
s
V_1
IL_0053
:
ldarg
.
0
IL_0054
:
call
""
Sub
System
.
Runtime
.
CompilerServices
.
AsyncTaskMethodBuilder
.
AwaitUnsafeOnCompleted
(
Of
System
.
Runtime
.
CompilerServices
.
TaskAwaiter
(
Of
Integer
),
Program
.
VB
$
StateMachine_0_Assign
)(
ByRef
System
.
Runtime
.
CompilerServices
.
TaskAwaiter
(
Of
Integer
),
ByRef
Program
.
VB
$
StateMachine_0_Assign
)
""
IL_0059
:
leave
IL_00de
IL_005e
:
ldarg
.
0
IL_005f
:
ldc
.
i4
.
m1
IL_0060
:
dup
IL_0061
:
stloc
.
0
IL_0062
:
stfld
""
Program
.
VB
$
StateMachine_0_Assign
.
$
State
As
Integer
""
IL_0067
:
ldarg
.
0
IL_0068
:
ldfld
""
Program
.
VB
$
StateMachine_0_Assign
.
$
A0
As
System
.
Runtime
.
CompilerServices
.
TaskAwaiter
(
Of
Integer
)
""
IL_006d
:
stloc
.
1
IL_006e
:
ldarg
.
0
IL_006f
:
ldflda
""
Program
.
VB
$
StateMachine_0_Assign
.
$
A0
As
System
.
Runtime
.
CompilerServices
.
TaskAwaiter
(
Of
Integer
)
""
IL_0074
:
initobj
""
System
.
Runtime
.
CompilerServices
.
TaskAwaiter
(
Of
Integer
)
""
IL_007a
:
ldarg
.
0
IL_007b
:
ldfld
""
Program
.
VB
$
StateMachine_0_Assign
.
$
U1
As
A
""
IL_0080
:
ldflda
""
A
.
b
As
B
""
IL_0085
:
ldflda
""
B
.
c
As
C
""
IL_008a
:
ldloca
.
s
V_1
IL_008c
:
call
""
Function
System
.
Runtime
.
CompilerServices
.
TaskAwaiter
(
Of
Integer
).
GetResult
()
As
Integer
""
IL_0091
:
ldloca
.
s
V_1
IL_0093
:
initobj
""
System
.
Runtime
.
CompilerServices
.
TaskAwaiter
(
Of
Integer
)
""
IL_0099
:
stfld
""C
.
x
As
Integer
""
IL_009e
:
ldarg
.
0
IL_009f
:
ldnull
IL_00a0
:
stfld
""
Program
.
VB
$
StateMachine_0_Assign
.
$
U1
As
A
""
IL_00a5
:
leave
.
s
IL_00c9
}
catch
System
.
Exception
{
IL_00a7
:
dup
IL_00a8
:
call
""
Sub
Microsoft
.
VisualBasic
.
CompilerServices
.
ProjectData
.
SetProjectError
(
System
.
Exception
)
""
IL_00ad
:
stloc
.
2
IL_00ae
:
ldarg
.
0
IL_00af
:
ldc
.
i4
.
s
-
2
IL_00b1
:
stfld
""
Program
.
VB
$
StateMachine_0_Assign
.
$
State
As
Integer
""
IL_00b6
:
ldarg
.
0
IL_00b7
:
ldflda
""
Program
.
VB
$
StateMachine_0_Assign
.
$
Builder
As
System
.
Runtime
.
CompilerServices
.
AsyncTaskMethodBuilder
""
IL_00bc
:
ldloc
.
2
IL_00bd
:
call
""
Sub
System
.
Runtime
.
CompilerServices
.
AsyncTaskMethodBuilder
.
SetException
(
System
.
Exception
)
""
IL_00c2
:
call
""
Sub
Microsoft
.
VisualBasic
.
CompilerServices
.
ProjectData
.
ClearProjectError
()
""
IL_00c7
:
leave
.
s
IL_00de
}
IL_00c9
:
ldarg
.
0
IL_00ca
:
ldc
.
i4
.
s
-
2
IL_00cc
:
dup
IL_00cd
:
stloc
.
0
IL_00ce
:
stfld
""
Program
.
VB
$
StateMachine_0_Assign
.
$
State
As
Integer
""
IL_00d3
:
ldarg
.
0
IL_00d4
:
ldflda
""
Program
.
VB
$
StateMachine_0_Assign
.
$
Builder
As
System
.
Runtime
.
CompilerServices
.
AsyncTaskMethodBuilder
""
IL_00d9
:
call
""
Sub
System
.
Runtime
.
CompilerServices
.
AsyncTaskMethodBuilder
.
SetResult
()
""
IL_00de
:
ret
}
")
End Sub
<Fact>
<WorkItem(42755, "
https
:
//
github
.
com
/
dotnet
/
roslyn
/
issues
/
42755
")>
Public Sub KeepLtrSemantics_ClassPropertyAssignmentOnClassProperty()
Dim source = "
Imports
System
Imports
System.Threading.Tasks
Module
Program
Private
Async
Function
Assign
(
ByVal
a
As
A
)
As
Task
a
.
b
.
x
=
Await
Write
(
""
RHS
""
)
End
Function
Public
Sub
Main
(
ByVal
args
As
String
())
TestAIsNull
().
Wait
()
TestAIsNotNull
().
Wait
()
ReassignADuringAssignment
().
Wait
()
End
Sub
Private
Async
Function
TestAIsNull
()
As
Task
Console
.
WriteLine
(
NameOf
(
Program
.
TestAIsNull
))
Dim
a
As
A
=
Nothing
Console
.
WriteLine
(
""
Before
Assignment
""
)
Try
Await
Assign
(
a
)
Catch
__
As
NullReferenceException
Console
.
WriteLine
(
""C
aught
NullReferenceException
""
)
End
Try
End
Function
Private
Async
Function
TestAIsNotNull
()
As
Task
Console
.
WriteLine
(
NameOf
(
Program
.
TestAIsNotNull
))
Dim
a
=
New
A
With
{
.
_b
=
New
B
()
}
Console
.
WriteLine
(
""
Before
Assignment
a
.
_b
.
_x
is
:
""
&
a
.
_b
.
_x
)
Await
Assign
(
a
)
Console
.
WriteLine
(
""
After
Assignment
a
.
_b
.
_x
is
:
""
&
a
.
_b
.
_x
)
End
Function
Private
Async
Function
ReassignADuringAssignment
()
As
Task
Console
.
WriteLine
(
NameOf
(
Program
.
ReassignADuringAssignment
))
Dim
a
=
New
A
With
{
.
_b
=
New
B
()
}
Dim
aCopy
=
a
Console
.
WriteLine
(
""
Before
Assignment
a
is
null
==
""
&
(
a
Is
Nothing
))
Console
.
WriteLine
(
""
Before
Assignment
aCopy
.
_b
.
_x
is
:
""
&
aCopy
.
_b
.
_x
)
Dim
WriteAndReassign
As
Func
(
Of
String
,
Task
(
Of
Integer
))
=
Async
Function
(
ByVal
s
As
String
)
Await
Task
.
Yield
()
a
=
Nothing
Console
.
WriteLine
(
s
)
Return
42
End
Function
a
.
b
.
x
=
Await
WriteAndReassign
(
""
RHS
""
)
Console
.
WriteLine
(
""
After
Assignment
a
is
null
==
""
&
(
a
Is
Nothing
))
Console
.
WriteLine
(
""
After
Assignment
aCopy
.
_b
.
_x
is
:
""
&
aCopy
.
_b
.
_x
)
End
Function
Private
Async
Function
Write
(
ByVal
s
As
String
)
As
Task
(
Of
Integer
)
Await
Task
.
Yield
()
Console
.
WriteLine
(
s
)
Return
42
End
Function
End
Module
Class
A
Public
_b
As
B
Public
Property
b
As
B
Get
Console
.
WriteLine
(
""
GetB
""
)
Return
_b
End
Get
Set
(
ByVal
value
As
B
)
Console
.
WriteLine
(
""
SetB
""
)
_b
=
value
End
Set
End
Property
End
Class
Class
B
Public
_x
As
Integer
Public
Property
x
As
Integer
Get
Console
.
WriteLine
(
""
GetX
""
)
Return
_x
End
Get
Set
(
ByVal
value
As
Integer
)
Console
.
WriteLine
(
""
SetX
""
)
_x
=
value
End
Set
End
Property
End
Class
"
Dim comp = CreateCompilation(source, options:=TestOptions.ReleaseExe)
CompileAndVerify(comp, expectedOutput:="
TestAIsNull
Before
Assignment
Caught
NullReferenceException
TestAIsNotNull
Before
Assignment
a
.
_b
.
_x
is
:
0
GetB
RHS
SetX
After
Assignment
a
.
_b
.
_x
is
:
42
ReassignADuringAssignment
Before
Assignment
a
is
null
==
False
Before
Assignment
aCopy
.
_b
.
_x
is
:
0
GetB
RHS
SetX
After
Assignment
a
is
null
==
True
After
Assignment
aCopy
.
_b
.
_x
is
:
42
").VerifyIL("
Program
.
VB
$
StateMachine_0_Assign
.
MoveNext
", "
{
//
Code
size
203
(
0
xcb
)
.
maxstack
3
.
locals
init
(
Integer
V_0
,
System
.
Runtime
.
CompilerServices
.
TaskAwaiter
(
Of
Integer
)
V_1
,
System
.
Exception
V_2
)
IL_0000
:
ldarg
.
0
IL_0001
:
ldfld
""
Program
.
VB
$
StateMachine_0_Assign
.
$
State
As
Integer
""
IL_0006
:
stloc
.
0
.
try
{
IL_0007
:
ldloc
.
0
IL_0008
:
brfalse
.
s
IL_0054
IL_000a
:
ldarg
.
0
IL_000b
:
ldarg
.
0
IL_000c
:
ldfld
""
Program
.
VB
$
StateMachine_0_Assign
.
$
VB
$
Local_a
As
A
""
IL_0011
:
callvirt
""
Function
A
.
get_b
()
As
B
""
IL_0016
:
stfld
""
Program
.
VB
$
StateMachine_0_Assign
.
$
U1
As
B
""
IL_001b
:
ldstr
""
RHS
""
IL_0020
:
call
""
Function
Program
.
Write
(
String
)
As
System
.
Threading
.
Tasks
.
Task
(
Of
Integer
)
""
IL_0025
:
callvirt
""
Function
System
.
Threading
.
Tasks
.
Task
(
Of
Integer
).
GetAwaiter
()
As
System
.
Runtime
.
CompilerServices
.
TaskAwaiter
(
Of
Integer
)
""
IL_002a
:
stloc
.
1
IL_002b
:
ldloca
.
s
V_1
IL_002d
:
call
""
Function
System
.
Runtime
.
CompilerServices
.
TaskAwaiter
(
Of
Integer
).
get_IsCompleted
()
As
Boolean
""
IL_0032
:
brtrue
.
s
IL_0070
IL_0034
:
ldarg
.
0
IL_0035
:
ldc
.
i4
.
0
IL_0036
:
dup
IL_0037
:
stloc
.
0
IL_0038
:
stfld
""
Program
.
VB
$
StateMachine_0_Assign
.
$
State
As
Integer
""
IL_003d
:
ldarg
.
0
IL_003e
:
ldloc
.
1
IL_003f
:
stfld
""
Program
.
VB
$
StateMachine_0_Assign
.
$
A0
As
System
.
Runtime
.
CompilerServices
.
TaskAwaiter
(
Of
Integer
)
""
IL_0044
:
ldarg
.
0
IL_0045
:
ldflda
""
Program
.
VB
$
StateMachine_0_Assign
.
$
Builder
As
System
.
Runtime
.
CompilerServices
.
AsyncTaskMethodBuilder
""
IL_004a
:
ldloca
.
s
V_1
IL_004c
:
ldarg
.
0
IL_004d
:
call
""
Sub
System
.
Runtime
.
CompilerServices
.
AsyncTaskMethodBuilder
.
AwaitUnsafeOnCompleted
(
Of
System
.
Runtime
.
CompilerServices
.
TaskAwaiter
(
Of
Integer
),
Program
.
VB
$
StateMachine_0_Assign
)(
ByRef
System
.
Runtime
.
CompilerServices
.
TaskAwaiter
(
Of
Integer
),
ByRef
Program
.
VB
$
StateMachine_0_Assign
)
""
IL_0052
:
leave
.
s
IL_00ca
IL_0054
:
ldarg
.
0
IL_0055
:
ldc
.
i4
.
m1
IL_0056
:
dup
IL_0057
:
stloc
.
0
IL_0058
:
stfld
""
Program
.
VB
$
StateMachine_0_Assign
.
$
State
As
Integer
""
IL_005d
:
ldarg
.
0
IL_005e
:
ldfld
""
Program
.
VB
$
StateMachine_0_Assign
.
$
A0
As
System
.
Runtime
.
CompilerServices
.
TaskAwaiter
(
Of
Integer
)
""
IL_0063
:
stloc
.
1
IL_0064
:
ldarg
.
0
IL_0065
:
ldflda
""
Program
.
VB
$
StateMachine_0_Assign
.
$
A0
As
System
.
Runtime
.
CompilerServices
.
TaskAwaiter
(
Of
Integer
)
""
IL_006a
:
initobj
""
System
.
Runtime
.
CompilerServices
.
TaskAwaiter
(
Of
Integer
)
""
IL_0070
:
ldarg
.
0
IL_0071
:
ldfld
""
Program
.
VB
$
StateMachine_0_Assign
.
$
U1
As
B
""
IL_0076
:
ldloca
.
s
V_1
IL_0078
:
call
""
Function
System
.
Runtime
.
CompilerServices
.
TaskAwaiter
(
Of
Integer
).
GetResult
()
As
Integer
""
IL_007d
:
ldloca
.
s
V_1
IL_007f
:
initobj
""
System
.
Runtime
.
CompilerServices
.
TaskAwaiter
(
Of
Integer
)
""
IL_0085
:
callvirt
""
Sub
B
.
set_x
(
Integer
)
""
IL_008a
:
ldarg
.
0
IL_008b
:
ldnull
IL_008c
:
stfld
""
Program
.
VB
$
StateMachine_0_Assign
.
$
U1
As
B
""
IL_0091
:
leave
.
s
IL_00b5
}
catch
System
.
Exception
{
IL_0093
:
dup
IL_0094
:
call
""
Sub
Microsoft
.
VisualBasic
.
CompilerServices
.
ProjectData
.
SetProjectError
(
System
.
Exception
)
""
IL_0099
:
stloc
.
2
IL_009a
:
ldarg
.
0
IL_009b
:
ldc
.
i4
.
s
-
2
IL_009d
:
stfld
""
Program
.
VB
$
StateMachine_0_Assign
.
$
State
As
Integer
""
IL_00a2
:
ldarg
.
0
IL_00a3
:
ldflda
""
Program
.
VB
$
StateMachine_0_Assign
.
$
Builder
As
System
.
Runtime
.
CompilerServices
.
AsyncTaskMethodBuilder
""
IL_00a8
:
ldloc
.
2
IL_00a9
:
call
""
Sub
System
.
Runtime
.
CompilerServices
.
AsyncTaskMethodBuilder
.
SetException
(
System
.
Exception
)
""
IL_00ae
:
call
""
Sub
Microsoft
.
VisualBasic
.
CompilerServices
.
ProjectData
.
ClearProjectError
()
""
IL_00b3
:
leave
.
s
IL_00ca
}
IL_00b5
:
ldarg
.
0
IL_00b6
:
ldc
.
i4
.
s
-
2
IL_00b8
:
dup
IL_00b9
:
stloc
.
0
IL_00ba
:
stfld
""
Program
.
VB
$
StateMachine_0_Assign
.
$
State
As
Integer
""
IL_00bf
:
ldarg
.
0
IL_00c0
:
ldflda
""
Program
.
VB
$
StateMachine_0_Assign
.
$
Builder
As
System
.
Runtime
.
CompilerServices
.
AsyncTaskMethodBuilder
""
IL_00c5
:
call
""
Sub
System
.
Runtime
.
CompilerServices
.
AsyncTaskMethodBuilder
.
SetResult
()
""
IL_00ca
:
ret
}
")
End Sub
<WorkItem(19609, "
https
:
//
github
.
com
/
dotnet
/
roslyn
/
issues
/
19609
")>
<Fact>
Public Sub KeepLtrSemantics_FieldAccessOnClass()
Dim source = "
Imports
System
Imports
System.Threading.Tasks
Module
Program
Private
Async
Function
Assign
(
ByVal
a
As
A
)
As
Task
a
.
x
=
Await
Write
(
""
RHS
""
)
End
Function
Public
Sub
Main
(
ByVal
args
As
String
())
TestAIsNull
().
Wait
()
TestAIsNotNull
().
Wait
()
ReassignADuringAssignment
().
Wait
()
End
Sub
Private
Async
Function
TestAIsNull
()
As
Task
Console
.
WriteLine
(
NameOf
(
Program
.
TestAIsNull
))
Dim
a
As
A
=
Nothing
Console
.
WriteLine
(
""
Before
Assignment
""
)
Try
Await
Assign
(
a
)
Catch
__
As
NullReferenceException
Console
.
WriteLine
(
""C
aught
NullReferenceException
""
)
End
Try
End
Function
Private
Async
Function
TestAIsNotNull
()
As
Task
Console
.
WriteLine
(
NameOf
(
Program
.
TestAIsNotNull
))
Dim
a
=
New
A
()
Console
.
WriteLine
(
""
Before
Assignment
a
.
x
is
:
""
&
a
.
x
)
Await
Assign
(
a
)
Console
.
WriteLine
(
""
After
Assignment
a
.
x
is
:
""
&
a
.
x
)
End
Function
Private
Async
Function
ReassignADuringAssignment
()
As
Task
Console
.
WriteLine
(
NameOf
(
Program
.
ReassignADuringAssignment
))
Dim
a
=
New
A
()
Dim
aCopy
=
a
Console
.
WriteLine
(
""
Before
Assignment
a
is
null
==
""
&
(
a
Is
Nothing
))
Console
.
WriteLine
(
""
Before
Assignment
aCopy
.
x
is
:
""
&
aCopy
.
x
)
Dim
WriteAndReassign
As
Func
(
Of
String
,
Task
(
Of
Integer
))
=
Async
Function
(
ByVal
s
As
String
)
Await
Task
.
Yield
()
a
=
Nothing
Console
.
WriteLine
(
s
)
Return
42
End
Function
a
.
x
=
Await
WriteAndReassign
(
""
RHS
""
)
Console
.
WriteLine
(
""
After
Assignment
a
is
null
==
""
&
(
a
Is
Nothing
))
Console
.
WriteLine
(
""
After
Assignment
aCopy
.
x
is
:
""
&
aCopy
.
x
)
End
Function
Private
Async
Function
Write
(
ByVal
s
As
String
)
As
Task
(
Of
Integer
)
Await
Task
.
Yield
()
Console
.
WriteLine
(
s
)
Return
42
End
Function
End
Module
Class
A
Public
x
As
Integer
End
Class
"
Dim comp = CreateCompilation(source, options:=TestOptions.ReleaseExe)
CompileAndVerify(comp, expectedOutput:="
TestAIsNull
Before
Assignment
RHS
Caught
NullReferenceException
TestAIsNotNull
Before
Assignment
a
.
x
is
:
0
RHS
After
Assignment
a
.
x
is
:
42
ReassignADuringAssignment
Before
Assignment
a
is
null
==
False
Before
Assignment
aCopy
.
x
is
:
0
RHS
After
Assignment
a
is
null
==
True
After
Assignment
aCopy
.
x
is
:
42
").VerifyIL("
Program
.
VB
$
StateMachine_0_Assign
.
MoveNext
", "
{
//
Code
size
198
(
0
xc6
)
.
maxstack
3
.
locals
init
(
Integer
V_0
,
System
.
Runtime
.
CompilerServices
.
TaskAwaiter
(
Of
Integer
)
V_1
,
System
.
Exception
V_2
)
IL_0000
:
ldarg
.
0
IL_0001
:
ldfld
""
Program
.
VB
$
StateMachine_0_Assign
.
$
State
As
Integer
""
IL_0006
:
stloc
.
0
.
try
{
IL_0007
:
ldloc
.
0
IL_0008
:
brfalse
.
s
IL_004f
IL_000a
:
ldarg
.
0
IL_000b
:
ldarg
.
0
IL_000c
:
ldfld
""
Program
.
VB
$
StateMachine_0_Assign
.
$
VB
$
Local_a
As
A
""
IL_0011
:
stfld
""
Program
.
VB
$
StateMachine_0_Assign
.
$
U1
As
A
""
IL_0016
:
ldstr
""
RHS
""
IL_001b
:
call
""
Function
Program
.
Write
(
String
)
As
System
.
Threading
.
Tasks
.
Task
(
Of
Integer
)
""
IL_0020
:
callvirt
""
Function
System
.
Threading
.
Tasks
.
Task
(
Of
Integer
).
GetAwaiter
()
As
System
.
Runtime
.
CompilerServices
.
TaskAwaiter
(
Of
Integer
)
""
IL_0025
:
stloc
.
1
IL_0026
:
ldloca
.
s
V_1
IL_0028
:
call
""
Function
System
.
Runtime
.
CompilerServices
.
TaskAwaiter
(
Of
Integer
).
get_IsCompleted
()
As
Boolean
""
IL_002d
:
brtrue
.
s
IL_006b
IL_002f
:
ldarg
.
0
IL_0030
:
ldc
.
i4
.
0
IL_0031
:
dup
IL_0032
:
stloc
.
0
IL_0033
:
stfld
""
Program
.
VB
$
StateMachine_0_Assign
.
$
State
As
Integer
""
IL_0038
:
ldarg
.
0
IL_0039
:
ldloc
.
1
IL_003a
:
stfld
""
Program
.
VB
$
StateMachine_0_Assign
.
$
A0
As
System
.
Runtime
.
CompilerServices
.
TaskAwaiter
(
Of
Integer
)
""
IL_003f
:
ldarg
.
0
IL_0040
:
ldflda
""
Program
.
VB
$
StateMachine_0_Assign
.
$
Builder
As
System
.
Runtime
.
CompilerServices
.
AsyncTaskMethodBuilder
""
IL_0045
:
ldloca
.
s
V_1
IL_0047
:
ldarg
.
0
IL_0048
:
call
""
Sub
System
.
Runtime
.
CompilerServices
.
AsyncTaskMethodBuilder
.
AwaitUnsafeOnCompleted
(
Of
System
.
Runtime
.
CompilerServices
.
TaskAwaiter
(
Of
Integer
),
Program
.
VB
$
StateMachine_0_Assign
)(
ByRef
System
.
Runtime
.
CompilerServices
.
TaskAwaiter
(
Of
Integer
),
ByRef
Program
.
VB
$
StateMachine_0_Assign
)
""
IL_004d
:
leave
.
s
IL_00c5
IL_004f
:
ldarg
.
0
IL_0050
:
ldc
.
i4
.
m1
IL_0051
:
dup
IL_0052
:
stloc
.
0
IL_0053
:
stfld
""
Program
.
VB
$
StateMachine_0_Assign
.
$
State
As
Integer
""
IL_0058
:
ldarg
.
0
IL_0059
:
ldfld
""
Program
.
VB
$
StateMachine_0_Assign
.
$
A0
As
System
.
Runtime
.
CompilerServices
.
TaskAwaiter
(
Of
Integer
)
""
IL_005e
:
stloc
.
1
IL_005f
:
ldarg
.
0
IL_0060
:
ldflda
""
Program
.
VB
$
StateMachine_0_Assign
.
$
A0
As
System
.
Runtime
.
CompilerServices
.
TaskAwaiter
(
Of
Integer
)
""
IL_0065
:
initobj
""
System
.
Runtime
.
CompilerServices
.
TaskAwaiter
(
Of
Integer
)
""
IL_006b
:
ldarg
.
0
IL_006c
:
ldfld
""
Program
.
VB
$
StateMachine_0_Assign
.
$
U1
As
A
""
IL_0071
:
ldloca
.
s
V_1
IL_0073
:
call
""
Function
System
.
Runtime
.
CompilerServices
.
TaskAwaiter
(
Of
Integer
).
GetResult
()
As
Integer
""
IL_0078
:
ldloca
.
s
V_1
IL_007a
:
initobj
""
System
.
Runtime
.
CompilerServices
.
TaskAwaiter
(
Of
Integer
)
""
IL_0080
:
stfld
""
A
.
x
As
Integer
""
IL_0085
:
ldarg
.
0
IL_0086
:
ldnull
IL_0087
:
stfld
""
Program
.
VB
$
StateMachine_0_Assign
.
$
U1
As
A
""
IL_008c
:
leave
.
s
IL_00b0
}
catch
System
.
Exception
{
IL_008e
:
dup
IL_008f
:
call
""
Sub
Microsoft
.
VisualBasic
.
CompilerServices
.
ProjectData
.
SetProjectError
(
System
.
Exception
)
""
IL_0094
:
stloc
.
2
IL_0095
:
ldarg
.
0
IL_0096
:
ldc
.
i4
.
s
-
2
IL_0098
:
stfld
""
Program
.
VB
$
StateMachine_0_Assign
.
$
State
As
Integer
""
IL_009d
:
ldarg
.
0
IL_009e
:
ldflda
""
Program
.
VB
$
StateMachine_0_Assign
.
$
Builder
As
System
.
Runtime
.
CompilerServices
.
AsyncTaskMethodBuilder
""
IL_00a3
:
ldloc
.
2
IL_00a4
:
call
""
Sub
System
.
Runtime
.
CompilerServices
.
AsyncTaskMethodBuilder
.
SetException
(
System
.
Exception
)
""
IL_00a9
:
call
""
Sub
Microsoft
.
VisualBasic
.
CompilerServices
.
ProjectData
.
ClearProjectError
()
""
IL_00ae
:
leave
.
s
IL_00c5
}
IL_00b0
:
ldarg
.
0
IL_00b1
:
ldc
.
i4
.
s
-
2
IL_00b3
:
dup
IL_00b4
:
stloc
.
0
IL_00b5
:
stfld
""
Program
.
VB
$
StateMachine_0_Assign
.
$
State
As
Integer
""
IL_00ba
:
ldarg
.
0
IL_00bb
:
ldflda
""
Program
.
VB
$
StateMachine_0_Assign
.
$
Builder
As
System
.
Runtime
.
CompilerServices
.
AsyncTaskMethodBuilder
""
IL_00c0
:
call
""
Sub
System
.
Runtime
.
CompilerServices
.
AsyncTaskMethodBuilder
.
SetResult
()
""
IL_00c5
:
ret
}
")
End Sub
<Fact>
<WorkItem(42755, "
https
:
//
github
.
com
/
dotnet
/
roslyn
/
issues
/
42755
")>
Public Sub KeepLtrSemantics_CompoundAssignment()
Dim source = "
Imports
System
Imports
System.Threading.Tasks
Module
Program
Private
Async
Function
Assign
(
ByVal
a
As
A
)
As
Task
a
.
x
+=
Await
Write
(
""
RHS
""
)
End
Function
Sub
Main
(
ByVal
args
As
String
())
TestAIsNull
().
Wait
()
TestAIsNotNull
().
Wait
()
ReassignADuringAssignment
().
Wait
()
ReassignXDuringAssignment
().
Wait
()
End
Sub
Private
Async
Function
TestAIsNull
()
As
Task
Console
.
WriteLine
(
NameOf
(
Program
.
TestAIsNull
))
Dim
a
As
A
=
Nothing
Console
.
WriteLine
(
""
Before
Assignment
""
)
Try
Await
Assign
(
a
)
Catch
__
As
NullReferenceException
Console
.
WriteLine
(
""C
aught
NullReferenceException
""
)
End
Try
End
Function
Private
Async
Function
TestAIsNotNull
()
As
Task
Console
.
WriteLine
(
NameOf
(
Program
.
TestAIsNotNull
))
Dim
a
=
New
A
()
With
{
.
x
=
1
}
Console
.
WriteLine
(
""
Before
Assignment
a
.
x
is
:
""
&
a
.
x
)
Await
Assign
(
a
)
Console
.
WriteLine
(
""
After
Assignment
a
.
x
is
:
""
&
a
.
x
)
End
Function
Private
Async
Function
ReassignADuringAssignment
()
As
Task
Console
.
WriteLine
(
NameOf
(
Program
.
ReassignADuringAssignment
))
Dim
a
=
New
A
()
With
{
.
x
=
1
}
Dim
aCopy
=
a
Console
.
WriteLine
(
""
Before
Assignment
a
is
null
==
""
&
(
a
Is
Nothing
))
Console
.
WriteLine
(
""
Before
Assignment
aCopy
.
x
is
:
""
&
aCopy
.
x
)
Dim
WriteAndReassign
As
Func
(
Of
String
,
Task
(
Of
Integer
))
=
Async
Function
(
ByVal
s
As
String
)
Await
Task
.
Yield
()
a
=
Nothing
Console
.
WriteLine
(
s
)
Return
42
End
Function
a
.
x
+=
Await
WriteAndReassign
(
""
RHS
""
)
Console
.
WriteLine
(
""
After
Assignment
a
is
null
==
""
&
(
a
Is
Nothing
))
Console
.
WriteLine
(
""
After
Assignment
aCopy
.
x
is
:
""
&
aCopy
.
x
)
End
Function
Private
Async
Function
ReassignXDuringAssignment
()
As
Task
Console
.
WriteLine
(
NameOf
(
Program
.
ReassignXDuringAssignment
))
Dim
a
=
New
A
()
With
{
.
x
=
1
}
Console
.
WriteLine
(
""
Before
Assignment
a
.
x
is
:
""
&
a
.
x
)
Dim
WriteAndReassign
As
Func
(
Of
String
,
Task
(
Of
Integer
))
=
Async
Function
(
ByVal
s
As
String
)
Await
Task
.
Yield
()
a
.
x
=
100
Console
.
WriteLine
(
s
)
Return
42
End
Function
a
.
x
+=
Await
WriteAndReassign
(
""
RHS
""
)
Console
.
WriteLine
(
""
After
Assignment
a
.
x
is
:
""
&
a
.
x
)
End
Function
Private
Async
Function
Write
(
ByVal
s
As
String
)
As
Task
(
Of
Integer
)
Await
Task
.
Yield
()
Console
.
WriteLine
(
s
)
Return
42
End
Function
End
Module
Class
A
Public
x
As
Integer
End
Class
"
Dim comp = CreateCompilation(source, options:=TestOptions.ReleaseExe)
CompileAndVerify(comp, expectedOutput:="
TestAIsNull
Before
Assignment
Caught
NullReferenceException
TestAIsNotNull
Before
Assignment
a
.
x
is
:
1
RHS
After
Assignment
a
.
x
is
:
43
ReassignADuringAssignment
Before
Assignment
a
is
null
==
False
Before
Assignment
aCopy
.
x
is
:
1
RHS
After
Assignment
a
is
null
==
True
After
Assignment
aCopy
.
x
is
:
43
ReassignXDuringAssignment
Before
Assignment
a
.
x
is
:
1
RHS
After
Assignment
a
.
x
is
:
43
").VerifyIL("
Program
.
VB
$
StateMachine_0_Assign
.
MoveNext
", "
{
//
Code
size
222
(
0
xde
)
.
maxstack
4
.
locals
init
(
Integer
V_0
,
System
.
Runtime
.
CompilerServices
.
TaskAwaiter
(
Of
Integer
)
V_1
,
System
.
Exception
V_2
)
IL_0000
:
ldarg
.
0
IL_0001
:
ldfld
""
Program
.
VB
$
StateMachine_0_Assign
.
$
State
As
Integer
""
IL_0006
:
stloc
.
0
.
try
{
IL_0007
:
ldloc
.
0
IL_0008
:
brfalse
.
s
IL_0060
IL_000a
:
ldarg
.
0
IL_000b
:
ldarg
.
0
IL_000c
:
ldfld
""
Program
.
VB
$
StateMachine_0_Assign
.
$
VB
$
Local_a
As
A
""
IL_0011
:
stfld
""
Program
.
VB
$
StateMachine_0_Assign
.
$
U2
As
A
""
IL_0016
:
ldarg
.
0
IL_0017
:
ldarg
.
0
IL_0018
:
ldfld
""
Program
.
VB
$
StateMachine_0_Assign
.
$
VB
$
Local_a
As
A
""
IL_001d
:
ldfld
""
A
.
x
As
Integer
""
IL_0022
:
stfld
""
Program
.
VB
$
StateMachine_0_Assign
.
$
U1
As
Integer
""
IL_0027
:
ldstr
""
RHS
""
IL_002c
:
call
""
Function
Program
.
Write
(
String
)
As
System
.
Threading
.
Tasks
.
Task
(
Of
Integer
)
""
IL_0031
:
callvirt
""
Function
System
.
Threading
.
Tasks
.
Task
(
Of
Integer
).
GetAwaiter
()
As
System
.
Runtime
.
CompilerServices
.
TaskAwaiter
(
Of
Integer
)
""
IL_0036
:
stloc
.
1
IL_0037
:
ldloca
.
s
V_1
IL_0039
:
call
""
Function
System
.
Runtime
.
CompilerServices
.
TaskAwaiter
(
Of
Integer
).
get_IsCompleted
()
As
Boolean
""
IL_003e
:
brtrue
.
s
IL_007c
IL_0040
:
ldarg
.
0
IL_0041
:
ldc
.
i4
.
0
IL_0042
:
dup
IL_0043
:
stloc
.
0
IL_0044
:
stfld
""
Program
.
VB
$
StateMachine_0_Assign
.
$
State
As
Integer
""
IL_0049
:
ldarg
.
0
IL_004a
:
ldloc
.
1
IL_004b
:
stfld
""
Program
.
VB
$
StateMachine_0_Assign
.
$
A0
As
System
.
Runtime
.
CompilerServices
.
TaskAwaiter
(
Of
Integer
)
""
IL_0050
:
ldarg
.
0
IL_0051
:
ldflda
""
Program
.
VB
$
StateMachine_0_Assign
.
$
Builder
As
System
.
Runtime
.
CompilerServices
.
AsyncTaskMethodBuilder
""
IL_0056
:
ldloca
.
s
V_1
IL_0058
:
ldarg
.
0
IL_0059
:
call
""
Sub
System
.
Runtime
.
CompilerServices
.
AsyncTaskMethodBuilder
.
AwaitUnsafeOnCompleted
(
Of
System
.
Runtime
.
CompilerServices
.
TaskAwaiter
(
Of
Integer
),
Program
.
VB
$
StateMachine_0_Assign
)(
ByRef
System
.
Runtime
.
CompilerServices
.
TaskAwaiter
(
Of
Integer
),
ByRef
Program
.
VB
$
StateMachine_0_Assign
)
""
IL_005e
:
leave
.
s
IL_00dd
IL_0060
:
ldarg
.
0
IL_0061
:
ldc
.
i4
.
m1
IL_0062
:
dup
IL_0063
:
stloc
.
0
IL_0064
:
stfld
""
Program
.
VB
$
StateMachine_0_Assign
.
$
State
As
Integer
""
IL_0069
:
ldarg
.
0
IL_006a
:
ldfld
""
Program
.
VB
$
StateMachine_0_Assign
.
$
A0
As
System
.
Runtime
.
CompilerServices
.
TaskAwaiter
(
Of
Integer
)
""
IL_006f
:
stloc
.
1
IL_0070
:
ldarg
.
0
IL_0071
:
ldflda
""
Program
.
VB
$
StateMachine_0_Assign
.
$
A0
As
System
.
Runtime
.
CompilerServices
.
TaskAwaiter
(
Of
Integer
)
""
IL_0076
:
initobj
""
System
.
Runtime
.
CompilerServices
.
TaskAwaiter
(
Of
Integer
)
""
IL_007c
:
ldarg
.
0
IL_007d
:
ldfld
""
Program
.
VB
$
StateMachine_0_Assign
.
$
U2
As
A
""
IL_0082
:
ldarg
.
0
IL_0083
:
ldfld
""
Program
.
VB
$
StateMachine_0_Assign
.
$
U1
As
Integer
""
IL_0088
:
ldloca
.
s
V_1
IL_008a
:
call
""
Function
System
.
Runtime
.
CompilerServices
.
TaskAwaiter
(
Of
Integer
).
GetResult
()
As
Integer
""
IL_008f
:
ldloca
.
s
V_1
IL_0091
:
initobj
""
System
.
Runtime
.
CompilerServices
.
TaskAwaiter
(
Of
Integer
)
""
IL_0097
:
add
.
ovf
IL_0098
:
stfld
""
A
.
x
As
Integer
""
IL_009d
:
ldarg
.
0
IL_009e
:
ldnull
IL_009f
:
stfld
""
Program
.
VB
$
StateMachine_0_Assign
.
$
U2
As
A
""
IL_00a4
:
leave
.
s
IL_00c8
}
catch
System
.
Exception
{
IL_00a6
:
dup
IL_00a7
:
call
""
Sub
Microsoft
.
VisualBasic
.
CompilerServices
.
ProjectData
.
SetProjectError
(
System
.
Exception
)
""
IL_00ac
:
stloc
.
2
IL_00ad
:
ldarg
.
0
IL_00ae
:
ldc
.
i4
.
s
-
2
IL_00b0
:
stfld
""
Program
.
VB
$
StateMachine_0_Assign
.
$
State
As
Integer
""
IL_00b5
:
ldarg
.
0
IL_00b6
:
ldflda
""
Program
.
VB
$
StateMachine_0_Assign
.
$
Builder
As
System
.
Runtime
.
CompilerServices
.
AsyncTaskMethodBuilder
""
IL_00bb
:
ldloc
.
2
IL_00bc
:
call
""
Sub
System
.
Runtime
.
CompilerServices
.
AsyncTaskMethodBuilder
.
SetException
(
System
.
Exception
)
""
IL_00c1
:
call
""
Sub
Microsoft
.
VisualBasic
.
CompilerServices
.
ProjectData
.
ClearProjectError
()
""
IL_00c6
:
leave
.
s
IL_00dd
}
IL_00c8
:
ldarg
.
0
IL_00c9
:
ldc
.
i4
.
s
-
2
IL_00cb
:
dup
IL_00cc
:
stloc
.
0
IL_00cd
:
stfld
""
Program
.
VB
$
StateMachine_0_Assign
.
$
State
As
Integer
""
IL_00d2
:
ldarg
.
0
IL_00d3
:
ldflda
""
Program
.
VB
$
StateMachine_0_Assign
.
$
Builder
As
System
.
Runtime
.
CompilerServices
.
AsyncTaskMethodBuilder
""
IL_00d8
:
call
""
Sub
System
.
Runtime
.
CompilerServices
.
AsyncTaskMethodBuilder
.
SetResult
()
""
IL_00dd
:
ret
}
")
End Sub
<Fact>
<WorkItem(42755, "
https
:
//
github
.
com
/
dotnet
/
roslyn
/
issues
/
42755
")>
Public Sub KeepLtrSemantics_CompoundAssignmentProperties()
Dim source = "
Imports
System
Imports
System.Threading.Tasks
Module
Program
Private
Async
Function
Assign
(
ByVal
a
As
A
)
As
Task
a
.
x
+=
Await
Write
(
""
RHS
""
)
End
Function
Public
Sub
Main
(
ByVal
args
As
String
())
TestAIsNull
().
Wait
()
TestAIsNotNull
().
Wait
()
ReassignADuringAssignment
().
Wait
()
ReassignXDuringAssignment
().
Wait
()
End
Sub
Private
Async
Function
TestAIsNull
()
As
Task
Console
.
WriteLine
(
NameOf
(
Program
.
TestAIsNull
))
Dim
a
As
A
=
Nothing
Console
.
WriteLine
(
""
Before
Assignment
""
)
Try
Await
Assign
(
a
)
Catch
__
As
NullReferenceException
Console
.
WriteLine
(
""C
aught
NullReferenceException
""
)
End
Try
End
Function
Private
Async
Function
TestAIsNotNull
()
As
Task
Console
.
WriteLine
(
NameOf
(
Program
.
TestAIsNotNull
))
Dim
a
=
New
A
()
With
{
.
_x
=
1
}
Console
.
WriteLine
(
""
Before
Assignment
a
.
_x
is
:
""
&
a
.
_x
)
Await
Assign
(
a
)
Console
.
WriteLine
(
""
After
Assignment
a
.
_x
is
:
""
&
a
.
_x
)
End
Function
Private
Async
Function
ReassignADuringAssignment
()
As
Task
Console
.
WriteLine
(
NameOf
(
Program
.
ReassignADuringAssignment
))
Dim
a
=
New
A
()
With
{
.
_x
=
1
}
Dim
aCopy
=
a
Console
.
WriteLine
(
""
Before
Assignment
a
is
null
==
""
&
(
a
Is
Nothing
))
Console
.
WriteLine
(
""
Before
Assignment
aCopy
.
_x
is
:
""
&
aCopy
.
_x
)
Dim
WriteAndReassign
As
Func
(
Of
String
,
Task
(
Of
Integer
))
=
Async
Function
(
ByVal
s
As
String
)
Await
Task
.
Yield
()
a
=
Nothing
Console
.
WriteLine
(
s
)
Return
42
End
Function
a
.
x
+=
Await
WriteAndReassign
(
""
RHS
""
)
Console
.
WriteLine
(
""
After
Assignment
a
is
null
==
""
&
(
a
Is
Nothing
))
Console
.
WriteLine
(
""
After
Assignment
aCopy
.
_x
is
:
""
&
aCopy
.
_x
)
End
Function
Private
Async
Function
ReassignXDuringAssignment
()
As
Task
Console
.
WriteLine
(
NameOf
(
Program
.
ReassignXDuringAssignment
))
Dim
a
=
New
A
()
With
{
.
_x
=
1
}
Console
.
WriteLine
(
""
Before
Assignment
a
.
_x
is
:
""
&
a
.
_x
)
Dim
WriteAndReassign
As
Func
(
Of
String
,
Task
(
Of
Integer
))
=
Async
Function
(
ByVal
s
As
String
)
Await
Task
.
Yield
()
a
.
_x
=
100
Console
.
WriteLine
(
s
)
Return
42
End
Function
a
.
x
+=
Await
WriteAndReassign
(
""
RHS
""
)
Console
.
WriteLine
(
""
After
Assignment
a
.
_x
is
:
""
&
a
.
_x
)
End
Function
Private
Async
Function
Write
(
ByVal
s
As
String
)
As
Task
(
Of
Integer
)
Await
Task
.
Yield
()
Console
.
WriteLine
(
s
)
Return
42
End
Function
End
Module
Class
A
Public
_x
As
Integer
Public
Property
x
As
Integer
Get
Console
.
WriteLine
(
""
GetX
""
)
Return
_x
End
Get
Set
(
ByVal
value
As
Integer
)
Console
.
WriteLine
(
""
SetX
""
)
_x
=
value
End
Set
End
Property
End
Class
"
Dim comp = CreateCompilation(source, options:=TestOptions.ReleaseExe)
CompileAndVerify(comp, expectedOutput:="
TestAIsNull
Before
Assignment
Caught
NullReferenceException
TestAIsNotNull
Before
Assignment
a
.
_x
is
:
1
GetX
RHS
SetX
After
Assignment
a
.
_x
is
:
43
ReassignADuringAssignment
Before
Assignment
a
is
null
==
False
Before
Assignment
aCopy
.
_x
is
:
1
GetX
RHS
SetX
After
Assignment
a
is
null
==
True
After
Assignment
aCopy
.
_x
is
:
43
ReassignXDuringAssignment
Before
Assignment
a
.
_x
is
:
1
GetX
RHS
SetX
After
Assignment
a
.
_x
is
:
43
").VerifyIL("
Program
.
VB
$
StateMachine_0_Assign
.
MoveNext
", "
{
//
Code
size
231
(
0
xe7
)
.
maxstack
4
.
locals
init
(
Integer
V_0
,
System
.
Runtime
.
CompilerServices
.
TaskAwaiter
(
Of
Integer
)
V_1
,
A
V_2
,
System
.
Exception
V_3
)
IL_0000
:
ldarg
.
0
IL_0001
:
ldfld
""
Program
.
VB
$
StateMachine_0_Assign
.
$
State
As
Integer
""
IL_0006
:
stloc
.
0
.
try
{
IL_0007
:
ldloc
.
0
IL_0008
:
brfalse
.
s
IL_0069
IL_000a
:
ldarg
.
0
IL_000b
:
ldarg
.
0
IL_000c
:
ldarg
.
0
IL_000d
:
ldfld
""
Program
.
VB
$
StateMachine_0_Assign
.
$
VB
$
Local_a
As
A
""
IL_0012
:
dup
IL_0013
:
stloc
.
2
IL_0014
:
stfld
""
Program
.
VB
$
StateMachine_0_Assign
.
$
S0
As
A
""
IL_0019
:
ldloc
.
2
IL_001a
:
stfld
""
Program
.
VB
$
StateMachine_0_Assign
.
$
U2
As
A
""
IL_001f
:
ldarg
.
0
IL_0020
:
ldarg
.
0
IL_0021
:
ldfld
""
Program
.
VB
$
StateMachine_0_Assign
.
$
S0
As
A
""
IL_0026
:
callvirt
""
Function
A
.
get_x
()
As
Integer
""
IL_002b
:
stfld
""
Program
.
VB
$
StateMachine_0_Assign
.
$
U1
As
Integer
""
IL_0030
:
ldstr
""
RHS
""
IL_0035
:
call
""
Function
Program
.
Write
(
String
)
As
System
.
Threading
.
Tasks
.
Task
(
Of
Integer
)
""
IL_003a
:
callvirt
""
Function
System
.
Threading
.
Tasks
.
Task
(
Of
Integer
).
GetAwaiter
()
As
System
.
Runtime
.
CompilerServices
.
TaskAwaiter
(
Of
Integer
)
""
IL_003f
:
stloc
.
1
IL_0040
:
ldloca
.
s
V_1
IL_0042
:
call
""
Function
System
.
Runtime
.
CompilerServices
.
TaskAwaiter
(
Of
Integer
).
get_IsCompleted
()
As
Boolean
""
IL_0047
:
brtrue
.
s
IL_0085
IL_0049
:
ldarg
.
0
IL_004a
:
ldc
.
i4
.
0
IL_004b
:
dup
IL_004c
:
stloc
.
0
IL_004d
:
stfld
""
Program
.
VB
$
StateMachine_0_Assign
.
$
State
As
Integer
""
IL_0052
:
ldarg
.
0
IL_0053
:
ldloc
.
1
IL_0054
:
stfld
""
Program
.
VB
$
StateMachine_0_Assign
.
$
A0
As
System
.
Runtime
.
CompilerServices
.
TaskAwaiter
(
Of
Integer
)
""
IL_0059
:
ldarg
.
0
IL_005a
:
ldflda
""
Program
.
VB
$
StateMachine_0_Assign
.
$
Builder
As
System
.
Runtime
.
CompilerServices
.
AsyncTaskMethodBuilder
""
IL_005f
:
ldloca
.
s
V_1
IL_0061
:
ldarg
.
0
IL_0062
:
call
""
Sub
System
.
Runtime
.
CompilerServices
.
AsyncTaskMethodBuilder
.
AwaitUnsafeOnCompleted
(
Of
System
.
Runtime
.
CompilerServices
.
TaskAwaiter
(
Of
Integer
),
Program
.
VB
$
StateMachine_0_Assign
)(
ByRef
System
.
Runtime
.
CompilerServices
.
TaskAwaiter
(
Of
Integer
),
ByRef
Program
.
VB
$
StateMachine_0_Assign
)
""
IL_0067
:
leave
.
s
IL_00e6
IL_0069
:
ldarg
.
0
IL_006a
:
ldc
.
i4
.
m1
IL_006b
:
dup
IL_006c
:
stloc
.
0
IL_006d
:
stfld
""
Program
.
VB
$
StateMachine_0_Assign
.
$
State
As
Integer
""
IL_0072
:
ldarg
.
0
IL_0073
:
ldfld
""
Program
.
VB
$
StateMachine_0_Assign
.
$
A0
As
System
.
Runtime
.
CompilerServices
.
TaskAwaiter
(
Of
Integer
)
""
IL_0078
:
stloc
.
1
IL_0079
:
ldarg
.
0
IL_007a
:
ldflda
""
Program
.
VB
$
StateMachine_0_Assign
.
$
A0
As
System
.
Runtime
.
CompilerServices
.
TaskAwaiter
(
Of
Integer
)
""
IL_007f
:
initobj
""
System
.
Runtime
.
CompilerServices
.
TaskAwaiter
(
Of
Integer
)
""
IL_0085
:
ldarg
.
0
IL_0086
:
ldfld
""
Program
.
VB
$
StateMachine_0_Assign
.
$
U2
As
A
""
IL_008b
:
ldarg
.
0
IL_008c
:
ldfld
""
Program
.
VB
$
StateMachine_0_Assign
.
$
U1
As
Integer
""
IL_0091
:
ldloca
.
s
V_1
IL_0093
:
call
""
Function
System
.
Runtime
.
CompilerServices
.
TaskAwaiter
(
Of
Integer
).
GetResult
()
As
Integer
""
IL_0098
:
ldloca
.
s
V_1
IL_009a
:
initobj
""
System
.
Runtime
.
CompilerServices
.
TaskAwaiter
(
Of
Integer
)
""
IL_00a0
:
add
.
ovf
IL_00a1
:
callvirt
""
Sub
A
.
set_x
(
Integer
)
""
IL_00a6
:
ldarg
.
0
IL_00a7
:
ldnull
IL_00a8
:
stfld
""
Program
.
VB
$
StateMachine_0_Assign
.
$
U2
As
A
""
IL_00ad
:
leave
.
s
IL_00d1
}
catch
System
.
Exception
{
IL_00af
:
dup
IL_00b0
:
call
""
Sub
Microsoft
.
VisualBasic
.
CompilerServices
.
ProjectData
.
SetProjectError
(
System
.
Exception
)
""
IL_00b5
:
stloc
.
3
IL_00b6
:
ldarg
.
0
IL_00b7
:
ldc
.
i4
.
s
-
2
IL_00b9
:
stfld
""
Program
.
VB
$
StateMachine_0_Assign
.
$
State
As
Integer
""
IL_00be
:
ldarg
.
0
IL_00bf
:
ldflda
""
Program
.
VB
$
StateMachine_0_Assign
.
$
Builder
As
System
.
Runtime
.
CompilerServices
.
AsyncTaskMethodBuilder
""
IL_00c4
:
ldloc
.
3
IL_00c5
:
call
""
Sub
System
.
Runtime
.
CompilerServices
.
AsyncTaskMethodBuilder
.
SetException
(
System
.
Exception
)
""
IL_00ca
:
call
""
Sub
Microsoft
.
VisualBasic
.
CompilerServices
.
ProjectData
.
ClearProjectError
()
""
IL_00cf
:
leave
.
s
IL_00e6
}
IL_00d1
:
ldarg
.
0
IL_00d2
:
ldc
.
i4
.
s
-
2
IL_00d4
:
dup
IL_00d5
:
stloc
.
0
IL_00d6
:
stfld
""
Program
.
VB
$
StateMachine_0_Assign
.
$
State
As
Integer
""
IL_00db
:
ldarg
.
0
IL_00dc
:
ldflda
""
Program
.
VB
$
StateMachine_0_Assign
.
$
Builder
As
System
.
Runtime
.
CompilerServices
.
AsyncTaskMethodBuilder
""
IL_00e1
:
call
""
Sub
System
.
Runtime
.
CompilerServices
.
AsyncTaskMethodBuilder
.
SetResult
()
""
IL_00e6
:
ret
}
")
End Sub
<Fact>
<WorkItem(42755, "
https
:
//
github
.
com
/
dotnet
/
roslyn
/
issues
/
42755
")>
Public Sub AssignmentToFieldOfStaticFieldOfStruct()
Dim source = "
Imports
System
Imports
System.Threading.Tasks
Module
Program
Private
Async
Function
Assign
()
As
Task
A
.
b
.
x
=
Await
Write
(
""
RHS
""
)
End
Function
Private
Async
Function
Write
(
ByVal
s
As
String
)
As
Task
(
Of
Integer
)
Await
Task
.
Yield
()
Console
.
WriteLine
(
s
)
Return
42
End
Function
Public
Sub
Main
(
ByVal
args
As
String
())
Console
.
WriteLine
(
""
Before
Assignment
A
.
b
.
x
is
:
""
&
A
.
b
.
x
)
Assign
().
Wait
()
Console
.
WriteLine
(
""
After
Assignment
A
.
b
.
x
is
:
""
&
A
.
b
.
x
)
End
Sub
End
Module
Structure
A
Public
Shared
b
As
B
End
Structure
Structure
B
Public
x
As
Integer
End
Structure
"
Dim comp = CreateCompilation(source, options:=TestOptions.ReleaseExe)
CompileAndVerify(comp, expectedOutput:="
Before
Assignment
A
.
b
.
x
is
:
0
RHS
After
Assignment
A
.
b
.
x
is
:
42
").VerifyIL("
Program
.
VB
$
StateMachine_0_Assign
.
MoveNext
", "
{
//
Code
size
178
(
0
xb2
)
.
maxstack
3
.
locals
init
(
Integer
V_0
,
System
.
Runtime
.
CompilerServices
.
TaskAwaiter
(
Of
Integer
)
V_1
,
System
.
Exception
V_2
)
IL_0000
:
ldarg
.
0
IL_0001
:
ldfld
""
Program
.
VB
$
StateMachine_0_Assign
.
$
State
As
Integer
""
IL_0006
:
stloc
.
0
.
try
{
IL_0007
:
ldloc
.
0
IL_0008
:
brfalse
.
s
IL_0043
IL_000a
:
ldstr
""
RHS
""
IL_000f
:
call
""
Function
Program
.
Write
(
String
)
As
System
.
Threading
.
Tasks
.
Task
(
Of
Integer
)
""
IL_0014
:
callvirt
""
Function
System
.
Threading
.
Tasks
.
Task
(
Of
Integer
).
GetAwaiter
()
As
System
.
Runtime
.
CompilerServices
.
TaskAwaiter
(
Of
Integer
)
""
IL_0019
:
stloc
.
1
IL_001a
:
ldloca
.
s
V_1
IL_001c
:
call
""
Function
System
.
Runtime
.
CompilerServices
.
TaskAwaiter
(
Of
Integer
).
get_IsCompleted
()
As
Boolean
""
IL_0021
:
brtrue
.
s
IL_005f
IL_0023
:
ldarg
.
0
IL_0024
:
ldc
.
i4
.
0
IL_0025
:
dup
IL_0026
:
stloc
.
0
IL_0027
:
stfld
""
Program
.
VB
$
StateMachine_0_Assign
.
$
State
As
Integer
""
IL_002c
:
ldarg
.
0
IL_002d
:
ldloc
.
1
IL_002e
:
stfld
""
Program
.
VB
$
StateMachine_0_Assign
.
$
A0
As
System
.
Runtime
.
CompilerServices
.
TaskAwaiter
(
Of
Integer
)
""
IL_0033
:
ldarg
.
0
IL_0034
:
ldflda
""
Program
.
VB
$
StateMachine_0_Assign
.
$
Builder
As
System
.
Runtime
.
CompilerServices
.
AsyncTaskMethodBuilder
""
IL_0039
:
ldloca
.
s
V_1
IL_003b
:
ldarg
.
0
IL_003c
:
call
""
Sub
System
.
Runtime
.
CompilerServices
.
AsyncTaskMethodBuilder
.
AwaitUnsafeOnCompleted
(
Of
System
.
Runtime
.
CompilerServices
.
TaskAwaiter
(
Of
Integer
),
Program
.
VB
$
StateMachine_0_Assign
)(
ByRef
System
.
Runtime
.
CompilerServices
.
TaskAwaiter
(
Of
Integer
),
ByRef
Program
.
VB
$
StateMachine_0_Assign
)
""
IL_0041
:
leave
.
s
IL_00b1
IL_0043
:
ldarg
.
0
IL_0044
:
ldc
.
i4
.
m1
IL_0045
:
dup
IL_0046
:
stloc
.
0
IL_0047
:
stfld
""
Program
.
VB
$
StateMachine_0_Assign
.
$
State
As
Integer
""
IL_004c
:
ldarg
.
0
IL_004d
:
ldfld
""
Program
.
VB
$
StateMachine_0_Assign
.
$
A0
As
System
.
Runtime
.
CompilerServices
.
TaskAwaiter
(
Of
Integer
)
""
IL_0052
:
stloc
.
1
IL_0053
:
ldarg
.
0
IL_0054
:
ldflda
""
Program
.
VB
$
StateMachine_0_Assign
.
$
A0
As
System
.
Runtime
.
CompilerServices
.
TaskAwaiter
(
Of
Integer
)
""
IL_0059
:
initobj
""
System
.
Runtime
.
CompilerServices
.
TaskAwaiter
(
Of
Integer
)
""
IL_005f
:
ldsflda
""
A
.
b
As
B
""
IL_0064
:
ldloca
.
s
V_1
IL_0066
:
call
""
Function
System
.
Runtime
.
CompilerServices
.
TaskAwaiter
(
Of
Integer
).
GetResult
()
As
Integer
""
IL_006b
:
ldloca
.
s
V_1
IL_006d
:
initobj
""
System
.
Runtime
.
CompilerServices
.
TaskAwaiter
(
Of
Integer
)
""
IL_0073
:
stfld
""
B
.
x
As
Integer
""
IL_0078
:
leave
.
s
IL_009c
}
catch
System
.
Exception
{
IL_007a
:
dup
IL_007b
:
call
""
Sub
Microsoft
.
VisualBasic
.
CompilerServices
.
ProjectData
.
SetProjectError
(
System
.
Exception
)
""
IL_0080
:
stloc
.
2
IL_0081
:
ldarg
.
0
IL_0082
:
ldc
.
i4
.
s
-
2
IL_0084
:
stfld
""
Program
.
VB
$
StateMachine_0_Assign
.
$
State
As
Integer
""
IL_0089
:
ldarg
.
0
IL_008a
:
ldflda
""
Program
.
VB
$
StateMachine_0_Assign
.
$
Builder
As
System
.
Runtime
.
CompilerServices
.
AsyncTaskMethodBuilder
""
IL_008f
:
ldloc
.
2
IL_0090
:
call
""
Sub
System
.
Runtime
.
CompilerServices
.
AsyncTaskMethodBuilder
.
SetException
(
System
.
Exception
)
""
IL_0095
:
call
""
Sub
Microsoft
.
VisualBasic
.
CompilerServices
.
ProjectData
.
ClearProjectError
()
""
IL_009a
:
leave
.
s
IL_00b1
}
IL_009c
:
ldarg
.
0
IL_009d
:
ldc
.
i4
.
s
-
2
IL_009f
:
dup
IL_00a0
:
stloc
.
0
IL_00a1
:
stfld
""
Program
.
VB
$
StateMachine_0_Assign
.
$
State
As
Integer
""
IL_00a6
:
ldarg
.
0
IL_00a7
:
ldflda
""
Program
.
VB
$
StateMachine_0_Assign
.
$
Builder
As
System
.
Runtime
.
CompilerServices
.
AsyncTaskMethodBuilder
""
IL_00ac
:
call
""
Sub
System
.
Runtime
.
CompilerServices
.
AsyncTaskMethodBuilder
.
SetResult
()
""
IL_00b1
:
ret
}
")
End Sub
<Fact>
<WorkItem(42755, "
https
:
//
github
.
com
/
dotnet
/
roslyn
/
issues
/
42755
")>
Public Sub KeepLtrSemantics_CallOnClassFieldOnClass()
Dim source =
"
Imports
System
Imports
System.Threading.Tasks
Module
Program
Private
Async
Function
Invoke
(
ByVal
a
As
A
)
As
Task
a
.
b
.
M
(
Await
Write
())
End
Function
Public
Sub
Main
(
ByVal
args
As
String
())
TestAIsNull
().
Wait
()
TestBIsNull
().
Wait
()
TestSucceeds
().
Wait
()
End
Sub
Private
Async
Function
TestAIsNull
()
As
Task
Console
.
WriteLine
(
NameOf
(
Program
.
TestAIsNull
))
Dim
a
As
A
=
Nothing
Console
.
WriteLine
(
""
Before
Invoke
""
)
Try
Await
Invoke
(
a
)
Catch
__
As
NullReferenceException
Console
.
WriteLine
(
""C
aught
NullReferenceException
""
)
End
Try
End
Function
Private
Async
Function
TestBIsNull
()
As
Task
Console
.
WriteLine
(
NameOf
(
Program
.
TestBIsNull
))
Dim
a
=
New
A
()
Console
.
WriteLine
(
""
Before
Invoke
""
)
Try
Await
Invoke
(
a
)
Catch
__
As
NullReferenceException
Console
.
WriteLine
(
""C
aught
NullReferenceException
""
)
End
Try
End
Function
Private
Async
Function
TestSucceeds
()
As
Task
Console
.
WriteLine
(
NameOf
(
Program
.
TestSucceeds
))
Dim
a
=
New
A
With
{
.
b
=
New
B
()
}
Console
.
WriteLine
(
""
Before
Invoke
""
)
Await
Invoke
(
a
)
Console
.
WriteLine
(
""
After
Invoke
""
)
End
Function
Private
Async
Function
Write
()
As
Task
(
Of
Integer
)
Await
Task
.
Yield
()
Console
.
WriteLine
(
""
Write
""
)
Return
42
End
Function
End
Module
Class
A
Public
b
As
B
End
Class
Class
B
Public
Sub
M
(
a
as
Integer
)
Console
.
WriteLine
(
""
M
""
)
End
Sub
End
Class
"
Dim comp = CreateCompilation(source, options:=TestOptions.ReleaseExe)
CompileAndVerify(comp, expectedOutput:="
TestAIsNull
Before
Invoke
Caught
NullReferenceException
TestBIsNull
Before
Invoke
Write
Caught
NullReferenceException
TestSucceeds
Before
Invoke
Write
M
After
Invoke
").VerifyIL("
Program
.
VB
$
StateMachine_0_Invoke
.
MoveNext
", "
{
//
Code
size
198
(
0
xc6
)
.
maxstack
3
.
locals
init
(
Integer
V_0
,
System
.
Runtime
.
CompilerServices
.
TaskAwaiter
(
Of
Integer
)
V_1
,
System
.
Exception
V_2
)
IL_0000
:
ldarg
.
0
IL_0001
:
ldfld
""
Program
.
VB
$
StateMachine_0_Invoke
.
$
State
As
Integer
""
IL_0006
:
stloc
.
0
.
try
{
IL_0007
:
ldloc
.
0
IL_0008
:
brfalse
.
s
IL_004f
IL_000a
:
ldarg
.
0
IL_000b
:
ldarg
.
0
IL_000c
:
ldfld
""
Program
.
VB
$
StateMachine_0_Invoke
.
$
VB
$
Local_a
As
A
""
IL_0011
:
ldfld
""
A
.
b
As
B
""
IL_0016
:
stfld
""
Program
.
VB
$
StateMachine_0_Invoke
.
$
U1
As
B
""
IL_001b
:
call
""
Function
Program
.
Write
()
As
System
.
Threading
.
Tasks
.
Task
(
Of
Integer
)
""
IL_0020
:
callvirt
""
Function
System
.
Threading
.
Tasks
.
Task
(
Of
Integer
).
GetAwaiter
()
As
System
.
Runtime
.
CompilerServices
.
TaskAwaiter
(
Of
Integer
)
""
IL_0025
:
stloc
.
1
IL_0026
:
ldloca
.
s
V_1
IL_0028
:
call
""
Function
System
.
Runtime
.
CompilerServices
.
TaskAwaiter
(
Of
Integer
).
get_IsCompleted
()
As
Boolean
""
IL_002d
:
brtrue
.
s
IL_006b
IL_002f
:
ldarg
.
0
IL_0030
:
ldc
.
i4
.
0
IL_0031
:
dup
IL_0032
:
stloc
.
0
IL_0033
:
stfld
""
Program
.
VB
$
StateMachine_0_Invoke
.
$
State
As
Integer
""
IL_0038
:
ldarg
.
0
IL_0039
:
ldloc
.
1
IL_003a
:
stfld
""
Program
.
VB
$
StateMachine_0_Invoke
.
$
A0
As
System
.
Runtime
.
CompilerServices
.
TaskAwaiter
(
Of
Integer
)
""
IL_003f
:
ldarg
.
0
IL_0040
:
ldflda
""
Program
.
VB
$
StateMachine_0_Invoke
.
$
Builder
As
System
.
Runtime
.
CompilerServices
.
AsyncTaskMethodBuilder
""
IL_0045
:
ldloca
.
s
V_1
IL_0047
:
ldarg
.
0
IL_0048
:
call
""
Sub
System
.
Runtime
.
CompilerServices
.
AsyncTaskMethodBuilder
.
AwaitUnsafeOnCompleted
(
Of
System
.
Runtime
.
CompilerServices
.
TaskAwaiter
(
Of
Integer
),
Program
.
VB
$
StateMachine_0_Invoke
)(
ByRef
System
.
Runtime
.
CompilerServices
.
TaskAwaiter
(
Of
Integer
),
ByRef
Program
.
VB
$
StateMachine_0_Invoke
)
""
IL_004d
:
leave
.
s
IL_00c5
IL_004f
:
ldarg
.
0
IL_0050
:
ldc
.
i4
.
m1
IL_0051
:
dup
IL_0052
:
stloc
.
0
IL_0053
:
stfld
""
Program
.
VB
$
StateMachine_0_Invoke
.
$
State
As
Integer
""
IL_0058
:
ldarg
.
0
IL_0059
:
ldfld
""
Program
.
VB
$
StateMachine_0_Invoke
.
$
A0
As
System
.
Runtime
.
CompilerServices
.
TaskAwaiter
(
Of
Integer
)
""
IL_005e
:
stloc
.
1
IL_005f
:
ldarg
.
0
IL_0060
:
ldflda
""
Program
.
VB
$
StateMachine_0_Invoke
.
$
A0
As
System
.
Runtime
.
CompilerServices
.
TaskAwaiter
(
Of
Integer
)
""
IL_0065
:
initobj
""
System
.
Runtime
.
CompilerServices
.
TaskAwaiter
(
Of
Integer
)
""
IL_006b
:
ldarg
.
0
IL_006c
:
ldfld
""
Program
.
VB
$
StateMachine_0_Invoke
.
$
U1
As
B
""
IL_0071
:
ldloca
.
s
V_1
IL_0073
:
call
""
Function
System
.
Runtime
.
CompilerServices
.
TaskAwaiter
(
Of
Integer
).
GetResult
()
As
Integer
""
IL_0078
:
ldloca
.
s
V_1
IL_007a
:
initobj
""
System
.
Runtime
.
CompilerServices
.
TaskAwaiter
(
Of
Integer
)
""
IL_0080
:
callvirt
""
Sub
B
.
M
(
Integer
)
""
IL_0085
:
ldarg
.
0
IL_0086
:
ldnull
IL_0087
:
stfld
""
Program
.
VB
$
StateMachine_0_Invoke
.
$
U1
As
B
""
IL_008c
:
leave
.
s
IL_00b0
}
catch
System
.
Exception
{
IL_008e
:
dup
IL_008f
:
call
""
Sub
Microsoft
.
VisualBasic
.
CompilerServices
.
ProjectData
.
SetProjectError
(
System
.
Exception
)
""
IL_0094
:
stloc
.
2
IL_0095
:
ldarg
.
0
IL_0096
:
ldc
.
i4
.
s
-
2
IL_0098
:
stfld
""
Program
.
VB
$
StateMachine_0_Invoke
.
$
State
As
Integer
""
IL_009d
:
ldarg
.
0
IL_009e
:
ldflda
""
Program
.
VB
$
StateMachine_0_Invoke
.
$
Builder
As
System
.
Runtime
.
CompilerServices
.
AsyncTaskMethodBuilder
""
IL_00a3
:
ldloc
.
2
IL_00a4
:
call
""
Sub
System
.
Runtime
.
CompilerServices
.
AsyncTaskMethodBuilder
.
SetException
(
System
.
Exception
)
""
IL_00a9
:
call
""
Sub
Microsoft
.
VisualBasic
.
CompilerServices
.
ProjectData
.
ClearProjectError
()
""
IL_00ae
:
leave
.
s
IL_00c5
}
IL_00b0
:
ldarg
.
0
IL_00b1
:
ldc
.
i4
.
s
-
2
IL_00b3
:
dup
IL_00b4
:
stloc
.
0
IL_00b5
:
stfld
""
Program
.
VB
$
StateMachine_0_Invoke
.
$
State
As
Integer
""
IL_00ba
:
ldarg
.
0
IL_00bb
:
ldflda
""
Program
.
VB
$
StateMachine_0_Invoke
.
$
Builder
As
System
.
Runtime
.
CompilerServices
.
AsyncTaskMethodBuilder
""
IL_00c0
:
call
""
Sub
System
.
Runtime
.
CompilerServices
.
AsyncTaskMethodBuilder
.
SetResult
()
""
IL_00c5
:
ret
}
")
End Sub
<Fact>
<WorkItem(42755, "
https
:
//
github
.
com
/
dotnet
/
roslyn
/
issues
/
42755
")>
Public Sub KeepLtrSemantics_CallOnStructFieldOnClass()
Dim source =
"
Imports
System
Imports
System.Threading.Tasks
Module
Program
Private
Async
Function
Invoke
(
ByVal
a
As
A
)
As
Task
a
.
b
.
M
(
Await
Write
())
End
Function
Public
Sub
Main
(
ByVal
args
As
String
())
TestAIsNull
().
Wait
()
TestSucceeds
().
Wait
()
End
Sub
Private
Async
Function
TestAIsNull
()
As
Task
Console
.
WriteLine
(
NameOf
(
Program
.
TestAIsNull
))
Dim
a
As
A
=
Nothing
Console
.
WriteLine
(
""
Before
Invoke
""
)
Try
Await
Invoke
(
a
)
Catch
__
As
NullReferenceException
Console
.
WriteLine
(
""C
aught
NullReferenceException
""
)
End
Try
End
Function
Private
Async
Function
TestSucceeds
()
As
Task
Console
.
WriteLine
(
NameOf
(
Program
.
TestSucceeds
))
Dim
a
=
New
A
()
Console
.
WriteLine
(
""
Before
Invoke
""
)
Await
Invoke
(
a
)
Console
.
WriteLine
(
""
After
Invoke
""
)
End
Function
Private
Async
Function
Write
()
As
Task
(
Of
Integer
)
Await
Task
.
Yield
()
Console
.
WriteLine
(
""
Write
""
)
Return
42
End
Function
End
Module
Class
A
Public
b
As
B
End
Class
Structure
B
Public
Sub
M
(
a
as
Integer
)
Console
.
WriteLine
(
""
M
""
)
End
Sub
End
Structure
"
Dim comp = CreateCompilation(source, options:=TestOptions.ReleaseExe)
CompileAndVerify(comp, expectedOutput:="
TestAIsNull
Before
Invoke
Caught
NullReferenceException
TestSucceeds
Before
Invoke
Write
M
After
Invoke
").VerifyIL("
Program
.
VB
$
StateMachine_0_Invoke
.
MoveNext
", "
{
//
Code
size
210
(
0
xd2
)
.
maxstack
3
.
locals
init
(
Integer
V_0
,
System
.
Runtime
.
CompilerServices
.
TaskAwaiter
(
Of
Integer
)
V_1
,
System
.
Exception
V_2
)
IL_0000
:
ldarg
.
0
IL_0001
:
ldfld
""
Program
.
VB
$
StateMachine_0_Invoke
.
$
State
As
Integer
""
IL_0006
:
stloc
.
0
.
try
{
IL_0007
:
ldloc
.
0
IL_0008
:
brfalse
.
s
IL_0056
IL_000a
:
ldarg
.
0
IL_000b
:
ldarg
.
0
IL_000c
:
ldfld
""
Program
.
VB
$
StateMachine_0_Invoke
.
$
VB
$
Local_a
As
A
""
IL_0011
:
stfld
""
Program
.
VB
$
StateMachine_0_Invoke
.
$
U1
As
A
""
IL_0016
:
ldarg
.
0
IL_0017
:
ldfld
""
Program
.
VB
$
StateMachine_0_Invoke
.
$
U1
As
A
""
IL_001c
:
ldfld
""
A
.
b
As
B
""
IL_0021
:
pop
IL_0022
:
call
""
Function
Program
.
Write
()
As
System
.
Threading
.
Tasks
.
Task
(
Of
Integer
)
""
IL_0027
:
callvirt
""
Function
System
.
Threading
.
Tasks
.
Task
(
Of
Integer
).
GetAwaiter
()
As
System
.
Runtime
.
CompilerServices
.
TaskAwaiter
(
Of
Integer
)
""
IL_002c
:
stloc
.
1
IL_002d
:
ldloca
.
s
V_1
IL_002f
:
call
""
Function
System
.
Runtime
.
CompilerServices
.
TaskAwaiter
(
Of
Integer
).
get_IsCompleted
()
As
Boolean
""
IL_0034
:
brtrue
.
s
IL_0072
IL_0036
:
ldarg
.
0
IL_0037
:
ldc
.
i4
.
0
IL_0038
:
dup
IL_0039
:
stloc
.
0
IL_003a
:
stfld
""
Program
.
VB
$
StateMachine_0_Invoke
.
$
State
As
Integer
""
IL_003f
:
ldarg
.
0
IL_0040
:
ldloc
.
1
IL_0041
:
stfld
""
Program
.
VB
$
StateMachine_0_Invoke
.
$
A0
As
System
.
Runtime
.
CompilerServices
.
TaskAwaiter
(
Of
Integer
)
""
IL_0046
:
ldarg
.
0
IL_0047
:
ldflda
""
Program
.
VB
$
StateMachine_0_Invoke
.
$
Builder
As
System
.
Runtime
.
CompilerServices
.
AsyncTaskMethodBuilder
""
IL_004c
:
ldloca
.
s
V_1
IL_004e
:
ldarg
.
0
IL_004f
:
call
""
Sub
System
.
Runtime
.
CompilerServices
.
AsyncTaskMethodBuilder
.
AwaitUnsafeOnCompleted
(
Of
System
.
Runtime
.
CompilerServices
.
TaskAwaiter
(
Of
Integer
),
Program
.
VB
$
StateMachine_0_Invoke
)(
ByRef
System
.
Runtime
.
CompilerServices
.
TaskAwaiter
(
Of
Integer
),
ByRef
Program
.
VB
$
StateMachine_0_Invoke
)
""
IL_0054
:
leave
.
s
IL_00d1
IL_0056
:
ldarg
.
0
IL_0057
:
ldc
.
i4
.
m1
IL_0058
:
dup
IL_0059
:
stloc
.
0
IL_005a
:
stfld
""
Program
.
VB
$
StateMachine_0_Invoke
.
$
State
As
Integer
""
IL_005f
:
ldarg
.
0
IL_0060
:
ldfld
""
Program
.
VB
$
StateMachine_0_Invoke
.
$
A0
As
System
.
Runtime
.
CompilerServices
.
TaskAwaiter
(
Of
Integer
)
""
IL_0065
:
stloc
.
1
IL_0066
:
ldarg
.
0
IL_0067
:
ldflda
""
Program
.
VB
$
StateMachine_0_Invoke
.
$
A0
As
System
.
Runtime
.
CompilerServices
.
TaskAwaiter
(
Of
Integer
)
""
IL_006c
:
initobj
""
System
.
Runtime
.
CompilerServices
.
TaskAwaiter
(
Of
Integer
)
""
IL_0072
:
ldarg
.
0
IL_0073
:
ldfld
""
Program
.
VB
$
StateMachine_0_Invoke
.
$
U1
As
A
""
IL_0078
:
ldflda
""
A
.
b
As
B
""
IL_007d
:
ldloca
.
s
V_1
IL_007f
:
call
""
Function
System
.
Runtime
.
CompilerServices
.
TaskAwaiter
(
Of
Integer
).
GetResult
()
As
Integer
""
IL_0084
:
ldloca
.
s
V_1
IL_0086
:
initobj
""
System
.
Runtime
.
CompilerServices
.
TaskAwaiter
(
Of
Integer
)
""
IL_008c
:
call
""
Sub
B
.
M
(
Integer
)
""
IL_0091
:
ldarg
.
0
IL_0092
:
ldnull
IL_0093
:
stfld
""
Program
.
VB
$
StateMachine_0_Invoke
.
$
U1
As
A
""
IL_0098
:
leave
.
s
IL_00bc
}
catch
System
.
Exception
{
IL_009a
:
dup
IL_009b
:
call
""
Sub
Microsoft
.
VisualBasic
.
CompilerServices
.
ProjectData
.
SetProjectError
(
System
.
Exception
)
""
IL_00a0
:
stloc
.
2
IL_00a1
:
ldarg
.
0
IL_00a2
:
ldc
.
i4
.
s
-
2
IL_00a4
:
stfld
""
Program
.
VB
$
StateMachine_0_Invoke
.
$
State
As
Integer
""
IL_00a9
:
ldarg
.
0
IL_00aa
:
ldflda
""
Program
.
VB
$
StateMachine_0_Invoke
.
$
Builder
As
System
.
Runtime
.
CompilerServices
.
AsyncTaskMethodBuilder
""
IL_00af
:
ldloc
.
2
IL_00b0
:
call
""
Sub
System
.
Runtime
.
CompilerServices
.
AsyncTaskMethodBuilder
.
SetException
(
System
.
Exception
)
""
IL_00b5
:
call
""
Sub
Microsoft
.
VisualBasic
.
CompilerServices
.
ProjectData
.
ClearProjectError
()
""
IL_00ba
:
leave
.
s
IL_00d1
}
IL_00bc
:
ldarg
.
0
IL_00bd
:
ldc
.
i4
.
s
-
2
IL_00bf
:
dup
IL_00c0
:
stloc
.
0
IL_00c1
:
stfld
""
Program
.
VB
$
StateMachine_0_Invoke
.
$
State
As
Integer
""
IL_00c6
:
ldarg
.
0
IL_00c7
:
ldflda
""
Program
.
VB
$
StateMachine_0_Invoke
.
$
Builder
As
System
.
Runtime
.
CompilerServices
.
AsyncTaskMethodBuilder
""
IL_00cc
:
call
""
Sub
System
.
Runtime
.
CompilerServices
.
AsyncTaskMethodBuilder
.
SetResult
()
""
IL_00d1
:
ret
}
")
End Sub
End Class
End Namespace
src/Compilers/VisualBasic/Test/Emit/PDB/PDBAsyncTests.vb
浏览文件 @
b18cb030
...
...
@@ -783,7 +783,7 @@ End Module
v
.
VerifyIL
(
"M.VB$StateMachine_0_F.MoveNext"
,
"
{
// Code size 2
66 (0x10a
)
// Code size 2
54 (0xfe
)
.maxstack 3
.locals init (Boolean V_0,
Integer V_1,
...
...
@@ -800,7 +800,7 @@ End Module
~IL_0007: ldloc.1
IL_0008: brfalse.s IL_000c
IL_000a: br.s IL_000e
IL_000c: br.s IL_006
f
IL_000c: br.s IL_006
3
-IL_000e: nop
~IL_000f: ldarg.0
IL_0010: newobj
""
Sub M._Closure$__0-0..ctor()
""
...
...
@@ -809,95 +809,91 @@ End Module
IL_001b: ldarg.0
IL_001c: ldfld
""
M.VB$StateMachine_0_F.$VB$ResumableLocal_$VB$Closure_$0 As M._Closure$__0-0
""
IL_0021: stfld
""
M.VB$StateMachine_0_F.$U1 As M._Closure$__0-0
""
IL_0026: ldarg.0
IL_0027: ldfld
""
M.VB$StateMachine_0_F.$U1 As M._Closure$__0-0
""
IL_002c: ldfld
""
M._Closure$__0-0.$VB$Local_z As Integer
""
IL_0031: pop
IL_0032: ldc.i4.1
IL_0033: call
""
Function System.Threading.Tasks.Task.FromResult(Of Integer)(Integer) As System.Threading.Tasks.Task(Of Integer)
""
IL_0038: callvirt
""
Function System.Threading.Tasks.Task(Of Integer).GetAwaiter() As System.Runtime.CompilerServices.TaskAwaiter(Of Integer)
""
IL_003d: stloc.3
~IL_003e: ldloca.s V_3
IL_0040: call
""
Function System.Runtime.CompilerServices.TaskAwaiter(Of Integer).get_IsCompleted() As Boolean
""
IL_0045: brtrue.s IL_008d
IL_0047: ldarg.0
IL_0048: ldc.i4.0
IL_0049: dup
IL_004a: stloc.1
IL_004b: stfld
""
M.VB$StateMachine_0_F.$State As Integer
""
<IL_0050: ldarg.0
IL_0051: ldloc.3
IL_0052: stfld
""
M.VB$StateMachine_0_F.$A0 As System.Runtime.CompilerServices.TaskAwaiter(Of Integer)
""
IL_0057: ldarg.0
IL_0058: ldflda
""
M.VB$StateMachine_0_F.$Builder As System.Runtime.CompilerServices.AsyncTaskMethodBuilder(Of Boolean)
""
IL_005d: ldloca.s V_3
IL_005f: ldarg.0
IL_0060: stloc.s V_4
IL_0062: ldloca.s V_4
IL_0064: call
""
Sub System.Runtime.CompilerServices.AsyncTaskMethodBuilder(Of Boolean).AwaitUnsafeOnCompleted(Of System.Runtime.CompilerServices.TaskAwaiter(Of Integer), M.VB$StateMachine_0_F)(ByRef System.Runtime.CompilerServices.TaskAwaiter(Of Integer), ByRef M.VB$StateMachine_0_F)
""
IL_0069: nop
IL_006a: leave IL_0109
>IL_006f: ldarg.0
IL_0070: ldc.i4.m1
IL_0071: dup
IL_0072: stloc.1
IL_0073: stfld
""
M.VB$StateMachine_0_F.$State As Integer
""
IL_0078: ldarg.0
IL_0079: ldfld
""
M.VB$StateMachine_0_F.$A0 As System.Runtime.CompilerServices.TaskAwaiter(Of Integer)
""
IL_007e: stloc.3
IL_007f: ldarg.0
IL_0080: ldflda
""
M.VB$StateMachine_0_F.$A0 As System.Runtime.CompilerServices.TaskAwaiter(Of Integer)
""
IL_0085: initobj
""
System.Runtime.CompilerServices.TaskAwaiter(Of Integer)
""
IL_008b: br.s IL_008d
IL_008d: ldarg.0
IL_008e: ldfld
""
M.VB$StateMachine_0_F.$U1 As M._Closure$__0-0
""
IL_0093: ldloca.s V_3
IL_0095: call
""
Function System.Runtime.CompilerServices.TaskAwaiter(Of Integer).GetResult() As Integer
""
IL_009a: stloc.s V_5
IL_009c: ldloca.s V_3
IL_009e: initobj
""
System.Runtime.CompilerServices.TaskAwaiter(Of Integer)
""
IL_00a4: ldloc.s V_5
IL_00a6: stfld
""
M._Closure$__0-0.$VB$Local_z As Integer
""
IL_00ab: ldarg.0
IL_00ac: ldnull
IL_00ad: stfld
""
M.VB$StateMachine_0_F.$U1 As M._Closure$__0-0
""
-IL_00b2: ldarg.0
IL_00b3: ldarg.0
IL_00b4: ldfld
""
M.VB$StateMachine_0_F.$VB$ResumableLocal_$VB$Closure_$0 As M._Closure$__0-0
""
IL_00b9: ldftn
""
Sub M._Closure$__0-0._Lambda$__0()
""
IL_00bf: newobj
""
Sub VB$AnonymousDelegate_0..ctor(Object, System.IntPtr)
""
IL_00c4: stfld
""
M.VB$StateMachine_0_F.$VB$ResumableLocal_x$1 As <generated method>
""
-IL_00c9: ldc.i4.0
IL_00ca: stloc.0
IL_00cb: leave.s IL_00f2
IL_0026: ldc.i4.1
IL_0027: call
""
Function System.Threading.Tasks.Task.FromResult(Of Integer)(Integer) As System.Threading.Tasks.Task(Of Integer)
""
IL_002c: callvirt
""
Function System.Threading.Tasks.Task(Of Integer).GetAwaiter() As System.Runtime.CompilerServices.TaskAwaiter(Of Integer)
""
IL_0031: stloc.3
~IL_0032: ldloca.s V_3
IL_0034: call
""
Function System.Runtime.CompilerServices.TaskAwaiter(Of Integer).get_IsCompleted() As Boolean
""
IL_0039: brtrue.s IL_0081
IL_003b: ldarg.0
IL_003c: ldc.i4.0
IL_003d: dup
IL_003e: stloc.1
IL_003f: stfld
""
M.VB$StateMachine_0_F.$State As Integer
""
<IL_0044: ldarg.0
IL_0045: ldloc.3
IL_0046: stfld
""
M.VB$StateMachine_0_F.$A0 As System.Runtime.CompilerServices.TaskAwaiter(Of Integer)
""
IL_004b: ldarg.0
IL_004c: ldflda
""
M.VB$StateMachine_0_F.$Builder As System.Runtime.CompilerServices.AsyncTaskMethodBuilder(Of Boolean)
""
IL_0051: ldloca.s V_3
IL_0053: ldarg.0
IL_0054: stloc.s V_4
IL_0056: ldloca.s V_4
IL_0058: call
""
Sub System.Runtime.CompilerServices.AsyncTaskMethodBuilder(Of Boolean).AwaitUnsafeOnCompleted(Of System.Runtime.CompilerServices.TaskAwaiter(Of Integer), M.VB$StateMachine_0_F)(ByRef System.Runtime.CompilerServices.TaskAwaiter(Of Integer), ByRef M.VB$StateMachine_0_F)
""
IL_005d: nop
IL_005e: leave IL_00fd
>IL_0063: ldarg.0
IL_0064: ldc.i4.m1
IL_0065: dup
IL_0066: stloc.1
IL_0067: stfld
""
M.VB$StateMachine_0_F.$State As Integer
""
IL_006c: ldarg.0
IL_006d: ldfld
""
M.VB$StateMachine_0_F.$A0 As System.Runtime.CompilerServices.TaskAwaiter(Of Integer)
""
IL_0072: stloc.3
IL_0073: ldarg.0
IL_0074: ldflda
""
M.VB$StateMachine_0_F.$A0 As System.Runtime.CompilerServices.TaskAwaiter(Of Integer)
""
IL_0079: initobj
""
System.Runtime.CompilerServices.TaskAwaiter(Of Integer)
""
IL_007f: br.s IL_0081
IL_0081: ldarg.0
IL_0082: ldfld
""
M.VB$StateMachine_0_F.$U1 As M._Closure$__0-0
""
IL_0087: ldloca.s V_3
IL_0089: call
""
Function System.Runtime.CompilerServices.TaskAwaiter(Of Integer).GetResult() As Integer
""
IL_008e: stloc.s V_5
IL_0090: ldloca.s V_3
IL_0092: initobj
""
System.Runtime.CompilerServices.TaskAwaiter(Of Integer)
""
IL_0098: ldloc.s V_5
IL_009a: stfld
""
M._Closure$__0-0.$VB$Local_z As Integer
""
IL_009f: ldarg.0
IL_00a0: ldnull
IL_00a1: stfld
""
M.VB$StateMachine_0_F.$U1 As M._Closure$__0-0
""
-IL_00a6: ldarg.0
IL_00a7: ldarg.0
IL_00a8: ldfld
""
M.VB$StateMachine_0_F.$VB$ResumableLocal_$VB$Closure_$0 As M._Closure$__0-0
""
IL_00ad: ldftn
""
Sub M._Closure$__0-0._Lambda$__0()
""
IL_00b3: newobj
""
Sub VB$AnonymousDelegate_0..ctor(Object, System.IntPtr)
""
IL_00b8: stfld
""
M.VB$StateMachine_0_F.$VB$ResumableLocal_x$1 As <generated method>
""
-IL_00bd: ldc.i4.0
IL_00be: stloc.0
IL_00bf: leave.s IL_00e6
}
catch System.Exception
{
~IL_00c
d
: dup
IL_00c
e
: call
""
Sub Microsoft.VisualBasic.CompilerServices.ProjectData.SetProjectError(System.Exception)
""
IL_00
d3
: stloc.s V_6
~IL_00
d5
: ldarg.0
IL_00
d6
: ldc.i4.s -2
IL_00
d8
: stfld
""
M.VB$StateMachine_0_F.$State As Integer
""
IL_00d
d
: ldarg.0
IL_00d
e
: ldflda
""
M.VB$StateMachine_0_F.$Builder As System.Runtime.CompilerServices.AsyncTaskMethodBuilder(Of Boolean)
""
IL_00
e3
: ldloc.s V_6
IL_00
e5
: call
""
Sub System.Runtime.CompilerServices.AsyncTaskMethodBuilder(Of Boolean).SetException(System.Exception)
""
IL_00
ea
: nop
IL_00
eb
: call
""
Sub Microsoft.VisualBasic.CompilerServices.ProjectData.ClearProjectError()
""
IL_00
f0: leave.s IL_0109
~IL_00c
1
: dup
IL_00c
2
: call
""
Sub Microsoft.VisualBasic.CompilerServices.ProjectData.SetProjectError(System.Exception)
""
IL_00
c7
: stloc.s V_6
~IL_00
c9
: ldarg.0
IL_00
ca
: ldc.i4.s -2
IL_00
cc
: stfld
""
M.VB$StateMachine_0_F.$State As Integer
""
IL_00d
1
: ldarg.0
IL_00d
2
: ldflda
""
M.VB$StateMachine_0_F.$Builder As System.Runtime.CompilerServices.AsyncTaskMethodBuilder(Of Boolean)
""
IL_00
d7
: ldloc.s V_6
IL_00
d9
: call
""
Sub System.Runtime.CompilerServices.AsyncTaskMethodBuilder(Of Boolean).SetException(System.Exception)
""
IL_00
de
: nop
IL_00
df
: call
""
Sub Microsoft.VisualBasic.CompilerServices.ProjectData.ClearProjectError()
""
IL_00
e4: leave.s IL_00fd
}
-IL_00
f2
: ldarg.0
IL_00
f3
: ldc.i4.s -2
IL_00
f5
: dup
IL_00
f6
: stloc.1
IL_00
f7
: stfld
""
M.VB$StateMachine_0_F.$State As Integer
""
~IL_00f
c
: ldarg.0
IL_00f
d
: ldflda
""
M.VB$StateMachine_0_F.$Builder As System.Runtime.CompilerServices.AsyncTaskMethodBuilder(Of Boolean)
""
IL_0
102
: ldloc.0
IL_0
103
: call
""
Sub System.Runtime.CompilerServices.AsyncTaskMethodBuilder(Of Boolean).SetResult(Boolean)
""
IL_0
108
: nop
IL_0
109
: ret
-IL_00
e6
: ldarg.0
IL_00
e7
: ldc.i4.s -2
IL_00
e9
: dup
IL_00
ea
: stloc.1
IL_00
eb
: stfld
""
M.VB$StateMachine_0_F.$State As Integer
""
~IL_00f
0
: ldarg.0
IL_00f
1
: ldflda
""
M.VB$StateMachine_0_F.$Builder As System.Runtime.CompilerServices.AsyncTaskMethodBuilder(Of Boolean)
""
IL_0
0f6
: ldloc.0
IL_0
0f7
: call
""
Sub System.Runtime.CompilerServices.AsyncTaskMethodBuilder(Of Boolean).SetResult(Boolean)
""
IL_0
0fc
: nop
IL_0
0fd
: ret
}
"
,
sequencePoints
:
=
"M+VB$StateMachine_0_F.MoveNext"
)
End
Sub
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录