From d4195ec5b8c9e8e0ddf7822a2097f1acd4631aad Mon Sep 17 00:00:00 2001 From: Fredric Silberberg Date: Fri, 28 Jun 2019 11:24:06 -0700 Subject: [PATCH] Fix some asserts in the DebugVerifier. Remove feature flag requirement from IDE quick info tests. Adjust assert for attributes semantic model. --- ...ticModel.SpeculativeMemberSemanticModel.cs | 10 +++- .../Compilation/MemberSemanticModel.cs | 9 ++-- .../NullableWalker.DebugVerifier.cs | 17 +++++-- .../Portable/FlowAnalysis/NullableWalker.cs | 49 +++++++++++++------ .../FlowAnalysis/NullableWalker_Patterns.cs | 4 ++ .../Symbols/Source/NullablePublicAPITests.cs | 2 +- .../EncapsulateField/EncapsulateFieldTests.cs | 2 +- .../IntroduceVariableTests.cs | 4 +- .../GenerateMethod/GenerateMethodTests.cs | 10 ++-- .../GenerateType/GenerateTypeTests.cs | 2 - .../GenerateConstructorTests.cs | 4 +- .../GenerateVariable/GenerateVariableTests.cs | 8 +-- .../QuickInfo/SemanticQuickInfoSourceTests.cs | 24 ++++----- .../UseLocalFunction/UseLocalFunctionTests.cs | 2 +- .../CSharpSemanticQuickInfoProvider.cs | 5 -- 15 files changed, 94 insertions(+), 58 deletions(-) diff --git a/src/Compilers/CSharp/Portable/Compilation/MemberSemanticModel.SpeculativeMemberSemanticModel.cs b/src/Compilers/CSharp/Portable/Compilation/MemberSemanticModel.SpeculativeMemberSemanticModel.cs index d2152f68848..00b58747892 100644 --- a/src/Compilers/CSharp/Portable/Compilation/MemberSemanticModel.SpeculativeMemberSemanticModel.cs +++ b/src/Compilers/CSharp/Portable/Compilation/MemberSemanticModel.SpeculativeMemberSemanticModel.cs @@ -19,11 +19,17 @@ private sealed class SpeculativeMemberSemanticModel : MemberSemanticModel /// /// Creates a speculative SemanticModel for a TypeSyntax node at a position within an existing MemberSemanticModel. /// - public SpeculativeMemberSemanticModel(SyntaxTreeSemanticModel parentSemanticModel, Symbol owner, TypeSyntax root, Binder rootBinder, int position) - : base(root, owner, rootBinder, containingSemanticModelOpt: null, parentSemanticModelOpt: parentSemanticModel, snapshotManagerOpt: null, speculatedPosition: position) + public SpeculativeMemberSemanticModel(SyntaxTreeSemanticModel parentSemanticModel, Symbol owner, TypeSyntax root, Binder rootBinder, NullableWalker.SnapshotManager snapshotManagerOpt, int position) + : base(root, owner, rootBinder, containingSemanticModelOpt: null, parentSemanticModelOpt: parentSemanticModel, snapshotManagerOpt, speculatedPosition: position) { } + protected override NullableWalker.SnapshotManager GetSnapshotManager() + { + // In this override, current nullability state cannot influence anything of speculatively bound expressions. + return _parentSnapshotManagerOpt; + } + protected override BoundNode RewriteNullableBoundNodesWithSnapshots(BoundNode boundRoot, Binder binder, DiagnosticBag diagnostics, bool createSnapshots, out NullableWalker.SnapshotManager snapshotManager) { Debug.Assert(boundRoot.Syntax is TypeSyntax); diff --git a/src/Compilers/CSharp/Portable/Compilation/MemberSemanticModel.cs b/src/Compilers/CSharp/Portable/Compilation/MemberSemanticModel.cs index dc72d4ce192..5956e56c71e 100644 --- a/src/Compilers/CSharp/Portable/Compilation/MemberSemanticModel.cs +++ b/src/Compilers/CSharp/Portable/Compilation/MemberSemanticModel.cs @@ -142,7 +142,7 @@ internal override MemberSemanticModel GetMemberModel(SyntaxNode node) /// /// This will cause the bound node cache to be populated if nullable semantic analysis is enabled. /// - protected NullableWalker.SnapshotManager GetSnapshotManager() + protected virtual NullableWalker.SnapshotManager GetSnapshotManager() { EnsureRootBoundForNullabilityIfNecessary(); Debug.Assert(_lazySnapshotManager is object || !Compilation.NullableSemanticAnalysisEnabled); @@ -156,7 +156,7 @@ internal sealed override bool TryGetSpeculativeSemanticModelCore(SyntaxTreeSeman var binder = this.GetSpeculativeBinder(position, expression, bindingOption); if (binder != null) { - speculativeModel = new SpeculativeMemberSemanticModel(parentModel, _memberSymbol, type, binder, position); + speculativeModel = new SpeculativeMemberSemanticModel(parentModel, _memberSymbol, type, binder, GetSnapshotManager(), position); return true; } @@ -1457,7 +1457,10 @@ protected void GuardedAddBoundTreeForStandaloneSyntax(SyntaxNode syntax, BoundNo NodeMapBuilder.AddToMap(bound, _guardedNodeMap, syntax); } - Debug.Assert((manager is null && (!Compilation.NullableSemanticAnalysisEnabled || syntax != Root)) || + Debug.Assert((manager is null && (!Compilation.NullableSemanticAnalysisEnabled || syntax != Root || syntax is TypeSyntax || + // Supporting attributes is tracked by + // https://github.com/dotnet/roslyn/issues/36066 + this is AttributeSemanticModel)) || (manager is object && syntax == Root && Compilation.NullableSemanticAnalysisEnabled && _lazySnapshotManager is null)); if (manager is object) { diff --git a/src/Compilers/CSharp/Portable/FlowAnalysis/NullableWalker.DebugVerifier.cs b/src/Compilers/CSharp/Portable/FlowAnalysis/NullableWalker.DebugVerifier.cs index 2867facf379..dee1464a9b0 100644 --- a/src/Compilers/CSharp/Portable/FlowAnalysis/NullableWalker.DebugVerifier.cs +++ b/src/Compilers/CSharp/Portable/FlowAnalysis/NullableWalker.DebugVerifier.cs @@ -57,10 +57,11 @@ protected override BoundExpression VisitExpressionWithoutStackGuard(BoundExpress public override BoundNode Visit(BoundNode node) { // Ensure that we always have a snapshot for every BoundExpression in the map - if (_snapshotManager != null && node != null) - { - _snapshotManager.VerifyNode(node); - } + // Re-enable of this assert is tracked by https://github.com/dotnet/roslyn/issues/36844 + //if (_snapshotManager != null && node != null) + //{ + // _snapshotManager.VerifyNode(node); + //} if (node is BoundExpression expr) { @@ -171,6 +172,14 @@ public override BoundNode VisitConvertedTupleLiteral(BoundConvertedTupleLiteral Visit(node.SourceTuple); return base.VisitConvertedTupleLiteral(node); } + + public override BoundNode VisitTypeExpression(BoundTypeExpression node) + { + // Ignore any dimensions + VerifyExpression(node); + Visit(node.BoundContainingTypeOpt); + return null; + } } #endif } diff --git a/src/Compilers/CSharp/Portable/FlowAnalysis/NullableWalker.cs b/src/Compilers/CSharp/Portable/FlowAnalysis/NullableWalker.cs index 99a239f455c..dff9871a787 100644 --- a/src/Compilers/CSharp/Portable/FlowAnalysis/NullableWalker.cs +++ b/src/Compilers/CSharp/Portable/FlowAnalysis/NullableWalker.cs @@ -1956,6 +1956,15 @@ private ArrayTypeSymbol VisitArrayInitializer(BoundArrayCreation node) checkConversion: true, fromExplicitCast: false, useLegacyWarnings: false, AssignmentKind.Assignment, reportRemainingWarnings: false); } } + else + { + // We need to ensure that we're tracking the inferred type with nullability of any conversions that + // were stripped off. + for (int i = 0; i < n; i++) + { + TrackAnalyzedNullabilityThroughConversionGroup(inferredType.ToTypeWithState(), expressions[i] as BoundConversion, expressionsNoConversions[i]); + } + } expressionsNoConversions.Free(); conversions.Free(); @@ -3151,24 +3160,33 @@ protected override void VisitArguments(ImmutableArray arguments // Visit outbound assignments and post-conditions // Note: the state may get split in this step - if (!node.HasErrors && !parameters.IsDefault) + for (int i = 0; i < argumentsNoConversions.Length; i++) { - for (int i = 0; i < argumentsNoConversions.Length; i++) + (ParameterSymbol parameter, TypeWithAnnotations parameterType, FlowAnalysisAnnotations parameterAnnotations) = GetCorrespondingParameter(i, parameters, argsToParamsOpt, expanded); + if (parameter is null) { - (ParameterSymbol parameter, TypeWithAnnotations parameterType, FlowAnalysisAnnotations parameterAnnotations) = GetCorrespondingParameter(i, parameters, argsToParamsOpt, expanded); - if (parameter is null) - { - continue; - } - - VisitArgumentOutboundAssignmentsAndPostConditions( - arguments[i], - GetRefKind(refKindsOpt, i), - parameter, - parameterType, - parameterAnnotations, - results[i]); + continue; } + + VisitArgumentOutboundAssignmentsAndPostConditions( + arguments[i], + GetRefKind(refKindsOpt, i), + parameter, + parameterType, + parameterAnnotations, + results[i]); + } + } + else + { + for (int i = 0; i < arguments.Length; i++) + { + // We can hit this case when dynamic methods are involved, or when there are errors. In either case we have no information, + // so just assume that the conversions have the same nullability as the underlying result + var argument = arguments[i]; + var result = results[i]; + var argumentNoConversion = argumentsNoConversions[i]; + TrackAnalyzedNullabilityThroughConversionGroup(TypeWithState.Create(argument.Type, result.RValueType.State), argument as BoundConversion, argumentNoConversion); } } @@ -6190,6 +6208,7 @@ public override void VisitForEachIterationVariables(BoundForEachStatement node) } else { + Visit(node.IterationVariableType); foreach (var iterationVariable in node.IterationVariables) { var state = NullableFlowState.NotNull; diff --git a/src/Compilers/CSharp/Portable/FlowAnalysis/NullableWalker_Patterns.cs b/src/Compilers/CSharp/Portable/FlowAnalysis/NullableWalker_Patterns.cs index 65db2602fdc..99404bed968 100644 --- a/src/Compilers/CSharp/Portable/FlowAnalysis/NullableWalker_Patterns.cs +++ b/src/Compilers/CSharp/Portable/FlowAnalysis/NullableWalker_Patterns.cs @@ -43,6 +43,7 @@ public override BoundNode VisitSubpattern(BoundSubpattern node) public override BoundNode VisitRecursivePattern(BoundRecursivePattern node) { + Visit(node.DeclaredType); VisitAll(node.Deconstruction); VisitAll(node.Properties); Visit(node.VariableAccess); @@ -180,6 +181,7 @@ protected override void VisitSwitchSection(BoundSwitchSection node, bool isLastS foreach (var label in node.SwitchLabels) { TakeIncrementalSnapshot(label); + VisitPatternForRewriting(label.Pattern); VisitLabel(label.Label, node); } @@ -505,6 +507,7 @@ public override BoundNode VisitSwitchExpression(BoundSwitchExpression node) SetState(!arm.Pattern.HasErrors && labelStateMap.TryGetValue(arm.Label, out var labelState) ? labelState.state : UnreachableState()); // https://github.com/dotnet/roslyn/issues/35836 Is this where we want to take the snapshot? TakeIncrementalSnapshot(arm); + VisitPatternForRewriting(arm.Pattern); (BoundExpression expression, Conversion conversion) = RemoveConversion(arm.Value, includeExplicitConversions: false); SnapshotWalkerThroughConversionGroup(arm.Value, expression); expressions.Add(expression); @@ -558,6 +561,7 @@ public override BoundNode VisitIsPatternExpression(BoundIsPatternExpression node { Debug.Assert(!IsConditionalState); LearnFromAnyNullPatterns(node.Expression, node.Pattern); + VisitPatternForRewriting(node.Pattern); var expressionState = VisitRvalueWithState(node.Expression); var labelStateMap = LearnFromDecisionDag(node.Syntax, node.DecisionDag, node.Expression, expressionState, ref this.State); var trueState = labelStateMap.TryGetValue(node.WhenTrueLabel, out var s1) ? s1.state : UnreachableState(); diff --git a/src/Compilers/CSharp/Test/Symbol/Symbols/Source/NullablePublicAPITests.cs b/src/Compilers/CSharp/Test/Symbol/Symbols/Source/NullablePublicAPITests.cs index fb6ebaf6271..da03edd5630 100644 --- a/src/Compilers/CSharp/Test/Symbol/Symbols/Source/NullablePublicAPITests.cs +++ b/src/Compilers/CSharp/Test/Symbol/Symbols/Source/NullablePublicAPITests.cs @@ -1055,7 +1055,7 @@ string M(string? s1) } }"; - var comp = CreateCompilation(source, options: WithNonNullTypesTrue(), parseOptions: TestOptions.Regular8WithNullableAnalysis); + var comp = CreateCompilation(source, options: WithNonNullTypesTrue()); comp.VerifyDiagnostics(); var syntaxTree = comp.SyntaxTrees[0]; diff --git a/src/EditorFeatures/CSharpTest/CodeActions/EncapsulateField/EncapsulateFieldTests.cs b/src/EditorFeatures/CSharpTest/CodeActions/EncapsulateField/EncapsulateFieldTests.cs index 801a432a4bb..186b3e7ce4f 100644 --- a/src/EditorFeatures/CSharpTest/CodeActions/EncapsulateField/EncapsulateFieldTests.cs +++ b/src/EditorFeatures/CSharpTest/CodeActions/EncapsulateField/EncapsulateFieldTests.cs @@ -122,7 +122,7 @@ void baz() } } "; - await TestAllOptionsOffAsync(text, expected, index: 1, parseOptions: TestOptions.Regular8WithNullableAnalysis); + await TestAllOptionsOffAsync(text, expected, index: 1); } [Fact, Trait(Traits.Feature, Traits.Features.EncapsulateField)] diff --git a/src/EditorFeatures/CSharpTest/CodeActions/IntroduceVariable/IntroduceVariableTests.cs b/src/EditorFeatures/CSharpTest/CodeActions/IntroduceVariable/IntroduceVariableTests.cs index 64f781a265f..3c4c14baba7 100644 --- a/src/EditorFeatures/CSharpTest/CodeActions/IntroduceVariable/IntroduceVariableTests.cs +++ b/src/EditorFeatures/CSharpTest/CodeActions/IntroduceVariable/IntroduceVariableTests.cs @@ -3133,7 +3133,7 @@ void M() void M2(string? s) { } -}", parseOptions: TestOptions.Regular8WithNullableAnalysis); +}"); [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsIntroduceVariable)] public Task TestIntroduceLocal_NullableType_FlowStateNull() @@ -3166,7 +3166,7 @@ void M() void M2(string? s) { } -}", parseOptions: TestOptions.Regular8WithNullableAnalysis); +}"); [WorkItem(1065661, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/1065661")] [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsIntroduceVariable)] diff --git a/src/EditorFeatures/CSharpTest/Diagnostics/GenerateMethod/GenerateMethodTests.cs b/src/EditorFeatures/CSharpTest/Diagnostics/GenerateMethod/GenerateMethodTests.cs index 61e67901749..717963e4d4a 100644 --- a/src/EditorFeatures/CSharpTest/Diagnostics/GenerateMethod/GenerateMethodTests.cs +++ b/src/EditorFeatures/CSharpTest/Diagnostics/GenerateMethod/GenerateMethodTests.cs @@ -322,7 +322,7 @@ private void Goo(string? s) { throw new NotImplementedException(); } -}", parseOptions: TestOptions.Regular8WithNullableAnalysis); +}"); } [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsGenerateMethod)] @@ -356,7 +356,7 @@ private void Goo(List l) { throw new NotImplementedException(); } -}", parseOptions: TestOptions.Regular8WithNullableAnalysis); +}"); } @@ -1138,7 +1138,7 @@ void Method() { throw new NotImplementedException(); } -}", parseOptions: TestOptions.Regular8WithNullableAnalysis); +}"); } [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsGenerateMethod)] @@ -1174,7 +1174,7 @@ private T Goo(T v) { throw new NotImplementedException(); } -}", parseOptions: TestOptions.Regular8WithNullableAnalysis); +}"); } [Fact(Skip = "https://github.com/dotnet/roslyn/issues/36044"), Trait(Traits.Feature, Traits.Features.CodeActionsGenerateMethod)] @@ -1212,7 +1212,7 @@ private T Goo(T e) { throw new NotImplementedException(); } -}", parseOptions: TestOptions.Regular8WithNullableAnalysis); +}"); } [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsGenerateMethod)] diff --git a/src/EditorFeatures/CSharpTest/Diagnostics/GenerateType/GenerateTypeTests.cs b/src/EditorFeatures/CSharpTest/Diagnostics/GenerateType/GenerateTypeTests.cs index 845e231600e..26a05e8d4fc 100644 --- a/src/EditorFeatures/CSharpTest/Diagnostics/GenerateType/GenerateTypeTests.cs +++ b/src/EditorFeatures/CSharpTest/Diagnostics/GenerateType/GenerateTypeTests.cs @@ -1438,7 +1438,6 @@ public T(string? s) this.s = s; } }", -parseOptions: TestOptions.Regular8WithNullableAnalysis, index: 1); } @@ -1474,7 +1473,6 @@ public T(string s) this.s = s; } }", -parseOptions: TestOptions.Regular8WithNullableAnalysis, index: 1); } diff --git a/src/EditorFeatures/CSharpTest/GenerateConstructor/GenerateConstructorTests.cs b/src/EditorFeatures/CSharpTest/GenerateConstructor/GenerateConstructorTests.cs index 121114fd7fb..4111748b9b2 100644 --- a/src/EditorFeatures/CSharpTest/GenerateConstructor/GenerateConstructorTests.cs +++ b/src/EditorFeatures/CSharpTest/GenerateConstructor/GenerateConstructorTests.cs @@ -3745,7 +3745,7 @@ void M() string? s = null; new C(s); } -}", parseOptions: TestOptions.Regular8WithNullableAnalysis); +}"); } [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsGenerateConstructor)] @@ -3782,7 +3782,7 @@ void M() IEnumerable s; new C(s); } -}", parseOptions: TestOptions.Regular8WithNullableAnalysis); +}"); } } } diff --git a/src/EditorFeatures/CSharpTest/GenerateVariable/GenerateVariableTests.cs b/src/EditorFeatures/CSharpTest/GenerateVariable/GenerateVariableTests.cs index 919d2790a6f..c2932f3f20c 100644 --- a/src/EditorFeatures/CSharpTest/GenerateVariable/GenerateVariableTests.cs +++ b/src/EditorFeatures/CSharpTest/GenerateVariable/GenerateVariableTests.cs @@ -230,7 +230,7 @@ void Method(string? s) { Method(goo); } -}", parseOptions: TestOptions.Regular8WithNullableAnalysis); +}"); } [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsGenerateVariable)] @@ -260,7 +260,7 @@ void Method(IEnumerable s) { Method(goo); } -}", parseOptions: TestOptions.Regular8WithNullableAnalysis); +}"); } [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsGenerateVariable)] @@ -3959,7 +3959,7 @@ static void Goo(string? s) { } }", -index: LocalIndex, parseOptions: TestOptions.Regular8WithNullableAnalysis); +index: LocalIndex); } [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsGenerateVariable)] @@ -3993,7 +3993,7 @@ static void Goo(IEnumerable s) { } }", -index: LocalIndex, parseOptions: TestOptions.Regular8WithNullableAnalysis); +index: LocalIndex); } [Fact, Trait(Traits.Feature, Traits.Features.CodeActionsGenerateVariable)] diff --git a/src/EditorFeatures/CSharpTest/QuickInfo/SemanticQuickInfoSourceTests.cs b/src/EditorFeatures/CSharpTest/QuickInfo/SemanticQuickInfoSourceTests.cs index 718ef4ea2aa..e7450dbcf69 100644 --- a/src/EditorFeatures/CSharpTest/QuickInfo/SemanticQuickInfoSourceTests.cs +++ b/src/EditorFeatures/CSharpTest/QuickInfo/SemanticQuickInfoSourceTests.cs @@ -12,6 +12,7 @@ using Microsoft.CodeAnalysis.Editor.UnitTests.Workspaces; using Microsoft.CodeAnalysis.QuickInfo; using Microsoft.CodeAnalysis.Test.Utilities; +using Microsoft.CodeAnalysis.Utilities; using Roslyn.Test.Utilities; using Roslyn.Utilities; using Xunit; @@ -6351,7 +6352,7 @@ void N() [Fact, Trait(Traits.Feature, Traits.Features.QuickInfo)] public async Task NullableParameterThatIsMaybeNull() { - await TestWithOptionsAsync(TestOptions.Regular8WithNullableAnalysis, + await TestWithOptionsAsync(TestOptions.Regular8, @"#nullable enable class X @@ -6368,7 +6369,7 @@ void N(string? s) [Fact, Trait(Traits.Feature, Traits.Features.QuickInfo)] public async Task NullableParameterThatIsNotNull() { - await TestWithOptionsAsync(TestOptions.Regular8WithNullableAnalysis, + await TestWithOptionsAsync(TestOptions.Regular8, @"#nullable enable class X @@ -6386,7 +6387,7 @@ void N(string? s) [Fact, Trait(Traits.Feature, Traits.Features.QuickInfo)] public async Task NullableFieldThatIsMaybeNull() { - await TestWithOptionsAsync(TestOptions.Regular8WithNullableAnalysis, + await TestWithOptionsAsync(TestOptions.Regular8, @"#nullable enable class X @@ -6405,7 +6406,7 @@ void N() [Fact, Trait(Traits.Feature, Traits.Features.QuickInfo)] public async Task NullableFieldThatIsNotNull() { - await TestWithOptionsAsync(TestOptions.Regular8WithNullableAnalysis, + await TestWithOptionsAsync(TestOptions.Regular8, @"#nullable enable class X @@ -6425,7 +6426,7 @@ void N() [Fact, Trait(Traits.Feature, Traits.Features.QuickInfo)] public async Task NullablePropertyThatIsMaybeNull() { - await TestWithOptionsAsync(TestOptions.Regular8WithNullableAnalysis, + await TestWithOptionsAsync(TestOptions.Regular8, @"#nullable enable class X @@ -6444,7 +6445,7 @@ void N() [Fact, Trait(Traits.Feature, Traits.Features.QuickInfo)] public async Task NullablePropertyThatIsNotNull() { - await TestWithOptionsAsync(TestOptions.Regular8WithNullableAnalysis, + await TestWithOptionsAsync(TestOptions.Regular8, @"#nullable enable class X @@ -6464,7 +6465,7 @@ void N() [Fact, Trait(Traits.Feature, Traits.Features.QuickInfo)] public async Task NullableRangeVariableThatIsMaybeNull() { - await TestWithOptionsAsync(TestOptions.Regular8WithNullableAnalysis, + await TestWithOptionsAsync(TestOptions.Regular8, @"#nullable enable using System.Collections.Generic; @@ -6488,7 +6489,7 @@ void N() [Fact, Trait(Traits.Feature, Traits.Features.QuickInfo)] public async Task NullableRangeVariableThatIsNotNull() { - await TestWithOptionsAsync(TestOptions.Regular8WithNullableAnalysis, + await TestWithOptionsAsync(TestOptions.Regular8, @"#nullable enable using System.Collections.Generic; @@ -6512,7 +6513,7 @@ void N() [Fact, Trait(Traits.Feature, Traits.Features.QuickInfo)] public async Task NullableLocalThatIsMaybeNull() { - await TestWithOptionsAsync(TestOptions.Regular8WithNullableAnalysis, + await TestWithOptionsAsync(TestOptions.Regular8, @"#nullable enable using System.Collections.Generic; @@ -6532,7 +6533,7 @@ void N() [Fact, Trait(Traits.Feature, Traits.Features.QuickInfo)] public async Task NullableLocalThatIsNotNull() { - await TestWithOptionsAsync(TestOptions.Regular8WithNullableAnalysis, + await TestWithOptionsAsync(TestOptions.Regular8, @"#nullable enable using System.Collections.Generic; @@ -6572,7 +6573,8 @@ void N() [Fact, Trait(Traits.Feature, Traits.Features.QuickInfo)] public async Task NullableNotShownWithoutFeatureFlag() { - await TestWithOptionsAsync(TestOptions.Regular8, + var options = TestOptions.Regular8.WithFeature(CompilerFeatureFlags.RunNullableAnalysis, "false"); + await TestWithOptionsAsync(options, @"#nullable enable using System.Collections.Generic; diff --git a/src/EditorFeatures/CSharpTest/UseLocalFunction/UseLocalFunctionTests.cs b/src/EditorFeatures/CSharpTest/UseLocalFunction/UseLocalFunctionTests.cs index cc08da8d8b5..72f8c7fc0dc 100644 --- a/src/EditorFeatures/CSharpTest/UseLocalFunction/UseLocalFunctionTests.cs +++ b/src/EditorFeatures/CSharpTest/UseLocalFunction/UseLocalFunctionTests.cs @@ -3687,7 +3687,7 @@ static void Main(string[] args) { static string? f(string? s) => s; } -}", parseOptions: TestOptions.Regular8WithNullableAnalysis); +}", parseOptions: TestOptions.Regular8); } } } diff --git a/src/Features/CSharp/Portable/QuickInfo/CSharpSemanticQuickInfoProvider.cs b/src/Features/CSharp/Portable/QuickInfo/CSharpSemanticQuickInfoProvider.cs index 9cc944beb85..8ac1a844ed6 100644 --- a/src/Features/CSharp/Portable/QuickInfo/CSharpSemanticQuickInfoProvider.cs +++ b/src/Features/CSharp/Portable/QuickInfo/CSharpSemanticQuickInfoProvider.cs @@ -56,11 +56,6 @@ protected override ImmutableArray TryGetNullabilityAnalysis(Workspac return default; } - if (!parseOptions.Features.ContainsKey(CompilerFeatureFlags.RunNullableAnalysis)) - { - return default; - } - var syntaxFacts = workspace.Services.GetLanguageServices(semanticModel.Language).GetRequiredService(); var bindableParent = syntaxFacts.GetBindableParent(token); var symbolInfo = semanticModel.GetSymbolInfo(bindableParent, cancellationToken); -- GitLab