diff --git a/src/librustc/ty/context.rs b/src/librustc/ty/context.rs index 87b9917f340da..c58811cea190c 100644 --- a/src/librustc/ty/context.rs +++ b/src/librustc/ty/context.rs @@ -316,6 +316,12 @@ pub struct GeneratorInteriorTypeCause<'tcx> { pub scope_span: Option, } +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 4608eb51df74e..c947d552a01a7 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::>(); - 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,29 @@ 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.iter().map(|t| (t.0).ty).collect::>(), + 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::>(); + 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 0000000000000..af20bc5bf9a2b --- /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. (#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() {}