about summary refs log tree commit diff
path: root/compiler/rustc_parse/src/parser/expr.rs
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2022-02-25 13:28:49 +0000
committerbors <bors@rust-lang.org>2022-02-25 13:28:49 +0000
commit9f8f0a6e9484fe25517c082a5cbe1e9edb17c8a8 (patch)
tree73d3fa90a8ca718ed39a8529e1901015f3a9bdc6 /compiler/rustc_parse/src/parser/expr.rs
parent9b2a46591ad0cc9dbe7699c17e2ecdb4dc921228 (diff)
parent60606456d3b5cd4baf68f18191b0cfca57d9c85c (diff)
downloadrust-9f8f0a6e9484fe25517c082a5cbe1e9edb17c8a8.tar.gz
rust-9f8f0a6e9484fe25517c082a5cbe1e9edb17c8a8.zip
Auto merge of #94357 - matthiaskrgr:rollup-xrjaof3, r=matthiaskrgr
Rollup of 7 pull requests

Successful merges:

 - #93845 (Remove in band lifetimes)
 - #94155 (Extend toggle GUI test a bit)
 - #94252 (don't special case `DefKind::Ctor` in encoding)
 - #94305 (Remove an unnecessary restriction in `dest_prop`)
 - #94343 (Miri fn ptr check: don't use conservative null check)
 - #94344 (diagnostic: suggest parens when users want logical ops, but get closures)
 - #94352 (Fix SGX docs build)

Failed merges:

r? `@ghost`
`@rustbot` modify labels: rollup
Diffstat (limited to 'compiler/rustc_parse/src/parser/expr.rs')
-rw-r--r--compiler/rustc_parse/src/parser/expr.rs18
1 files changed, 16 insertions, 2 deletions
diff --git a/compiler/rustc_parse/src/parser/expr.rs b/compiler/rustc_parse/src/parser/expr.rs
index c6919779ffd..a11cb3f5677 100644
--- a/compiler/rustc_parse/src/parser/expr.rs
+++ b/compiler/rustc_parse/src/parser/expr.rs
@@ -372,10 +372,17 @@ impl<'a> Parser<'a> {
                 self.sess.ambiguous_block_expr_parse.borrow_mut().insert(sp, lhs.span);
                 false
             }
-            (true, Some(AssocOp::LAnd)) => {
+            (true, Some(AssocOp::LAnd)) |
+            (true, Some(AssocOp::LOr)) |
+            (true, Some(AssocOp::BitOr)) => {
                 // `{ 42 } &&x` (#61475) or `{ 42 } && if x { 1 } else { 0 }`. Separated from the
                 // above due to #74233.
                 // These cases are ambiguous and can't be identified in the parser alone.
+                //
+                // Bitwise AND is left out because guessing intent is hard. We can make
+                // suggestions based on the assumption that double-refs are rarely intentional,
+                // and closures are distinct enough that they don't get mixed up with their
+                // return value.
                 let sp = self.sess.source_map().start_point(self.token.span);
                 self.sess.ambiguous_block_expr_parse.borrow_mut().insert(sp, lhs.span);
                 false
@@ -1247,7 +1254,14 @@ impl<'a> Parser<'a> {
         } else if self.check(&token::OpenDelim(token::Brace)) {
             self.parse_block_expr(None, lo, BlockCheckMode::Default, attrs)
         } else if self.check(&token::BinOp(token::Or)) || self.check(&token::OrOr) {
-            self.parse_closure_expr(attrs)
+            self.parse_closure_expr(attrs).map_err(|mut err| {
+                // If the input is something like `if a { 1 } else { 2 } | if a { 3 } else { 4 }`
+                // then suggest parens around the lhs.
+                if let Some(sp) = self.sess.ambiguous_block_expr_parse.borrow().get(&lo) {
+                    self.sess.expr_parentheses_needed(&mut err, *sp);
+                }
+                err
+            })
         } else if self.check(&token::OpenDelim(token::Bracket)) {
             self.parse_array_or_repeat_expr(attrs, token::Bracket)
         } else if self.check_path() {