Skip to content

suggest removing type ascription in bad parsing position #95104

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Mar 21, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
41 changes: 35 additions & 6 deletions compiler/rustc_parse/src/parser/expr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -800,11 +800,17 @@ impl<'a> Parser<'a> {
&mut self,
cast_expr: P<Expr>,
) -> PResult<'a, P<Expr>> {
let span = cast_expr.span;
let maybe_ascription_span = if let ExprKind::Type(ascripted_expr, _) = &cast_expr.kind {
Some(ascripted_expr.span.shrink_to_hi().with_hi(span.hi()))
} else {
None
};

// Save the memory location of expr before parsing any following postfix operators.
// This will be compared with the memory location of the output expression.
// If they different we can assume we parsed another expression because the existing expression is not reallocated.
let addr_before = &*cast_expr as *const _ as usize;
let span = cast_expr.span;
let with_postfix = self.parse_dot_or_call_expr_with_(cast_expr, span)?;
let changed = addr_before != &*with_postfix as *const _ as usize;

Expand All @@ -825,11 +831,8 @@ impl<'a> Parser<'a> {
}
);
let mut err = self.struct_span_err(span, &msg);
// 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 {

let suggest_parens = |err: &mut DiagnosticBuilder<'_, _>| {
let suggestions = vec![
(span.shrink_to_lo(), "(".to_string()),
(span.shrink_to_hi(), ")".to_string()),
Expand All @@ -839,6 +842,32 @@ impl<'a> Parser<'a> {
suggestions,
Applicability::MachineApplicable,
);
};

// 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 Some(ascription_span) = maybe_ascription_span {
let is_nightly = self.sess.unstable_features.is_nightly_build();
if is_nightly {
suggest_parens(&mut err);
}
err.span_suggestion(
ascription_span,
&format!(
"{}remove the type ascription",
if is_nightly { "alternatively, " } else { "" }
),
String::new(),
if is_nightly {
Applicability::MaybeIncorrect
} else {
Applicability::MachineApplicable
},
);
} else {
suggest_parens(&mut err);
}
err.emit();
};
Expand Down
80 changes: 80 additions & 0 deletions src/test/ui/parser/issues/issue-35813-postfix-after-cast.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,11 @@ help: try surrounding the expression in parentheses
|
LL | (vec![1, 2, 3]: Vec<i32>)[0];
| + +
help: alternatively, remove the type ascription
|
LL - vec![1, 2, 3]: Vec<i32>[0];
LL + vec![1, 2, 3][0];
|

error: casts cannot be followed by indexing
--> $DIR/issue-35813-postfix-after-cast.rs:17:5
Expand All @@ -41,6 +46,11 @@ help: try surrounding the expression in parentheses
|
LL | ((&[0i32]): &[i32; 1])[0];
| + +
help: alternatively, remove the type ascription
|
LL - (&[0i32]): &[i32; 1][0];
LL + (&[0i32])[0];
|

error: casts cannot be followed by a method call
--> $DIR/issue-35813-postfix-after-cast.rs:39:13
Expand All @@ -52,6 +62,11 @@ help: try surrounding the expression in parentheses
|
LL | let _ = (0i32: i32: i32).count_ones();
| + +
help: alternatively, remove the type ascription
|
LL - let _ = 0i32: i32: i32.count_ones();
LL + let _ = 0i32: i32.count_ones();
|

error: casts cannot be followed by a method call
--> $DIR/issue-35813-postfix-after-cast.rs:41:13
Expand All @@ -63,6 +78,11 @@ help: try surrounding the expression in parentheses
|
LL | let _ = (0 as i32: i32).count_ones();
| + +
help: alternatively, remove the type ascription
|
LL - let _ = 0 as i32: i32.count_ones();
LL + let _ = 0 as i32.count_ones();
|

error: casts cannot be followed by a method call
--> $DIR/issue-35813-postfix-after-cast.rs:43:13
Expand Down Expand Up @@ -107,6 +127,11 @@ help: try surrounding the expression in parentheses
|
LL | let _ = (0i32: i32).count_ones(): u32;
| + +
help: alternatively, remove the type ascription
|
LL - let _ = 0i32: i32.count_ones(): u32;
LL + let _ = 0i32.count_ones(): u32;
|

error: casts cannot be followed by a method call
--> $DIR/issue-35813-postfix-after-cast.rs:51:13
Expand All @@ -129,6 +154,11 @@ help: try surrounding the expression in parentheses
|
LL | let _ = (0i32: i32).count_ones() as u32;
| + +
help: alternatively, remove the type ascription
|
LL - let _ = 0i32: i32.count_ones() as u32;
LL + let _ = 0i32.count_ones() as u32;
|

error: casts cannot be followed by a method call
--> $DIR/issue-35813-postfix-after-cast.rs:55:13
Expand All @@ -151,6 +181,11 @@ help: try surrounding the expression in parentheses
|
LL | let _ = (0i32: i32: i32).count_ones() as u32 as i32;
| + +
help: alternatively, remove the type ascription
|
LL - let _ = 0i32: i32: i32.count_ones() as u32 as i32;
LL + let _ = 0i32: 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
Expand Down Expand Up @@ -198,6 +233,11 @@ help: try surrounding the expression in parentheses
|
LL | (0: i32).max(0);
| + +
help: alternatively, remove the type ascription
|
LL - 0: i32.max(0);
LL + 0.max(0);
|

error: casts cannot be followed by a method call
--> $DIR/issue-35813-postfix-after-cast.rs:92:8
Expand All @@ -220,6 +260,11 @@ help: try surrounding the expression in parentheses
|
LL | if (5u64: u64).max(0) == 0 {
| + +
help: alternatively, remove the type ascription
|
LL - if 5u64: u64.max(0) == 0 {
LL + if 5u64.max(0) == 0 {
|

error: casts cannot be followed by a method call
--> $DIR/issue-35813-postfix-after-cast.rs:102:9
Expand All @@ -242,6 +287,11 @@ help: try surrounding the expression in parentheses
|
LL | (5u64: u64).max(0) == 0
| + +
help: alternatively, remove the type ascription
|
LL - 5u64: u64.max(0) == 0
LL + 5u64.max(0) == 0
|

error: casts cannot be followed by indexing
--> $DIR/issue-35813-postfix-after-cast.rs:111:24
Expand All @@ -264,6 +314,11 @@ help: try surrounding the expression in parentheses
|
LL | static bar2: &[i32] = &((&[1i32,2,3]: &[i32; 3])[0..1]);
| + +
help: alternatively, remove the type ascription
|
LL - static bar2: &[i32] = &(&[1i32,2,3]: &[i32; 3][0..1]);
LL + static bar2: &[i32] = &(&[1i32,2,3][0..1]);
|

error: casts cannot be followed by `?`
--> $DIR/issue-35813-postfix-after-cast.rs:119:5
Expand All @@ -286,6 +341,11 @@ help: try surrounding the expression in parentheses
|
LL | (Err(0u64): Result<u64,u64>)?;
| + +
help: alternatively, remove the type ascription
|
LL - Err(0u64): Result<u64,u64>?;
LL + Err(0u64)?;
|

error: casts cannot be followed by a function call
--> $DIR/issue-35813-postfix-after-cast.rs:145:5
Expand All @@ -308,6 +368,11 @@ help: try surrounding the expression in parentheses
|
LL | (drop_ptr: fn(u8))(0);
| + +
help: alternatively, remove the type ascription
|
LL - drop_ptr: fn(u8)(0);
LL + drop_ptr(0);
|

error: casts cannot be followed by `.await`
--> $DIR/issue-35813-postfix-after-cast.rs:152:5
Expand All @@ -330,6 +395,11 @@ help: try surrounding the expression in parentheses
|
LL | (Box::pin(noop()): Pin<Box<_>>).await;
| + +
help: alternatively, remove the type ascription
|
LL - Box::pin(noop()): Pin<Box<_>>.await;
LL + Box::pin(noop()).await;
|

error: casts cannot be followed by a field access
--> $DIR/issue-35813-postfix-after-cast.rs:167:5
Expand All @@ -352,6 +422,11 @@ help: try surrounding the expression in parentheses
|
LL | (Foo::default(): Foo).bar;
| + +
help: alternatively, remove the type ascription
|
LL - Foo::default(): Foo.bar;
LL + Foo::default().bar;
|

error: casts cannot be followed by a method call
--> $DIR/issue-35813-postfix-after-cast.rs:84:9
Expand All @@ -374,6 +449,11 @@ help: try surrounding the expression in parentheses
|
LL | (if true { 33 } else { 44 }: i32).max(0)
| + +
help: alternatively, remove the type ascription
|
LL - if true { 33 } else { 44 }: i32.max(0)
LL + if true { 33 } else { 44 }.max(0)
|

error[E0214]: parenthesized type parameters may only be used with a `Fn` trait
--> $DIR/issue-35813-postfix-after-cast.rs:131:13
Expand Down