From 0f306a7db431f335b5a3d94c31222a8b008d5437 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Esteban=20K=C3=BCber?= <esteban@kuber.com.ar>
Date: Tue, 3 Dec 2019 15:02:27 -0800
Subject: [PATCH 1/2] Do not ICE on async fn with non-Copy infered type arg

Fix #66958.
---
 .../diagnostics/conflict_errors.rs            | 19 ++++++++++---------
 src/test/ui/issues/issue-66958.rs             | 15 +++++++++++++++
 src/test/ui/issues/issue-66958.stderr         | 13 +++++++++++++
 3 files changed, 38 insertions(+), 9 deletions(-)
 create mode 100644 src/test/ui/issues/issue-66958.rs
 create mode 100644 src/test/ui/issues/issue-66958.stderr

diff --git a/src/librustc_mir/borrow_check/diagnostics/conflict_errors.rs b/src/librustc_mir/borrow_check/diagnostics/conflict_errors.rs
index d14957b9017da..a0f126fb2cb30 100644
--- a/src/librustc_mir/borrow_check/diagnostics/conflict_errors.rs
+++ b/src/librustc_mir/borrow_check/diagnostics/conflict_errors.rs
@@ -240,15 +240,16 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
                     let tcx = self.infcx.tcx;
                     let generics = tcx.generics_of(self.mir_def_id);
                     let param = generics.type_param(&param_ty, tcx);
-                    let generics = tcx.hir().get_generics(self.mir_def_id).unwrap();
-                    suggest_constraining_type_param(
-                        generics,
-                        &mut err,
-                        &param.name.as_str(),
-                        "Copy",
-                        tcx.sess.source_map(),
-                        span,
-                    );
+                    if let Some(generics) = tcx.hir().get_generics(self.mir_def_id) {
+                        suggest_constraining_type_param(
+                            generics,
+                            &mut err,
+                            &param.name.as_str(),
+                            "Copy",
+                            tcx.sess.source_map(),
+                            span,
+                        );
+                    }
                 }
                 let span = if let Some(local) = place.as_local() {
                     let decl = &self.body.local_decls[local];
diff --git a/src/test/ui/issues/issue-66958.rs b/src/test/ui/issues/issue-66958.rs
new file mode 100644
index 0000000000000..a4c48ab05c020
--- /dev/null
+++ b/src/test/ui/issues/issue-66958.rs
@@ -0,0 +1,15 @@
+// edition:2018
+
+struct Ia<S>(u32, S);
+
+impl<S> Ia<S> {
+    fn partial(_: S) {}
+    fn full(self) {}
+
+    async fn crash(self) {
+        Self::partial(self.1);
+        Self::full(self); //~ ERROR use of moved value: `self`
+    }
+}
+
+fn main() {}
diff --git a/src/test/ui/issues/issue-66958.stderr b/src/test/ui/issues/issue-66958.stderr
new file mode 100644
index 0000000000000..79a80168a5e59
--- /dev/null
+++ b/src/test/ui/issues/issue-66958.stderr
@@ -0,0 +1,13 @@
+error[E0382]: use of moved value: `self`
+  --> $DIR/issue-66958.rs:11:20
+   |
+LL |         Self::partial(self.1);
+   |                       ------ value moved here
+LL |         Self::full(self);
+   |                    ^^^^ value used here after partial move
+   |
+   = note: move occurs because `self.1` has type `S`, which does not implement the `Copy` trait
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0382`.

From 7ed90667664a910ae4327415fc4a33eb580dd2ea Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Esteban=20K=C3=BCber?= <esteban@kuber.com.ar>
Date: Thu, 5 Dec 2019 06:57:34 -0800
Subject: [PATCH 2/2] review comments

---
 .../issues/issue-66958-non-copy-infered-type-arg.rs}        | 4 ++--
 .../issues/issue-66958-non-copy-infered-type-arg.stderr}    | 6 +++---
 2 files changed, 5 insertions(+), 5 deletions(-)
 rename src/test/ui/{issues/issue-66958.rs => async-await/issues/issue-66958-non-copy-infered-type-arg.rs} (78%)
 rename src/test/ui/{issues/issue-66958.stderr => async-await/issues/issue-66958-non-copy-infered-type-arg.stderr} (68%)

diff --git a/src/test/ui/issues/issue-66958.rs b/src/test/ui/async-await/issues/issue-66958-non-copy-infered-type-arg.rs
similarity index 78%
rename from src/test/ui/issues/issue-66958.rs
rename to src/test/ui/async-await/issues/issue-66958-non-copy-infered-type-arg.rs
index a4c48ab05c020..c8c2702ec447e 100644
--- a/src/test/ui/issues/issue-66958.rs
+++ b/src/test/ui/async-await/issues/issue-66958-non-copy-infered-type-arg.rs
@@ -1,13 +1,13 @@
 // edition:2018
 
-struct Ia<S>(u32, S);
+struct Ia<S>(S);
 
 impl<S> Ia<S> {
     fn partial(_: S) {}
     fn full(self) {}
 
     async fn crash(self) {
-        Self::partial(self.1);
+        Self::partial(self.0);
         Self::full(self); //~ ERROR use of moved value: `self`
     }
 }
diff --git a/src/test/ui/issues/issue-66958.stderr b/src/test/ui/async-await/issues/issue-66958-non-copy-infered-type-arg.stderr
similarity index 68%
rename from src/test/ui/issues/issue-66958.stderr
rename to src/test/ui/async-await/issues/issue-66958-non-copy-infered-type-arg.stderr
index 79a80168a5e59..9177b83dd48d7 100644
--- a/src/test/ui/issues/issue-66958.stderr
+++ b/src/test/ui/async-await/issues/issue-66958-non-copy-infered-type-arg.stderr
@@ -1,12 +1,12 @@
 error[E0382]: use of moved value: `self`
-  --> $DIR/issue-66958.rs:11:20
+  --> $DIR/issue-66958-non-copy-infered-type-arg.rs:11:20
    |
-LL |         Self::partial(self.1);
+LL |         Self::partial(self.0);
    |                       ------ value moved here
 LL |         Self::full(self);
    |                    ^^^^ value used here after partial move
    |
-   = note: move occurs because `self.1` has type `S`, which does not implement the `Copy` trait
+   = note: move occurs because `self.0` has type `S`, which does not implement the `Copy` trait
 
 error: aborting due to previous error