Rollup merge of #98119 - EdwinRy:path-parenthesized-type-error, r=estebank

Refactor path segment parameter error

This PR attempts to rewrite the error handling for an unexpected parenthesised type parameters to:
- Use provided data instead of re-parsing the whole span
- Add a multipart suggestion to reflect on the changes with an underline
- Remove the unnecessary "if" nesting
This commit is contained in:
Yuki Okushi 2022-06-16 07:24:43 +09:00 committed by GitHub
commit bfc6c90115
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 61 additions and 39 deletions

View File

@ -196,25 +196,32 @@ pub(crate) fn lower_path_segment(
ParenthesizedGenericArgs::Err => { ParenthesizedGenericArgs::Err => {
let mut err = struct_span_err!(self.sess, data.span, E0214, "{}", msg); let mut err = struct_span_err!(self.sess, data.span, E0214, "{}", msg);
err.span_label(data.span, "only `Fn` traits may use parentheses"); err.span_label(data.span, "only `Fn` traits may use parentheses");
if let Ok(snippet) = self.sess.source_map().span_to_snippet(data.span) { // Suggest replacing parentheses with angle brackets `Trait(params...)` to `Trait<params...>`
// Do not suggest going from `Trait()` to `Trait<>`
if !data.inputs.is_empty() { if !data.inputs.is_empty() {
// Suggest replacing `(` and `)` with `<` and `>` // Start of the span to the 1st character of 1st argument
// The snippet may be missing the closing `)`, skip that case let open_param = data.inputs_span.shrink_to_lo().to(data
if snippet.ends_with(')') { .inputs
if let Some(split) = snippet.find('(') { .first()
let trait_name = &snippet[0..split]; .unwrap()
let args = &snippet[split + 1..snippet.len() - 1]; .span
err.span_suggestion( .shrink_to_lo());
data.span, // Last character position of last argument to the end of the span
"use angle brackets instead", let close_param = data
format!("{}<{}>", trait_name, args), .inputs
.last()
.unwrap()
.span
.shrink_to_hi()
.to(data.inputs_span.shrink_to_hi());
err.multipart_suggestion(
&format!("use angle brackets instead",),
vec![
(open_param, String::from("<")),
(close_param, String::from(">")),
],
Applicability::MaybeIncorrect, Applicability::MaybeIncorrect,
); );
} }
}
}
};
err.emit(); err.emit();
( (
self.lower_angle_bracketed_parameter_data( self.lower_angle_bracketed_parameter_data(

View File

@ -2,10 +2,12 @@ error[E0214]: parenthesized type parameters may only be used with a `Fn` trait
--> $DIR/E0214.rs:2:12 --> $DIR/E0214.rs:2:12
| |
LL | let v: Vec(&str) = vec!["foo"]; LL | let v: Vec(&str) = vec!["foo"];
| ^^^^^^^^^ | ^^^^^^^^^ only `Fn` traits may use parentheses
| | |
| only `Fn` traits may use parentheses help: use angle brackets instead
| help: use angle brackets instead: `Vec<&str>` |
LL | let v: Vec<&str> = vec!["foo"];
| ~ ~
error: aborting due to previous error error: aborting due to previous error

View File

@ -2,10 +2,12 @@ error[E0214]: parenthesized type parameters may only be used with a `Fn` trait
--> $DIR/issue-23589.rs:2:12 --> $DIR/issue-23589.rs:2:12
| |
LL | let v: Vec(&str) = vec!['1', '2']; LL | let v: Vec(&str) = vec!['1', '2'];
| ^^^^^^^^^ | ^^^^^^^^^ only `Fn` traits may use parentheses
| | |
| only `Fn` traits may use parentheses help: use angle brackets instead
| help: use angle brackets instead: `Vec<&str>` |
LL | let v: Vec<&str> = vec!['1', '2'];
| ~ ~
error[E0308]: mismatched types error[E0308]: mismatched types
--> $DIR/issue-23589.rs:2:29 --> $DIR/issue-23589.rs:2:29

View File

@ -2,10 +2,12 @@ error[E0214]: parenthesized type parameters may only be used with a `Fn` trait
--> $DIR/issue-66286.rs:8:22 --> $DIR/issue-66286.rs:8:22
| |
LL | pub extern fn foo(_: Vec(u32)) -> u32 { LL | pub extern fn foo(_: Vec(u32)) -> u32 {
| ^^^^^^^^ | ^^^^^^^^ only `Fn` traits may use parentheses
| | |
| only `Fn` traits may use parentheses help: use angle brackets instead
| help: use angle brackets instead: `Vec<u32>` |
LL | pub extern fn foo(_: Vec<u32>) -> u32 {
| ~ ~
error: aborting due to previous error error: aborting due to previous error

View File

@ -10,10 +10,12 @@ error[E0214]: parenthesized type parameters may only be used with a `Fn` trait
--> $DIR/let-binding-init-expr-as-ty.rs:2:19 --> $DIR/let-binding-init-expr-as-ty.rs:2:19
| |
LL | let foo: i32::from_be(num); LL | let foo: i32::from_be(num);
| ^^^^^^^^^^^^ | ^^^^^^^^^^^^ only `Fn` traits may use parentheses
| | |
| only `Fn` traits may use parentheses help: use angle brackets instead
| help: use angle brackets instead: `from_be<num>` |
LL | let foo: i32::from_be<num>;
| ~ ~
error[E0223]: ambiguous associated type error[E0223]: ambiguous associated type
--> $DIR/let-binding-init-expr-as-ty.rs:2:14 --> $DIR/let-binding-init-expr-as-ty.rs:2:14

View File

@ -29,6 +29,11 @@ error[E0214]: parenthesized type parameters may only be used with a `Fn` trait
| |
LL | 0: u8(ţ LL | 0: u8(ţ
| ^^^^ only `Fn` traits may use parentheses | ^^^^ only `Fn` traits may use parentheses
|
help: use angle brackets instead
|
LL | 0: u8<ţ>
| ~ +
error[E0109]: type arguments are not allowed on this type error[E0109]: type arguments are not allowed on this type
--> $DIR/issue-91268.rs:9:11 --> $DIR/issue-91268.rs:9:11

View File

@ -2,10 +2,12 @@ error[E0214]: parenthesized type parameters may only be used with a `Fn` trait
--> $DIR/unboxed-closure-sugar-used-on-struct-3.rs:14:13 --> $DIR/unboxed-closure-sugar-used-on-struct-3.rs:14:13
| |
LL | let b = Bar::(isize, usize)::new(); // OK too (for the parser) LL | let b = Bar::(isize, usize)::new(); // OK too (for the parser)
| ^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^ only `Fn` traits may use parentheses
| | |
| only `Fn` traits may use parentheses help: use angle brackets instead
| help: use angle brackets instead: `Bar::<isize, usize>` |
LL | let b = Bar::<isize, usize>::new(); // OK too (for the parser)
| ~ ~
error: aborting due to previous error error: aborting due to previous error