));
for (super_predicate, _) in super_predicates.predicates {
let subst_predicate = super_predicate.subst_supertrait(tcx, &trait_ref);
- if let Some(binder) = subst_predicate.to_opt_poly_trait_ref() {
- stack.push(binder.value);
+ if let Some(binder) = subst_predicate.to_opt_poly_trait_pred() {
+ stack.push(binder.map_bound(|t| t.trait_ref));
}
}
fn next(&mut self) -> Option<ty::PolyTraitRef<'tcx>> {
while let Some(obligation) = self.base_iterator.next() {
- if let Some(data) = obligation.predicate.to_opt_poly_trait_ref() {
- return Some(data.value);
+ if let Some(data) = obligation.predicate.to_opt_poly_trait_pred() {
+ return Some(data.map_bound(|t| t.trait_ref));
}
}
None
/// `false` if there are no *further* obligations.
has_nested: bool,
},
- ParamCandidate((ty::ConstnessAnd<ty::PolyTraitRef<'tcx>>, ty::ImplPolarity)),
+ ParamCandidate(ty::PolyTraitPredicate<'tcx>),
ImplCandidate(DefId),
AutoImplCandidate(DefId),
}
impl<'tcx> Predicate<'tcx> {
- pub fn to_opt_poly_trait_ref(self) -> Option<ConstnessAnd<PolyTraitRef<'tcx>>> {
+ pub fn to_opt_poly_trait_pred(self) -> Option<PolyTraitPredicate<'tcx>> {
let predicate = self.kind();
match predicate.skip_binder() {
- PredicateKind::Trait(t) => {
- Some(ConstnessAnd { constness: t.constness, value: predicate.rebind(t.trait_ref) })
- }
+ PredicateKind::Trait(t) => Some(predicate.rebind(t)),
PredicateKind::Projection(..)
| PredicateKind::Subtype(..)
| PredicateKind::Coerce(..)
.predicates
.into_iter()
.filter_map(move |(pred, _)| {
- pred.subst_supertrait(tcx, &inner_most_trait_ref).to_opt_poly_trait_ref()
+ pred.subst_supertrait(tcx, &inner_most_trait_ref).to_opt_poly_trait_pred()
});
'diving_in_skip_visited_traits: loop {
if let Some(next_super_trait) = direct_super_traits_iter.next() {
if visited.insert(next_super_trait.to_predicate(tcx)) {
+ // We're throwing away potential constness of super traits here.
+ // FIXME: handle ~const super traits
+ let next_super_trait = next_super_trait.map_bound(|t| t.trait_ref);
stack.push((
- next_super_trait.value,
+ next_super_trait,
emit_vptr_on_new_entry,
Some(direct_super_traits_iter),
));
if let Some(siblings) = siblings_opt {
if let Some(next_inner_most_trait_ref) = siblings.next() {
if visited.insert(next_inner_most_trait_ref.to_predicate(tcx)) {
- *inner_most_trait_ref = next_inner_most_trait_ref.value;
+ // We're throwing away potential constness of super traits here.
+ // FIXME: handle ~const super traits
+ let next_inner_most_trait_ref =
+ next_inner_most_trait_ref.map_bound(|t| t.trait_ref);
+ *inner_most_trait_ref = next_inner_most_trait_ref;
*emit_vptr = emit_vptr_on_new_entry;
break 'exiting_out;
} else {
.param_env
.caller_bounds()
.iter()
- .filter_map(|o| o.to_opt_poly_trait_ref());
+ .filter_map(|o| o.to_opt_poly_trait_pred());
// Micro-optimization: filter out predicates relating to different traits.
let matching_bounds =
- all_bounds.filter(|p| p.value.def_id() == stack.obligation.predicate.def_id());
+ all_bounds.filter(|p| p.def_id() == stack.obligation.predicate.def_id());
// Keep only those bounds which may apply, and propagate overflow if it occurs.
for bound in matching_bounds {
- let wc = self.evaluate_where_clause(stack, bound.value)?;
+ // FIXME(oli-obk): it is suspicious that we are dropping the constness and
+ // polarity here.
+ let wc = self.evaluate_where_clause(stack, bound.map_bound(|t| t.trait_ref))?;
if wc.may_apply() {
- candidates.vec.push(ParamCandidate((bound, stack.obligation.polarity())));
+ candidates.vec.push(ParamCandidate(bound));
}
}
}
ParamCandidate(param) => {
- let obligations = self.confirm_param_candidate(obligation, param.0.value);
- Ok(ImplSource::Param(obligations, param.0.constness))
+ let obligations =
+ self.confirm_param_candidate(obligation, param.map_bound(|t| t.trait_ref));
+ Ok(ImplSource::Param(obligations, param.skip_binder().constness))
}
ImplCandidate(impl_def_id) => {
let trait_predicate = self.infcx.shallow_resolve(obligation.predicate);
let placeholder_trait_predicate =
- self.infcx().replace_bound_vars_with_placeholders(trait_predicate);
+ self.infcx().replace_bound_vars_with_placeholders(trait_predicate).trait_ref;
let placeholder_self_ty = placeholder_trait_predicate.self_ty();
let placeholder_trait_predicate = ty::Binder::dummy(placeholder_trait_predicate);
let (def_id, substs) = match *placeholder_self_ty.kind() {
let candidate_predicate = tcx.item_bounds(def_id)[idx].subst(tcx, substs);
let candidate = candidate_predicate
- .to_opt_poly_trait_ref()
- .expect("projection candidate is not a trait predicate");
+ .to_opt_poly_trait_pred()
+ .expect("projection candidate is not a trait predicate")
+ .map_bound(|t| t.trait_ref);
let mut obligations = Vec::new();
let candidate = normalize_with_depth_to(
self,
obligations.extend(self.infcx.commit_if_ok(|_| {
self.infcx
.at(&obligation.cause, obligation.param_env)
- .sup(placeholder_trait_predicate.to_poly_trait_ref(), candidate.value)
+ .sup(placeholder_trait_predicate, candidate)
.map(|InferOk { obligations, .. }| obligations)
.map_err(|_| Unimplemented)
})?);
ImplCandidate(def_id)
if tcx.impl_constness(def_id) == hir::Constness::Const => {}
// const param
- ParamCandidate((
- ty::ConstnessAnd { constness: ty::BoundConstness::ConstIfConst, .. },
- _,
- )) => {}
+ ParamCandidate(trait_pred)
+ if trait_pred.skip_binder().constness
+ == ty::BoundConstness::ConstIfConst => {}
// auto trait impl
AutoImplCandidate(..) => {}
// generator, this will raise error in other places
// Check if a bound would previously have been removed when normalizing
// the param_env so that it can be given the lowest priority. See
// #50825 for the motivation for this.
- let is_global = |cand: &ty::PolyTraitRef<'tcx>| {
+ let is_global = |cand: &ty::PolyTraitPredicate<'tcx>| {
cand.is_global(self.infcx.tcx) && !cand.has_late_bound_regions()
};
| ConstDropCandidate,
) => false,
- (
- ParamCandidate((other, other_polarity)),
- ParamCandidate((victim, victim_polarity)),
- ) => {
- let same_except_bound_vars = other.value.skip_binder()
- == victim.value.skip_binder()
- && other.constness == victim.constness
- && other_polarity == victim_polarity
- && !other.value.skip_binder().has_escaping_bound_vars();
+ (ParamCandidate(other), ParamCandidate(victim)) => {
+ let same_except_bound_vars = other.skip_binder().trait_ref
+ == victim.skip_binder().trait_ref
+ && other.skip_binder().constness == victim.skip_binder().constness
+ && other.skip_binder().polarity == victim.skip_binder().polarity
+ && !other.skip_binder().trait_ref.has_escaping_bound_vars();
if same_except_bound_vars {
// See issue #84398. In short, we can generate multiple ParamCandidates which are
// the same except for unused bound vars. Just pick the one with the fewest bound vars
// or the current one if tied (they should both evaluate to the same answer). This is
// probably best characterized as a "hack", since we might prefer to just do our
// best to *not* create essentially duplicate candidates in the first place.
- other.value.bound_vars().len() <= victim.value.bound_vars().len()
- } else if other.value == victim.value
- && victim.constness == ty::BoundConstness::NotConst
- && other_polarity == victim_polarity
+ other.bound_vars().len() <= victim.bound_vars().len()
+ } else if other.skip_binder().trait_ref == victim.skip_binder().trait_ref
+ && victim.skip_binder().constness == ty::BoundConstness::NotConst
+ && other.skip_binder().polarity == victim.skip_binder().polarity
{
// Drop otherwise equivalent non-const candidates in favor of const candidates.
true
| TraitAliasCandidate(..)
| ObjectCandidate(_)
| ProjectionCandidate(_),
- ) => !is_global(&cand.0.value),
+ ) => !is_global(cand),
(ObjectCandidate(_) | ProjectionCandidate(_), ParamCandidate(ref cand)) => {
// Prefer these to a global where-clause bound
// (see issue #50825).
- is_global(&cand.0.value)
+ is_global(cand)
}
(
ImplCandidate(_)
) => {
// Prefer these to a global where-clause bound
// (see issue #50825).
- is_global(&cand.0.value) && other.evaluation.must_apply_modulo_regions()
+ is_global(cand) && other.evaluation.must_apply_modulo_regions()
}
(ProjectionCandidate(i), ProjectionCandidate(j))
Vec::with_capacity(predicates.len() + types_without_default_bounds.len());
for (p, _) in predicates {
- if let Some(poly_trait_ref) = p.to_opt_poly_trait_ref() {
- if Some(poly_trait_ref.value.def_id()) == sized_trait {
- types_without_default_bounds.remove(poly_trait_ref.value.self_ty().skip_binder());
+ if let Some(poly_trait_ref) = p.to_opt_poly_trait_pred() {
+ if Some(poly_trait_ref.def_id()) == sized_trait {
+ types_without_default_bounds.remove(poly_trait_ref.self_ty().skip_binder());
continue;
}
}
let items = predicates.predicates.iter().rev().filter_map(|(pred, span)| {
pred.subst_supertrait(tcx, &trait_ref)
- .to_opt_poly_trait_ref()
- .map(|trait_ref| item.clone_and_push(trait_ref.value, *span))
+ .to_opt_poly_trait_pred()
+ .map(|trait_ref| item.clone_and_push(trait_ref.map_bound(|t| t.trait_ref), *span))
});
debug!("expand_trait_aliases: items={:?}", items.clone());
predicates
.predicates
.iter()
- .filter_map(|(pred, _)| pred.to_opt_poly_trait_ref())
- .map(|trait_ref| trait_ref.value.def_id())
+ .filter_map(|(pred, _)| pred.to_opt_poly_trait_pred())
+ .map(|trait_ref| trait_ref.def_id())
.filter(|&super_def_id| visited.insert(super_def_id)),
);
Some(def_id)
let extend = |obligation: traits::PredicateObligation<'tcx>| {
let mut cause = cause.clone();
- if let Some(parent_trait_ref) = obligation.predicate.to_opt_poly_trait_ref() {
+ if let Some(parent_trait_ref) = obligation.predicate.to_opt_poly_trait_pred() {
let derived_cause = traits::DerivedObligationCause {
- parent_trait_ref: parent_trait_ref.value,
+ // TODO: sus
+ parent_trait_ref: parent_trait_ref.map_bound(|t| t.trait_ref),
parent_code: Lrc::new(obligation.cause.code.clone()),
};
cause.make_mut().code =
traits::transitive_bounds_that_define_assoc_type(
tcx,
predicates.iter().filter_map(|(p, _)| {
- p.to_opt_poly_trait_ref().map(|trait_ref| trait_ref.value)
+ Some(p.to_opt_poly_trait_pred()?.map_bound(|t| t.trait_ref))
}),
assoc_name,
)