Instantiate all bound vars universally
This commit is contained in:
parent
cdb96be11e
commit
6bf17d249b
4 changed files with 36 additions and 25 deletions
|
@ -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).
|
||||||
|
|
|
@ -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)
|
||||||
});
|
});
|
||||||
|
|
|
@ -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) {
|
||||||
|
|
|
@ -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
|
||||||
|
|
Loading…
Add table
Reference in a new issue