From 5a863d594c725d09ab8f0df5caba374d72200976 Mon Sep 17 00:00:00 2001 From: Theodore Luo Wang Date: Wed, 1 Sep 2021 11:54:06 -0400 Subject: [PATCH] Add checks for a block before a unary plus. Fix failing tests --- compiler/rustc_parse/src/parser/expr.rs | 30 ++++++++--- compiler/rustc_parse/src/parser/stmt.rs | 3 ++ .../ui/associated-types/issue-36499.stderr | 7 ++- src/test/ui/parser/expr-as-stmt.fixed | 6 +-- src/test/ui/parser/expr-as-stmt.rs | 6 +-- src/test/ui/parser/expr-as-stmt.stderr | 12 ++--- .../issue-88276-unary-plus.fixed | 4 +- .../issue-88276-unary-plus.rs | 4 +- .../issue-88276-unary-plus.stderr | 54 +++++++++---------- 9 files changed, 73 insertions(+), 53 deletions(-) rename src/test/ui/{did_you_mean => parser}/issue-88276-unary-plus.fixed (78%) rename src/test/ui/{did_you_mean => parser}/issue-88276-unary-plus.rs (78%) rename src/test/ui/{did_you_mean => parser}/issue-88276-unary-plus.stderr (61%) 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) => { diff --git a/compiler/rustc_parse/src/parser/stmt.rs b/compiler/rustc_parse/src/parser/stmt.rs index 85515bd2a63..329b60f9a87 100644 --- a/compiler/rustc_parse/src/parser/stmt.rs +++ b/compiler/rustc_parse/src/parser/stmt.rs @@ -21,6 +21,8 @@ use rustc_span::symbol::{kw, sym}; use std::mem; +use tracing::debug; + impl<'a> Parser<'a> { /// Parses a statement. This stops just before trailing semicolons on everything but items. /// e.g., a `StmtKind::Semi` parses to a `StmtKind::Expr`, leaving the trailing `;` unconsumed. @@ -418,6 +420,7 @@ impl<'a> Parser<'a> { if self.token == token::Eof { break; } + debug!("parsing statements, stmts: {:?}", &stmts); let stmt = match self.parse_full_stmt(recover) { Err(mut err) if recover.yes() => { self.maybe_annotate_with_ascription(&mut err, false); diff --git a/src/test/ui/associated-types/issue-36499.stderr b/src/test/ui/associated-types/issue-36499.stderr index ff450f60acc..990ef09e3f7 100644 --- a/src/test/ui/associated-types/issue-36499.stderr +++ b/src/test/ui/associated-types/issue-36499.stderr @@ -1,8 +1,11 @@ -error: expected expression, found `+` +error: leading `+` is not supported --> $DIR/issue-36499.rs:4:9 | LL | 2 + +2; - | ^ expected expression + | ^ + | | + | unexpected `+` + | help: try removing the `+` error: aborting due to previous error diff --git a/src/test/ui/parser/expr-as-stmt.fixed b/src/test/ui/parser/expr-as-stmt.fixed index c217ab9774f..79d73090a04 100644 --- a/src/test/ui/parser/expr-as-stmt.fixed +++ b/src/test/ui/parser/expr-as-stmt.fixed @@ -5,18 +5,18 @@ #![allow(unused_must_use)] fn foo() -> i32 { - ({2}) + {2} //~ ERROR expected expression, found `+` + ({2}) + {2} //~ ERROR leading `+` is not supported //~^ ERROR mismatched types } fn bar() -> i32 { - ({2}) + 2 //~ ERROR expected expression, found `+` + ({2}) + 2 //~ ERROR leading `+` is not supported //~^ ERROR mismatched types } fn zul() -> u32 { let foo = 3; - ({ 42 }) + foo; //~ ERROR expected expression, found `+` + ({ 42 }) + foo; //~ ERROR leading `+` is not supported //~^ ERROR mismatched types 32 } diff --git a/src/test/ui/parser/expr-as-stmt.rs b/src/test/ui/parser/expr-as-stmt.rs index b04025faaec..8698f99b81a 100644 --- a/src/test/ui/parser/expr-as-stmt.rs +++ b/src/test/ui/parser/expr-as-stmt.rs @@ -5,18 +5,18 @@ #![allow(unused_must_use)] fn foo() -> i32 { - {2} + {2} //~ ERROR expected expression, found `+` + {2} + {2} //~ ERROR leading `+` is not supported //~^ ERROR mismatched types } fn bar() -> i32 { - {2} + 2 //~ ERROR expected expression, found `+` + {2} + 2 //~ ERROR leading `+` is not supported //~^ ERROR mismatched types } fn zul() -> u32 { let foo = 3; - { 42 } + foo; //~ ERROR expected expression, found `+` + { 42 } + foo; //~ ERROR leading `+` is not supported //~^ ERROR mismatched types 32 } diff --git a/src/test/ui/parser/expr-as-stmt.stderr b/src/test/ui/parser/expr-as-stmt.stderr index ba5cd01abfc..91f97c4662a 100644 --- a/src/test/ui/parser/expr-as-stmt.stderr +++ b/src/test/ui/parser/expr-as-stmt.stderr @@ -1,30 +1,30 @@ -error: expected expression, found `+` +error: leading `+` is not supported --> $DIR/expr-as-stmt.rs:8:9 | LL | {2} + {2} - | ^ expected expression + | ^ unexpected `+` | help: parentheses are required to parse this as an expression | LL | ({2}) + {2} | + + -error: expected expression, found `+` +error: leading `+` is not supported --> $DIR/expr-as-stmt.rs:13:9 | LL | {2} + 2 - | ^ expected expression + | ^ unexpected `+` | help: parentheses are required to parse this as an expression | LL | ({2}) + 2 | + + -error: expected expression, found `+` +error: leading `+` is not supported --> $DIR/expr-as-stmt.rs:19:12 | LL | { 42 } + foo; - | ^ expected expression + | ^ unexpected `+` | help: parentheses are required to parse this as an expression | diff --git a/src/test/ui/did_you_mean/issue-88276-unary-plus.fixed b/src/test/ui/parser/issue-88276-unary-plus.fixed similarity index 78% rename from src/test/ui/did_you_mean/issue-88276-unary-plus.fixed rename to src/test/ui/parser/issue-88276-unary-plus.fixed index 4bd248663b8..279cdb5060a 100644 --- a/src/test/ui/did_you_mean/issue-88276-unary-plus.fixed +++ b/src/test/ui/parser/issue-88276-unary-plus.fixed @@ -3,10 +3,10 @@ fn main() { let _ = 1; //~ ERROR leading `+` is not supported let _ = -(1+2)*3; //~ ERROR leading `+` is not supported - let _ = -(1+2)*3; //~ ERROR leading `+` is not supported - //~| ERROR leading `+` is not supported let _ = --(1+2)*3; //~ ERROR leading `+` is not supported //~| ERROR leading `+` is not supported + let _ = (1 + 2) * 3; //~ ERROR leading `+` is not supported + //~| ERROR leading `+` is not supported let _ = (&"hello"); //~ ERROR leading `+` is not supported let _ = [3, 4+6]; //~ ERROR leading `+` is not supported //~| ERROR leading `+` is not supported diff --git a/src/test/ui/did_you_mean/issue-88276-unary-plus.rs b/src/test/ui/parser/issue-88276-unary-plus.rs similarity index 78% rename from src/test/ui/did_you_mean/issue-88276-unary-plus.rs rename to src/test/ui/parser/issue-88276-unary-plus.rs index e2cce677b47..a72dad4dc71 100644 --- a/src/test/ui/did_you_mean/issue-88276-unary-plus.rs +++ b/src/test/ui/parser/issue-88276-unary-plus.rs @@ -3,10 +3,10 @@ fn main() { let _ = +1; //~ ERROR leading `+` is not supported let _ = -+(1+2)*3; //~ ERROR leading `+` is not supported - let _ = +-+(1+2)*3; //~ ERROR leading `+` is not supported - //~| ERROR leading `+` is not supported let _ = -+-+(1+2)*3; //~ ERROR leading `+` is not supported //~| ERROR leading `+` is not supported + let _ = (1 + +2) * +3; //~ ERROR leading `+` is not supported + //~| ERROR leading `+` is not supported let _ = (+&"hello"); //~ ERROR leading `+` is not supported let _ = +[+3, 4+6]; //~ ERROR leading `+` is not supported //~| ERROR leading `+` is not supported diff --git a/src/test/ui/did_you_mean/issue-88276-unary-plus.stderr b/src/test/ui/parser/issue-88276-unary-plus.stderr similarity index 61% rename from src/test/ui/did_you_mean/issue-88276-unary-plus.stderr rename to src/test/ui/parser/issue-88276-unary-plus.stderr index 9c1227d7c35..255839bc684 100644 --- a/src/test/ui/did_you_mean/issue-88276-unary-plus.stderr +++ b/src/test/ui/parser/issue-88276-unary-plus.stderr @@ -5,7 +5,7 @@ LL | let _ = +1; | ^ | | | unexpected `+` - | help: remove the `+` + | help: try removing the `+` error: leading `+` is not supported --> $DIR/issue-88276-unary-plus.rs:5:14 @@ -14,43 +14,43 @@ LL | let _ = -+(1+2)*3; | ^ | | | unexpected `+` - | help: remove the `+` + | help: try removing the `+` error: leading `+` is not supported - --> $DIR/issue-88276-unary-plus.rs:6:13 - | -LL | let _ = +-+(1+2)*3; - | ^ - | | - | unexpected `+` - | help: remove the `+` - -error: leading `+` is not supported - --> $DIR/issue-88276-unary-plus.rs:6:15 - | -LL | let _ = +-+(1+2)*3; - | ^ - | | - | unexpected `+` - | help: remove the `+` - -error: leading `+` is not supported - --> $DIR/issue-88276-unary-plus.rs:8:14 + --> $DIR/issue-88276-unary-plus.rs:6:14 | LL | let _ = -+-+(1+2)*3; | ^ | | | unexpected `+` - | help: remove the `+` + | help: try removing the `+` error: leading `+` is not supported - --> $DIR/issue-88276-unary-plus.rs:8:16 + --> $DIR/issue-88276-unary-plus.rs:6:16 | LL | let _ = -+-+(1+2)*3; | ^ | | | unexpected `+` - | help: remove the `+` + | help: try removing the `+` + +error: leading `+` is not supported + --> $DIR/issue-88276-unary-plus.rs:8:18 + | +LL | let _ = (1 + +2) * +3; + | ^ + | | + | unexpected `+` + | help: try removing the `+` + +error: leading `+` is not supported + --> $DIR/issue-88276-unary-plus.rs:8:24 + | +LL | let _ = (1 + +2) * +3; + | ^ + | | + | unexpected `+` + | help: try removing the `+` error: leading `+` is not supported --> $DIR/issue-88276-unary-plus.rs:10:14 @@ -59,7 +59,7 @@ LL | let _ = (+&"hello"); | ^ | | | unexpected `+` - | help: remove the `+` + | help: try removing the `+` error: leading `+` is not supported --> $DIR/issue-88276-unary-plus.rs:11:13 @@ -68,7 +68,7 @@ LL | let _ = +[+3, 4+6]; | ^ | | | unexpected `+` - | help: remove the `+` + | help: try removing the `+` error: leading `+` is not supported --> $DIR/issue-88276-unary-plus.rs:11:15 @@ -77,7 +77,7 @@ LL | let _ = +[+3, 4+6]; | ^ | | | unexpected `+` - | help: remove the `+` + | help: try removing the `+` error: aborting due to 9 previous errors