Fix a crash when checking a nested tuple-pattern (#7716)

Adds a virtual node to `DefaultValuePattern` to end the
`ExprRegionForPattern` before checking the expression
for the default value.

When checking the default value expression, the context
was still configured to interpret expressions as patterns,
which caused some corruption of state with tuple-pattern
subpatterns.

Corrects an assertion failure I found while working on
feedback from #7665.
This commit is contained in:
Lucile Rose Nihlen
2026-09-04 01:22:16 +00:00
committed by GitHub
parent 1b969c292b
commit 2952ec9c10
10 changed files with 141 additions and 2 deletions
@@ -29,6 +29,7 @@ fn I(x: i32 = _);
// CHECK:STDOUT: │ │ │ ├─BindingPatternTypeStart ':'
// CHECK:STDOUT: │ │ │ ├─IntTypeLiteral 'i32'
// CHECK:STDOUT: │ │ │ ╭─LetBindingPattern ':'
// CHECK:STDOUT: │ │ │ ├─DefaultValueExprStart '='
// CHECK:STDOUT: │ │ │ ├─IntLiteral '0'
// CHECK:STDOUT: │ │ ├─DefaultValuePattern '='
// CHECK:STDOUT: │ ├─ExplicitParamList ')'
@@ -47,6 +48,7 @@ fn I(x: i32 = _);
// CHECK:STDOUT: │ │ │ │ ├─IntTypeLiteral 'i32'
// CHECK:STDOUT: │ │ │ ├─LetBindingPattern ':'
// CHECK:STDOUT: │ │ │ ╭─TuplePattern ')'
// CHECK:STDOUT: │ │ │ ├─DefaultValueExprStart '='
// CHECK:STDOUT: │ │ │ │ ╭─TupleLiteralStart '('
// CHECK:STDOUT: │ │ │ │ ├─IntLiteral '1'
// CHECK:STDOUT: │ │ │ │ ├─TupleLiteralComma ','
@@ -63,6 +65,7 @@ fn I(x: i32 = _);
// CHECK:STDOUT: │ │ │ ├─IntTypeLiteral 'i32'
// CHECK:STDOUT: │ │ │ ╭─LetBindingPattern ':'
// CHECK:STDOUT: │ │ │ ╭─UnusedPattern 'unused'
// CHECK:STDOUT: │ │ │ ├─DefaultValueExprStart '='
// CHECK:STDOUT: │ │ │ ├─IntLiteral '25'
// CHECK:STDOUT: │ │ ├─DefaultValuePattern '='
// CHECK:STDOUT: │ ├─ExplicitParamList ')'
@@ -80,6 +83,7 @@ fn I(x: i32 = _);
// CHECK:STDOUT: │ │ │ │ ├─BindingPatternTypeStart ':'
// CHECK:STDOUT: │ │ │ │ ├─IntTypeLiteral 'i32'
// CHECK:STDOUT: │ │ │ │ ╭─LetBindingPattern ':'
// CHECK:STDOUT: │ │ │ │ ├─DefaultValueExprStart '='
// CHECK:STDOUT: │ │ │ │ ├─IntLiteral '0'
// CHECK:STDOUT: │ │ │ ├─DefaultValuePattern '='
// CHECK:STDOUT: │ │ ├─ExplicitParamList ')'
@@ -94,6 +98,7 @@ fn I(x: i32 = _);
// CHECK:STDOUT: │ │ │ ├─BindingPatternTypeStart ':'
// CHECK:STDOUT: │ │ │ ├─IntTypeLiteral 'i32'
// CHECK:STDOUT: │ │ │ ╭─LetBindingPattern ':'
// CHECK:STDOUT: │ │ │ ├─DefaultValueExprStart '='
// CHECK:STDOUT: │ │ │ ├─DefaultValueUnspecified '_'
// CHECK:STDOUT: │ │ ├─DefaultValuePattern '='
// CHECK:STDOUT: │ ├─ExplicitParamList ')'
+3
View File
@@ -567,6 +567,7 @@ let {var _: i32} = {};
// CHECK:STDOUT: │ ╭─LetIntroducer 'let'
// CHECK:STDOUT: │ │ ╭─StructPatternStart '{'
// CHECK:STDOUT: │ │ │ ╭─InvalidParse '=' has_error
// CHECK:STDOUT: │ │ │ ├─DefaultValueExprStart '='
// CHECK:STDOUT: │ │ │ ├─IdentifierNameExpr 'y'
// CHECK:STDOUT: │ │ ├─DefaultValuePattern '=' has_error
// CHECK:STDOUT: │ ├─StructPattern '}' has_error
@@ -834,6 +835,7 @@ let {var _: i32} = {};
// CHECK:STDOUT: │ │ │ ╭─IdentifierNameExpr 'foo'
// CHECK:STDOUT: │ │ │ ├─IdentifierNameNotBeforeSignature 'y'
// CHECK:STDOUT: │ │ │ ╭─MemberAccessExpr '.'
// CHECK:STDOUT: │ │ │ ├─DefaultValueExprStart '='
// CHECK:STDOUT: │ │ │ ├─IdentifierNameExpr 'y'
// CHECK:STDOUT: │ │ ├─DefaultValuePattern '='
// CHECK:STDOUT: │ ├─StructPattern '}' has_error
@@ -959,6 +961,7 @@ let {var _: i32} = {};
// CHECK:STDOUT: │ ╭─LetIntroducer 'let'
// CHECK:STDOUT: │ │ ╭─StructPatternStart '{'
// CHECK:STDOUT: │ │ │ ╭─StringLiteral '"foo"'
// CHECK:STDOUT: │ │ │ ├─DefaultValueExprStart '='
// CHECK:STDOUT: │ │ │ ├─InvalidParse ',' has_error
// CHECK:STDOUT: │ │ ├─DefaultValuePattern '=' has_error
// CHECK:STDOUT: │ │ ├─PatternListComma ','
@@ -79,6 +79,7 @@ fn AfterAnd(generic Z: Q where .R impls S and () = .A);
// CHECK:STDOUT: │ │ │ │ ├─IntTypeLiteral 'i32'
// CHECK:STDOUT: │ │ │ ├─WhereExpr 'where' has_error
// CHECK:STDOUT: │ │ │ ╭─CompileTimeBindingPattern ':' has_error
// CHECK:STDOUT: │ │ │ ├─DefaultValueExprStart '='
// CHECK:STDOUT: │ │ │ │ ╭─IdentifierNameNotBeforeSignature 'U'
// CHECK:STDOUT: │ │ │ ├─DesignatorExpr '.'
// CHECK:STDOUT: │ │ ├─DefaultValuePattern '=' has_error
@@ -101,6 +102,7 @@ fn AfterAnd(generic Z: Q where .R impls S and () = .A);
// CHECK:STDOUT: │ │ │ │ ├─ParenExpr ')'
// CHECK:STDOUT: │ │ │ ├─WhereExpr 'where' has_error
// CHECK:STDOUT: │ │ │ ╭─CompileTimeBindingPattern ':' has_error
// CHECK:STDOUT: │ │ │ ├─DefaultValueExprStart '='
// CHECK:STDOUT: │ │ │ ├─BoolTypeLiteral 'bool'
// CHECK:STDOUT: │ │ ├─DefaultValuePattern '=' has_error
// CHECK:STDOUT: │ ├─ExplicitParamList ')' has_error
@@ -120,6 +122,7 @@ fn AfterAnd(generic Z: Q where .R impls S and () = .A);
// CHECK:STDOUT: │ │ │ │ ├─DesignatorExpr '.'
// CHECK:STDOUT: │ │ │ ├─WhereExpr 'where' has_error
// CHECK:STDOUT: │ │ │ ╭─CompileTimeBindingPattern ':' has_error
// CHECK:STDOUT: │ │ │ ├─DefaultValueExprStart '='
// CHECK:STDOUT: │ │ │ ├─FloatTypeLiteral 'f32'
// CHECK:STDOUT: │ │ ├─DefaultValuePattern '=' has_error
// CHECK:STDOUT: │ ├─ExplicitParamList ')' has_error
@@ -139,6 +142,7 @@ fn AfterAnd(generic Z: Q where .R impls S and () = .A);
// CHECK:STDOUT: │ │ │ │ ├─DesignatorExpr '.' has_error
// CHECK:STDOUT: │ │ │ ├─WhereExpr 'where' has_error
// CHECK:STDOUT: │ │ │ ╭─CompileTimeBindingPattern ':' has_error
// CHECK:STDOUT: │ │ │ ├─DefaultValueExprStart '='
// CHECK:STDOUT: │ │ │ ├─UnsignedIntTypeLiteral 'u8'
// CHECK:STDOUT: │ │ ├─DefaultValuePattern '=' has_error
// CHECK:STDOUT: │ ├─ExplicitParamList ')' has_error
@@ -159,6 +163,7 @@ fn AfterAnd(generic Z: Q where .R impls S and () = .A);
// CHECK:STDOUT: │ │ │ │ ├─PostfixOperatorStar '*'
// CHECK:STDOUT: │ │ │ ├─WhereExpr 'where' has_error
// CHECK:STDOUT: │ │ │ ╭─CompileTimeBindingPattern ':' has_error
// CHECK:STDOUT: │ │ │ ├─DefaultValueExprStart '='
// CHECK:STDOUT: │ │ │ │ ╭─UnsignedIntTypeLiteral 'u64'
// CHECK:STDOUT: │ │ │ ├─PostfixOperatorStar '*'
// CHECK:STDOUT: │ │ ├─DefaultValuePattern '=' has_error
@@ -182,6 +187,7 @@ fn AfterAnd(generic Z: Q where .R impls S and () = .A);
// CHECK:STDOUT: │ │ │ │ ├─InfixOperatorPlus '+'
// CHECK:STDOUT: │ │ │ ├─WhereExpr 'where' has_error
// CHECK:STDOUT: │ │ │ ╭─CompileTimeBindingPattern ':' has_error
// CHECK:STDOUT: │ │ │ ├─DefaultValueExprStart '='
// CHECK:STDOUT: │ │ │ │ ╭─StructLiteralStart '{'
// CHECK:STDOUT: │ │ │ ├─StructLiteral '}'
// CHECK:STDOUT: │ │ ├─DefaultValuePattern '=' has_error
@@ -207,6 +213,7 @@ fn AfterAnd(generic Z: Q where .R impls S and () = .A);
// CHECK:STDOUT: │ │ │ │ ├─TupleLiteral ')'
// CHECK:STDOUT: │ │ │ ├─WhereExpr 'where' has_error
// CHECK:STDOUT: │ │ │ ╭─CompileTimeBindingPattern ':' has_error
// CHECK:STDOUT: │ │ │ ├─DefaultValueExprStart '='
// CHECK:STDOUT: │ │ │ │ ╭─IdentifierNameNotBeforeSignature 'A'
// CHECK:STDOUT: │ │ │ ├─DesignatorExpr '.'
// CHECK:STDOUT: │ │ ├─DefaultValuePattern '=' has_error