mirror of
https://github.com/carbon-language/carbon-lang.git
synced 2026-10-05 22:02:55 +01:00
Only allow designators when parsing where __ = ... (#4304)
Implements [TODO](https://github.com/carbon-language/carbon-lang/pull/4275/files#r1751000646) introduced in #4275 . Note that this enforces the restriction syntactically in parse, following the [design](https://github.com/carbon-language/carbon-lang/blob/trunk/docs/design/generics/details.md#rewrite-constraints). --------- Co-authored-by: Josh L <josh11b@users.noreply.github.com>
This commit is contained in:
@@ -9,9 +9,23 @@
|
||||
namespace Carbon::Parse {
|
||||
|
||||
auto HandleRequirementBegin(Context& context) -> void {
|
||||
context.PopAndDiscardState();
|
||||
// TODO: Peek ahead for `.designator = ...`, and give it special handling.
|
||||
context.PushState(State::RequirementOperator);
|
||||
auto state = context.PopState();
|
||||
|
||||
// Peek ahead for `.designator = ...`, and give it special handling.
|
||||
if (context.PositionKind() == Lex::TokenKind::Period &&
|
||||
context.PositionKind(Lookahead::NextToken) ==
|
||||
Lex::TokenKind::Identifier &&
|
||||
context.PositionKind(static_cast<Lookahead>(2)) ==
|
||||
Lex::TokenKind::Equal) {
|
||||
auto period = context.Consume();
|
||||
context.AddNode(NodeKind::IdentifierName, context.Consume(),
|
||||
/*has_error=*/false);
|
||||
context.AddNode(NodeKind::DesignatorExpr, period, /*has_error=*/false);
|
||||
state.token = context.Consume();
|
||||
context.PushState(state, State::RequirementOperatorFinish);
|
||||
} else {
|
||||
context.PushState(State::RequirementOperator);
|
||||
}
|
||||
context.PushStateForExpr(PrecedenceGroup::ForRequirements());
|
||||
}
|
||||
|
||||
@@ -19,14 +33,22 @@ auto HandleRequirementOperator(Context& context) -> void {
|
||||
auto state = context.PopState();
|
||||
|
||||
switch (context.PositionKind()) {
|
||||
case Lex::TokenKind::Impls: {
|
||||
// Accept either `impls` or `==`
|
||||
case Lex::TokenKind::Impls:
|
||||
case Lex::TokenKind::EqualEqual:
|
||||
break;
|
||||
}
|
||||
|
||||
// Reject `=` since correct usage is consumed in `HandleRequirementBegin`.
|
||||
case Lex::TokenKind::Equal: {
|
||||
break;
|
||||
}
|
||||
case Lex::TokenKind::EqualEqual: {
|
||||
break;
|
||||
if (!state.has_error) {
|
||||
CARBON_DIAGNOSTIC(
|
||||
RequirementEqualAfterNonDesignator, Error,
|
||||
"Requirement can only use `=` after `.member` designator.");
|
||||
context.emitter().Emit(*context.position(),
|
||||
RequirementEqualAfterNonDesignator);
|
||||
}
|
||||
context.ReturnErrorOnState();
|
||||
return;
|
||||
}
|
||||
default: {
|
||||
if (!state.has_error) {
|
||||
|
||||
Reference in New Issue
Block a user