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

AbstractFlowPass.VisitIsPatternExpression - add handling for list-pattern specific patterns #59285

Merged
merged 4 commits into from
Feb 15, 2022
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -1035,6 +1035,7 @@ static bool patternMatchesNull(BoundPattern pattern)
case BoundITuplePattern:
case BoundRelationalPattern:
case BoundDeclarationPattern:
case BoundListPattern:
Copy link
Member

@alrz alrz Feb 4, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There's another switch with a missing case in patternMatchesNull above.

It's not clear how an exhaustive switch is supposed to help here since not every pattern node is going through this check as demonstrated in this bug. Unless there's a compile-time diagnostic, you'd need to scan the code to find each instance or else, wait for a crash later. Would it make sense to have a safe default with Assert(false) instead of throwing right away? (or make it so that every pattern is visited here regardless of the source tree) #Resolved

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks. Fixed that other case, plus two more (for slices).

I added an assertion that should help catch this problem with future patterns.

return null;
default:
throw ExceptionUtilities.UnexpectedValue(pattern.Kind);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8121,4 +8121,36 @@ public void ListPattern_NullTestOnSlice()
Diagnostic(ErrorCode.ERR_SwitchCaseSubsumed, "[1,2,3]").WithLocation(15, 10)
);
}

[Fact, WorkItem(58738, "https://github.com/dotnet/roslyn/issues/58738")]
public void ListPattern_DefiniteAssignmentOnErrorCode()
{
var source = @"
var a = new[] { 1 };

if (a is [var x] and x is [1])
{
}

var b = new[] { true };
if ((b is [var y] and y) is [true])
{
}
";
var comp = CreateCompilationWithIndexAndRangeAndSpan(new[] { source, TestSources.GetSubArray });
comp.VerifyEmitDiagnostics(
// (4,22): error CS0029: Cannot implicitly convert type 'int' to 'int[]'
// if (a is [var x] and x is [1])
Diagnostic(ErrorCode.ERR_NoImplicitConv, "x").WithArguments("int", "int[]").WithLocation(4, 22),
// (4,27): error CS0021: Cannot apply indexing with [] to an expression of type 'bool'
// if (a is [var x] and x is [1])
Diagnostic(ErrorCode.ERR_BadIndexLHS, "[1]").WithArguments("bool").WithLocation(4, 27),
// (9,23): error CS0029: Cannot implicitly convert type 'bool' to 'bool[]'
// if ((b is [var y] and y) is [true])
Diagnostic(ErrorCode.ERR_NoImplicitConv, "y").WithArguments("bool", "bool[]").WithLocation(9, 23),
// (9,29): error CS0021: Cannot apply indexing with [] to an expression of type 'bool'
// if ((b is [var y] and y) is [true])
Diagnostic(ErrorCode.ERR_BadIndexLHS, "[true]").WithArguments("bool").WithLocation(9, 29)
);
}
}