mirror of
https://github.com/carbon-language/carbon-lang.git
synced 2026-10-05 22:02:55 +01:00
Support ref tags on arguments to ref params (#6312)
The issue of whether/how to include `ref` tags in the textual and in-memory SemIR (see discussion [here](https://discord.com/channels/655572317891461132/655578254970716160/1431316355742961805)) is left as future work. --------- Co-authored-by: Richard Smith <richard@metafoo.co.uk>
This commit is contained in:
co-authored by
Richard Smith
parent
b36f85c2a5
commit
43ffd721a4
@@ -43,6 +43,34 @@ auto HandleOnlyParenExprFinish(Context& context) -> void {
|
||||
FinishParenExpr(context, state);
|
||||
}
|
||||
|
||||
static auto HandleRefTagFinish(Context& context, StateKind state_kind) -> void {
|
||||
auto state = context.PopState();
|
||||
if (state_kind == StateKind::RefTagFinishAsAfterOpenParen &&
|
||||
!context.PositionIs(Lex::TokenKind::Comma)) {
|
||||
CARBON_DIAGNOSTIC(UnexpectedRef, Error,
|
||||
"found `ref` in unexpected position");
|
||||
context.emitter().Emit(state.token, UnexpectedRef);
|
||||
}
|
||||
context.AddNode(NodeKind::RefTag, state.token, state.has_error);
|
||||
}
|
||||
|
||||
auto HandleRefTagFinishAsRegular(Context& context) -> void {
|
||||
HandleRefTagFinish(context, StateKind::RefTagFinishAsRegular);
|
||||
}
|
||||
|
||||
auto HandleRefTagFinishAsAfterOpenParen(Context& context) -> void {
|
||||
HandleRefTagFinish(context, StateKind::RefTagFinishAsAfterOpenParen);
|
||||
}
|
||||
|
||||
static auto StartTupleLiteralElement(Context& context) -> void {
|
||||
context.PushState(StateKind::TupleLiteralElementFinish);
|
||||
if (context.PositionIs(Lex::TokenKind::Ref)) {
|
||||
context.PushState(StateKind::RefTagFinishAsRegular);
|
||||
context.ConsumeChecked(Lex::TokenKind::Ref);
|
||||
}
|
||||
context.PushState(StateKind::Expr);
|
||||
}
|
||||
|
||||
auto HandleParenExpr(Context& context) -> void {
|
||||
auto state = context.PopState();
|
||||
|
||||
@@ -56,6 +84,10 @@ auto HandleParenExpr(Context& context) -> void {
|
||||
} else {
|
||||
context.PushState(state, StateKind::ParenExprFinish);
|
||||
context.PushState(StateKind::ExprAfterOpenParenFinish);
|
||||
if (context.PositionIs(Lex::TokenKind::Ref)) {
|
||||
context.PushState(StateKind::RefTagFinishAsAfterOpenParen);
|
||||
context.ConsumeChecked(Lex::TokenKind::Ref);
|
||||
}
|
||||
context.PushState(StateKind::Expr);
|
||||
}
|
||||
}
|
||||
@@ -78,25 +110,26 @@ auto HandleExprAfterOpenParenFinish(Context& context) -> void {
|
||||
// If the comma is not immediately followed by a close paren, push handlers
|
||||
// for the next tuple element.
|
||||
if (list_token_kind != Context::ListTokenKind::CommaClose) {
|
||||
context.PushState(state, StateKind::TupleLiteralElementFinish);
|
||||
context.PushState(StateKind::Expr);
|
||||
StartTupleLiteralElement(context);
|
||||
}
|
||||
}
|
||||
|
||||
auto HandleTupleLiteralElementFinish(Context& context) -> void {
|
||||
auto state = context.PopState();
|
||||
|
||||
if (state.has_error) {
|
||||
context.ReturnErrorOnState();
|
||||
}
|
||||
|
||||
if (context.ConsumeListToken(NodeKind::TupleLiteralComma,
|
||||
Lex::TokenKind::CloseParen, state.has_error) ==
|
||||
Context::ListTokenKind::Comma) {
|
||||
context.PushState(state);
|
||||
context.PushState(StateKind::Expr);
|
||||
StartTupleLiteralElement(context);
|
||||
}
|
||||
}
|
||||
|
||||
auto HandleParenExprFinish(Context& context) -> void {
|
||||
auto state = context.PopState();
|
||||
|
||||
context.ReplacePlaceholderNode(state.subtree_start, NodeKind::ParenExprStart,
|
||||
state.token);
|
||||
FinishParenExpr(context, state);
|
||||
@@ -110,4 +143,20 @@ auto HandleTupleLiteralFinish(Context& context) -> void {
|
||||
context.AddNode(NodeKind::TupleLiteral, context.Consume(), state.has_error);
|
||||
}
|
||||
|
||||
auto HandleCallExpr(Context& context) -> void {
|
||||
auto state = context.PopState();
|
||||
context.PushState(state, StateKind::CallExprFinish);
|
||||
|
||||
context.AddNode(NodeKind::CallExprStart, context.Consume(), state.has_error);
|
||||
if (!context.PositionIs(Lex::TokenKind::CloseParen)) {
|
||||
StartTupleLiteralElement(context);
|
||||
}
|
||||
}
|
||||
|
||||
auto HandleCallExprFinish(Context& context) -> void {
|
||||
auto state = context.PopState();
|
||||
|
||||
context.AddNode(NodeKind::CallExpr, context.Consume(), state.has_error);
|
||||
}
|
||||
|
||||
} // namespace Carbon::Parse
|
||||
|
||||
Reference in New Issue
Block a user