skol -> placeholder

This commit is contained in:
Bastian Kauschke 2020-06-06 11:52:02 +02:00
parent 033013cab3
commit c4840db8fc
4 changed files with 34 additions and 35 deletions

View File

@ -290,7 +290,7 @@ pub(crate) enum UndoLog<'tcx> {
/// We added a GLB/LUB "combination variable".
AddCombination(CombineMapType, TwoRegions<'tcx>),
/// During skolemization, we sometimes purge entries from the undo
/// During freshening, we sometimes purge entries from the undo
/// log in a kind of minisnapshot (unlike other snapshots, this
/// purging actually takes place *on success*). In that case, we
/// replace the corresponding entry with `Noop` so as to avoid the
@ -489,7 +489,7 @@ pub fn var_origin(&self, vid: RegionVid) -> RegionVariableOrigin {
}
/// Removes all the edges to/from the placeholder regions that are
/// in `skols`. This is used after a higher-ranked operation
/// in `placeholders`. This is used after a higher-ranked operation
/// completes to remove all trace of the placeholder regions
/// created in that time.
pub fn pop_placeholders(&mut self, placeholders: &FxHashSet<ty::Region<'tcx>>) {

View File

@ -1754,27 +1754,26 @@ fn collect_predicates_for_types(
) -> Vec<PredicateObligation<'tcx>> {
// Because the types were potentially derived from
// higher-ranked obligations they may reference late-bound
// regions. For example, `for<'a> Foo<&'a int> : Copy` would
// yield a type like `for<'a> &'a int`. In general, we
// regions. For example, `for<'a> Foo<&'a i32> : Copy` would
// yield a type like `for<'a> &'a i32`. In general, we
// maintain the invariant that we never manipulate bound
// regions, so we have to process these bound regions somehow.
//
// The strategy is to:
//
// 1. Instantiate those regions to placeholder regions (e.g.,
// `for<'a> &'a int` becomes `&0 int`.
// 2. Produce something like `&'0 int : Copy`
// 3. Re-bind the regions back to `for<'a> &'a int : Copy`
// `for<'a> &'a int` becomes `&0 i32`.
// 2. Produce something like `&'0 i32 : Copy`
// 3. Re-bind the regions back to `for<'a> &'a i32 : Copy`
types
.skip_binder()
.skip_binder() // binder moved -\
.iter()
.flat_map(|ty| {
// binder moved -\
let ty: ty::Binder<Ty<'tcx>> = ty::Binder::bind(ty); // <----/
self.infcx.commit_unconditionally(|_| {
let (skol_ty, _) = self.infcx.replace_bound_vars_with_placeholders(&ty);
let (placeholder_ty, _) = self.infcx.replace_bound_vars_with_placeholders(&ty);
let Normalized { value: normalized_ty, mut obligations } =
ensure_sufficient_stack(|| {
project::normalize_with_depth(
@ -1782,10 +1781,10 @@ fn collect_predicates_for_types(
param_env,
cause.clone(),
recursion_depth,
&skol_ty,
&placeholder_ty,
)
});
let skol_obligation = predicate_for_trait_def(
let placeholder_obligation = predicate_for_trait_def(
self.tcx(),
param_env,
cause.clone(),
@ -1794,7 +1793,7 @@ fn collect_predicates_for_types(
normalized_ty,
&[],
);
obligations.push(skol_obligation);
obligations.push(placeholder_obligation);
obligations
})
})
@ -1844,9 +1843,9 @@ fn match_impl(
return Err(());
}
let (skol_obligation, placeholder_map) =
let (placeholder_obligation, placeholder_map) =
self.infcx().replace_bound_vars_with_placeholders(&obligation.predicate);
let skol_obligation_trait_ref = skol_obligation.trait_ref;
let placeholder_obligation_trait_ref = placeholder_obligation.trait_ref;
let impl_substs = self.infcx.fresh_substs_for_item(obligation.cause.span, impl_def_id);
@ -1865,14 +1864,14 @@ fn match_impl(
debug!(
"match_impl(impl_def_id={:?}, obligation={:?}, \
impl_trait_ref={:?}, skol_obligation_trait_ref={:?})",
impl_def_id, obligation, impl_trait_ref, skol_obligation_trait_ref
impl_trait_ref={:?}, placeholder_obligation_trait_ref={:?})",
impl_def_id, obligation, impl_trait_ref, placeholder_obligation_trait_ref
);
let InferOk { obligations, .. } = self
.infcx
.at(&obligation.cause, obligation.param_env)
.eq(skol_obligation_trait_ref, impl_trait_ref)
.eq(placeholder_obligation_trait_ref, impl_trait_ref)
.map_err(|e| debug!("match_impl: failed eq_trait_refs due to `{}`", e))?;
nested_obligations.extend(obligations);

View File

@ -130,7 +130,7 @@ pub(super) fn specializes(tcx: TyCtxt<'_>, (impl1_def_id, impl2_def_id): (DefId,
// We determine whether there's a subset relationship by:
//
// - skolemizing impl1,
// - replacing bound vars with placeholders in impl1,
// - assuming the where clauses for impl1,
// - instantiating impl2 with fresh inference variables,
// - unifying,

View File

@ -91,14 +91,14 @@ fn compare_predicate_entailment<'tcx>(
// This code is best explained by example. Consider a trait:
//
// trait Trait<'t,T> {
// fn method<'a,M>(t: &'t T, m: &'a M) -> Self;
// trait Trait<'t, T> {
// fn method<'a, M>(t: &'t T, m: &'a M) -> Self;
// }
//
// And an impl:
//
// impl<'i, 'j, U> Trait<'j, &'i U> for Foo {
// fn method<'b,N>(t: &'j &'i U, m: &'b N) -> Foo;
// fn method<'b, N>(t: &'j &'i U, m: &'b N) -> Foo;
// }
//
// We wish to decide if those two method types are compatible.
@ -116,9 +116,9 @@ fn compare_predicate_entailment<'tcx>(
// regions (Note: but only early-bound regions, i.e., those
// declared on the impl or used in type parameter bounds).
//
// impl_to_skol_substs = {'i => 'i0, U => U0, N => N0 }
// impl_to_placeholder_substs = {'i => 'i0, U => U0, N => N0 }
//
// Now we can apply skol_substs to the type of the impl method
// Now we can apply placeholder_substs to the type of the impl method
// to yield a new function type in terms of our fresh, placeholder
// types:
//
@ -127,11 +127,11 @@ fn compare_predicate_entailment<'tcx>(
// We now want to extract and substitute the type of the *trait*
// method and compare it. To do so, we must create a compound
// substitution by combining trait_to_impl_substs and
// impl_to_skol_substs, and also adding a mapping for the method
// impl_to_placeholder_substs, and also adding a mapping for the method
// type parameters. We extend the mapping to also include
// the method parameters.
//
// trait_to_skol_substs = { T => &'i0 U0, Self => Foo, M => N0 }
// trait_to_placeholder_substs = { T => &'i0 U0, Self => Foo, M => N0 }
//
// Applying this to the trait method type yields:
//
@ -145,20 +145,20 @@ fn compare_predicate_entailment<'tcx>(
// satisfied by the implementation's method.
//
// We do this by creating a parameter environment which contains a
// substitution corresponding to impl_to_skol_substs. We then build
// trait_to_skol_substs and use it to convert the predicates contained
// substitution corresponding to impl_to_placeholder_substs. We then build
// trait_to_placeholder_substs and use it to convert the predicates contained
// in the trait_m.generics to the placeholder form.
//
// Finally we register each of these predicates as an obligation in
// a fresh FulfillmentCtxt, and invoke select_all_or_error.
// Create mapping from impl to placeholder.
let impl_to_skol_substs = InternalSubsts::identity_for_item(tcx, impl_m.def_id);
let impl_to_placeholder_substs = InternalSubsts::identity_for_item(tcx, impl_m.def_id);
// Create mapping from trait to placeholder.
let trait_to_skol_substs =
impl_to_skol_substs.rebase_onto(tcx, impl_m.container.id(), trait_to_impl_substs);
debug!("compare_impl_method: trait_to_skol_substs={:?}", trait_to_skol_substs);
let trait_to_placeholder_substs =
impl_to_placeholder_substs.rebase_onto(tcx, impl_m.container.id(), trait_to_impl_substs);
debug!("compare_impl_method: trait_to_placeholder_substs={:?}", trait_to_placeholder_substs);
let impl_m_generics = tcx.generics_of(impl_m.def_id);
let trait_m_generics = tcx.generics_of(trait_m.def_id);
@ -194,7 +194,7 @@ fn compare_predicate_entailment<'tcx>(
// if all constraints hold.
hybrid_preds
.predicates
.extend(trait_m_predicates.instantiate_own(tcx, trait_to_skol_substs).predicates);
.extend(trait_m_predicates.instantiate_own(tcx, trait_to_placeholder_substs).predicates);
// Construct trait parameter environment and then shift it into the placeholder viewpoint.
// The key step here is to update the caller_bounds's predicates to be
@ -220,7 +220,7 @@ fn compare_predicate_entailment<'tcx>(
let mut selcx = traits::SelectionContext::new(&infcx);
let impl_m_own_bounds = impl_m_predicates.instantiate_own(tcx, impl_to_skol_substs);
let impl_m_own_bounds = impl_m_predicates.instantiate_own(tcx, impl_to_placeholder_substs);
let (impl_m_own_bounds, _) = infcx.replace_bound_vars_with_fresh_vars(
impl_m_span,
infer::HigherRankedType,
@ -261,7 +261,7 @@ fn compare_predicate_entailment<'tcx>(
debug!("compare_impl_method: impl_fty={:?}", impl_fty);
let trait_sig = tcx.liberate_late_bound_regions(impl_m.def_id, &tcx.fn_sig(trait_m.def_id));
let trait_sig = trait_sig.subst(tcx, trait_to_skol_substs);
let trait_sig = trait_sig.subst(tcx, trait_to_placeholder_substs);
let trait_sig =
inh.normalize_associated_types_in(impl_m_span, impl_m_hir_id, param_env, &trait_sig);
let trait_fty = tcx.mk_fn_ptr(ty::Binder::bind(trait_sig));