Compute generator saved locals on MIR.
This commit is contained in:
parent
400cb9aa41
commit
60e04d1e8c
18 changed files with 392 additions and 19 deletions
|
@ -13,7 +13,7 @@ use rustc_infer::infer::InferOk;
|
|||
use rustc_infer::infer::LateBoundRegionConversionTime::HigherRankedType;
|
||||
use rustc_middle::ty::{
|
||||
self, Binder, GenericArg, GenericArgKind, GenericParamDefKind, InternalSubsts, SubstsRef,
|
||||
ToPolyTraitRef, ToPredicate, TraitRef, Ty, TyCtxt,
|
||||
ToPolyTraitRef, ToPredicate, TraitRef, Ty, TyCtxt, TypeVisitable,
|
||||
};
|
||||
use rustc_session::config::TraitSolver;
|
||||
use rustc_span::def_id::DefId;
|
||||
|
@ -1285,8 +1285,13 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
|||
ty::GeneratorWitness(tys) => {
|
||||
stack.extend(tcx.erase_late_bound_regions(tys).to_vec());
|
||||
}
|
||||
ty::GeneratorWitnessMIR(..) => {
|
||||
todo!()
|
||||
ty::GeneratorWitnessMIR(def_id, substs) => {
|
||||
let tcx = self.tcx();
|
||||
stack.extend(tcx.generator_hidden_types(def_id).map(|bty| {
|
||||
let ty = bty.subst(tcx, substs);
|
||||
debug_assert!(!ty.has_late_bound_regions());
|
||||
ty
|
||||
}))
|
||||
}
|
||||
|
||||
// If we have a projection type, make sure to normalize it so we replace it
|
||||
|
|
|
@ -2183,8 +2183,14 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
|||
Where(ty::Binder::bind_with_vars(witness_tys.to_vec(), all_vars))
|
||||
}
|
||||
|
||||
ty::GeneratorWitnessMIR(..) => {
|
||||
todo!()
|
||||
ty::GeneratorWitnessMIR(def_id, ref substs) => {
|
||||
let hidden_types = bind_generator_hidden_types_above(
|
||||
self.infcx,
|
||||
def_id,
|
||||
substs,
|
||||
obligation.predicate.bound_vars(),
|
||||
);
|
||||
Where(hidden_types)
|
||||
}
|
||||
|
||||
ty::Closure(_, substs) => {
|
||||
|
@ -2284,8 +2290,8 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
|||
types.map_bound(|types| types.to_vec())
|
||||
}
|
||||
|
||||
ty::GeneratorWitnessMIR(..) => {
|
||||
todo!()
|
||||
ty::GeneratorWitnessMIR(def_id, ref substs) => {
|
||||
bind_generator_hidden_types_above(self.infcx, def_id, substs, t.bound_vars())
|
||||
}
|
||||
|
||||
// For `PhantomData<T>`, we pass `T`.
|
||||
|
@ -2930,3 +2936,56 @@ pub enum ProjectionMatchesProjection {
|
|||
Ambiguous,
|
||||
No,
|
||||
}
|
||||
|
||||
/// 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.
|
||||
#[instrument(level = "trace", skip(infcx), ret)]
|
||||
fn bind_generator_hidden_types_above<'tcx>(
|
||||
infcx: &InferCtxt<'tcx>,
|
||||
def_id: DefId,
|
||||
substs: ty::SubstsRef<'tcx>,
|
||||
bound_vars: &ty::List<ty::BoundVariableKind>,
|
||||
) -> ty::Binder<'tcx, Vec<Ty<'tcx>>> {
|
||||
let tcx = infcx.tcx;
|
||||
let mut seen_tys = FxHashSet::default();
|
||||
|
||||
let considering_regions = infcx.considering_regions;
|
||||
|
||||
let num_bound_variables = bound_vars.len() as u32;
|
||||
let mut counter = num_bound_variables;
|
||||
|
||||
let hidden_types: Vec<_> = tcx
|
||||
.generator_hidden_types(def_id)
|
||||
// Deduplicate tys to avoid repeated work.
|
||||
.filter(|bty| seen_tys.insert(*bty))
|
||||
.map(|bty| {
|
||||
let mut ty = bty.subst(tcx, substs);
|
||||
|
||||
// Only remap erased regions if we use them.
|
||||
if considering_regions {
|
||||
ty = tcx.fold_regions(ty, |mut r, current_depth| {
|
||||
if let ty::ReErased = r.kind() {
|
||||
let br = ty::BoundRegion {
|
||||
var: ty::BoundVar::from_u32(counter),
|
||||
kind: ty::BrAnon(counter, None),
|
||||
};
|
||||
counter += 1;
|
||||
r = tcx.mk_region(ty::ReLateBound(current_depth, br));
|
||||
}
|
||||
r
|
||||
})
|
||||
}
|
||||
|
||||
ty
|
||||
})
|
||||
.collect();
|
||||
if considering_regions {
|
||||
debug_assert!(!hidden_types.has_erased_regions());
|
||||
}
|
||||
let bound_vars = tcx.mk_bound_variable_kinds(bound_vars.iter().chain(
|
||||
(num_bound_variables..counter).map(|i| ty::BoundVariableKind::Region(ty::BrAnon(i, None))),
|
||||
));
|
||||
ty::Binder::bind_with_vars(hidden_types, bound_vars)
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue