mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-01 06:51:58 +00:00
Auto merge of #106395 - compiler-errors:rework-predicates, r=eholk
Rework some `predicates_of`/`{Generic,Instantiated}Predicates` code 1. Make `instantiate_own` return an iterator, since it's a bit more efficient and easier to work with 2. Remove `bound_{explicit,}_predicates_of` -- these `bound_` methods in particular were a bit awkward to work with since `ty::GenericPredicates` *already* acts kinda like an `EarlyBinder` with its own `instantiate_*` methods, and had only a few call sites anyways. 3. Implement `IntoIterator` for `InstantiatedPredicates`, since it's *very* commonly being `zip`'d together.
This commit is contained in:
commit
d12412c90f
@ -673,40 +673,34 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
|
||||
let tcx = self.infcx.tcx;
|
||||
|
||||
// Find out if the predicates show that the type is a Fn or FnMut
|
||||
let find_fn_kind_from_did = |predicates: ty::EarlyBinder<
|
||||
&[(ty::Predicate<'tcx>, Span)],
|
||||
>,
|
||||
substs| {
|
||||
predicates.0.iter().find_map(|(pred, _)| {
|
||||
let pred = if let Some(substs) = substs {
|
||||
predicates.rebind(*pred).subst(tcx, substs).kind().skip_binder()
|
||||
} else {
|
||||
pred.kind().skip_binder()
|
||||
};
|
||||
if let ty::PredicateKind::Clause(ty::Clause::Trait(pred)) = pred && pred.self_ty() == ty {
|
||||
if Some(pred.def_id()) == tcx.lang_items().fn_trait() {
|
||||
return Some(hir::Mutability::Not);
|
||||
} else if Some(pred.def_id()) == tcx.lang_items().fn_mut_trait() {
|
||||
return Some(hir::Mutability::Mut);
|
||||
}
|
||||
let find_fn_kind_from_did = |(pred, _): (ty::Predicate<'tcx>, _)| {
|
||||
if let ty::PredicateKind::Clause(ty::Clause::Trait(pred)) = pred.kind().skip_binder()
|
||||
&& pred.self_ty() == ty
|
||||
{
|
||||
if Some(pred.def_id()) == tcx.lang_items().fn_trait() {
|
||||
return Some(hir::Mutability::Not);
|
||||
} else if Some(pred.def_id()) == tcx.lang_items().fn_mut_trait() {
|
||||
return Some(hir::Mutability::Mut);
|
||||
}
|
||||
None
|
||||
})
|
||||
}
|
||||
None
|
||||
};
|
||||
|
||||
// If the type is opaque/param/closure, and it is Fn or FnMut, let's suggest (mutably)
|
||||
// borrowing the type, since `&mut F: FnMut` iff `F: FnMut` and similarly for `Fn`.
|
||||
// These types seem reasonably opaque enough that they could be substituted with their
|
||||
// borrowed variants in a function body when we see a move error.
|
||||
let borrow_level = match ty.kind() {
|
||||
ty::Param(_) => find_fn_kind_from_did(
|
||||
tcx.bound_explicit_predicates_of(self.mir_def_id().to_def_id())
|
||||
.map_bound(|p| p.predicates),
|
||||
None,
|
||||
),
|
||||
ty::Alias(ty::Opaque, ty::AliasTy { def_id, substs, .. }) => {
|
||||
find_fn_kind_from_did(tcx.bound_explicit_item_bounds(*def_id), Some(*substs))
|
||||
}
|
||||
let borrow_level = match *ty.kind() {
|
||||
ty::Param(_) => tcx
|
||||
.explicit_predicates_of(self.mir_def_id().to_def_id())
|
||||
.predicates
|
||||
.iter()
|
||||
.copied()
|
||||
.find_map(find_fn_kind_from_did),
|
||||
ty::Alias(ty::Opaque, ty::AliasTy { def_id, substs, .. }) => tcx
|
||||
.bound_explicit_item_bounds(def_id)
|
||||
.subst_iter_copied(tcx, substs)
|
||||
.find_map(find_fn_kind_from_did),
|
||||
ty::Closure(_, substs) => match substs.as_closure().kind() {
|
||||
ty::ClosureKind::Fn => Some(hir::Mutability::Not),
|
||||
ty::ClosureKind::FnMut => Some(hir::Mutability::Mut),
|
||||
|
@ -107,11 +107,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
|
||||
instantiated_predicates: ty::InstantiatedPredicates<'tcx>,
|
||||
locations: Locations,
|
||||
) {
|
||||
for (predicate, span) in instantiated_predicates
|
||||
.predicates
|
||||
.into_iter()
|
||||
.zip(instantiated_predicates.spans.into_iter())
|
||||
{
|
||||
for (predicate, span) in instantiated_predicates {
|
||||
debug!(?predicate);
|
||||
let category = ConstraintCategory::Predicate(span);
|
||||
let predicate = self.normalize_with_category(predicate, locations, category);
|
||||
|
@ -209,9 +209,11 @@ fn compare_method_predicate_entailment<'tcx>(
|
||||
//
|
||||
// We then register the obligations from the impl_m and check to see
|
||||
// if all constraints hold.
|
||||
hybrid_preds
|
||||
.predicates
|
||||
.extend(trait_m_predicates.instantiate_own(tcx, trait_to_placeholder_substs).predicates);
|
||||
hybrid_preds.predicates.extend(
|
||||
trait_m_predicates
|
||||
.instantiate_own(tcx, trait_to_placeholder_substs)
|
||||
.map(|(predicate, _)| predicate),
|
||||
);
|
||||
|
||||
// Construct trait parameter environment and then shift it into the placeholder viewpoint.
|
||||
// The key step here is to update the caller_bounds's predicates to be
|
||||
@ -230,7 +232,7 @@ fn compare_method_predicate_entailment<'tcx>(
|
||||
debug!("compare_impl_method: caller_bounds={:?}", param_env.caller_bounds());
|
||||
|
||||
let impl_m_own_bounds = impl_m_predicates.instantiate_own(tcx, impl_to_placeholder_substs);
|
||||
for (predicate, span) in iter::zip(impl_m_own_bounds.predicates, impl_m_own_bounds.spans) {
|
||||
for (predicate, span) in impl_m_own_bounds {
|
||||
let normalize_cause = traits::ObligationCause::misc(span, impl_m_hir_id);
|
||||
let predicate = ocx.normalize(&normalize_cause, param_env, predicate);
|
||||
|
||||
@ -1828,8 +1830,7 @@ fn compare_type_predicate_entailment<'tcx>(
|
||||
check_region_bounds_on_impl_item(tcx, impl_ty, trait_ty, false)?;
|
||||
|
||||
let impl_ty_own_bounds = impl_ty_predicates.instantiate_own(tcx, impl_substs);
|
||||
|
||||
if impl_ty_own_bounds.is_empty() {
|
||||
if impl_ty_own_bounds.len() == 0 {
|
||||
// Nothing to check.
|
||||
return Ok(());
|
||||
}
|
||||
@ -1844,9 +1845,11 @@ fn compare_type_predicate_entailment<'tcx>(
|
||||
// associated type in the trait are assumed.
|
||||
let impl_predicates = tcx.predicates_of(impl_ty_predicates.parent.unwrap());
|
||||
let mut hybrid_preds = impl_predicates.instantiate_identity(tcx);
|
||||
hybrid_preds
|
||||
.predicates
|
||||
.extend(trait_ty_predicates.instantiate_own(tcx, trait_to_impl_substs).predicates);
|
||||
hybrid_preds.predicates.extend(
|
||||
trait_ty_predicates
|
||||
.instantiate_own(tcx, trait_to_impl_substs)
|
||||
.map(|(predicate, _)| predicate),
|
||||
);
|
||||
|
||||
debug!("compare_type_predicate_entailment: bounds={:?}", hybrid_preds);
|
||||
|
||||
@ -1862,9 +1865,7 @@ fn compare_type_predicate_entailment<'tcx>(
|
||||
|
||||
debug!("compare_type_predicate_entailment: caller_bounds={:?}", param_env.caller_bounds());
|
||||
|
||||
assert_eq!(impl_ty_own_bounds.predicates.len(), impl_ty_own_bounds.spans.len());
|
||||
for (span, predicate) in std::iter::zip(impl_ty_own_bounds.spans, impl_ty_own_bounds.predicates)
|
||||
{
|
||||
for (predicate, span) in impl_ty_own_bounds {
|
||||
let cause = ObligationCause::misc(span, impl_ty_hir_id);
|
||||
let predicate = ocx.normalize(&cause, param_env, predicate);
|
||||
|
||||
|
@ -32,7 +32,6 @@ use rustc_trait_selection::traits::{
|
||||
};
|
||||
|
||||
use std::cell::LazyCell;
|
||||
use std::iter;
|
||||
use std::ops::{ControlFlow, Deref};
|
||||
|
||||
pub(super) struct WfCheckingCtxt<'a, 'tcx> {
|
||||
@ -1310,7 +1309,7 @@ fn check_where_clauses<'tcx>(wfcx: &WfCheckingCtxt<'_, 'tcx>, span: Span, def_id
|
||||
let infcx = wfcx.infcx;
|
||||
let tcx = wfcx.tcx();
|
||||
|
||||
let predicates = tcx.bound_predicates_of(def_id.to_def_id());
|
||||
let predicates = tcx.predicates_of(def_id.to_def_id());
|
||||
let generics = tcx.generics_of(def_id);
|
||||
|
||||
let is_our_default = |def: &ty::GenericParamDef| match def.kind {
|
||||
@ -1411,7 +1410,6 @@ fn check_where_clauses<'tcx>(wfcx: &WfCheckingCtxt<'_, 'tcx>, span: Span, def_id
|
||||
|
||||
// Now we build the substituted predicates.
|
||||
let default_obligations = predicates
|
||||
.0
|
||||
.predicates
|
||||
.iter()
|
||||
.flat_map(|&(pred, sp)| {
|
||||
@ -1442,13 +1440,13 @@ fn check_where_clauses<'tcx>(wfcx: &WfCheckingCtxt<'_, 'tcx>, span: Span, def_id
|
||||
}
|
||||
let mut param_count = CountParams::default();
|
||||
let has_region = pred.visit_with(&mut param_count).is_break();
|
||||
let substituted_pred = predicates.rebind(pred).subst(tcx, substs);
|
||||
let substituted_pred = ty::EarlyBinder(pred).subst(tcx, substs);
|
||||
// Don't check non-defaulted params, dependent defaults (including lifetimes)
|
||||
// or preds with multiple params.
|
||||
if substituted_pred.has_non_region_param() || param_count.params.len() > 1 || has_region
|
||||
{
|
||||
None
|
||||
} else if predicates.0.predicates.iter().any(|&(p, _)| p == substituted_pred) {
|
||||
} else if predicates.predicates.iter().any(|&(p, _)| p == substituted_pred) {
|
||||
// Avoid duplication of predicates that contain no parameters, for example.
|
||||
None
|
||||
} else {
|
||||
@ -1474,22 +1472,21 @@ fn check_where_clauses<'tcx>(wfcx: &WfCheckingCtxt<'_, 'tcx>, span: Span, def_id
|
||||
traits::Obligation::new(tcx, cause, wfcx.param_env, pred)
|
||||
});
|
||||
|
||||
let predicates = predicates.0.instantiate_identity(tcx);
|
||||
let predicates = predicates.instantiate_identity(tcx);
|
||||
|
||||
let predicates = wfcx.normalize(span, None, predicates);
|
||||
|
||||
debug!(?predicates.predicates);
|
||||
assert_eq!(predicates.predicates.len(), predicates.spans.len());
|
||||
let wf_obligations =
|
||||
iter::zip(&predicates.predicates, &predicates.spans).flat_map(|(&p, &sp)| {
|
||||
traits::wf::predicate_obligations(
|
||||
infcx,
|
||||
wfcx.param_env.without_const(),
|
||||
wfcx.body_id,
|
||||
p,
|
||||
sp,
|
||||
)
|
||||
});
|
||||
let wf_obligations = predicates.into_iter().flat_map(|(p, sp)| {
|
||||
traits::wf::predicate_obligations(
|
||||
infcx,
|
||||
wfcx.param_env.without_const(),
|
||||
wfcx.body_id,
|
||||
p,
|
||||
sp,
|
||||
)
|
||||
});
|
||||
|
||||
let obligations: Vec<_> = wf_obligations.chain(default_obligations).collect();
|
||||
wfcx.register_obligations(obligations);
|
||||
|
@ -375,14 +375,12 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
if self.tcx.has_attr(def_id, sym::rustc_evaluate_where_clauses) {
|
||||
let predicates = self.tcx.predicates_of(def_id);
|
||||
let predicates = predicates.instantiate(self.tcx, subst);
|
||||
for (predicate, predicate_span) in
|
||||
predicates.predicates.iter().zip(&predicates.spans)
|
||||
{
|
||||
for (predicate, predicate_span) in predicates {
|
||||
let obligation = Obligation::new(
|
||||
self.tcx,
|
||||
ObligationCause::dummy_with_span(callee_expr.span),
|
||||
self.param_env,
|
||||
*predicate,
|
||||
predicate,
|
||||
);
|
||||
let result = self.evaluate_obligation(&obligation);
|
||||
self.tcx
|
||||
@ -391,7 +389,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
callee_expr.span,
|
||||
&format!("evaluate({:?}) = {:?}", predicate, result),
|
||||
)
|
||||
.span_label(*predicate_span, "predicate")
|
||||
.span_label(predicate_span, "predicate")
|
||||
.emit();
|
||||
}
|
||||
}
|
||||
|
@ -2140,8 +2140,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
// FIXME(compiler-errors): This could be problematic if something has two
|
||||
// fn-like predicates with different args, but callable types really never
|
||||
// do that, so it's OK.
|
||||
for (predicate, span) in
|
||||
std::iter::zip(instantiated.predicates, instantiated.spans)
|
||||
for (predicate, span) in instantiated
|
||||
{
|
||||
if let ty::PredicateKind::Clause(ty::Clause::Trait(pred)) = predicate.kind().skip_binder()
|
||||
&& pred.self_ty().peel_refs() == callee_ty
|
||||
|
@ -19,7 +19,6 @@ use rustc_middle::ty::{InternalSubsts, UserSubsts, UserType};
|
||||
use rustc_span::{Span, DUMMY_SP};
|
||||
use rustc_trait_selection::traits;
|
||||
|
||||
use std::iter;
|
||||
use std::ops::Deref;
|
||||
|
||||
struct ConfirmContext<'a, 'tcx> {
|
||||
@ -101,7 +100,7 @@ impl<'a, 'tcx> ConfirmContext<'a, 'tcx> {
|
||||
let filler_substs = rcvr_substs
|
||||
.extend_to(self.tcx, pick.item.def_id, |def, _| self.tcx.mk_param_from_def(def));
|
||||
let illegal_sized_bound = self.predicates_require_illegal_sized_bound(
|
||||
&self.tcx.predicates_of(pick.item.def_id).instantiate(self.tcx, filler_substs),
|
||||
self.tcx.predicates_of(pick.item.def_id).instantiate(self.tcx, filler_substs),
|
||||
);
|
||||
|
||||
// Unify the (adjusted) self type with what the method expects.
|
||||
@ -565,7 +564,7 @@ impl<'a, 'tcx> ConfirmContext<'a, 'tcx> {
|
||||
|
||||
fn predicates_require_illegal_sized_bound(
|
||||
&self,
|
||||
predicates: &ty::InstantiatedPredicates<'tcx>,
|
||||
predicates: ty::InstantiatedPredicates<'tcx>,
|
||||
) -> Option<Span> {
|
||||
let sized_def_id = self.tcx.lang_items().sized_trait()?;
|
||||
|
||||
@ -575,10 +574,11 @@ impl<'a, 'tcx> ConfirmContext<'a, 'tcx> {
|
||||
ty::PredicateKind::Clause(ty::Clause::Trait(trait_pred))
|
||||
if trait_pred.def_id() == sized_def_id =>
|
||||
{
|
||||
let span = iter::zip(&predicates.predicates, &predicates.spans)
|
||||
let span = predicates
|
||||
.iter()
|
||||
.find_map(
|
||||
|(p, span)| {
|
||||
if *p == obligation.predicate { Some(*span) } else { None }
|
||||
if p == obligation.predicate { Some(span) } else { None }
|
||||
},
|
||||
)
|
||||
.unwrap_or(rustc_span::DUMMY_SP);
|
||||
|
@ -330,9 +330,8 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
|
||||
|
||||
let Ok(trait_predicates) = self
|
||||
.tcx
|
||||
.bound_explicit_predicates_of(trait_item_def_id)
|
||||
.map_bound(|p| p.predicates)
|
||||
.subst_iter_copied(self.tcx, trait_item_substs)
|
||||
.explicit_predicates_of(trait_item_def_id)
|
||||
.instantiate_own(self.tcx, trait_item_substs)
|
||||
.map(|(pred, _)| {
|
||||
if pred.is_suggestable(self.tcx, false) {
|
||||
Ok(pred.to_string())
|
||||
|
@ -341,15 +341,9 @@ impl<'tcx> GenericPredicates<'tcx> {
|
||||
&self,
|
||||
tcx: TyCtxt<'tcx>,
|
||||
substs: SubstsRef<'tcx>,
|
||||
) -> InstantiatedPredicates<'tcx> {
|
||||
InstantiatedPredicates {
|
||||
predicates: self
|
||||
.predicates
|
||||
.iter()
|
||||
.map(|(p, _)| EarlyBinder(*p).subst(tcx, substs))
|
||||
.collect(),
|
||||
spans: self.predicates.iter().map(|(_, sp)| *sp).collect(),
|
||||
}
|
||||
) -> impl Iterator<Item = (Predicate<'tcx>, Span)> + DoubleEndedIterator + ExactSizeIterator
|
||||
{
|
||||
EarlyBinder(self.predicates).subst_iter_copied(tcx, substs)
|
||||
}
|
||||
|
||||
#[instrument(level = "debug", skip(self, tcx))]
|
||||
|
@ -1252,6 +1252,35 @@ impl<'tcx> InstantiatedPredicates<'tcx> {
|
||||
pub fn is_empty(&self) -> bool {
|
||||
self.predicates.is_empty()
|
||||
}
|
||||
|
||||
pub fn iter(&self) -> <&Self as IntoIterator>::IntoIter {
|
||||
(&self).into_iter()
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx> IntoIterator for InstantiatedPredicates<'tcx> {
|
||||
type Item = (Predicate<'tcx>, Span);
|
||||
|
||||
type IntoIter = std::iter::Zip<std::vec::IntoIter<Predicate<'tcx>>, std::vec::IntoIter<Span>>;
|
||||
|
||||
fn into_iter(self) -> Self::IntoIter {
|
||||
debug_assert_eq!(self.predicates.len(), self.spans.len());
|
||||
std::iter::zip(self.predicates, self.spans)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, 'tcx> IntoIterator for &'a InstantiatedPredicates<'tcx> {
|
||||
type Item = (Predicate<'tcx>, Span);
|
||||
|
||||
type IntoIter = std::iter::Zip<
|
||||
std::iter::Copied<std::slice::Iter<'a, Predicate<'tcx>>>,
|
||||
std::iter::Copied<std::slice::Iter<'a, Span>>,
|
||||
>;
|
||||
|
||||
fn into_iter(self) -> Self::IntoIter {
|
||||
debug_assert_eq!(self.predicates.len(), self.spans.len());
|
||||
std::iter::zip(self.predicates.iter().copied(), self.spans.iter().copied())
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, HashStable, TyEncodable, TyDecodable, Lift)]
|
||||
|
@ -639,6 +639,13 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx, I: IntoIterator> ExactSizeIterator for SubstIter<'_, 'tcx, I>
|
||||
where
|
||||
I::IntoIter: ExactSizeIterator,
|
||||
I::Item: TypeFoldable<'tcx>,
|
||||
{
|
||||
}
|
||||
|
||||
impl<'tcx, 's, I: IntoIterator> EarlyBinder<I>
|
||||
where
|
||||
I::Item: Deref,
|
||||
@ -686,6 +693,14 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx, I: IntoIterator> ExactSizeIterator for SubstIterCopied<'_, 'tcx, I>
|
||||
where
|
||||
I::IntoIter: ExactSizeIterator,
|
||||
I::Item: Deref,
|
||||
<I::Item as Deref>::Target: Copy + TypeFoldable<'tcx>,
|
||||
{
|
||||
}
|
||||
|
||||
pub struct EarlyBinderIter<T> {
|
||||
t: T,
|
||||
}
|
||||
|
@ -666,20 +666,6 @@ impl<'tcx> TyCtxt<'tcx> {
|
||||
ty::EarlyBinder(self.item_bounds(def_id))
|
||||
}
|
||||
|
||||
pub fn bound_predicates_of(
|
||||
self,
|
||||
def_id: DefId,
|
||||
) -> ty::EarlyBinder<ty::generics::GenericPredicates<'tcx>> {
|
||||
ty::EarlyBinder(self.predicates_of(def_id))
|
||||
}
|
||||
|
||||
pub fn bound_explicit_predicates_of(
|
||||
self,
|
||||
def_id: DefId,
|
||||
) -> ty::EarlyBinder<ty::generics::GenericPredicates<'tcx>> {
|
||||
ty::EarlyBinder(self.explicit_predicates_of(def_id))
|
||||
}
|
||||
|
||||
pub fn bound_impl_subject(self, def_id: DefId) -> ty::EarlyBinder<ty::ImplSubject<'tcx>> {
|
||||
ty::EarlyBinder(self.impl_subject(def_id))
|
||||
}
|
||||
|
@ -82,9 +82,7 @@ pub fn recompute_applicable_impls<'tcx>(
|
||||
|
||||
let predicates =
|
||||
tcx.predicates_of(obligation.cause.body_id.owner.to_def_id()).instantiate_identity(tcx);
|
||||
for obligation in
|
||||
elaborate_predicates_with_span(tcx, std::iter::zip(predicates.predicates, predicates.spans))
|
||||
{
|
||||
for obligation in elaborate_predicates_with_span(tcx, predicates.into_iter()) {
|
||||
let kind = obligation.predicate.kind();
|
||||
if let ty::PredicateKind::Clause(ty::Clause::Trait(trait_pred)) = kind.skip_binder()
|
||||
&& param_env_candidate_may_apply(kind.rebind(trait_pred))
|
||||
|
@ -2070,7 +2070,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
|
||||
|
||||
// Find another predicate whose self-type is equal to the expected self type,
|
||||
// but whose substs don't match.
|
||||
let other_pred = std::iter::zip(&predicates.predicates, &predicates.spans)
|
||||
let other_pred = predicates.into_iter()
|
||||
.enumerate()
|
||||
.find(|(other_idx, (pred, _))| match pred.kind().skip_binder() {
|
||||
ty::PredicateKind::Clause(ty::Clause::Trait(trait_pred))
|
||||
@ -2095,7 +2095,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
|
||||
// If we found one, then it's very likely the cause of the error.
|
||||
if let Some((_, (_, other_pred_span))) = other_pred {
|
||||
err.span_note(
|
||||
*other_pred_span,
|
||||
other_pred_span,
|
||||
"closure inferred to have a different signature due to this bound",
|
||||
);
|
||||
}
|
||||
|
@ -115,14 +115,12 @@ pub fn predicates_for_generics<'tcx>(
|
||||
param_env: ty::ParamEnv<'tcx>,
|
||||
generic_bounds: ty::InstantiatedPredicates<'tcx>,
|
||||
) -> impl Iterator<Item = PredicateObligation<'tcx>> {
|
||||
std::iter::zip(generic_bounds.predicates, generic_bounds.spans).enumerate().map(
|
||||
move |(idx, (predicate, span))| Obligation {
|
||||
cause: cause(idx, span),
|
||||
recursion_depth: 0,
|
||||
param_env,
|
||||
predicate,
|
||||
},
|
||||
)
|
||||
generic_bounds.into_iter().enumerate().map(move |(idx, (predicate, span))| Obligation {
|
||||
cause: cause(idx, span),
|
||||
recursion_depth: 0,
|
||||
param_env,
|
||||
predicate,
|
||||
})
|
||||
}
|
||||
|
||||
/// Determines whether the type `ty` is known to meet `bound` and
|
||||
|
@ -2259,25 +2259,23 @@ fn confirm_impl_trait_in_trait_candidate<'tcx>(
|
||||
tcx.predicates_of(impl_fn_def_id).instantiate(tcx, impl_fn_substs),
|
||||
&mut obligations,
|
||||
);
|
||||
obligations.extend(std::iter::zip(predicates.predicates, predicates.spans).map(
|
||||
|(pred, span)| {
|
||||
Obligation::with_depth(
|
||||
tcx,
|
||||
ObligationCause::new(
|
||||
obligation.cause.span,
|
||||
obligation.cause.body_id,
|
||||
if span.is_dummy() {
|
||||
super::ItemObligation(impl_fn_def_id)
|
||||
} else {
|
||||
super::BindingObligation(impl_fn_def_id, span)
|
||||
},
|
||||
),
|
||||
obligation.recursion_depth + 1,
|
||||
obligation.param_env,
|
||||
pred,
|
||||
)
|
||||
},
|
||||
));
|
||||
obligations.extend(predicates.into_iter().map(|(pred, span)| {
|
||||
Obligation::with_depth(
|
||||
tcx,
|
||||
ObligationCause::new(
|
||||
obligation.cause.span,
|
||||
obligation.cause.body_id,
|
||||
if span.is_dummy() {
|
||||
super::ItemObligation(impl_fn_def_id)
|
||||
} else {
|
||||
super::BindingObligation(impl_fn_def_id, span)
|
||||
},
|
||||
),
|
||||
obligation.recursion_depth + 1,
|
||||
obligation.param_env,
|
||||
pred,
|
||||
)
|
||||
}));
|
||||
|
||||
let ty = normalize_with_depth_to(
|
||||
selcx,
|
||||
@ -2303,10 +2301,10 @@ fn assoc_ty_own_obligations<'cx, 'tcx>(
|
||||
nested: &mut Vec<PredicateObligation<'tcx>>,
|
||||
) {
|
||||
let tcx = selcx.tcx();
|
||||
let own = tcx
|
||||
let predicates = tcx
|
||||
.predicates_of(obligation.predicate.def_id)
|
||||
.instantiate_own(tcx, obligation.predicate.substs);
|
||||
for (predicate, span) in std::iter::zip(own.predicates, own.spans) {
|
||||
for (predicate, span) in predicates {
|
||||
let normalized = normalize_with_depth_to(
|
||||
selcx,
|
||||
obligation.param_env,
|
||||
|
@ -185,9 +185,8 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
||||
})?);
|
||||
|
||||
if let ty::Alias(ty::Projection, ..) = placeholder_self_ty.kind() {
|
||||
let predicates = tcx.predicates_of(def_id).instantiate_own(tcx, substs).predicates;
|
||||
debug!(?predicates, "projection predicates");
|
||||
for predicate in predicates {
|
||||
let predicates = tcx.predicates_of(def_id).instantiate_own(tcx, substs);
|
||||
for (predicate, _) in predicates {
|
||||
let normalized = normalize_with_depth_to(
|
||||
self,
|
||||
obligation.param_env,
|
||||
|
@ -2558,12 +2558,11 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
||||
// obligation will normalize to `<$0 as Iterator>::Item = $1` and
|
||||
// `$1: Copy`, so we must ensure the obligations are emitted in
|
||||
// that order.
|
||||
let predicates = tcx.bound_predicates_of(def_id);
|
||||
debug!(?predicates);
|
||||
assert_eq!(predicates.0.parent, None);
|
||||
let mut obligations = Vec::with_capacity(predicates.0.predicates.len());
|
||||
for (predicate, span) in predicates.0.predicates {
|
||||
let span = *span;
|
||||
let predicates = tcx.predicates_of(def_id);
|
||||
assert_eq!(predicates.parent, None);
|
||||
let predicates = predicates.instantiate_own(tcx, substs);
|
||||
let mut obligations = Vec::with_capacity(predicates.len());
|
||||
for (predicate, span) in predicates {
|
||||
let cause = cause.clone().derived_cause(parent_trait_pred, |derived| {
|
||||
ImplDerivedObligation(Box::new(ImplDerivedObligationCause {
|
||||
derived,
|
||||
@ -2576,7 +2575,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
||||
param_env,
|
||||
cause.clone(),
|
||||
recursion_depth,
|
||||
predicates.rebind(*predicate).subst(tcx, substs),
|
||||
predicate,
|
||||
&mut obligations,
|
||||
);
|
||||
obligations.push(Obligation { cause, recursion_depth, param_env, predicate });
|
||||
|
@ -261,7 +261,10 @@ fn vtable_entries<'tcx>(
|
||||
// Note that this method could then never be called, so we
|
||||
// do not want to try and codegen it, in that case (see #23435).
|
||||
let predicates = tcx.predicates_of(def_id).instantiate_own(tcx, substs);
|
||||
if impossible_predicates(tcx, predicates.predicates) {
|
||||
if impossible_predicates(
|
||||
tcx,
|
||||
predicates.map(|(predicate, _)| predicate).collect(),
|
||||
) {
|
||||
debug!("vtable_entries: predicates do not hold");
|
||||
return VtblEntry::Vacant;
|
||||
}
|
||||
|
@ -736,7 +736,7 @@ impl<'tcx> WfPredicates<'tcx> {
|
||||
trace!("{:#?}", predicates);
|
||||
debug_assert_eq!(predicates.predicates.len(), origins.len());
|
||||
|
||||
iter::zip(iter::zip(predicates.predicates, predicates.spans), origins.into_iter().rev())
|
||||
iter::zip(predicates, origins.into_iter().rev())
|
||||
.map(|((mut pred, span), origin_def_id)| {
|
||||
let code = if span.is_dummy() {
|
||||
traits::ItemObligation(origin_def_id)
|
||||
|
@ -7,7 +7,7 @@
|
||||
//! `crate::chalk::lowering` (to lower rustc types into Chalk types).
|
||||
|
||||
use rustc_middle::traits::ChalkRustInterner as RustInterner;
|
||||
use rustc_middle::ty::{self, AssocKind, EarlyBinder, Ty, TyCtxt, TypeFoldable, TypeSuperFoldable};
|
||||
use rustc_middle::ty::{self, AssocKind, Ty, TyCtxt, TypeFoldable, TypeSuperFoldable};
|
||||
use rustc_middle::ty::{InternalSubsts, SubstsRef};
|
||||
use rustc_target::abi::{Integer, IntegerType};
|
||||
|
||||
@ -38,13 +38,12 @@ impl<'tcx> RustIrDatabase<'tcx> {
|
||||
def_id: DefId,
|
||||
bound_vars: SubstsRef<'tcx>,
|
||||
) -> Vec<chalk_ir::QuantifiedWhereClause<RustInterner<'tcx>>> {
|
||||
let predicates = self.interner.tcx.predicates_defined_on(def_id).predicates;
|
||||
predicates
|
||||
.iter()
|
||||
.map(|(wc, _)| EarlyBinder(*wc).subst(self.interner.tcx, bound_vars))
|
||||
.filter_map(|wc| LowerInto::<
|
||||
Option<chalk_ir::QuantifiedWhereClause<RustInterner<'tcx>>>
|
||||
>::lower_into(wc, self.interner)).collect()
|
||||
self.interner
|
||||
.tcx
|
||||
.predicates_defined_on(def_id)
|
||||
.instantiate_own(self.interner.tcx, bound_vars)
|
||||
.filter_map(|(wc, _)| LowerInto::lower_into(wc, self.interner))
|
||||
.collect()
|
||||
}
|
||||
|
||||
fn bounds_for<T>(&self, def_id: DefId, bound_vars: SubstsRef<'tcx>) -> Vec<T>
|
||||
|
@ -17,7 +17,6 @@ use rustc_trait_selection::traits::query::type_op::subtype::Subtype;
|
||||
use rustc_trait_selection::traits::query::{Fallible, NoSolution};
|
||||
use rustc_trait_selection::traits::{Normalized, Obligation, ObligationCause, ObligationCtxt};
|
||||
use std::fmt;
|
||||
use std::iter::zip;
|
||||
|
||||
pub(crate) fn provide(p: &mut Providers) {
|
||||
*p = Providers {
|
||||
@ -108,9 +107,7 @@ fn relate_mir_and_user_substs<'tcx>(
|
||||
let instantiated_predicates = tcx.predicates_of(def_id).instantiate(tcx, substs);
|
||||
|
||||
debug!(?instantiated_predicates);
|
||||
for (instantiated_predicate, predicate_span) in
|
||||
zip(instantiated_predicates.predicates, instantiated_predicates.spans)
|
||||
{
|
||||
for (instantiated_predicate, predicate_span) in instantiated_predicates {
|
||||
let span = if span == DUMMY_SP { predicate_span } else { span };
|
||||
let cause = ObligationCause::new(
|
||||
span,
|
||||
|
Loading…
Reference in New Issue
Block a user