about summary refs log tree commit diff
path: root/compiler/rustc_parse/src/parser/expr.rs
diff options
context:
space:
mode:
authorTheodore Luo Wang <wangtheo662@gmail.com>2021-09-01 11:54:06 -0400
committerTheodore Luo Wang <wangtheo662@gmail.com>2021-09-01 11:54:06 -0400
commit5a863d594c725d09ab8f0df5caba374d72200976 (patch)
treed28a9a6e49f245fe04115c05df353464723e0912 /compiler/rustc_parse/src/parser/expr.rs
parente7fb98e7258557034f0d0caf81a53b0070a87297 (diff)
downloadrust-5a863d594c725d09ab8f0df5caba374d72200976.tar.gz
rust-5a863d594c725d09ab8f0df5caba374d72200976.zip
Add checks for a block before a unary plus. Fix failing tests
Diffstat (limited to 'compiler/rustc_parse/src/parser/expr.rs')
-rw-r--r--compiler/rustc_parse/src/parser/expr.rs30
1 files changed, 22 insertions, 8 deletions
diff --git a/compiler/rustc_parse/src/parser/expr.rs b/compiler/rustc_parse/src/parser/expr.rs
index 43de53e8723..c887f9fe0cf 100644
--- a/compiler/rustc_parse/src/parser/expr.rs
+++ b/compiler/rustc_parse/src/parser/expr.rs
@@ -165,9 +165,12 @@ impl<'a> Parser<'a> {
             if [token::DotDot, token::DotDotDot, token::DotDotEq].contains(&self.token.kind) {
                 return self.parse_prefix_range_expr(attrs);
             } else {
-                self.parse_prefix_expr(attrs)?
+                let result = self.parse_prefix_expr(attrs);
+                debug!("parse_prefix_expr result: {:?}", &result);
+                result?
             }
         };
+        debug!("parse_assoc_expr_with(lhs = {:?})", &lhs);
         let last_type_ascription_set = self.last_type_ascription.is_some();
 
         if !self.should_continue_as_assoc_expr(&lhs) {
@@ -175,8 +178,11 @@ impl<'a> Parser<'a> {
             return Ok(lhs);
         }
 
+        debug!("continue_as_assoc_expr");
+
         self.expected_tokens.push(TokenType::Operator);
         while let Some(op) = self.check_assoc_op() {
+            debug!("op: {:?}", op);
             // Adjust the span for interpolated LHS to point to the `$lhs` token
             // and not to what it refers to.
             let lhs_span = match self.prev_token.kind {
@@ -520,17 +526,25 @@ impl<'a> Parser<'a> {
                 make_it!(this, attrs, |this, _| this.parse_borrow_expr(lo))
             }
             token::BinOp(token::Plus) => {
-                this.struct_span_err(lo, "leading `+` is not supported")
-                    .span_label(lo, "unexpected `+`")
-                    .span_suggestion_short(
+                debug!("leading + detected: {:?}", lo);
+                let mut err = this.struct_span_err(lo, "leading `+` is not supported");
+                err.span_label(lo, "unexpected `+`");
+
+                // a block on the LHS might have been intended to be an expression instead
+                let sp = this.sess.source_map().start_point(lo);
+                if let Some(sp) = this.sess.ambiguous_block_expr_parse.borrow().get(&sp) {
+                    this.sess.expr_parentheses_needed(&mut err, *sp);
+                } else {
+                   err.span_suggestion(
                         lo,
-                        "remove the `+`",
+                        "try removing the `+`",
                         "".to_string(),
                         Applicability::MachineApplicable,
-                    )
-                    .emit();
-                this.bump();
+                    );
+                }
+                err.emit();
 
+                this.bump();
                 this.parse_prefix_expr(None)
             } // `+expr`
             token::Ident(..) if this.token.is_keyword(kw::Box) => {