Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

remove leftover mentions of skol and int from the compiler #73055

Merged
merged 3 commits into from
Jun 20, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 2 additions & 8 deletions src/librustc_infer/infer/higher_ranked/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@matthewjasper I removed the outdated note here, even if the new one doesn't completely explain what needs to be done, I would still like to land this as is now.

/// 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
Expand Down
2 changes: 1 addition & 1 deletion src/librustc_infer/infer/region_constraints/leak_check.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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(..) => {}
}
}
}
Expand Down
67 changes: 0 additions & 67 deletions src/librustc_infer/infer/region_constraints/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -289,14 +289,6 @@ 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
/// 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)]
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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 `skols`. 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>>) {
debug!("pop_placeholders(placeholders={:?})", placeholders);

assert!(UndoLogs::<super::UndoLog<'_>>::in_snapshot(&self.undo_log));

let constraints_to_kill: Vec<usize> = 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<ty::Region<'tcx>>,
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);
Expand Down
4 changes: 0 additions & 4 deletions src/librustc_infer/infer/undo_log.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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<usize> for InferCtxtUndoLogs<'tcx> {
Expand Down
4 changes: 2 additions & 2 deletions src/librustc_infer/traits/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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)]
Expand Down
4 changes: 2 additions & 2 deletions src/librustc_infer/traits/util.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
28 changes: 15 additions & 13 deletions src/librustc_middle/traits/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -393,23 +393,25 @@ pub type SelectionResult<'tcx, T> = Result<Option<T>, SelectionError<'tcx>>;
/// ```
/// impl<T:Clone> Clone<T> for Option<T> { ... } // Impl_1
/// impl<T:Clone> Clone<T> for Box<T> { ... } // Impl_2
/// impl Clone for int { ... } // Impl_3
/// impl Clone for i32 { ... } // Impl_3
///
/// fn foo<T:Clone>(concrete: Option<Box<int>>,
/// param: T,
/// mixed: Option<T>) {
/// fn foo<T: Clone>(concrete: Option<Box<i32>>, param: T, mixed: Option<T>) {
/// // 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])
/// }
/// ```
///
Expand Down
12 changes: 6 additions & 6 deletions src/librustc_middle/ty/subst.rs
Original file line number Diff line number Diff line change
Expand Up @@ -599,12 +599,12 @@ impl<'a, 'tcx> SubstFolder<'a, 'tcx> {
///
/// ```
/// type Func<A> = 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
Expand All @@ -613,26 +613,26 @@ 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.
///
/// As a second example, consider this twist:
///
/// ```
/// type FuncTuple<A> = (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<T: TypeFoldable<'tcx>>(&self, val: T) -> T {
Expand Down
6 changes: 3 additions & 3 deletions src/librustc_middle/ty/walk.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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<Bar<int>, usize>`.
/// Example: Imagine you are walking `Foo<Bar<i32>, usize>`.
///
/// ```
/// let mut iter: TypeWalker = ...;
/// iter.next(); // yields Foo
/// iter.next(); // yields Bar<int>
/// iter.skip_current_subtree(); // skips int
/// iter.next(); // yields Bar<i32>
/// iter.skip_current_subtree(); // skips i32
/// iter.next(); // yields usize
/// ```
pub fn skip_current_subtree(&mut self) {
Expand Down
2 changes: 1 addition & 1 deletion src/librustc_trait_selection/traits/project.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
2 changes: 1 addition & 1 deletion src/librustc_trait_selection/traits/query/normalize.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
8 changes: 4 additions & 4 deletions src/librustc_trait_selection/traits/select/confirmation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
31 changes: 15 additions & 16 deletions src/librustc_trait_selection/traits/select/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1754,38 +1754,37 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
) -> 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 i32` 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(
self,
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(),
Expand All @@ -1794,7 +1793,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
normalized_ty,
&[],
);
obligations.push(skol_obligation);
obligations.push(placeholder_obligation);
obligations
})
})
Expand Down Expand Up @@ -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);

Expand All @@ -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);

Expand Down
2 changes: 1 addition & 1 deletion src/librustc_trait_selection/traits/specialize/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
Loading