]> git.lizzy.rs Git - rust.git/commitdiff
Dedup suggestions
authorashtneoi <ashtneoi@gmail.com>
Mon, 13 Aug 2018 10:17:53 +0000 (03:17 -0700)
committerashtneoi <ashtneoi@gmail.com>
Wed, 15 Aug 2018 22:14:21 +0000 (15:14 -0700)
src/librustc_mir/borrow_check/move_errors.rs
src/test/ui/suggestions/dont-suggest-ref.rs
src/test/ui/suggestions/dont-suggest-ref.stderr

index 61b8b8d9220bbaf48dcb86b4cec187d9b574c91e..1615ff04badb1eb08a87047646a2c895cb9569f9 100644 (file)
@@ -380,11 +380,14 @@ fn add_move_hints(
         }
     }
 
+    // FIXME: Move the loop outside this method and add_move_error_labels()
+    // so they can share it.
     fn add_move_error_suggestions(
         &self,
         err: &mut DiagnosticBuilder<'a>,
         binds_to: &[Local],
     ) {
+        let mut suggestions: Vec<(Span, String, String)> = Vec::new();
         for local in binds_to {
             let bind_to = &self.mir.local_decls[*local];
             if let Some(
@@ -410,14 +413,19 @@ fn add_move_error_suggestions(
                         suggestion = pat_snippet;
                         to_remove = "&";
                     }
-                    err.span_suggestion(
+                    suggestions.push((
                         pat_span,
-                        &format!("consider removing the `{}`", to_remove),
+                        format!("consider removing the `{}`", to_remove),
                         suggestion.to_owned(),
-                    );
+                    ));
                 }
             }
         }
+        suggestions.sort_unstable_by_key(|&(span, _, _)| span);
+        suggestions.dedup_by_key(|&mut (span, _, _)| span);
+        for (span, msg, suggestion) in suggestions {
+            err.span_suggestion(span, &msg, suggestion);
+        }
     }
 
     fn add_move_error_labels(
index b7543ac1b3335c73b954e94fb65f0b61c655307c..8fa19e84e4c99318c30d06aa854559c8d3632967 100644 (file)
 
 #![feature(nll)]
 
+#[derive(Clone)]
 enum Either {
     One(X),
     Two(X),
 }
 
+#[derive(Clone)]
 struct X(Y);
 
+#[derive(Clone)]
 struct Y;
 
 pub fn main() {
@@ -338,4 +341,118 @@ fn f2(&mut X(_t): &mut X) { }
         //~| SUGGESTION Either::One(_t)
         Either::Two(_t) => (),
     }
+
+    // --------
+
+    let &(X(_t), X(_u)) = &(x.clone(), x.clone());
+    //~^ ERROR cannot move
+    //~| HELP consider removing the `&`
+    //~| SUGGESTION (X(_t), X(_u))
+    if let &(Either::One(_t), Either::Two(_u)) = &(e.clone(), e.clone()) { }
+    //~^ ERROR cannot move
+    //~| HELP consider removing the `&`
+    //~| SUGGESTION (Either::One(_t), Either::Two(_u))
+    while let &(Either::One(_t), Either::Two(_u)) = &(e.clone(), e.clone()) { }
+    //~^ ERROR cannot move
+    //~| HELP consider removing the `&`
+    //~| SUGGESTION (Either::One(_t), Either::Two(_u))
+    match &(e.clone(), e.clone()) {
+        //~^ ERROR cannot move
+        &(Either::One(_t), Either::Two(_u)) => (),
+        //~^ HELP consider removing the `&`
+        //~| SUGGESTION (Either::One(_t), Either::Two(_u))
+        &(Either::Two(_t), Either::One(_u)) => (),
+        //~^ HELP consider removing the `&`
+        //~| SUGGESTION (Either::Two(_t), Either::One(_u))
+        _ => (),
+    }
+    match &(e.clone(), e.clone()) {
+        //~^ ERROR cannot move
+        &(Either::One(_t), Either::Two(_u))
+        //~^ HELP consider removing the `&`
+        //~| SUGGESTION (Either::One(_t), Either::Two(_u))
+        | &(Either::Two(_t), Either::One(_u)) => (),
+        // FIXME: would really like a suggestion here too
+        _ => (),
+    }
+    match &(e.clone(), e.clone()) {
+        //~^ ERROR cannot move
+        &(Either::One(_t), Either::Two(_u)) => (),
+        //~^ HELP consider removing the `&`
+        //~| SUGGESTION (Either::One(_t), Either::Two(_u))
+        &(Either::Two(ref _t), Either::One(ref _u)) => (),
+        _ => (),
+    }
+    match &(e.clone(), e.clone()) {
+        //~^ ERROR cannot move
+        &(Either::One(_t), Either::Two(_u)) => (),
+        //~^ HELP consider removing the `&`
+        //~| SUGGESTION (Either::One(_t), Either::Two(_u))
+        (Either::Two(_t), Either::One(_u)) => (),
+        _ => (),
+    }
+    fn f3(&(X(_t), X(_u)): &(X, X)) { }
+    //~^ ERROR cannot move
+    //~| HELP consider removing the `&`
+    //~| SUGGESTION (X(_t), X(_u))
+
+    let &mut (X(_t), X(_u)) = &mut (xm.clone(), xm.clone());
+    //~^ ERROR cannot move
+    //~| HELP consider removing the `&mut`
+    //~| SUGGESTION (X(_t), X(_u))
+    if let &mut (Either::One(_t), Either::Two(_u)) = &mut (em.clone(), em.clone()) { }
+    //~^ ERROR cannot move
+    //~| HELP consider removing the `&mut`
+    //~| SUGGESTION (Either::One(_t), Either::Two(_u))
+    while let &mut (Either::One(_t), Either::Two(_u)) = &mut (em.clone(), em.clone()) { }
+    //~^ ERROR cannot move
+    //~| HELP consider removing the `&mut`
+    //~| SUGGESTION (Either::One(_t), Either::Two(_u))
+    match &mut (em.clone(), em.clone()) {
+        //~^ ERROR cannot move
+        &mut (Either::One(_t), Either::Two(_u)) => (),
+        //~^ HELP consider removing the `&mut`
+        //~| SUGGESTION (Either::One(_t), Either::Two(_u))
+        &mut (Either::Two(_t), Either::One(_u)) => (),
+        //~^ HELP consider removing the `&mut`
+        //~| SUGGESTION (Either::Two(_t), Either::One(_u))
+        _ => (),
+    }
+    match &mut (em.clone(), em.clone()) {
+        //~^ ERROR cannot move
+        &mut (Either::One(_t), Either::Two(_u))
+        //~^ HELP consider removing the `&mut`
+        //~| SUGGESTION (Either::One(_t), Either::Two(_u))
+        | &mut (Either::Two(_t), Either::One(_u)) => (),
+        // FIXME: would really like a suggestion here too
+        _ => (),
+    }
+    match &mut (em.clone(), em.clone()) {
+        //~^ ERROR cannot move
+        &mut (Either::One(_t), Either::Two(_u)) => (),
+        //~^ HELP consider removing the `&mut`
+        //~| SUGGESTION (Either::One(_t), Either::Two(_u))
+        &mut (Either::Two(ref _t), Either::One(ref _u)) => (),
+        _ => (),
+    }
+    match &mut (em.clone(), em.clone()) {
+        //~^ ERROR cannot move
+        &mut (Either::One(_t), Either::Two(_u)) => (),
+        //~^ HELP consider removing the `&mut`
+        //~| SUGGESTION (Either::One(_t), Either::Two(_u))
+        &mut (Either::Two(ref mut _t), Either::One(ref mut _u)) => (),
+        _ => (),
+    }
+    match &mut (em.clone(), em.clone()) {
+        //~^ ERROR cannot move
+        &mut (Either::One(_t), Either::Two(_u)) => (),
+        //~^ HELP consider removing the `&mut`
+        //~| SUGGESTION (Either::One(_t), Either::Two(_u))
+        (Either::Two(_t), Either::One(_u)) => (),
+        _ => (),
+    }
+    fn f4(&mut (X(_t), X(_u)): &mut (X, X)) { }
+    //~^ ERROR cannot move
+    //~| HELP consider removing the `&mut`
+    //~| SUGGESTION (X(_t), X(_u))
 }
index 05aff35c636e92f5d3585d1ff46c2ee5fe3286e8..81e3c21084802778e12adb9ba5691cd75b6101fb 100644 (file)
@@ -1,5 +1,5 @@
 error[E0507]: cannot move out of borrowed content
-  --> $DIR/dont-suggest-ref.rs:47:17
+  --> $DIR/dont-suggest-ref.rs:50:17
    |
 LL |     let X(_t) = *s;
    |           --    ^^
@@ -9,13 +9,13 @@ LL |     let X(_t) = *s;
    |           data moved here
    |
 note: move occurs because `_t` has type `Y`, which does not implement the `Copy` trait
-  --> $DIR/dont-suggest-ref.rs:47:11
+  --> $DIR/dont-suggest-ref.rs:50:11
    |
 LL |     let X(_t) = *s;
    |           ^^
 
 error[E0507]: cannot move out of borrowed content
-  --> $DIR/dont-suggest-ref.rs:51:30
+  --> $DIR/dont-suggest-ref.rs:54:30
    |
 LL |     if let Either::One(_t) = *r { }
    |                        --    ^^
@@ -25,13 +25,13 @@ LL |     if let Either::One(_t) = *r { }
    |                        data moved here
    |
 note: move occurs because `_t` has type `X`, which does not implement the `Copy` trait
-  --> $DIR/dont-suggest-ref.rs:51:24
+  --> $DIR/dont-suggest-ref.rs:54:24
    |
 LL |     if let Either::One(_t) = *r { }
    |                        ^^
 
 error[E0507]: cannot move out of borrowed content
-  --> $DIR/dont-suggest-ref.rs:55:33
+  --> $DIR/dont-suggest-ref.rs:58:33
    |
 LL |     while let Either::One(_t) = *r { }
    |                           --    ^^
@@ -41,13 +41,13 @@ LL |     while let Either::One(_t) = *r { }
    |                           data moved here
    |
 note: move occurs because `_t` has type `X`, which does not implement the `Copy` trait
-  --> $DIR/dont-suggest-ref.rs:55:27
+  --> $DIR/dont-suggest-ref.rs:58:27
    |
 LL |     while let Either::One(_t) = *r { }
    |                           ^^
 
 error[E0507]: cannot move out of borrowed content
-  --> $DIR/dont-suggest-ref.rs:59:11
+  --> $DIR/dont-suggest-ref.rs:62:11
    |
 LL |     match *r {
    |           ^^
@@ -59,13 +59,13 @@ LL |         Either::One(_t)
    |                     -- data moved here
    |
 note: move occurs because `_t` has type `X`, which does not implement the `Copy` trait
-  --> $DIR/dont-suggest-ref.rs:63:21
+  --> $DIR/dont-suggest-ref.rs:66:21
    |
 LL |         Either::One(_t)
    |                     ^^
 
 error[E0507]: cannot move out of borrowed content
-  --> $DIR/dont-suggest-ref.rs:66:11
+  --> $DIR/dont-suggest-ref.rs:69:11
    |
 LL |     match *r {
    |           ^^
@@ -77,13 +77,13 @@ LL |         Either::One(_t) => (),
    |                     -- data moved here
    |
 note: move occurs because `_t` has type `X`, which does not implement the `Copy` trait
-  --> $DIR/dont-suggest-ref.rs:70:21
+  --> $DIR/dont-suggest-ref.rs:73:21
    |
 LL |         Either::One(_t) => (),
    |                     ^^
 
 error[E0507]: cannot move out of borrowed content
-  --> $DIR/dont-suggest-ref.rs:75:17
+  --> $DIR/dont-suggest-ref.rs:78:17
    |
 LL |     let X(_t) = *sm;
    |           --    ^^^
@@ -93,13 +93,13 @@ LL |     let X(_t) = *sm;
    |           data moved here
    |
 note: move occurs because `_t` has type `Y`, which does not implement the `Copy` trait
-  --> $DIR/dont-suggest-ref.rs:75:11
+  --> $DIR/dont-suggest-ref.rs:78:11
    |
 LL |     let X(_t) = *sm;
    |           ^^
 
 error[E0507]: cannot move out of borrowed content
-  --> $DIR/dont-suggest-ref.rs:79:30
+  --> $DIR/dont-suggest-ref.rs:82:30
    |
 LL |     if let Either::One(_t) = *rm { }
    |                        --    ^^^
@@ -109,13 +109,13 @@ LL |     if let Either::One(_t) = *rm { }
    |                        data moved here
    |
 note: move occurs because `_t` has type `X`, which does not implement the `Copy` trait
-  --> $DIR/dont-suggest-ref.rs:79:24
+  --> $DIR/dont-suggest-ref.rs:82:24
    |
 LL |     if let Either::One(_t) = *rm { }
    |                        ^^
 
 error[E0507]: cannot move out of borrowed content
-  --> $DIR/dont-suggest-ref.rs:83:33
+  --> $DIR/dont-suggest-ref.rs:86:33
    |
 LL |     while let Either::One(_t) = *rm { }
    |                           --    ^^^
@@ -125,13 +125,13 @@ LL |     while let Either::One(_t) = *rm { }
    |                           data moved here
    |
 note: move occurs because `_t` has type `X`, which does not implement the `Copy` trait
-  --> $DIR/dont-suggest-ref.rs:83:27
+  --> $DIR/dont-suggest-ref.rs:86:27
    |
 LL |     while let Either::One(_t) = *rm { }
    |                           ^^
 
 error[E0507]: cannot move out of borrowed content
-  --> $DIR/dont-suggest-ref.rs:87:11
+  --> $DIR/dont-suggest-ref.rs:90:11
    |
 LL |     match *rm {
    |           ^^^
@@ -143,13 +143,13 @@ LL |         Either::One(_t)
    |                     -- data moved here
    |
 note: move occurs because `_t` has type `X`, which does not implement the `Copy` trait
-  --> $DIR/dont-suggest-ref.rs:91:21
+  --> $DIR/dont-suggest-ref.rs:94:21
    |
 LL |         Either::One(_t)
    |                     ^^
 
 error[E0507]: cannot move out of borrowed content
-  --> $DIR/dont-suggest-ref.rs:94:11
+  --> $DIR/dont-suggest-ref.rs:97:11
    |
 LL |     match *rm {
    |           ^^^
@@ -161,13 +161,13 @@ LL |         Either::One(_t) => (),
    |                     -- data moved here
    |
 note: move occurs because `_t` has type `X`, which does not implement the `Copy` trait
-  --> $DIR/dont-suggest-ref.rs:98:21
+  --> $DIR/dont-suggest-ref.rs:101:21
    |
 LL |         Either::One(_t) => (),
    |                     ^^
 
 error[E0507]: cannot move out of borrowed content
-  --> $DIR/dont-suggest-ref.rs:102:11
+  --> $DIR/dont-suggest-ref.rs:105:11
    |
 LL |     match *rm {
    |           ^^^
@@ -179,13 +179,13 @@ LL |         Either::One(_t) => (),
    |                     -- data moved here
    |
 note: move occurs because `_t` has type `X`, which does not implement the `Copy` trait
-  --> $DIR/dont-suggest-ref.rs:106:21
+  --> $DIR/dont-suggest-ref.rs:109:21
    |
 LL |         Either::One(_t) => (),
    |                     ^^
 
 error[E0507]: cannot move out of borrowed content
-  --> $DIR/dont-suggest-ref.rs:111:17
+  --> $DIR/dont-suggest-ref.rs:114:17
    |
 LL |     let X(_t) = vs[0];
    |           --    ^^^^^
@@ -195,13 +195,13 @@ LL |     let X(_t) = vs[0];
    |           data moved here
    |
 note: move occurs because `_t` has type `Y`, which does not implement the `Copy` trait
-  --> $DIR/dont-suggest-ref.rs:111:11
+  --> $DIR/dont-suggest-ref.rs:114:11
    |
 LL |     let X(_t) = vs[0];
    |           ^^
 
 error[E0507]: cannot move out of borrowed content
-  --> $DIR/dont-suggest-ref.rs:115:30
+  --> $DIR/dont-suggest-ref.rs:118:30
    |
 LL |     if let Either::One(_t) = vr[0] { }
    |                        --    ^^^^^
@@ -211,13 +211,13 @@ LL |     if let Either::One(_t) = vr[0] { }
    |                        data moved here
    |
 note: move occurs because `_t` has type `X`, which does not implement the `Copy` trait
-  --> $DIR/dont-suggest-ref.rs:115:24
+  --> $DIR/dont-suggest-ref.rs:118:24
    |
 LL |     if let Either::One(_t) = vr[0] { }
    |                        ^^
 
 error[E0507]: cannot move out of borrowed content
-  --> $DIR/dont-suggest-ref.rs:119:33
+  --> $DIR/dont-suggest-ref.rs:122:33
    |
 LL |     while let Either::One(_t) = vr[0] { }
    |                           --    ^^^^^
@@ -227,13 +227,13 @@ LL |     while let Either::One(_t) = vr[0] { }
    |                           data moved here
    |
 note: move occurs because `_t` has type `X`, which does not implement the `Copy` trait
-  --> $DIR/dont-suggest-ref.rs:119:27
+  --> $DIR/dont-suggest-ref.rs:122:27
    |
 LL |     while let Either::One(_t) = vr[0] { }
    |                           ^^
 
 error[E0507]: cannot move out of borrowed content
-  --> $DIR/dont-suggest-ref.rs:123:11
+  --> $DIR/dont-suggest-ref.rs:126:11
    |
 LL |     match vr[0] {
    |           ^^^^^
@@ -245,13 +245,13 @@ LL |         Either::One(_t)
    |                     -- data moved here
    |
 note: move occurs because `_t` has type `X`, which does not implement the `Copy` trait
-  --> $DIR/dont-suggest-ref.rs:127:21
+  --> $DIR/dont-suggest-ref.rs:130:21
    |
 LL |         Either::One(_t)
    |                     ^^
 
 error[E0507]: cannot move out of borrowed content
-  --> $DIR/dont-suggest-ref.rs:130:11
+  --> $DIR/dont-suggest-ref.rs:133:11
    |
 LL |     match vr[0] {
    |           ^^^^^
@@ -263,13 +263,13 @@ LL |         Either::One(_t) => (),
    |                     -- data moved here
    |
 note: move occurs because `_t` has type `X`, which does not implement the `Copy` trait
-  --> $DIR/dont-suggest-ref.rs:134:21
+  --> $DIR/dont-suggest-ref.rs:137:21
    |
 LL |         Either::One(_t) => (),
    |                     ^^
 
 error[E0507]: cannot move out of borrowed content
-  --> $DIR/dont-suggest-ref.rs:139:17
+  --> $DIR/dont-suggest-ref.rs:142:17
    |
 LL |     let X(_t) = vsm[0];
    |           --    ^^^^^^
@@ -279,13 +279,13 @@ LL |     let X(_t) = vsm[0];
    |           data moved here
    |
 note: move occurs because `_t` has type `Y`, which does not implement the `Copy` trait
-  --> $DIR/dont-suggest-ref.rs:139:11
+  --> $DIR/dont-suggest-ref.rs:142:11
    |
 LL |     let X(_t) = vsm[0];
    |           ^^
 
 error[E0507]: cannot move out of borrowed content
-  --> $DIR/dont-suggest-ref.rs:143:30
+  --> $DIR/dont-suggest-ref.rs:146:30
    |
 LL |     if let Either::One(_t) = vrm[0] { }
    |                        --    ^^^^^^
@@ -295,13 +295,13 @@ LL |     if let Either::One(_t) = vrm[0] { }
    |                        data moved here
    |
 note: move occurs because `_t` has type `X`, which does not implement the `Copy` trait
-  --> $DIR/dont-suggest-ref.rs:143:24
+  --> $DIR/dont-suggest-ref.rs:146:24
    |
 LL |     if let Either::One(_t) = vrm[0] { }
    |                        ^^
 
 error[E0507]: cannot move out of borrowed content
-  --> $DIR/dont-suggest-ref.rs:147:33
+  --> $DIR/dont-suggest-ref.rs:150:33
    |
 LL |     while let Either::One(_t) = vrm[0] { }
    |                           --    ^^^^^^
@@ -311,13 +311,13 @@ LL |     while let Either::One(_t) = vrm[0] { }
    |                           data moved here
    |
 note: move occurs because `_t` has type `X`, which does not implement the `Copy` trait
-  --> $DIR/dont-suggest-ref.rs:147:27
+  --> $DIR/dont-suggest-ref.rs:150:27
    |
 LL |     while let Either::One(_t) = vrm[0] { }
    |                           ^^
 
 error[E0507]: cannot move out of borrowed content
-  --> $DIR/dont-suggest-ref.rs:151:11
+  --> $DIR/dont-suggest-ref.rs:154:11
    |
 LL |     match vrm[0] {
    |           ^^^^^^
@@ -329,13 +329,13 @@ LL |         Either::One(_t)
    |                     -- data moved here
    |
 note: move occurs because `_t` has type `X`, which does not implement the `Copy` trait
-  --> $DIR/dont-suggest-ref.rs:155:21
+  --> $DIR/dont-suggest-ref.rs:158:21
    |
 LL |         Either::One(_t)
    |                     ^^
 
 error[E0507]: cannot move out of borrowed content
-  --> $DIR/dont-suggest-ref.rs:158:11
+  --> $DIR/dont-suggest-ref.rs:161:11
    |
 LL |     match vrm[0] {
    |           ^^^^^^
@@ -347,13 +347,13 @@ LL |         Either::One(_t) => (),
    |                     -- data moved here
    |
 note: move occurs because `_t` has type `X`, which does not implement the `Copy` trait
-  --> $DIR/dont-suggest-ref.rs:162:21
+  --> $DIR/dont-suggest-ref.rs:165:21
    |
 LL |         Either::One(_t) => (),
    |                     ^^
 
 error[E0507]: cannot move out of borrowed content
-  --> $DIR/dont-suggest-ref.rs:166:11
+  --> $DIR/dont-suggest-ref.rs:169:11
    |
 LL |     match vrm[0] {
    |           ^^^^^^
@@ -365,13 +365,13 @@ LL |         Either::One(_t) => (),
    |                     -- data moved here
    |
 note: move occurs because `_t` has type `X`, which does not implement the `Copy` trait
-  --> $DIR/dont-suggest-ref.rs:170:21
+  --> $DIR/dont-suggest-ref.rs:173:21
    |
 LL |         Either::One(_t) => (),
    |                     ^^
 
 error[E0507]: cannot move out of borrowed content
-  --> $DIR/dont-suggest-ref.rs:177:18
+  --> $DIR/dont-suggest-ref.rs:180:18
    |
 LL |     let &X(_t) = s;
    |         ------   ^ cannot move out of borrowed content
@@ -380,13 +380,13 @@ LL |     let &X(_t) = s;
    |         help: consider removing the `&`: `X(_t)`
    |
 note: move occurs because `_t` has type `Y`, which does not implement the `Copy` trait
-  --> $DIR/dont-suggest-ref.rs:177:12
+  --> $DIR/dont-suggest-ref.rs:180:12
    |
 LL |     let &X(_t) = s;
    |            ^^
 
 error[E0507]: cannot move out of borrowed content
-  --> $DIR/dont-suggest-ref.rs:181:31
+  --> $DIR/dont-suggest-ref.rs:184:31
    |
 LL |     if let &Either::One(_t) = r { }
    |            ----------------   ^ cannot move out of borrowed content
@@ -395,13 +395,13 @@ LL |     if let &Either::One(_t) = r { }
    |            help: consider removing the `&`: `Either::One(_t)`
    |
 note: move occurs because `_t` has type `X`, which does not implement the `Copy` trait
-  --> $DIR/dont-suggest-ref.rs:181:25
+  --> $DIR/dont-suggest-ref.rs:184:25
    |
 LL |     if let &Either::One(_t) = r { }
    |                         ^^
 
 error[E0507]: cannot move out of borrowed content
-  --> $DIR/dont-suggest-ref.rs:185:34
+  --> $DIR/dont-suggest-ref.rs:188:34
    |
 LL |     while let &Either::One(_t) = r { }
    |               ----------------   ^ cannot move out of borrowed content
@@ -410,13 +410,13 @@ LL |     while let &Either::One(_t) = r { }
    |               help: consider removing the `&`: `Either::One(_t)`
    |
 note: move occurs because `_t` has type `X`, which does not implement the `Copy` trait
-  --> $DIR/dont-suggest-ref.rs:185:28
+  --> $DIR/dont-suggest-ref.rs:188:28
    |
 LL |     while let &Either::One(_t) = r { }
    |                            ^^
 
 error[E0507]: cannot move out of borrowed content
-  --> $DIR/dont-suggest-ref.rs:189:11
+  --> $DIR/dont-suggest-ref.rs:192:11
    |
 LL |     match r {
    |           ^ cannot move out of borrowed content
@@ -428,13 +428,13 @@ LL |         &Either::One(_t)
    |         help: consider removing the `&`: `Either::One(_t)`
    |
 note: move occurs because `_t` has type `X`, which does not implement the `Copy` trait
-  --> $DIR/dont-suggest-ref.rs:191:22
+  --> $DIR/dont-suggest-ref.rs:194:22
    |
 LL |         &Either::One(_t)
    |                      ^^
 
 error[E0507]: cannot move out of borrowed content
-  --> $DIR/dont-suggest-ref.rs:197:11
+  --> $DIR/dont-suggest-ref.rs:200:11
    |
 LL |     match r {
    |           ^ cannot move out of borrowed content
@@ -446,13 +446,13 @@ LL |         &Either::One(_t) => (),
    |         help: consider removing the `&`: `Either::One(_t)`
    |
 note: move occurs because `_t` has type `X`, which does not implement the `Copy` trait
-  --> $DIR/dont-suggest-ref.rs:199:22
+  --> $DIR/dont-suggest-ref.rs:202:22
    |
 LL |         &Either::One(_t) => (),
    |                      ^^
 
 error[E0507]: cannot move out of borrowed content
-  --> $DIR/dont-suggest-ref.rs:204:11
+  --> $DIR/dont-suggest-ref.rs:207:11
    |
 LL |     match r {
    |           ^ cannot move out of borrowed content
@@ -464,13 +464,13 @@ LL |         &Either::One(_t) => (),
    |         help: consider removing the `&`: `Either::One(_t)`
    |
 note: move occurs because `_t` has type `X`, which does not implement the `Copy` trait
-  --> $DIR/dont-suggest-ref.rs:206:22
+  --> $DIR/dont-suggest-ref.rs:209:22
    |
 LL |         &Either::One(_t) => (),
    |                      ^^
 
 error[E0507]: cannot move out of borrowed content
-  --> $DIR/dont-suggest-ref.rs:216:22
+  --> $DIR/dont-suggest-ref.rs:219:22
    |
 LL |     let &mut X(_t) = sm;
    |         ----------   ^^ cannot move out of borrowed content
@@ -479,13 +479,13 @@ LL |     let &mut X(_t) = sm;
    |         help: consider removing the `&mut`: `X(_t)`
    |
 note: move occurs because `_t` has type `Y`, which does not implement the `Copy` trait
-  --> $DIR/dont-suggest-ref.rs:216:16
+  --> $DIR/dont-suggest-ref.rs:219:16
    |
 LL |     let &mut X(_t) = sm;
    |                ^^
 
 error[E0507]: cannot move out of borrowed content
-  --> $DIR/dont-suggest-ref.rs:220:35
+  --> $DIR/dont-suggest-ref.rs:223:35
    |
 LL |     if let &mut Either::One(_t) = rm { }
    |            --------------------   ^^ cannot move out of borrowed content
@@ -494,13 +494,13 @@ LL |     if let &mut Either::One(_t) = rm { }
    |            help: consider removing the `&mut`: `Either::One(_t)`
    |
 note: move occurs because `_t` has type `X`, which does not implement the `Copy` trait
-  --> $DIR/dont-suggest-ref.rs:220:29
+  --> $DIR/dont-suggest-ref.rs:223:29
    |
 LL |     if let &mut Either::One(_t) = rm { }
    |                             ^^
 
 error[E0507]: cannot move out of borrowed content
-  --> $DIR/dont-suggest-ref.rs:224:38
+  --> $DIR/dont-suggest-ref.rs:227:38
    |
 LL |     while let &mut Either::One(_t) = rm { }
    |               --------------------   ^^ cannot move out of borrowed content
@@ -509,13 +509,13 @@ LL |     while let &mut Either::One(_t) = rm { }
    |               help: consider removing the `&mut`: `Either::One(_t)`
    |
 note: move occurs because `_t` has type `X`, which does not implement the `Copy` trait
-  --> $DIR/dont-suggest-ref.rs:224:32
+  --> $DIR/dont-suggest-ref.rs:227:32
    |
 LL |     while let &mut Either::One(_t) = rm { }
    |                                ^^
 
 error[E0507]: cannot move out of borrowed content
-  --> $DIR/dont-suggest-ref.rs:228:11
+  --> $DIR/dont-suggest-ref.rs:231:11
    |
 LL |     match rm {
    |           ^^ cannot move out of borrowed content
@@ -527,12 +527,12 @@ LL |         &mut Either::Two(_t) => (),
    |                          -- ... and here
    |
 note: move occurs because `_t` has type `X`, which does not implement the `Copy` trait
-  --> $DIR/dont-suggest-ref.rs:230:26
+  --> $DIR/dont-suggest-ref.rs:233:26
    |
 LL |         &mut Either::One(_t) => (),
    |                          ^^
 note: move occurs because `_t` has type `X`, which does not implement the `Copy` trait
-  --> $DIR/dont-suggest-ref.rs:233:26
+  --> $DIR/dont-suggest-ref.rs:236:26
    |
 LL |         &mut Either::Two(_t) => (),
    |                          ^^
@@ -546,7 +546,7 @@ LL |         Either::Two(_t) => (),
    |         ^^^^^^^^^^^^^^^
 
 error[E0507]: cannot move out of borrowed content
-  --> $DIR/dont-suggest-ref.rs:237:11
+  --> $DIR/dont-suggest-ref.rs:240:11
    |
 LL |     match rm {
    |           ^^ cannot move out of borrowed content
@@ -558,13 +558,13 @@ LL |         &mut Either::One(_t) => (),
    |         help: consider removing the `&mut`: `Either::One(_t)`
    |
 note: move occurs because `_t` has type `X`, which does not implement the `Copy` trait
-  --> $DIR/dont-suggest-ref.rs:239:26
+  --> $DIR/dont-suggest-ref.rs:242:26
    |
 LL |         &mut Either::One(_t) => (),
    |                          ^^
 
 error[E0507]: cannot move out of borrowed content
-  --> $DIR/dont-suggest-ref.rs:244:11
+  --> $DIR/dont-suggest-ref.rs:247:11
    |
 LL |     match rm {
    |           ^^ cannot move out of borrowed content
@@ -576,13 +576,13 @@ LL |         &mut Either::One(_t) => (),
    |         help: consider removing the `&mut`: `Either::One(_t)`
    |
 note: move occurs because `_t` has type `X`, which does not implement the `Copy` trait
-  --> $DIR/dont-suggest-ref.rs:246:26
+  --> $DIR/dont-suggest-ref.rs:249:26
    |
 LL |         &mut Either::One(_t) => (),
    |                          ^^
 
 error[E0507]: cannot move out of borrowed content
-  --> $DIR/dont-suggest-ref.rs:251:11
+  --> $DIR/dont-suggest-ref.rs:254:11
    |
 LL |     match rm {
    |           ^^ cannot move out of borrowed content
@@ -594,13 +594,13 @@ LL |         &mut Either::One(_t) => (),
    |         help: consider removing the `&mut`: `Either::One(_t)`
    |
 note: move occurs because `_t` has type `X`, which does not implement the `Copy` trait
-  --> $DIR/dont-suggest-ref.rs:253:26
+  --> $DIR/dont-suggest-ref.rs:256:26
    |
 LL |         &mut Either::One(_t) => (),
    |                          ^^
 
 error[E0507]: cannot move out of borrowed content
-  --> $DIR/dont-suggest-ref.rs:265:18
+  --> $DIR/dont-suggest-ref.rs:268:18
    |
 LL |     let &X(_t) = &x;
    |         ------   ^^ cannot move out of borrowed content
@@ -609,13 +609,13 @@ LL |     let &X(_t) = &x;
    |         help: consider removing the `&`: `X(_t)`
    |
 note: move occurs because `_t` has type `Y`, which does not implement the `Copy` trait
-  --> $DIR/dont-suggest-ref.rs:265:12
+  --> $DIR/dont-suggest-ref.rs:268:12
    |
 LL |     let &X(_t) = &x;
    |            ^^
 
 error[E0507]: cannot move out of borrowed content
-  --> $DIR/dont-suggest-ref.rs:269:31
+  --> $DIR/dont-suggest-ref.rs:272:31
    |
 LL |     if let &Either::One(_t) = &e { }
    |            ----------------   ^^ cannot move out of borrowed content
@@ -624,13 +624,13 @@ LL |     if let &Either::One(_t) = &e { }
    |            help: consider removing the `&`: `Either::One(_t)`
    |
 note: move occurs because `_t` has type `X`, which does not implement the `Copy` trait
-  --> $DIR/dont-suggest-ref.rs:269:25
+  --> $DIR/dont-suggest-ref.rs:272:25
    |
 LL |     if let &Either::One(_t) = &e { }
    |                         ^^
 
 error[E0507]: cannot move out of borrowed content
-  --> $DIR/dont-suggest-ref.rs:273:34
+  --> $DIR/dont-suggest-ref.rs:276:34
    |
 LL |     while let &Either::One(_t) = &e { }
    |               ----------------   ^^ cannot move out of borrowed content
@@ -639,13 +639,13 @@ LL |     while let &Either::One(_t) = &e { }
    |               help: consider removing the `&`: `Either::One(_t)`
    |
 note: move occurs because `_t` has type `X`, which does not implement the `Copy` trait
-  --> $DIR/dont-suggest-ref.rs:273:28
+  --> $DIR/dont-suggest-ref.rs:276:28
    |
 LL |     while let &Either::One(_t) = &e { }
    |                            ^^
 
 error[E0507]: cannot move out of borrowed content
-  --> $DIR/dont-suggest-ref.rs:277:11
+  --> $DIR/dont-suggest-ref.rs:280:11
    |
 LL |     match &e {
    |           ^^ cannot move out of borrowed content
@@ -657,13 +657,13 @@ LL |         &Either::One(_t)
    |         help: consider removing the `&`: `Either::One(_t)`
    |
 note: move occurs because `_t` has type `X`, which does not implement the `Copy` trait
-  --> $DIR/dont-suggest-ref.rs:279:22
+  --> $DIR/dont-suggest-ref.rs:282:22
    |
 LL |         &Either::One(_t)
    |                      ^^
 
 error[E0507]: cannot move out of borrowed content
-  --> $DIR/dont-suggest-ref.rs:285:11
+  --> $DIR/dont-suggest-ref.rs:288:11
    |
 LL |     match &e {
    |           ^^ cannot move out of borrowed content
@@ -675,13 +675,13 @@ LL |         &Either::One(_t) => (),
    |         help: consider removing the `&`: `Either::One(_t)`
    |
 note: move occurs because `_t` has type `X`, which does not implement the `Copy` trait
-  --> $DIR/dont-suggest-ref.rs:287:22
+  --> $DIR/dont-suggest-ref.rs:290:22
    |
 LL |         &Either::One(_t) => (),
    |                      ^^
 
 error[E0507]: cannot move out of borrowed content
-  --> $DIR/dont-suggest-ref.rs:292:11
+  --> $DIR/dont-suggest-ref.rs:295:11
    |
 LL |     match &e {
    |           ^^ cannot move out of borrowed content
@@ -693,13 +693,13 @@ LL |         &Either::One(_t) => (),
    |         help: consider removing the `&`: `Either::One(_t)`
    |
 note: move occurs because `_t` has type `X`, which does not implement the `Copy` trait
-  --> $DIR/dont-suggest-ref.rs:294:22
+  --> $DIR/dont-suggest-ref.rs:297:22
    |
 LL |         &Either::One(_t) => (),
    |                      ^^
 
 error[E0507]: cannot move out of borrowed content
-  --> $DIR/dont-suggest-ref.rs:300:22
+  --> $DIR/dont-suggest-ref.rs:303:22
    |
 LL |     let &mut X(_t) = &mut xm;
    |         ----------   ^^^^^^^ cannot move out of borrowed content
@@ -708,13 +708,13 @@ LL |     let &mut X(_t) = &mut xm;
    |         help: consider removing the `&mut`: `X(_t)`
    |
 note: move occurs because `_t` has type `Y`, which does not implement the `Copy` trait
-  --> $DIR/dont-suggest-ref.rs:300:16
+  --> $DIR/dont-suggest-ref.rs:303:16
    |
 LL |     let &mut X(_t) = &mut xm;
    |                ^^
 
 error[E0507]: cannot move out of borrowed content
-  --> $DIR/dont-suggest-ref.rs:304:35
+  --> $DIR/dont-suggest-ref.rs:307:35
    |
 LL |     if let &mut Either::One(_t) = &mut em { }
    |            --------------------   ^^^^^^^ cannot move out of borrowed content
@@ -723,13 +723,13 @@ LL |     if let &mut Either::One(_t) = &mut em { }
    |            help: consider removing the `&mut`: `Either::One(_t)`
    |
 note: move occurs because `_t` has type `X`, which does not implement the `Copy` trait
-  --> $DIR/dont-suggest-ref.rs:304:29
+  --> $DIR/dont-suggest-ref.rs:307:29
    |
 LL |     if let &mut Either::One(_t) = &mut em { }
    |                             ^^
 
 error[E0507]: cannot move out of borrowed content
-  --> $DIR/dont-suggest-ref.rs:308:38
+  --> $DIR/dont-suggest-ref.rs:311:38
    |
 LL |     while let &mut Either::One(_t) = &mut em { }
    |               --------------------   ^^^^^^^ cannot move out of borrowed content
@@ -738,13 +738,13 @@ LL |     while let &mut Either::One(_t) = &mut em { }
    |               help: consider removing the `&mut`: `Either::One(_t)`
    |
 note: move occurs because `_t` has type `X`, which does not implement the `Copy` trait
-  --> $DIR/dont-suggest-ref.rs:308:32
+  --> $DIR/dont-suggest-ref.rs:311:32
    |
 LL |     while let &mut Either::One(_t) = &mut em { }
    |                                ^^
 
 error[E0507]: cannot move out of borrowed content
-  --> $DIR/dont-suggest-ref.rs:312:11
+  --> $DIR/dont-suggest-ref.rs:315:11
    |
 LL |     match &mut em {
    |           ^^^^^^^ cannot move out of borrowed content
@@ -756,13 +756,13 @@ LL |         &mut Either::One(_t)
    |         help: consider removing the `&mut`: `Either::One(_t)`
    |
 note: move occurs because `_t` has type `X`, which does not implement the `Copy` trait
-  --> $DIR/dont-suggest-ref.rs:314:26
+  --> $DIR/dont-suggest-ref.rs:317:26
    |
 LL |         &mut Either::One(_t)
    |                          ^^
 
 error[E0507]: cannot move out of borrowed content
-  --> $DIR/dont-suggest-ref.rs:320:11
+  --> $DIR/dont-suggest-ref.rs:323:11
    |
 LL |     match &mut em {
    |           ^^^^^^^ cannot move out of borrowed content
@@ -774,13 +774,13 @@ LL |         &mut Either::One(_t) => (),
    |         help: consider removing the `&mut`: `Either::One(_t)`
    |
 note: move occurs because `_t` has type `X`, which does not implement the `Copy` trait
-  --> $DIR/dont-suggest-ref.rs:322:26
+  --> $DIR/dont-suggest-ref.rs:325:26
    |
 LL |         &mut Either::One(_t) => (),
    |                          ^^
 
 error[E0507]: cannot move out of borrowed content
-  --> $DIR/dont-suggest-ref.rs:327:11
+  --> $DIR/dont-suggest-ref.rs:330:11
    |
 LL |     match &mut em {
    |           ^^^^^^^ cannot move out of borrowed content
@@ -792,13 +792,13 @@ LL |         &mut Either::One(_t) => (),
    |         help: consider removing the `&mut`: `Either::One(_t)`
    |
 note: move occurs because `_t` has type `X`, which does not implement the `Copy` trait
-  --> $DIR/dont-suggest-ref.rs:329:26
+  --> $DIR/dont-suggest-ref.rs:332:26
    |
 LL |         &mut Either::One(_t) => (),
    |                          ^^
 
 error[E0507]: cannot move out of borrowed content
-  --> $DIR/dont-suggest-ref.rs:334:11
+  --> $DIR/dont-suggest-ref.rs:337:11
    |
 LL |     match &mut em {
    |           ^^^^^^^ cannot move out of borrowed content
@@ -810,13 +810,393 @@ LL |         &mut Either::One(_t) => (),
    |         help: consider removing the `&mut`: `Either::One(_t)`
    |
 note: move occurs because `_t` has type `X`, which does not implement the `Copy` trait
-  --> $DIR/dont-suggest-ref.rs:336:26
+  --> $DIR/dont-suggest-ref.rs:339:26
    |
 LL |         &mut Either::One(_t) => (),
    |                          ^^
 
 error[E0507]: cannot move out of borrowed content
-  --> $DIR/dont-suggest-ref.rs:211:11
+  --> $DIR/dont-suggest-ref.rs:347:27
+   |
+LL |     let &(X(_t), X(_u)) = &(x.clone(), x.clone());
+   |         ---------------   ^^^^^^^^^^^^^^^^^^^^^^^ cannot move out of borrowed content
+   |         |   |      |
+   |         |   |      ... and here
+   |         |   data moved here
+   |         help: consider removing the `&`: `(X(_t), X(_u))`
+   |
+note: move occurs because `_t` has type `Y`, which does not implement the `Copy` trait
+  --> $DIR/dont-suggest-ref.rs:347:13
+   |
+LL |     let &(X(_t), X(_u)) = &(x.clone(), x.clone());
+   |             ^^
+note: move occurs because `_u` has type `Y`, which does not implement the `Copy` trait
+  --> $DIR/dont-suggest-ref.rs:347:20
+   |
+LL |     let &(X(_t), X(_u)) = &(x.clone(), x.clone());
+   |                    ^^
+
+error[E0507]: cannot move out of borrowed content
+  --> $DIR/dont-suggest-ref.rs:351:50
+   |
+LL |     if let &(Either::One(_t), Either::Two(_u)) = &(e.clone(), e.clone()) { }
+   |            -----------------------------------   ^^^^^^^^^^^^^^^^^^^^^^^ cannot move out of borrowed content
+   |            |             |                |
+   |            |             |                ... and here
+   |            |             data moved here
+   |            help: consider removing the `&`: `(Either::One(_t), Either::Two(_u))`
+   |
+note: move occurs because `_t` has type `X`, which does not implement the `Copy` trait
+  --> $DIR/dont-suggest-ref.rs:351:26
+   |
+LL |     if let &(Either::One(_t), Either::Two(_u)) = &(e.clone(), e.clone()) { }
+   |                          ^^
+note: move occurs because `_u` has type `X`, which does not implement the `Copy` trait
+  --> $DIR/dont-suggest-ref.rs:351:43
+   |
+LL |     if let &(Either::One(_t), Either::Two(_u)) = &(e.clone(), e.clone()) { }
+   |                                           ^^
+
+error[E0507]: cannot move out of borrowed content
+  --> $DIR/dont-suggest-ref.rs:355:53
+   |
+LL |     while let &(Either::One(_t), Either::Two(_u)) = &(e.clone(), e.clone()) { }
+   |               -----------------------------------   ^^^^^^^^^^^^^^^^^^^^^^^ cannot move out of borrowed content
+   |               |             |                |
+   |               |             |                ... and here
+   |               |             data moved here
+   |               help: consider removing the `&`: `(Either::One(_t), Either::Two(_u))`
+   |
+note: move occurs because `_t` has type `X`, which does not implement the `Copy` trait
+  --> $DIR/dont-suggest-ref.rs:355:29
+   |
+LL |     while let &(Either::One(_t), Either::Two(_u)) = &(e.clone(), e.clone()) { }
+   |                             ^^
+note: move occurs because `_u` has type `X`, which does not implement the `Copy` trait
+  --> $DIR/dont-suggest-ref.rs:355:46
+   |
+LL |     while let &(Either::One(_t), Either::Two(_u)) = &(e.clone(), e.clone()) { }
+   |                                              ^^
+
+error[E0507]: cannot move out of borrowed content
+  --> $DIR/dont-suggest-ref.rs:359:11
+   |
+LL |     match &(e.clone(), e.clone()) {
+   |           ^^^^^^^^^^^^^^^^^^^^^^^ cannot move out of borrowed content
+LL |         //~^ ERROR cannot move
+LL |         &(Either::One(_t), Either::Two(_u)) => (),
+   |                       --               -- ... and here
+   |                       |
+   |                       data moved here
+...
+LL |         &(Either::Two(_t), Either::One(_u)) => (),
+   |                       -- ... and here  -- ... and here
+   |
+note: move occurs because `_t` has type `X`, which does not implement the `Copy` trait
+  --> $DIR/dont-suggest-ref.rs:361:23
+   |
+LL |         &(Either::One(_t), Either::Two(_u)) => (),
+   |                       ^^
+note: move occurs because `_u` has type `X`, which does not implement the `Copy` trait
+  --> $DIR/dont-suggest-ref.rs:361:40
+   |
+LL |         &(Either::One(_t), Either::Two(_u)) => (),
+   |                                        ^^
+note: move occurs because `_t` has type `X`, which does not implement the `Copy` trait
+  --> $DIR/dont-suggest-ref.rs:364:23
+   |
+LL |         &(Either::Two(_t), Either::One(_u)) => (),
+   |                       ^^
+note: move occurs because `_u` has type `X`, which does not implement the `Copy` trait
+  --> $DIR/dont-suggest-ref.rs:364:40
+   |
+LL |         &(Either::Two(_t), Either::One(_u)) => (),
+   |                                        ^^
+help: consider removing the `&`
+   |
+LL |         (Either::One(_t), Either::Two(_u)) => (),
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+help: consider removing the `&`
+   |
+LL |         (Either::Two(_t), Either::One(_u)) => (),
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error[E0507]: cannot move out of borrowed content
+  --> $DIR/dont-suggest-ref.rs:369:11
+   |
+LL |     match &(e.clone(), e.clone()) {
+   |           ^^^^^^^^^^^^^^^^^^^^^^^ cannot move out of borrowed content
+LL |         //~^ ERROR cannot move
+LL |         &(Either::One(_t), Either::Two(_u))
+   |         -----------------------------------
+   |         |             |                |
+   |         |             |                ... and here
+   |         |             data moved here
+   |         help: consider removing the `&`: `(Either::One(_t), Either::Two(_u))`
+   |
+note: move occurs because `_t` has type `X`, which does not implement the `Copy` trait
+  --> $DIR/dont-suggest-ref.rs:371:23
+   |
+LL |         &(Either::One(_t), Either::Two(_u))
+   |                       ^^
+note: move occurs because `_u` has type `X`, which does not implement the `Copy` trait
+  --> $DIR/dont-suggest-ref.rs:371:40
+   |
+LL |         &(Either::One(_t), Either::Two(_u))
+   |                                        ^^
+
+error[E0507]: cannot move out of borrowed content
+  --> $DIR/dont-suggest-ref.rs:378:11
+   |
+LL |     match &(e.clone(), e.clone()) {
+   |           ^^^^^^^^^^^^^^^^^^^^^^^ cannot move out of borrowed content
+LL |         //~^ ERROR cannot move
+LL |         &(Either::One(_t), Either::Two(_u)) => (),
+   |         -----------------------------------
+   |         |             |                |
+   |         |             |                ... and here
+   |         |             data moved here
+   |         help: consider removing the `&`: `(Either::One(_t), Either::Two(_u))`
+   |
+note: move occurs because `_t` has type `X`, which does not implement the `Copy` trait
+  --> $DIR/dont-suggest-ref.rs:380:23
+   |
+LL |         &(Either::One(_t), Either::Two(_u)) => (),
+   |                       ^^
+note: move occurs because `_u` has type `X`, which does not implement the `Copy` trait
+  --> $DIR/dont-suggest-ref.rs:380:40
+   |
+LL |         &(Either::One(_t), Either::Two(_u)) => (),
+   |                                        ^^
+
+error[E0507]: cannot move out of borrowed content
+  --> $DIR/dont-suggest-ref.rs:386:11
+   |
+LL |     match &(e.clone(), e.clone()) {
+   |           ^^^^^^^^^^^^^^^^^^^^^^^ cannot move out of borrowed content
+LL |         //~^ ERROR cannot move
+LL |         &(Either::One(_t), Either::Two(_u)) => (),
+   |         -----------------------------------
+   |         |             |                |
+   |         |             |                ... and here
+   |         |             data moved here
+   |         help: consider removing the `&`: `(Either::One(_t), Either::Two(_u))`
+   |
+note: move occurs because `_t` has type `X`, which does not implement the `Copy` trait
+  --> $DIR/dont-suggest-ref.rs:388:23
+   |
+LL |         &(Either::One(_t), Either::Two(_u)) => (),
+   |                       ^^
+note: move occurs because `_u` has type `X`, which does not implement the `Copy` trait
+  --> $DIR/dont-suggest-ref.rs:388:40
+   |
+LL |         &(Either::One(_t), Either::Two(_u)) => (),
+   |                                        ^^
+
+error[E0507]: cannot move out of borrowed content
+  --> $DIR/dont-suggest-ref.rs:399:31
+   |
+LL |     let &mut (X(_t), X(_u)) = &mut (xm.clone(), xm.clone());
+   |         -------------------   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot move out of borrowed content
+   |         |       |      |
+   |         |       |      ... and here
+   |         |       data moved here
+   |         help: consider removing the `&mut`: `(X(_t), X(_u))`
+   |
+note: move occurs because `_t` has type `Y`, which does not implement the `Copy` trait
+  --> $DIR/dont-suggest-ref.rs:399:17
+   |
+LL |     let &mut (X(_t), X(_u)) = &mut (xm.clone(), xm.clone());
+   |                 ^^
+note: move occurs because `_u` has type `Y`, which does not implement the `Copy` trait
+  --> $DIR/dont-suggest-ref.rs:399:24
+   |
+LL |     let &mut (X(_t), X(_u)) = &mut (xm.clone(), xm.clone());
+   |                        ^^
+
+error[E0507]: cannot move out of borrowed content
+  --> $DIR/dont-suggest-ref.rs:403:54
+   |
+LL |     if let &mut (Either::One(_t), Either::Two(_u)) = &mut (em.clone(), em.clone()) { }
+   |            ---------------------------------------   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot move out of borrowed content
+   |            |                 |                |
+   |            |                 |                ... and here
+   |            |                 data moved here
+   |            help: consider removing the `&mut`: `(Either::One(_t), Either::Two(_u))`
+   |
+note: move occurs because `_t` has type `X`, which does not implement the `Copy` trait
+  --> $DIR/dont-suggest-ref.rs:403:30
+   |
+LL |     if let &mut (Either::One(_t), Either::Two(_u)) = &mut (em.clone(), em.clone()) { }
+   |                              ^^
+note: move occurs because `_u` has type `X`, which does not implement the `Copy` trait
+  --> $DIR/dont-suggest-ref.rs:403:47
+   |
+LL |     if let &mut (Either::One(_t), Either::Two(_u)) = &mut (em.clone(), em.clone()) { }
+   |                                               ^^
+
+error[E0507]: cannot move out of borrowed content
+  --> $DIR/dont-suggest-ref.rs:407:57
+   |
+LL |     while let &mut (Either::One(_t), Either::Two(_u)) = &mut (em.clone(), em.clone()) { }
+   |               ---------------------------------------   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot move out of borrowed content
+   |               |                 |                |
+   |               |                 |                ... and here
+   |               |                 data moved here
+   |               help: consider removing the `&mut`: `(Either::One(_t), Either::Two(_u))`
+   |
+note: move occurs because `_t` has type `X`, which does not implement the `Copy` trait
+  --> $DIR/dont-suggest-ref.rs:407:33
+   |
+LL |     while let &mut (Either::One(_t), Either::Two(_u)) = &mut (em.clone(), em.clone()) { }
+   |                                 ^^
+note: move occurs because `_u` has type `X`, which does not implement the `Copy` trait
+  --> $DIR/dont-suggest-ref.rs:407:50
+   |
+LL |     while let &mut (Either::One(_t), Either::Two(_u)) = &mut (em.clone(), em.clone()) { }
+   |                                                  ^^
+
+error[E0507]: cannot move out of borrowed content
+  --> $DIR/dont-suggest-ref.rs:411:11
+   |
+LL |     match &mut (em.clone(), em.clone()) {
+   |           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot move out of borrowed content
+LL |         //~^ ERROR cannot move
+LL |         &mut (Either::One(_t), Either::Two(_u)) => (),
+   |                           --               -- ... and here
+   |                           |
+   |                           data moved here
+...
+LL |         &mut (Either::Two(_t), Either::One(_u)) => (),
+   |                           -- ... and here  -- ... and here
+   |
+note: move occurs because `_t` has type `X`, which does not implement the `Copy` trait
+  --> $DIR/dont-suggest-ref.rs:413:27
+   |
+LL |         &mut (Either::One(_t), Either::Two(_u)) => (),
+   |                           ^^
+note: move occurs because `_u` has type `X`, which does not implement the `Copy` trait
+  --> $DIR/dont-suggest-ref.rs:413:44
+   |
+LL |         &mut (Either::One(_t), Either::Two(_u)) => (),
+   |                                            ^^
+note: move occurs because `_t` has type `X`, which does not implement the `Copy` trait
+  --> $DIR/dont-suggest-ref.rs:416:27
+   |
+LL |         &mut (Either::Two(_t), Either::One(_u)) => (),
+   |                           ^^
+note: move occurs because `_u` has type `X`, which does not implement the `Copy` trait
+  --> $DIR/dont-suggest-ref.rs:416:44
+   |
+LL |         &mut (Either::Two(_t), Either::One(_u)) => (),
+   |                                            ^^
+help: consider removing the `&mut`
+   |
+LL |         (Either::One(_t), Either::Two(_u)) => (),
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+help: consider removing the `&mut`
+   |
+LL |         (Either::Two(_t), Either::One(_u)) => (),
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error[E0507]: cannot move out of borrowed content
+  --> $DIR/dont-suggest-ref.rs:421:11
+   |
+LL |     match &mut (em.clone(), em.clone()) {
+   |           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot move out of borrowed content
+LL |         //~^ ERROR cannot move
+LL |         &mut (Either::One(_t), Either::Two(_u))
+   |         ---------------------------------------
+   |         |                 |                |
+   |         |                 |                ... and here
+   |         |                 data moved here
+   |         help: consider removing the `&mut`: `(Either::One(_t), Either::Two(_u))`
+   |
+note: move occurs because `_t` has type `X`, which does not implement the `Copy` trait
+  --> $DIR/dont-suggest-ref.rs:423:27
+   |
+LL |         &mut (Either::One(_t), Either::Two(_u))
+   |                           ^^
+note: move occurs because `_u` has type `X`, which does not implement the `Copy` trait
+  --> $DIR/dont-suggest-ref.rs:423:44
+   |
+LL |         &mut (Either::One(_t), Either::Two(_u))
+   |                                            ^^
+
+error[E0507]: cannot move out of borrowed content
+  --> $DIR/dont-suggest-ref.rs:430:11
+   |
+LL |     match &mut (em.clone(), em.clone()) {
+   |           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot move out of borrowed content
+LL |         //~^ ERROR cannot move
+LL |         &mut (Either::One(_t), Either::Two(_u)) => (),
+   |         ---------------------------------------
+   |         |                 |                |
+   |         |                 |                ... and here
+   |         |                 data moved here
+   |         help: consider removing the `&mut`: `(Either::One(_t), Either::Two(_u))`
+   |
+note: move occurs because `_t` has type `X`, which does not implement the `Copy` trait
+  --> $DIR/dont-suggest-ref.rs:432:27
+   |
+LL |         &mut (Either::One(_t), Either::Two(_u)) => (),
+   |                           ^^
+note: move occurs because `_u` has type `X`, which does not implement the `Copy` trait
+  --> $DIR/dont-suggest-ref.rs:432:44
+   |
+LL |         &mut (Either::One(_t), Either::Two(_u)) => (),
+   |                                            ^^
+
+error[E0507]: cannot move out of borrowed content
+  --> $DIR/dont-suggest-ref.rs:438:11
+   |
+LL |     match &mut (em.clone(), em.clone()) {
+   |           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot move out of borrowed content
+LL |         //~^ ERROR cannot move
+LL |         &mut (Either::One(_t), Either::Two(_u)) => (),
+   |         ---------------------------------------
+   |         |                 |                |
+   |         |                 |                ... and here
+   |         |                 data moved here
+   |         help: consider removing the `&mut`: `(Either::One(_t), Either::Two(_u))`
+   |
+note: move occurs because `_t` has type `X`, which does not implement the `Copy` trait
+  --> $DIR/dont-suggest-ref.rs:440:27
+   |
+LL |         &mut (Either::One(_t), Either::Two(_u)) => (),
+   |                           ^^
+note: move occurs because `_u` has type `X`, which does not implement the `Copy` trait
+  --> $DIR/dont-suggest-ref.rs:440:44
+   |
+LL |         &mut (Either::One(_t), Either::Two(_u)) => (),
+   |                                            ^^
+
+error[E0507]: cannot move out of borrowed content
+  --> $DIR/dont-suggest-ref.rs:446:11
+   |
+LL |     match &mut (em.clone(), em.clone()) {
+   |           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot move out of borrowed content
+LL |         //~^ ERROR cannot move
+LL |         &mut (Either::One(_t), Either::Two(_u)) => (),
+   |         ---------------------------------------
+   |         |                 |                |
+   |         |                 |                ... and here
+   |         |                 data moved here
+   |         help: consider removing the `&mut`: `(Either::One(_t), Either::Two(_u))`
+   |
+note: move occurs because `_t` has type `X`, which does not implement the `Copy` trait
+  --> $DIR/dont-suggest-ref.rs:448:27
+   |
+LL |         &mut (Either::One(_t), Either::Two(_u)) => (),
+   |                           ^^
+note: move occurs because `_u` has type `X`, which does not implement the `Copy` trait
+  --> $DIR/dont-suggest-ref.rs:448:44
+   |
+LL |         &mut (Either::One(_t), Either::Two(_u)) => (),
+   |                                            ^^
+
+error[E0507]: cannot move out of borrowed content
+  --> $DIR/dont-suggest-ref.rs:214:11
    |
 LL |     fn f1(&X(_t): &X) { }
    |           ^^^--^
@@ -826,13 +1206,13 @@ LL |     fn f1(&X(_t): &X) { }
    |           help: consider removing the `&`: `X(_t)`
    |
 note: move occurs because `_t` has type `Y`, which does not implement the `Copy` trait
-  --> $DIR/dont-suggest-ref.rs:211:14
+  --> $DIR/dont-suggest-ref.rs:214:14
    |
 LL |     fn f1(&X(_t): &X) { }
    |              ^^
 
 error[E0507]: cannot move out of borrowed content
-  --> $DIR/dont-suggest-ref.rs:258:11
+  --> $DIR/dont-suggest-ref.rs:261:11
    |
 LL |     fn f2(&mut X(_t): &mut X) { }
    |           ^^^^^^^--^
@@ -842,11 +1222,55 @@ LL |     fn f2(&mut X(_t): &mut X) { }
    |           help: consider removing the `&mut`: `X(_t)`
    |
 note: move occurs because `_t` has type `Y`, which does not implement the `Copy` trait
-  --> $DIR/dont-suggest-ref.rs:258:18
+  --> $DIR/dont-suggest-ref.rs:261:18
    |
 LL |     fn f2(&mut X(_t): &mut X) { }
    |                  ^^
 
-error: aborting due to 50 previous errors
+error[E0507]: cannot move out of borrowed content
+  --> $DIR/dont-suggest-ref.rs:394:11
+   |
+LL |     fn f3(&(X(_t), X(_u)): &(X, X)) { }
+   |           ^^^^--^^^^^--^^
+   |           |   |      |
+   |           |   |      ... and here
+   |           |   data moved here
+   |           cannot move out of borrowed content
+   |           help: consider removing the `&`: `(X(_t), X(_u))`
+   |
+note: move occurs because `_t` has type `Y`, which does not implement the `Copy` trait
+  --> $DIR/dont-suggest-ref.rs:394:15
+   |
+LL |     fn f3(&(X(_t), X(_u)): &(X, X)) { }
+   |               ^^
+note: move occurs because `_u` has type `Y`, which does not implement the `Copy` trait
+  --> $DIR/dont-suggest-ref.rs:394:22
+   |
+LL |     fn f3(&(X(_t), X(_u)): &(X, X)) { }
+   |                      ^^
+
+error[E0507]: cannot move out of borrowed content
+  --> $DIR/dont-suggest-ref.rs:454:11
+   |
+LL |     fn f4(&mut (X(_t), X(_u)): &mut (X, X)) { }
+   |           ^^^^^^^^--^^^^^--^^
+   |           |       |      |
+   |           |       |      ... and here
+   |           |       data moved here
+   |           cannot move out of borrowed content
+   |           help: consider removing the `&mut`: `(X(_t), X(_u))`
+   |
+note: move occurs because `_t` has type `Y`, which does not implement the `Copy` trait
+  --> $DIR/dont-suggest-ref.rs:454:19
+   |
+LL |     fn f4(&mut (X(_t), X(_u)): &mut (X, X)) { }
+   |                   ^^
+note: move occurs because `_u` has type `Y`, which does not implement the `Copy` trait
+  --> $DIR/dont-suggest-ref.rs:454:26
+   |
+LL |     fn f4(&mut (X(_t), X(_u)): &mut (X, X)) { }
+   |                          ^^
+
+error: aborting due to 67 previous errors
 
 For more information about this error, try `rustc --explain E0507`.