Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
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
2 changes: 1 addition & 1 deletion src/Compilers/CSharp/Portable/BoundTree/BoundNodes.xml
Original file line number Diff line number Diff line change
Expand Up @@ -2529,7 +2529,7 @@
Left.InputType is the InputType
Right.InputType is the Left.NarrowedType
-->
<Node Name="BoundBinaryPattern" Base="BoundPattern" HasValidate="true">
<Node Name="BoundBinaryPattern" Base="BoundPattern" HasValidate="true" SkipInNullabilityRewriter="true">
<Field Name="Disjunction" Type="bool"/>
<Field Name="Left" Type="BoundPattern"/>
<Field Name="Right" Type="BoundPattern"/>
Expand Down
35 changes: 35 additions & 0 deletions src/Compilers/CSharp/Portable/BoundTree/NullabilityRewriter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,41 @@ private BoundNode VisitBinaryOperatorBase(BoundBinaryOperatorBase binaryOperator
return currentBinary!;
}

public override BoundNode? VisitBinaryPattern(BoundBinaryPattern node)
{
// Use an explicit stack to avoid blowing the managed stack when visiting deeply-recursive
// binary nodes
var stack = ArrayBuilder<BoundBinaryPattern>.GetInstance();
BoundBinaryPattern? currentBinary = node;

do
{
stack.Push(currentBinary);
currentBinary = currentBinary.Left as BoundBinaryPattern;
}
while (currentBinary is not null);

Debug.Assert(stack.Count > 0);
var leftChild = (BoundPattern)Visit(stack.Peek().Left);

do
{
currentBinary = stack.Pop();

TypeSymbol inputType = GetUpdatedSymbol(currentBinary, currentBinary.InputType);
TypeSymbol narrowedType = GetUpdatedSymbol(currentBinary, currentBinary.NarrowedType);

var right = (BoundPattern)Visit(currentBinary.Right);

currentBinary = currentBinary.Update(currentBinary.Disjunction, leftChild, right, inputType, narrowedType);

leftChild = currentBinary;
}
while (stack.Count > 0);

return currentBinary;
}

public override BoundNode? VisitCompoundAssignmentOperator(BoundCompoundAssignmentOperator node)
{
ImmutableArray<MethodSymbol> originalUserDefinedOperatorsOpt = GetUpdatedArray(node, node.OriginalUserDefinedOperatorsOpt);
Expand Down

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

10 changes: 6 additions & 4 deletions src/Compilers/CSharp/Test/EndToEnd/EndToEndTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -892,11 +892,13 @@ public void ManyBinaryPatterns_01(string pattern, string expectedOutput)
public void ManyBinaryPatterns_02()
{
const int numOfEnumMembers = 5_000;
const int capacity = 97953;
const int capacity = 97973;

var builder = new StringBuilder(capacity);

builder.Append("""
#nullable enable

class ErrorFacts
{
static bool Test(E code)
Expand Down Expand Up @@ -942,7 +944,7 @@ enum E
var source = builder.ToString();
RunInThread(() =>
{
var comp = CreateCompilation(source, options: TestOptions.DebugDll.WithConcurrentBuild(false), parseOptions: TestOptions.RegularDefault.WithFeature("run-nullable-analysis", "never"));
var comp = CreateCompilation(source, options: TestOptions.DebugDll.WithConcurrentBuild(false));

var tree = comp.SyntaxTrees.Single();
var model = comp.GetSemanticModel(tree);
Expand All @@ -959,9 +961,9 @@ enum E
Assert.NotNull(ControlFlowGraph.Create((IMethodBodyOperation)operation));

model.GetDiagnostics().Verify(
// (5,21): warning CS8524: The switch expression does not handle some values of its input type (it is not exhaustive) involving an unnamed enum value. For example, the pattern '(E)5000' is not covered.
// (7,21): warning CS8524: The switch expression does not handle some values of its input type (it is not exhaustive) involving an unnamed enum value. For example, the pattern '(E)5000' is not covered.
// return code switch
Diagnostic(ErrorCode.WRN_SwitchExpressionNotExhaustiveWithUnnamedEnumValue, "switch").WithArguments("(E)" + numOfEnumMembers).WithLocation(5, 21)
Diagnostic(ErrorCode.WRN_SwitchExpressionNotExhaustiveWithUnnamedEnumValue, "switch").WithArguments("(E)" + numOfEnumMembers).WithLocation(7, 21)
);
});
}
Expand Down
Loading