`EnsureCSharpSymbolOrNull` throws in some IDE features
Nobody has claimed this yet.
- Dominant language
- C#
- Stars
- 20.7k
- Forks
- 4.3k
- PR merge metrics
- PR metrics pending
Description
Hit in latest main, but likely a bug that has been since long and affects multiple IDE features. For example, https://github.com/dotnet/roslyn/issues/37333 was previously opened.
I don't have a minimal repro but I have insights as to what's going on.
First, this is the callstack I'm hitting this in:
Microsoft.CodeAnalysis.CSharp.dll!Microsoft.CodeAnalysis.CSharp.Symbols.SymbolExtensions.EnsureCSharpSymbolOrNull(Microsoft.CodeAnalysis.ISymbol symbol, string paramName) Line 378
at /_/src/Compilers/CSharp/Portable/Symbols/SymbolExtensions.cs(378)
Microsoft.CodeAnalysis.CSharp.dll!Microsoft.CodeAnalysis.CSharp.CSharpCompilation.ClassifyConversion(Microsoft.CodeAnalysis.ITypeSymbol source, Microsoft.CodeAnalysis.ITypeSymbol destination) Line 2412
at /_/src/Compilers/CSharp/Portable/Compilation/CSharpCompilation.cs(2412)
Microsoft.CodeAnalysis.CSharp.dll!Microsoft.CodeAnalysis.CSharp.CSharpCompilation.ClassifyCommonConversion(Microsoft.CodeAnalysis.ITypeSymbol source, Microsoft.CodeAnalysis.ITypeSymbol destination) Line 2431
at /_/src/Compilers/CSharp/Portable/Compilation/CSharpCompilation.cs(2431)
Microsoft.CodeAnalysis.Features.dll!Microsoft.CodeAnalysis.ImplementInterface.AbstractImplementInterfaceService<System.__Canon>.ImplementInterfaceGenerator.CanForwardToConflictingMethod.AnonymousMethod__1((Microsoft.CodeAnalysis.IParameterSymbol p1, Microsoft.CodeAnalysis.IParameterSymbol p2) t) Line 82
at /_/src/Analyzers/Core/CodeFixes/ImplementInterface/ImplementInterfaceGenerator_Method.cs(82)
System.Core.dll!System.Linq.Enumerable.Any<(Microsoft.CodeAnalysis.IParameterSymbol, Microsoft.CodeAnalysis.IParameterSymbol)>(System.Collections.Generic.IEnumerable<(Microsoft.CodeAnalysis.IParameterSymbol, Microsoft.CodeAnalysis.IParameterSymbol)> source, System.Func<(Microsoft.CodeAnalysis.IParameterSymbol, Microsoft.CodeAnalysis.IParameterSymbol), bool> predicate) Line 3148
at System.Linq\Enumerable.cs(3148)
Microsoft.CodeAnalysis.Features.dll!Microsoft.CodeAnalysis.ImplementInterface.AbstractImplementInterfaceService<Microsoft.CodeAnalysis.CSharp.Syntax.TypeDeclarationSyntax>.ImplementInterfaceGenerator.CanForwardToConflictingMethod(Microsoft.CodeAnalysis.Compilation compilation, Microsoft.CodeAnalysis.IMethodSymbol method, Microsoft.CodeAnalysis.IMethodSymbol conflictingMethod) Line 81
at /_/src/Analyzers/Core/CodeFixes/ImplementInterface/ImplementInterfaceGenerator_Method.cs(81)
Microsoft.CodeAnalysis.Features.dll!Microsoft.CodeAnalysis.ImplementInterface.AbstractImplementInterfaceService<Microsoft.CodeAnalysis.CSharp.Syntax.TypeDeclarationSyntax>.ImplementInterfaceGenerator.GenerateStatement(Microsoft.CodeAnalysis.Compilation compilation, Microsoft.CodeAnalysis.IMethodSymbol updatedMethod, Microsoft.CodeAnalysis.IMethodSymbol conflictingMethod) Line 53
at /_/src/Analyzers/Core/CodeFixes/ImplementInterface/ImplementInterfaceGenerator_Method.cs(53)
Microsoft.CodeAnalysis.Features.dll!Microsoft.CodeAnalysis.ImplementInterface.AbstractImplementInterfaceService<Microsoft.CodeAnalysis.CSharp.Syntax.TypeDeclarationSyntax>.ImplementInterfaceGenerator.GenerateMethod(Microsoft.CodeAnalysis.Compilation compilation, Microsoft.CodeAnalysis.IMethodSymbol method, Microsoft.CodeAnalysis.IMethodSymbol conflictingMethod, Microsoft.CodeAnalysis.Accessibility accessibility, Microsoft.CodeAnalysis.Editing.DeclarationModifiers modifiers, bool generateAbstractly, bool useExplicitInterfaceSymbol, string memberName) Line 36
at /_/src/Analyzers/Core/CodeFixes/ImplementInterface/ImplementInterfaceGenerator_Method.cs(36)
Microsoft.CodeAnalysis.Features.dll!Microsoft.CodeAnalysis.ImplementInterface.AbstractImplementInterfaceService<System.__Canon>.ImplementInterfaceGenerator.GenerateMembers(Microsoft.CodeAnalysis.Compilation compilation, Microsoft.CodeAnalysis.ISymbol member, Microsoft.CodeAnalysis.ISymbol conflictingMember, string memberName, bool generateInvisibly, bool generateAbstractly, bool addNew, bool addUnsafe, Microsoft.CodeAnalysis.ImplementType.ImplementTypePropertyGenerationBehavior propertyGenerationBehavior) Line 299
at /_/src/Analyzers/Core/CodeFixes/ImplementInterface/ImplementInterfaceGenerator.cs(299)
Microsoft.CodeAnalysis.Features.dll!Microsoft.CodeAnalysis.ImplementInterface.AbstractImplementInterfaceService<System.__Canon>.ImplementInterfaceGenerator.GenerateMembers(Microsoft.CodeAnalysis.Compilation compilation, Microsoft.CodeAnalysis.ParseOptions options, Microsoft.CodeAnalysis.ISymbol member, Microsoft.CodeAnalysis.PooledObjects.ArrayBuilder<Microsoft.CodeAnalysis.ISymbol> implementedVisibleMembers, Microsoft.CodeAnalysis.ImplementType.ImplementTypePropertyGenerationBehavior propertyGenerationBehavior) Line 217
at /_/src/Analyzers/Core/CodeFixes/ImplementInterface/ImplementInterfaceGenerator.cs(217)
Microsoft.CodeAnalysis.Features.dll!Microsoft.CodeAnalysis.ImplementInterface.AbstractImplementInterfaceService<Microsoft.CodeAnalysis.CSharp.Syntax.TypeDeclarationSyntax>.ImplementInterfaceGenerator.GenerateMembers(Microsoft.CodeAnalysis.Compilation compilation, Microsoft.CodeAnalysis.ParseOptions options, System.Collections.Immutable.ImmutableArray<(Microsoft.CodeAnalysis.INamedTypeSymbol type, System.Collections.Immutable.ImmutableArray<Microsoft.CodeAnalysis.ISymbol> members)> unimplementedMembers, Microsoft.CodeAnalysis.ImplementType.ImplementTypePropertyGenerationBehavior propertyGenerationBehavior) Line 127
at /_/src/Analyzers/Core/CodeFixes/ImplementInterface/ImplementInterfaceGenerator.cs(127)
Microsoft.CodeAnalysis.Features.dll!Microsoft.CodeAnalysis.ImplementInterface.AbstractImplementInterfaceService<Microsoft.CodeAnalysis.CSharp.Syntax.TypeDeclarationSyntax>.ImplementInterfaceGenerator.ImplementInterfaceAsync(System.Collections.Immutable.ImmutableArray<(Microsoft.CodeAnalysis.INamedTypeSymbol type, System.Collections.Immutable.ImmutableArray<Microsoft.CodeAnalysis.ISymbol> members)> unimplementedMembers, System.Collections.Immutable.ImmutableArray<Microsoft.CodeAnalysis.ISymbol> extraMembers, System.Threading.CancellationToken cancellationToken) Line 98
at /_/src/Analyzers/Core/CodeFixes/ImplementInterface/ImplementInterfaceGenerator.cs(98)
Microsoft.CodeAnalysis.Features.dll!Microsoft.CodeAnalysis.ImplementInterface.AbstractImplementInterfaceService<System.__Canon>.ImplementInterfaceGenerator.ImplementInterfaceAsync(System.Threading.CancellationToken cancellationToken) Line 64
at /_/src/Analyzers/Core/CodeFixes/ImplementInterface/ImplementInterfaceGenerator.cs(64)
Microsoft.CodeAnalysis.Features.dll!Microsoft.CodeAnalysis.ImplementInterface.AbstractImplementInterfaceService<Microsoft.CodeAnalysis.CSharp.Syntax.TypeDeclarationSyntax>.ImplementInterfaceAsync(Microsoft.CodeAnalysis.Document document, Microsoft.CodeAnalysis.ImplementInterface.ImplementInterfaceInfo info, Microsoft.CodeAnalysis.ImplementType.ImplementTypeOptions options, Microsoft.CodeAnalysis.ImplementInterface.ImplementInterfaceConfiguration configuration, System.Threading.CancellationToken cancellationToken) Line 116
at /_/src/Analyzers/Core/CodeFixes/ImplementInterface/AbstractImplementInterfaceService.cs(116)
Microsoft.CodeAnalysis.Features.dll!Microsoft.CodeAnalysis.ImplementInterface.AbstractImplementInterfaceService<System.__Canon>.GetCodeActionsAsync.AnonymousMethod__0(System.Threading.CancellationToken cancellationToken) Line 165
at /_/src/Analyzers/Core/CodeFixes/ImplementInterface/AbstractImplementInterfaceService.cs(165)
Microsoft.CodeAnalysis.Workspaces.dll!Microsoft.CodeAnalysis.CodeActions.CodeAction.Create.AnonymousMethod__0(System.IProgress<Microsoft.CodeAnalysis.CodeAnalysisProgress> _, System.Threading.CancellationToken c) Line 487
at /_/src/Workspaces/Core/Portable/CodeActions/CodeAction.cs(487)
Microsoft.CodeAnalysis.Workspaces.dll!Microsoft.CodeAnalysis.CodeActions.CodeAction.DocumentChangeAction.GetChangedDocumentAsync(System.IProgress<Microsoft.CodeAnalysis.CodeAnalysisProgress> progress, System.Threading.CancellationToken cancellationToken) Line 694
at /_/src/Workspaces/Core/Portable/CodeActions/CodeAction.cs(694)
Microsoft.CodeAnalysis.Workspaces.dll!Microsoft.CodeAnalysis.CodeActions.CodeAction.GetChangedSolutionAsync(System.IProgress<Microsoft.CodeAnalysis.CodeAnalysisProgress> progress, System.Threading.CancellationToken cancellationToken) Line 356
at /_/src/Workspaces/Core/Portable/CodeActions/CodeAction.cs(356)
Microsoft.CodeAnalysis.Workspaces.dll!Microsoft.CodeAnalysis.CodeActions.CodeAction.ComputeOperationsAsync(System.IProgress<Microsoft.CodeAnalysis.CodeAnalysisProgress> progress, System.Threading.CancellationToken cancellationToken) Line 310
at /_/src/Workspaces/Core/Portable/CodeActions/CodeAction.cs(310)
Microsoft.CodeAnalysis.Workspaces.dll!Microsoft.CodeAnalysis.CodeActions.CodeAction.ComputePreviewOperationsAsync(System.Threading.CancellationToken cancellationToken) Line 324
at /_/src/Workspaces/Core/Portable/CodeActions/CodeAction.cs(324)
Microsoft.CodeAnalysis.Workspaces.dll!Microsoft.CodeAnalysis.CodeActions.CodeAction.DocumentChangeAction.ComputePreviewOperationsAsync(System.Threading.CancellationToken cancellationToken) Line 687
at /_/src/Workspaces/Core/Portable/CodeActions/CodeAction.cs(687)
Microsoft.CodeAnalysis.Workspaces.dll!Microsoft.CodeAnalysis.CodeActions.CodeAction.GetPreviewOperationsAsync(Microsoft.CodeAnalysis.Solution originalSolution, System.Threading.CancellationToken cancellationToken) Line 268
at /_/src/Workspaces/Core/Portable/CodeActions/CodeAction.cs(268)
Microsoft.CodeAnalysis.EditorFeatures.dll!Microsoft.CodeAnalysis.Editor.Implementation.Suggestions.EditorSuggestedAction.GetPreviewOperationsAsync(System.Threading.CancellationToken cancellationToken) Line 81
at /_/src/EditorFeatures/Core/Suggestions/SuggestedActions/EditorSuggestedAction.cs(81)
[Resuming Async Method]
mscorlib.dll!System.Threading.ExecutionContext.RunInternal(System.Threading.ExecutionContext executionContext, System.Threading.ContextCallback callback, object state, bool preserveSyncCtx) Line 980
at f:\dd\ndp\clr\src\BCL\system\threading\executioncontext.cs(980)
mscorlib.dll!System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext executionContext, System.Threading.ContextCallback callback, object state, bool preserveSyncCtx) Line 927
at f:\dd\ndp\clr\src\BCL\system\threading\executioncontext.cs(927)
mscorlib.dll!System.Runtime.CompilerServices.AsyncMethodBuilderCore.MoveNextRunner.Run() Line 1070
at f:\dd\ndp\clr\src\BCL\system\runtime\compilerservices\AsyncMethodBuilder.cs(1070)
mscorlib.dll!System.Runtime.CompilerServices.AsyncMethodBuilderCore.OutputAsyncCausalityEvents.AnonymousMethod__0() Line 975
at f:\dd\ndp\clr\src\BCL\system\runtime\compilerservices\AsyncMethodBuilder.cs(975)
mscorlib.dll!System.Threading.QueueUserWorkItemCallback.System.Threading.IThreadPoolWorkItem.ExecuteWorkItem() Line 1246
at f:\dd\ndp\clr\src\BCL\system\threading\threadpool.cs(1246)
mscorlib.dll!System.Threading.ThreadPoolWorkQueue.Dispatch() Line 819
at f:\dd\ndp\clr\src\BCL\system\threading\threadpool.cs(819)
[Async Call Stack]
[Async] Microsoft.CodeAnalysis.EditorFeatures.dll!Microsoft.CodeAnalysis.Editor.Implementation.Suggestions.EditorSuggestedAction.GetPreviewResultAsync(System.Threading.CancellationToken cancellationToken) Line 214
at /_/src/EditorFeatures/Core/Suggestions/SuggestedActions/EditorSuggestedAction.cs(214)
[Async] Microsoft.CodeAnalysis.EditorFeatures.dll!Microsoft.CodeAnalysis.Editor.Implementation.Suggestions.EditorSuggestedActionWithNestedFlavors.GetPreviewAsync.AnonymousMethod__0(System.Threading.CancellationToken cancellationToken) Line 175
at /_/src/EditorFeatures/Core/Suggestions/SuggestedActions/EditorSuggestedActionWithNestedFlavors.cs(175)
[Async] Microsoft.CodeAnalysis.Workspaces.dll!Microsoft.CodeAnalysis.Extensions.IExtensionManagerExtensions.PerformFunctionAsync<System.Collections.Generic.IReadOnlyList<object>>(Microsoft.CodeAnalysis.Extensions.IExtensionManager extensionManager, object extension, System.Func<System.Threading.CancellationToken, System.Threading.Tasks.Task<System.Collections.Generic.IReadOnlyList<object>>> function, System.Collections.Generic.IReadOnlyList<object> defaultValue, System.Threading.CancellationToken cancellationToken) Line 80
at /_/src/Workspaces/Core/Portable/ExtensionManager/IExtensionManagerExtensions.cs(80)
[Async] Microsoft.CodeAnalysis.EditorFeatures.dll!Microsoft.CodeAnalysis.Editor.Implementation.Suggestions.EditorSuggestedActionWithNestedFlavors.GetPreviewAsync(System.Threading.CancellationToken cancellationToken) Line 171
at /_/src/EditorFeatures/Core/Suggestions/SuggestedActions/EditorSuggestedActionWithNestedFlavors.cs(171)
[Async] Microsoft.VisualStudio.Platform.VSEditor.dll!Microsoft.VisualStudio.Text.Utilities.GuardedOperations.CallExtensionPointAsync<object>(object errorSource, System.Func<System.Threading.Tasks.Task<object>> asyncCall, object valueOnThrow) Line 654
at D:\a\_work\1\s\src\Editor\Text\Util\TextDataUtil\GuardedOperations.cs(654)
[Async] Microsoft.VisualStudio.Platform.VSEditor.dll!Microsoft.VisualStudio.Language.Intellisense.Implementation.LightBulbSession.GetPreviewAsync(Microsoft.VisualStudio.Language.Intellisense.ISuggestedAction action, System.Threading.CancellationToken showPreviewCancellationToken) Line 532
at D:\a\_work\1\s\src\Editor\Language\Impl\Intellisense\LightBulb\LightBulbSession.cs(532)
[Async] Microsoft.VisualStudio.Platform.VSEditor.dll!Microsoft.VisualStudio.Language.Intellisense.Implementation.LightBulbMenuItem.GetOrCreatePreviewAsync(System.Func<System.Threading.Tasks.Task<object>> previewCreator, System.Threading.CancellationToken cancellationToken) Line 755
at D:\a\_work\1\s\src\Editor\Language\Impl\Intellisense\LightBulb\DefaultPresenter\LightBulbMenuItem.cs(755)
[Async] Microsoft.VisualStudio.Platform.VSEditor.dll!Microsoft.VisualStudio.Language.Intellisense.Implementation.LightBulbMenuItem.InitializeFlavoredAsync(Microsoft.VisualStudio.Language.Intellisense.Implementation.LightBulb lightBulbControl, System.Threading.CancellationToken cancellationToken) Line 273
at D:\a\_work\1\s\src\Editor\Language\Impl\Intellisense\LightBulb\DefaultPresenter\LightBulbMenuItem.cs(273)
[Async] Microsoft.VisualStudio.Platform.VSEditor.dll!Microsoft.VisualStudio.Language.Intellisense.Implementation.LightBulbMenuItem.InitializeAsync(System.Threading.CancellationToken cancellationToken) Line 166
at D:\a\_work\1\s\src\Editor\Language\Impl\Intellisense\LightBulb\DefaultPresenter\LightBulbMenuItem.cs(166)
[Async] Microsoft.VisualStudio.Platform.VSEditor.dll!Microsoft.VisualStudio.Language.Intellisense.Implementation.LightBulb.OnMenuItemGotKeyboardFocus(Microsoft.VisualStudio.Language.Intellisense.ISuggestedAction action, System.Windows.Input.KeyboardFocusChangedEventArgs e, Microsoft.VisualStudio.Language.Intellisense.Implementation.LightBulbMenuItem menuItem) Line 390
at D:\a\_work\1\s\src\Editor\Language\Impl\Intellisense\LightBulb\DefaultPresenter\LightBulb.xaml.cs(390)
The symbol in question is CodeGenerationConstructedNamedTypeSymbol. This is IDE-specific implementation that the compiler isn't aware of and cannot deal with as of today.
The interesting stack frame looks like the following to me:
The bad symbol is likely coming from either EnsureNonConflictingNames or RemoveInaccessibleAttributesAndAttributesOfTypes.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with EnsureCSharpSymbolOrNull in src/Compilers/CSharp/Portable/Symbols/SymbolExtensions.cs and trace the call path through CSharpCompilation.cs into ImplementInterfaceGenerator_Method.cs. Compare the behavior with the context in issue #37333, then investigate a minimal reproduction for the reported IDE feature failure. Done means the affected IDE feature no longer throws, with regression coverage for the failure if an appropriate test location is identified.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- csharp
- Domain
- devtools
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Quiet
- Clarity
- Needs clarification
- Newbie friendliness
- 35/100