Diagnose where in a binding that introduces a .Self that does not refer to the binding (#7517)

This is in addition to finding a `where` on the RHS of another `where`.
Since a generic binding introduces `.Self`, any `where` expression that
isn't part of a facet type modifying the binding itself would introduce
an ambiguous `.Self`.

Add virtual parse nodes for let, var, and form bindings, which goes
before the type. This allows us to track if `where` appears in the
binding's type. We only need to look for an invalid `where` if any
appeared in the type. We combine these three nodes together into a
single node kind, which requires us to remove the name from it as a
child. We move it up to the Pattern node again, and rename the
PatternStart nodes to PatternTypeStart as they are now located in the
middle of the Pattern nodes, just before the type.

And we only need to thaw `.Self` in generic bindings. Non-generic
bindings can only have `.Self` through a `where` expression, since the
name is not provided otherwise to non-generic bindings. And `where`
expressions thaw their `.Self` independently. So the binding only needs
to thaw a `.Self` that it introduced, which is only for generic
bindings.
This commit is contained in:
Dana Jansens
2026-07-22 16:45:00 +00:00
committed by GitHub
parent 21dc5cde04
commit d2ac9b3933
170 changed files with 1858 additions and 1314 deletions
+5 -4
View File
@@ -27,12 +27,13 @@ impl i32 as Interface {
// CHECK:STDOUT: {kind: 'SelfBindingPattern', text: 'self', subtree_size: 2},
// CHECK:STDOUT: {kind: 'PatternListComma', text: ','},
// CHECK:STDOUT: {kind: 'IdentifierNameNotBeforeSignature', text: 'b'},
// CHECK:STDOUT: {kind: 'BindingPatternTypeStart', text: ':'},
// CHECK:STDOUT: {kind: 'SelfTypeNameExpr', text: 'Self'},
// CHECK:STDOUT: {kind: 'LetBindingPattern', text: ':', subtree_size: 3},
// CHECK:STDOUT: {kind: 'ExplicitParamList', text: ')', subtree_size: 8},
// CHECK:STDOUT: {kind: 'LetBindingPattern', text: ':', subtree_size: 4},
// CHECK:STDOUT: {kind: 'ExplicitParamList', text: ')', subtree_size: 9},
// CHECK:STDOUT: {kind: 'SelfTypeNameExpr', text: 'Self'},
// CHECK:STDOUT: {kind: 'ReturnType', text: '->', subtree_size: 2},
// CHECK:STDOUT: {kind: 'FunctionDecl', text: ';', subtree_size: 13},
// CHECK:STDOUT: {kind: 'ImplDefinition', text: '}', subtree_size: 19},
// CHECK:STDOUT: {kind: 'FunctionDecl', text: ';', subtree_size: 14},
// CHECK:STDOUT: {kind: 'ImplDefinition', text: '}', subtree_size: 20},
// CHECK:STDOUT: {kind: 'FileEnd', text: ''},
// CHECK:STDOUT: ]
+6 -6
View File
@@ -146,8 +146,8 @@ impl
// CHECK:STDOUT: {kind: 'ImplIntroducer', text: 'impl'},
// CHECK:STDOUT: {kind: 'Forall', text: 'forall'},
// CHECK:STDOUT: {kind: 'ImplicitParamListStart', text: '['},
// CHECK:STDOUT: {kind: 'IdentifierNameNotBeforeSignature', text: 'T'},
// CHECK:STDOUT: {kind: 'CompileTimeBindingPatternStart', text: ':', subtree_size: 2},
// CHECK:STDOUT: {kind: 'IdentifierNameNotBeforeSignature', text: 'T'},
// CHECK:STDOUT: {kind: 'CompileTimeBindingPatternTypeStart', text: ':'},
// CHECK:STDOUT: {kind: 'TypeTypeLiteral', text: 'type'},
// CHECK:STDOUT: {kind: 'CompileTimeBindingPattern', text: ':', subtree_size: 4},
// CHECK:STDOUT: {kind: 'ImplicitParamList', text: ']', subtree_size: 6},
@@ -156,8 +156,8 @@ impl
// CHECK:STDOUT: {kind: 'ImplIntroducer', text: 'impl'},
// CHECK:STDOUT: {kind: 'Forall', text: 'forall'},
// CHECK:STDOUT: {kind: 'ImplicitParamListStart', text: '['},
// CHECK:STDOUT: {kind: 'IdentifierNameNotBeforeSignature', text: 'T'},
// CHECK:STDOUT: {kind: 'CompileTimeBindingPatternStart', text: ':', subtree_size: 2},
// CHECK:STDOUT: {kind: 'IdentifierNameNotBeforeSignature', text: 'T'},
// CHECK:STDOUT: {kind: 'CompileTimeBindingPatternTypeStart', text: ':'},
// CHECK:STDOUT: {kind: 'TypeTypeLiteral', text: 'type'},
// CHECK:STDOUT: {kind: 'CompileTimeBindingPattern', text: ':', subtree_size: 4},
// CHECK:STDOUT: {kind: 'ImplicitParamList', text: ']', subtree_size: 6},
@@ -166,8 +166,8 @@ impl
// CHECK:STDOUT: {kind: 'ImplIntroducer', text: 'impl'},
// CHECK:STDOUT: {kind: 'Forall', text: 'forall'},
// CHECK:STDOUT: {kind: 'ImplicitParamListStart', text: '['},
// CHECK:STDOUT: {kind: 'IdentifierNameNotBeforeSignature', text: 'T'},
// CHECK:STDOUT: {kind: 'CompileTimeBindingPatternStart', text: ':', subtree_size: 2},
// CHECK:STDOUT: {kind: 'IdentifierNameNotBeforeSignature', text: 'T'},
// CHECK:STDOUT: {kind: 'CompileTimeBindingPatternTypeStart', text: ':'},
// CHECK:STDOUT: {kind: 'TypeTypeLiteral', text: 'type'},
// CHECK:STDOUT: {kind: 'CompileTimeBindingPattern', text: ':', subtree_size: 4},
// CHECK:STDOUT: {kind: 'ImplicitParamList', text: ']', subtree_size: 6},
@@ -29,8 +29,8 @@ impl forall [T: J] T as Interface {
// CHECK:STDOUT: {kind: 'ImplIntroducer', text: 'impl'},
// CHECK:STDOUT: {kind: 'Forall', text: 'forall'},
// CHECK:STDOUT: {kind: 'ImplicitParamListStart', text: '['},
// CHECK:STDOUT: {kind: 'IdentifierNameNotBeforeSignature', text: 'T'},
// CHECK:STDOUT: {kind: 'CompileTimeBindingPatternStart', text: ':', subtree_size: 2},
// CHECK:STDOUT: {kind: 'IdentifierNameNotBeforeSignature', text: 'T'},
// CHECK:STDOUT: {kind: 'CompileTimeBindingPatternTypeStart', text: ':'},
// CHECK:STDOUT: {kind: 'IdentifierNameExpr', text: 'I'},
// CHECK:STDOUT: {kind: 'CompileTimeBindingPattern', text: ':', subtree_size: 4},
// CHECK:STDOUT: {kind: 'ImplicitParamList', text: ']', subtree_size: 6},
@@ -45,18 +45,19 @@ impl forall [T: J] T as Interface {
// CHECK:STDOUT: {kind: 'SelfBindingPattern', text: 'self', subtree_size: 2},
// CHECK:STDOUT: {kind: 'PatternListComma', text: ','},
// CHECK:STDOUT: {kind: 'IdentifierNameNotBeforeSignature', text: 'b'},
// CHECK:STDOUT: {kind: 'BindingPatternTypeStart', text: ':'},
// CHECK:STDOUT: {kind: 'SelfTypeNameExpr', text: 'Self'},
// CHECK:STDOUT: {kind: 'LetBindingPattern', text: ':', subtree_size: 3},
// CHECK:STDOUT: {kind: 'ExplicitParamList', text: ')', subtree_size: 8},
// CHECK:STDOUT: {kind: 'LetBindingPattern', text: ':', subtree_size: 4},
// CHECK:STDOUT: {kind: 'ExplicitParamList', text: ')', subtree_size: 9},
// CHECK:STDOUT: {kind: 'SelfTypeNameExpr', text: 'Self'},
// CHECK:STDOUT: {kind: 'ReturnType', text: '->', subtree_size: 2},
// CHECK:STDOUT: {kind: 'FunctionDecl', text: ';', subtree_size: 13},
// CHECK:STDOUT: {kind: 'ImplDefinition', text: '}', subtree_size: 26},
// CHECK:STDOUT: {kind: 'FunctionDecl', text: ';', subtree_size: 14},
// CHECK:STDOUT: {kind: 'ImplDefinition', text: '}', subtree_size: 27},
// CHECK:STDOUT: {kind: 'ImplIntroducer', text: 'impl'},
// CHECK:STDOUT: {kind: 'Forall', text: 'forall'},
// CHECK:STDOUT: {kind: 'ImplicitParamListStart', text: '['},
// CHECK:STDOUT: {kind: 'IdentifierNameNotBeforeSignature', text: 'T'},
// CHECK:STDOUT: {kind: 'CompileTimeBindingPatternStart', text: ':', subtree_size: 2},
// CHECK:STDOUT: {kind: 'IdentifierNameNotBeforeSignature', text: 'T'},
// CHECK:STDOUT: {kind: 'CompileTimeBindingPatternTypeStart', text: ':'},
// CHECK:STDOUT: {kind: 'IdentifierNameExpr', text: 'J'},
// CHECK:STDOUT: {kind: 'CompileTimeBindingPattern', text: ':', subtree_size: 4},
// CHECK:STDOUT: {kind: 'ImplicitParamList', text: ']', subtree_size: 6},
@@ -71,13 +72,14 @@ impl forall [T: J] T as Interface {
// CHECK:STDOUT: {kind: 'SelfBindingPattern', text: 'self', subtree_size: 2},
// CHECK:STDOUT: {kind: 'PatternListComma', text: ','},
// CHECK:STDOUT: {kind: 'IdentifierNameNotBeforeSignature', text: 'b'},
// CHECK:STDOUT: {kind: 'BindingPatternTypeStart', text: ':'},
// CHECK:STDOUT: {kind: 'SelfTypeNameExpr', text: 'Self'},
// CHECK:STDOUT: {kind: 'LetBindingPattern', text: ':', subtree_size: 3},
// CHECK:STDOUT: {kind: 'ExplicitParamList', text: ')', subtree_size: 8},
// CHECK:STDOUT: {kind: 'LetBindingPattern', text: ':', subtree_size: 4},
// CHECK:STDOUT: {kind: 'ExplicitParamList', text: ')', subtree_size: 9},
// CHECK:STDOUT: {kind: 'SelfTypeNameExpr', text: 'Self'},
// CHECK:STDOUT: {kind: 'ReturnType', text: '->', subtree_size: 2},
// CHECK:STDOUT: {kind: 'FunctionDecl', text: ';', subtree_size: 13},
// CHECK:STDOUT: {kind: 'ImplDefinition', text: '}', subtree_size: 26},
// CHECK:STDOUT: {kind: 'MatchFirst', text: '}', subtree_size: 56},
// CHECK:STDOUT: {kind: 'FunctionDecl', text: ';', subtree_size: 14},
// CHECK:STDOUT: {kind: 'ImplDefinition', text: '}', subtree_size: 27},
// CHECK:STDOUT: {kind: 'MatchFirst', text: '}', subtree_size: 58},
// CHECK:STDOUT: {kind: 'FileEnd', text: ''},
// CHECK:STDOUT: ]
+6 -6
View File
@@ -19,8 +19,8 @@ impl forall [T: type, U: Interface] U as Interface(T) {
// CHECK:STDOUT: {kind: 'ImplIntroducer', text: 'impl'},
// CHECK:STDOUT: {kind: 'Forall', text: 'forall'},
// CHECK:STDOUT: {kind: 'ImplicitParamListStart', text: '['},
// CHECK:STDOUT: {kind: 'IdentifierNameNotBeforeSignature', text: 'T'},
// CHECK:STDOUT: {kind: 'CompileTimeBindingPatternStart', text: ':', subtree_size: 2},
// CHECK:STDOUT: {kind: 'IdentifierNameNotBeforeSignature', text: 'T'},
// CHECK:STDOUT: {kind: 'CompileTimeBindingPatternTypeStart', text: ':'},
// CHECK:STDOUT: {kind: 'TypeTypeLiteral', text: 'type'},
// CHECK:STDOUT: {kind: 'CompileTimeBindingPattern', text: ':', subtree_size: 4},
// CHECK:STDOUT: {kind: 'ImplicitParamList', text: ']', subtree_size: 6},
@@ -31,13 +31,13 @@ impl forall [T: type, U: Interface] U as Interface(T) {
// CHECK:STDOUT: {kind: 'ImplIntroducer', text: 'impl'},
// CHECK:STDOUT: {kind: 'Forall', text: 'forall'},
// CHECK:STDOUT: {kind: 'ImplicitParamListStart', text: '['},
// CHECK:STDOUT: {kind: 'IdentifierNameNotBeforeSignature', text: 'T'},
// CHECK:STDOUT: {kind: 'CompileTimeBindingPatternStart', text: ':', subtree_size: 2},
// CHECK:STDOUT: {kind: 'IdentifierNameNotBeforeSignature', text: 'T'},
// CHECK:STDOUT: {kind: 'CompileTimeBindingPatternTypeStart', text: ':'},
// CHECK:STDOUT: {kind: 'TypeTypeLiteral', text: 'type'},
// CHECK:STDOUT: {kind: 'CompileTimeBindingPattern', text: ':', subtree_size: 4},
// CHECK:STDOUT: {kind: 'PatternListComma', text: ','},
// CHECK:STDOUT: {kind: 'IdentifierNameNotBeforeSignature', text: 'U'},
// CHECK:STDOUT: {kind: 'CompileTimeBindingPatternStart', text: ':', subtree_size: 2},
// CHECK:STDOUT: {kind: 'IdentifierNameNotBeforeSignature', text: 'U'},
// CHECK:STDOUT: {kind: 'CompileTimeBindingPatternTypeStart', text: ':'},
// CHECK:STDOUT: {kind: 'IdentifierNameExpr', text: 'Interface'},
// CHECK:STDOUT: {kind: 'CompileTimeBindingPattern', text: ':', subtree_size: 4},
// CHECK:STDOUT: {kind: 'ImplicitParamList', text: ']', subtree_size: 11},
+15 -13
View File
@@ -75,8 +75,8 @@ impl forall [T: J] T as Interface {
// CHECK:STDOUT: {kind: 'ImplIntroducer', text: 'impl'},
// CHECK:STDOUT: {kind: 'Forall', text: 'forall'},
// CHECK:STDOUT: {kind: 'ImplicitParamListStart', text: '['},
// CHECK:STDOUT: {kind: 'IdentifierNameNotBeforeSignature', text: 'T'},
// CHECK:STDOUT: {kind: 'CompileTimeBindingPatternStart', text: ':', subtree_size: 2},
// CHECK:STDOUT: {kind: 'IdentifierNameNotBeforeSignature', text: 'T'},
// CHECK:STDOUT: {kind: 'CompileTimeBindingPatternTypeStart', text: ':'},
// CHECK:STDOUT: {kind: 'IdentifierNameExpr', text: 'I'},
// CHECK:STDOUT: {kind: 'CompileTimeBindingPattern', text: ':', subtree_size: 4},
// CHECK:STDOUT: {kind: 'ImplicitParamList', text: ']', subtree_size: 6},
@@ -91,18 +91,19 @@ impl forall [T: J] T as Interface {
// CHECK:STDOUT: {kind: 'SelfBindingPattern', text: 'self', subtree_size: 2},
// CHECK:STDOUT: {kind: 'PatternListComma', text: ','},
// CHECK:STDOUT: {kind: 'IdentifierNameNotBeforeSignature', text: 'b'},
// CHECK:STDOUT: {kind: 'BindingPatternTypeStart', text: ':'},
// CHECK:STDOUT: {kind: 'SelfTypeNameExpr', text: 'Self'},
// CHECK:STDOUT: {kind: 'LetBindingPattern', text: ':', subtree_size: 3},
// CHECK:STDOUT: {kind: 'ExplicitParamList', text: ')', subtree_size: 8},
// CHECK:STDOUT: {kind: 'LetBindingPattern', text: ':', subtree_size: 4},
// CHECK:STDOUT: {kind: 'ExplicitParamList', text: ')', subtree_size: 9},
// CHECK:STDOUT: {kind: 'SelfTypeNameExpr', text: 'Self'},
// CHECK:STDOUT: {kind: 'ReturnType', text: '->', subtree_size: 2},
// CHECK:STDOUT: {kind: 'FunctionDecl', text: ';', subtree_size: 13},
// CHECK:STDOUT: {kind: 'ImplDefinition', text: '}', subtree_size: 26},
// CHECK:STDOUT: {kind: 'FunctionDecl', text: ';', subtree_size: 14},
// CHECK:STDOUT: {kind: 'ImplDefinition', text: '}', subtree_size: 27},
// CHECK:STDOUT: {kind: 'ImplIntroducer', text: 'impl'},
// CHECK:STDOUT: {kind: 'Forall', text: 'forall'},
// CHECK:STDOUT: {kind: 'ImplicitParamListStart', text: '['},
// CHECK:STDOUT: {kind: 'IdentifierNameNotBeforeSignature', text: 'T'},
// CHECK:STDOUT: {kind: 'CompileTimeBindingPatternStart', text: ':', subtree_size: 2},
// CHECK:STDOUT: {kind: 'IdentifierNameNotBeforeSignature', text: 'T'},
// CHECK:STDOUT: {kind: 'CompileTimeBindingPatternTypeStart', text: ':'},
// CHECK:STDOUT: {kind: 'IdentifierNameExpr', text: 'J'},
// CHECK:STDOUT: {kind: 'CompileTimeBindingPattern', text: ':', subtree_size: 4},
// CHECK:STDOUT: {kind: 'ImplicitParamList', text: ']', subtree_size: 6},
@@ -117,13 +118,14 @@ impl forall [T: J] T as Interface {
// CHECK:STDOUT: {kind: 'SelfBindingPattern', text: 'self', subtree_size: 2},
// CHECK:STDOUT: {kind: 'PatternListComma', text: ','},
// CHECK:STDOUT: {kind: 'IdentifierNameNotBeforeSignature', text: 'b'},
// CHECK:STDOUT: {kind: 'BindingPatternTypeStart', text: ':'},
// CHECK:STDOUT: {kind: 'SelfTypeNameExpr', text: 'Self'},
// CHECK:STDOUT: {kind: 'LetBindingPattern', text: ':', subtree_size: 3},
// CHECK:STDOUT: {kind: 'ExplicitParamList', text: ')', subtree_size: 8},
// CHECK:STDOUT: {kind: 'LetBindingPattern', text: ':', subtree_size: 4},
// CHECK:STDOUT: {kind: 'ExplicitParamList', text: ')', subtree_size: 9},
// CHECK:STDOUT: {kind: 'SelfTypeNameExpr', text: 'Self'},
// CHECK:STDOUT: {kind: 'ReturnType', text: '->', subtree_size: 2},
// CHECK:STDOUT: {kind: 'FunctionDecl', text: ';', subtree_size: 13},
// CHECK:STDOUT: {kind: 'ImplDefinition', text: '}', subtree_size: 26},
// CHECK:STDOUT: {kind: 'MatchFirst', text: '}', subtree_size: 55},
// CHECK:STDOUT: {kind: 'FunctionDecl', text: ';', subtree_size: 14},
// CHECK:STDOUT: {kind: 'ImplDefinition', text: '}', subtree_size: 27},
// CHECK:STDOUT: {kind: 'MatchFirst', text: '}', subtree_size: 57},
// CHECK:STDOUT: {kind: 'FileEnd', text: ''},
// CHECK:STDOUT: ]