diff options
author | Philip Herron <philip.herron@embecosm.com> | 2021-02-08 13:26:07 +0000 |
---|---|---|
committer | Philip Herron <herron.philip@googlemail.com> | 2021-02-09 09:47:13 +0000 |
commit | 60cccd8e58f2a024676599cc00971a6e406e6d42 (patch) | |
tree | fbdf44ca68e745e5af0d89fb16789570673c8a75 /gcc | |
parent | 9f3ddb35959606cbf7059362acfc27a9966ac3d4 (diff) | |
download | gcc-60cccd8e58f2a024676599cc00971a6e406e6d42.zip gcc-60cccd8e58f2a024676599cc00971a6e406e6d42.tar.gz gcc-60cccd8e58f2a024676599cc00971a6e406e6d42.tar.bz2 |
Fixes parsing if expressions as part of an expression.
This allows for rust style ternery expressions.
Fixes #214
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/rust/parse/rust-parse-impl.h | 50 | ||||
-rw-r--r-- | gcc/rust/parse/rust-parse.h | 6 | ||||
-rw-r--r-- | gcc/testsuite/rust.test/compilable/block_expr_parser_bug.rs | 4 |
3 files changed, 50 insertions, 10 deletions
diff --git a/gcc/rust/parse/rust-parse-impl.h b/gcc/rust/parse/rust-parse-impl.h index ea468ca..906f6b1 100644 --- a/gcc/rust/parse/rust-parse-impl.h +++ b/gcc/rust/parse/rust-parse-impl.h @@ -7504,12 +7504,23 @@ Parser<ManagedTokenSource>::parse_loop_label () template <typename ManagedTokenSource> std::unique_ptr<AST::IfExpr> Parser<ManagedTokenSource>::parse_if_expr ( - std::vector<AST::Attribute> outer_attrs ATTRIBUTE_UNUSED) + std::vector<AST::Attribute> outer_attrs ATTRIBUTE_UNUSED, bool pratt_parse) { // TODO: make having outer attributes an error? - - Location locus = lexer.peek_token ()->get_locus (); - skip_token (IF); + Location locus = Linemap::unknown_location (); + if (!pratt_parse) + { + locus = lexer.peek_token ()->get_locus (); + if (!skip_token (IF)) + { + skip_after_end_block (); + return nullptr; + } + } + else + { + locus = lexer.peek_token ()->get_locus () - 1; + } // detect accidental if let if (lexer.peek_token ()->get_id () == LET) @@ -7640,12 +7651,23 @@ Parser<ManagedTokenSource>::parse_if_expr ( template <typename ManagedTokenSource> std::unique_ptr<AST::IfLetExpr> Parser<ManagedTokenSource>::parse_if_let_expr ( - std::vector<AST::Attribute> outer_attrs ATTRIBUTE_UNUSED) + std::vector<AST::Attribute> outer_attrs ATTRIBUTE_UNUSED, bool pratt_parse) { // TODO: make having outer attributes an error? - - Location locus = lexer.peek_token ()->get_locus (); - skip_token (IF); + Location locus = Linemap::unknown_location (); + if (!pratt_parse) + { + locus = lexer.peek_token ()->get_locus (); + if (!skip_token (IF)) + { + skip_after_end_block (); + return nullptr; + } + } + else + { + locus = lexer.peek_token ()->get_locus () - 1; + } // detect accidental if expr parsed as if let expr if (lexer.peek_token ()->get_id () != LET) @@ -12399,6 +12421,18 @@ Parser<ManagedTokenSource>::null_denotation ( case LEFT_CURLY: // ok - this is an expression with block for once. return parse_block_expr (std::move (outer_attrs), true); + case IF: + // if or if let, so more lookahead to find out + if (lexer.peek_token (1)->get_id () == LET) + { + // if let expr + return parse_if_let_expr (std::move (outer_attrs), true); + } + else + { + // if expr + return parse_if_expr (std::move (outer_attrs), true); + } case MATCH_TOK: // also an expression with block return parse_match_expr (std::move (outer_attrs), true); diff --git a/gcc/rust/parse/rust-parse.h b/gcc/rust/parse/rust-parse.h index 2778ec7..aeda82b 100644 --- a/gcc/rust/parse/rust-parse.h +++ b/gcc/rust/parse/rust-parse.h @@ -480,10 +480,12 @@ private: bool pratt_parse = false); std::unique_ptr<AST::IfExpr> parse_if_expr (std::vector<AST::Attribute> outer_attrs - = std::vector<AST::Attribute> ()); + = std::vector<AST::Attribute> (), + bool pratt_parse = false); std::unique_ptr<AST::IfLetExpr> parse_if_let_expr (std::vector<AST::Attribute> outer_attrs - = std::vector<AST::Attribute> ()); + = std::vector<AST::Attribute> (), + bool pratt_parse = false); std::unique_ptr<AST::LoopExpr> parse_loop_expr (std::vector<AST::Attribute> outer_attrs = std::vector<AST::Attribute> (), diff --git a/gcc/testsuite/rust.test/compilable/block_expr_parser_bug.rs b/gcc/testsuite/rust.test/compilable/block_expr_parser_bug.rs new file mode 100644 index 0000000..e583008 --- /dev/null +++ b/gcc/testsuite/rust.test/compilable/block_expr_parser_bug.rs @@ -0,0 +1,4 @@ +fn main() { + let a = 123; + let b = if a > 10 { a - 1 } else { a + 1 }; +} |