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 // First, we instantiate each bound region in the supertype with a
// fresh placeholder region. // fresh placeholder region.
let (b_prime, placeholder_map) = 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 // Next, we instantiate each bound region in the subtype
// with a fresh region variable. These region variables -- // 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 // First, we instantiate each bound region in the matcher
// with a placeholder region. // with a placeholder region.
let ((a_match, a_value), placeholder_map) = 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: a_match={:?}", a_match);
debug!("higher_ranked_match: placeholder_map={:?}", placeholder_map); debug!("higher_ranked_match: placeholder_map={:?}", placeholder_map);
@ -314,10 +314,10 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
region_vars region_vars
} }
/// Replace all regions bound by `binder` with placeholder regions and /// Replace all regions (resp. types) bound by `binder` with placeholder
/// return a map indicating which bound-region was replaced with what /// regions (resp. types) and return a map indicating which bound-region
/// placeholder region. This is the first step of checking subtyping /// was replaced with what placeholder region. This is the first step of
/// when higher-ranked things are involved. /// checking subtyping when higher-ranked things are involved.
/// ///
/// **Important:** you must call this function from within a snapshot. /// **Important:** you must call this function from within a snapshot.
/// Moreover, before committing the snapshot, you must eventually call /// Moreover, before committing the snapshot, you must eventually call
@ -330,26 +330,37 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
/// the [rustc guide]. /// the [rustc guide].
/// ///
/// [rustc guide]: https://rust-lang-nursery.github.io/rustc-guide/traits/hrtb.html /// [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, &self,
binder: &ty::Binder<T>, binder: &ty::Binder<T>
) -> (T, PlaceholderMap<'tcx>) ) -> (T, PlaceholderMap<'tcx>)
where where
T : TypeFoldable<'tcx>, T: TypeFoldable<'tcx>
{ {
let next_universe = self.create_next_universe(); 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 { self.tcx.mk_region(ty::RePlaceholder(ty::PlaceholderRegion {
universe: next_universe, universe: next_universe,
name: br, name: br,
})) }))
}); };
debug!("replace_late_bound_regions_with_placeholders(binder={:?}, result={:?}, map={:?})", let fld_t = |bound_ty: ty::BoundTy| {
binder, self.tcx.mk_ty(ty::Placeholder(ty::PlaceholderType {
result, universe: next_universe,
map); 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) (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 /// Pops the placeholder regions found in `placeholder_map` from the region
/// inference context. Whenever you create placeholder regions via /// 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 /// 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 /// probe or as a result of an error, then this is not necessary, as
/// popping happens as part of the rollback). /// 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>, 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 /// indicating the placeholder region that each late-bound region was
/// replaced with. /// replaced with.
pub type PlaceholderMap<'tcx> = BTreeMap<ty::BoundRegion, ty::Region<'tcx>>; pub type PlaceholderMap<'tcx> = BTreeMap<ty::BoundRegion, ty::Region<'tcx>>;
@ -935,7 +935,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
b, b,
}, },
placeholder_map, placeholder_map,
) = self.replace_late_bound_regions_with_placeholders(predicate); ) = self.replace_bound_vars_with_placeholders(predicate);
let cause_span = cause.span; let cause_span = cause.span;
let ok = self.at(cause, param_env).sub_exp(a_is_expected, a, b)?; 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> { ) -> UnitResult<'tcx> {
self.commit_if_ok(|snapshot| { self.commit_if_ok(|snapshot| {
let (ty::OutlivesPredicate(r_a, r_b), placeholder_map) = 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, || { let origin = SubregionOrigin::from_obligation_cause(cause, || {
RelateRegionParamBound(cause.span) RelateRegionParamBound(cause.span)
}); });

View file

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