Skip to content

Commit 6ea43ce

Browse files
powerboat9P-E-P
authored andcommitted
Remove Parser::parse_path_in_expression_pratt
This improves our handling of PathInExpression and fixes #4056. gcc/rust/ChangeLog: * parse/rust-parse-impl.h (Parser::parse_expr): Avoid skipping or splitting tokens. (Parser::null_denotation): Assume initial token was not skipped and adjust function signature to match. Use parse_path_in_expression instead of parse_path_in_expression_pratt and handle SCOPE_RESOLUTION. (Parser::parse_path_in_expression_pratt): Remove function. * parse/rust-parse.h (null_denotation): Remove initial token parameter. (parse_path_in_expression_pratt): Remove function. gcc/testsuite/ChangeLog: * rust/compile/global-path-array.rs: New test. Signed-off-by: Owen Avery <powerboat9.gamer@gmail.com>
1 parent 5800d70 commit 6ea43ce

File tree

3 files changed

+19
-137
lines changed

3 files changed

+19
-137
lines changed

gcc/rust/parse/rust-parse-impl.h

Lines changed: 13 additions & 135 deletions
Original file line numberDiff line numberDiff line change
@@ -12155,20 +12155,12 @@ Parser<ManagedTokenSource>::parse_expr (int right_binding_power,
1215512155
return nullptr;
1215612156
}
1215712157

12158-
if (current_token->get_id () == LEFT_SHIFT)
12159-
{
12160-
lexer.split_current_token (LEFT_ANGLE, LEFT_ANGLE);
12161-
current_token = lexer.peek_token ();
12162-
}
12163-
12164-
lexer.skip_token ();
12165-
1216612158
ParseRestrictions null_denotation_restrictions = restrictions;
1216712159
null_denotation_restrictions.expr_can_be_stmt = false;
1216812160

1216912161
// parse null denotation (unary part of expression)
1217012162
std::unique_ptr<AST::Expr> expr
12171-
= null_denotation (current_token, {}, null_denotation_restrictions);
12163+
= null_denotation ({}, null_denotation_restrictions);
1217212164

1217312165
return left_denotations (std::move (expr), right_binding_power,
1217412166
std::move (outer_attrs), restrictions);
@@ -12236,8 +12228,7 @@ Parser<ManagedTokenSource>::parse_expr (AST::AttrVec outer_attrs,
1223612228
/* Determines action to take when finding token at beginning of expression. */
1223712229
template <typename ManagedTokenSource>
1223812230
std::unique_ptr<AST::Expr>
12239-
Parser<ManagedTokenSource>::null_denotation (const_TokenPtr tok,
12240-
AST::AttrVec outer_attrs,
12231+
Parser<ManagedTokenSource>::null_denotation (AST::AttrVec outer_attrs,
1224112232
ParseRestrictions restrictions)
1224212233
{
1224312234
/* note: tok is previous character in input stream, not current one, as
@@ -12247,6 +12238,8 @@ Parser<ManagedTokenSource>::null_denotation (const_TokenPtr tok,
1224712238
* denotation and then a left denotation), null denotations handle primaries
1224812239
* and unary operands (but only prefix unary operands) */
1224912240

12241+
auto tok = lexer.peek_token ();
12242+
1225012243
switch (tok->get_id ())
1225112244
{
1225212245
case IDENTIFIER:
@@ -12255,28 +12248,26 @@ Parser<ManagedTokenSource>::null_denotation (const_TokenPtr tok,
1225512248
case DOLLAR_SIGN:
1225612249
case CRATE:
1225712250
case SUPER:
12251+
case SCOPE_RESOLUTION:
1225812252
{
1225912253
// DEBUG
1226012254
rust_debug ("beginning null denotation identifier handling");
1226112255

1226212256
/* best option: parse as path, then extract identifier, macro,
1226312257
* struct/enum, or just path info from it */
12264-
AST::PathInExpression path = parse_path_in_expression_pratt (tok);
12258+
AST::PathInExpression path = parse_path_in_expression ();
1226512259

1226612260
return null_denotation_path (std::move (path), std::move (outer_attrs),
1226712261
restrictions);
1226812262
}
12269-
case SCOPE_RESOLUTION:
12270-
{
12271-
// TODO: fix: this is for global paths, i.e. std::string::whatever
12272-
Error error (tok->get_locus (),
12273-
"found null denotation scope resolution operator, and "
12274-
"have not written handling for it");
12275-
add_error (std::move (error));
12276-
12277-
return nullptr;
12278-
}
1227912263
default:
12264+
if (tok->get_id () == LEFT_SHIFT)
12265+
{
12266+
lexer.split_current_token (LEFT_ANGLE, LEFT_ANGLE);
12267+
tok = lexer.peek_token ();
12268+
}
12269+
12270+
lexer.skip_token ();
1228012271
return null_denotation_not_path (std::move (tok), std::move (outer_attrs),
1228112272
restrictions);
1228212273
}
@@ -14442,119 +14433,6 @@ Parser<ManagedTokenSource>::parse_struct_expr_tuple_partial (
1444214433
std::move (outer_attrs), path_locus));
1444314434
}
1444414435

14445-
/* Parses a path in expression with the first token passed as a parameter (as
14446-
* it is skipped in token stream). Note that this only parses segment-first
14447-
* paths, not global ones. */
14448-
template <typename ManagedTokenSource>
14449-
AST::PathInExpression
14450-
Parser<ManagedTokenSource>::parse_path_in_expression_pratt (const_TokenPtr tok)
14451-
{
14452-
// HACK-y way of making up for pratt-parsing consuming first token
14453-
14454-
// DEBUG
14455-
rust_debug ("current peek token when starting path pratt parse: '%s'",
14456-
lexer.peek_token ()->get_token_description ());
14457-
14458-
// create segment vector
14459-
std::vector<AST::PathExprSegment> segments;
14460-
14461-
std::string initial_str;
14462-
14463-
switch (tok->get_id ())
14464-
{
14465-
case IDENTIFIER:
14466-
initial_str = tok->get_str ();
14467-
break;
14468-
case SUPER:
14469-
initial_str = Values::Keywords::SUPER;
14470-
break;
14471-
case SELF:
14472-
initial_str = Values::Keywords::SELF;
14473-
break;
14474-
case SELF_ALIAS:
14475-
initial_str = Values::Keywords::SELF_ALIAS;
14476-
break;
14477-
case CRATE:
14478-
initial_str = Values::Keywords::CRATE;
14479-
break;
14480-
case DOLLAR_SIGN:
14481-
if (lexer.peek_token ()->get_id () == CRATE)
14482-
{
14483-
initial_str = "$crate";
14484-
break;
14485-
}
14486-
gcc_fallthrough ();
14487-
default:
14488-
add_error (Error (tok->get_locus (),
14489-
"unrecognised token %qs in path in expression",
14490-
tok->get_token_description ()));
14491-
14492-
return AST::PathInExpression::create_error ();
14493-
}
14494-
14495-
// parse required initial segment
14496-
AST::PathExprSegment initial_segment (initial_str, tok->get_locus ());
14497-
// parse generic args (and turbofish), if they exist
14498-
/* use lookahead to determine if they actually exist (don't want to
14499-
* accidently parse over next ident segment) */
14500-
if (lexer.peek_token ()->get_id () == SCOPE_RESOLUTION
14501-
&& lexer.peek_token (1)->get_id () == LEFT_ANGLE)
14502-
{
14503-
// skip scope resolution
14504-
lexer.skip_token ();
14505-
14506-
AST::GenericArgs generic_args = parse_path_generic_args ();
14507-
14508-
initial_segment
14509-
= AST::PathExprSegment (AST::PathIdentSegment (initial_str,
14510-
tok->get_locus ()),
14511-
tok->get_locus (), std::move (generic_args));
14512-
}
14513-
if (initial_segment.is_error ())
14514-
{
14515-
// skip after somewhere?
14516-
// don't necessarily throw error but yeah
14517-
14518-
// DEBUG
14519-
rust_debug ("initial segment is error - returning null");
14520-
14521-
return AST::PathInExpression::create_error ();
14522-
}
14523-
segments.push_back (std::move (initial_segment));
14524-
14525-
// parse optional segments (as long as scope resolution operator exists)
14526-
const_TokenPtr t = lexer.peek_token ();
14527-
while (t->get_id () == SCOPE_RESOLUTION)
14528-
{
14529-
// skip scope resolution operator
14530-
lexer.skip_token ();
14531-
14532-
// parse the actual segment - it is an error if it doesn't exist now
14533-
AST::PathExprSegment segment = parse_path_expr_segment ();
14534-
if (segment.is_error ())
14535-
{
14536-
// skip after somewhere?
14537-
Error error (t->get_locus (),
14538-
"could not parse path expression segment");
14539-
add_error (std::move (error));
14540-
14541-
return AST::PathInExpression::create_error ();
14542-
}
14543-
14544-
segments.push_back (std::move (segment));
14545-
14546-
t = lexer.peek_token ();
14547-
}
14548-
14549-
// DEBUG:
14550-
rust_debug (
14551-
"current token (just about to return path to null denotation): '%s'",
14552-
lexer.peek_token ()->get_token_description ());
14553-
14554-
return AST::PathInExpression (std::move (segments), {}, tok->get_locus (),
14555-
false);
14556-
}
14557-
1455814436
// Parses a closure expression with pratt parsing (from null denotation).
1455914437
template <typename ManagedTokenSource>
1456014438
std::unique_ptr<AST::ClosureExpr>

gcc/rust/parse/rust-parse.h

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -397,7 +397,7 @@ template <typename ManagedTokenSource> class Parser
397397
AST::AttrVec outer_attrs = AST::AttrVec (),
398398
ParseRestrictions restrictions = ParseRestrictions ());
399399
std::unique_ptr<AST::Expr>
400-
null_denotation (const_TokenPtr t, AST::AttrVec outer_attrs = AST::AttrVec (),
400+
null_denotation (AST::AttrVec outer_attrs = AST::AttrVec (),
401401
ParseRestrictions restrictions = ParseRestrictions ());
402402
std::unique_ptr<AST::Expr>
403403
null_denotation_path (AST::PathInExpression path, AST::AttrVec outer_attrs,
@@ -602,7 +602,6 @@ template <typename ManagedTokenSource> class Parser
602602
std::unique_ptr<AST::CallExpr>
603603
parse_struct_expr_tuple_partial (AST::PathInExpression path,
604604
AST::AttrVec outer_attrs);
605-
AST::PathInExpression parse_path_in_expression_pratt (const_TokenPtr tok);
606605
std::unique_ptr<AST::ClosureExpr>
607606
parse_closure_expr_pratt (const_TokenPtr tok,
608607
AST::AttrVec outer_attrs = AST::AttrVec ());
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
const X: i32 = 1;
2+
3+
pub fn foo() -> [i32; 1] {
4+
[::X]
5+
}

0 commit comments

Comments
 (0)