Skip to content

Commit

Permalink
Hande error scenarios involving target types and named arguments in n…
Browse files Browse the repository at this point in the history
…ullable walker (#72635)

* Recover from wrong collection expression target type in nullable walker

* Test collection initializer

* Catch error target typing scenarios sooner

* Fix assert
  • Loading branch information
jjonescz committed Mar 25, 2024
1 parent bd74319 commit ea0acb2
Show file tree
Hide file tree
Showing 2 changed files with 58 additions and 5 deletions.
13 changes: 8 additions & 5 deletions src/Compilers/CSharp/Portable/FlowAnalysis/NullableWalker.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6718,7 +6718,13 @@ private ImmutableArray<VisitResult> VisitArguments(
(ParameterSymbol? parameter, TypeWithAnnotations parameterType, FlowAnalysisAnnotations parameterAnnotations, bool isExpandedParamsArgument) =
GetCorrespondingParameter(i, parametersOpt, argsToParamsOpt, expanded, ref paramsIterationType);

if (parameter is null)
if (// This is known to happen for certain error scenarios, because
// the parameter matching logic above is not as flexible as the one we use in `Binder.BuildArgumentsForErrorRecovery`
// so we may end up with a pending conversion completion for an argument apparently without a corresponding parameter.
parameter is null ||
// In error recovery with named arguments, target-typing cannot work as we can get a different parameter type
// from our GetCorrespondingParameter logic than Binder.BuildArgumentsForErrorRecovery does.
node is BoundCall { HasErrors: true, ArgumentNamesOpt.IsDefaultOrEmpty: false, ArgsToParamsOpt.IsDefault: true })
{
if (IsTargetTypedExpression(argumentNoConversion) && _targetTypedAnalysisCompletionOpt?.TryGetValue(argumentNoConversion, out var completion) is true)
{
Expand All @@ -6728,10 +6734,7 @@ private ImmutableArray<VisitResult> VisitArguments(
completion(TypeWithAnnotations.Create(argument.Type));
TargetTypedAnalysisCompletion.Remove(argumentNoConversion);

// This is known to happen for certain error scenarios, because
// the parameter matching logic above is not as flexible as the one we use in `Binder.BuildArgumentsForErrorRecovery`
// so we may end up with a pending conversion completion for an argument apparently without a corresponding parameter.
Debug.Assert(method is ErrorMethodSymbol);
Debug.Assert(parameter is not null || method is ErrorMethodSymbol);
}
continue;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13431,6 +13431,56 @@ private static void VerifyTypes(SemanticModel model, ExpressionSyntax expr, stri
Assert.Equal(expectedConversionKind, conversion.Kind);
}

[Fact, WorkItem("https://github.com/dotnet/roslyn/issues/72541")]
public void NamedArgumentConversion()
{
var source = """
#nullable enable
using System.Collections.Generic;

static class C
{
static void Main()
{
C.M(y: [new D { }]);
}
static void M(string x, IReadOnlyList<D> y) { }
}

class D { }
""";
var comp = CreateCompilation(source);
comp.VerifyDiagnostics(
// (8,11): error CS7036: There is no argument given that corresponds to the required parameter 'x' of 'C.M(string, IReadOnlyList<D>)'
// C.M(y: [new D { }]);
Diagnostic(ErrorCode.ERR_NoCorrespondingArgument, "M").WithArguments("x", "C.M(string, System.Collections.Generic.IReadOnlyList<D>)").WithLocation(8, 11));
}

[Fact, WorkItem("https://github.com/dotnet/roslyn/issues/72541")]
public void NamedArgumentConversion_CollectionInitializer()
{
var source = """
#nullable enable
using System.Collections.Generic;

static class C
{
static void Main()
{
C.M(y: new() { new D() { } });
}
static void M(string x, List<D> y) { }
}

class D { }
""";
var comp = CreateCompilation(source);
comp.VerifyDiagnostics(
// (8,11): error CS7036: There is no argument given that corresponds to the required parameter 'x' of 'C.M(string, List<D>)'
// C.M(y: new() { new D() { } });
Diagnostic(ErrorCode.ERR_NoCorrespondingArgument, "M").WithArguments("x", "C.M(string, System.Collections.Generic.List<D>)").WithLocation(8, 11));
}

[CombinatorialData]
[Theory]
public void CollectionBuilder_01(bool useCompilationReference)
Expand Down

0 comments on commit ea0acb2

Please sign in to comment.