Make InstantiatedPredicates impl IntoIterator
This commit is contained in:
parent
91fd862df0
commit
9b28edb6d7
12 changed files with 74 additions and 65 deletions
|
@ -107,11 +107,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
|
||||||
instantiated_predicates: ty::InstantiatedPredicates<'tcx>,
|
instantiated_predicates: ty::InstantiatedPredicates<'tcx>,
|
||||||
locations: Locations,
|
locations: Locations,
|
||||||
) {
|
) {
|
||||||
for (predicate, span) in instantiated_predicates
|
for (predicate, span) in instantiated_predicates {
|
||||||
.predicates
|
|
||||||
.into_iter()
|
|
||||||
.zip(instantiated_predicates.spans.into_iter())
|
|
||||||
{
|
|
||||||
debug!(?predicate);
|
debug!(?predicate);
|
||||||
let category = ConstraintCategory::Predicate(span);
|
let category = ConstraintCategory::Predicate(span);
|
||||||
let predicate = self.normalize_with_category(predicate, locations, category);
|
let predicate = self.normalize_with_category(predicate, locations, category);
|
||||||
|
|
|
@ -32,7 +32,6 @@ use rustc_trait_selection::traits::{
|
||||||
};
|
};
|
||||||
|
|
||||||
use std::cell::LazyCell;
|
use std::cell::LazyCell;
|
||||||
use std::iter;
|
|
||||||
use std::ops::{ControlFlow, Deref};
|
use std::ops::{ControlFlow, Deref};
|
||||||
|
|
||||||
pub(super) struct WfCheckingCtxt<'a, 'tcx> {
|
pub(super) struct WfCheckingCtxt<'a, 'tcx> {
|
||||||
|
@ -1480,16 +1479,15 @@ fn check_where_clauses<'tcx>(wfcx: &WfCheckingCtxt<'_, 'tcx>, span: Span, def_id
|
||||||
|
|
||||||
debug!(?predicates.predicates);
|
debug!(?predicates.predicates);
|
||||||
assert_eq!(predicates.predicates.len(), predicates.spans.len());
|
assert_eq!(predicates.predicates.len(), predicates.spans.len());
|
||||||
let wf_obligations =
|
let wf_obligations = predicates.into_iter().flat_map(|(p, sp)| {
|
||||||
iter::zip(&predicates.predicates, &predicates.spans).flat_map(|(&p, &sp)| {
|
traits::wf::predicate_obligations(
|
||||||
traits::wf::predicate_obligations(
|
infcx,
|
||||||
infcx,
|
wfcx.param_env.without_const(),
|
||||||
wfcx.param_env.without_const(),
|
wfcx.body_id,
|
||||||
wfcx.body_id,
|
p,
|
||||||
p,
|
sp,
|
||||||
sp,
|
)
|
||||||
)
|
});
|
||||||
});
|
|
||||||
|
|
||||||
let obligations: Vec<_> = wf_obligations.chain(default_obligations).collect();
|
let obligations: Vec<_> = wf_obligations.chain(default_obligations).collect();
|
||||||
wfcx.register_obligations(obligations);
|
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) {
|
if self.tcx.has_attr(def_id, sym::rustc_evaluate_where_clauses) {
|
||||||
let predicates = self.tcx.predicates_of(def_id);
|
let predicates = self.tcx.predicates_of(def_id);
|
||||||
let predicates = predicates.instantiate(self.tcx, subst);
|
let predicates = predicates.instantiate(self.tcx, subst);
|
||||||
for (predicate, predicate_span) in
|
for (predicate, predicate_span) in predicates {
|
||||||
predicates.predicates.iter().zip(&predicates.spans)
|
|
||||||
{
|
|
||||||
let obligation = Obligation::new(
|
let obligation = Obligation::new(
|
||||||
self.tcx,
|
self.tcx,
|
||||||
ObligationCause::dummy_with_span(callee_expr.span),
|
ObligationCause::dummy_with_span(callee_expr.span),
|
||||||
self.param_env,
|
self.param_env,
|
||||||
*predicate,
|
predicate,
|
||||||
);
|
);
|
||||||
let result = self.evaluate_obligation(&obligation);
|
let result = self.evaluate_obligation(&obligation);
|
||||||
self.tcx
|
self.tcx
|
||||||
|
@ -391,7 +389,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||||
callee_expr.span,
|
callee_expr.span,
|
||||||
&format!("evaluate({:?}) = {:?}", predicate, result),
|
&format!("evaluate({:?}) = {:?}", predicate, result),
|
||||||
)
|
)
|
||||||
.span_label(*predicate_span, "predicate")
|
.span_label(predicate_span, "predicate")
|
||||||
.emit();
|
.emit();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2140,8 +2140,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||||
// FIXME(compiler-errors): This could be problematic if something has two
|
// FIXME(compiler-errors): This could be problematic if something has two
|
||||||
// fn-like predicates with different args, but callable types really never
|
// fn-like predicates with different args, but callable types really never
|
||||||
// do that, so it's OK.
|
// do that, so it's OK.
|
||||||
for (predicate, span) in
|
for (predicate, span) in instantiated
|
||||||
std::iter::zip(instantiated.predicates, instantiated.spans)
|
|
||||||
{
|
{
|
||||||
if let ty::PredicateKind::Clause(ty::Clause::Trait(pred)) = predicate.kind().skip_binder()
|
if let ty::PredicateKind::Clause(ty::Clause::Trait(pred)) = predicate.kind().skip_binder()
|
||||||
&& pred.self_ty().peel_refs() == callee_ty
|
&& 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_span::{Span, DUMMY_SP};
|
||||||
use rustc_trait_selection::traits;
|
use rustc_trait_selection::traits;
|
||||||
|
|
||||||
use std::iter;
|
|
||||||
use std::ops::Deref;
|
use std::ops::Deref;
|
||||||
|
|
||||||
struct ConfirmContext<'a, 'tcx> {
|
struct ConfirmContext<'a, 'tcx> {
|
||||||
|
@ -101,7 +100,7 @@ impl<'a, 'tcx> ConfirmContext<'a, 'tcx> {
|
||||||
let filler_substs = rcvr_substs
|
let filler_substs = rcvr_substs
|
||||||
.extend_to(self.tcx, pick.item.def_id, |def, _| self.tcx.mk_param_from_def(def));
|
.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(
|
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.
|
// 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(
|
fn predicates_require_illegal_sized_bound(
|
||||||
&self,
|
&self,
|
||||||
predicates: &ty::InstantiatedPredicates<'tcx>,
|
predicates: ty::InstantiatedPredicates<'tcx>,
|
||||||
) -> Option<Span> {
|
) -> Option<Span> {
|
||||||
let sized_def_id = self.tcx.lang_items().sized_trait()?;
|
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))
|
ty::PredicateKind::Clause(ty::Clause::Trait(trait_pred))
|
||||||
if trait_pred.def_id() == sized_def_id =>
|
if trait_pred.def_id() == sized_def_id =>
|
||||||
{
|
{
|
||||||
let span = iter::zip(&predicates.predicates, &predicates.spans)
|
let span = predicates
|
||||||
|
.iter()
|
||||||
.find_map(
|
.find_map(
|
||||||
|(p, span)| {
|
|(p, span)| {
|
||||||
if *p == obligation.predicate { Some(*span) } else { None }
|
if p == obligation.predicate { Some(span) } else { None }
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
.unwrap_or(rustc_span::DUMMY_SP);
|
.unwrap_or(rustc_span::DUMMY_SP);
|
||||||
|
|
|
@ -1252,6 +1252,33 @@ impl<'tcx> InstantiatedPredicates<'tcx> {
|
||||||
pub fn is_empty(&self) -> bool {
|
pub fn is_empty(&self) -> bool {
|
||||||
self.predicates.is_empty()
|
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 {
|
||||||
|
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 {
|
||||||
|
std::iter::zip(self.predicates.iter().copied(), self.spans.iter().copied())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, HashStable, TyEncodable, TyDecodable, Lift)]
|
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, HashStable, TyEncodable, TyDecodable, Lift)]
|
||||||
|
|
|
@ -82,9 +82,7 @@ pub fn recompute_applicable_impls<'tcx>(
|
||||||
|
|
||||||
let predicates =
|
let predicates =
|
||||||
tcx.predicates_of(obligation.cause.body_id.owner.to_def_id()).instantiate_identity(tcx);
|
tcx.predicates_of(obligation.cause.body_id.owner.to_def_id()).instantiate_identity(tcx);
|
||||||
for obligation in
|
for obligation in elaborate_predicates_with_span(tcx, predicates.into_iter()) {
|
||||||
elaborate_predicates_with_span(tcx, std::iter::zip(predicates.predicates, predicates.spans))
|
|
||||||
{
|
|
||||||
let kind = obligation.predicate.kind();
|
let kind = obligation.predicate.kind();
|
||||||
if let ty::PredicateKind::Clause(ty::Clause::Trait(trait_pred)) = kind.skip_binder()
|
if let ty::PredicateKind::Clause(ty::Clause::Trait(trait_pred)) = kind.skip_binder()
|
||||||
&& param_env_candidate_may_apply(kind.rebind(trait_pred))
|
&& 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,
|
// Find another predicate whose self-type is equal to the expected self type,
|
||||||
// but whose substs don't match.
|
// but whose substs don't match.
|
||||||
let other_pred = std::iter::zip(&predicates.predicates, &predicates.spans)
|
let other_pred = predicates.into_iter()
|
||||||
.enumerate()
|
.enumerate()
|
||||||
.find(|(other_idx, (pred, _))| match pred.kind().skip_binder() {
|
.find(|(other_idx, (pred, _))| match pred.kind().skip_binder() {
|
||||||
ty::PredicateKind::Clause(ty::Clause::Trait(trait_pred))
|
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 we found one, then it's very likely the cause of the error.
|
||||||
if let Some((_, (_, other_pred_span))) = other_pred {
|
if let Some((_, (_, other_pred_span))) = other_pred {
|
||||||
err.span_note(
|
err.span_note(
|
||||||
*other_pred_span,
|
other_pred_span,
|
||||||
"closure inferred to have a different signature due to this bound",
|
"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>,
|
param_env: ty::ParamEnv<'tcx>,
|
||||||
generic_bounds: ty::InstantiatedPredicates<'tcx>,
|
generic_bounds: ty::InstantiatedPredicates<'tcx>,
|
||||||
) -> impl Iterator<Item = PredicateObligation<'tcx>> {
|
) -> impl Iterator<Item = PredicateObligation<'tcx>> {
|
||||||
std::iter::zip(generic_bounds.predicates, generic_bounds.spans).enumerate().map(
|
generic_bounds.into_iter().enumerate().map(move |(idx, (predicate, span))| Obligation {
|
||||||
move |(idx, (predicate, span))| Obligation {
|
cause: cause(idx, span),
|
||||||
cause: cause(idx, span),
|
recursion_depth: 0,
|
||||||
recursion_depth: 0,
|
param_env,
|
||||||
param_env,
|
predicate,
|
||||||
predicate,
|
})
|
||||||
},
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Determines whether the type `ty` is known to meet `bound` and
|
/// 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),
|
tcx.predicates_of(impl_fn_def_id).instantiate(tcx, impl_fn_substs),
|
||||||
&mut obligations,
|
&mut obligations,
|
||||||
);
|
);
|
||||||
obligations.extend(std::iter::zip(predicates.predicates, predicates.spans).map(
|
obligations.extend(predicates.into_iter().map(|(pred, span)| {
|
||||||
|(pred, span)| {
|
Obligation::with_depth(
|
||||||
Obligation::with_depth(
|
tcx,
|
||||||
tcx,
|
ObligationCause::new(
|
||||||
ObligationCause::new(
|
obligation.cause.span,
|
||||||
obligation.cause.span,
|
obligation.cause.body_id,
|
||||||
obligation.cause.body_id,
|
if span.is_dummy() {
|
||||||
if span.is_dummy() {
|
super::ItemObligation(impl_fn_def_id)
|
||||||
super::ItemObligation(impl_fn_def_id)
|
} else {
|
||||||
} else {
|
super::BindingObligation(impl_fn_def_id, span)
|
||||||
super::BindingObligation(impl_fn_def_id, span)
|
},
|
||||||
},
|
),
|
||||||
),
|
obligation.recursion_depth + 1,
|
||||||
obligation.recursion_depth + 1,
|
obligation.param_env,
|
||||||
obligation.param_env,
|
pred,
|
||||||
pred,
|
)
|
||||||
)
|
}));
|
||||||
},
|
|
||||||
));
|
|
||||||
|
|
||||||
let ty = normalize_with_depth_to(
|
let ty = normalize_with_depth_to(
|
||||||
selcx,
|
selcx,
|
||||||
|
|
|
@ -736,7 +736,7 @@ impl<'tcx> WfPredicates<'tcx> {
|
||||||
trace!("{:#?}", predicates);
|
trace!("{:#?}", predicates);
|
||||||
debug_assert_eq!(predicates.predicates.len(), origins.len());
|
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)| {
|
.map(|((mut pred, span), origin_def_id)| {
|
||||||
let code = if span.is_dummy() {
|
let code = if span.is_dummy() {
|
||||||
traits::ItemObligation(origin_def_id)
|
traits::ItemObligation(origin_def_id)
|
||||||
|
|
|
@ -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::query::{Fallible, NoSolution};
|
||||||
use rustc_trait_selection::traits::{Normalized, Obligation, ObligationCause, ObligationCtxt};
|
use rustc_trait_selection::traits::{Normalized, Obligation, ObligationCause, ObligationCtxt};
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
use std::iter::zip;
|
|
||||||
|
|
||||||
pub(crate) fn provide(p: &mut Providers) {
|
pub(crate) fn provide(p: &mut Providers) {
|
||||||
*p = 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);
|
let instantiated_predicates = tcx.predicates_of(def_id).instantiate(tcx, substs);
|
||||||
|
|
||||||
debug!(?instantiated_predicates);
|
debug!(?instantiated_predicates);
|
||||||
for (instantiated_predicate, predicate_span) in
|
for (instantiated_predicate, predicate_span) in instantiated_predicates {
|
||||||
zip(instantiated_predicates.predicates, instantiated_predicates.spans)
|
|
||||||
{
|
|
||||||
let span = if span == DUMMY_SP { predicate_span } else { span };
|
let span = if span == DUMMY_SP { predicate_span } else { span };
|
||||||
let cause = ObligationCause::new(
|
let cause = ObligationCause::new(
|
||||||
span,
|
span,
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue