diff --git a/src/librustc_parse/parser/expr.rs b/src/librustc_parse/parser/expr.rs index 3d0f746d395..12729019e9b 100644 --- a/src/librustc_parse/parser/expr.rs +++ b/src/librustc_parse/parser/expr.rs @@ -648,8 +648,6 @@ impl<'a> Parser<'a> { if !matches!(with_postfix.kind, ExprKind::Cast(_, _) | ExprKind::Type(_, _)) || after_hash != before_hash { - let expr_str = self.span_to_snippet(span); - let msg = format!( "casts cannot be followed by {}", match with_postfix.kind { @@ -663,22 +661,20 @@ impl<'a> Parser<'a> { } ); let mut err = self.struct_span_err(span, &msg); - let suggestion = "try surrounding the expression in parentheses"; // if type ascription is "likely an error", the user will already be getting a useful // help message, and doesn't need a second. if self.last_type_ascription.map_or(false, |last_ascription| last_ascription.1) { self.maybe_annotate_with_ascription(&mut err, false); } else { - if let Ok(expr_str) = expr_str { - err.span_suggestion( - span, - suggestion, - format!("({})", expr_str), - Applicability::MachineApplicable, - ); - } else { - err.span_help(span, suggestion); - } + let suggestions = vec![ + (span.shrink_to_lo(), "(".to_string()), + (span.shrink_to_hi(), ")".to_string()), + ]; + err.multipart_suggestion( + "try surrounding the expression in parentheses", + suggestions, + Applicability::MachineApplicable, + ); } err.emit(); }; diff --git a/src/test/ui/parser/issue-35813-postfix-after-cast.rs b/src/test/ui/parser/issue-35813-postfix-after-cast.rs index 5c6e0ce5024..e725aa5d73d 100644 --- a/src/test/ui/parser/issue-35813-postfix-after-cast.rs +++ b/src/test/ui/parser/issue-35813-postfix-after-cast.rs @@ -58,6 +58,13 @@ pub fn cast_cast_method_call() { //~^ ERROR: casts cannot be followed by a method call } +pub fn multiline_error() { + let _ = 0 + as i32 + .count_ones(); + //~^^^ ERROR: casts cannot be followed by a method call +} + // this tests that the precedence for `!x as Y.Z` is still what we expect pub fn precedence() { let x: i32 = &vec![1, 2, 3] as &Vec[0]; diff --git a/src/test/ui/parser/issue-35813-postfix-after-cast.stderr b/src/test/ui/parser/issue-35813-postfix-after-cast.stderr index 42b614edf76..255e9f40921 100644 --- a/src/test/ui/parser/issue-35813-postfix-after-cast.stderr +++ b/src/test/ui/parser/issue-35813-postfix-after-cast.stderr @@ -2,148 +2,282 @@ error: casts cannot be followed by indexing --> $DIR/issue-35813-postfix-after-cast.rs:10:5 | LL | vec![1, 2, 3] as Vec[0]; - | ^^^^^^^^^^^^^^^^^^^^^^^^^ help: try surrounding the expression in parentheses: `(vec![1, 2, 3] as Vec)` + | ^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: try surrounding the expression in parentheses + | +LL | (vec![1, 2, 3] as Vec)[0]; + | ^ ^ error: casts cannot be followed by indexing --> $DIR/issue-35813-postfix-after-cast.rs:12:5 | LL | vec![1, 2, 3]: Vec[0]; - | ^^^^^^^^^^^^^^^^^^^^^^^ help: try surrounding the expression in parentheses: `(vec![1, 2, 3]: Vec)` + | ^^^^^^^^^^^^^^^^^^^^^^^ + | +help: try surrounding the expression in parentheses + | +LL | (vec![1, 2, 3]: Vec)[0]; + | ^ ^ error: casts cannot be followed by indexing --> $DIR/issue-35813-postfix-after-cast.rs:17:5 | LL | (&[0]) as &[i32][0]; - | ^^^^^^^^^^^^^^^^ help: try surrounding the expression in parentheses: `((&[0]) as &[i32])` + | ^^^^^^^^^^^^^^^^ + | +help: try surrounding the expression in parentheses + | +LL | ((&[0]) as &[i32])[0]; + | ^ ^ error: casts cannot be followed by indexing --> $DIR/issue-35813-postfix-after-cast.rs:19:5 | LL | (&[0i32]): &[i32; 1][0]; - | ^^^^^^^^^^^^^^^^^^^^ help: try surrounding the expression in parentheses: `((&[0i32]): &[i32; 1])` + | ^^^^^^^^^^^^^^^^^^^^ + | +help: try surrounding the expression in parentheses + | +LL | ((&[0i32]): &[i32; 1])[0]; + | ^ ^ error: casts cannot be followed by a method call --> $DIR/issue-35813-postfix-after-cast.rs:39:13 | LL | let _ = 0i32: i32: i32.count_ones(); - | ^^^^^^^^^^^^^^ help: try surrounding the expression in parentheses: `(0i32: i32: i32)` + | ^^^^^^^^^^^^^^ + | +help: try surrounding the expression in parentheses + | +LL | let _ = (0i32: i32: i32).count_ones(); + | ^ ^ error: casts cannot be followed by a method call --> $DIR/issue-35813-postfix-after-cast.rs:41:13 | LL | let _ = 0 as i32: i32.count_ones(); - | ^^^^^^^^^^^^^ help: try surrounding the expression in parentheses: `(0 as i32: i32)` + | ^^^^^^^^^^^^^ + | +help: try surrounding the expression in parentheses + | +LL | let _ = (0 as i32: i32).count_ones(); + | ^ ^ error: casts cannot be followed by a method call --> $DIR/issue-35813-postfix-after-cast.rs:43:13 | LL | let _ = 0i32: i32 as i32.count_ones(); - | ^^^^^^^^^^^^^^^^ help: try surrounding the expression in parentheses: `(0i32: i32 as i32)` + | ^^^^^^^^^^^^^^^^ + | +help: try surrounding the expression in parentheses + | +LL | let _ = (0i32: i32 as i32).count_ones(); + | ^ ^ error: casts cannot be followed by a method call --> $DIR/issue-35813-postfix-after-cast.rs:45:13 | LL | let _ = 0 as i32 as i32.count_ones(); - | ^^^^^^^^^^^^^^^ help: try surrounding the expression in parentheses: `(0 as i32 as i32)` + | ^^^^^^^^^^^^^^^ + | +help: try surrounding the expression in parentheses + | +LL | let _ = (0 as i32 as i32).count_ones(); + | ^ ^ error: casts cannot be followed by a method call --> $DIR/issue-35813-postfix-after-cast.rs:47:13 | LL | let _ = 0i32: i32: i32 as u32 as i32.count_ones(); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try surrounding the expression in parentheses: `(0i32: i32: i32 as u32 as i32)` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: try surrounding the expression in parentheses + | +LL | let _ = (0i32: i32: i32 as u32 as i32).count_ones(); + | ^ ^ error: casts cannot be followed by a method call --> $DIR/issue-35813-postfix-after-cast.rs:49:13 | LL | let _ = 0i32: i32.count_ones(): u32; - | ^^^^^^^^^ help: try surrounding the expression in parentheses: `(0i32: i32)` + | ^^^^^^^^^ + | +help: try surrounding the expression in parentheses + | +LL | let _ = (0i32: i32).count_ones(): u32; + | ^ ^ error: casts cannot be followed by a method call --> $DIR/issue-35813-postfix-after-cast.rs:51:13 | LL | let _ = 0 as i32.count_ones(): u32; - | ^^^^^^^^ help: try surrounding the expression in parentheses: `(0 as i32)` + | ^^^^^^^^ + | +help: try surrounding the expression in parentheses + | +LL | let _ = (0 as i32).count_ones(): u32; + | ^ ^ error: casts cannot be followed by a method call --> $DIR/issue-35813-postfix-after-cast.rs:53:13 | LL | let _ = 0i32: i32.count_ones() as u32; - | ^^^^^^^^^ help: try surrounding the expression in parentheses: `(0i32: i32)` + | ^^^^^^^^^ + | +help: try surrounding the expression in parentheses + | +LL | let _ = (0i32: i32).count_ones() as u32; + | ^ ^ error: casts cannot be followed by a method call --> $DIR/issue-35813-postfix-after-cast.rs:55:13 | LL | let _ = 0 as i32.count_ones() as u32; - | ^^^^^^^^ help: try surrounding the expression in parentheses: `(0 as i32)` + | ^^^^^^^^ + | +help: try surrounding the expression in parentheses + | +LL | let _ = (0 as i32).count_ones() as u32; + | ^ ^ error: casts cannot be followed by a method call --> $DIR/issue-35813-postfix-after-cast.rs:57:13 | LL | let _ = 0i32: i32: i32.count_ones() as u32 as i32; - | ^^^^^^^^^^^^^^ help: try surrounding the expression in parentheses: `(0i32: i32: i32)` + | ^^^^^^^^^^^^^^ + | +help: try surrounding the expression in parentheses + | +LL | let _ = (0i32: i32: i32).count_ones() as u32 as i32; + | ^ ^ + +error: casts cannot be followed by a method call + --> $DIR/issue-35813-postfix-after-cast.rs:62:13 + | +LL | let _ = 0 + | _____________^ +LL | | as i32 + | |______________^ + | +help: try surrounding the expression in parentheses + | +LL | let _ = (0 +LL | as i32) + | error: casts cannot be followed by indexing - --> $DIR/issue-35813-postfix-after-cast.rs:63:18 + --> $DIR/issue-35813-postfix-after-cast.rs:70:18 | LL | let x: i32 = &vec![1, 2, 3] as &Vec[0]; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try surrounding the expression in parentheses: `(&vec![1, 2, 3] as &Vec)` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: try surrounding the expression in parentheses + | +LL | let x: i32 = (&vec![1, 2, 3] as &Vec)[0]; + | ^ ^ error: casts cannot be followed by a method call - --> $DIR/issue-35813-postfix-after-cast.rs:68:5 + --> $DIR/issue-35813-postfix-after-cast.rs:75:5 | LL | 0 as i32.max(0); - | ^^^^^^^^ help: try surrounding the expression in parentheses: `(0 as i32)` + | ^^^^^^^^ + | +help: try surrounding the expression in parentheses + | +LL | (0 as i32).max(0); + | ^ ^ error: casts cannot be followed by a method call - --> $DIR/issue-35813-postfix-after-cast.rs:70:5 + --> $DIR/issue-35813-postfix-after-cast.rs:77:5 | LL | 0: i32.max(0); - | ^^^^^^ help: try surrounding the expression in parentheses: `(0: i32)` + | ^^^^^^ + | +help: try surrounding the expression in parentheses + | +LL | (0: i32).max(0); + | ^ ^ error: casts cannot be followed by a method call - --> $DIR/issue-35813-postfix-after-cast.rs:85:8 + --> $DIR/issue-35813-postfix-after-cast.rs:92:8 | LL | if 5u64 as i32.max(0) == 0 { - | ^^^^^^^^^^^ help: try surrounding the expression in parentheses: `(5u64 as i32)` + | ^^^^^^^^^^^ + | +help: try surrounding the expression in parentheses + | +LL | if (5u64 as i32).max(0) == 0 { + | ^ ^ error: casts cannot be followed by a method call - --> $DIR/issue-35813-postfix-after-cast.rs:88:8 + --> $DIR/issue-35813-postfix-after-cast.rs:95:8 | LL | if 5u64: u64.max(0) == 0 { - | ^^^^^^^^^ help: try surrounding the expression in parentheses: `(5u64: u64)` + | ^^^^^^^^^ + | +help: try surrounding the expression in parentheses + | +LL | if (5u64: u64).max(0) == 0 { + | ^ ^ error: casts cannot be followed by a method call - --> $DIR/issue-35813-postfix-after-cast.rs:95:9 + --> $DIR/issue-35813-postfix-after-cast.rs:102:9 | LL | 5u64 as u32.max(0) == 0 - | ^^^^^^^^^^^ help: try surrounding the expression in parentheses: `(5u64 as u32)` + | ^^^^^^^^^^^ + | +help: try surrounding the expression in parentheses + | +LL | (5u64 as u32).max(0) == 0 + | ^ ^ error: casts cannot be followed by a method call - --> $DIR/issue-35813-postfix-after-cast.rs:99:9 + --> $DIR/issue-35813-postfix-after-cast.rs:106:9 | LL | 5u64: u64.max(0) == 0 - | ^^^^^^^^^ help: try surrounding the expression in parentheses: `(5u64: u64)` + | ^^^^^^^^^ + | +help: try surrounding the expression in parentheses + | +LL | (5u64: u64).max(0) == 0 + | ^ ^ error: casts cannot be followed by indexing - --> $DIR/issue-35813-postfix-after-cast.rs:104:24 + --> $DIR/issue-35813-postfix-after-cast.rs:111:24 | LL | static bar: &[i32] = &(&[1,2,3] as &[i32][0..1]); - | ^^^^^^^^^^^^^^^^^^ help: try surrounding the expression in parentheses: `(&[1,2,3] as &[i32])` + | ^^^^^^^^^^^^^^^^^^ + | +help: try surrounding the expression in parentheses + | +LL | static bar: &[i32] = &((&[1,2,3] as &[i32])[0..1]); + | ^ ^ error: casts cannot be followed by indexing - --> $DIR/issue-35813-postfix-after-cast.rs:107:25 + --> $DIR/issue-35813-postfix-after-cast.rs:114:25 | LL | static bar2: &[i32] = &(&[1i32,2,3]: &[i32; 3][0..1]); - | ^^^^^^^^^^^^^^^^^^^^^^ help: try surrounding the expression in parentheses: `(&[1i32,2,3]: &[i32; 3])` + | ^^^^^^^^^^^^^^^^^^^^^^ + | +help: try surrounding the expression in parentheses + | +LL | static bar2: &[i32] = &((&[1i32,2,3]: &[i32; 3])[0..1]); + | ^ ^ error: casts cannot be followed by ? - --> $DIR/issue-35813-postfix-after-cast.rs:112:5 + --> $DIR/issue-35813-postfix-after-cast.rs:119:5 | LL | Err(0u64) as Result?; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try surrounding the expression in parentheses: `(Err(0u64) as Result)` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: try surrounding the expression in parentheses + | +LL | (Err(0u64) as Result)?; + | ^ ^ error: casts cannot be followed by ? - --> $DIR/issue-35813-postfix-after-cast.rs:114:5 + --> $DIR/issue-35813-postfix-after-cast.rs:121:5 | LL | Err(0u64): Result?; | ^^^^^^^^^-^^^^^^^^^^^^^^^^ @@ -154,25 +288,40 @@ LL | Err(0u64): Result?; = note: see issue #23416 for more information error: casts cannot be followed by a function call - --> $DIR/issue-35813-postfix-after-cast.rs:138:5 - | -LL | drop as fn(u8)(0); - | ^^^^^^^^^^^^^^ help: try surrounding the expression in parentheses: `(drop as fn(u8))` - -error: casts cannot be followed by a function call - --> $DIR/issue-35813-postfix-after-cast.rs:140:5 - | -LL | drop_ptr: fn(u8)(0); - | ^^^^^^^^^^^^^^^^ help: try surrounding the expression in parentheses: `(drop_ptr: fn(u8))` - -error: casts cannot be followed by `.await` --> $DIR/issue-35813-postfix-after-cast.rs:145:5 | -LL | Box::pin(noop()) as Pin>>.await; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try surrounding the expression in parentheses: `(Box::pin(noop()) as Pin>>)` +LL | drop as fn(u8)(0); + | ^^^^^^^^^^^^^^ + | +help: try surrounding the expression in parentheses + | +LL | (drop as fn(u8))(0); + | ^ ^ + +error: casts cannot be followed by a function call + --> $DIR/issue-35813-postfix-after-cast.rs:147:5 + | +LL | drop_ptr: fn(u8)(0); + | ^^^^^^^^^^^^^^^^ + | +help: try surrounding the expression in parentheses + | +LL | (drop_ptr: fn(u8))(0); + | ^ ^ error: casts cannot be followed by `.await` - --> $DIR/issue-35813-postfix-after-cast.rs:148:5 + --> $DIR/issue-35813-postfix-after-cast.rs:152:5 + | +LL | Box::pin(noop()) as Pin>>.await; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: try surrounding the expression in parentheses + | +LL | (Box::pin(noop()) as Pin>>).await; + | ^ ^ + +error: casts cannot be followed by `.await` + --> $DIR/issue-35813-postfix-after-cast.rs:155:5 | LL | Box::pin(noop()): Pin>.await; | ^^^^^^^^^^^^^^^^-^^^^^^^^^^^^ @@ -183,41 +332,61 @@ LL | Box::pin(noop()): Pin>.await; = note: see issue #23416 for more information error: casts cannot be followed by a field access - --> $DIR/issue-35813-postfix-after-cast.rs:160:5 + --> $DIR/issue-35813-postfix-after-cast.rs:167:5 | LL | Foo::default() as Foo.bar; - | ^^^^^^^^^^^^^^^^^^^^^ help: try surrounding the expression in parentheses: `(Foo::default() as Foo)` + | ^^^^^^^^^^^^^^^^^^^^^ + | +help: try surrounding the expression in parentheses + | +LL | (Foo::default() as Foo).bar; + | ^ ^ error: casts cannot be followed by a field access - --> $DIR/issue-35813-postfix-after-cast.rs:162:5 + --> $DIR/issue-35813-postfix-after-cast.rs:169:5 | LL | Foo::default(): Foo.bar; - | ^^^^^^^^^^^^^^^^^^^ help: try surrounding the expression in parentheses: `(Foo::default(): Foo)` + | ^^^^^^^^^^^^^^^^^^^ + | +help: try surrounding the expression in parentheses + | +LL | (Foo::default(): Foo).bar; + | ^ ^ error: casts cannot be followed by a method call - --> $DIR/issue-35813-postfix-after-cast.rs:77:9 + --> $DIR/issue-35813-postfix-after-cast.rs:84:9 | LL | if true { 33 } else { 44 } as i32.max(0), - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try surrounding the expression in parentheses: `(if true { 33 } else { 44 } as i32)` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: try surrounding the expression in parentheses + | +LL | (if true { 33 } else { 44 } as i32).max(0), + | ^ ^ error: casts cannot be followed by a method call - --> $DIR/issue-35813-postfix-after-cast.rs:79:9 + --> $DIR/issue-35813-postfix-after-cast.rs:86:9 | LL | if true { 33 } else { 44 }: i32.max(0) - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try surrounding the expression in parentheses: `(if true { 33 } else { 44 }: i32)` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: try surrounding the expression in parentheses + | +LL | (if true { 33 } else { 44 }: i32).max(0) + | ^ ^ error[E0214]: parenthesized type parameters may only be used with a `Fn` trait - --> $DIR/issue-35813-postfix-after-cast.rs:124:13 + --> $DIR/issue-35813-postfix-after-cast.rs:131:13 | LL | drop as F(); | ^^^ only `Fn` traits may use parentheses error[E0214]: parenthesized type parameters may only be used with a `Fn` trait - --> $DIR/issue-35813-postfix-after-cast.rs:126:15 + --> $DIR/issue-35813-postfix-after-cast.rs:133:15 | LL | drop_ptr: F(); | ^^^ only `Fn` traits may use parentheses -error: aborting due to 35 previous errors +error: aborting due to 36 previous errors For more information about this error, try `rustc --explain E0214`.