Skip to content

Commit a4e3ffd

Browse files
bors[bot]Mark Wielaard
and
Mark Wielaard
authored
Merge #593
593: Support RangeFrom ([x..]) and RangeFromTo ([x..y]) in the parser r=philberty a=dkm Parsing the .. (DOT_DOT) operator to get a range had two issues. Trying to compile: let block = [1,2,3,4,5]; let _rf = &block[1..]; let _rt = &block[..3]; let _rft = &block[2..4]; range.rs:4:23: error: found unexpected token ‘]’ in null denotation 4 | let _rf = &block[1..]; | ^ range.rs:4:24: error: expecting ‘]’ but ‘;’ found 4 | let _rf = &block[1..]; | ^ Since .. can represent either a range from or a range from-to it can be followed by an expression or not. We do have a hack in our pratt-parser so that it is allowed to return a nullptr. But even in that case it will have swallowed the next token. Add another hack to the pratt-parser so that if the next token is one that cannot start an expression and the caller allows a nullptr return then don't skip the token and return immediately. After this patch we can parse the above range expressions, but we still don't handle them fully: range.rs:4:20: fatal error: Failed to lower expr: [1..] 4 | let _rf = &block[1..]; | ^ Ranges are actually syntactic sugar for std::ops::Range[From|To]. Co-authored-by: Mark Wielaard <[email protected]>
2 parents 4447dba + f2ce416 commit a4e3ffd

File tree

1 file changed

+15
-0
lines changed

1 file changed

+15
-0
lines changed

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

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12348,6 +12348,18 @@ Parser<ManagedTokenSource>::parse_expr (int right_binding_power,
1234812348
ParseRestrictions restrictions)
1234912349
{
1235012350
const_TokenPtr current_token = lexer.peek_token ();
12351+
// Special hack because we are allowed to return nullptr, in that case we
12352+
// don't want to skip the token, since we don't actually parse it. But if
12353+
// null isn't allowed it indicates an error, and we want to skip past that.
12354+
// So return early if it is one of the tokens that ends an expression
12355+
// (or at least cannot start a new expression).
12356+
if (restrictions.expr_can_be_null)
12357+
{
12358+
TokenId id = current_token->get_id ();
12359+
if (id == SEMICOLON || id == RIGHT_PAREN || id == RIGHT_CURLY
12360+
|| id == RIGHT_SQUARE)
12361+
return nullptr;
12362+
}
1235112363
lexer.skip_token ();
1235212364

1235312365
// parse null denotation (unary part of expression)
@@ -14036,6 +14048,9 @@ Parser<ManagedTokenSource>::parse_led_range_exclusive_expr (
1403614048
{
1403714049
// FIXME: this probably parses expressions accidently or whatever
1403814050
// try parsing RHS (as tok has already been consumed in parse_expression)
14051+
// Can be nullptr, in which case it is a RangeFromExpr, otherwise a
14052+
// RangeFromToExpr.
14053+
restrictions.expr_can_be_null = true;
1403914054
std::unique_ptr<AST::Expr> right
1404014055
= parse_expr (LBP_DOT_DOT, AST::AttrVec (), restrictions);
1404114056

0 commit comments

Comments
 (0)