use crate::traits::{Obligation, ObligationCause, PredicateObligation};
use rustc_data_structures::fx::FxHashSet;
use rustc_middle::ty::outlives::Component;
-use rustc_middle::ty::{self, ToPolyTraitRef, ToPredicate, TyCtxt, WithConstness};
+use rustc_middle::ty::{self, ToPredicate, TyCtxt, WithConstness};
use rustc_span::Span;
pub fn anonymize_predicate<'tcx>(
) -> ty::Predicate<'tcx> {
let kind = pred.kind();
let new = match kind {
- &ty::PredicateKind::Trait(ref data, constness) => {
- ty::PredicateKind::Trait(tcx.anonymize_late_bound_regions(data), constness)
+ ty::PredicateKind::ForAll(binder) => {
+ ty::PredicateKind::ForAll(tcx.anonymize_late_bound_regions(binder))
}
+ &ty::PredicateKind::Trait(data, constness) => ty::PredicateKind::Trait(data, constness),
- ty::PredicateKind::RegionOutlives(data) => {
- ty::PredicateKind::RegionOutlives(tcx.anonymize_late_bound_regions(data))
- }
+ &ty::PredicateKind::RegionOutlives(data) => ty::PredicateKind::RegionOutlives(data),
- ty::PredicateKind::TypeOutlives(data) => {
- ty::PredicateKind::TypeOutlives(tcx.anonymize_late_bound_regions(data))
- }
+ &ty::PredicateKind::TypeOutlives(data) => ty::PredicateKind::TypeOutlives(data),
- ty::PredicateKind::Projection(data) => {
- ty::PredicateKind::Projection(tcx.anonymize_late_bound_regions(data))
- }
+ &ty::PredicateKind::Projection(data) => ty::PredicateKind::Projection(data),
&ty::PredicateKind::WellFormed(data) => ty::PredicateKind::WellFormed(data),
ty::PredicateKind::ClosureKind(closure_def_id, closure_substs, kind)
}
- ty::PredicateKind::Subtype(data) => {
- ty::PredicateKind::Subtype(tcx.anonymize_late_bound_regions(data))
- }
+ &ty::PredicateKind::Subtype(data) => ty::PredicateKind::Subtype(data),
&ty::PredicateKind::ConstEvaluatable(def_id, substs) => {
ty::PredicateKind::ConstEvaluatable(def_id, substs)
}
- ty::PredicateKind::ConstEquate(c1, c2) => ty::PredicateKind::ConstEquate(c1, c2),
+ &ty::PredicateKind::ConstEquate(c1, c2) => ty::PredicateKind::ConstEquate(c1, c2),
};
if new != *kind { new.to_predicate(tcx) } else { pred }
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.
}
impl Elaborator<'tcx> {
- pub fn filter_to_traits(self) -> FilterToTraits<Self> {
- FilterToTraits::new(self)
+ pub fn filter_to_traits(self) -> FilterToTraits<'tcx, Self> {
+ FilterToTraits::new(self.visited.tcx, self)
}
fn elaborate(&mut self, obligation: &PredicateObligation<'tcx>) {
let tcx = self.visited.tcx;
- match obligation.predicate.kind() {
- ty::PredicateKind::Trait(ref data, _) => {
+
+ match obligation.predicate.ignore_qualifiers(tcx).skip_binder().kind() {
+ ty::PredicateKind::ForAll(_) => {
+ bug!("unexpected predicate: {:?}", obligation.predicate)
+ }
+ ty::PredicateKind::Trait(data, _) => {
// Get predicates declared on the trait.
let predicates = tcx.super_predicates_of(data.def_id());
- let obligations = predicates.predicates.iter().map(|(pred, span)| {
+ let obligations = predicates.predicates.iter().map(|&(pred, span)| {
predicate_obligation(
- pred.subst_supertrait(tcx, &data.to_poly_trait_ref()),
- Some(*span),
+ pred.subst_supertrait(tcx, &ty::Binder::bind(data.trait_ref)),
+ Some(span),
)
});
debug!("super_predicates: data={:?}", data);
ty::PredicateKind::RegionOutlives(..) => {
// Nothing to elaborate from `'a: 'b`.
}
- ty::PredicateKind::TypeOutlives(ref data) => {
+ ty::PredicateKind::TypeOutlives(ty::OutlivesPredicate(ty_max, r_min)) => {
// We know that `T: 'a` for some type `T`. We can
// often elaborate this. For example, if we know that
// `[U]: 'a`, that implies that `U: 'a`. Similarly, if
// consider this as evidence that `T: 'static`, but
// I'm a bit wary of such constructions and so for now
// I want to be conservative. --nmatsakis
- let ty_max = data.skip_binder().0;
- let r_min = data.skip_binder().1;
if r_min.is_late_bound() {
return;
}
if r.is_late_bound() {
None
} else {
- Some(ty::PredicateKind::RegionOutlives(ty::Binder::dummy(
- ty::OutlivesPredicate(r, r_min),
+ Some(ty::PredicateKind::RegionOutlives(ty::OutlivesPredicate(
+ r, r_min,
)))
}
}
Component::Param(p) => {
let ty = tcx.mk_ty_param(p.index, p.name);
- Some(ty::PredicateKind::TypeOutlives(ty::Binder::dummy(
- ty::OutlivesPredicate(ty, r_min),
+ Some(ty::PredicateKind::TypeOutlives(ty::OutlivesPredicate(
+ ty, r_min,
)))
}
// Supertrait iterator
///////////////////////////////////////////////////////////////////////////
-pub type Supertraits<'tcx> = FilterToTraits<Elaborator<'tcx>>;
+pub type Supertraits<'tcx> = FilterToTraits<'tcx, Elaborator<'tcx>>;
pub fn supertraits<'tcx>(
tcx: TyCtxt<'tcx>,
/// A filter around an iterator of predicates that makes it yield up
/// just trait references.
-pub struct FilterToTraits<I> {
+pub struct FilterToTraits<'tcx, I> {
+ tcx: TyCtxt<'tcx>,
base_iterator: I,
}
-impl<I> FilterToTraits<I> {
- fn new(base: I) -> FilterToTraits<I> {
- FilterToTraits { base_iterator: base }
+impl<'tcx, I> FilterToTraits<'tcx, I> {
+ fn new(tcx: TyCtxt<'tcx>, base: I) -> FilterToTraits<'tcx, I> {
+ FilterToTraits { tcx, base_iterator: base }
}
}
-impl<'tcx, I: Iterator<Item = PredicateObligation<'tcx>>> Iterator for FilterToTraits<I> {
+impl<'tcx, I: Iterator<Item = PredicateObligation<'tcx>>> Iterator for FilterToTraits<'tcx, I> {
type Item = ty::PolyTraitRef<'tcx>;
fn next(&mut self) -> Option<ty::PolyTraitRef<'tcx>> {
while let Some(obligation) = self.base_iterator.next() {
- if let ty::PredicateKind::Trait(data, _) = obligation.predicate.kind() {
- return Some(data.to_poly_trait_ref());
+ if let Some(data) = obligation.predicate.to_opt_poly_trait_ref(self.tcx) {
+ return Some(data);
}
}
None