span_bug!(cause.span, "unexpected const outlives {:?}", constraint);
}
};
- let predicate =
- predicate.rebind(atom).potentially_quantified(self.tcx, ty::PredicateKind::ForAll);
+ let predicate = predicate.rebind(atom).potentially_quantified(self.tcx);
Obligation::new(cause.clone(), param_env, predicate)
})
let new = ty::PredicateKind::ForAll(tcx.anonymize_late_bound_regions(binder));
tcx.reuse_or_mk_predicate(pred, new)
}
- ty::PredicateKind::Atom(_) => pred,
}
}
computation.add_predicate_atom(atom)
});
}
- ty::PredicateKind::Atom(atom) => self.add_predicate_atom(atom),
}
}
}
#[cfg(target_arch = "x86_64")]
-static_assert_size!(PredicateInner<'_>, 48);
+static_assert_size!(PredicateInner<'_>, 40);
#[derive(Clone, Copy, Lift)]
pub struct Predicate<'tcx> {
pub fn skip_binders(self) -> PredicateAtom<'tcx> {
match self.kind() {
&PredicateKind::ForAll(binder) => binder.skip_binder(),
- &PredicateKind::Atom(atom) => {
- debug_assert!(!atom.has_escaping_bound_vars());
- atom
- }
}
}
pub fn skip_binders_unchecked(self) -> PredicateAtom<'tcx> {
match self.kind() {
&PredicateKind::ForAll(binder) => binder.skip_binder(),
- &PredicateKind::Atom(atom) => atom,
}
}
pub fn bound_atom(self) -> Binder<PredicateAtom<'tcx>> {
match self.kind() {
&PredicateKind::ForAll(binder) => binder,
- &PredicateKind::Atom(atom) => {
- debug_assert!(!atom.has_escaping_bound_vars());
- Binder::dummy(atom)
- }
}
}
/// Allows using a `Binder<PredicateAtom<'tcx>>` even if the given predicate previously
/// contained unbound variables by shifting these variables outwards.
- pub fn bound_atom_with_opt_escaping(self, tcx: TyCtxt<'tcx>) -> Binder<PredicateAtom<'tcx>> {
+ pub fn bound_atom_with_opt_escaping(self, _tcx: TyCtxt<'tcx>) -> Binder<PredicateAtom<'tcx>> {
match self.kind() {
&PredicateKind::ForAll(binder) => binder,
- &PredicateKind::Atom(atom) => Binder::wrap_nonbinding(tcx, atom),
}
}
}
pub enum PredicateKind<'tcx> {
/// `for<'a>: ...`
ForAll(Binder<PredicateAtom<'tcx>>),
- Atom(PredicateAtom<'tcx>),
}
#[derive(Clone, Copy, PartialEq, Eq, Hash, TyEncodable, TyDecodable)]
impl<'tcx> Binder<PredicateAtom<'tcx>> {
/// Wraps `self` with the given qualifier if this predicate has any unbound variables.
- pub fn potentially_quantified(
- self,
- tcx: TyCtxt<'tcx>,
- qualifier: impl FnOnce(Binder<PredicateAtom<'tcx>>) -> PredicateKind<'tcx>,
- ) -> Predicate<'tcx> {
- match self.no_bound_vars() {
- Some(atom) => PredicateKind::Atom(atom),
- None => qualifier(self),
- }
- .to_predicate(tcx)
+ pub fn potentially_quantified(self, tcx: TyCtxt<'tcx>) -> Predicate<'tcx> {
+ PredicateKind::ForAll(self).to_predicate(tcx)
}
}
let substs = trait_ref.skip_binder().substs;
let pred = self.skip_binders();
let new = pred.subst(tcx, substs);
- if new != pred {
- ty::Binder::bind(new).potentially_quantified(tcx, PredicateKind::ForAll)
- } else {
- self
- }
+ if new != pred { ty::Binder::bind(new).potentially_quantified(tcx) } else { self }
}
}
#[inline(always)]
fn to_predicate(self, tcx: TyCtxt<'tcx>) -> Predicate<'tcx> {
debug_assert!(!self.has_escaping_bound_vars(), "escaping bound vars for {:?}", self);
- tcx.mk_predicate(PredicateKind::Atom(self))
+ tcx.mk_predicate(PredicateKind::ForAll(Binder::dummy(self)))
}
}
fn to_predicate(self, tcx: TyCtxt<'tcx>) -> Predicate<'tcx> {
self.value
.map_bound(|value| PredicateAtom::Trait(value, self.constness))
- .potentially_quantified(tcx, PredicateKind::ForAll)
+ .potentially_quantified(tcx)
}
}
impl<'tcx> ToPredicate<'tcx> for PolyRegionOutlivesPredicate<'tcx> {
fn to_predicate(self, tcx: TyCtxt<'tcx>) -> Predicate<'tcx> {
- self.map_bound(PredicateAtom::RegionOutlives)
- .potentially_quantified(tcx, PredicateKind::ForAll)
+ self.map_bound(PredicateAtom::RegionOutlives).potentially_quantified(tcx)
}
}
impl<'tcx> ToPredicate<'tcx> for PolyTypeOutlivesPredicate<'tcx> {
fn to_predicate(self, tcx: TyCtxt<'tcx>) -> Predicate<'tcx> {
- self.map_bound(PredicateAtom::TypeOutlives)
- .potentially_quantified(tcx, PredicateKind::ForAll)
+ self.map_bound(PredicateAtom::TypeOutlives).potentially_quantified(tcx)
}
}
impl<'tcx> ToPredicate<'tcx> for PolyProjectionPredicate<'tcx> {
fn to_predicate(self, tcx: TyCtxt<'tcx>) -> Predicate<'tcx> {
- self.map_bound(PredicateAtom::Projection).potentially_quantified(tcx, PredicateKind::ForAll)
+ self.map_bound(PredicateAtom::Projection).potentially_quantified(tcx)
}
}
ty::Predicate<'tcx> {
match self.kind() {
- &ty::PredicateKind::Atom(atom) => p!(print(atom)),
ty::PredicateKind::ForAll(binder) => p!(print(binder)),
}
}
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match *self {
ty::PredicateKind::ForAll(binder) => write!(f, "ForAll({:?})", binder),
- ty::PredicateKind::Atom(atom) => write!(f, "{:?}", atom),
}
}
}
fn lift_to_tcx(self, tcx: TyCtxt<'tcx>) -> Option<Self::Lifted> {
match self {
ty::PredicateKind::ForAll(binder) => tcx.lift(binder).map(ty::PredicateKind::ForAll),
- ty::PredicateKind::Atom(atom) => tcx.lift(atom).map(ty::PredicateKind::Atom),
}
}
}
let infcx = self.selcx.infcx();
match *obligation.predicate.kind() {
- ty::PredicateKind::ForAll(binder) => match binder.skip_binder() {
- // Evaluation will discard candidates using the leak check.
- // This means we need to pass it the bound version of our
- // predicate.
- ty::PredicateAtom::Trait(trait_ref, _constness) => {
- let trait_obligation = obligation.with(binder.rebind(trait_ref));
-
- self.process_trait_obligation(
- obligation,
- trait_obligation,
- &mut pending_obligation.stalled_on,
- )
- }
- ty::PredicateAtom::Projection(data) => {
- let project_obligation = obligation.with(binder.rebind(data));
+ ty::PredicateKind::ForAll(binder) if binder.skip_binder().has_escaping_bound_vars() => {
+ match binder.skip_binder() {
+ // Evaluation will discard candidates using the leak check.
+ // This means we need to pass it the bound version of our
+ // predicate.
+ ty::PredicateAtom::Trait(trait_ref, _constness) => {
+ let trait_obligation = obligation.with(binder.rebind(trait_ref));
+
+ self.process_trait_obligation(
+ obligation,
+ trait_obligation,
+ &mut pending_obligation.stalled_on,
+ )
+ }
+ ty::PredicateAtom::Projection(data) => {
+ let project_obligation = obligation.with(binder.rebind(data));
- self.process_projection_obligation(
- project_obligation,
- &mut pending_obligation.stalled_on,
- )
- }
- ty::PredicateAtom::RegionOutlives(_)
- | ty::PredicateAtom::TypeOutlives(_)
- | ty::PredicateAtom::WellFormed(_)
- | ty::PredicateAtom::ObjectSafe(_)
- | ty::PredicateAtom::ClosureKind(..)
- | ty::PredicateAtom::Subtype(_)
- | ty::PredicateAtom::ConstEvaluatable(..)
- | ty::PredicateAtom::ConstEquate(..) => {
- let pred = infcx.replace_bound_vars_with_placeholders(binder);
- ProcessResult::Changed(mk_pending(vec![
- obligation.with(pred.to_predicate(self.selcx.tcx())),
- ]))
- }
- ty::PredicateAtom::TypeWellFormedFromEnv(..) => {
- bug!("TypeWellFormedFromEnv is only used for Chalk")
+ self.process_projection_obligation(
+ project_obligation,
+ &mut pending_obligation.stalled_on,
+ )
+ }
+ ty::PredicateAtom::RegionOutlives(_)
+ | ty::PredicateAtom::TypeOutlives(_)
+ | ty::PredicateAtom::WellFormed(_)
+ | ty::PredicateAtom::ObjectSafe(_)
+ | ty::PredicateAtom::ClosureKind(..)
+ | ty::PredicateAtom::Subtype(_)
+ | ty::PredicateAtom::ConstEvaluatable(..)
+ | ty::PredicateAtom::ConstEquate(..) => {
+ let pred = infcx.replace_bound_vars_with_placeholders(binder);
+ ProcessResult::Changed(mk_pending(vec![
+ obligation.with(pred.to_predicate(self.selcx.tcx())),
+ ]))
+ }
+ ty::PredicateAtom::TypeWellFormedFromEnv(..) => {
+ bug!("TypeWellFormedFromEnv is only used for Chalk")
+ }
}
- },
- ty::PredicateKind::Atom(atom) => match atom {
+ }
+ ty::PredicateKind::ForAll(binder) => match binder.skip_binder() {
ty::PredicateAtom::Trait(data, _) => {
let trait_obligation = obligation.with(Binder::dummy(data));
implied_bounds.extend(obligations.into_iter().flat_map(|obligation| {
assert!(!obligation.has_escaping_bound_vars());
match obligation.predicate.kind() {
- &ty::PredicateKind::ForAll(..) => vec![],
- &ty::PredicateKind::Atom(atom) => match atom {
+ &ty::PredicateKind::ForAll(binder)
+ if binder.skip_binder().has_escaping_bound_vars() =>
+ {
+ vec![]
+ }
+ &ty::PredicateKind::ForAll(binder) => match binder.skip_binder() {
ty::PredicateAtom::Trait(..)
| ty::PredicateAtom::Subtype(..)
| ty::PredicateAtom::Projection(..)
let predicate = ty::Binder::bind(ty::PredicateAtom::TypeOutlives(
ty::OutlivesPredicate(ty, re_root_empty),
));
- predicates.insert((
- predicate.potentially_quantified(tcx, ty::PredicateKind::ForAll),
- span,
- ));
+ predicates.insert((predicate.potentially_quantified(tcx), span));
}
}
ty::Binder::bind(ty::PredicateAtom::TypeOutlives(
ty::OutlivesPredicate(ty, region),
))
- .potentially_quantified(tcx, ty::PredicateKind::ForAll),
+ .potentially_quantified(tcx),
lifetime.span,
));
}
let mut pred: Vec<String> = predicates
.iter()
.map(|(out_pred, _)| match out_pred.kind() {
- ty::PredicateKind::Atom(ty::PredicateAtom::RegionOutlives(p)) => {
- p.to_string()
- }
- ty::PredicateKind::Atom(ty::PredicateAtom::TypeOutlives(p)) => {
- p.to_string()
- }
- err => bug!("unexpected predicate {:?}", err),
+ ty::PredicateKind::ForAll(binder) => match binder.skip_binder() {
+ ty::PredicateAtom::RegionOutlives(p) => p.to_string(),
+ ty::PredicateAtom::TypeOutlives(p) => p.to_string(),
+ err => bug!("unexpected predicate {:?}", err),
+ },
})
.collect();
pred.sort();
-error: cannot specialize on `ProjectionPredicate(ProjectionTy { substs: [V], item_def_id: DefId(0:6 ~ repeated_projection_type[317d]::Id::This) }, (I,))`
+error: cannot specialize on `ForAll(Binder(ProjectionPredicate(ProjectionTy { substs: [V], item_def_id: DefId(0:6 ~ repeated_projection_type[317d]::Id::This) }, (I,))))`
--> $DIR/repeated_projection_type.rs:19:1
|
LL | / impl<I, V: Id<This = (I,)>> X for V {
.filter(|p| !p.is_global())
.filter_map(|obligation| {
// Note that we do not want to deal with qualified predicates here.
- if let ty::PredicateKind::Atom(ty::PredicateAtom::Trait(pred, _)) = obligation.predicate.kind() {
- if pred.def_id() == sized_trait {
- return None;
+ let ty::PredicateKind::ForAll(binder) = obligation.predicate.kind();
+ match binder.skip_binder() {
+ ty::PredicateAtom::Trait(pred, _) if !binder.has_escaping_bound_vars() => {
+ if pred.def_id() == sized_trait {
+ return None;
+ }
+ Some(pred)
}
- Some(pred)
- } else {
- None
+ _ => None,
}
})
.collect::<Vec<_>>();