1
Fork 0

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". /// We added a GLB/LUB "combination variable".
AddCombination(CombineMapType, TwoRegions<'tcx>), 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 /// log in a kind of minisnapshot (unlike other snapshots, this
/// purging actually takes place *on success*). In that case, we /// purging actually takes place *on success*). In that case, we
/// replace the corresponding entry with `Noop` so as to avoid the /// replace the corresponding entry with `Noop` so as to avoid the
@ -489,7 +489,7 @@ impl<'tcx> RegionConstraintCollector<'_, 'tcx> {
} }
/// Removes all the edges to/from the placeholder regions that are /// 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 /// completes to remove all trace of the placeholder regions
/// created in that time. /// created in that time.
pub fn pop_placeholders(&mut self, placeholders: &FxHashSet<ty::Region<'tcx>>) { pub fn pop_placeholders(&mut self, placeholders: &FxHashSet<ty::Region<'tcx>>) {

View file

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

View file

@ -91,14 +91,14 @@ fn compare_predicate_entailment<'tcx>(
// This code is best explained by example. Consider a trait: // This code is best explained by example. Consider a trait:
// //
// trait Trait<'t,T> { // trait Trait<'t, T> {
// fn method<'a,M>(t: &'t T, m: &'a M) -> Self; // fn method<'a, M>(t: &'t T, m: &'a M) -> Self;
// } // }
// //
// And an impl: // And an impl:
// //
// impl<'i, 'j, U> Trait<'j, &'i U> for Foo { // 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. // 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 // regions (Note: but only early-bound regions, i.e., those
// declared on the impl or used in type parameter bounds). // 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 // to yield a new function type in terms of our fresh, placeholder
// types: // types:
// //
@ -127,11 +127,11 @@ fn compare_predicate_entailment<'tcx>(
// We now want to extract and substitute the type of the *trait* // We now want to extract and substitute the type of the *trait*
// method and compare it. To do so, we must create a compound // method and compare it. To do so, we must create a compound
// substitution by combining trait_to_impl_substs and // 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 // type parameters. We extend the mapping to also include
// the method parameters. // 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: // Applying this to the trait method type yields:
// //
@ -145,20 +145,20 @@ fn compare_predicate_entailment<'tcx>(
// satisfied by the implementation's method. // satisfied by the implementation's method.
// //
// We do this by creating a parameter environment which contains a // We do this by creating a parameter environment which contains a
// substitution corresponding to impl_to_skol_substs. We then build // substitution corresponding to impl_to_placeholder_substs. We then build
// trait_to_skol_substs and use it to convert the predicates contained // trait_to_placeholder_substs and use it to convert the predicates contained
// in the trait_m.generics to the placeholder form. // in the trait_m.generics to the placeholder form.
// //
// Finally we register each of these predicates as an obligation in // Finally we register each of these predicates as an obligation in
// a fresh FulfillmentCtxt, and invoke select_all_or_error. // a fresh FulfillmentCtxt, and invoke select_all_or_error.
// Create mapping from impl to placeholder. // 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. // Create mapping from trait to placeholder.
let trait_to_skol_substs = let trait_to_placeholder_substs =
impl_to_skol_substs.rebase_onto(tcx, impl_m.container.id(), trait_to_impl_substs); impl_to_placeholder_substs.rebase_onto(tcx, impl_m.container.id(), trait_to_impl_substs);
debug!("compare_impl_method: trait_to_skol_substs={:?}", trait_to_skol_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 impl_m_generics = tcx.generics_of(impl_m.def_id);
let trait_m_generics = tcx.generics_of(trait_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. // if all constraints hold.
hybrid_preds hybrid_preds
.predicates .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. // 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 // 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 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( let (impl_m_own_bounds, _) = infcx.replace_bound_vars_with_fresh_vars(
impl_m_span, impl_m_span,
infer::HigherRankedType, infer::HigherRankedType,
@ -261,7 +261,7 @@ fn compare_predicate_entailment<'tcx>(
debug!("compare_impl_method: impl_fty={:?}", impl_fty); 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 = 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 = let trait_sig =
inh.normalize_associated_types_in(impl_m_span, impl_m_hir_id, param_env, &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)); let trait_fty = tcx.mk_fn_ptr(ty::Binder::bind(trait_sig));