diff --git a/src/Compilers/CSharp/Portable/CodeGen/Optimizer.cs b/src/Compilers/CSharp/Portable/CodeGen/Optimizer.cs index 8ecd4127f296795878eaee987fb70ea2962b4b57..b9d61ee19696259211de73ba312c0510a84db249 100644 --- a/src/Compilers/CSharp/Portable/CodeGen/Optimizer.cs +++ b/src/Compilers/CSharp/Portable/CodeGen/Optimizer.cs @@ -1756,6 +1756,11 @@ internal override SynthesizedLocalKind SynthesizedKind get { return SynthesizedLocalKind.OptimizerTemp; } } + internal override LocalSymbol WithSynthesizedLocalKindAndSyntax(SynthesizedLocalKind kind, SyntaxNode syntax) + { + throw new NotImplementedException(); + } + internal override SyntaxToken IdentifierToken { get { return default(SyntaxToken); } diff --git a/src/Compilers/CSharp/Portable/Lowering/AsyncRewriter/AwaitExpressionSpiller.cs b/src/Compilers/CSharp/Portable/Lowering/AsyncRewriter/AwaitExpressionSpiller.cs index 1a8be2b6b6012d40fc0b9b2a2e82fe1aceb8fc87..57c06624cc85ae7ed8af9f36063c5795d7ba9113 100644 --- a/src/Compilers/CSharp/Portable/Lowering/AsyncRewriter/AwaitExpressionSpiller.cs +++ b/src/Compilers/CSharp/Portable/Lowering/AsyncRewriter/AwaitExpressionSpiller.cs @@ -1107,11 +1107,8 @@ private void PromoteAndAddLocals(BoundSpillSequenceBuilder builder, ImmutableArr else { Debug.Assert(_F.Syntax.IsKind(SyntaxKind.AwaitExpression)); - - SynthesizedLocal shortLived = (SynthesizedLocal)local; - SynthesizedLocal longLived = shortLived.WithSynthesizedLocalKindAndSyntax(SynthesizedLocalKind.AwaitSpill, _F.Syntax); - _tempSubstitution.Add(shortLived, longLived); - + LocalSymbol longLived = local.WithSynthesizedLocalKindAndSyntax(SynthesizedLocalKind.AwaitSpill, _F.Syntax); + _tempSubstitution.Add(local, longLived); builder.AddLocal(longLived, _F.Diagnostics); } } diff --git a/src/Compilers/CSharp/Portable/Symbols/LocalSymbol.cs b/src/Compilers/CSharp/Portable/Symbols/LocalSymbol.cs index ab6ee087f880d4dd661bda3770b0c95f6692a3b7..2eecb9cf2171daacd8b5aae7fd00de0757019904 100644 --- a/src/Compilers/CSharp/Portable/Symbols/LocalSymbol.cs +++ b/src/Compilers/CSharp/Portable/Symbols/LocalSymbol.cs @@ -25,6 +25,8 @@ protected LocalSymbol() get; } + internal abstract LocalSymbol WithSynthesizedLocalKindAndSyntax(SynthesizedLocalKind kind, SyntaxNode syntax); + internal abstract bool IsImportedFromMetadata { get; diff --git a/src/Compilers/CSharp/Portable/Symbols/Source/SourceLocalSymbol.cs b/src/Compilers/CSharp/Portable/Symbols/Source/SourceLocalSymbol.cs index 2201cf3ab6b589057ba0ea9f86a7ea2d7920ba11..488ad8fba31a7bd8944d8f199da661664c60811f 100644 --- a/src/Compilers/CSharp/Portable/Symbols/Source/SourceLocalSymbol.cs +++ b/src/Compilers/CSharp/Portable/Symbols/Source/SourceLocalSymbol.cs @@ -103,6 +103,11 @@ internal override SynthesizedLocalKind SynthesizedKind get { return SynthesizedLocalKind.UserDefined; } } + internal override LocalSymbol WithSynthesizedLocalKindAndSyntax(SynthesizedLocalKind kind, SyntaxNode syntax) + { + throw ExceptionUtilities.Unreachable; + } + internal override bool IsPinned { get diff --git a/src/Compilers/CSharp/Portable/Symbols/Synthesized/SynthesizedLocal.cs b/src/Compilers/CSharp/Portable/Symbols/Synthesized/SynthesizedLocal.cs index bd230067f3917604433486b1c51a0ccfa209f110..3e2b9ce50158d851e6e21669bbecc13c1142959a 100644 --- a/src/Compilers/CSharp/Portable/Symbols/Synthesized/SynthesizedLocal.cs +++ b/src/Compilers/CSharp/Portable/Symbols/Synthesized/SynthesizedLocal.cs @@ -70,7 +70,7 @@ public SyntaxNode SyntaxOpt get { return _syntaxOpt; } } - internal SynthesizedLocal WithSynthesizedLocalKindAndSyntax(SynthesizedLocalKind kind, SyntaxNode syntax) + internal override LocalSymbol WithSynthesizedLocalKindAndSyntax(SynthesizedLocalKind kind, SyntaxNode syntax) { return new SynthesizedLocal( _containingMethodOpt, diff --git a/src/Compilers/CSharp/Portable/Symbols/Synthesized/TypeSubstitutedLocalSymbol.cs b/src/Compilers/CSharp/Portable/Symbols/Synthesized/TypeSubstitutedLocalSymbol.cs index ba8f2f7189a2874785dbcd921f40edd3f66637e7..bc12f8d0d738a5903111d2f3e4abeceb6788ce91 100644 --- a/src/Compilers/CSharp/Portable/Symbols/Synthesized/TypeSubstitutedLocalSymbol.cs +++ b/src/Compilers/CSharp/Portable/Symbols/Synthesized/TypeSubstitutedLocalSymbol.cs @@ -97,5 +97,15 @@ internal override ImmutableArray GetConstantValueDiagnostics(BoundEx { return _originalVariable.GetConstantValueDiagnostics(boundInitValue); } + + internal override LocalSymbol WithSynthesizedLocalKindAndSyntax(SynthesizedLocalKind kind, SyntaxNode syntax) + { + var origSynthesized = (SynthesizedLocal)_originalVariable; + return new TypeSubstitutedLocalSymbol( + origSynthesized.WithSynthesizedLocalKindAndSyntax(kind, syntax), + _type, + _containingSymbol + ); + } } } diff --git a/src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenAsyncTests.cs b/src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenAsyncTests.cs index 54ee777dafab5112ed5c10b8c84168fa4a252d55..6320dc7ed401d8e65b052d51bb6a09b84ddface5 100644 --- a/src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenAsyncTests.cs +++ b/src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenAsyncTests.cs @@ -3400,6 +3400,48 @@ async Task Test(IDisposable id, Task task) CompileAndVerify(comp.WithOptions(TestOptions.ReleaseExe)); } + [Fact, WorkItem(4697, "https://github.com/dotnet/roslyn/issues/4697")] + public void AwaitInObjInitializer() + { + var source = @" +using System; +using System.Threading.Tasks; + +namespace CompilerCrashRepro2 +{ + public class Item + { + public T Value { get; set; } + } + + public class Crasher + { + public static void Main() + { + var r = Build()().Result.Value; + System.Console.WriteLine(r); + } + + public static Func>> Build() + { + return async () => new Item() + { + Value = await GetValue() + }; + } + + public static Task GetValue() + { + return Task.FromResult(default(T)); + } + } +}"; + var comp = CreateCompilation(source, options: TestOptions.DebugExe); + CompileAndVerify(comp, expectedOutput: "0"); + CompileAndVerify(comp.WithOptions(TestOptions.ReleaseExe), expectedOutput: "0"); + } + + [Fact] public void AwaitInScriptExpression() { diff --git a/src/ExpressionEvaluator/CSharp/Source/ExpressionCompiler/Symbols/EELocalSymbolBase.cs b/src/ExpressionEvaluator/CSharp/Source/ExpressionCompiler/Symbols/EELocalSymbolBase.cs index c84bbf1e72dac9d64e6ccacdc27d3a9c49d3aa2c..d36f918aa33fa89aafabf79b2211eab6a1274b24 100644 --- a/src/ExpressionEvaluator/CSharp/Source/ExpressionCompiler/Symbols/EELocalSymbolBase.cs +++ b/src/ExpressionEvaluator/CSharp/Source/ExpressionCompiler/Symbols/EELocalSymbolBase.cs @@ -43,6 +43,11 @@ internal sealed override SynthesizedLocalKind SynthesizedKind get { return SynthesizedLocalKind.UserDefined; } } + internal sealed override LocalSymbol WithSynthesizedLocalKindAndSyntax(SynthesizedLocalKind kind, SyntaxNode syntax) + { + throw ExceptionUtilities.Unreachable; + } + internal sealed override bool IsImportedFromMetadata { get { return true; }