mirror of
https://github.com/carbon-language/carbon-lang.git
synced 2026-09-24 22:02:23 +01:00
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:
@@ -163,7 +163,8 @@ auto HandleBindingPattern(Context& context) -> void {
|
||||
return;
|
||||
}
|
||||
on_error(/*expected_name=*/false);
|
||||
// Add a substitute for a type node.
|
||||
// Add a substitute for the identifier name and virtual type-start nodes.
|
||||
context.AddInvalidParse(*context.position());
|
||||
context.AddInvalidParse(*context.position());
|
||||
context.PushState(state, StateKind::BindingPatternFinishAsRegular);
|
||||
return;
|
||||
@@ -255,10 +256,13 @@ auto HandleBindingPattern(Context& context) -> void {
|
||||
// Use the `:` or `:?` for the root node.
|
||||
state.token = context.Consume();
|
||||
|
||||
// Add a virtual node before the binding's type expression.
|
||||
if (!is_form && resolved_generic) {
|
||||
// Add a virtual node before the compile time binding's type expression.
|
||||
context.AddNode(NodeKind::CompileTimeBindingPatternStart, state.token,
|
||||
state.has_error);
|
||||
context.AddLeafNode(NodeKind::CompileTimeBindingPatternTypeStart,
|
||||
state.token, state.has_error);
|
||||
} else {
|
||||
context.AddLeafNode(NodeKind::BindingPatternTypeStart, state.token,
|
||||
state.has_error);
|
||||
}
|
||||
|
||||
context.PushState(state);
|
||||
|
||||
Reference in New Issue
Block a user