Skip to content

Commit 77f421c

Browse files
authored
Rollup merge of rust-lang#103123 - compiler-errors:early-binder-iter, r=cjgillot
Introduce `subst_iter` and `subst_iter_copied` on `EarlyBinder` Makes working with bounds lists a bit easier, which I seem to do a lot. Specifically, means that we don't need to do `.transpose_iter().map(|(pred, _)| *pred)` every time we want to iterate through an `EarlyBinder<&'tcx [(Predicate, Span)]>` (and even then, still have to call `subst` later), which was a very awkward idiom imo.
2 parents 6e95b6d + aa8931c commit 77f421c

File tree

9 files changed

+59
-57
lines changed

9 files changed

+59
-57
lines changed

compiler/rustc_hir_analysis/src/check/compare_method.rs

+4-12
Original file line numberDiff line numberDiff line change
@@ -664,10 +664,7 @@ impl<'tcx> TypeFolder<'tcx> for ImplTraitInTraitCollector<'_, 'tcx> {
664664
});
665665
self.types.insert(proj.item_def_id, (infer_ty, proj.substs));
666666
// Recurse into bounds
667-
for pred in self.tcx().bound_explicit_item_bounds(proj.item_def_id).transpose_iter() {
668-
let pred_span = pred.0.1;
669-
670-
let pred = pred.map_bound(|(pred, _)| *pred).subst(self.tcx(), proj.substs);
667+
for (pred, pred_span) in self.tcx().bound_explicit_item_bounds(proj.item_def_id).subst_iter_copied(self.tcx(), proj.substs) {
671668
let pred = pred.fold_with(self);
672669
let pred = self.ocx.normalize(
673670
ObligationCause::misc(self.span, self.body_id),
@@ -1752,15 +1749,10 @@ pub fn check_type_bounds<'tcx>(
17521749

17531750
let obligations = tcx
17541751
.bound_explicit_item_bounds(trait_ty.def_id)
1755-
.transpose_iter()
1756-
.map(|e| e.map_bound(|e| *e).transpose_tuple2())
1757-
.map(|(bound, span)| {
1758-
debug!(?bound);
1759-
// this is where opaque type is found
1760-
let concrete_ty_bound = bound.subst(tcx, rebased_substs);
1752+
.subst_iter_copied(tcx, rebased_substs)
1753+
.map(|(concrete_ty_bound, span)| {
17611754
debug!("check_type_bounds: concrete_ty_bound = {:?}", concrete_ty_bound);
1762-
1763-
traits::Obligation::new(mk_cause(span.0), param_env, concrete_ty_bound)
1755+
traits::Obligation::new(mk_cause(span), param_env, concrete_ty_bound)
17641756
})
17651757
.collect();
17661758
debug!("check_type_bounds: item_bounds={:?}", obligations);

compiler/rustc_hir_typeck/src/_match.rs

+5-2
Original file line numberDiff line numberDiff line change
@@ -514,8 +514,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
514514
}
515515

516516
for ty in [first_ty, second_ty] {
517-
for pred in self.tcx.bound_explicit_item_bounds(rpit_def_id).transpose_iter() {
518-
let pred = pred.map_bound(|(pred, _)| *pred).subst(self.tcx, substs);
517+
for (pred, _) in self
518+
.tcx
519+
.bound_explicit_item_bounds(rpit_def_id)
520+
.subst_iter_copied(self.tcx, substs)
521+
{
519522
let pred = match pred.kind().skip_binder() {
520523
ty::PredicateKind::Trait(mut trait_pred) => {
521524
assert_eq!(trait_pred.trait_ref.self_ty(), opaque_ty);

compiler/rustc_hir_typeck/src/closure.rs

+14-17
Original file line numberDiff line numberDiff line change
@@ -176,24 +176,23 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
176176
match *expected_ty.kind() {
177177
ty::Opaque(def_id, substs) => {
178178
let bounds = self.tcx.bound_explicit_item_bounds(def_id);
179-
let sig = bounds
180-
.transpose_iter()
181-
.map(|e| e.map_bound(|e| *e).transpose_tuple2())
182-
.find_map(|(pred, span)| match pred.0.kind().skip_binder() {
179+
let sig =
180+
bounds.subst_iter_copied(self.tcx, substs).find_map(|(pred, span)| match pred
181+
.kind()
182+
.skip_binder()
183+
{
183184
ty::PredicateKind::Projection(proj_predicate) => self
184185
.deduce_sig_from_projection(
185-
Some(span.0),
186-
pred.0
187-
.kind()
188-
.rebind(pred.rebind(proj_predicate).subst(self.tcx, substs)),
186+
Some(span),
187+
pred.kind().rebind(proj_predicate),
189188
),
190189
_ => None,
191190
});
192191

193192
let kind = bounds
194-
.transpose_iter()
195-
.map(|e| e.map_bound(|e| *e).transpose_tuple2())
196-
.filter_map(|(pred, _)| match pred.0.kind().skip_binder() {
193+
.0
194+
.iter()
195+
.filter_map(|(pred, _)| match pred.kind().skip_binder() {
197196
ty::PredicateKind::Trait(tp) => {
198197
self.tcx.fn_trait_kind_from_lang_item(tp.def_id())
199198
}
@@ -697,18 +696,16 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
697696
ty::Opaque(def_id, substs) => self
698697
.tcx
699698
.bound_explicit_item_bounds(def_id)
700-
.transpose_iter()
701-
.map(|e| e.map_bound(|e| *e).transpose_tuple2())
702-
.find_map(|(p, s)| get_future_output(p.subst(self.tcx, substs), s.0))?,
699+
.subst_iter_copied(self.tcx, substs)
700+
.find_map(|(p, s)| get_future_output(p, s))?,
703701
ty::Error(_) => return None,
704702
ty::Projection(proj)
705703
if self.tcx.def_kind(proj.item_def_id) == DefKind::ImplTraitPlaceholder =>
706704
{
707705
self.tcx
708706
.bound_explicit_item_bounds(proj.item_def_id)
709-
.transpose_iter()
710-
.map(|e| e.map_bound(|e| *e).transpose_tuple2())
711-
.find_map(|(p, s)| get_future_output(p.subst(self.tcx, proj.substs), s.0))?
707+
.subst_iter_copied(self.tcx, proj.substs)
708+
.find_map(|(p, s)| get_future_output(p, s))?
712709
}
713710
_ => span_bug!(
714711
self.tcx.def_span(expr_def_id),

compiler/rustc_infer/src/infer/error_reporting/mod.rs

+1-2
Original file line numberDiff line numberDiff line change
@@ -338,8 +338,7 @@ impl<'tcx> InferCtxt<'tcx> {
338338

339339
let bounds = self.tcx.bound_explicit_item_bounds(*def_id);
340340

341-
for predicate in bounds.transpose_iter().map(|e| e.map_bound(|(p, _)| *p)) {
342-
let predicate = predicate.subst(self.tcx, substs);
341+
for (predicate, _) in bounds.subst_iter_copied(self.tcx, substs) {
343342
let output = predicate
344343
.kind()
345344
.map_bound(|kind| match kind {

compiler/rustc_infer/src/infer/opaque_types.rs

+1-4
Original file line numberDiff line numberDiff line change
@@ -543,10 +543,7 @@ impl<'tcx> InferCtxt<'tcx> {
543543

544544
let item_bounds = tcx.bound_explicit_item_bounds(def_id.to_def_id());
545545

546-
for predicate in item_bounds.transpose_iter().map(|e| e.map_bound(|(p, _)| *p)) {
547-
debug!(?predicate);
548-
let predicate = predicate.subst(tcx, substs);
549-
546+
for (predicate, _) in item_bounds.subst_iter_copied(tcx, substs) {
550547
let predicate = predicate.fold_with(&mut BottomUpFolder {
551548
tcx,
552549
ty_op: |ty| match *ty.kind() {

compiler/rustc_lint/src/opaque_hidden_inferred_bound.rs

+5-7
Original file line numberDiff line numberDiff line change
@@ -91,14 +91,12 @@ impl<'tcx> LateLintPass<'tcx> for OpaqueHiddenInferredBound {
9191
// For example, in `impl Trait<Assoc = impl Send>`, for all of the bounds on `Assoc`,
9292
// e.g. `type Assoc: OtherTrait`, replace `<impl Trait as Trait>::Assoc: OtherTrait`
9393
// with `impl Send: OtherTrait`.
94-
for assoc_pred_and_span in
95-
cx.tcx.bound_explicit_item_bounds(proj.projection_ty.item_def_id).transpose_iter()
94+
for (assoc_pred, assoc_pred_span) in cx
95+
.tcx
96+
.bound_explicit_item_bounds(proj.projection_ty.item_def_id)
97+
.subst_iter_copied(cx.tcx, &proj.projection_ty.substs)
9698
{
97-
let assoc_pred_span = assoc_pred_and_span.0.1;
98-
let assoc_pred = assoc_pred_and_span
99-
.map_bound(|(pred, _)| *pred)
100-
.subst(cx.tcx, &proj.projection_ty.substs)
101-
.fold_with(proj_replacer);
99+
let assoc_pred = assoc_pred.fold_with(proj_replacer);
102100
let Ok(assoc_pred) = traits::fully_normalize(infcx, traits::ObligationCause::dummy(), cx.param_env, assoc_pred) else {
103101
continue;
104102
};

compiler/rustc_middle/src/ty/print/pretty.rs

+1-2
Original file line numberDiff line numberDiff line change
@@ -795,8 +795,7 @@ pub trait PrettyPrinter<'tcx>:
795795
let mut fn_traits = FxIndexMap::default();
796796
let mut is_sized = false;
797797

798-
for predicate in bounds.transpose_iter().map(|e| e.map_bound(|(p, _)| *p)) {
799-
let predicate = predicate.subst(tcx, substs);
798+
for (predicate, _) in bounds.subst_iter_copied(tcx, substs) {
800799
let bound_predicate = predicate.kind();
801800

802801
match bound_predicate.skip_binder() {

compiler/rustc_middle/src/ty/subst.rs

+23
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ use crate::ty::sty::{ClosureSubsts, GeneratorSubsts, InlineConstSubsts};
66
use crate::ty::visit::{TypeVisitable, TypeVisitor};
77
use crate::ty::{self, Lift, List, ParamConst, Ty, TyCtxt};
88

9+
use rustc_data_structures::captures::Captures;
910
use rustc_data_structures::intern::{Interned, WithStableHash};
1011
use rustc_hir::def_id::DefId;
1112
use rustc_macros::HashStable;
@@ -558,6 +559,28 @@ impl<T, U> EarlyBinder<(T, U)> {
558559
}
559560
}
560561

562+
impl<'tcx, 's, T: IntoIterator<Item = I>, I: TypeFoldable<'tcx>> EarlyBinder<T> {
563+
pub fn subst_iter(
564+
self,
565+
tcx: TyCtxt<'tcx>,
566+
substs: &'s [GenericArg<'tcx>],
567+
) -> impl Iterator<Item = I> + Captures<'s> + Captures<'tcx> {
568+
self.0.into_iter().map(move |t| EarlyBinder(t).subst(tcx, substs))
569+
}
570+
}
571+
572+
impl<'tcx, 's, 'a, T: IntoIterator<Item = &'a I>, I: Copy + TypeFoldable<'tcx> + 'a>
573+
EarlyBinder<T>
574+
{
575+
pub fn subst_iter_copied(
576+
self,
577+
tcx: TyCtxt<'tcx>,
578+
substs: &'s [GenericArg<'tcx>],
579+
) -> impl Iterator<Item = I> + Captures<'s> + Captures<'tcx> + Captures<'a> {
580+
self.0.into_iter().map(move |t| EarlyBinder(*t).subst(tcx, substs))
581+
}
582+
}
583+
561584
pub struct EarlyBinderIter<T> {
562585
t: T,
563586
}

src/tools/clippy/clippy_utils/src/ty.rs

+5-11
Original file line numberDiff line numberDiff line change
@@ -657,21 +657,18 @@ fn sig_for_projection<'tcx>(cx: &LateContext<'tcx>, ty: ProjectionTy<'tcx>) -> O
657657
let mut output = None;
658658
let lang_items = cx.tcx.lang_items();
659659

660-
for pred in cx
660+
for (pred, _) in cx
661661
.tcx
662662
.bound_explicit_item_bounds(ty.item_def_id)
663-
.transpose_iter()
664-
.map(|x| x.map_bound(|(p, _)| p))
663+
.subst_iter_copied(cx.tcx, ty.substs)
665664
{
666-
match pred.0.kind().skip_binder() {
665+
match pred.kind().skip_binder() {
667666
PredicateKind::Trait(p)
668667
if (lang_items.fn_trait() == Some(p.def_id())
669668
|| lang_items.fn_mut_trait() == Some(p.def_id())
670669
|| lang_items.fn_once_trait() == Some(p.def_id())) =>
671670
{
672-
let i = pred
673-
.map_bound(|pred| pred.kind().rebind(p.trait_ref.substs.type_at(1)))
674-
.subst(cx.tcx, ty.substs);
671+
let i = pred.kind().rebind(p.trait_ref.substs.type_at(1));
675672

676673
if inputs.map_or(false, |inputs| inputs != i) {
677674
// 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
684681
// Multiple different fn trait impls. Is this even allowed?
685682
return None;
686683
}
687-
output = Some(
688-
pred.map_bound(|pred| pred.kind().rebind(p.term.ty().unwrap()))
689-
.subst(cx.tcx, ty.substs),
690-
);
684+
output = pred.kind().rebind(p.term.ty()).transpose();
691685
},
692686
_ => (),
693687
}

0 commit comments

Comments
 (0)