) -> Vec<traits::PredicateObligation<'tcx>> {
let mut wf = WfPredicates { infcx, param_env, body_id, span, out: vec![], item: None };
- // (*) ok to skip binders, because wf code is prepared for it
match predicate.kind() {
- ty::PredicateKind::Trait(t, _) => {
- wf.compute_trait_ref(&t.skip_binder().trait_ref, Elaborate::None); // (*)
+ ty::PredicateKind::ForAll(binder) => {
+ // It's ok to skip the binder here because wf code is prepared for it
+ return predicate_obligations(infcx, param_env, body_id, binder.skip_binder(), span);
}
- ty::PredicateKind::RegionOutlives(..) => {}
- ty::PredicateKind::TypeOutlives(t) => {
- wf.compute(t.skip_binder().0.into());
- }
- ty::PredicateKind::Projection(t) => {
- let t = t.skip_binder(); // (*)
- wf.compute_projection(t.projection_ty);
- wf.compute(t.ty.into());
- }
- &ty::PredicateKind::WellFormed(arg) => {
- wf.compute(arg);
- }
- ty::PredicateKind::ObjectSafe(_) => {}
- ty::PredicateKind::ClosureKind(..) => {}
- ty::PredicateKind::Subtype(data) => {
- wf.compute(data.skip_binder().a.into()); // (*)
- wf.compute(data.skip_binder().b.into()); // (*)
- }
- &ty::PredicateKind::ConstEvaluatable(def_id, substs) => {
- let obligations = wf.nominal_obligations(def_id, substs);
- wf.out.extend(obligations);
-
- for arg in substs.iter() {
+ &ty::PredicateKind::Atom(atom) => match atom {
+ ty::PredicateAtom::Trait(t, _) => {
+ wf.compute_trait_ref(&t.trait_ref, Elaborate::None);
+ }
+ ty::PredicateAtom::RegionOutlives(..) => {}
+ ty::PredicateAtom::TypeOutlives(ty::OutlivesPredicate(ty, _reg)) => {
+ wf.compute(ty.into());
+ }
+ ty::PredicateAtom::Projection(t) => {
+ wf.compute_projection(t.projection_ty);
+ wf.compute(t.ty.into());
+ }
+ ty::PredicateAtom::WellFormed(arg) => {
wf.compute(arg);
}
- }
- &ty::PredicateKind::ConstEquate(c1, c2) => {
- wf.compute(c1.into());
- wf.compute(c2.into());
- }
+ ty::PredicateAtom::ObjectSafe(_) => {}
+ ty::PredicateAtom::ClosureKind(..) => {}
+ ty::PredicateAtom::Subtype(ty::SubtypePredicate { a, b, a_is_expected: _ }) => {
+ wf.compute(a.into());
+ wf.compute(b.into());
+ }
+ ty::PredicateAtom::ConstEvaluatable(def, substs) => {
+ let obligations = wf.nominal_obligations(def.did, substs);
+ wf.out.extend(obligations);
+
+ for arg in substs.iter() {
+ wf.compute(arg);
+ }
+ }
+ ty::PredicateAtom::ConstEquate(c1, c2) => {
+ wf.compute(c1.into());
+ wf.compute(c2.into());
+ }
+ },
}
wf.normalize()
trait_ref: &ty::TraitRef<'tcx>,
item: Option<&hir::Item<'tcx>>,
cause: &mut traits::ObligationCause<'tcx>,
- pred: &ty::Predicate<'_>,
+ pred: &ty::Predicate<'tcx>,
mut trait_assoc_items: impl Iterator<Item = &'tcx ty::AssocItem>,
) {
debug!(
hir::ImplItemKind::Const(ty, _) | hir::ImplItemKind::TyAlias(ty) => ty.span,
_ => impl_item_ref.span,
};
- match pred.kind() {
- ty::PredicateKind::Projection(proj) => {
+
+ // It is fine to skip the binder as we don't care about regions here.
+ match pred.skip_binders() {
+ ty::PredicateAtom::Projection(proj) => {
// The obligation comes not from the current `impl` nor the `trait` being implemented,
// but rather from a "second order" obligation, where an associated type has a
// projection coming from another associated type. See
// `src/test/ui/associated-types/point-at-type-on-obligation-failure.rs` and
// `traits-assoc-type-in-supertrait-bad.rs`.
- let kind = &proj.ty().skip_binder().kind;
- if let ty::Projection(projection_ty) = kind {
+ if let ty::Projection(projection_ty) = proj.ty.kind {
let trait_assoc_item = tcx.associated_item(projection_ty.item_def_id);
if let Some(impl_item_span) =
items.iter().find(|item| item.ident == trait_assoc_item.ident).map(fix_span)
}
}
}
- ty::PredicateKind::Trait(pred, _) => {
+ ty::PredicateAtom::Trait(pred, _) => {
// An associated item obligation born out of the `trait` failed to be met. An example
// can be seen in `ui/associated-types/point-at-type-on-obligation-failure-2.rs`.
debug!("extended_cause_with_original_assoc_item_obligation trait proj {:?}", pred);
- if let ty::Projection(ty::ProjectionTy { item_def_id, .. }) =
- &pred.skip_binder().self_ty().kind
- {
+ if let ty::Projection(ty::ProjectionTy { item_def_id, .. }) = pred.self_ty().kind {
if let Some(impl_item_span) = trait_assoc_items
- .find(|i| i.def_id == *item_def_id)
+ .find(|i| i.def_id == item_def_id)
.and_then(|trait_assoc_item| {
items.iter().find(|i| i.ident == trait_assoc_item.ident).map(fix_span)
})
trait_ref
.substs
.iter()
- .filter(|arg| {
+ .enumerate()
+ .filter(|(_, arg)| {
matches!(arg.unpack(), GenericArgKind::Type(..) | GenericArgKind::Const(..))
})
- .filter(|arg| !arg.has_escaping_bound_vars())
- .map(|arg| {
+ .filter(|(_, arg)| !arg.has_escaping_bound_vars())
+ .map(|(i, arg)| {
+ let mut new_cause = cause.clone();
+ // The first subst is the self ty - use the correct span for it.
+ if i == 0 {
+ if let Some(hir::ItemKind::Impl { self_ty, .. }) = item.map(|i| &i.kind) {
+ new_cause.make_mut().span = self_ty.span;
+ }
+ }
traits::Obligation::new(
- cause.clone(),
+ new_cause,
param_env,
- ty::PredicateKind::WellFormed(arg).to_predicate(tcx),
+ ty::PredicateAtom::WellFormed(arg).to_predicate(tcx),
)
}),
);
let obligations = self.nominal_obligations(def.did, substs);
self.out.extend(obligations);
- let predicate = ty::PredicateKind::ConstEvaluatable(def.did, substs)
+ let predicate = ty::PredicateAtom::ConstEvaluatable(def, substs)
.to_predicate(self.tcx());
let cause = self.cause(traits::MiscObligation);
self.out.push(traits::Obligation::new(
self.out.push(traits::Obligation::new(
cause,
self.param_env,
- ty::PredicateKind::WellFormed(resolved_constant.into())
+ ty::PredicateAtom::WellFormed(resolved_constant.into())
.to_predicate(self.tcx()),
));
}
self.out.push(traits::Obligation::new(
cause,
param_env,
- ty::PredicateKind::TypeOutlives(ty::Binder::dummy(
- ty::OutlivesPredicate(rty, r),
- ))
- .to_predicate(self.tcx()),
+ ty::PredicateAtom::TypeOutlives(ty::OutlivesPredicate(rty, r))
+ .to_predicate(self.tcx()),
));
}
}
traits::Obligation::new(
cause.clone(),
param_env,
- ty::PredicateKind::ObjectSafe(did).to_predicate(tcx),
+ ty::PredicateAtom::ObjectSafe(did).to_predicate(tcx),
)
}));
}
self.out.push(traits::Obligation::new(
cause,
param_env,
- ty::PredicateKind::WellFormed(ty.into()).to_predicate(self.tcx()),
+ ty::PredicateAtom::WellFormed(ty.into()).to_predicate(self.tcx()),
));
} else {
// Yes, resolved, proceed with the result.