From c4840db8fcc11a2b3bfc352bc60dacd87232bd4e Mon Sep 17 00:00:00 2001 From: Bastian Kauschke Date: Sat, 6 Jun 2020 11:52:02 +0200 Subject: [PATCH 1/3] skol -> placeholder --- .../infer/region_constraints/mod.rs | 4 +-- .../traits/select/mod.rs | 31 +++++++++--------- .../traits/specialize/mod.rs | 2 +- src/librustc_typeck/check/compare_method.rs | 32 +++++++++---------- 4 files changed, 34 insertions(+), 35 deletions(-) diff --git a/src/librustc_infer/infer/region_constraints/mod.rs b/src/librustc_infer/infer/region_constraints/mod.rs index 90d61a78f9b99..42a6a6ff40afd 100644 --- a/src/librustc_infer/infer/region_constraints/mod.rs +++ b/src/librustc_infer/infer/region_constraints/mod.rs @@ -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 @@ impl<'tcx> RegionConstraintCollector<'_, 'tcx> { } /// 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>) { diff --git a/src/librustc_trait_selection/traits/select/mod.rs b/src/librustc_trait_selection/traits/select/mod.rs index 3fd566eab437e..c3b1079fb1284 100644 --- a/src/librustc_trait_selection/traits/select/mod.rs +++ b/src/librustc_trait_selection/traits/select/mod.rs @@ -1754,27 +1754,26 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { ) -> Vec> { // 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::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 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { 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 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { normalized_ty, &[], ); - obligations.push(skol_obligation); + obligations.push(placeholder_obligation); obligations }) }) @@ -1844,9 +1843,9 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { 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 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { 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); diff --git a/src/librustc_trait_selection/traits/specialize/mod.rs b/src/librustc_trait_selection/traits/specialize/mod.rs index 2b596be954267..42901102c1076 100644 --- a/src/librustc_trait_selection/traits/specialize/mod.rs +++ b/src/librustc_trait_selection/traits/specialize/mod.rs @@ -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, diff --git a/src/librustc_typeck/check/compare_method.rs b/src/librustc_typeck/check/compare_method.rs index b39cfcb377595..1d47e64630c18 100644 --- a/src/librustc_typeck/check/compare_method.rs +++ b/src/librustc_typeck/check/compare_method.rs @@ -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)); From a24c8977eeef97a445336af597fd628de65524cb Mon Sep 17 00:00:00 2001 From: Bastian Kauschke Date: Sat, 6 Jun 2020 12:05:37 +0200 Subject: [PATCH 2/3] int -> i32 --- src/librustc_infer/traits/mod.rs | 4 +-- src/librustc_infer/traits/util.rs | 4 +-- src/librustc_middle/traits/mod.rs | 28 ++++++++++--------- src/librustc_middle/ty/subst.rs | 12 ++++---- src/librustc_middle/ty/walk.rs | 6 ++-- .../traits/project.rs | 2 +- .../traits/query/normalize.rs | 2 +- .../traits/select/confirmation.rs | 8 +++--- .../traits/select/mod.rs | 2 +- src/librustc_typeck/astconv.rs | 4 +-- src/librustc_typeck/check/method/probe.rs | 2 +- src/librustc_typeck/check/pat.rs | 14 +++++----- 12 files changed, 45 insertions(+), 43 deletions(-) diff --git a/src/librustc_infer/traits/mod.rs b/src/librustc_infer/traits/mod.rs index a15ac819be966..47555aca9f3fb 100644 --- a/src/librustc_infer/traits/mod.rs +++ b/src/librustc_infer/traits/mod.rs @@ -29,10 +29,10 @@ crate use self::util::elaborate_predicates; pub use rustc_middle::traits::*; -/// An `Obligation` represents some trait reference (e.g., `int: Eq`) for +/// An `Obligation` represents some trait reference (e.g., `i32: Eq`) for /// which the "impl_source" must be found. The process of finding a "impl_source" is /// called "resolving" the `Obligation`. This process consists of -/// either identifying an `impl` (e.g., `impl Eq for int`) that +/// either identifying an `impl` (e.g., `impl Eq for i32`) that /// satisfies the obligation, or else finding a bound that is in /// scope. The eventual result is usually a `Selection` (defined below). #[derive(Clone, PartialEq, Eq, Hash)] diff --git a/src/librustc_infer/traits/util.rs b/src/librustc_infer/traits/util.rs index ee9846c64b67c..4ae7e417a8f67 100644 --- a/src/librustc_infer/traits/util.rs +++ b/src/librustc_infer/traits/util.rs @@ -63,11 +63,11 @@ impl PredicateSet<'tcx> { fn insert(&mut self, pred: ty::Predicate<'tcx>) -> bool { // We have to be careful here because we want // - // for<'a> Foo<&'a int> + // for<'a> Foo<&'a i32> // // and // - // for<'b> Foo<&'b int> + // for<'b> Foo<&'b i32> // // to be considered equivalent. So normalize all late-bound // regions before we throw things into the underlying set. diff --git a/src/librustc_middle/traits/mod.rs b/src/librustc_middle/traits/mod.rs index 17ea84836bf0a..f650240a41c63 100644 --- a/src/librustc_middle/traits/mod.rs +++ b/src/librustc_middle/traits/mod.rs @@ -393,23 +393,25 @@ pub type SelectionResult<'tcx, T> = Result, SelectionError<'tcx>>; /// ``` /// impl Clone for Option { ... } // Impl_1 /// impl Clone for Box { ... } // Impl_2 -/// impl Clone for int { ... } // Impl_3 +/// impl Clone for i32 { ... } // Impl_3 /// -/// fn foo(concrete: Option>, -/// param: T, -/// mixed: Option) { +/// fn foo(concrete: Option>, param: T, mixed: Option) { +/// // Case A: Vtable points at a specific impl. Only possible when +/// // type is concretely known. If the impl itself has bounded +/// // type parameters, Vtable will carry resolutions for those as well: +/// concrete.clone(); // Vtable(Impl_1, [Vtable(Impl_2, [Vtable(Impl_3)])]) /// -/// // Case A: ImplSource points at a specific impl. Only possible when -/// // type is concretely known. If the impl itself has bounded -/// // type parameters, ImplSource will carry resolutions for those as well: -/// concrete.clone(); // ImplSource(Impl_1, [ImplSource(Impl_2, [ImplSource(Impl_3)])]) +/// // Case A: ImplSource points at a specific impl. Only possible when +/// // type is concretely known. If the impl itself has bounded +/// // type parameters, ImplSource will carry resolutions for those as well: +/// concrete.clone(); // ImplSource(Impl_1, [ImplSource(Impl_2, [ImplSource(Impl_3)])]) /// -/// // Case B: ImplSource must be provided by caller. This applies when -/// // type is a type parameter. -/// param.clone(); // ImplSourceParam +/// // Case B: ImplSource must be provided by caller. This applies when +/// // type is a type parameter. +/// param.clone(); // ImplSourceParam /// -/// // Case C: A mix of cases A and B. -/// mixed.clone(); // ImplSource(Impl_1, [ImplSourceParam]) +/// // Case C: A mix of cases A and B. +/// mixed.clone(); // ImplSource(Impl_1, [ImplSourceParam]) /// } /// ``` /// diff --git a/src/librustc_middle/ty/subst.rs b/src/librustc_middle/ty/subst.rs index 1529f1173b391..3b4254a18ea61 100644 --- a/src/librustc_middle/ty/subst.rs +++ b/src/librustc_middle/ty/subst.rs @@ -599,12 +599,12 @@ impl<'a, 'tcx> SubstFolder<'a, 'tcx> { /// /// ``` /// type Func = fn(A); - /// type MetaFunc = for<'a> fn(Func<&'a int>) + /// type MetaFunc = for<'a> fn(Func<&'a i32>) /// ``` /// /// The type `MetaFunc`, when fully expanded, will be /// - /// for<'a> fn(fn(&'a int)) + /// for<'a> fn(fn(&'a i32)) /// ^~ ^~ ^~~ /// | | | /// | | DebruijnIndex of 2 @@ -613,7 +613,7 @@ impl<'a, 'tcx> SubstFolder<'a, 'tcx> { /// Here the `'a` lifetime is bound in the outer function, but appears as an argument of the /// inner one. Therefore, that appearance will have a DebruijnIndex of 2, because we must skip /// over the inner binder (remember that we count De Bruijn indices from 1). However, in the - /// definition of `MetaFunc`, the binder is not visible, so the type `&'a int` will have a + /// definition of `MetaFunc`, the binder is not visible, so the type `&'a i32` will have a /// De Bruijn index of 1. It's only during the substitution that we can see we must increase the /// depth by 1 to account for the binder that we passed through. /// @@ -621,18 +621,18 @@ impl<'a, 'tcx> SubstFolder<'a, 'tcx> { /// /// ``` /// type FuncTuple = (A,fn(A)); - /// type MetaFuncTuple = for<'a> fn(FuncTuple<&'a int>) + /// type MetaFuncTuple = for<'a> fn(FuncTuple<&'a i32>) /// ``` /// /// Here the final type will be: /// - /// for<'a> fn((&'a int, fn(&'a int))) + /// for<'a> fn((&'a i32, fn(&'a i32))) /// ^~~ ^~~ /// | | /// DebruijnIndex of 1 | /// DebruijnIndex of 2 /// - /// As indicated in the diagram, here the same type `&'a int` is substituted once, but in the + /// As indicated in the diagram, here the same type `&'a i32` is substituted once, but in the /// first case we do not increase the De Bruijn index and in the second case we do. The reason /// is that only in the second case have we passed through a fn binder. fn shift_vars_through_binders>(&self, val: T) -> T { diff --git a/src/librustc_middle/ty/walk.rs b/src/librustc_middle/ty/walk.rs index d6f504fdb338b..633d4fda8a46d 100644 --- a/src/librustc_middle/ty/walk.rs +++ b/src/librustc_middle/ty/walk.rs @@ -22,13 +22,13 @@ impl<'tcx> TypeWalker<'tcx> { /// Skips the subtree corresponding to the last type /// returned by `next()`. /// - /// Example: Imagine you are walking `Foo, usize>`. + /// Example: Imagine you are walking `Foo, usize>`. /// /// ``` /// let mut iter: TypeWalker = ...; /// iter.next(); // yields Foo - /// iter.next(); // yields Bar - /// iter.skip_current_subtree(); // skips int + /// iter.next(); // yields Bar + /// iter.skip_current_subtree(); // skips i32 /// iter.next(); // yields usize /// ``` pub fn skip_current_subtree(&mut self) { diff --git a/src/librustc_trait_selection/traits/project.rs b/src/librustc_trait_selection/traits/project.rs index 706e68698eb55..1964054254734 100644 --- a/src/librustc_trait_selection/traits/project.rs +++ b/src/librustc_trait_selection/traits/project.rs @@ -361,7 +361,7 @@ impl<'a, 'b, 'tcx> TypeFolder<'tcx> for AssocTypeNormalizer<'a, 'b, 'tcx> { // handle normalization within binders because // otherwise we wind up a need to normalize when doing // trait matching (since you can have a trait - // obligation like `for<'a> T::B : Fn(&'a int)`), but + // obligation like `for<'a> T::B: Fn(&'a i32)`), but // we can't normalize with bound regions in scope. So // far now we just ignore binders but only normalize // if all bound regions are gone (and then we still diff --git a/src/librustc_trait_selection/traits/query/normalize.rs b/src/librustc_trait_selection/traits/query/normalize.rs index 3e7749356d212..ca49ff5884f98 100644 --- a/src/librustc_trait_selection/traits/query/normalize.rs +++ b/src/librustc_trait_selection/traits/query/normalize.rs @@ -145,7 +145,7 @@ impl<'cx, 'tcx> TypeFolder<'tcx> for QueryNormalizer<'cx, 'tcx> { // handle normalization within binders because // otherwise we wind up a need to normalize when doing // trait matching (since you can have a trait - // obligation like `for<'a> T::B : Fn(&'a int)`), but + // obligation like `for<'a> T::B: Fn(&'a i32)`), but // we can't normalize with bound regions in scope. So // far now we just ignore binders but only normalize // if all bound regions are gone (and then we still diff --git a/src/librustc_trait_selection/traits/select/confirmation.rs b/src/librustc_trait_selection/traits/select/confirmation.rs index f8d26c06a219d..50c04e8fc3452 100644 --- a/src/librustc_trait_selection/traits/select/confirmation.rs +++ b/src/librustc_trait_selection/traits/select/confirmation.rs @@ -553,14 +553,14 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { /// /// Here is an example. Imagine we have a closure expression /// and we desugared it so that the type of the expression is - /// `Closure`, and `Closure` expects an int as argument. Then it + /// `Closure`, and `Closure` expects `i32` as argument. Then it /// is "as if" the compiler generated this impl: /// - /// impl Fn(int) for Closure { ... } + /// impl Fn(i32) for Closure { ... } /// - /// Now imagine our obligation is `Fn(usize) for Closure`. So far + /// Now imagine our obligation is `Closure: Fn(usize)`. So far /// we have matched the self type `Closure`. At this point we'll - /// compare the `int` to `usize` and generate an error. + /// compare the `i32` to `usize` and generate an error. /// /// Note that this checking occurs *after* the impl has selected, /// because these output type parameters should not affect the diff --git a/src/librustc_trait_selection/traits/select/mod.rs b/src/librustc_trait_selection/traits/select/mod.rs index c3b1079fb1284..7dc8c2cf4cdc2 100644 --- a/src/librustc_trait_selection/traits/select/mod.rs +++ b/src/librustc_trait_selection/traits/select/mod.rs @@ -1762,7 +1762,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { // The strategy is to: // // 1. Instantiate those regions to placeholder regions (e.g., - // `for<'a> &'a int` becomes `&0 i32`. + // `for<'a> &'a i32` becomes `&0 i32`. // 2. Produce something like `&'0 i32 : Copy` // 3. Re-bind the regions back to `for<'a> &'a i32 : Copy` diff --git a/src/librustc_typeck/astconv.rs b/src/librustc_typeck/astconv.rs index b592d30c37d3c..33d57e2571173 100644 --- a/src/librustc_typeck/astconv.rs +++ b/src/librustc_typeck/astconv.rs @@ -1394,13 +1394,13 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { // That is, consider this case: // // ``` - // trait SubTrait: SuperTrait { } + // trait SubTrait: SuperTrait { } // trait SuperTrait { type T; } // // ... B: SubTrait ... // ``` // - // We want to produce `>::T == foo`. + // We want to produce `>::T == foo`. // Find any late-bound regions declared in `ty` that are not // declared in the trait-ref. These are not well-formed. diff --git a/src/librustc_typeck/check/method/probe.rs b/src/librustc_typeck/check/method/probe.rs index eb8f76687174e..efd23894d02d1 100644 --- a/src/librustc_typeck/check/method/probe.rs +++ b/src/librustc_typeck/check/method/probe.rs @@ -1468,7 +1468,7 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> { /// /// ``` /// trait Foo { ... } - /// impl Foo for Vec { ... } + /// impl Foo for Vec { ... } /// impl Foo for Vec { ... } /// ``` /// diff --git a/src/librustc_typeck/check/pat.rs b/src/librustc_typeck/check/pat.rs index 7965c9c9ce12a..ea47ae68ce7d3 100644 --- a/src/librustc_typeck/check/pat.rs +++ b/src/librustc_typeck/check/pat.rs @@ -212,7 +212,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // errors in some cases, such as this one: // // ``` - // fn foo<'x>(x: &'x int) { + // fn foo<'x>(x: &'x i32) { // let a = 1; // let mut z = x; // z = &a; @@ -220,7 +220,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // ``` // // The reason we might get an error is that `z` might be - // assigned a type like `&'x int`, and then we would have + // assigned a type like `&'x i32`, and then we would have // a problem when we try to assign `&a` to `z`, because // the lifetime of `&a` (i.e., the enclosing block) is // shorter than `'x`. @@ -229,11 +229,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // expected type here is whatever type the user wrote, not // the initializer's type. In this case the user wrote // nothing, so we are going to create a type variable `Z`. - // Then we will assign the type of the initializer (`&'x - // int`) as a subtype of `Z`: `&'x int <: Z`. And hence we - // will instantiate `Z` as a type `&'0 int` where `'0` is - // a fresh region variable, with the constraint that `'x : - // '0`. So basically we're all set. + // Then we will assign the type of the initializer (`&'x i32`) + // as a subtype of `Z`: `&'x i32 <: Z`. And hence we + // will instantiate `Z` as a type `&'0 i32` where `'0` is + // a fresh region variable, with the constraint that `'x : '0`. + // So basically we're all set. // // Note that there are two tests to check that this remains true // (`regions-reassign-{match,let}-bound-pointer.rs`). From 180334c7a8ce250d878e96d3336e1c54b3d8b0e3 Mon Sep 17 00:00:00 2001 From: Bastian Kauschke Date: Sat, 6 Jun 2020 16:41:48 +0200 Subject: [PATCH 3/3] remove `pop_placeholders` --- src/librustc_infer/infer/higher_ranked/mod.rs | 10 +-- .../infer/region_constraints/leak_check.rs | 2 +- .../infer/region_constraints/mod.rs | 67 ------------------- src/librustc_infer/infer/undo_log.rs | 4 -- 4 files changed, 3 insertions(+), 80 deletions(-) diff --git a/src/librustc_infer/infer/higher_ranked/mod.rs b/src/librustc_infer/infer/higher_ranked/mod.rs index ef18918c1772f..0499dc9ed2232 100644 --- a/src/librustc_infer/infer/higher_ranked/mod.rs +++ b/src/librustc_infer/infer/higher_ranked/mod.rs @@ -63,14 +63,8 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { /// 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 - /// either `plug_leaks` or `pop_placeholders` to remove the placeholder - /// regions. If you rollback the snapshot (or are using a probe), then - /// the pop occurs as part of the rollback, so an explicit call is not - /// needed (but is also permitted). - /// - /// For more information about how placeholders and HRTBs work, see + /// **Important:** You have to be careful to not leak these placeholders, + /// for more information about how placeholders and HRTBs work, see /// the [rustc dev guide]. /// /// [rustc dev guide]: https://rustc-dev-guide.rust-lang.org/traits/hrtb.html diff --git a/src/librustc_infer/infer/region_constraints/leak_check.rs b/src/librustc_infer/infer/region_constraints/leak_check.rs index 473550d5433df..91c39a0e78ffb 100644 --- a/src/librustc_infer/infer/region_constraints/leak_check.rs +++ b/src/librustc_infer/infer/region_constraints/leak_check.rs @@ -128,7 +128,7 @@ impl<'tcx> TaintSet<'tcx> { verifys[i].origin.span(), "we never add verifications while doing higher-ranked things", ), - &Purged | &AddCombination(..) | &AddVar(..) => {} + &AddCombination(..) | &AddVar(..) => {} } } } diff --git a/src/librustc_infer/infer/region_constraints/mod.rs b/src/librustc_infer/infer/region_constraints/mod.rs index 42a6a6ff40afd..2902c41a6bcae 100644 --- a/src/librustc_infer/infer/region_constraints/mod.rs +++ b/src/librustc_infer/infer/region_constraints/mod.rs @@ -289,14 +289,6 @@ pub(crate) enum UndoLog<'tcx> { /// We added a GLB/LUB "combination variable". AddCombination(CombineMapType, TwoRegions<'tcx>), - - /// 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 - /// need to do a bunch of swapping. (We can't use `swap_remove` as - /// the order of the vector is important.) - Purged, } #[derive(Copy, Clone, PartialEq)] @@ -357,9 +349,6 @@ impl<'tcx> RegionConstraintStorage<'tcx> { fn rollback_undo_entry(&mut self, undo_entry: UndoLog<'tcx>) { match undo_entry { - Purged => { - // nothing to do here - } AddVar(vid) => { self.var_infos.pop().unwrap(); assert_eq!(self.var_infos.len(), vid.index() as usize); @@ -488,62 +477,6 @@ impl<'tcx> RegionConstraintCollector<'_, 'tcx> { self.var_infos[vid].origin } - /// Removes all the edges to/from the placeholder regions that are - /// 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>) { - debug!("pop_placeholders(placeholders={:?})", placeholders); - - assert!(UndoLogs::>::in_snapshot(&self.undo_log)); - - let constraints_to_kill: Vec = self - .undo_log - .iter() - .enumerate() - .rev() - .filter(|&(_, undo_entry)| match undo_entry { - super::UndoLog::RegionConstraintCollector(undo_entry) => { - kill_constraint(placeholders, undo_entry) - } - _ => false, - }) - .map(|(index, _)| index) - .collect(); - - for index in constraints_to_kill { - let undo_entry = match &mut self.undo_log[index] { - super::UndoLog::RegionConstraintCollector(undo_entry) => { - mem::replace(undo_entry, Purged) - } - _ => unreachable!(), - }; - self.rollback_undo_entry(undo_entry); - } - - return; - - fn kill_constraint<'tcx>( - placeholders: &FxHashSet>, - undo_entry: &UndoLog<'tcx>, - ) -> bool { - match undo_entry { - &AddConstraint(Constraint::VarSubVar(..)) => false, - &AddConstraint(Constraint::RegSubVar(a, _)) => placeholders.contains(&a), - &AddConstraint(Constraint::VarSubReg(_, b)) => placeholders.contains(&b), - &AddConstraint(Constraint::RegSubReg(a, b)) => { - placeholders.contains(&a) || placeholders.contains(&b) - } - &AddGiven(..) => false, - &AddVerify(_) => false, - &AddCombination(_, ref two_regions) => { - placeholders.contains(&two_regions.a) || placeholders.contains(&two_regions.b) - } - &AddVar(..) | &Purged => false, - } - } - } - fn add_constraint(&mut self, constraint: Constraint<'tcx>, origin: SubregionOrigin<'tcx>) { // cannot add constraints once regions are resolved debug!("RegionConstraintCollector: add_constraint({:?})", constraint); diff --git a/src/librustc_infer/infer/undo_log.rs b/src/librustc_infer/infer/undo_log.rs index e7f1869955d20..2cfd6bb904c41 100644 --- a/src/librustc_infer/infer/undo_log.rs +++ b/src/librustc_infer/infer/undo_log.rs @@ -198,10 +198,6 @@ impl<'tcx> InferCtxtUndoLogs<'tcx> { assert!(self.logs.len() >= snapshot.undo_len); assert!(self.num_open_snapshots > 0); } - - pub(crate) fn iter(&self) -> std::slice::Iter<'_, UndoLog<'tcx>> { - self.logs.iter() - } } impl<'tcx> std::ops::Index for InferCtxtUndoLogs<'tcx> {