Instantiate all bound vars universally

This commit is contained in:
scalexm 2018-11-03 14:52:37 +01:00
parent cdb96be11e
commit 6bf17d249b
4 changed files with 36 additions and 25 deletions

View file

@ -53,7 +53,7 @@ impl<'a, 'gcx, 'tcx> CombineFields<'a, 'gcx, 'tcx> {
// First, we instantiate each bound region in the supertype with a
// fresh placeholder region.
let (b_prime, placeholder_map) =
self.infcx.replace_late_bound_regions_with_placeholders(b);
self.infcx.replace_bound_vars_with_placeholders(b);
// Next, we instantiate each bound region in the subtype
// with a fresh region variable. These region variables --
@ -115,7 +115,7 @@ impl<'a, 'gcx, 'tcx> CombineFields<'a, 'gcx, 'tcx> {
// First, we instantiate each bound region in the matcher
// with a placeholder region.
let ((a_match, a_value), placeholder_map) =
self.infcx.replace_late_bound_regions_with_placeholders(a_pair);
self.infcx.replace_bound_vars_with_placeholders(a_pair);
debug!("higher_ranked_match: a_match={:?}", a_match);
debug!("higher_ranked_match: placeholder_map={:?}", placeholder_map);
@ -314,10 +314,10 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
region_vars
}
/// Replace all regions bound by `binder` with placeholder regions and
/// return a map indicating which bound-region was replaced with what
/// placeholder region. This is the first step of checking subtyping
/// when higher-ranked things are involved.
/// Replace all regions (resp. types) bound by `binder` with placeholder
/// regions (resp. types) and return a map indicating which bound-region
/// was replaced with what placeholder region. This is the first step of
/// checking subtyping when higher-ranked things are involved.
///
/// **Important:** you must call this function from within a snapshot.
/// Moreover, before committing the snapshot, you must eventually call
@ -330,26 +330,37 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
/// the [rustc guide].
///
/// [rustc guide]: https://rust-lang-nursery.github.io/rustc-guide/traits/hrtb.html
pub fn replace_late_bound_regions_with_placeholders<T>(
pub fn replace_bound_vars_with_placeholders<T>(
&self,
binder: &ty::Binder<T>,
binder: &ty::Binder<T>
) -> (T, PlaceholderMap<'tcx>)
where
T : TypeFoldable<'tcx>,
T: TypeFoldable<'tcx>
{
let next_universe = self.create_next_universe();
let (result, map) = self.tcx.replace_late_bound_regions(binder, |br| {
let fld_r = |br| {
self.tcx.mk_region(ty::RePlaceholder(ty::PlaceholderRegion {
universe: next_universe,
name: br,
}))
});
};
debug!("replace_late_bound_regions_with_placeholders(binder={:?}, result={:?}, map={:?})",
binder,
result,
map);
let fld_t = |bound_ty: ty::BoundTy| {
self.tcx.mk_ty(ty::Placeholder(ty::PlaceholderType {
universe: next_universe,
name: bound_ty.var,
}))
};
let (result, map) = self.tcx.replace_bound_vars(binder, fld_r, fld_t);
debug!(
"replace_bound_vars_with_placeholders(binder={:?}, result={:?}, map={:?})",
binder,
result,
map
);
(result, map)
}
@ -530,7 +541,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
/// Pops the placeholder regions found in `placeholder_map` from the region
/// inference context. Whenever you create placeholder regions via
/// `replace_late_bound_regions_with_placeholders`, they must be popped before you
/// `replace_bound_vars_with_placeholders`, they must be popped before you
/// commit the enclosing snapshot (if you do not commit, e.g. within a
/// probe or as a result of an error, then this is not necessary, as
/// popping happens as part of the rollback).

View file

@ -227,7 +227,7 @@ pub struct InferCtxt<'a, 'gcx: 'a + 'tcx, 'tcx: 'a> {
universe: Cell<ty::UniverseIndex>,
}
/// A map returned by `replace_late_bound_regions_with_placeholders()`
/// A map returned by `replace_bound_vars_with_placeholders()`
/// indicating the placeholder region that each late-bound region was
/// replaced with.
pub type PlaceholderMap<'tcx> = BTreeMap<ty::BoundRegion, ty::Region<'tcx>>;
@ -935,7 +935,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
b,
},
placeholder_map,
) = self.replace_late_bound_regions_with_placeholders(predicate);
) = self.replace_bound_vars_with_placeholders(predicate);
let cause_span = cause.span;
let ok = self.at(cause, param_env).sub_exp(a_is_expected, a, b)?;
@ -952,7 +952,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
) -> UnitResult<'tcx> {
self.commit_if_ok(|snapshot| {
let (ty::OutlivesPredicate(r_a, r_b), placeholder_map) =
self.replace_late_bound_regions_with_placeholders(predicate);
self.replace_bound_vars_with_placeholders(predicate);
let origin = SubregionOrigin::from_obligation_cause(cause, || {
RelateRegionParamBound(cause.span)
});

View file

@ -204,7 +204,7 @@ pub fn poly_project_and_unify_type<'cx, 'gcx, 'tcx>(
let infcx = selcx.infcx();
infcx.commit_if_ok(|snapshot| {
let (placeholder_predicate, placeholder_map) =
infcx.replace_late_bound_regions_with_placeholders(&obligation.predicate);
infcx.replace_bound_vars_with_placeholders(&obligation.predicate);
let skol_obligation = obligation.with(placeholder_predicate);
let r = match project_and_unify_type(selcx, &skol_obligation) {

View file

@ -1726,7 +1726,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
let poly_trait_predicate = self.infcx()
.resolve_type_vars_if_possible(&obligation.predicate);
let (skol_trait_predicate, placeholder_map) = self.infcx()
.replace_late_bound_regions_with_placeholders(&poly_trait_predicate);
.replace_bound_vars_with_placeholders(&poly_trait_predicate);
debug!(
"match_projection_obligation_against_definition_bounds: \
skol_trait_predicate={:?} placeholder_map={:?}",
@ -2685,7 +2685,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
self.in_snapshot(|this, snapshot| {
let (skol_ty, placeholder_map) = this.infcx()
.replace_late_bound_regions_with_placeholders(&ty);
.replace_bound_vars_with_placeholders(&ty);
let Normalized {
value: normalized_ty,
mut obligations,
@ -2919,7 +2919,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
let trait_obligations: Vec<PredicateObligation<'_>> = self.in_snapshot(|this, snapshot| {
let poly_trait_ref = obligation.predicate.to_poly_trait_ref();
let (trait_ref, placeholder_map) = this.infcx()
.replace_late_bound_regions_with_placeholders(&poly_trait_ref);
.replace_bound_vars_with_placeholders(&poly_trait_ref);
let cause = obligation.derived_cause(ImplDerivedObligation);
this.impl_or_trait_obligations(
cause,
@ -3122,7 +3122,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
self.in_snapshot(|this, snapshot| {
let (predicate, placeholder_map) = this.infcx()
.replace_late_bound_regions_with_placeholders(&obligation.predicate);
.replace_bound_vars_with_placeholders(&obligation.predicate);
let trait_ref = predicate.trait_ref;
let trait_def_id = trait_ref.def_id;
let substs = trait_ref.substs;
@ -3585,7 +3585,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
}
let (skol_obligation, placeholder_map) = self.infcx()
.replace_late_bound_regions_with_placeholders(&obligation.predicate);
.replace_bound_vars_with_placeholders(&obligation.predicate);
let skol_obligation_trait_ref = skol_obligation.trait_ref;
let impl_substs = self.infcx