Auto merge of #104846 - spastorino:santa-clauses-make-goals-early-christmas-🎄, r=oli-obk

Branch Clause from Predicate

r? `@oli-obk`

This is part of what's proposed in https://github.com/rust-lang/compiler-team/issues/531
This commit is contained in:
bors 2022-11-25 15:59:31 +00:00
commit 051cab2b84
85 changed files with 625 additions and 496 deletions

View file

@ -131,7 +131,7 @@ impl<'a, 'tcx> Autoderef<'a, 'tcx> {
tcx,
cause.clone(),
self.param_env,
ty::Binder::dummy(trait_ref).without_const(),
ty::Binder::dummy(trait_ref),
);
if !self.infcx.predicate_may_hold(&obligation) {
debug!("overloaded_deref_ty: cannot match obligation");

View file

@ -10,7 +10,7 @@ use crate::traits::project::ProjectAndUnifyResult;
use rustc_middle::mir::interpret::ErrorHandled;
use rustc_middle::ty::fold::{TypeFolder, TypeSuperFoldable};
use rustc_middle::ty::visit::TypeVisitable;
use rustc_middle::ty::{PolyTraitRef, Region, RegionVid};
use rustc_middle::ty::{ImplPolarity, Region, RegionVid};
use rustc_data_structures::fx::{FxHashMap, FxHashSet, FxIndexSet};
@ -88,19 +88,22 @@ impl<'tcx> AutoTraitFinder<'tcx> {
let trait_ref = tcx.mk_trait_ref(trait_did, [ty]);
let trait_pred = ty::Binder::dummy(trait_ref);
let infcx = tcx.infer_ctxt().build();
let mut selcx = SelectionContext::new(&infcx);
for f in [
PolyTraitRef::to_poly_trait_predicate,
PolyTraitRef::to_poly_trait_predicate_negative_polarity,
] {
for polarity in [true, false] {
let result = selcx.select(&Obligation::new(
tcx,
ObligationCause::dummy(),
orig_env,
f(&trait_pred),
ty::Binder::dummy(ty::TraitPredicate {
trait_ref,
constness: ty::BoundConstness::NotConst,
polarity: if polarity {
ImplPolarity::Positive
} else {
ImplPolarity::Negative
},
}),
));
if let Ok(Some(ImplSource::UserDefined(_))) = result {
debug!(
@ -400,8 +403,10 @@ impl<'tcx> AutoTraitFinder<'tcx> {
) {
let mut should_add_new = true;
user_computed_preds.retain(|&old_pred| {
if let (ty::PredicateKind::Trait(new_trait), ty::PredicateKind::Trait(old_trait)) =
(new_pred.kind().skip_binder(), old_pred.kind().skip_binder())
if let (
ty::PredicateKind::Clause(ty::Clause::Trait(new_trait)),
ty::PredicateKind::Clause(ty::Clause::Trait(old_trait)),
) = (new_pred.kind().skip_binder(), old_pred.kind().skip_binder())
{
if new_trait.def_id() == old_trait.def_id() {
let new_substs = new_trait.trait_ref.substs;
@ -621,14 +626,14 @@ impl<'tcx> AutoTraitFinder<'tcx> {
let bound_predicate = predicate.kind();
match bound_predicate.skip_binder() {
ty::PredicateKind::Trait(p) => {
ty::PredicateKind::Clause(ty::Clause::Trait(p)) => {
// Add this to `predicates` so that we end up calling `select`
// with it. If this predicate ends up being unimplemented,
// then `evaluate_predicates` will handle adding it the `ParamEnv`
// if possible.
predicates.push_back(bound_predicate.rebind(p));
}
ty::PredicateKind::Projection(p) => {
ty::PredicateKind::Clause(ty::Clause::Projection(p)) => {
let p = bound_predicate.rebind(p);
debug!(
"evaluate_nested_obligations: examining projection predicate {:?}",
@ -761,11 +766,11 @@ impl<'tcx> AutoTraitFinder<'tcx> {
}
}
}
ty::PredicateKind::RegionOutlives(binder) => {
ty::PredicateKind::Clause(ty::Clause::RegionOutlives(binder)) => {
let binder = bound_predicate.rebind(binder);
select.infcx().region_outlives_predicate(&dummy_cause, binder)
}
ty::PredicateKind::TypeOutlives(binder) => {
ty::PredicateKind::Clause(ty::Clause::TypeOutlives(binder)) => {
let binder = bound_predicate.rebind(binder);
match (
binder.no_bound_vars(),

View file

@ -39,8 +39,7 @@ pub fn codegen_select_candidate<'tcx>(
let mut selcx = SelectionContext::new(&infcx);
let obligation_cause = ObligationCause::dummy();
let obligation =
Obligation::new(tcx, obligation_cause, param_env, trait_ref.to_poly_trait_predicate());
let obligation = Obligation::new(tcx, obligation_cause, param_env, trait_ref);
let selection = match selcx.select(&obligation) {
Ok(Some(selection)) => selection,

View file

@ -587,7 +587,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
let bound_predicate = obligation.predicate.kind();
match bound_predicate.skip_binder() {
ty::PredicateKind::Trait(trait_predicate) => {
ty::PredicateKind::Clause(ty::Clause::Trait(trait_predicate)) => {
let trait_predicate = bound_predicate.rebind(trait_predicate);
let mut trait_predicate = self.resolve_vars_if_possible(trait_predicate);
@ -1051,9 +1051,9 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
span_bug!(span, "coerce requirement gave wrong error: `{:?}`", predicate)
}
ty::PredicateKind::RegionOutlives(..)
| ty::PredicateKind::Projection(..)
| ty::PredicateKind::TypeOutlives(..) => {
ty::PredicateKind::Clause(ty::Clause::RegionOutlives(..))
| ty::PredicateKind::Clause(ty::Clause::Projection(..))
| ty::PredicateKind::Clause(ty::Clause::TypeOutlives(..)) => {
let predicate = self.resolve_vars_if_possible(obligation.predicate);
struct_span_err!(
self.tcx.sess,
@ -1473,9 +1473,10 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
// FIXME: It should be possible to deal with `ForAll` in a cleaner way.
let bound_error = error.kind();
let (cond, error) = match (cond.kind().skip_binder(), bound_error.skip_binder()) {
(ty::PredicateKind::Trait(..), ty::PredicateKind::Trait(error)) => {
(cond, bound_error.rebind(error))
}
(
ty::PredicateKind::Clause(ty::Clause::Trait(..)),
ty::PredicateKind::Clause(ty::Clause::Trait(error)),
) => (cond, bound_error.rebind(error)),
_ => {
// FIXME: make this work in other cases too.
return false;
@ -1484,7 +1485,9 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
for obligation in super::elaborate_predicates(self.tcx, std::iter::once(cond)) {
let bound_predicate = obligation.predicate.kind();
if let ty::PredicateKind::Trait(implication) = bound_predicate.skip_binder() {
if let ty::PredicateKind::Clause(ty::Clause::Trait(implication)) =
bound_predicate.skip_binder()
{
let error = error.to_poly_trait_ref();
let implication = bound_predicate.rebind(implication.trait_ref);
// FIXME: I'm just not taking associated types at all here.
@ -1581,7 +1584,9 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
// this can fail if the problem was higher-ranked, in which
// cause I have no idea for a good error message.
let bound_predicate = predicate.kind();
if let ty::PredicateKind::Projection(data) = bound_predicate.skip_binder() {
if let ty::PredicateKind::Clause(ty::Clause::Projection(data)) =
bound_predicate.skip_binder()
{
let mut selcx = SelectionContext::new(self);
let data = self.replace_bound_vars_with_fresh_vars(
obligation.cause.span,
@ -1629,7 +1634,7 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
let mut diag = struct_span_err!(self.tcx.sess, obligation.cause.span, E0271, "{msg}");
let secondary_span = match predicate.kind().skip_binder() {
ty::PredicateKind::Projection(proj) => self
ty::PredicateKind::Clause(ty::Clause::Projection(proj)) => self
.tcx
.opt_associated_item(proj.projection_ty.item_def_id)
.and_then(|trait_assoc_item| {
@ -2047,7 +2052,7 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
let bound_predicate = predicate.kind();
let mut err = match bound_predicate.skip_binder() {
ty::PredicateKind::Trait(data) => {
ty::PredicateKind::Clause(ty::Clause::Trait(data)) => {
let trait_ref = bound_predicate.rebind(data.trait_ref);
debug!(?trait_ref);
@ -2111,7 +2116,7 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
)
};
let obligation = obligation.with(self.tcx, trait_ref.to_poly_trait_predicate());
let obligation = obligation.with(self.tcx, trait_ref);
let mut selcx = SelectionContext::new(&self);
match selcx.select_from_obligation(&obligation) {
Ok(None) => {
@ -2324,7 +2329,7 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
assert!(a.is_ty_var() && b.is_ty_var());
self.emit_inference_failure_err(body_id, span, a.into(), ErrorCode::E0282, true)
}
ty::PredicateKind::Projection(data) => {
ty::PredicateKind::Clause(ty::Clause::Projection(data)) => {
if predicate.references_error() || self.tainted_by_errors().is_some() {
return;
}
@ -2570,7 +2575,7 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
err: &mut Diagnostic,
obligation: &PredicateObligation<'tcx>,
) {
let ty::PredicateKind::Trait(pred) = obligation.predicate.kind().skip_binder() else { return; };
let ty::PredicateKind::Clause(ty::Clause::Trait(pred)) = obligation.predicate.kind().skip_binder() else { return; };
let (ObligationCauseCode::BindingObligation(item_def_id, span)
| ObligationCauseCode::ExprBindingObligation(item_def_id, span, ..))
= *obligation.cause.code().peel_derives() else { return; };

View file

@ -810,7 +810,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
err: &mut Diagnostic,
trait_pred: ty::PolyTraitPredicate<'tcx>,
) -> bool {
if let ty::PredicateKind::Trait(trait_pred) = obligation.predicate.kind().skip_binder()
if let ty::PredicateKind::Clause(ty::Clause::Trait(trait_pred)) = obligation.predicate.kind().skip_binder()
&& Some(trait_pred.def_id()) == self.tcx.lang_items().sized_trait()
{
// Don't suggest calling to turn an unsized type into a sized type
@ -839,7 +839,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
}
ty::Opaque(def_id, substs) => {
self.tcx.bound_item_bounds(def_id).subst(self.tcx, substs).iter().find_map(|pred| {
if let ty::PredicateKind::Projection(proj) = pred.kind().skip_binder()
if let ty::PredicateKind::Clause(ty::Clause::Projection(proj)) = pred.kind().skip_binder()
&& Some(proj.projection_ty.item_def_id) == self.tcx.lang_items().fn_once_output()
// args tuple will always be substs[1]
&& let ty::Tuple(args) = proj.projection_ty.substs.type_at(1).kind()
@ -873,7 +873,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
}
ty::Param(_) => {
obligation.param_env.caller_bounds().iter().find_map(|pred| {
if let ty::PredicateKind::Projection(proj) = pred.kind().skip_binder()
if let ty::PredicateKind::Clause(ty::Clause::Projection(proj)) = pred.kind().skip_binder()
&& Some(proj.projection_ty.item_def_id) == self.tcx.lang_items().fn_once_output()
&& proj.projection_ty.self_ty() == found
// args tuple will always be substs[1]
@ -1256,7 +1256,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
);
// FIXME: account for associated `async fn`s.
if let hir::Expr { span, kind: hir::ExprKind::Call(base, _), .. } = expr {
if let ty::PredicateKind::Trait(pred) =
if let ty::PredicateKind::Clause(ty::Clause::Trait(pred)) =
obligation.predicate.kind().skip_binder()
{
err.span_label(
@ -1755,7 +1755,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
if let ObligationCauseCode::ExprBindingObligation(def_id, _, _, idx) = cause
&& let predicates = self.tcx.predicates_of(def_id).instantiate_identity(self.tcx)
&& let Some(pred) = predicates.predicates.get(*idx)
&& let ty::PredicateKind::Trait(trait_pred) = pred.kind().skip_binder()
&& let ty::PredicateKind::Clause(ty::Clause::Trait(trait_pred)) = pred.kind().skip_binder()
&& ty::ClosureKind::from_def_id(self.tcx, trait_pred.def_id()).is_some()
{
let expected_self =
@ -1769,7 +1769,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
let other_pred = std::iter::zip(&predicates.predicates, &predicates.spans)
.enumerate()
.find(|(other_idx, (pred, _))| match pred.kind().skip_binder() {
ty::PredicateKind::Trait(trait_pred)
ty::PredicateKind::Clause(ty::Clause::Trait(trait_pred))
if ty::ClosureKind::from_def_id(self.tcx, trait_pred.def_id())
.is_some()
&& other_idx != idx
@ -1896,7 +1896,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
// bound was introduced. At least one generator should be present for this diagnostic to be
// modified.
let (mut trait_ref, mut target_ty) = match obligation.predicate.kind().skip_binder() {
ty::PredicateKind::Trait(p) => (Some(p), Some(p.self_ty())),
ty::PredicateKind::Clause(ty::Clause::Trait(p)) => (Some(p), Some(p.self_ty())),
_ => (None, None),
};
let mut generator = None;

View file

@ -269,7 +269,7 @@ impl<'a, 'tcx> ObligationProcessor for FulfillProcessor<'a, 'tcx> {
// Evaluation will discard candidates using the leak check.
// This means we need to pass it the bound version of our
// predicate.
ty::PredicateKind::Trait(trait_ref) => {
ty::PredicateKind::Clause(ty::Clause::Trait(trait_ref)) => {
let trait_obligation = obligation.with(infcx.tcx, binder.rebind(trait_ref));
self.process_trait_obligation(
@ -278,7 +278,7 @@ impl<'a, 'tcx> ObligationProcessor for FulfillProcessor<'a, 'tcx> {
&mut pending_obligation.stalled_on,
)
}
ty::PredicateKind::Projection(data) => {
ty::PredicateKind::Clause(ty::Clause::Projection(data)) => {
let project_obligation = obligation.with(infcx.tcx, binder.rebind(data));
self.process_projection_obligation(
@ -287,8 +287,8 @@ impl<'a, 'tcx> ObligationProcessor for FulfillProcessor<'a, 'tcx> {
&mut pending_obligation.stalled_on,
)
}
ty::PredicateKind::RegionOutlives(_)
| ty::PredicateKind::TypeOutlives(_)
ty::PredicateKind::Clause(ty::Clause::RegionOutlives(_))
| ty::PredicateKind::Clause(ty::Clause::TypeOutlives(_))
| ty::PredicateKind::WellFormed(_)
| ty::PredicateKind::ObjectSafe(_)
| ty::PredicateKind::ClosureKind(..)
@ -306,7 +306,7 @@ impl<'a, 'tcx> ObligationProcessor for FulfillProcessor<'a, 'tcx> {
}
},
Some(pred) => match pred {
ty::PredicateKind::Trait(data) => {
ty::PredicateKind::Clause(ty::Clause::Trait(data)) => {
let trait_obligation = obligation.with(infcx.tcx, Binder::dummy(data));
self.process_trait_obligation(
@ -316,7 +316,7 @@ impl<'a, 'tcx> ObligationProcessor for FulfillProcessor<'a, 'tcx> {
)
}
ty::PredicateKind::RegionOutlives(data) => {
ty::PredicateKind::Clause(ty::Clause::RegionOutlives(data)) => {
if infcx.considering_regions {
infcx.region_outlives_predicate(&obligation.cause, Binder::dummy(data));
}
@ -324,14 +324,17 @@ impl<'a, 'tcx> ObligationProcessor for FulfillProcessor<'a, 'tcx> {
ProcessResult::Changed(vec![])
}
ty::PredicateKind::TypeOutlives(ty::OutlivesPredicate(t_a, r_b)) => {
ty::PredicateKind::Clause(ty::Clause::TypeOutlives(ty::OutlivesPredicate(
t_a,
r_b,
))) => {
if infcx.considering_regions {
infcx.register_region_obligation_with_cause(t_a, r_b, &obligation.cause);
}
ProcessResult::Changed(vec![])
}
ty::PredicateKind::Projection(ref data) => {
ty::PredicateKind::Clause(ty::Clause::Projection(ref data)) => {
let project_obligation = obligation.with(infcx.tcx, Binder::dummy(*data));
self.process_projection_obligation(

View file

@ -317,7 +317,10 @@ pub fn normalize_param_env_or_error<'tcx>(
// TypeOutlives predicates - these are normally used by regionck.
let outlives_predicates: Vec<_> = predicates
.drain_filter(|predicate| {
matches!(predicate.kind().skip_binder(), ty::PredicateKind::TypeOutlives(..))
matches!(
predicate.kind().skip_binder(),
ty::PredicateKind::Clause(ty::Clause::TypeOutlives(..))
)
})
.collect();
@ -477,7 +480,7 @@ fn subst_and_check_impossible_predicates<'tcx>(
// associated items.
if let Some(trait_def_id) = tcx.trait_of_item(key.0) {
let trait_ref = ty::TraitRef::from_method(tcx, trait_def_id, key.1);
predicates.push(ty::Binder::dummy(trait_ref).to_poly_trait_predicate().to_predicate(tcx));
predicates.push(ty::Binder::dummy(trait_ref).to_predicate(tcx));
}
predicates.retain(|predicate| !predicate.needs_subst());

View file

@ -288,11 +288,11 @@ fn predicate_references_self<'tcx>(
let self_ty = tcx.types.self_param;
let has_self_ty = |arg: &GenericArg<'tcx>| arg.walk().any(|arg| arg == self_ty.into());
match predicate.kind().skip_binder() {
ty::PredicateKind::Trait(ref data) => {
ty::PredicateKind::Clause(ty::Clause::Trait(ref data)) => {
// In the case of a trait predicate, we can skip the "self" type.
if data.trait_ref.substs[1..].iter().any(has_self_ty) { Some(sp) } else { None }
}
ty::PredicateKind::Projection(ref data) => {
ty::PredicateKind::Clause(ty::Clause::Projection(ref data)) => {
// And similarly for projections. This should be redundant with
// the previous check because any projection should have a
// matching `Trait` predicate with the same inputs, but we do
@ -312,8 +312,8 @@ fn predicate_references_self<'tcx>(
}
ty::PredicateKind::WellFormed(..)
| ty::PredicateKind::ObjectSafe(..)
| ty::PredicateKind::TypeOutlives(..)
| ty::PredicateKind::RegionOutlives(..)
| ty::PredicateKind::Clause(ty::Clause::TypeOutlives(..))
| ty::PredicateKind::Clause(ty::Clause::RegionOutlives(..))
| ty::PredicateKind::ClosureKind(..)
| ty::PredicateKind::Subtype(..)
| ty::PredicateKind::Coerce(..)
@ -338,17 +338,17 @@ fn generics_require_sized_self(tcx: TyCtxt<'_>, def_id: DefId) -> bool {
let predicates = predicates.instantiate_identity(tcx).predicates;
elaborate_predicates(tcx, predicates.into_iter()).any(|obligation| {
match obligation.predicate.kind().skip_binder() {
ty::PredicateKind::Trait(ref trait_pred) => {
ty::PredicateKind::Clause(ty::Clause::Trait(ref trait_pred)) => {
trait_pred.def_id() == sized_def_id && trait_pred.self_ty().is_param(0)
}
ty::PredicateKind::Projection(..)
ty::PredicateKind::Clause(ty::Clause::Projection(..))
| ty::PredicateKind::Subtype(..)
| ty::PredicateKind::Coerce(..)
| ty::PredicateKind::RegionOutlives(..)
| ty::PredicateKind::Clause(ty::Clause::RegionOutlives(..))
| ty::PredicateKind::WellFormed(..)
| ty::PredicateKind::ObjectSafe(..)
| ty::PredicateKind::ClosureKind(..)
| ty::PredicateKind::TypeOutlives(..)
| ty::PredicateKind::Clause(ty::Clause::TypeOutlives(..))
| ty::PredicateKind::ConstEvaluatable(..)
| ty::PredicateKind::ConstEquate(..)
| ty::PredicateKind::Ambiguous
@ -723,8 +723,7 @@ fn receiver_is_dispatchable<'tcx>(
let obligation = {
let predicate = ty::Binder::dummy(
tcx.mk_trait_ref(dispatch_from_dyn_did, [receiver_ty, unsized_receiver_ty]),
)
.without_const();
);
Obligation::new(tcx, ObligationCause::dummy(), param_env, predicate)
};

View file

@ -1328,8 +1328,7 @@ fn assemble_candidate_for_impl_trait_in_trait<'cx, 'tcx>(
obligation.predicate.substs.truncate_to(tcx, tcx.generics_of(trait_def_id));
// FIXME(named-returns): Binders
let trait_predicate =
ty::Binder::dummy(ty::TraitRef { def_id: trait_def_id, substs: trait_substs })
.to_poly_trait_predicate();
ty::Binder::dummy(ty::TraitRef { def_id: trait_def_id, substs: trait_substs });
let _ = selcx.infcx().commit_if_ok(|_| {
match selcx.select(&obligation.with(tcx, trait_predicate)) {
@ -1477,7 +1476,9 @@ fn assemble_candidates_from_predicates<'cx, 'tcx>(
let infcx = selcx.infcx();
for predicate in env_predicates {
let bound_predicate = predicate.kind();
if let ty::PredicateKind::Projection(data) = predicate.kind().skip_binder() {
if let ty::PredicateKind::Clause(ty::Clause::Projection(data)) =
predicate.kind().skip_binder()
{
let data = bound_predicate.rebind(data);
if data.projection_def_id() != obligation.predicate.item_def_id {
continue;
@ -1527,7 +1528,7 @@ fn assemble_candidates_from_impls<'cx, 'tcx>(
// If we are resolving `<T as TraitRef<...>>::Item == Type`,
// start out by selecting the predicate `T as TraitRef<...>`:
let poly_trait_ref = ty::Binder::dummy(obligation.predicate.trait_ref(selcx.tcx()));
let trait_obligation = obligation.with(selcx.tcx(), poly_trait_ref.to_poly_trait_predicate());
let trait_obligation = obligation.with(selcx.tcx(), poly_trait_ref);
let _ = selcx.infcx().commit_if_ok(|_| {
let impl_source = match selcx.select(&trait_obligation) {
Ok(Some(impl_source)) => impl_source,

View file

@ -66,7 +66,7 @@ impl<'tcx> InferCtxtExt<'tcx> for InferCtxt<'tcx> {
let mut _orig_values = OriginalQueryValues::default();
let param_env = match obligation.predicate.kind().skip_binder() {
ty::PredicateKind::Trait(pred) => {
ty::PredicateKind::Clause(ty::Clause::Trait(pred)) => {
// we ignore the value set to it.
let mut _constness = pred.constness;
obligation

View file

@ -15,7 +15,9 @@ impl<'tcx> super::QueryTypeOp<'tcx> for ProvePredicate<'tcx> {
// `&T`, accounts for about 60% percentage of the predicates
// we have to prove. No need to canonicalize and all that for
// such cases.
if let ty::PredicateKind::Trait(trait_ref) = key.value.predicate.kind().skip_binder() {
if let ty::PredicateKind::Clause(ty::Clause::Trait(trait_ref)) =
key.value.predicate.kind().skip_binder()
{
if let Some(sized_def_id) = tcx.lang_items().sized_trait() {
if trait_ref.def_id() == sized_def_id {
if trait_ref.self_ty().is_trivially_sized(tcx) {
@ -33,7 +35,7 @@ impl<'tcx> super::QueryTypeOp<'tcx> for ProvePredicate<'tcx> {
mut canonicalized: Canonicalized<'tcx, ParamEnvAnd<'tcx, Self>>,
) -> Fallible<CanonicalizedQueryResponse<'tcx, ()>> {
match canonicalized.value.value.predicate.kind().skip_binder() {
ty::PredicateKind::Trait(pred) => {
ty::PredicateKind::Clause(ty::Clause::Trait(pred)) => {
canonicalized.value.param_env.remap_constness_with(pred.constness);
}
_ => canonicalized.value.param_env = canonicalized.value.param_env.without_const(),

View file

@ -12,7 +12,7 @@ pub(crate) fn update<'tcx, T>(
T: TraitEngine<'tcx>,
{
// (*) binder skipped
if let ty::PredicateKind::Trait(tpred) = obligation.predicate.kind().skip_binder()
if let ty::PredicateKind::Clause(ty::Clause::Trait(tpred)) = obligation.predicate.kind().skip_binder()
&& let Some(ty) = infcx.shallow_resolve(tpred.self_ty()).ty_vid().map(|t| infcx.root_var(t))
&& infcx.tcx.lang_items().sized_trait().map_or(false, |st| st != tpred.trait_ref.def_id)
{
@ -26,7 +26,7 @@ pub(crate) fn update<'tcx, T>(
.kind()
.rebind(
// (*) binder moved here
ty::PredicateKind::Trait(tpred.with_self_type(infcx.tcx, new_self_ty))
ty::PredicateKind::Clause(ty::Clause::Trait(tpred.with_self_type(infcx.tcx, new_self_ty)))
),
);
// Don't report overflow errors. Otherwise equivalent to may_hold.
@ -35,7 +35,9 @@ pub(crate) fn update<'tcx, T>(
}
}
if let ty::PredicateKind::Projection(predicate) = obligation.predicate.kind().skip_binder() {
if let ty::PredicateKind::Clause(ty::Clause::Projection(predicate)) =
obligation.predicate.kind().skip_binder()
{
// If the projection predicate (Foo::Bar == X) has X as a non-TyVid,
// we need to make it into one.
if let Some(vid) = predicate.term.ty().and_then(|ty| ty.ty_vid()) {

View file

@ -731,12 +731,8 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
// <ty as Deref>
let trait_ref = tcx.mk_trait_ref(tcx.lang_items().deref_trait()?, [ty]);
let obligation = traits::Obligation::new(
tcx,
cause.clone(),
param_env,
ty::Binder::dummy(trait_ref).without_const(),
);
let obligation =
traits::Obligation::new(tcx, cause.clone(), param_env, ty::Binder::dummy(trait_ref));
if !self.infcx.predicate_may_hold(&obligation) {
return None;
}

View file

@ -634,12 +634,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
);
let tr =
ty::Binder::dummy(self.tcx().at(cause.span).mk_trait_ref(LangItem::Sized, [output_ty]));
nested.push(Obligation::new(
self.infcx.tcx,
cause,
obligation.param_env,
tr.to_poly_trait_predicate(),
));
nested.push(Obligation::new(self.infcx.tcx, cause, obligation.param_env, tr));
Ok(ImplSourceFnPointerData { fn_ty: self_ty, nested })
}

View file

@ -419,7 +419,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
ensure_sufficient_stack(|| {
let bound_predicate = obligation.predicate.kind();
match bound_predicate.skip_binder() {
ty::PredicateKind::Trait(t) => {
ty::PredicateKind::Clause(ty::Clause::Trait(t)) => {
let t = bound_predicate.rebind(t);
debug_assert!(!t.has_escaping_bound_vars());
let obligation = obligation.with(self.tcx(), t);
@ -546,7 +546,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
}
}
ty::PredicateKind::TypeOutlives(pred) => {
ty::PredicateKind::Clause(ty::Clause::TypeOutlives(pred)) => {
// A global type with no late-bound regions can only
// contain the "'static" lifetime (any other lifetime
// would either be late-bound or local), so it is guaranteed
@ -558,7 +558,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
}
}
ty::PredicateKind::RegionOutlives(..) => {
ty::PredicateKind::Clause(ty::Clause::RegionOutlives(..)) => {
// We do not consider region relationships when evaluating trait matches.
Ok(EvaluatedToOkModuloRegions)
}
@ -571,7 +571,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
}
}
ty::PredicateKind::Projection(data) => {
ty::PredicateKind::Clause(ty::Clause::Projection(data)) => {
let data = bound_predicate.rebind(data);
let project_obligation = obligation.with(self.tcx(), data);
match project::poly_project_and_unify_type(self, &project_obligation) {
@ -931,7 +931,9 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
fn coinductive_predicate(&self, predicate: ty::Predicate<'tcx>) -> bool {
let result = match predicate.kind().skip_binder() {
ty::PredicateKind::Trait(ref data) => self.tcx().trait_is_coinductive(data.def_id()),
ty::PredicateKind::Clause(ty::Clause::Trait(ref data)) => {
self.tcx().trait_is_coinductive(data.def_id())
}
ty::PredicateKind::WellFormed(_) => true,
_ => false,
};
@ -1377,7 +1379,9 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
.enumerate()
.filter_map(|(idx, bound)| {
let bound_predicate = bound.kind();
if let ty::PredicateKind::Trait(pred) = bound_predicate.skip_binder() {
if let ty::PredicateKind::Clause(ty::Clause::Trait(pred)) =
bound_predicate.skip_binder()
{
let bound = bound_predicate.rebind(pred.trait_ref);
if self.infcx.probe(|_| {
match self.match_normalize_trait_ref(

View file

@ -476,7 +476,9 @@ pub(crate) fn to_pretty_impl_header(tcx: TyCtxt<'_>, impl_def_id: DefId) -> Opti
trait_pred
});
p = tcx.mk_predicate(new_trait_pred.map_bound(ty::PredicateKind::Trait))
p = tcx.mk_predicate(
new_trait_pred.map_bound(|p| ty::PredicateKind::Clause(ty::Clause::Trait(p))),
)
}
}
pretty_predicates.push(p.to_string());

View file

@ -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(),
@ -228,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
@ -245,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);
@ -561,9 +561,9 @@ impl<'tcx> WfPredicates<'tcx> {
cause,
depth,
param_env,
ty::Binder::dummy(ty::PredicateKind::TypeOutlives(
ty::Binder::dummy(ty::PredicateKind::Clause(ty::Clause::TypeOutlives(
ty::OutlivesPredicate(rty, r),
)),
))),
));
}
}
@ -866,19 +866,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