summaryrefslogtreecommitdiffstats
path: root/compiler/rustc_trait_selection/src/traits/wf.rs
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/rustc_trait_selection/src/traits/wf.rs')
-rw-r--r--compiler/rustc_trait_selection/src/traits/wf.rs102
1 files changed, 67 insertions, 35 deletions
diff --git a/compiler/rustc_trait_selection/src/traits/wf.rs b/compiler/rustc_trait_selection/src/traits/wf.rs
index fc0a9f690..681fb753f 100644
--- a/compiler/rustc_trait_selection/src/traits/wf.rs
+++ b/compiler/rustc_trait_selection/src/traits/wf.rs
@@ -4,7 +4,7 @@ use rustc_hir as hir;
use rustc_hir::def_id::DefId;
use rustc_hir::lang_items::LangItem;
use rustc_middle::ty::subst::{GenericArg, GenericArgKind, SubstsRef};
-use rustc_middle::ty::{self, ToPredicate, Ty, TyCtxt, TypeVisitable};
+use rustc_middle::ty::{self, Ty, TyCtxt, TypeVisitable};
use rustc_span::Span;
use std::iter;
@@ -121,14 +121,14 @@ pub fn predicate_obligations<'tcx>(
// It's ok to skip the binder here because wf code is prepared for it
match predicate.kind().skip_binder() {
- ty::PredicateKind::Trait(t) => {
+ ty::PredicateKind::Clause(ty::Clause::Trait(t)) => {
wf.compute_trait_pred(&t, Elaborate::None);
}
- ty::PredicateKind::RegionOutlives(..) => {}
- ty::PredicateKind::TypeOutlives(ty::OutlivesPredicate(ty, _reg)) => {
+ ty::PredicateKind::Clause(ty::Clause::RegionOutlives(..)) => {}
+ ty::PredicateKind::Clause(ty::Clause::TypeOutlives(ty::OutlivesPredicate(ty, _reg))) => {
wf.compute(ty.into());
}
- ty::PredicateKind::Projection(t) => {
+ ty::PredicateKind::Clause(ty::Clause::Projection(t)) => {
wf.compute_projection(t.projection_ty);
wf.compute(match t.term.unpack() {
ty::TermKind::Ty(ty) => ty.into(),
@@ -155,6 +155,7 @@ pub fn predicate_obligations<'tcx>(
wf.compute(c1.into());
wf.compute(c2.into());
}
+ ty::PredicateKind::Ambiguous => {}
ty::PredicateKind::TypeWellFormedFromEnv(..) => {
bug!("TypeWellFormedFromEnv is only used for Chalk")
}
@@ -227,7 +228,7 @@ fn extend_cause_with_original_assoc_item_obligation<'tcx>(
// It is fine to skip the binder as we don't care about regions here.
match pred.kind().skip_binder() {
- ty::PredicateKind::Projection(proj) => {
+ ty::PredicateKind::Clause(ty::Clause::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
@@ -244,7 +245,7 @@ fn extend_cause_with_original_assoc_item_obligation<'tcx>(
cause.span = impl_item_span;
}
}
- ty::PredicateKind::Trait(pred) => {
+ ty::PredicateKind::Clause(ty::Clause::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);
@@ -324,7 +325,7 @@ impl<'tcx> WfPredicates<'tcx> {
extend_cause_with_original_assoc_item_obligation(
tcx, trait_ref, item, &mut cause, predicate,
);
- traits::Obligation::with_depth(cause, depth, param_env, predicate)
+ traits::Obligation::with_depth(tcx, cause, depth, param_env, predicate)
};
if let Elaborate::All = elaborate {
@@ -356,10 +357,11 @@ impl<'tcx> WfPredicates<'tcx> {
}
}
traits::Obligation::with_depth(
+ tcx,
cause,
depth,
param_env,
- ty::Binder::dummy(ty::PredicateKind::WellFormed(arg)).to_predicate(tcx),
+ ty::Binder::dummy(ty::PredicateKind::WellFormed(arg)),
)
}),
);
@@ -407,10 +409,11 @@ impl<'tcx> WfPredicates<'tcx> {
.filter(|arg| !arg.has_escaping_bound_vars())
.map(|arg| {
traits::Obligation::with_depth(
+ tcx,
cause.clone(),
depth,
param_env,
- ty::Binder::dummy(ty::PredicateKind::WellFormed(arg)).to_predicate(tcx),
+ ty::Binder::dummy(ty::PredicateKind::WellFormed(arg)),
)
}),
);
@@ -419,15 +422,13 @@ impl<'tcx> WfPredicates<'tcx> {
fn require_sized(&mut self, subty: Ty<'tcx>, cause: traits::ObligationCauseCode<'tcx>) {
if !subty.has_escaping_bound_vars() {
let cause = self.cause(cause);
- let trait_ref = ty::TraitRef {
- def_id: self.tcx.require_lang_item(LangItem::Sized, None),
- substs: self.tcx.mk_substs_trait(subty, &[]),
- };
+ let trait_ref = self.tcx.at(cause.span).mk_trait_ref(LangItem::Sized, [subty]);
self.out.push(traits::Obligation::with_depth(
+ self.tcx,
cause,
self.recursion_depth,
self.param_env,
- ty::Binder::dummy(trait_ref).without_const().to_predicate(self.tcx),
+ ty::Binder::dummy(trait_ref).without_const(),
));
}
}
@@ -454,10 +455,10 @@ impl<'tcx> WfPredicates<'tcx> {
self.out.extend(obligations);
let predicate =
- ty::Binder::dummy(ty::PredicateKind::ConstEvaluatable(ct))
- .to_predicate(self.tcx());
+ ty::Binder::dummy(ty::PredicateKind::ConstEvaluatable(ct));
let cause = self.cause(traits::WellFormed(None));
self.out.push(traits::Obligation::with_depth(
+ self.tcx(),
cause,
self.recursion_depth,
self.param_env,
@@ -468,13 +469,33 @@ impl<'tcx> WfPredicates<'tcx> {
let cause = self.cause(traits::WellFormed(None));
self.out.push(traits::Obligation::with_depth(
+ self.tcx(),
cause,
self.recursion_depth,
self.param_env,
- ty::Binder::dummy(ty::PredicateKind::WellFormed(ct.into()))
- .to_predicate(self.tcx()),
+ ty::Binder::dummy(ty::PredicateKind::WellFormed(ct.into())),
));
}
+ ty::ConstKind::Expr(_) => {
+ // FIXME(generic_const_exprs): this doesnt verify that given `Expr(N + 1)` the
+ // trait bound `typeof(N): Add<typeof(1)>` holds. This is currently unnecessary
+ // as `ConstKind::Expr` is only produced via normalization of `ConstKind::Unevaluated`
+ // which means that the `DefId` would have been typeck'd elsewhere. However in
+ // the future we may allow directly lowering to `ConstKind::Expr` in which case
+ // we would not be proving bounds we should.
+
+ let predicate =
+ ty::Binder::dummy(ty::PredicateKind::ConstEvaluatable(ct));
+ let cause = self.cause(traits::WellFormed(None));
+ self.out.push(traits::Obligation::with_depth(
+ self.tcx(),
+ cause,
+ self.recursion_depth,
+ self.param_env,
+ predicate,
+ ));
+ }
+
ty::ConstKind::Error(_)
| ty::ConstKind::Param(_)
| ty::ConstKind::Bound(..)
@@ -556,13 +577,13 @@ impl<'tcx> WfPredicates<'tcx> {
if !r.has_escaping_bound_vars() && !rty.has_escaping_bound_vars() {
let cause = self.cause(traits::ReferenceOutlivesReferent(ty));
self.out.push(traits::Obligation::with_depth(
+ self.tcx(),
cause,
depth,
param_env,
- ty::Binder::dummy(ty::PredicateKind::TypeOutlives(
+ ty::Binder::dummy(ty::PredicateKind::Clause(ty::Clause::TypeOutlives(
ty::OutlivesPredicate(rty, r),
- ))
- .to_predicate(self.tcx()),
+ ))),
));
}
}
@@ -631,7 +652,7 @@ impl<'tcx> WfPredicates<'tcx> {
// All of the requirements on type parameters
// have already been checked for `impl Trait` in
// return position. We do need to check type-alias-impl-trait though.
- if ty::is_impl_trait_defn(self.tcx, did).is_none() {
+ if self.tcx.is_type_alias_impl_trait(did) {
let obligations = self.nominal_obligations(did, substs);
self.out.extend(obligations);
}
@@ -656,11 +677,11 @@ impl<'tcx> WfPredicates<'tcx> {
let tcx = self.tcx();
self.out.extend(component_traits.map(|did| {
traits::Obligation::with_depth(
+ tcx,
cause.clone(),
depth,
param_env,
- ty::Binder::dummy(ty::PredicateKind::ObjectSafe(did))
- .to_predicate(tcx),
+ ty::Binder::dummy(ty::PredicateKind::ObjectSafe(did)),
)
}));
}
@@ -681,11 +702,11 @@ impl<'tcx> WfPredicates<'tcx> {
ty::Infer(_) => {
let cause = self.cause(traits::WellFormed(None));
self.out.push(traits::Obligation::with_depth(
+ self.tcx(),
cause,
self.recursion_depth,
param_env,
- ty::Binder::dummy(ty::PredicateKind::WellFormed(ty.into()))
- .to_predicate(self.tcx()),
+ ty::Binder::dummy(ty::PredicateKind::WellFormed(ty.into())),
));
}
}
@@ -724,7 +745,13 @@ impl<'tcx> WfPredicates<'tcx> {
if remap_constness {
pred = pred.without_const(self.tcx);
}
- traits::Obligation::with_depth(cause, self.recursion_depth, self.param_env, pred)
+ traits::Obligation::with_depth(
+ self.tcx,
+ cause,
+ self.recursion_depth,
+ self.param_env,
+ pred,
+ )
})
.filter(|pred| !pred.has_escaping_bound_vars())
.collect()
@@ -749,7 +776,7 @@ impl<'tcx> WfPredicates<'tcx> {
fn from_object_ty(
&mut self,
ty: Ty<'tcx>,
- data: &'tcx ty::List<ty::Binder<'tcx, ty::ExistentialPredicate<'tcx>>>,
+ data: &'tcx ty::List<ty::PolyExistentialPredicate<'tcx>>,
region: ty::Region<'tcx>,
) {
// Imagine a type like this:
@@ -794,10 +821,11 @@ impl<'tcx> WfPredicates<'tcx> {
let outlives =
ty::Binder::dummy(ty::OutlivesPredicate(explicit_bound, implicit_bound));
self.out.push(traits::Obligation::with_depth(
+ self.tcx,
cause,
self.recursion_depth,
self.param_env,
- outlives.to_predicate(self.tcx),
+ outlives,
));
}
}
@@ -812,7 +840,7 @@ impl<'tcx> WfPredicates<'tcx> {
/// `infer::required_region_bounds`, see that for more information.
pub fn object_region_bounds<'tcx>(
tcx: TyCtxt<'tcx>,
- existential_predicates: &'tcx ty::List<ty::Binder<'tcx, ty::ExistentialPredicate<'tcx>>>,
+ existential_predicates: &'tcx ty::List<ty::PolyExistentialPredicate<'tcx>>,
) -> Vec<ty::Region<'tcx>> {
// Since we don't actually *know* the self type for an object,
// this "open(err)" serves as a kind of dummy standin -- basically
@@ -858,18 +886,22 @@ pub(crate) fn required_region_bounds<'tcx>(
.filter_map(|obligation| {
debug!(?obligation);
match obligation.predicate.kind().skip_binder() {
- ty::PredicateKind::Projection(..)
- | ty::PredicateKind::Trait(..)
+ ty::PredicateKind::Clause(ty::Clause::Projection(..))
+ | ty::PredicateKind::Clause(ty::Clause::Trait(..))
| ty::PredicateKind::Subtype(..)
| ty::PredicateKind::Coerce(..)
| ty::PredicateKind::WellFormed(..)
| ty::PredicateKind::ObjectSafe(..)
| ty::PredicateKind::ClosureKind(..)
- | ty::PredicateKind::RegionOutlives(..)
+ | ty::PredicateKind::Clause(ty::Clause::RegionOutlives(..))
| ty::PredicateKind::ConstEvaluatable(..)
| ty::PredicateKind::ConstEquate(..)
+ | ty::PredicateKind::Ambiguous
| ty::PredicateKind::TypeWellFormedFromEnv(..) => None,
- ty::PredicateKind::TypeOutlives(ty::OutlivesPredicate(ref t, ref r)) => {
+ ty::PredicateKind::Clause(ty::Clause::TypeOutlives(ty::OutlivesPredicate(
+ ref t,
+ ref r,
+ ))) => {
// Search for a bound of the form `erased_self_ty
// : 'a`, but be wary of something like `for<'a>
// erased_self_ty : 'a` (we interpret a