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:
commit
051cab2b84
85 changed files with 625 additions and 496 deletions
|
@ -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");
|
||||
|
|
|
@ -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(),
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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; };
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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(
|
||||
|
|
|
@ -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());
|
||||
|
|
|
@ -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)
|
||||
};
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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(),
|
||||
|
|
|
@ -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()) {
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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 })
|
||||
}
|
||||
|
|
|
@ -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(
|
||||
|
|
|
@ -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());
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue