about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorEsteban Küber <esteban@kuber.com.ar>2018-11-26 08:32:47 -0800
committerEsteban Küber <esteban@kuber.com.ar>2018-11-26 08:32:47 -0800
commit45dfe43887fee6c2ce4cbc3e46b31626330be094 (patch)
tree93a79fafb7d26f4a3264778a7077abd2f23e14e5 /src
parent234d043d18175aff37200a91df2a1b7c3064fc80 (diff)
downloadrust-45dfe43887fee6c2ce4cbc3e46b31626330be094.tar.gz
rust-45dfe43887fee6c2ce4cbc3e46b31626330be094.zip
Emit one diagnostic for multiple misplaced lifetimes
Diffstat (limited to 'src')
-rw-r--r--src/libsyntax/parse/parser.rs31
-rw-r--r--src/test/ui/suggestions/suggest-move-lifetimes.rs6
-rw-r--r--src/test/ui/suggestions/suggest-move-lifetimes.stderr16
3 files changed, 38 insertions, 15 deletions
diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs
index 1fdf86d4867..ab5afaf3d99 100644
--- a/src/libsyntax/parse/parser.rs
+++ b/src/libsyntax/parse/parser.rs
@@ -5182,6 +5182,8 @@ impl<'a> Parser<'a> {
         let mut params = Vec::new();
         let mut seen_ty_param: Option<Span> = None;
         let mut last_comma_span = None;
+        let mut bad_lifetime_pos = vec![];
+        let mut suggestions = vec![];
         loop {
             let attrs = self.parse_outer_attributes()?;
             if self.check_lifetime() {
@@ -5207,20 +5209,12 @@ impl<'a> Parser<'a> {
                     } else {
                         last_comma_span.unwrap_or(param_span).to(param_span)
                     };
-                    let mut err = self.struct_span_err(
-                        self.prev_span,
-                        "lifetime parameters must be declared prior to type parameters",
-                    );
+                    bad_lifetime_pos.push(param_span);
+
                     if let Ok(snippet) = self.sess.source_map().span_to_snippet(param_span) {
-                        err.multipart_suggestion(
-                            "move the lifetime parameter prior to the first type parameter",
-                            vec![
-                                (remove_sp, String::new()),
-                                (sp.shrink_to_lo(), format!("{}, ", snippet)),
-                            ],
-                        );
+                        suggestions.push((remove_sp, String::new()));
+                        suggestions.push((sp.shrink_to_lo(), format!("{}, ", snippet)));
                     }
-                    err.emit();
                     if ate_comma {
                         last_comma_span = Some(self.prev_span);
                         continue
@@ -5247,6 +5241,19 @@ impl<'a> Parser<'a> {
             }
             last_comma_span = Some(self.prev_span);
         }
+        if !bad_lifetime_pos.is_empty() {
+            let mut err = self.struct_span_err(
+                bad_lifetime_pos,
+                "lifetime parameters must be declared prior to type parameters",
+            );
+            if !suggestions.is_empty() {
+                err.multipart_suggestion(
+                    "move the lifetime parameter prior to the first type parameter",
+                    suggestions,
+                );
+            }
+            err.emit();
+        }
         lifetimes.extend(params);  // ensure the correct order of lifetimes and type params
         Ok(lifetimes)
     }
diff --git a/src/test/ui/suggestions/suggest-move-lifetimes.rs b/src/test/ui/suggestions/suggest-move-lifetimes.rs
index be6d29d9337..5051a406078 100644
--- a/src/test/ui/suggestions/suggest-move-lifetimes.rs
+++ b/src/test/ui/suggestions/suggest-move-lifetimes.rs
@@ -12,4 +12,10 @@ struct C<T, U, 'a> {
     u: U,
 }
 
+struct D<T, U, 'a, 'b, V, 'c> {
+    t: &'a T,
+    u: &'b U,
+    v: &'c V,
+}
+
 fn main() {}
diff --git a/src/test/ui/suggestions/suggest-move-lifetimes.stderr b/src/test/ui/suggestions/suggest-move-lifetimes.stderr
index fa1cfe66ab5..f3d6469b512 100644
--- a/src/test/ui/suggestions/suggest-move-lifetimes.stderr
+++ b/src/test/ui/suggestions/suggest-move-lifetimes.stderr
@@ -9,10 +9,10 @@ LL | struct A<'a, T> {
    |          ^^^ --
 
 error: lifetime parameters must be declared prior to type parameters
-  --> $DIR/suggest-move-lifetimes.rs:5:15
+  --> $DIR/suggest-move-lifetimes.rs:5:13
    |
 LL | struct B<T, 'a, U> {
-   |               ^
+   |             ^^
 help: move the lifetime parameter prior to the first type parameter
    |
 LL | struct B<'a, T, U> {
@@ -28,5 +28,15 @@ help: move the lifetime parameter prior to the first type parameter
 LL | struct C<'a, T, U> {
    |          ^^^    --
 
-error: aborting due to 3 previous errors
+error: lifetime parameters must be declared prior to type parameters
+  --> $DIR/suggest-move-lifetimes.rs:15:16
+   |
+LL | struct D<T, U, 'a, 'b, V, 'c> {
+   |                ^^  ^^     ^^
+help: move the lifetime parameter prior to the first type parameter
+   |
+LL | struct D<'a, 'b, 'c, T, U, V> {
+   |          ^^^ ^^^ ^^^      ---
+
+error: aborting due to 4 previous errors