about summary refs log tree commit diff
diff options
context:
space:
mode:
authorYuki Okushi <jtitor@2k36.org>2022-06-16 07:24:43 +0900
committerGitHub <noreply@github.com>2022-06-16 07:24:43 +0900
commitbfc6c90115a84157451b0738f5f56fd8275a9aaa (patch)
treec2354dbb0c69a5d3c2647c3db2f0a3e5bb6ed24f
parentad61ae59bf3a3d64fc724bb4d6b32eba33b01671 (diff)
parent71a98e1a4ec98d263984e78f0e54ea0dfa0c7846 (diff)
downloadrust-bfc6c90115a84157451b0738f5f56fd8275a9aaa.tar.gz
rust-bfc6c90115a84157451b0738f5f56fd8275a9aaa.zip
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
-rw-r--r--compiler/rustc_ast_lowering/src/path.rs45
-rw-r--r--src/test/ui/error-codes/E0214.stderr10
-rw-r--r--src/test/ui/issues/issue-23589.stderr10
-rw-r--r--src/test/ui/proc-macro/issue-66286.stderr10
-rw-r--r--src/test/ui/suggestions/let-binding-init-expr-as-ty.stderr10
-rw-r--r--src/test/ui/type/issue-91268.stderr5
-rw-r--r--src/test/ui/unboxed-closures/unboxed-closure-sugar-used-on-struct-3.stderr10
7 files changed, 61 insertions, 39 deletions
diff --git a/compiler/rustc_ast_lowering/src/path.rs b/compiler/rustc_ast_lowering/src/path.rs
index ac63a075ac6..5d56b0ffe8d 100644
--- a/compiler/rustc_ast_lowering/src/path.rs
+++ b/compiler/rustc_ast_lowering/src/path.rs
@@ -196,25 +196,32 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
                     ParenthesizedGenericArgs::Err => {
                         let mut err = struct_span_err!(self.sess, data.span, E0214, "{}", msg);
                         err.span_label(data.span, "only `Fn` traits may use parentheses");
-                        if let Ok(snippet) = self.sess.source_map().span_to_snippet(data.span) {
-                            // Do not suggest going from `Trait()` to `Trait<>`
-                            if !data.inputs.is_empty() {
-                                // Suggest replacing `(` and `)` with `<` and `>`
-                                // The snippet may be missing the closing `)`, skip that case
-                                if snippet.ends_with(')') {
-                                    if let Some(split) = snippet.find('(') {
-                                        let trait_name = &snippet[0..split];
-                                        let args = &snippet[split + 1..snippet.len() - 1];
-                                        err.span_suggestion(
-                                            data.span,
-                                            "use angle brackets instead",
-                                            format!("{}<{}>", trait_name, args),
-                                            Applicability::MaybeIncorrect,
-                                        );
-                                    }
-                                }
-                            }
-                        };
+                        // Suggest replacing parentheses with angle brackets `Trait(params...)` to `Trait<params...>`
+                        if !data.inputs.is_empty() {
+                            // Start of the span to the 1st character of 1st argument
+                            let open_param = data.inputs_span.shrink_to_lo().to(data
+                                .inputs
+                                .first()
+                                .unwrap()
+                                .span
+                                .shrink_to_lo());
+                            // Last character position of last argument to the end of the span
+                            let close_param = data
+                                .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,
+                            );
+                        }
                         err.emit();
                         (
                             self.lower_angle_bracketed_parameter_data(
diff --git a/src/test/ui/error-codes/E0214.stderr b/src/test/ui/error-codes/E0214.stderr
index bcbd3a91cb9..e0179aac27f 100644
--- a/src/test/ui/error-codes/E0214.stderr
+++ b/src/test/ui/error-codes/E0214.stderr
@@ -2,10 +2,12 @@ error[E0214]: parenthesized type parameters may only be used with a `Fn` trait
   --> $DIR/E0214.rs:2:12
    |
 LL |     let v: Vec(&str) = vec!["foo"];
-   |            ^^^^^^^^^
-   |            |
-   |            only `Fn` traits may use parentheses
-   |            help: use angle brackets instead: `Vec<&str>`
+   |            ^^^^^^^^^ only `Fn` traits may use parentheses
+   |
+help: use angle brackets instead
+   |
+LL |     let v: Vec<&str> = vec!["foo"];
+   |               ~    ~
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/issues/issue-23589.stderr b/src/test/ui/issues/issue-23589.stderr
index e065e17c280..1a91f5e04db 100644
--- a/src/test/ui/issues/issue-23589.stderr
+++ b/src/test/ui/issues/issue-23589.stderr
@@ -2,10 +2,12 @@ error[E0214]: parenthesized type parameters may only be used with a `Fn` trait
   --> $DIR/issue-23589.rs:2:12
    |
 LL |     let v: Vec(&str) = vec!['1', '2'];
-   |            ^^^^^^^^^
-   |            |
-   |            only `Fn` traits may use parentheses
-   |            help: use angle brackets instead: `Vec<&str>`
+   |            ^^^^^^^^^ only `Fn` traits may use parentheses
+   |
+help: use angle brackets instead
+   |
+LL |     let v: Vec<&str> = vec!['1', '2'];
+   |               ~    ~
 
 error[E0308]: mismatched types
   --> $DIR/issue-23589.rs:2:29
diff --git a/src/test/ui/proc-macro/issue-66286.stderr b/src/test/ui/proc-macro/issue-66286.stderr
index 2854dd7d59c..fe2464b3b81 100644
--- a/src/test/ui/proc-macro/issue-66286.stderr
+++ b/src/test/ui/proc-macro/issue-66286.stderr
@@ -2,10 +2,12 @@ error[E0214]: parenthesized type parameters may only be used with a `Fn` trait
   --> $DIR/issue-66286.rs:8:22
    |
 LL | pub extern fn foo(_: Vec(u32)) -> u32 {
-   |                      ^^^^^^^^
-   |                      |
-   |                      only `Fn` traits may use parentheses
-   |                      help: use angle brackets instead: `Vec<u32>`
+   |                      ^^^^^^^^ only `Fn` traits may use parentheses
+   |
+help: use angle brackets instead
+   |
+LL | pub extern fn foo(_: Vec<u32>) -> u32 {
+   |                         ~   ~
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/suggestions/let-binding-init-expr-as-ty.stderr b/src/test/ui/suggestions/let-binding-init-expr-as-ty.stderr
index 63ba7893f04..2bf072ef521 100644
--- a/src/test/ui/suggestions/let-binding-init-expr-as-ty.stderr
+++ b/src/test/ui/suggestions/let-binding-init-expr-as-ty.stderr
@@ -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
    |
 LL |     let foo: i32::from_be(num);
-   |                   ^^^^^^^^^^^^
-   |                   |
-   |                   only `Fn` traits may use parentheses
-   |                   help: use angle brackets instead: `from_be<num>`
+   |                   ^^^^^^^^^^^^ only `Fn` traits may use parentheses
+   |
+help: use angle brackets instead
+   |
+LL |     let foo: i32::from_be<num>;
+   |                          ~   ~
 
 error[E0223]: ambiguous associated type
   --> $DIR/let-binding-init-expr-as-ty.rs:2:14
diff --git a/src/test/ui/type/issue-91268.stderr b/src/test/ui/type/issue-91268.stderr
index 199fd6a23f7..71c357865fe 100644
--- a/src/test/ui/type/issue-91268.stderr
+++ b/src/test/ui/type/issue-91268.stderr
@@ -29,6 +29,11 @@ error[E0214]: parenthesized type parameters may only be used with a `Fn` trait
    |
 LL |     0: u8(ţ
    |        ^^^^ only `Fn` traits may use parentheses
+   |
+help: use angle brackets instead
+   |
+LL |     0: u8<ţ>
+   |          ~ +
 
 error[E0109]: type arguments are not allowed on this type
   --> $DIR/issue-91268.rs:9:11
diff --git a/src/test/ui/unboxed-closures/unboxed-closure-sugar-used-on-struct-3.stderr b/src/test/ui/unboxed-closures/unboxed-closure-sugar-used-on-struct-3.stderr
index f5cf6db30f9..4df404e8198 100644
--- a/src/test/ui/unboxed-closures/unboxed-closure-sugar-used-on-struct-3.stderr
+++ b/src/test/ui/unboxed-closures/unboxed-closure-sugar-used-on-struct-3.stderr
@@ -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
    |
 LL |     let b = Bar::(isize, usize)::new(); // OK too (for the parser)
-   |             ^^^^^^^^^^^^^^^^^^^
-   |             |
-   |             only `Fn` traits may use parentheses
-   |             help: use angle brackets instead: `Bar::<isize, usize>`
+   |             ^^^^^^^^^^^^^^^^^^^ only `Fn` traits may use parentheses
+   |
+help: use angle brackets instead
+   |
+LL |     let b = Bar::<isize, usize>::new(); // OK too (for the parser)
+   |                  ~            ~
 
 error: aborting due to previous error