Rollup merge of #64989 - sinkuu:fix_ice_64964, r=davidtwco

Fix ICE #64964

Fixes #64964, which is an ICE with `await`ing in a method + incr-comp.
This commit is contained in:
Mazdak Farrokhzad 2019-10-02 18:24:42 +02:00 committed by GitHub
commit 028ffd1366
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 37 additions and 9 deletions

View File

@ -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.

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,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 = {:?}",

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