about summary refs log tree commit diff
diff options
context:
space:
mode:
authorEsteban Küber <esteban@kuber.com.ar>2020-03-28 17:45:36 -0700
committerEsteban Küber <esteban@kuber.com.ar>2020-03-28 17:45:36 -0700
commitdcb4e817bc8469a0a47e0eaecdf1cf0ea980a496 (patch)
tree114dec3af225f23c106e1f08a1928fce041b60f6
parent33d793c326a83ed2e71a4d5e612526cf13c890b2 (diff)
downloadrust-dcb4e817bc8469a0a47e0eaecdf1cf0ea980a496.tar.gz
rust-dcb4e817bc8469a0a47e0eaecdf1cf0ea980a496.zip
Suggest correct order for args and constraints
-rw-r--r--src/librustc_ast_passes/ast_validation.rs23
-rw-r--r--src/test/ui/parser/issue-32214.stderr5
-rw-r--r--src/test/ui/suggestions/suggest-move-types.stderr40
3 files changed, 68 insertions, 0 deletions
diff --git a/src/librustc_ast_passes/ast_validation.rs b/src/librustc_ast_passes/ast_validation.rs
index 680a58d8b77..4c7edfc83fa 100644
--- a/src/librustc_ast_passes/ast_validation.rs
+++ b/src/librustc_ast_passes/ast_validation.rs
@@ -663,6 +663,20 @@ impl<'a> AstValidator<'a> {
                 _ => None,
             })
             .collect::<Vec<_>>();
+        let snippet_span = match &constraint_spans[..] {
+            [single] => *single,
+            [first, .., last] => first.to(*last),
+            [] => unreachable!(),
+        };
+        let removal_span = match &arg_spans[..] {
+            [first, ..] => snippet_span.until(*first),
+            [] => unreachable!(),
+        };
+        let sugg_span = match &arg_spans[..] {
+            [.., last] => last.shrink_to_hi(),
+            [] => unreachable!(),
+        };
+        let snippet = self.session.source_map().span_to_snippet(snippet_span).unwrap();
         let constraint_len = constraint_spans.len();
         // ...and then error:
         self.err_handler()
@@ -679,6 +693,15 @@ impl<'a> AstValidator<'a> {
                 ),
             )
             .span_labels(arg_spans, "generic argument")
+            .multipart_suggestion(
+                "move the constraints after the generic arguments",
+                vec![
+                    (removal_span, String::new()),
+                    (sugg_span.shrink_to_lo(), ", ".to_string()),
+                    (sugg_span, snippet),
+                ],
+                Applicability::MachineApplicable,
+            )
             .emit();
     }
 }
diff --git a/src/test/ui/parser/issue-32214.stderr b/src/test/ui/parser/issue-32214.stderr
index 6bb1425ee13..959a1ab121b 100644
--- a/src/test/ui/parser/issue-32214.stderr
+++ b/src/test/ui/parser/issue-32214.stderr
@@ -5,6 +5,11 @@ LL | pub fn test<W, I: Trait<Item=(), W> >() {}
    |                         -------  ^ generic argument
    |                         |
    |                         the constraint is provided here
+   |
+help: move the constraints after the generic arguments
+   |
+LL | pub fn test<W, I: Trait<W, Item=()> >() {}
+   |                        --^^^^^^^
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/suggestions/suggest-move-types.stderr b/src/test/ui/suggestions/suggest-move-types.stderr
index b4cf0deacee..3d2b35fcf45 100644
--- a/src/test/ui/suggestions/suggest-move-types.stderr
+++ b/src/test/ui/suggestions/suggest-move-types.stderr
@@ -5,6 +5,11 @@ LL | struct A<T, M: One<A=(), T>> {
    |                    ----  ^ generic argument
    |                    |
    |                    the constraint is provided here
+   |
+help: move the constraints after the generic arguments
+   |
+LL | struct A<T, M: One<T, A=()>> {
+   |                   --^^^^
 
 error: generic arguments must come before the first constraint
   --> $DIR/suggest-move-types.rs:33:43
@@ -14,6 +19,11 @@ LL | struct Al<'a, T, M: OneWithLifetime<A=(), T, 'a>> {
    |                                     |     |
    |                                     |     generic argument
    |                                     the constraint is provided here
+   |
+help: move the constraints after the generic arguments
+   |
+LL | struct Al<'a, T, M: OneWithLifetime<T, 'a, A=()>> {
+   |                                    --    ^^^^
 
 error: generic arguments must come before the first constraint
   --> $DIR/suggest-move-types.rs:40:46
@@ -26,6 +36,11 @@ LL | struct B<T, U, V, M: Three<A=(), B=(), C=(), T, U, V>> {
    |                            |     |     the constraints are provided here
    |                            |     the constraints are provided here
    |                            the constraints are provided here
+   |
+help: move the constraints after the generic arguments
+   |
+LL | struct B<T, U, V, M: Three<T, U, V, A=(), B=(), C=()>> {
+   |                           --      ^^^^^^^^^^^^^^^^
 
 error: generic arguments must come before the first constraint
   --> $DIR/suggest-move-types.rs:48:71
@@ -41,6 +56,11 @@ LL | struct Bl<'a, 'b, 'c, T, U, V, M: ThreeWithLifetime<A=(), B=(), C=(), T, U,
    |                                                     |     |     the constraints are provided here
    |                                                     |     the constraints are provided here
    |                                                     the constraints are provided here
+   |
+help: move the constraints after the generic arguments
+   |
+LL | struct Bl<'a, 'b, 'c, T, U, V, M: ThreeWithLifetime<T, U, V, 'a, 'b, 'c, A=(), B=(), C=()>> {
+   |                                                    --                  ^^^^^^^^^^^^^^^^
 
 error: generic arguments must come before the first constraint
   --> $DIR/suggest-move-types.rs:57:28
@@ -53,6 +73,11 @@ LL | struct C<T, U, V, M: Three<T, A=(), B=(), C=(), U, V>> {
    |                            |  |     the constraints are provided here
    |                            |  the constraints are provided here
    |                            generic argument
+   |
+help: move the constraints after the generic arguments
+   |
+LL | struct C<T, U, V, M: Three<A=(), B=(), C=(), U, V, A=(), B=(), C=()>> {
+   |                           --                     ^^^^^^^^^^^^^^^^
 
 error: generic arguments must come before the first constraint
   --> $DIR/suggest-move-types.rs:65:53
@@ -68,6 +93,11 @@ LL | struct Cl<'a, 'b, 'c, T, U, V, M: ThreeWithLifetime<T, 'a, A=(), B=(), C=()
    |                                                     |  |   the constraints are provided here
    |                                                     |  generic argument
    |                                                     generic argument
+   |
+help: move the constraints after the generic arguments
+   |
+LL | struct Cl<'a, 'b, 'c, T, U, V, M: ThreeWithLifetime<A=(), B=(), C=(), U, 'b, V, 'c, A=(), B=(), C=()>> {
+   |                                                    --                             ^^^^^^^^^^^^^^^^
 
 error: generic arguments must come before the first constraint
   --> $DIR/suggest-move-types.rs:74:28
@@ -80,6 +110,11 @@ LL | struct D<T, U, V, M: Three<T, A=(), B=(), U, C=(), V>> {
    |                            |  |     the constraints are provided here
    |                            |  the constraints are provided here
    |                            generic argument
+   |
+help: move the constraints after the generic arguments
+   |
+LL | struct D<T, U, V, M: Three<A=(), B=(), U, C=(), V, A=(), B=(), U, C=()>> {
+   |                           --                     ^^^^^^^^^^^^^^^^^^^
 
 error: generic arguments must come before the first constraint
   --> $DIR/suggest-move-types.rs:82:53
@@ -95,6 +130,11 @@ LL | struct Dl<'a, 'b, 'c, T, U, V, M: ThreeWithLifetime<T, 'a, A=(), B=(), U, '
    |                                                     |  |   the constraints are provided here
    |                                                     |  generic argument
    |                                                     generic argument
+   |
+help: move the constraints after the generic arguments
+   |
+LL | struct Dl<'a, 'b, 'c, T, U, V, M: ThreeWithLifetime<A=(), B=(), U, 'b, C=(), V, 'c, A=(), B=(), U, 'b, C=()>> {
+   |                                                    --                             ^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0747]: type provided when a lifetime was expected
   --> $DIR/suggest-move-types.rs:33:43