Skip to content
This repository has been archived by the owner on Jul 15, 2023. It is now read-only.

ccrewrite chokes on async preconditions with using in VS2017 #481

Open
yaakov-h opened this issue Feb 14, 2017 · 0 comments
Open

ccrewrite chokes on async preconditions with using in VS2017 #481

yaakov-h opened this issue Feb 14, 2017 · 0 comments

Comments

@yaakov-h
Copy link
Contributor

Using Visual Studio 2017 Enterprise RC, 15.0.0-RC.4+26206.0

Output:

error CC1017: Malformed contract section in method 'AsyncContracts.AsyncContracts+<DoTheThingSlowly>d__0.MoveNext'

Code that triggers this bug:

using System;
using System.Diagnostics.Contracts;
using System.IO;
using System.Threading.Tasks;

namespace AsyncContracts
{
	public class AsyncContracts
	{
		public static async Task<string> DoTheThingSlowly(object o)
		{
			Contract.Requires(o != null);

			await Task.Delay(TimeSpan.FromSeconds(1));

			using (var s = new MemoryStream())
			{
				await Task.Delay(TimeSpan.FromSeconds(1));
				await Task.Delay(TimeSpan.FromSeconds(1));
				return o.ToString();
			}
		}
	}
}

IL of the generated async state machine:

.class nested private auto ansi sealed beforefieldinit '<DoTheThingSlowly>d__0'
	extends [mscorlib]System.ValueType
	implements [mscorlib]System.Runtime.CompilerServices.IAsyncStateMachine
{
	.custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = (
		01 00 00 00
	)
	// Fields
	.field public int32 '<>1__state'
	.field public valuetype [mscorlib]System.Runtime.CompilerServices.AsyncTaskMethodBuilder`1<string> '<>t__builder'
	.field public object o
	.field private class [mscorlib]System.IO.MemoryStream '<s>5__1'
	.field private valuetype [mscorlib]System.Runtime.CompilerServices.TaskAwaiter '<>u__1'

	// Methods
	.method private final hidebysig newslot virtual 
		instance void MoveNext () cil managed 
	{
		.override method instance void [mscorlib]System.Runtime.CompilerServices.IAsyncStateMachine::MoveNext()
		// Method begins at RVA 0xbe2c
		// Code size 476 (0x1dc)
		.maxstack 3
		.locals init (
			[0] int32,
			[1] string,
			[2] valuetype [mscorlib]System.Runtime.CompilerServices.TaskAwaiter,
			[3] valuetype [mscorlib]System.Runtime.CompilerServices.TaskAwaiter,
			[4] valuetype [mscorlib]System.Runtime.CompilerServices.TaskAwaiter,
			[5] class [mscorlib]System.Exception
		)

		IL_0000: ldarg.0
		IL_0001: ldfld int32 AsyncContracts.AsyncContracts/'<DoTheThingSlowly>d__0'::'<>1__state'
		IL_0006: stloc.0
		.try
		{
			IL_0007: ldloc.0
			IL_0008: brfalse.s IL_0066

			IL_000a: ldloc.0
			IL_000b: ldc.i4.1
			IL_000c: sub
			IL_000d: ldc.i4.1
			IL_000e: ble.un IL_009c

			IL_0013: ldarg.0
			IL_0014: ldfld object AsyncContracts.AsyncContracts/'<DoTheThingSlowly>d__0'::o
			IL_0019: ldnull
			IL_001a: cgt.un
			IL_001c: call void [mscorlib]System.Diagnostics.Contracts.Contract::Requires(bool)
			IL_0021: ldc.r8 1
			IL_002a: call valuetype [mscorlib]System.TimeSpan [mscorlib]System.TimeSpan::FromSeconds(float64)
			IL_002f: call class [mscorlib]System.Threading.Tasks.Task [mscorlib]System.Threading.Tasks.Task::Delay(valuetype [mscorlib]System.TimeSpan)
			IL_0034: callvirt instance valuetype [mscorlib]System.Runtime.CompilerServices.TaskAwaiter [mscorlib]System.Threading.Tasks.Task::GetAwaiter()
			IL_0039: stloc.2
			IL_003a: ldloca.s 2
			IL_003c: call instance bool [mscorlib]System.Runtime.CompilerServices.TaskAwaiter::get_IsCompleted()
			IL_0041: brtrue.s IL_0082

			IL_0043: ldarg.0
			IL_0044: ldc.i4.0
			IL_0045: dup
			IL_0046: stloc.0
			IL_0047: stfld int32 AsyncContracts.AsyncContracts/'<DoTheThingSlowly>d__0'::'<>1__state'
			IL_004c: ldarg.0
			IL_004d: ldloc.2
			IL_004e: stfld valuetype [mscorlib]System.Runtime.CompilerServices.TaskAwaiter AsyncContracts.AsyncContracts/'<DoTheThingSlowly>d__0'::'<>u__1'
			IL_0053: ldarg.0
			IL_0054: ldflda valuetype [mscorlib]System.Runtime.CompilerServices.AsyncTaskMethodBuilder`1<string> AsyncContracts.AsyncContracts/'<DoTheThingSlowly>d__0'::'<>t__builder'
			IL_0059: ldloca.s 2
			IL_005b: ldarg.0
			IL_005c: call instance void valuetype [mscorlib]System.Runtime.CompilerServices.AsyncTaskMethodBuilder`1<string>::AwaitUnsafeOnCompleted<valuetype [mscorlib]System.Runtime.CompilerServices.TaskAwaiter, valuetype AsyncContracts.AsyncContracts/'<DoTheThingSlowly>d__0'>(!!0&, !!1&)
			IL_0061: leave IL_01db

			IL_0066: ldarg.0
			IL_0067: ldfld valuetype [mscorlib]System.Runtime.CompilerServices.TaskAwaiter AsyncContracts.AsyncContracts/'<DoTheThingSlowly>d__0'::'<>u__1'
			IL_006c: stloc.2
			IL_006d: ldarg.0
			IL_006e: ldflda valuetype [mscorlib]System.Runtime.CompilerServices.TaskAwaiter AsyncContracts.AsyncContracts/'<DoTheThingSlowly>d__0'::'<>u__1'
			IL_0073: initobj [mscorlib]System.Runtime.CompilerServices.TaskAwaiter
			IL_0079: ldarg.0
			IL_007a: ldc.i4.m1
			IL_007b: dup
			IL_007c: stloc.0
			IL_007d: stfld int32 AsyncContracts.AsyncContracts/'<DoTheThingSlowly>d__0'::'<>1__state'

			IL_0082: ldloca.s 2
			IL_0084: call instance void [mscorlib]System.Runtime.CompilerServices.TaskAwaiter::GetResult()
			IL_0089: ldloca.s 2
			IL_008b: initobj [mscorlib]System.Runtime.CompilerServices.TaskAwaiter
			IL_0091: ldarg.0
			IL_0092: newobj instance void [mscorlib]System.IO.MemoryStream::.ctor()
			IL_0097: stfld class [mscorlib]System.IO.MemoryStream AsyncContracts.AsyncContracts/'<DoTheThingSlowly>d__0'::'<s>5__1'

			IL_009c: nop
			.try
			{
				IL_009d: ldloc.0
				IL_009e: ldc.i4.1
				IL_009f: beq.s IL_00ed

				IL_00a1: ldloc.0
				IL_00a2: ldc.i4.2
				IL_00a3: beq IL_015c

				IL_00a8: ldc.r8 1
				IL_00b1: call valuetype [mscorlib]System.TimeSpan [mscorlib]System.TimeSpan::FromSeconds(float64)
				IL_00b6: call class [mscorlib]System.Threading.Tasks.Task [mscorlib]System.Threading.Tasks.Task::Delay(valuetype [mscorlib]System.TimeSpan)
				IL_00bb: callvirt instance valuetype [mscorlib]System.Runtime.CompilerServices.TaskAwaiter [mscorlib]System.Threading.Tasks.Task::GetAwaiter()
				IL_00c0: stloc.3
				IL_00c1: ldloca.s 3
				IL_00c3: call instance bool [mscorlib]System.Runtime.CompilerServices.TaskAwaiter::get_IsCompleted()
				IL_00c8: brtrue.s IL_0109

				IL_00ca: ldarg.0
				IL_00cb: ldc.i4.1
				IL_00cc: dup
				IL_00cd: stloc.0
				IL_00ce: stfld int32 AsyncContracts.AsyncContracts/'<DoTheThingSlowly>d__0'::'<>1__state'
				IL_00d3: ldarg.0
				IL_00d4: ldloc.3
				IL_00d5: stfld valuetype [mscorlib]System.Runtime.CompilerServices.TaskAwaiter AsyncContracts.AsyncContracts/'<DoTheThingSlowly>d__0'::'<>u__1'
				IL_00da: ldarg.0
				IL_00db: ldflda valuetype [mscorlib]System.Runtime.CompilerServices.AsyncTaskMethodBuilder`1<string> AsyncContracts.AsyncContracts/'<DoTheThingSlowly>d__0'::'<>t__builder'
				IL_00e0: ldloca.s 3
				IL_00e2: ldarg.0
				IL_00e3: call instance void valuetype [mscorlib]System.Runtime.CompilerServices.AsyncTaskMethodBuilder`1<string>::AwaitUnsafeOnCompleted<valuetype [mscorlib]System.Runtime.CompilerServices.TaskAwaiter, valuetype AsyncContracts.AsyncContracts/'<DoTheThingSlowly>d__0'>(!!0&, !!1&)
				IL_00e8: leave IL_01db

				IL_00ed: ldarg.0
				IL_00ee: ldfld valuetype [mscorlib]System.Runtime.CompilerServices.TaskAwaiter AsyncContracts.AsyncContracts/'<DoTheThingSlowly>d__0'::'<>u__1'
				IL_00f3: stloc.3
				IL_00f4: ldarg.0
				IL_00f5: ldflda valuetype [mscorlib]System.Runtime.CompilerServices.TaskAwaiter AsyncContracts.AsyncContracts/'<DoTheThingSlowly>d__0'::'<>u__1'
				IL_00fa: initobj [mscorlib]System.Runtime.CompilerServices.TaskAwaiter
				IL_0100: ldarg.0
				IL_0101: ldc.i4.m1
				IL_0102: dup
				IL_0103: stloc.0
				IL_0104: stfld int32 AsyncContracts.AsyncContracts/'<DoTheThingSlowly>d__0'::'<>1__state'

				IL_0109: ldloca.s 3
				IL_010b: call instance void [mscorlib]System.Runtime.CompilerServices.TaskAwaiter::GetResult()
				IL_0110: ldloca.s 3
				IL_0112: initobj [mscorlib]System.Runtime.CompilerServices.TaskAwaiter
				IL_0118: ldc.r8 1
				IL_0121: call valuetype [mscorlib]System.TimeSpan [mscorlib]System.TimeSpan::FromSeconds(float64)
				IL_0126: call class [mscorlib]System.Threading.Tasks.Task [mscorlib]System.Threading.Tasks.Task::Delay(valuetype [mscorlib]System.TimeSpan)
				IL_012b: callvirt instance valuetype [mscorlib]System.Runtime.CompilerServices.TaskAwaiter [mscorlib]System.Threading.Tasks.Task::GetAwaiter()
				IL_0130: stloc.s 4
				IL_0132: ldloca.s 4
				IL_0134: call instance bool [mscorlib]System.Runtime.CompilerServices.TaskAwaiter::get_IsCompleted()
				IL_0139: brtrue.s IL_0179

				IL_013b: ldarg.0
				IL_013c: ldc.i4.2
				IL_013d: dup
				IL_013e: stloc.0
				IL_013f: stfld int32 AsyncContracts.AsyncContracts/'<DoTheThingSlowly>d__0'::'<>1__state'
				IL_0144: ldarg.0
				IL_0145: ldloc.s 4
				IL_0147: stfld valuetype [mscorlib]System.Runtime.CompilerServices.TaskAwaiter AsyncContracts.AsyncContracts/'<DoTheThingSlowly>d__0'::'<>u__1'
				IL_014c: ldarg.0
				IL_014d: ldflda valuetype [mscorlib]System.Runtime.CompilerServices.AsyncTaskMethodBuilder`1<string> AsyncContracts.AsyncContracts/'<DoTheThingSlowly>d__0'::'<>t__builder'
				IL_0152: ldloca.s 4
				IL_0154: ldarg.0
				IL_0155: call instance void valuetype [mscorlib]System.Runtime.CompilerServices.AsyncTaskMethodBuilder`1<string>::AwaitUnsafeOnCompleted<valuetype [mscorlib]System.Runtime.CompilerServices.TaskAwaiter, valuetype AsyncContracts.AsyncContracts/'<DoTheThingSlowly>d__0'>(!!0&, !!1&)
				IL_015a: leave.s IL_01db

				IL_015c: ldarg.0
				IL_015d: ldfld valuetype [mscorlib]System.Runtime.CompilerServices.TaskAwaiter AsyncContracts.AsyncContracts/'<DoTheThingSlowly>d__0'::'<>u__1'
				IL_0162: stloc.s 4
				IL_0164: ldarg.0
				IL_0165: ldflda valuetype [mscorlib]System.Runtime.CompilerServices.TaskAwaiter AsyncContracts.AsyncContracts/'<DoTheThingSlowly>d__0'::'<>u__1'
				IL_016a: initobj [mscorlib]System.Runtime.CompilerServices.TaskAwaiter
				IL_0170: ldarg.0
				IL_0171: ldc.i4.m1
				IL_0172: dup
				IL_0173: stloc.0
				IL_0174: stfld int32 AsyncContracts.AsyncContracts/'<DoTheThingSlowly>d__0'::'<>1__state'

				IL_0179: ldloca.s 4
				IL_017b: call instance void [mscorlib]System.Runtime.CompilerServices.TaskAwaiter::GetResult()
				IL_0180: ldloca.s 4
				IL_0182: initobj [mscorlib]System.Runtime.CompilerServices.TaskAwaiter
				IL_0188: ldarg.0
				IL_0189: ldfld object AsyncContracts.AsyncContracts/'<DoTheThingSlowly>d__0'::o
				IL_018e: callvirt instance string [mscorlib]System.Object::ToString()
				IL_0193: stloc.1
				IL_0194: leave.s IL_01c7
			} // end .try
			finally
			{
				IL_0196: ldloc.0
				IL_0197: ldc.i4.0
				IL_0198: bge.s IL_01ad

				IL_019a: ldarg.0
				IL_019b: ldfld class [mscorlib]System.IO.MemoryStream AsyncContracts.AsyncContracts/'<DoTheThingSlowly>d__0'::'<s>5__1'
				IL_01a0: brfalse.s IL_01ad

				IL_01a2: ldarg.0
				IL_01a3: ldfld class [mscorlib]System.IO.MemoryStream AsyncContracts.AsyncContracts/'<DoTheThingSlowly>d__0'::'<s>5__1'
				IL_01a8: callvirt instance void [mscorlib]System.IDisposable::Dispose()

				IL_01ad: endfinally
			} // end handler
		} // end .try
		catch [mscorlib]System.Exception
		{
			IL_01ae: stloc.s 5
			IL_01b0: ldarg.0
			IL_01b1: ldc.i4.s -2
			IL_01b3: stfld int32 AsyncContracts.AsyncContracts/'<DoTheThingSlowly>d__0'::'<>1__state'
			IL_01b8: ldarg.0
			IL_01b9: ldflda valuetype [mscorlib]System.Runtime.CompilerServices.AsyncTaskMethodBuilder`1<string> AsyncContracts.AsyncContracts/'<DoTheThingSlowly>d__0'::'<>t__builder'
			IL_01be: ldloc.s 5
			IL_01c0: call instance void valuetype [mscorlib]System.Runtime.CompilerServices.AsyncTaskMethodBuilder`1<string>::SetException(class [mscorlib]System.Exception)
			IL_01c5: leave.s IL_01db
		} // end handler

		IL_01c7: ldarg.0
		IL_01c8: ldc.i4.s -2
		IL_01ca: stfld int32 AsyncContracts.AsyncContracts/'<DoTheThingSlowly>d__0'::'<>1__state'
		IL_01cf: ldarg.0
		IL_01d0: ldflda valuetype [mscorlib]System.Runtime.CompilerServices.AsyncTaskMethodBuilder`1<string> AsyncContracts.AsyncContracts/'<DoTheThingSlowly>d__0'::'<>t__builder'
		IL_01d5: ldloc.1
		IL_01d6: call instance void valuetype [mscorlib]System.Runtime.CompilerServices.AsyncTaskMethodBuilder`1<string>::SetResult(!0)

		IL_01db: ret
	} // end of method '<DoTheThingSlowly>d__0'::MoveNext

	.method private final hidebysig newslot virtual 
		instance void SetStateMachine (
			class [mscorlib]System.Runtime.CompilerServices.IAsyncStateMachine stateMachine
		) cil managed 
	{
		.custom instance void [mscorlib]System.Diagnostics.DebuggerHiddenAttribute::.ctor() = (
			01 00 00 00
		)
		.override method instance void [mscorlib]System.Runtime.CompilerServices.IAsyncStateMachine::SetStateMachine(class [mscorlib]System.Runtime.CompilerServices.IAsyncStateMachine)
		// Method begins at RVA 0xc048
		// Code size 13 (0xd)
		.maxstack 8

		IL_0000: ldarg.0
		IL_0001: ldflda valuetype [mscorlib]System.Runtime.CompilerServices.AsyncTaskMethodBuilder`1<string> AsyncContracts.AsyncContracts/'<DoTheThingSlowly>d__0'::'<>t__builder'
		IL_0006: ldarg.1
		IL_0007: call instance void valuetype [mscorlib]System.Runtime.CompilerServices.AsyncTaskMethodBuilder`1<string>::SetStateMachine(class [mscorlib]System.Runtime.CompilerServices.IAsyncStateMachine)
		IL_000c: ret
	} // end of method '<DoTheThingSlowly>d__0'::SetStateMachine

} // end of class <DoTheThingSlowly>d__0

IL from VS2015, this works with ccrewrite:

.class nested private auto ansi sealed beforefieldinit '<DoTheThingSlowly>d__0'
	extends [mscorlib]System.ValueType
	implements [mscorlib]System.Runtime.CompilerServices.IAsyncStateMachine
{
	.custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = (
		01 00 00 00
	)
	// Fields
	.field public int32 '<>1__state'
	.field public valuetype [mscorlib]System.Runtime.CompilerServices.AsyncTaskMethodBuilder`1<string> '<>t__builder'
	.field public object o
	.field private class [mscorlib]System.IO.MemoryStream '<s>5__1'
	.field private valuetype [mscorlib]System.Runtime.CompilerServices.TaskAwaiter '<>u__1'

	// Methods
	.method private final hidebysig newslot virtual 
		instance void MoveNext () cil managed 
	{
		.override method instance void [mscorlib]System.Runtime.CompilerServices.IAsyncStateMachine::MoveNext()
		// Method begins at RVA 0xbe2c
		// Code size 482 (0x1e2)
		.maxstack 3
		.locals init (
			[0] int32,
			[1] string,
			[2] valuetype [mscorlib]System.Runtime.CompilerServices.TaskAwaiter,
			[3] valuetype [mscorlib]System.Runtime.CompilerServices.TaskAwaiter,
			[4] valuetype [mscorlib]System.Runtime.CompilerServices.TaskAwaiter,
			[5] class [mscorlib]System.Exception
		)

		IL_0000: ldarg.0
		IL_0001: ldfld int32 AsyncContracts.AsyncContracts/'<DoTheThingSlowly>d__0'::'<>1__state'
		IL_0006: stloc.0
		.try
		{
			IL_0007: ldloc.0
			IL_0008: switch (IL_006c, IL_00a2, IL_00a2)

			IL_0019: ldarg.0
			IL_001a: ldfld object AsyncContracts.AsyncContracts/'<DoTheThingSlowly>d__0'::o
			IL_001f: ldnull
			IL_0020: cgt.un
			IL_0022: call void [mscorlib]System.Diagnostics.Contracts.Contract::Requires(bool)
			IL_0027: ldc.r8 1
			IL_0030: call valuetype [mscorlib]System.TimeSpan [mscorlib]System.TimeSpan::FromSeconds(float64)
			IL_0035: call class [mscorlib]System.Threading.Tasks.Task [mscorlib]System.Threading.Tasks.Task::Delay(valuetype [mscorlib]System.TimeSpan)
			IL_003a: callvirt instance valuetype [mscorlib]System.Runtime.CompilerServices.TaskAwaiter [mscorlib]System.Threading.Tasks.Task::GetAwaiter()
			IL_003f: stloc.2
			IL_0040: ldloca.s 2
			IL_0042: call instance bool [mscorlib]System.Runtime.CompilerServices.TaskAwaiter::get_IsCompleted()
			IL_0047: brtrue.s IL_0088

			IL_0049: ldarg.0
			IL_004a: ldc.i4.0
			IL_004b: dup
			IL_004c: stloc.0
			IL_004d: stfld int32 AsyncContracts.AsyncContracts/'<DoTheThingSlowly>d__0'::'<>1__state'
			IL_0052: ldarg.0
			IL_0053: ldloc.2
			IL_0054: stfld valuetype [mscorlib]System.Runtime.CompilerServices.TaskAwaiter AsyncContracts.AsyncContracts/'<DoTheThingSlowly>d__0'::'<>u__1'
			IL_0059: ldarg.0
			IL_005a: ldflda valuetype [mscorlib]System.Runtime.CompilerServices.AsyncTaskMethodBuilder`1<string> AsyncContracts.AsyncContracts/'<DoTheThingSlowly>d__0'::'<>t__builder'
			IL_005f: ldloca.s 2
			IL_0061: ldarg.0
			IL_0062: call instance void valuetype [mscorlib]System.Runtime.CompilerServices.AsyncTaskMethodBuilder`1<string>::AwaitUnsafeOnCompleted<valuetype [mscorlib]System.Runtime.CompilerServices.TaskAwaiter, valuetype AsyncContracts.AsyncContracts/'<DoTheThingSlowly>d__0'>(!!0&, !!1&)
			IL_0067: leave IL_01e1

			IL_006c: ldarg.0
			IL_006d: ldfld valuetype [mscorlib]System.Runtime.CompilerServices.TaskAwaiter AsyncContracts.AsyncContracts/'<DoTheThingSlowly>d__0'::'<>u__1'
			IL_0072: stloc.2
			IL_0073: ldarg.0
			IL_0074: ldflda valuetype [mscorlib]System.Runtime.CompilerServices.TaskAwaiter AsyncContracts.AsyncContracts/'<DoTheThingSlowly>d__0'::'<>u__1'
			IL_0079: initobj [mscorlib]System.Runtime.CompilerServices.TaskAwaiter
			IL_007f: ldarg.0
			IL_0080: ldc.i4.m1
			IL_0081: dup
			IL_0082: stloc.0
			IL_0083: stfld int32 AsyncContracts.AsyncContracts/'<DoTheThingSlowly>d__0'::'<>1__state'

			IL_0088: ldloca.s 2
			IL_008a: call instance void [mscorlib]System.Runtime.CompilerServices.TaskAwaiter::GetResult()
			IL_008f: ldloca.s 2
			IL_0091: initobj [mscorlib]System.Runtime.CompilerServices.TaskAwaiter
			IL_0097: ldarg.0
			IL_0098: newobj instance void [mscorlib]System.IO.MemoryStream::.ctor()
			IL_009d: stfld class [mscorlib]System.IO.MemoryStream AsyncContracts.AsyncContracts/'<DoTheThingSlowly>d__0'::'<s>5__1'

			IL_00a2: nop
			.try
			{
				IL_00a3: ldloc.0
				IL_00a4: ldc.i4.1
				IL_00a5: beq.s IL_00f3

				IL_00a7: ldloc.0
				IL_00a8: ldc.i4.2
				IL_00a9: beq IL_0162

				IL_00ae: ldc.r8 1
				IL_00b7: call valuetype [mscorlib]System.TimeSpan [mscorlib]System.TimeSpan::FromSeconds(float64)
				IL_00bc: call class [mscorlib]System.Threading.Tasks.Task [mscorlib]System.Threading.Tasks.Task::Delay(valuetype [mscorlib]System.TimeSpan)
				IL_00c1: callvirt instance valuetype [mscorlib]System.Runtime.CompilerServices.TaskAwaiter [mscorlib]System.Threading.Tasks.Task::GetAwaiter()
				IL_00c6: stloc.3
				IL_00c7: ldloca.s 3
				IL_00c9: call instance bool [mscorlib]System.Runtime.CompilerServices.TaskAwaiter::get_IsCompleted()
				IL_00ce: brtrue.s IL_010f

				IL_00d0: ldarg.0
				IL_00d1: ldc.i4.1
				IL_00d2: dup
				IL_00d3: stloc.0
				IL_00d4: stfld int32 AsyncContracts.AsyncContracts/'<DoTheThingSlowly>d__0'::'<>1__state'
				IL_00d9: ldarg.0
				IL_00da: ldloc.3
				IL_00db: stfld valuetype [mscorlib]System.Runtime.CompilerServices.TaskAwaiter AsyncContracts.AsyncContracts/'<DoTheThingSlowly>d__0'::'<>u__1'
				IL_00e0: ldarg.0
				IL_00e1: ldflda valuetype [mscorlib]System.Runtime.CompilerServices.AsyncTaskMethodBuilder`1<string> AsyncContracts.AsyncContracts/'<DoTheThingSlowly>d__0'::'<>t__builder'
				IL_00e6: ldloca.s 3
				IL_00e8: ldarg.0
				IL_00e9: call instance void valuetype [mscorlib]System.Runtime.CompilerServices.AsyncTaskMethodBuilder`1<string>::AwaitUnsafeOnCompleted<valuetype [mscorlib]System.Runtime.CompilerServices.TaskAwaiter, valuetype AsyncContracts.AsyncContracts/'<DoTheThingSlowly>d__0'>(!!0&, !!1&)
				IL_00ee: leave IL_01e1

				IL_00f3: ldarg.0
				IL_00f4: ldfld valuetype [mscorlib]System.Runtime.CompilerServices.TaskAwaiter AsyncContracts.AsyncContracts/'<DoTheThingSlowly>d__0'::'<>u__1'
				IL_00f9: stloc.3
				IL_00fa: ldarg.0
				IL_00fb: ldflda valuetype [mscorlib]System.Runtime.CompilerServices.TaskAwaiter AsyncContracts.AsyncContracts/'<DoTheThingSlowly>d__0'::'<>u__1'
				IL_0100: initobj [mscorlib]System.Runtime.CompilerServices.TaskAwaiter
				IL_0106: ldarg.0
				IL_0107: ldc.i4.m1
				IL_0108: dup
				IL_0109: stloc.0
				IL_010a: stfld int32 AsyncContracts.AsyncContracts/'<DoTheThingSlowly>d__0'::'<>1__state'

				IL_010f: ldloca.s 3
				IL_0111: call instance void [mscorlib]System.Runtime.CompilerServices.TaskAwaiter::GetResult()
				IL_0116: ldloca.s 3
				IL_0118: initobj [mscorlib]System.Runtime.CompilerServices.TaskAwaiter
				IL_011e: ldc.r8 1
				IL_0127: call valuetype [mscorlib]System.TimeSpan [mscorlib]System.TimeSpan::FromSeconds(float64)
				IL_012c: call class [mscorlib]System.Threading.Tasks.Task [mscorlib]System.Threading.Tasks.Task::Delay(valuetype [mscorlib]System.TimeSpan)
				IL_0131: callvirt instance valuetype [mscorlib]System.Runtime.CompilerServices.TaskAwaiter [mscorlib]System.Threading.Tasks.Task::GetAwaiter()
				IL_0136: stloc.s 4
				IL_0138: ldloca.s 4
				IL_013a: call instance bool [mscorlib]System.Runtime.CompilerServices.TaskAwaiter::get_IsCompleted()
				IL_013f: brtrue.s IL_017f

				IL_0141: ldarg.0
				IL_0142: ldc.i4.2
				IL_0143: dup
				IL_0144: stloc.0
				IL_0145: stfld int32 AsyncContracts.AsyncContracts/'<DoTheThingSlowly>d__0'::'<>1__state'
				IL_014a: ldarg.0
				IL_014b: ldloc.s 4
				IL_014d: stfld valuetype [mscorlib]System.Runtime.CompilerServices.TaskAwaiter AsyncContracts.AsyncContracts/'<DoTheThingSlowly>d__0'::'<>u__1'
				IL_0152: ldarg.0
				IL_0153: ldflda valuetype [mscorlib]System.Runtime.CompilerServices.AsyncTaskMethodBuilder`1<string> AsyncContracts.AsyncContracts/'<DoTheThingSlowly>d__0'::'<>t__builder'
				IL_0158: ldloca.s 4
				IL_015a: ldarg.0
				IL_015b: call instance void valuetype [mscorlib]System.Runtime.CompilerServices.AsyncTaskMethodBuilder`1<string>::AwaitUnsafeOnCompleted<valuetype [mscorlib]System.Runtime.CompilerServices.TaskAwaiter, valuetype AsyncContracts.AsyncContracts/'<DoTheThingSlowly>d__0'>(!!0&, !!1&)
				IL_0160: leave.s IL_01e1

				IL_0162: ldarg.0
				IL_0163: ldfld valuetype [mscorlib]System.Runtime.CompilerServices.TaskAwaiter AsyncContracts.AsyncContracts/'<DoTheThingSlowly>d__0'::'<>u__1'
				IL_0168: stloc.s 4
				IL_016a: ldarg.0
				IL_016b: ldflda valuetype [mscorlib]System.Runtime.CompilerServices.TaskAwaiter AsyncContracts.AsyncContracts/'<DoTheThingSlowly>d__0'::'<>u__1'
				IL_0170: initobj [mscorlib]System.Runtime.CompilerServices.TaskAwaiter
				IL_0176: ldarg.0
				IL_0177: ldc.i4.m1
				IL_0178: dup
				IL_0179: stloc.0
				IL_017a: stfld int32 AsyncContracts.AsyncContracts/'<DoTheThingSlowly>d__0'::'<>1__state'

				IL_017f: ldloca.s 4
				IL_0181: call instance void [mscorlib]System.Runtime.CompilerServices.TaskAwaiter::GetResult()
				IL_0186: ldloca.s 4
				IL_0188: initobj [mscorlib]System.Runtime.CompilerServices.TaskAwaiter
				IL_018e: ldarg.0
				IL_018f: ldfld object AsyncContracts.AsyncContracts/'<DoTheThingSlowly>d__0'::o
				IL_0194: callvirt instance string [mscorlib]System.Object::ToString()
				IL_0199: stloc.1
				IL_019a: leave.s IL_01cd
			} // end .try
			finally
			{
				IL_019c: ldloc.0
				IL_019d: ldc.i4.0
				IL_019e: bge.s IL_01b3

				IL_01a0: ldarg.0
				IL_01a1: ldfld class [mscorlib]System.IO.MemoryStream AsyncContracts.AsyncContracts/'<DoTheThingSlowly>d__0'::'<s>5__1'
				IL_01a6: brfalse.s IL_01b3

				IL_01a8: ldarg.0
				IL_01a9: ldfld class [mscorlib]System.IO.MemoryStream AsyncContracts.AsyncContracts/'<DoTheThingSlowly>d__0'::'<s>5__1'
				IL_01ae: callvirt instance void [mscorlib]System.IDisposable::Dispose()

				IL_01b3: endfinally
			} // end handler
		} // end .try
		catch [mscorlib]System.Exception
		{
			IL_01b4: stloc.s 5
			IL_01b6: ldarg.0
			IL_01b7: ldc.i4.s -2
			IL_01b9: stfld int32 AsyncContracts.AsyncContracts/'<DoTheThingSlowly>d__0'::'<>1__state'
			IL_01be: ldarg.0
			IL_01bf: ldflda valuetype [mscorlib]System.Runtime.CompilerServices.AsyncTaskMethodBuilder`1<string> AsyncContracts.AsyncContracts/'<DoTheThingSlowly>d__0'::'<>t__builder'
			IL_01c4: ldloc.s 5
			IL_01c6: call instance void valuetype [mscorlib]System.Runtime.CompilerServices.AsyncTaskMethodBuilder`1<string>::SetException(class [mscorlib]System.Exception)
			IL_01cb: leave.s IL_01e1
		} // end handler

		IL_01cd: ldarg.0
		IL_01ce: ldc.i4.s -2
		IL_01d0: stfld int32 AsyncContracts.AsyncContracts/'<DoTheThingSlowly>d__0'::'<>1__state'
		IL_01d5: ldarg.0
		IL_01d6: ldflda valuetype [mscorlib]System.Runtime.CompilerServices.AsyncTaskMethodBuilder`1<string> AsyncContracts.AsyncContracts/'<DoTheThingSlowly>d__0'::'<>t__builder'
		IL_01db: ldloc.1
		IL_01dc: call instance void valuetype [mscorlib]System.Runtime.CompilerServices.AsyncTaskMethodBuilder`1<string>::SetResult(!0)

		IL_01e1: ret
	} // end of method '<DoTheThingSlowly>d__0'::MoveNext

	.method private final hidebysig newslot virtual 
		instance void SetStateMachine (
			class [mscorlib]System.Runtime.CompilerServices.IAsyncStateMachine stateMachine
		) cil managed 
	{
		.custom instance void [mscorlib]System.Diagnostics.DebuggerHiddenAttribute::.ctor() = (
			01 00 00 00
		)
		.override method instance void [mscorlib]System.Runtime.CompilerServices.IAsyncStateMachine::SetStateMachine(class [mscorlib]System.Runtime.CompilerServices.IAsyncStateMachine)
		// Method begins at RVA 0xc050
		// Code size 13 (0xd)
		.maxstack 8

		IL_0000: ldarg.0
		IL_0001: ldflda valuetype [mscorlib]System.Runtime.CompilerServices.AsyncTaskMethodBuilder`1<string> AsyncContracts.AsyncContracts/'<DoTheThingSlowly>d__0'::'<>t__builder'
		IL_0006: ldarg.1
		IL_0007: call instance void valuetype [mscorlib]System.Runtime.CompilerServices.AsyncTaskMethodBuilder`1<string>::SetStateMachine(class [mscorlib]System.Runtime.CompilerServices.IAsyncStateMachine)
		IL_000c: ret
	} // end of method '<DoTheThingSlowly>d__0'::SetStateMachine

} // end of class <DoTheThingSlowly>d__0

It appears that this block of IL, which exists before the calls to Contract.Requires, is confusing the rewriter. The rewriter seems to understand a switch statement and a simple condition, but not this subtraction-based condition.

IL_0007: ldloc.0
IL_0008: brfalse.s IL_0066

IL_000a: ldloc.0
IL_000b: ldc.i4.1
IL_000c: sub
IL_000d: ldc.i4.1
IL_000e: ble.un IL_009c

(Related to VS2017, so tagging #451 here).

@SergeyTeplyakov Is this something that can be easily fixed?

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant