Fix async/await ICE #64964

This commit is contained in:
Shotaro Yamada 2019-10-02 15:34:31 +09:00
parent 7130fc54e0
commit 8e67180c52
3 changed files with 41 additions and 9 deletions

View file

@ -316,6 +316,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.

View file

@ -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,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::<Vec<_>>(),
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 = {:?}",

View file

@ -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() {}