about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--src/librustc/ty/context.rs6
-rw-r--r--src/librustc_typeck/check/generator_interior.rs18
-rw-r--r--src/test/ui/async-await/issues/issue-64964.rs22
3 files changed, 37 insertions, 9 deletions
diff --git a/src/librustc/ty/context.rs b/src/librustc/ty/context.rs
index 5f1a17e4a95..42d45c5dfd3 100644
--- a/src/librustc/ty/context.rs
+++ b/src/librustc/ty/context.rs
@@ -317,6 +317,12 @@ pub struct GeneratorInteriorTypeCause<'tcx> {
     pub scope_span: Option<Span>,
 }
 
+BraceStructTypeFoldableImpl! {
+    impl<'tcx> TypeFoldable<'tcx> for GeneratorInteriorTypeCause<'tcx> {
+        ty, span, scope_span
+    }
+}
+
 #[derive(RustcEncodable, RustcDecodable, Debug)]
 pub struct TypeckTables<'tcx> {
     /// The HirId::owner all ItemLocalIds in this table are relative to.
diff --git a/src/librustc_typeck/check/generator_interior.rs b/src/librustc_typeck/check/generator_interior.rs
index 4608eb51df7..940537a5f48 100644
--- a/src/librustc_typeck/check/generator_interior.rs
+++ b/src/librustc_typeck/check/generator_interior.rs
@@ -123,13 +123,6 @@ pub fn resolve_interior<'a, 'tcx>(
     // Sort types by insertion order
     types.sort_by_key(|t| t.1);
 
-    // Store the generator types and spans into the tables for this generator.
-    let interior_types = types.iter().cloned().map(|t| t.0).collect::<Vec<_>>();
-    visitor.fcx.inh.tables.borrow_mut().generator_interior_types = interior_types;
-
-    // Extract type components
-    let type_list = fcx.tcx.mk_type_list(types.into_iter().map(|t| (t.0).ty));
-
     // The types in the generator interior contain lifetimes local to the generator itself,
     // which should not be exposed outside of the generator. Therefore, we replace these
     // lifetimes with existentially-bound lifetimes, which reflect the exact value of the
@@ -139,18 +132,25 @@ pub fn resolve_interior<'a, 'tcx>(
     // if a Sync generator contains an &'α T, we need to check whether &'α T: Sync),
     // so knowledge of the exact relationships between them isn't particularly important.
 
-    debug!("types in generator {:?}, span = {:?}", type_list, body.value.span);
+    debug!("types in generator {:?}, span = {:?}", types, body.value.span);
 
     // Replace all regions inside the generator interior with late bound regions
     // Note that each region slot in the types gets a new fresh late bound region,
     // which means that none of the regions inside relate to any other, even if
     // typeck had previously found constraints that would cause them to be related.
     let mut counter = 0;
-    let type_list = fcx.tcx.fold_regions(&type_list, &mut false, |_, current_depth| {
+    let types = fcx.tcx.fold_regions(&types, &mut false, |_, current_depth| {
         counter += 1;
         fcx.tcx.mk_region(ty::ReLateBound(current_depth, ty::BrAnon(counter)))
     });
 
+    // Store the generator types and spans into the tables for this generator.
+    let interior_types = types.iter().map(|t| t.0.clone()).collect::<Vec<_>>();
+    visitor.fcx.inh.tables.borrow_mut().generator_interior_types = interior_types;
+
+    // Extract type components
+    let type_list = fcx.tcx.mk_type_list(types.into_iter().map(|t| (t.0).ty));
+
     let witness = fcx.tcx.mk_generator_witness(ty::Binder::bind(type_list));
 
     debug!("types in generator after region replacement {:?}, span = {:?}",
diff --git a/src/test/ui/async-await/issues/issue-64964.rs b/src/test/ui/async-await/issues/issue-64964.rs
new file mode 100644
index 00000000000..11f6cb6af9c
--- /dev/null
+++ b/src/test/ui/async-await/issues/issue-64964.rs
@@ -0,0 +1,22 @@
+// check-pass
+// compile-flags: -Z query-dep-graph
+// edition:2018
+
+// Regression test for ICE related to `await`ing in a method + incr. comp. (#64964)
+
+struct Body;
+impl Body {
+    async fn next(&mut self) {
+        async {}.await
+    }
+}
+
+// Another reproduction: `await`ing with a variable from for-loop.
+
+async fn bar() {
+    for x in 0..10 {
+        async { Some(x) }.await.unwrap();
+    }
+}
+
+fn main() {}