Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Nested local functions causes KeyNotFoundException #21645

Closed
Keboo opened this issue Aug 21, 2017 · 3 comments
Closed

Nested local functions causes KeyNotFoundException #21645

Keboo opened this issue Aug 21, 2017 · 3 comments
Assignees
Milestone

Comments

@Keboo
Copy link
Member

Keboo commented Aug 21, 2017

Version Used:
Microsoft Visual Studio Enterprise 2017
Version 15.3.1
VisualStudio.15.Release/15.3.1+26730.8
Microsoft .NET Framework
Version 4.7.02046

Steps to Reproduce:

  1. Create a new C# project
  2. Add the following code
public class Class1
{
    private void Test()
    {
        bool outside = true;

        void Inner() //This can also be a lambda (ie. Action action = () => { ... };)
        {
            void Bar()
            {
            }

            void Foo()
            {
                Bar();

                bool captured = outside;
            }
        }
    }
}
  1. Compile with VS 2017 15.3.1

Example repository available here.
This same code does compile with VS 2017 v15.2 (26430.15 release).

Expected Behavior:
Compile succeeds without error.

Actual Behavior:
CSC.exe crash with error code -2146232797

MSBuild output:

1>  Task "Csc"
1>    C:\Program Files (x86)\Microsoft Visual Studio\2017\Enterprise\MSBuild\15.0\Bin\Roslyn\csc.exe /noconfig /unsafe- /checked- /nowarn:1701,1702,1705,1701,1702,2008 /nostdlib+ /errorreport:prompt /warn:4 /define:TRACE;DEBUG;NETSTANDARD1_4 /errorendlocation /preferreduilang:en-US /reference:C:\Users\Kevin\.nuget\packages\microsoft.win32.primitives\4.3.0\ref\netstandard1.3\Microsoft.Win32.Primitives.dll /reference:C:\Users\Kevin\.nuget\packages\system.appcontext\4.3.0\ref\netstandard1.3\System.AppContext.dll /reference:C:\Users\Kevin\.nuget\packages\system.collections.concurrent\4.3.0\ref\netstandard1.3\System.Collections.Concurrent.dll /reference:C:\Users\Kevin\.nuget\packages\system.collections\4.3.0\ref\netstandard1.3\System.Collections.dll /reference:C:\Users\Kevin\.nuget\packages\system.console\4.3.0\ref\netstandard1.3\System.Console.dll /reference:C:\Users\Kevin\.nuget\packages\system.diagnostics.debug\4.3.0\ref\netstandard1.3\System.Diagnostics.Debug.dll /reference:C:\Users\Kevin\.nuget\packages\system.diagnostics.tools\4.3.0\ref\netstandard1.0\System.Diagnostics.Tools.dll /reference:C:\Users\Kevin\.nuget\packages\system.diagnostics.tracing\4.3.0\ref\netstandard1.3\System.Diagnostics.Tracing.dll /reference:C:\Users\Kevin\.nuget\packages\system.globalization.calendars\4.3.0\ref\netstandard1.3\System.Globalization.Calendars.dll /reference:C:\Users\Kevin\.nuget\packages\system.globalization\4.3.0\ref\netstandard1.3\System.Globalization.dll /reference:C:\Users\Kevin\.nuget\packages\system.io.compression\4.3.0\ref\netstandard1.3\System.IO.Compression.dll /reference:C:\Users\Kevin\.nuget\packages\system.io.compression.zipfile\4.3.0\ref\netstandard1.3\System.IO.Compression.ZipFile.dll /reference:C:\Users\Kevin\.nuget\packages\system.io\4.3.0\ref\netstandard1.3\System.IO.dll /reference:C:\Users\Kevin\.nuget\packages\system.io.filesystem\4.3.0\ref\netstandard1.3\System.IO.FileSystem.dll /reference:C:\Users\Kevin\.nuget\packages\system.io.filesystem.primitives\4.3.0\ref\netstandard1.3\System.IO.FileSystem.Primitives.dll /reference:C:\Users\Kevin\.nuget\packages\system.linq\4.3.0\ref\netstandard1.0\System.Linq.dll /reference:C:\Users\Kevin\.nuget\packages\system.linq.expressions\4.3.0\ref\netstandard1.3\System.Linq.Expressions.dll /reference:C:\Users\Kevin\.nuget\packages\system.net.http\4.3.0\ref\netstandard1.3\System.Net.Http.dll /reference:C:\Users\Kevin\.nuget\packages\system.net.primitives\4.3.0\ref\netstandard1.3\System.Net.Primitives.dll /reference:C:\Users\Kevin\.nuget\packages\system.net.sockets\4.3.0\ref\netstandard1.3\System.Net.Sockets.dll /reference:C:\Users\Kevin\.nuget\packages\system.objectmodel\4.3.0\ref\netstandard1.3\System.ObjectModel.dll /reference:C:\Users\Kevin\.nuget\packages\system.reflection\4.3.0\ref\netstandard1.3\System.Reflection.dll /reference:C:\Users\Kevin\.nuget\packages\system.reflection.extensions\4.3.0\ref\netstandard1.0\System.Reflection.Extensions.dll /reference:C:\Users\Kevin\.nuget\packages\system.reflection.primitives\4.3.0\ref\netstandard1.0\System.Reflection.Primitives.dll /reference:C:\Users\Kevin\.nuget\packages\system.resources.resourcemanager\4.3.0\ref\netstandard1.0\System.Resources.ResourceManager.dll /reference:C:\Users\Kevin\.nuget\packages\system.runtime\4.3.0\ref\netstandard1.3\System.Runtime.dll /reference:C:\Users\Kevin\.nuget\packages\system.runtime.extensions\4.3.0\ref\netstandard1.3\System.Runtime.Extensions.dll /reference:C:\Users\Kevin\.nuget\packages\system.runtime.handles\4.3.0\ref\netstandard1.3\System.Runtime.Handles.dll /reference:C:\Users\Kevin\.nuget\packages\system.runtime.interopservices\4.3.0\ref\netstandard1.3\System.Runtime.InteropServices.dll /reference:C:\Users\Kevin\.nuget\packages\system.runtime.interopservices.runtimeinformation\4.3.0\ref\netstandard1.1\System.Runtime.InteropServices.RuntimeInformation.dll /reference:C:\Users\Kevin\.nuget\packages\system.runtime.numerics\4.3.0\ref\netstandard1.1\System.Runtime.Numerics.dll /reference:C:\Users\Kevin\.nuget\packages\system.security.cryptography.algorithms\4.3.0\ref\netstandard1.4\System.Security.Cryptography.Algorithms.dll /reference:C:\Users\Kevin\.nuget\packages\system.security.cryptography.encoding\4.3.0\ref\netstandard1.3\System.Security.Cryptography.Encoding.dll /reference:C:\Users\Kevin\.nuget\packages\system.security.cryptography.primitives\4.3.0\ref\netstandard1.3\System.Security.Cryptography.Primitives.dll /reference:C:\Users\Kevin\.nuget\packages\system.security.cryptography.x509certificates\4.3.0\ref\netstandard1.4\System.Security.Cryptography.X509Certificates.dll /reference:C:\Users\Kevin\.nuget\packages\system.text.encoding\4.3.0\ref\netstandard1.3\System.Text.Encoding.dll /reference:C:\Users\Kevin\.nuget\packages\system.text.encoding.extensions\4.3.0\ref\netstandard1.3\System.Text.Encoding.Extensions.dll /reference:C:\Users\Kevin\.nuget\packages\system.text.regularexpressions\4.3.0\ref\netstandard1.3\System.Text.RegularExpressions.dll /reference:C:\Users\Kevin\.nuget\packages\system.threading\4.3.0\ref\netstandard1.3\System.Threading.dll /reference:C:\Users\Kevin\.nuget\packages\system.threading.tasks\4.3.0\ref\netstandard1.3\System.Threading.Tasks.dll /reference:C:\Users\Kevin\.nuget\packages\system.threading.timer\4.3.0\ref\netstandard1.2\System.Threading.Timer.dll /reference:C:\Users\Kevin\.nuget\packages\system.xml.readerwriter\4.3.0\ref\netstandard1.3\System.Xml.ReaderWriter.dll /reference:C:\Users\Kevin\.nuget\packages\system.xml.xdocument\4.3.0\ref\netstandard1.3\System.Xml.XDocument.dll /debug+ /debug:portable /filealign:512 /nologo /optimize- /out:obj\Debug\netstandard1.4\NestedInnerFunctionsBug.dll /ruleset:"C:\Program Files (x86)\Microsoft Visual Studio\2017\Enterprise\Team Tools\Static Analysis Tools\\Rule Sets\MinimumRecommendedRules.ruleset" /target:library /warnaserror- /utf8output /deterministic+ Class1.cs "C:\Users\Kevin\AppData\Local\Temp\.NETStandard,Version=v1.4.AssemblyAttributes.cs" obj\Debug\netstandard1.4\\TemporaryGeneratedFile_E7A71F73-0F8D-4B9B-B56E-8E70B10BC5D3.cs obj\Debug\netstandard1.4\\TemporaryGeneratedFile_036C0B5B-1481-4323-8D20-8F5ADCB23D92.cs obj\Debug\netstandard1.4\\TemporaryGeneratedFile_5937a670-0e60-4077-877b-f7221da3dda1.cs obj\Debug\netstandard1.4\NestedInnerFunctionsBug.AssemblyInfo.cs
1>    Using shared compilation with compiler from directory: C:\Program Files (x86)\Microsoft Visual Studio\2017\Enterprise\MSBuild\15.0\Bin\Roslyn
1>    C:\Program Files (x86)\Microsoft Visual Studio\2017\Enterprise\MSBuild\15.0\Bin\Roslyn\Microsoft.CSharp.Core.targets(84,5): error MSB6006: "csc.exe" exited with code -2146232797.
1>  Done executing task "Csc" -- FAILED.

Event view log:

Application: csc.exe
Framework Version: v4.0.30319
Description: The application requested process termination through System.Environment.FailFast(string message).
Message: System.Collections.Generic.KeyNotFoundException: The given key was not present in the dictionary.
   at System.ThrowHelper.ThrowKeyNotFoundException()
   at System.Collections.Generic.Dictionary`2.get_Item(TKey key)
   at Microsoft.CodeAnalysis.CSharp.LambdaRewriter.RewriteLambdaOrLocalFunction(IBoundLambdaOrFunction node, ClosureKind& closureKind, NamedTypeSymbol& translatedLambdaContainer, LambdaFrame& containerAsFrame, BoundNode& lambdaScope, DebugId& topLevelMethodId, DebugId& lambdaId)
   at Microsoft.CodeAnalysis.CSharp.LambdaRewriter.VisitLocalFunctionStatement(BoundLocalFunctionStatement node)
   at Microsoft.CodeAnalysis.CSharp.BoundTreeRewriterWithStackGuard.Visit(BoundNode node)
   at Microsoft.CodeAnalysis.CSharp.LambdaRewriter.RewriteBlock(BoundBlock node, ArrayBuilder`1 prologue, ArrayBuilder`1 newLocals)
   at Microsoft.CodeAnalysis.CSharp.LambdaRewriter.VisitBlock(BoundBlock node)
   at Microsoft.CodeAnalysis.CSharp.LambdaRewriter.RewriteLambdaOrLocalFunction(IBoundLambdaOrFunction node, ClosureKind& closureKind, NamedTypeSymbol& translatedLambdaContainer, LambdaFrame& containerAsFrame, BoundNode& lambdaScope, DebugId& topLevelMethodId, DebugId& lambdaId)
   at Microsoft.CodeAnalysis.CSharp.LambdaRewriter.VisitLocalFunctionStatement(BoundLocalFunctionStatement node)
   at Microsoft.CodeAnalysis.CSharp.BoundTreeRewriterWithStackGuard.Visit(BoundNode node)
   at Microsoft.CodeAnalysis.CSharp.LambdaRewriter.RewriteBlock(BoundBlock node, ArrayBuilder`1 prologue, ArrayBuilder`1 newLocals)
   at Microsoft.CodeAnalysis.CSharp.LambdaRewriter.IntroduceFrame(BoundNode node, LambdaFrame frame, Func`3 F)
   at Microsoft.CodeAnalysis.CSharp.LambdaRewriter.VisitBlock(BoundBlock node)
   at Microsoft.CodeAnalysis.CSharp.BoundTreeRewriterWithStackGuard.Visit(BoundNode node)
   at Microsoft.CodeAnalysis.CSharp.LambdaRewriter.Rewrite(BoundStatement loweredBody, NamedTypeSymbol thisType, ParameterSymbol thisParameter, MethodSymbol method, Int32 methodOrdinal, MethodSymbol substitutedSourceMethod, ArrayBuilder`1 lambdaDebugInfoBuilder, ArrayBuilder`1 closureDebugInfoBuilder, VariableSlotAllocator slotAllocatorOpt, TypeCompilationState compilationState, DiagnosticBag diagnostics, HashSet`1 assignLocals)
   at Microsoft.CodeAnalysis.CSharp.MethodCompiler.LowerBodyOrInitializer(MethodSymbol method, Int32 methodOrdinal, BoundStatement body, SynthesizedSubmissionFields previousSubmissionFields, TypeCompilationState compilationState, Boolean instrumentForDynamicAnalysis, DebugDocumentProvider debugDocumentProvider, ImmutableArray`1& dynamicAnalysisSpans, DiagnosticBag diagnostics, VariableSlotAllocator& lazyVariableSlotAllocator, ArrayBuilder`1 lambdaDebugInfoBuilder, ArrayBuilder`1 closureDebugInfoBuilder, StateMachineTypeSymbol& stateMachineTypeOpt)
   at Microsoft.CodeAnalysis.CSharp.MethodCompiler.CompileMethod(MethodSymbol methodSymbol, Int32 methodOrdinal, ProcessedFieldInitializers& processedInitializers, SynthesizedSubmissionFields previousSubmissionFields, TypeCompilationState compilationState)
   at Microsoft.CodeAnalysis.CSharp.MethodCompiler.CompileNamedType(NamedTypeSymbol containingType)
   at Microsoft.CodeAnalysis.CSharp.MethodCompiler.<>c__DisplayClass21_0.<CompileNamedTypeAsTask>b__0()
Stack:
   at System.Environment.FailFast(System.String, System.Exception)
   at Microsoft.CodeAnalysis.FatalError.Report(System.Exception, System.Action`1<System.Exception>)
   at Microsoft.CodeAnalysis.FatalError.ReportUnlessCanceled(System.Exception)
   at Microsoft.CodeAnalysis.CSharp.MethodCompiler+<>c__DisplayClass21_0.<CompileNamedTypeAsTask>b__0()
   at System.ThrowHelper.ThrowKeyNotFoundException()
   at System.Collections.Generic.Dictionary`2[[System.__Canon, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089],[System.__Canon, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]].get_Item(System.__Canon)
   at Microsoft.CodeAnalysis.CSharp.LambdaRewriter.RewriteLambdaOrLocalFunction(Microsoft.CodeAnalysis.CSharp.IBoundLambdaOrFunction, Microsoft.CodeAnalysis.CSharp.ClosureKind ByRef, Microsoft.CodeAnalysis.CSharp.Symbols.NamedTypeSymbol ByRef, Microsoft.CodeAnalysis.CSharp.LambdaFrame ByRef, Microsoft.CodeAnalysis.CSharp.BoundNode ByRef, Microsoft.CodeAnalysis.CodeGen.DebugId ByRef, Microsoft.CodeAnalysis.CodeGen.DebugId ByRef)
   at Microsoft.CodeAnalysis.CSharp.LambdaRewriter.VisitLocalFunctionStatement(Microsoft.CodeAnalysis.CSharp.BoundLocalFunctionStatement)
   at Microsoft.CodeAnalysis.CSharp.BoundTreeRewriterWithStackGuard.Visit(Microsoft.CodeAnalysis.CSharp.BoundNode)
   at Microsoft.CodeAnalysis.CSharp.LambdaRewriter.RewriteBlock(Microsoft.CodeAnalysis.CSharp.BoundBlock, Microsoft.CodeAnalysis.ArrayBuilder`1<Microsoft.CodeAnalysis.CSharp.BoundExpression>, Microsoft.CodeAnalysis.ArrayBuilder`1<Microsoft.CodeAnalysis.CSharp.Symbols.LocalSymbol>)
   at Microsoft.CodeAnalysis.CSharp.LambdaRewriter.VisitBlock(Microsoft.CodeAnalysis.CSharp.BoundBlock)
   at Microsoft.CodeAnalysis.CSharp.LambdaRewriter.RewriteLambdaOrLocalFunction(Microsoft.CodeAnalysis.CSharp.IBoundLambdaOrFunction, Microsoft.CodeAnalysis.CSharp.ClosureKind ByRef, Microsoft.CodeAnalysis.CSharp.Symbols.NamedTypeSymbol ByRef, Microsoft.CodeAnalysis.CSharp.LambdaFrame ByRef, Microsoft.CodeAnalysis.CSharp.BoundNode ByRef, Microsoft.CodeAnalysis.CodeGen.DebugId ByRef, Microsoft.CodeAnalysis.CodeGen.DebugId ByRef)
   at Microsoft.CodeAnalysis.CSharp.LambdaRewriter.VisitLocalFunctionStatement(Microsoft.CodeAnalysis.CSharp.BoundLocalFunctionStatement)
   at Microsoft.CodeAnalysis.CSharp.BoundTreeRewriterWithStackGuard.Visit(Microsoft.CodeAnalysis.CSharp.BoundNode)
   at Microsoft.CodeAnalysis.CSharp.LambdaRewriter.RewriteBlock(Microsoft.CodeAnalysis.CSharp.BoundBlock, Microsoft.CodeAnalysis.ArrayBuilder`1<Microsoft.CodeAnalysis.CSharp.BoundExpression>, Microsoft.CodeAnalysis.ArrayBuilder`1<Microsoft.CodeAnalysis.CSharp.Symbols.LocalSymbol>)
   at Microsoft.CodeAnalysis.CSharp.LambdaRewriter.IntroduceFrame(Microsoft.CodeAnalysis.CSharp.BoundNode, Microsoft.CodeAnalysis.CSharp.LambdaFrame, System.Func`3<Microsoft.CodeAnalysis.ArrayBuilder`1<Microsoft.CodeAnalysis.CSharp.BoundExpression>,Microsoft.CodeAnalysis.ArrayBuilder`1<Microsoft.CodeAnalysis.CSharp.Symbols.LocalSymbol>,Microsoft.CodeAnalysis.CSharp.BoundNode>)
   at Microsoft.CodeAnalysis.CSharp.LambdaRewriter.VisitBlock(Microsoft.CodeAnalysis.CSharp.BoundBlock)
   at Microsoft.CodeAnalysis.CSharp.BoundTreeRewriterWithStackGuard.Visit(Microsoft.CodeAnalysis.CSharp.BoundNode)
   at Microsoft.CodeAnalysis.CSharp.LambdaRewriter.Rewrite(Microsoft.CodeAnalysis.CSharp.BoundStatement, Microsoft.CodeAnalysis.CSharp.Symbols.NamedTypeSymbol, Microsoft.CodeAnalysis.CSharp.Symbols.ParameterSymbol, Microsoft.CodeAnalysis.CSharp.Symbols.MethodSymbol, Int32, Microsoft.CodeAnalysis.CSharp.Symbols.MethodSymbol, Microsoft.CodeAnalysis.ArrayBuilder`1<Microsoft.CodeAnalysis.CodeGen.LambdaDebugInfo>, Microsoft.CodeAnalysis.ArrayBuilder`1<Microsoft.CodeAnalysis.CodeGen.ClosureDebugInfo>, Microsoft.CodeAnalysis.CodeGen.VariableSlotAllocator, Microsoft.CodeAnalysis.CSharp.TypeCompilationState, Microsoft.CodeAnalysis.DiagnosticBag, System.Collections.Generic.HashSet`1<Microsoft.CodeAnalysis.CSharp.Symbols.LocalSymbol>)
   at Microsoft.CodeAnalysis.CSharp.MethodCompiler.LowerBodyOrInitializer(Microsoft.CodeAnalysis.CSharp.Symbols.MethodSymbol, Int32, Microsoft.CodeAnalysis.CSharp.BoundStatement, Microsoft.CodeAnalysis.CSharp.SynthesizedSubmissionFields, Microsoft.CodeAnalysis.CSharp.TypeCompilationState, Boolean, Microsoft.CodeAnalysis.CodeGen.DebugDocumentProvider, System.Collections.Immutable.ImmutableArray`1<Microsoft.CodeAnalysis.CodeGen.SourceSpan> ByRef, Microsoft.CodeAnalysis.DiagnosticBag, Microsoft.CodeAnalysis.CodeGen.VariableSlotAllocator ByRef, Microsoft.CodeAnalysis.ArrayBuilder`1<Microsoft.CodeAnalysis.CodeGen.LambdaDebugInfo>, Microsoft.CodeAnalysis.ArrayBuilder`1<Microsoft.CodeAnalysis.CodeGen.ClosureDebugInfo>, Microsoft.CodeAnalysis.CSharp.StateMachineTypeSymbol ByRef)
   at Microsoft.CodeAnalysis.CSharp.MethodCompiler.CompileMethod(Microsoft.CodeAnalysis.CSharp.Symbols.MethodSymbol, Int32, ProcessedFieldInitializers ByRef, Microsoft.CodeAnalysis.CSharp.SynthesizedSubmissionFields, Microsoft.CodeAnalysis.CSharp.TypeCompilationState)
   at Microsoft.CodeAnalysis.CSharp.MethodCompiler.CompileNamedType(Microsoft.CodeAnalysis.CSharp.Symbols.NamedTypeSymbol)
   at Microsoft.CodeAnalysis.CSharp.MethodCompiler+<>c__DisplayClass21_0.<CompileNamedTypeAsTask>b__0()
   at Roslyn.Utilities.UICultureUtilities+<>c__DisplayClass5_0.<WithCurrentUICulture>b__0()
   at System.Threading.Tasks.Task.Execute()
   at System.Threading.ExecutionContext.RunInternal(System.Threading.ExecutionContext, System.Threading.ContextCallback, System.Object, Boolean)
   at System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext, System.Threading.ContextCallback, System.Object, Boolean)
   at System.Threading.Tasks.Task.ExecuteWithThreadLocal(System.Threading.Tasks.Task ByRef)
   at System.Threading.Tasks.Task.ExecuteEntry(Boolean)
   at System.Threading.ThreadPoolWorkQueue.Dispatch()

Potentially related to #17814 and #16895?

@svick
Copy link
Contributor

svick commented Aug 23, 2017

This seems to have been already fixed by #21367. That change is not included in 15.3, but should be in a future version.

@jaredpar
Copy link
Member

Agree with @svick that this should be fixed already. Will let @agocke verify + add a test case.

@jcouv jcouv added this to the 15.5 milestone Aug 24, 2017
@benjamin-hodgson
Copy link

I'm getting the same error with a slightly different repro:

class Class
{
    public void Meth()
    {
        var x = 3;
        {
            var y = 4;
            void Local()
            {
                Console.WriteLine(x);
                Func<int> f = () => y;
            }
            Local();
        }
    }
}

The key to the repro (at least in this case) appears to be having a local function inside a local function, each of which accesses a different local from two scopes out.

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

No branches or pull requests

7 participants