Skip to content

Commit

Permalink
Auto merge of #68672 - jonas-schievink:dedup-witness, r=Zoxc
Browse files Browse the repository at this point in the history
Deduplicate types in the generator witness

For the `await-call-tree` benchmark this often reduces the types inside the witness from 12 to 2.
  • Loading branch information
bors committed Feb 2, 2020
2 parents e5b150e + 791123d commit bc4a339
Show file tree
Hide file tree
Showing 3 changed files with 30 additions and 24 deletions.
48 changes: 27 additions & 21 deletions src/librustc_typeck/check/generator_interior.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ use super::FnCtxt;
use rustc::hir::map::Map;
use rustc::middle::region::{self, YieldData};
use rustc::ty::{self, Ty};
use rustc_data_structures::fx::FxHashMap;
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
use rustc_hir as hir;
use rustc_hir::def::{CtorKind, DefKind, Res};
use rustc_hir::def_id::DefId;
Expand Down Expand Up @@ -160,33 +160,39 @@ pub fn resolve_interior<'a, 'tcx>(

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 fold_types: Vec<_> = types.iter().map(|(t, _)| t.ty).collect();
let folded_types = fcx.tcx.fold_regions(&fold_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 types = types
let mut captured_tys = FxHashSet::default();
let type_causes: Vec<_> = types
.into_iter()
.zip(&folded_types)
.map(|((mut interior_cause, _), ty)| {
interior_cause.ty = ty;
interior_cause
.filter_map(|(mut cause, _)| {
// Erase regions and canonicalize late-bound regions to deduplicate as many types as we
// can.
let erased = fcx.tcx.erase_regions(&cause.ty);
if captured_tys.insert(erased) {
// 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 folded = fcx.tcx.fold_regions(&erased, &mut false, |_, current_depth| {
counter += 1;
fcx.tcx.mk_region(ty::ReLateBound(current_depth, ty::BrAnon(counter)))
});

cause.ty = folded;
Some(cause)
} else {
None
}
})
.collect();
visitor.fcx.inh.tables.borrow_mut().generator_interior_types = types;

// Extract type components
let type_list = fcx.tcx.mk_type_list(folded_types.iter());

// Extract type components to build the witness type.
let type_list = fcx.tcx.mk_type_list(type_causes.iter().map(|cause| cause.ty));
let witness = fcx.tcx.mk_generator_witness(ty::Binder::bind(type_list));

// Store the generator types and spans into the tables for this generator.
visitor.fcx.inh.tables.borrow_mut().generator_interior_types = type_causes;

debug!(
"types in generator after region replacement {:?}, span = {:?}",
witness, body.value.span
Expand Down
2 changes: 1 addition & 1 deletion src/test/ui/generator/not-send-sync.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ LL | fn assert_sync<T: Sync>(_: T) {}
LL | assert_sync(|| {
| ^^^^^^^^^^^ future returned by `main` is not `Sync`
|
= help: within `[generator@$DIR/not-send-sync.rs:9:17: 13:6 {std::cell::Cell<i32>, (), ()}]`, the trait `std::marker::Sync` is not implemented for `std::cell::Cell<i32>`
= help: within `[generator@$DIR/not-send-sync.rs:9:17: 13:6 {std::cell::Cell<i32>, ()}]`, the trait `std::marker::Sync` is not implemented for `std::cell::Cell<i32>`
note: future is not `Sync` as this value is used across an yield
--> $DIR/not-send-sync.rs:12:9
|
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ error[E0720]: opaque type expands to a recursive type
LL | fn generator_capture() -> impl Sized {
| ^^^^^^^^^^ expands to a recursive type
|
= note: expanded type is `[generator@$DIR/recursive-impl-trait-type-indirect.rs:50:5: 50:26 x:impl Sized {(), ()}]`
= note: expanded type is `[generator@$DIR/recursive-impl-trait-type-indirect.rs:50:5: 50:26 x:impl Sized {()}]`

error[E0720]: opaque type expands to a recursive type
--> $DIR/recursive-impl-trait-type-indirect.rs:53:26
Expand All @@ -92,7 +92,7 @@ error[E0720]: opaque type expands to a recursive type
LL | fn generator_hold() -> impl Sized {
| ^^^^^^^^^^ expands to a recursive type
|
= note: expanded type is `[generator@$DIR/recursive-impl-trait-type-indirect.rs:58:5: 62:6 {impl Sized, (), ()}]`
= note: expanded type is `[generator@$DIR/recursive-impl-trait-type-indirect.rs:58:5: 62:6 {impl Sized, ()}]`

error[E0720]: opaque type expands to a recursive type
--> $DIR/recursive-impl-trait-type-indirect.rs:69:26
Expand Down

0 comments on commit bc4a339

Please sign in to comment.