Introduce subst_iter and subst_iter_copied on EarlyBinder
This commit is contained in:
parent
eecde5850c
commit
aa8931c612
9 changed files with 59 additions and 57 deletions
|
@ -664,10 +664,7 @@ impl<'tcx> TypeFolder<'tcx> for ImplTraitInTraitCollector<'_, 'tcx> {
|
|||
});
|
||||
self.types.insert(proj.item_def_id, (infer_ty, proj.substs));
|
||||
// Recurse into bounds
|
||||
for pred in self.tcx().bound_explicit_item_bounds(proj.item_def_id).transpose_iter() {
|
||||
let pred_span = pred.0.1;
|
||||
|
||||
let pred = pred.map_bound(|(pred, _)| *pred).subst(self.tcx(), proj.substs);
|
||||
for (pred, pred_span) in self.tcx().bound_explicit_item_bounds(proj.item_def_id).subst_iter_copied(self.tcx(), proj.substs) {
|
||||
let pred = pred.fold_with(self);
|
||||
let pred = self.ocx.normalize(
|
||||
ObligationCause::misc(self.span, self.body_id),
|
||||
|
@ -1752,15 +1749,10 @@ pub fn check_type_bounds<'tcx>(
|
|||
|
||||
let obligations = tcx
|
||||
.bound_explicit_item_bounds(trait_ty.def_id)
|
||||
.transpose_iter()
|
||||
.map(|e| e.map_bound(|e| *e).transpose_tuple2())
|
||||
.map(|(bound, span)| {
|
||||
debug!(?bound);
|
||||
// this is where opaque type is found
|
||||
let concrete_ty_bound = bound.subst(tcx, rebased_substs);
|
||||
.subst_iter_copied(tcx, rebased_substs)
|
||||
.map(|(concrete_ty_bound, span)| {
|
||||
debug!("check_type_bounds: concrete_ty_bound = {:?}", concrete_ty_bound);
|
||||
|
||||
traits::Obligation::new(mk_cause(span.0), param_env, concrete_ty_bound)
|
||||
traits::Obligation::new(mk_cause(span), param_env, concrete_ty_bound)
|
||||
})
|
||||
.collect();
|
||||
debug!("check_type_bounds: item_bounds={:?}", obligations);
|
||||
|
|
|
@ -514,8 +514,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||
}
|
||||
|
||||
for ty in [first_ty, second_ty] {
|
||||
for pred in self.tcx.bound_explicit_item_bounds(rpit_def_id).transpose_iter() {
|
||||
let pred = pred.map_bound(|(pred, _)| *pred).subst(self.tcx, substs);
|
||||
for (pred, _) in self
|
||||
.tcx
|
||||
.bound_explicit_item_bounds(rpit_def_id)
|
||||
.subst_iter_copied(self.tcx, substs)
|
||||
{
|
||||
let pred = match pred.kind().skip_binder() {
|
||||
ty::PredicateKind::Trait(mut trait_pred) => {
|
||||
assert_eq!(trait_pred.trait_ref.self_ty(), opaque_ty);
|
||||
|
|
|
@ -176,24 +176,23 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||
match *expected_ty.kind() {
|
||||
ty::Opaque(def_id, substs) => {
|
||||
let bounds = self.tcx.bound_explicit_item_bounds(def_id);
|
||||
let sig = bounds
|
||||
.transpose_iter()
|
||||
.map(|e| e.map_bound(|e| *e).transpose_tuple2())
|
||||
.find_map(|(pred, span)| match pred.0.kind().skip_binder() {
|
||||
let sig =
|
||||
bounds.subst_iter_copied(self.tcx, substs).find_map(|(pred, span)| match pred
|
||||
.kind()
|
||||
.skip_binder()
|
||||
{
|
||||
ty::PredicateKind::Projection(proj_predicate) => self
|
||||
.deduce_sig_from_projection(
|
||||
Some(span.0),
|
||||
pred.0
|
||||
.kind()
|
||||
.rebind(pred.rebind(proj_predicate).subst(self.tcx, substs)),
|
||||
Some(span),
|
||||
pred.kind().rebind(proj_predicate),
|
||||
),
|
||||
_ => None,
|
||||
});
|
||||
|
||||
let kind = bounds
|
||||
.transpose_iter()
|
||||
.map(|e| e.map_bound(|e| *e).transpose_tuple2())
|
||||
.filter_map(|(pred, _)| match pred.0.kind().skip_binder() {
|
||||
.0
|
||||
.iter()
|
||||
.filter_map(|(pred, _)| match pred.kind().skip_binder() {
|
||||
ty::PredicateKind::Trait(tp) => {
|
||||
self.tcx.fn_trait_kind_from_lang_item(tp.def_id())
|
||||
}
|
||||
|
@ -697,18 +696,16 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||
ty::Opaque(def_id, substs) => self
|
||||
.tcx
|
||||
.bound_explicit_item_bounds(def_id)
|
||||
.transpose_iter()
|
||||
.map(|e| e.map_bound(|e| *e).transpose_tuple2())
|
||||
.find_map(|(p, s)| get_future_output(p.subst(self.tcx, substs), s.0))?,
|
||||
.subst_iter_copied(self.tcx, substs)
|
||||
.find_map(|(p, s)| get_future_output(p, s))?,
|
||||
ty::Error(_) => return None,
|
||||
ty::Projection(proj)
|
||||
if self.tcx.def_kind(proj.item_def_id) == DefKind::ImplTraitPlaceholder =>
|
||||
{
|
||||
self.tcx
|
||||
.bound_explicit_item_bounds(proj.item_def_id)
|
||||
.transpose_iter()
|
||||
.map(|e| e.map_bound(|e| *e).transpose_tuple2())
|
||||
.find_map(|(p, s)| get_future_output(p.subst(self.tcx, proj.substs), s.0))?
|
||||
.subst_iter_copied(self.tcx, proj.substs)
|
||||
.find_map(|(p, s)| get_future_output(p, s))?
|
||||
}
|
||||
_ => span_bug!(
|
||||
self.tcx.def_span(expr_def_id),
|
||||
|
|
|
@ -338,8 +338,7 @@ impl<'tcx> InferCtxt<'tcx> {
|
|||
|
||||
let bounds = self.tcx.bound_explicit_item_bounds(*def_id);
|
||||
|
||||
for predicate in bounds.transpose_iter().map(|e| e.map_bound(|(p, _)| *p)) {
|
||||
let predicate = predicate.subst(self.tcx, substs);
|
||||
for (predicate, _) in bounds.subst_iter_copied(self.tcx, substs) {
|
||||
let output = predicate
|
||||
.kind()
|
||||
.map_bound(|kind| match kind {
|
||||
|
|
|
@ -543,10 +543,7 @@ impl<'tcx> InferCtxt<'tcx> {
|
|||
|
||||
let item_bounds = tcx.bound_explicit_item_bounds(def_id.to_def_id());
|
||||
|
||||
for predicate in item_bounds.transpose_iter().map(|e| e.map_bound(|(p, _)| *p)) {
|
||||
debug!(?predicate);
|
||||
let predicate = predicate.subst(tcx, substs);
|
||||
|
||||
for (predicate, _) in item_bounds.subst_iter_copied(tcx, substs) {
|
||||
let predicate = predicate.fold_with(&mut BottomUpFolder {
|
||||
tcx,
|
||||
ty_op: |ty| match *ty.kind() {
|
||||
|
|
|
@ -91,14 +91,12 @@ impl<'tcx> LateLintPass<'tcx> for OpaqueHiddenInferredBound {
|
|||
// For example, in `impl Trait<Assoc = impl Send>`, for all of the bounds on `Assoc`,
|
||||
// e.g. `type Assoc: OtherTrait`, replace `<impl Trait as Trait>::Assoc: OtherTrait`
|
||||
// with `impl Send: OtherTrait`.
|
||||
for assoc_pred_and_span in
|
||||
cx.tcx.bound_explicit_item_bounds(proj.projection_ty.item_def_id).transpose_iter()
|
||||
for (assoc_pred, assoc_pred_span) in cx
|
||||
.tcx
|
||||
.bound_explicit_item_bounds(proj.projection_ty.item_def_id)
|
||||
.subst_iter_copied(cx.tcx, &proj.projection_ty.substs)
|
||||
{
|
||||
let assoc_pred_span = assoc_pred_and_span.0.1;
|
||||
let assoc_pred = assoc_pred_and_span
|
||||
.map_bound(|(pred, _)| *pred)
|
||||
.subst(cx.tcx, &proj.projection_ty.substs)
|
||||
.fold_with(proj_replacer);
|
||||
let assoc_pred = assoc_pred.fold_with(proj_replacer);
|
||||
let Ok(assoc_pred) = traits::fully_normalize(infcx, traits::ObligationCause::dummy(), cx.param_env, assoc_pred) else {
|
||||
continue;
|
||||
};
|
||||
|
|
|
@ -795,8 +795,7 @@ pub trait PrettyPrinter<'tcx>:
|
|||
let mut fn_traits = FxIndexMap::default();
|
||||
let mut is_sized = false;
|
||||
|
||||
for predicate in bounds.transpose_iter().map(|e| e.map_bound(|(p, _)| *p)) {
|
||||
let predicate = predicate.subst(tcx, substs);
|
||||
for (predicate, _) in bounds.subst_iter_copied(tcx, substs) {
|
||||
let bound_predicate = predicate.kind();
|
||||
|
||||
match bound_predicate.skip_binder() {
|
||||
|
|
|
@ -6,6 +6,7 @@ use crate::ty::sty::{ClosureSubsts, GeneratorSubsts, InlineConstSubsts};
|
|||
use crate::ty::visit::{TypeVisitable, TypeVisitor};
|
||||
use crate::ty::{self, Lift, List, ParamConst, Ty, TyCtxt};
|
||||
|
||||
use rustc_data_structures::captures::Captures;
|
||||
use rustc_data_structures::intern::{Interned, WithStableHash};
|
||||
use rustc_hir::def_id::DefId;
|
||||
use rustc_macros::HashStable;
|
||||
|
@ -550,6 +551,28 @@ impl<T, U> EarlyBinder<(T, U)> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<'tcx, 's, T: IntoIterator<Item = I>, I: TypeFoldable<'tcx>> EarlyBinder<T> {
|
||||
pub fn subst_iter(
|
||||
self,
|
||||
tcx: TyCtxt<'tcx>,
|
||||
substs: &'s [GenericArg<'tcx>],
|
||||
) -> impl Iterator<Item = I> + Captures<'s> + Captures<'tcx> {
|
||||
self.0.into_iter().map(move |t| EarlyBinder(t).subst(tcx, substs))
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx, 's, 'a, T: IntoIterator<Item = &'a I>, I: Copy + TypeFoldable<'tcx> + 'a>
|
||||
EarlyBinder<T>
|
||||
{
|
||||
pub fn subst_iter_copied(
|
||||
self,
|
||||
tcx: TyCtxt<'tcx>,
|
||||
substs: &'s [GenericArg<'tcx>],
|
||||
) -> impl Iterator<Item = I> + Captures<'s> + Captures<'tcx> + Captures<'a> {
|
||||
self.0.into_iter().map(move |t| EarlyBinder(*t).subst(tcx, substs))
|
||||
}
|
||||
}
|
||||
|
||||
pub struct EarlyBinderIter<T> {
|
||||
t: T,
|
||||
}
|
||||
|
|
|
@ -657,21 +657,18 @@ fn sig_for_projection<'tcx>(cx: &LateContext<'tcx>, ty: ProjectionTy<'tcx>) -> O
|
|||
let mut output = None;
|
||||
let lang_items = cx.tcx.lang_items();
|
||||
|
||||
for pred in cx
|
||||
for (pred, _) in cx
|
||||
.tcx
|
||||
.bound_explicit_item_bounds(ty.item_def_id)
|
||||
.transpose_iter()
|
||||
.map(|x| x.map_bound(|(p, _)| p))
|
||||
.subst_iter_copied(cx.tcx, ty.substs)
|
||||
{
|
||||
match pred.0.kind().skip_binder() {
|
||||
match pred.kind().skip_binder() {
|
||||
PredicateKind::Trait(p)
|
||||
if (lang_items.fn_trait() == Some(p.def_id())
|
||||
|| lang_items.fn_mut_trait() == Some(p.def_id())
|
||||
|| lang_items.fn_once_trait() == Some(p.def_id())) =>
|
||||
{
|
||||
let i = pred
|
||||
.map_bound(|pred| pred.kind().rebind(p.trait_ref.substs.type_at(1)))
|
||||
.subst(cx.tcx, ty.substs);
|
||||
let i = pred.kind().rebind(p.trait_ref.substs.type_at(1));
|
||||
|
||||
if inputs.map_or(false, |inputs| inputs != i) {
|
||||
// Multiple different fn trait impls. Is this even allowed?
|
||||
|
@ -684,10 +681,7 @@ fn sig_for_projection<'tcx>(cx: &LateContext<'tcx>, ty: ProjectionTy<'tcx>) -> O
|
|||
// Multiple different fn trait impls. Is this even allowed?
|
||||
return None;
|
||||
}
|
||||
output = Some(
|
||||
pred.map_bound(|pred| pred.kind().rebind(p.term.ty().unwrap()))
|
||||
.subst(cx.tcx, ty.substs),
|
||||
);
|
||||
output = pred.kind().rebind(p.term.ty()).transpose();
|
||||
},
|
||||
_ => (),
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue