Shrink ParamEnv to 16 bytes
This commit is contained in:
parent
3503f565e1
commit
aae1215f7f
24 changed files with 187 additions and 83 deletions
|
@ -11,7 +11,7 @@ pub fn explicit_outlives_bounds<'tcx>(
|
|||
param_env: ty::ParamEnv<'tcx>,
|
||||
) -> impl Iterator<Item = OutlivesBound<'tcx>> + 'tcx {
|
||||
debug!("explicit_outlives_bounds()");
|
||||
param_env.caller_bounds.into_iter().filter_map(move |predicate| match predicate.kind() {
|
||||
param_env.caller_bounds().into_iter().filter_map(move |predicate| match predicate.kind() {
|
||||
ty::PredicateKind::Projection(..)
|
||||
| ty::PredicateKind::Trait(..)
|
||||
| ty::PredicateKind::Subtype(..)
|
||||
|
|
|
@ -221,7 +221,7 @@ impl<'cx, 'tcx> VerifyBoundCx<'cx, 'tcx> {
|
|||
// dubious for projections, but it will work for simple cases
|
||||
// like `T` and `T::Item`. It may not work as well for things
|
||||
// like `<T as Foo<'a>>::Item`.
|
||||
let c_b = self.param_env.caller_bounds;
|
||||
let c_b = self.param_env.caller_bounds();
|
||||
let param_bounds = self.collect_outlives_from_predicate_list(&compare_ty, c_b.into_iter());
|
||||
|
||||
// Next, collect regions we scraped from the well-formedness
|
||||
|
|
|
@ -57,7 +57,7 @@ pub type TraitObligation<'tcx> = Obligation<'tcx, ty::PolyTraitPredicate<'tcx>>;
|
|||
|
||||
// `PredicateObligation` is used a lot. Make sure it doesn't unintentionally get bigger.
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
static_assert_size!(PredicateObligation<'_>, 48);
|
||||
static_assert_size!(PredicateObligation<'_>, 40);
|
||||
|
||||
pub type Obligations<'tcx, O> = Vec<Obligation<'tcx, O>>;
|
||||
pub type PredicateObligations<'tcx> = Vec<PredicateObligation<'tcx>>;
|
||||
|
|
|
@ -1588,7 +1588,7 @@ impl<'tcx> LayoutCx<'tcx, TyCtxt<'tcx>> {
|
|||
// Ignore layouts that are done with non-empty environments or
|
||||
// non-monomorphic layouts, as the user only wants to see the stuff
|
||||
// resulting from the final codegen session.
|
||||
if layout.ty.has_param_types_or_consts() || !self.param_env.caller_bounds.is_empty() {
|
||||
if layout.ty.has_param_types_or_consts() || !self.param_env.caller_bounds().is_empty() {
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
// ignore-tidy-filelength
|
||||
|
||||
pub use self::fold::{TypeFoldable, TypeVisitor};
|
||||
pub use self::AssocItemContainer::*;
|
||||
pub use self::BorrowKind::*;
|
||||
|
@ -45,6 +47,7 @@ use std::cell::RefCell;
|
|||
use std::cmp::Ordering;
|
||||
use std::fmt;
|
||||
use std::hash::{Hash, Hasher};
|
||||
use std::marker::PhantomData;
|
||||
use std::ops::Range;
|
||||
use std::ptr;
|
||||
|
||||
|
@ -1571,17 +1574,34 @@ pub type PlaceholderConst = Placeholder<BoundVar>;
|
|||
/// When type checking, we use the `ParamEnv` to track
|
||||
/// details about the set of where-clauses that are in scope at this
|
||||
/// particular point.
|
||||
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, HashStable, TypeFoldable)]
|
||||
#[derive(Copy, Clone)]
|
||||
pub struct ParamEnv<'tcx> {
|
||||
// We pack the caller_bounds List pointer and a Reveal enum into this usize.
|
||||
// Specifically, the low bit represents Reveal, with 0 meaning `UserFacing`
|
||||
// and 1 meaning `All`. The rest is the pointer.
|
||||
//
|
||||
// This relies on the List<ty::Predicate<'tcx>> type having at least 2-byte
|
||||
// alignment. Lists start with a usize and are repr(C) so this should be
|
||||
// fine; there is a debug_assert in the constructor as well.
|
||||
//
|
||||
// Note that the choice of 0 for UserFacing is intentional -- since it is the
|
||||
// first variant in Reveal this means that joining the pointer is a simple `or`.
|
||||
packed_data: usize,
|
||||
|
||||
/// `Obligation`s that the caller must satisfy. This is basically
|
||||
/// the set of bounds on the in-scope type parameters, translated
|
||||
/// into `Obligation`s, and elaborated and normalized.
|
||||
pub caller_bounds: &'tcx List<ty::Predicate<'tcx>>,
|
||||
///
|
||||
/// Note: This is packed into the `packed_data` usize above, use the
|
||||
/// `caller_bounds()` method to access it.
|
||||
caller_bounds: PhantomData<&'tcx List<ty::Predicate<'tcx>>>,
|
||||
|
||||
/// Typically, this is `Reveal::UserFacing`, but during codegen we
|
||||
/// want `Reveal::All` -- note that this is always paired with an
|
||||
/// empty environment. To get that, use `ParamEnv::reveal()`.
|
||||
pub reveal: traits::Reveal,
|
||||
/// want `Reveal::All`.
|
||||
///
|
||||
/// Note: This is packed into the caller_bounds usize above, use the reveal()
|
||||
/// method to access it.
|
||||
reveal: PhantomData<traits::Reveal>,
|
||||
|
||||
/// If this `ParamEnv` comes from a call to `tcx.param_env(def_id)`,
|
||||
/// register that `def_id` (useful for transitioning to the chalk trait
|
||||
|
@ -1589,6 +1609,57 @@ pub struct ParamEnv<'tcx> {
|
|||
pub def_id: Option<DefId>,
|
||||
}
|
||||
|
||||
impl<'tcx> fmt::Debug for ParamEnv<'tcx> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
f.debug_struct("ParamEnv")
|
||||
.field("caller_bounds", &self.caller_bounds())
|
||||
.field("reveal", &self.reveal())
|
||||
.field("def_id", &self.def_id)
|
||||
.finish()
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx> Hash for ParamEnv<'tcx> {
|
||||
fn hash<H: Hasher>(&self, state: &mut H) {
|
||||
self.caller_bounds().hash(state);
|
||||
self.reveal().hash(state);
|
||||
self.def_id.hash(state);
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx> PartialEq for ParamEnv<'tcx> {
|
||||
fn eq(&self, other: &Self) -> bool {
|
||||
self.caller_bounds() == other.caller_bounds()
|
||||
&& self.reveal() == other.reveal()
|
||||
&& self.def_id == other.def_id
|
||||
}
|
||||
}
|
||||
impl<'tcx> Eq for ParamEnv<'tcx> {}
|
||||
|
||||
impl<'a, 'tcx> HashStable<StableHashingContext<'a>> for ParamEnv<'tcx> {
|
||||
fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher) {
|
||||
self.caller_bounds().hash_stable(hcx, hasher);
|
||||
self.reveal().hash_stable(hcx, hasher);
|
||||
self.def_id.hash_stable(hcx, hasher);
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx> TypeFoldable<'tcx> for ParamEnv<'tcx> {
|
||||
fn super_fold_with<F: ty::fold::TypeFolder<'tcx>>(&self, folder: &mut F) -> Self {
|
||||
ParamEnv::new(
|
||||
self.caller_bounds().fold_with(folder),
|
||||
self.reveal().fold_with(folder),
|
||||
self.def_id.fold_with(folder),
|
||||
)
|
||||
}
|
||||
|
||||
fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
|
||||
self.caller_bounds().visit_with(visitor)
|
||||
|| self.reveal().visit_with(visitor)
|
||||
|| self.def_id.visit_with(visitor)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx> ParamEnv<'tcx> {
|
||||
/// Construct a trait environment suitable for contexts where
|
||||
/// there are no where-clauses in scope. Hidden types (like `impl
|
||||
|
@ -1599,6 +1670,17 @@ impl<'tcx> ParamEnv<'tcx> {
|
|||
Self::new(List::empty(), Reveal::UserFacing, None)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn caller_bounds(self) -> &'tcx List<ty::Predicate<'tcx>> {
|
||||
// mask out bottom bit
|
||||
unsafe { &*((self.packed_data & (!1)) as *const _) }
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn reveal(self) -> traits::Reveal {
|
||||
if self.packed_data & 1 == 0 { traits::Reveal::UserFacing } else { traits::Reveal::All }
|
||||
}
|
||||
|
||||
/// Construct a trait environment with no where-clauses in scope
|
||||
/// where the values of all `impl Trait` and other hidden types
|
||||
/// are revealed. This is suitable for monomorphized, post-typeck
|
||||
|
@ -1618,7 +1700,25 @@ impl<'tcx> ParamEnv<'tcx> {
|
|||
reveal: Reveal,
|
||||
def_id: Option<DefId>,
|
||||
) -> Self {
|
||||
ty::ParamEnv { caller_bounds, reveal, def_id }
|
||||
let packed_data = caller_bounds as *const _ as usize;
|
||||
// Check that we can pack the reveal data into the pointer.
|
||||
debug_assert!(packed_data & 1 == 0);
|
||||
ty::ParamEnv {
|
||||
packed_data: packed_data
|
||||
| match reveal {
|
||||
Reveal::UserFacing => 0,
|
||||
Reveal::All => 1,
|
||||
},
|
||||
caller_bounds: PhantomData,
|
||||
reveal: PhantomData,
|
||||
def_id,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn with_user_facing(mut self) -> Self {
|
||||
// clear bottom bit
|
||||
self.packed_data &= !1;
|
||||
self
|
||||
}
|
||||
|
||||
/// Returns a new parameter environment with the same clauses, but
|
||||
|
@ -1627,13 +1727,14 @@ impl<'tcx> ParamEnv<'tcx> {
|
|||
/// the desired behavior during codegen and certain other special
|
||||
/// contexts; normally though we want to use `Reveal::UserFacing`,
|
||||
/// which is the default.
|
||||
pub fn with_reveal_all(self) -> Self {
|
||||
ty::ParamEnv { reveal: Reveal::All, ..self }
|
||||
pub fn with_reveal_all(mut self) -> Self {
|
||||
self.packed_data |= 1;
|
||||
self
|
||||
}
|
||||
|
||||
/// Returns this same environment but with no caller bounds.
|
||||
pub fn without_caller_bounds(self) -> Self {
|
||||
ty::ParamEnv { caller_bounds: List::empty(), ..self }
|
||||
Self::new(List::empty(), self.reveal(), self.def_id)
|
||||
}
|
||||
|
||||
/// Creates a suitable environment in which to perform trait
|
||||
|
@ -1649,7 +1750,7 @@ impl<'tcx> ParamEnv<'tcx> {
|
|||
/// satisfiable. We generally want to behave as if they were true,
|
||||
/// although the surrounding function is never reachable.
|
||||
pub fn and<T: TypeFoldable<'tcx>>(self, value: T) -> ParamEnvAnd<'tcx, T> {
|
||||
match self.reveal {
|
||||
match self.reveal() {
|
||||
Reveal::UserFacing => ParamEnvAnd { param_env: self, value },
|
||||
|
||||
Reveal::All => {
|
||||
|
|
|
@ -521,11 +521,8 @@ impl<'tcx, T: Lift<'tcx>> Lift<'tcx> for ty::Binder<T> {
|
|||
impl<'a, 'tcx> Lift<'tcx> for ty::ParamEnv<'a> {
|
||||
type Lifted = ty::ParamEnv<'tcx>;
|
||||
fn lift_to_tcx(&self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {
|
||||
tcx.lift(&self.caller_bounds).map(|caller_bounds| ty::ParamEnv {
|
||||
reveal: self.reveal,
|
||||
caller_bounds,
|
||||
def_id: self.def_id,
|
||||
})
|
||||
tcx.lift(&self.caller_bounds())
|
||||
.map(|caller_bounds| ty::ParamEnv::new(caller_bounds, self.reveal(), self.def_id))
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -226,9 +226,9 @@ pub fn const_eval_validated_provider<'tcx>(
|
|||
key: ty::ParamEnvAnd<'tcx, GlobalId<'tcx>>,
|
||||
) -> ::rustc_middle::mir::interpret::ConstEvalResult<'tcx> {
|
||||
// see comment in const_eval_raw_provider for what we're doing here
|
||||
if key.param_env.reveal == Reveal::All {
|
||||
if key.param_env.reveal() == Reveal::All {
|
||||
let mut key = key;
|
||||
key.param_env.reveal = Reveal::UserFacing;
|
||||
key.param_env = key.param_env.with_user_facing();
|
||||
match tcx.const_eval_validated(key) {
|
||||
// try again with reveal all as requested
|
||||
Err(ErrorHandled::TooGeneric) => {}
|
||||
|
@ -267,9 +267,9 @@ pub fn const_eval_raw_provider<'tcx>(
|
|||
// information being available.
|
||||
|
||||
// In case we fail in the `UserFacing` variant, we just do the real computation.
|
||||
if key.param_env.reveal == Reveal::All {
|
||||
if key.param_env.reveal() == Reveal::All {
|
||||
let mut key = key;
|
||||
key.param_env.reveal = Reveal::UserFacing;
|
||||
key.param_env = key.param_env.with_user_facing();
|
||||
match tcx.const_eval_raw(key) {
|
||||
// try again with reveal all as requested
|
||||
Err(ErrorHandled::TooGeneric) => {}
|
||||
|
@ -326,7 +326,7 @@ pub fn const_eval_raw_provider<'tcx>(
|
|||
// this is `Reveal::UserFacing`, then it's expected that we could get a
|
||||
// `TooGeneric` error. When we fall back to `Reveal::All`, then it will either
|
||||
// succeed or we'll report this error then.
|
||||
if key.param_env.reveal == Reveal::All {
|
||||
if key.param_env.reveal() == Reveal::All {
|
||||
tcx.sess.delay_span_bug(
|
||||
err.span,
|
||||
&format!("static eval failure did not emit an error: {:#?}", v),
|
||||
|
|
|
@ -279,7 +279,7 @@ where
|
|||
let subpath = self.elaborator.field_subpath(variant_path, field);
|
||||
let tcx = self.tcx();
|
||||
|
||||
assert_eq!(self.elaborator.param_env().reveal, Reveal::All);
|
||||
assert_eq!(self.elaborator.param_env().reveal(), Reveal::All);
|
||||
let field_ty =
|
||||
tcx.normalize_erasing_regions(self.elaborator.param_env(), f.ty(tcx, substs));
|
||||
(tcx.mk_place_field(base_place, field, field_ty), subpath)
|
||||
|
|
|
@ -281,8 +281,8 @@ impl AutoTraitFinder<'tcx> {
|
|||
},
|
||||
}));
|
||||
|
||||
let computed_preds = param_env.caller_bounds.iter();
|
||||
let mut user_computed_preds: FxHashSet<_> = user_env.caller_bounds.iter().collect();
|
||||
let computed_preds = param_env.caller_bounds().iter();
|
||||
let mut user_computed_preds: FxHashSet<_> = user_env.caller_bounds().iter().collect();
|
||||
|
||||
let mut new_env = param_env;
|
||||
let dummy_cause = ObligationCause::dummy();
|
||||
|
@ -368,12 +368,12 @@ impl AutoTraitFinder<'tcx> {
|
|||
)
|
||||
.map(|o| o.predicate);
|
||||
new_env =
|
||||
ty::ParamEnv::new(tcx.mk_predicates(normalized_preds), param_env.reveal, None);
|
||||
ty::ParamEnv::new(tcx.mk_predicates(normalized_preds), param_env.reveal(), None);
|
||||
}
|
||||
|
||||
let final_user_env = ty::ParamEnv::new(
|
||||
tcx.mk_predicates(user_computed_preds.into_iter()),
|
||||
user_env.reveal,
|
||||
user_env.reveal(),
|
||||
None,
|
||||
);
|
||||
debug!(
|
||||
|
|
|
@ -137,7 +137,7 @@ fn in_environment(
|
|||
|
||||
let environment = match obligation.param_env.def_id {
|
||||
Some(def_id) => environment(infcx.tcx, def_id),
|
||||
None if obligation.param_env.caller_bounds.is_empty() => ty::List::empty(),
|
||||
None if obligation.param_env.caller_bounds().is_empty() => ty::List::empty(),
|
||||
// FIXME(chalk): this is hit in ui/where-clauses/where-clause-constraints-are-local-for-trait-impl
|
||||
// and ui/generics/generic-static-methods
|
||||
//_ => bug!("non-empty `ParamEnv` with no def-id"),
|
||||
|
|
|
@ -84,7 +84,7 @@ pub struct PendingPredicateObligation<'tcx> {
|
|||
|
||||
// `PendingPredicateObligation` is used a lot. Make sure it doesn't unintentionally get bigger.
|
||||
#[cfg(target_arch = "x86_64")]
|
||||
static_assert_size!(PendingPredicateObligation<'_>, 72);
|
||||
static_assert_size!(PendingPredicateObligation<'_>, 64);
|
||||
|
||||
impl<'a, 'tcx> FulfillmentContext<'tcx> {
|
||||
/// Creates a new fulfillment context.
|
||||
|
|
|
@ -297,7 +297,7 @@ pub fn normalize_param_env_or_error<'tcx>(
|
|||
);
|
||||
|
||||
let mut predicates: Vec<_> =
|
||||
util::elaborate_predicates(tcx, unnormalized_env.caller_bounds.into_iter())
|
||||
util::elaborate_predicates(tcx, unnormalized_env.caller_bounds().into_iter())
|
||||
.map(|obligation| obligation.predicate)
|
||||
.collect();
|
||||
|
||||
|
@ -305,7 +305,7 @@ pub fn normalize_param_env_or_error<'tcx>(
|
|||
|
||||
let elaborated_env = ty::ParamEnv::new(
|
||||
tcx.intern_predicates(&predicates),
|
||||
unnormalized_env.reveal,
|
||||
unnormalized_env.reveal(),
|
||||
unnormalized_env.def_id,
|
||||
);
|
||||
|
||||
|
@ -361,7 +361,7 @@ pub fn normalize_param_env_or_error<'tcx>(
|
|||
let outlives_env: Vec<_> =
|
||||
non_outlives_predicates.iter().chain(&outlives_predicates).cloned().collect();
|
||||
let outlives_env =
|
||||
ty::ParamEnv::new(tcx.intern_predicates(&outlives_env), unnormalized_env.reveal, None);
|
||||
ty::ParamEnv::new(tcx.intern_predicates(&outlives_env), unnormalized_env.reveal(), None);
|
||||
let outlives_predicates = match do_normalize_predicates(
|
||||
tcx,
|
||||
region_context,
|
||||
|
@ -383,7 +383,7 @@ pub fn normalize_param_env_or_error<'tcx>(
|
|||
debug!("normalize_param_env_or_error: final predicates={:?}", predicates);
|
||||
ty::ParamEnv::new(
|
||||
tcx.intern_predicates(&predicates),
|
||||
unnormalized_env.reveal,
|
||||
unnormalized_env.reveal(),
|
||||
unnormalized_env.def_id,
|
||||
)
|
||||
}
|
||||
|
|
|
@ -631,7 +631,7 @@ fn receiver_is_dispatchable<'tcx>(
|
|||
// create a modified param env, with `Self: Unsize<U>` and `U: Trait` added to caller bounds
|
||||
// `U: ?Sized` is already implied here
|
||||
let param_env = {
|
||||
let mut param_env = tcx.param_env(method.def_id);
|
||||
let param_env = tcx.param_env(method.def_id);
|
||||
|
||||
// Self: Unsize<U>
|
||||
let unsize_predicate = ty::TraitRef {
|
||||
|
@ -656,15 +656,17 @@ fn receiver_is_dispatchable<'tcx>(
|
|||
};
|
||||
|
||||
let caller_bounds: Vec<Predicate<'tcx>> = param_env
|
||||
.caller_bounds
|
||||
.caller_bounds()
|
||||
.iter()
|
||||
.chain(iter::once(unsize_predicate))
|
||||
.chain(iter::once(trait_predicate))
|
||||
.collect();
|
||||
|
||||
param_env.caller_bounds = tcx.intern_predicates(&caller_bounds);
|
||||
|
||||
param_env
|
||||
ty::ParamEnv::new(
|
||||
tcx.intern_predicates(&caller_bounds),
|
||||
param_env.reveal(),
|
||||
param_env.def_id,
|
||||
)
|
||||
};
|
||||
|
||||
// Receiver: DispatchFromDyn<Receiver[Self => U]>
|
||||
|
|
|
@ -326,7 +326,7 @@ impl<'a, 'b, 'tcx> TypeFolder<'tcx> for AssocTypeNormalizer<'a, 'b, 'tcx> {
|
|||
ty::Opaque(def_id, substs) if !substs.has_escaping_bound_vars() => {
|
||||
// (*)
|
||||
// Only normalize `impl Trait` after type-checking, usually in codegen.
|
||||
match self.param_env.reveal {
|
||||
match self.param_env.reveal() {
|
||||
Reveal::UserFacing => ty,
|
||||
|
||||
Reveal::All => {
|
||||
|
@ -869,7 +869,7 @@ fn assemble_candidates_from_param_env<'cx, 'tcx>(
|
|||
obligation_trait_ref,
|
||||
candidate_set,
|
||||
ProjectionTyCandidate::ParamEnv,
|
||||
obligation.param_env.caller_bounds.iter(),
|
||||
obligation.param_env.caller_bounds().iter(),
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -1028,7 +1028,7 @@ fn assemble_candidates_from_impls<'cx, 'tcx>(
|
|||
// and the obligation is monomorphic, otherwise passes such as
|
||||
// transmute checking and polymorphic MIR optimizations could
|
||||
// get a result which isn't correct for all monomorphizations.
|
||||
if obligation.param_env.reveal == Reveal::All {
|
||||
if obligation.param_env.reveal() == Reveal::All {
|
||||
// NOTE(eddyb) inference variables can resolve to parameters, so
|
||||
// assume `poly_trait_ref` isn't monomorphic, if it contains any.
|
||||
let poly_trait_ref =
|
||||
|
|
|
@ -104,7 +104,7 @@ impl<'cx, 'tcx> TypeFolder<'tcx> for QueryNormalizer<'cx, 'tcx> {
|
|||
ty::Opaque(def_id, substs) if !substs.has_escaping_bound_vars() => {
|
||||
// (*)
|
||||
// Only normalize `impl Trait` after type-checking, usually in codegen.
|
||||
match self.param_env.reveal {
|
||||
match self.param_env.reveal() {
|
||||
Reveal::UserFacing => ty,
|
||||
|
||||
Reveal::All => {
|
||||
|
|
|
@ -186,7 +186,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
|||
let all_bounds = stack
|
||||
.obligation
|
||||
.param_env
|
||||
.caller_bounds
|
||||
.caller_bounds()
|
||||
.iter()
|
||||
.filter_map(|o| o.to_opt_poly_trait_ref());
|
||||
|
||||
|
|
|
@ -552,7 +552,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
|||
|
||||
if !self.intercrate
|
||||
&& obligation.is_global()
|
||||
&& obligation.param_env.caller_bounds.iter().all(|bound| bound.needs_subst())
|
||||
&& obligation.param_env.caller_bounds().iter().all(|bound| bound.needs_subst())
|
||||
{
|
||||
// If a param env has no global bounds, global obligations do not
|
||||
// depend on its particular value in order to work, so we can clear
|
||||
|
|
|
@ -231,7 +231,10 @@ fn fulfill_implication<'a, 'tcx>(
|
|||
debug!(
|
||||
"fulfill_implication: for impls on {:?} and {:?}, \
|
||||
could not fulfill: {:?} given {:?}",
|
||||
source_trait_ref, target_trait_ref, errors, param_env.caller_bounds
|
||||
source_trait_ref,
|
||||
target_trait_ref,
|
||||
errors,
|
||||
param_env.caller_bounds()
|
||||
);
|
||||
Err(())
|
||||
}
|
||||
|
|
|
@ -126,7 +126,7 @@ fn resolve_associated_item<'tcx>(
|
|||
// and the obligation is monomorphic, otherwise passes such as
|
||||
// transmute checking and polymorphic MIR optimizations could
|
||||
// get a result which isn't correct for all monomorphizations.
|
||||
if param_env.reveal == Reveal::All {
|
||||
if param_env.reveal() == Reveal::All {
|
||||
!trait_ref.still_further_specializable()
|
||||
} else {
|
||||
false
|
||||
|
|
|
@ -218,7 +218,7 @@ fn compare_predicate_entailment<'tcx>(
|
|||
let inh = Inherited::new(infcx, impl_m.def_id.expect_local());
|
||||
let infcx = &inh.infcx;
|
||||
|
||||
debug!("compare_impl_method: caller_bounds={:?}", param_env.caller_bounds);
|
||||
debug!("compare_impl_method: caller_bounds={:?}", param_env.caller_bounds());
|
||||
|
||||
let mut selcx = traits::SelectionContext::new(&infcx);
|
||||
|
||||
|
@ -1141,7 +1141,7 @@ fn compare_type_predicate_entailment<'tcx>(
|
|||
let inh = Inherited::new(infcx, impl_ty.def_id.expect_local());
|
||||
let infcx = &inh.infcx;
|
||||
|
||||
debug!("compare_type_predicate_entailment: caller_bounds={:?}", param_env.caller_bounds);
|
||||
debug!("compare_type_predicate_entailment: caller_bounds={:?}", param_env.caller_bounds());
|
||||
|
||||
let mut selcx = traits::SelectionContext::new(&infcx);
|
||||
|
||||
|
|
|
@ -798,26 +798,25 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
|
|||
// FIXME: do we want to commit to this behavior for param bounds?
|
||||
debug!("assemble_inherent_candidates_from_param(param_ty={:?})", param_ty);
|
||||
|
||||
let bounds =
|
||||
self.param_env.caller_bounds.iter().filter_map(|predicate| match predicate.kind() {
|
||||
ty::PredicateKind::Trait(ref trait_predicate, _) => {
|
||||
match trait_predicate.skip_binder().trait_ref.self_ty().kind {
|
||||
ty::Param(ref p) if *p == param_ty => {
|
||||
Some(trait_predicate.to_poly_trait_ref())
|
||||
}
|
||||
_ => None,
|
||||
}
|
||||
let bounds = self.param_env.caller_bounds().iter().filter_map(|predicate| match predicate
|
||||
.kind()
|
||||
{
|
||||
ty::PredicateKind::Trait(ref trait_predicate, _) => {
|
||||
match trait_predicate.skip_binder().trait_ref.self_ty().kind {
|
||||
ty::Param(ref p) if *p == param_ty => Some(trait_predicate.to_poly_trait_ref()),
|
||||
_ => None,
|
||||
}
|
||||
ty::PredicateKind::Subtype(..)
|
||||
| ty::PredicateKind::Projection(..)
|
||||
| ty::PredicateKind::RegionOutlives(..)
|
||||
| ty::PredicateKind::WellFormed(..)
|
||||
| ty::PredicateKind::ObjectSafe(..)
|
||||
| ty::PredicateKind::ClosureKind(..)
|
||||
| ty::PredicateKind::TypeOutlives(..)
|
||||
| ty::PredicateKind::ConstEvaluatable(..)
|
||||
| ty::PredicateKind::ConstEquate(..) => None,
|
||||
});
|
||||
}
|
||||
ty::PredicateKind::Subtype(..)
|
||||
| ty::PredicateKind::Projection(..)
|
||||
| ty::PredicateKind::RegionOutlives(..)
|
||||
| ty::PredicateKind::WellFormed(..)
|
||||
| ty::PredicateKind::ObjectSafe(..)
|
||||
| ty::PredicateKind::ClosureKind(..)
|
||||
| ty::PredicateKind::TypeOutlives(..)
|
||||
| ty::PredicateKind::ConstEvaluatable(..)
|
||||
| ty::PredicateKind::ConstEquate(..) => None,
|
||||
});
|
||||
|
||||
self.elaborate_bounds(bounds, |this, poly_trait_ref, item| {
|
||||
let trait_ref = this.erase_late_bound_regions(&poly_trait_ref);
|
||||
|
|
|
@ -2927,18 +2927,20 @@ impl<'a, 'tcx> AstConv<'tcx> for FnCtxt<'a, 'tcx> {
|
|||
let index = generics.param_def_id_to_index[&def_id];
|
||||
ty::GenericPredicates {
|
||||
parent: None,
|
||||
predicates: tcx.arena.alloc_from_iter(self.param_env.caller_bounds.iter().filter_map(
|
||||
|predicate| match predicate.kind() {
|
||||
ty::PredicateKind::Trait(ref data, _)
|
||||
if data.skip_binder().self_ty().is_param(index) =>
|
||||
{
|
||||
// HACK(eddyb) should get the original `Span`.
|
||||
let span = tcx.def_span(def_id);
|
||||
Some((predicate, span))
|
||||
predicates: tcx.arena.alloc_from_iter(
|
||||
self.param_env.caller_bounds().iter().filter_map(|predicate| {
|
||||
match predicate.kind() {
|
||||
ty::PredicateKind::Trait(ref data, _)
|
||||
if data.skip_binder().self_ty().is_param(index) =>
|
||||
{
|
||||
// HACK(eddyb) should get the original `Span`.
|
||||
let span = tcx.def_span(def_id);
|
||||
Some((predicate, span))
|
||||
}
|
||||
_ => None,
|
||||
}
|
||||
_ => None,
|
||||
},
|
||||
)),
|
||||
}),
|
||||
),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -459,9 +459,9 @@ impl<'a, 'tcx> AutoTraitFinder<'a, 'tcx> {
|
|||
let mut replacer = RegionReplacer { vid_to_region: &vid_to_region, tcx };
|
||||
|
||||
let orig_bounds: FxHashSet<_> =
|
||||
self.cx.tcx.param_env(param_env_def_id).caller_bounds.iter().collect();
|
||||
self.cx.tcx.param_env(param_env_def_id).caller_bounds().iter().collect();
|
||||
let clean_where_predicates = param_env
|
||||
.caller_bounds
|
||||
.caller_bounds()
|
||||
.iter()
|
||||
.filter(|p| {
|
||||
!orig_bounds.contains(p)
|
||||
|
|
|
@ -111,7 +111,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for NeedlessPassByValue {
|
|||
|
||||
let fn_def_id = cx.tcx.hir().local_def_id(hir_id);
|
||||
|
||||
let preds = traits::elaborate_predicates(cx.tcx, cx.param_env.caller_bounds.iter())
|
||||
let preds = traits::elaborate_predicates(cx.tcx, cx.param_env.caller_bounds().iter())
|
||||
.filter(|p| !p.is_global())
|
||||
.filter_map(|obligation| {
|
||||
if let ty::PredicateKind::Trait(poly_trait_ref, _) = obligation.predicate.kind() {
|
||||
|
|
Loading…
Reference in a new issue