Assertion in nullability analysis of collection expression with extension `Add` method
- Dominant language
- C#
- Stars
- 20.7k
- Forks
- 4.3k
- PR merge metrics
- PR metrics pending
Description
The following code results in an assertion when calling `VerifyEmitDiagnostics`.
This should have been covered by PR https://github.com/dotnet/roslyn/pull/70192
Relates to nullability work for collection expressions: https://github.com/dotnet/roslyn/issues/68786
```csharp
#nullable enable
using System.Collections;
using System.Collections.Generic;
object? oNull = null;
object oNotNull = new object();
MyCollection c = [oNull, oNotNull];
static class E
{
public static void Add(this MyCollection c, object o) { }
}
public class MyCollection : IEnumerable
{
IEnumerator IEnumerable.GetEnumerator() => throw null!;
IEnumerator IEnumerable.GetEnumerator() => throw null!;
}
```
```
Message:
System.InvalidOperationException : Did not find Microsoft.CodeAnalysis.CSharp.BoundLocal `oNull` in the map.
Stack Trace:
ThrowingTraceListener.Fail(String message, String detailMessage) line 26
TraceInternal.Fail(String message, String detailMessage)
Debug.Fail(String message, String detailMessage)
RoslynDebug.Assert(Boolean condition, AssertInterpolatedStringHandler& message) line 30
DebugVerifier.VerifyExpression(BoundExpression expression, Boolean overrideSkippedExpression) line 75
DebugVerifier.VisitExpressionOrPatternWithoutStackGuard(BoundNode node) line 84
BoundTreeVisitor.VisitExpressionOrPatternWithStackGuard(Int32& recursionDepth, BoundNode node) line 213
DebugVerifier.Visit(BoundNode node) line 100
BoundTreeWalker.VisitList[T](ImmutableArray`1 list) line 23
BoundTreeWalker.VisitCollectionElementInitializer(BoundCollectionElementInitializer node) line 10579
BoundCollectionElementInitializer.Accept(BoundTreeVisitor visitor) line 6893
BoundTreeVisitor.Visit(BoundNode node) line 151
DebugVerifier.VisitExpressionOrPatternWithoutStackGuard(BoundNode node) line 86
BoundTreeVisitor.VisitExpressionOrPatternWithStackGuard(Int32& recursionDepth, BoundNode node) line 213
DebugVerifier.Visit(BoundNode node) line 100
DebugVerifier.VisitCollectionExpression(BoundCollectionExpression node) line 146
BoundCollectionExpression.Accept(BoundTreeVisitor visitor) line 6461
BoundTreeVisitor.Visit(BoundNode node) line 151
DebugVerifier.VisitExpressionOrPatternWithoutStackGuard(BoundNode node) line 86
BoundTreeVisitor.VisitExpressionOrPatternWithStackGuard(Int32& recursionDepth, BoundNode node) line 213
DebugVerifier.Visit(BoundNode node) line 100
BoundTreeWalker.VisitConversion(BoundConversion node) line 10076
DebugVerifier.VisitConversion(BoundConversion node) line 408
BoundConversion.Accept(BoundTreeVisitor visitor) line 2978
BoundTreeVisitor.Visit(BoundNode node) line 151
DebugVerifier.VisitExpressionOrPatternWithoutStackGuard(BoundNode node) line 86
BoundTreeVisitor.VisitExpressionOrPatternWithStackGuard(Int32& recursionDepth, BoundNode node) line 213
DebugVerifier.Visit(BoundNode node) line 100
BoundTreeWalker.VisitLocalDeclaration(BoundLocalDeclaration node) line 10127
BoundLocalDeclaration.Accept(BoundTreeVisitor visitor) line 3419
BoundTreeVisitor.Visit(BoundNode node) line 151
DebugVerifier.Visit(BoundNode node) line 102
BoundTreeWalker.VisitList[T](ImmutableArray`1 list) line 23
BoundTreeWalker.VisitBlock(BoundBlock node) line 10111
BoundBlock.Accept(BoundTreeVisitor visitor) line 3323
BoundTreeVisitor.Visit(BoundNode node) line 151
DebugVerifier.Visit(BoundNode node) line 102
BoundTreeWalker.VisitNonConstructorMethodBody(BoundNonConstructorMethodBody node) line 10808
BoundNonConstructorMethodBody.Accept(BoundTreeVisitor visitor) line 8749
BoundTreeVisitor.Visit(BoundNode node) line 151
DebugVerifier.Visit(BoundNode node) line 102
DebugVerifier.Verify(ImmutableDictionary`2 analyzedNullabilityMap, SnapshotManager snapshotManagerOpt, BoundNode node) line 40
NullableWalker.AnalyzeWithSemanticInfo(CSharpCompilation compilation, Symbol symbol, BoundNode node, Binder binder, VariableState initialState, DiagnosticBag diagnostics, Boolean createSnapshots, Boolean requiresAnalysis) line 1634
NullableWalker.AnalyzeAndRewrite(CSharpCompilation compilation, Symbol symbol, BoundNode node, Binder binder, VariableState initialState, DiagnosticBag diagnostics, Boolean createSnapshots, SnapshotManager& snapshotManager, ImmutableDictionary`2& remappedSymbols) line 1586
MethodCompiler.BindMethodBody(MethodSymbol method, TypeCompilationState compilationState, BindingDiagnosticBag diagnostics, Boolean includeInitializersInBody, BoundNode initializersBody, Boolean reportNullableDiagnostics, ImportChain& importChain, Boolean& originalBodyNested, Boolean& prependedDefaultValueTypeConstructorInitializer, InitialState& forSemanticModel) line 1910
MethodCompiler.CompileMethod(MethodSymbol methodSymbol, Int32 methodOrdinal, ProcessedFieldInitializers& processedInitializers, SynthesizedSubmissionFields previousSubmissionFields, TypeCompilationState compilationState) line 1032
MethodCompiler.CompileNamedType(NamedTypeSymbol containingType) line 547
<>c__DisplayClass25_0.b__0() line 440
<>c__DisplayClass5_0.b__0() line 139
ExecutionContext.RunFromThreadPoolDispatchLoop(Thread threadPoolThread, ExecutionContext executionContext, ContextCallback callback, Object state)
--- End of stack trace from previous location ---
ExecutionContext.RunFromThreadPoolDispatchLoop(Thread threadPoolThread, ExecutionContext executionContext, ContextCallback callback, Object state)
Task.ExecuteWithThreadLocal(Task& currentTaskSlot, Thread threadPoolThread)
--- End of stack trace from previous location ---
MethodCompiler.WaitForWorkers() line 339
MethodCompiler.CompileMethodBodies(CSharpCompilation compilation, PEModuleBuilder moduleBeingBuiltOpt, Boolean emittingPdb, Boolean hasDeclarationErrors, Boolean emitMethodBodies, BindingDiagnosticBag diagnostics, Predicate`1 filterOpt, CancellationToken cancellationToken) line 159
CSharpCompilation.CompileMethods(CommonPEModuleBuilder moduleBuilder, Boolean emittingPdb, DiagnosticBag diagnostics, Predicate`1 filterOpt, CancellationToken cancellationToken) line 3546
Compilation.Emit(Stream peStream, Stream metadataPEStream, Stream pdbStream, Stream xmlDocumentationStream, Stream win32Resources, IEnumerable`1 manifestResources, EmitOptions options, IMethodSymbol debugEntryPoint, Stream sourceLinkStream, IEnumerable`1 embeddedTexts, RebuildData rebuildData, CompilationTestData testData, CancellationToken cancellationToken) line 2969
Compilation.Emit(Stream peStream, Stream pdbStream, Stream xmlDocumentationStream, Stream win32Resources, IEnumerable`1 manifestResources, EmitOptions options, IMethodSymbol debugEntryPoint, Stream sourceLinkStream, IEnumerable`1 embeddedTexts, Stream metadataPEStream, RebuildData rebuildData, CancellationToken cancellationToken) line 2910
Compilation.Emit(Stream peStream, Stream pdbStream, Stream xmlDocumentationStream, Stream win32Resources, IEnumerable`1 manifestResources, EmitOptions options, IMethodSymbol debugEntryPoint, Stream sourceLinkStream, IEnumerable`1 embeddedTexts, Stream metadataPEStream, CancellationToken cancellationToken) line 2798
DiagnosticExtensions.GetEmitDiagnostics[TCompilation](TCompilation c, EmitOptions options, IEnumerable`1 manifestResources) line 367
DiagnosticExtensions.VerifyEmitDiagnostics[TCompilation](TCompilation c, EmitOptions options, DiagnosticDescription[] expected) line 356
DiagnosticExtensions.VerifyEmitDiagnostics[TCompilation](TCompilation c, DiagnosticDescription[] expected) line 373
ExtensionTests.Nullability_CollectionExpression_01() line 37042
RuntimeMethodHandle.InvokeMethod(Object target, Void** arguments, Signature sig, Boolean isConstructor)
MethodBaseInvoker.InvokeWithNoArgs(Object obj, BindingFlags invokeAttr)
```
Contributor guide
Assessment
This issue has not been assessed yet.