Skip to content

Commit 91afd02

Browse files
committed
Add bound_explicit_item_bounds and bound_item_bounds
1 parent 0247fae commit 91afd02

File tree

11 files changed

+121
-77
lines changed

11 files changed

+121
-77
lines changed

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

+3-3
Original file line numberDiff line numberDiff line change
@@ -1849,10 +1849,10 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
18491849
// Future::Output
18501850
let item_def_id = self.tcx.associated_item_def_ids(future_trait)[0];
18511851

1852-
let bounds = self.tcx.explicit_item_bounds(*def_id);
1852+
let bounds = self.tcx.bound_explicit_item_bounds(*def_id);
18531853

1854-
for (predicate, _) in bounds {
1855-
let predicate = EarlyBinder(*predicate).subst(self.tcx, substs);
1854+
for predicate in bounds.transpose_iter().map(|e| e.map_bound(|(p, _)| *p)) {
1855+
let predicate = predicate.subst(self.tcx, substs);
18561856
let output = predicate
18571857
.kind()
18581858
.map_bound(|kind| match kind {

compiler/rustc_infer/src/infer/opaque_types.rs

+4-4
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ use rustc_middle::traits::ObligationCause;
99
use rustc_middle::ty::fold::BottomUpFolder;
1010
use rustc_middle::ty::subst::{GenericArgKind, Subst};
1111
use rustc_middle::ty::{
12-
self, EarlyBinder, OpaqueHiddenType, OpaqueTypeKey, Ty, TyCtxt, TypeFoldable, TypeVisitor,
12+
self, OpaqueHiddenType, OpaqueTypeKey, Ty, TyCtxt, TypeFoldable, TypeVisitor,
1313
};
1414
use rustc_span::Span;
1515

@@ -561,11 +561,11 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
561561
obligations = self.at(&cause, param_env).eq(prev, hidden_ty)?.obligations;
562562
}
563563

564-
let item_bounds = tcx.explicit_item_bounds(def_id);
564+
let item_bounds = tcx.bound_explicit_item_bounds(def_id);
565565

566-
for (predicate, _) in item_bounds {
566+
for predicate in item_bounds.transpose_iter().map(|e| e.map_bound(|(p, _)| *p)) {
567567
debug!(?predicate);
568-
let predicate = EarlyBinder(*predicate).subst(tcx, substs);
568+
let predicate = predicate.subst(tcx, substs);
569569

570570
let predicate = predicate.fold_with(&mut BottomUpFolder {
571571
tcx,

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

+4-6
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,6 @@
11
use crate::mir::interpret::{AllocRange, ConstValue, GlobalAlloc, Pointer, Provenance, Scalar};
22
use crate::ty::subst::{GenericArg, GenericArgKind, Subst};
3-
use crate::ty::{
4-
self, ConstInt, DefIdTree, EarlyBinder, ParamConst, ScalarInt, Term, Ty, TyCtxt, TypeFoldable,
5-
};
3+
use crate::ty::{self, ConstInt, DefIdTree, ParamConst, ScalarInt, Term, Ty, TyCtxt, TypeFoldable};
64
use rustc_apfloat::ieee::{Double, Single};
75
use rustc_data_structures::fx::FxHashMap;
86
use rustc_data_structures::sso::SsoHashSet;
@@ -776,14 +774,14 @@ pub trait PrettyPrinter<'tcx>:
776774

777775
// Grab the "TraitA + TraitB" from `impl TraitA + TraitB`,
778776
// by looking up the projections associated with the def_id.
779-
let bounds = self.tcx().explicit_item_bounds(def_id);
777+
let bounds = self.tcx().bound_explicit_item_bounds(def_id);
780778

781779
let mut traits = BTreeMap::new();
782780
let mut fn_traits = BTreeMap::new();
783781
let mut is_sized = false;
784782

785-
for (predicate, _) in bounds {
786-
let predicate = EarlyBinder(*predicate).subst(self.tcx(), substs);
783+
for predicate in bounds.transpose_iter().map(|e| e.map_bound(|(p, _)| *p)) {
784+
let predicate = predicate.subst(self.tcx(), substs);
787785
let bound_predicate = predicate.kind();
788786

789787
match bound_predicate.skip_binder() {

compiler/rustc_middle/src/ty/sty.rs

+24
Original file line numberDiff line numberDiff line change
@@ -1109,6 +1109,30 @@ impl<T> EarlyBinder<Option<T>> {
11091109
}
11101110
}
11111111

1112+
impl<T, U> EarlyBinder<(T, U)> {
1113+
pub fn transpose_tuple2(self) -> (EarlyBinder<T>, EarlyBinder<U>) {
1114+
(EarlyBinder(self.0.0), EarlyBinder(self.0.1))
1115+
}
1116+
}
1117+
1118+
pub struct EarlyBinderIter<T> {
1119+
t: T,
1120+
}
1121+
1122+
impl<T: IntoIterator> EarlyBinder<T> {
1123+
pub fn transpose_iter(self) -> EarlyBinderIter<T::IntoIter> {
1124+
EarlyBinderIter { t: self.0.into_iter() }
1125+
}
1126+
}
1127+
1128+
impl<T: Iterator> Iterator for EarlyBinderIter<T> {
1129+
type Item = EarlyBinder<T::Item>;
1130+
1131+
fn next(&mut self) -> Option<Self::Item> {
1132+
self.t.next().map(|i| EarlyBinder(i))
1133+
}
1134+
}
1135+
11121136
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug, TyEncodable, TyDecodable)]
11131137
#[derive(HashStable)]
11141138
pub enum BoundVariableKind {

compiler/rustc_middle/src/ty/util.rs

+14
Original file line numberDiff line numberDiff line change
@@ -604,6 +604,20 @@ impl<'tcx> TyCtxt<'tcx> {
604604
pub fn bound_impl_trait_ref(self, def_id: DefId) -> Option<EarlyBinder<ty::TraitRef<'tcx>>> {
605605
self.impl_trait_ref(def_id).map(|i| EarlyBinder(i))
606606
}
607+
608+
pub fn bound_explicit_item_bounds(
609+
self,
610+
def_id: DefId,
611+
) -> EarlyBinder<&'tcx [(ty::Predicate<'tcx>, rustc_span::Span)]> {
612+
EarlyBinder(self.explicit_item_bounds(def_id))
613+
}
614+
615+
pub fn bound_item_bounds(
616+
self,
617+
def_id: DefId,
618+
) -> EarlyBinder<&'tcx ty::List<ty::Predicate<'tcx>>> {
619+
EarlyBinder(self.item_bounds(def_id))
620+
}
607621
}
608622

609623
struct OpaqueTypeExpander<'tcx> {

compiler/rustc_trait_selection/src/traits/project.rs

+2-4
Original file line numberDiff line numberDiff line change
@@ -1276,10 +1276,8 @@ fn assemble_candidates_from_trait_def<'cx, 'tcx>(
12761276
// Check whether the self-type is itself a projection.
12771277
// If so, extract what we know from the trait and try to come up with a good answer.
12781278
let bounds = match *obligation.predicate.self_ty().kind() {
1279-
ty::Projection(ref data) => {
1280-
EarlyBinder(tcx.item_bounds(data.item_def_id)).subst(tcx, data.substs)
1281-
}
1282-
ty::Opaque(def_id, substs) => EarlyBinder(tcx.item_bounds(def_id)).subst(tcx, substs),
1279+
ty::Projection(ref data) => tcx.bound_item_bounds(data.item_def_id).subst(tcx, data.substs),
1280+
ty::Opaque(def_id, substs) => tcx.bound_item_bounds(def_id).subst(tcx, substs),
12831281
ty::Infer(ty::TyVar(_)) => {
12841282
// If the self-type is an inference variable, then it MAY wind up
12851283
// being a projected type, so induce an ambiguity.

compiler/rustc_trait_selection/src/traits/select/confirmation.rs

+26-25
Original file line numberDiff line numberDiff line change
@@ -174,7 +174,8 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
174174
_ => bug!("projection candidate for unexpected type: {:?}", placeholder_self_ty),
175175
};
176176

177-
let candidate_predicate = EarlyBinder(tcx.item_bounds(def_id)[idx]).subst(tcx, substs);
177+
let candidate_predicate =
178+
tcx.bound_item_bounds(def_id).map_bound(|i| i[idx]).subst(tcx, substs);
178179
let candidate = candidate_predicate
179180
.to_opt_poly_trait_pred()
180181
.expect("projection candidate is not a trait predicate")
@@ -500,21 +501,21 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
500501
// This maybe belongs in wf, but that can't (doesn't) handle
501502
// higher-ranked things.
502503
// Prevent, e.g., `dyn Iterator<Item = str>`.
503-
for bound in self.tcx().item_bounds(assoc_type) {
504-
let subst_bound = if defs.count() == 0 {
505-
EarlyBinder(bound).subst(tcx, trait_predicate.trait_ref.substs)
506-
} else {
507-
let mut substs = smallvec::SmallVec::with_capacity(defs.count());
508-
substs.extend(trait_predicate.trait_ref.substs.iter());
509-
let mut bound_vars: smallvec::SmallVec<[ty::BoundVariableKind; 8]> =
510-
smallvec::SmallVec::with_capacity(
511-
bound.kind().bound_vars().len() + defs.count(),
512-
);
513-
bound_vars.extend(bound.kind().bound_vars().into_iter());
514-
InternalSubsts::fill_single(
515-
&mut substs,
516-
defs,
517-
&mut |param, _| match param.kind {
504+
for bound in self.tcx().bound_item_bounds(assoc_type).transpose_iter() {
505+
let subst_bound =
506+
if defs.count() == 0 {
507+
bound.subst(tcx, trait_predicate.trait_ref.substs)
508+
} else {
509+
let mut substs = smallvec::SmallVec::with_capacity(defs.count());
510+
substs.extend(trait_predicate.trait_ref.substs.iter());
511+
let mut bound_vars: smallvec::SmallVec<[ty::BoundVariableKind; 8]> =
512+
smallvec::SmallVec::with_capacity(
513+
bound.0.kind().bound_vars().len() + defs.count(),
514+
);
515+
bound_vars.extend(bound.0.kind().bound_vars().into_iter());
516+
InternalSubsts::fill_single(&mut substs, defs, &mut |param, _| match param
517+
.kind
518+
{
518519
GenericParamDefKind::Type { .. } => {
519520
let kind = ty::BoundTyKind::Param(param.name);
520521
let bound_var = ty::BoundVariableKind::Ty(kind);
@@ -553,15 +554,15 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
553554
})
554555
.into()
555556
}
556-
},
557-
);
558-
let bound_vars = tcx.mk_bound_variable_kinds(bound_vars.into_iter());
559-
let assoc_ty_substs = tcx.intern_substs(&substs);
560-
561-
let bound_vars = tcx.mk_bound_variable_kinds(bound_vars.into_iter());
562-
let bound = EarlyBinder(bound.kind().skip_binder()).subst(tcx, assoc_ty_substs);
563-
tcx.mk_predicate(ty::Binder::bind_with_vars(bound, bound_vars))
564-
};
557+
});
558+
let bound_vars = tcx.mk_bound_variable_kinds(bound_vars.into_iter());
559+
let assoc_ty_substs = tcx.intern_substs(&substs);
560+
561+
let bound_vars = tcx.mk_bound_variable_kinds(bound_vars.into_iter());
562+
let bound =
563+
EarlyBinder(bound.0.kind().skip_binder()).subst(tcx, assoc_ty_substs);
564+
tcx.mk_predicate(ty::Binder::bind_with_vars(bound, bound_vars))
565+
};
565566
let normalized_bound = normalize_with_depth_to(
566567
self,
567568
obligation.param_env,

compiler/rustc_trait_selection/src/traits/select/mod.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1341,7 +1341,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
13411341
);
13421342
}
13431343
};
1344-
let bounds = EarlyBinder(tcx.item_bounds(def_id)).subst(tcx, substs);
1344+
let bounds = tcx.bound_item_bounds(def_id).subst(tcx, substs);
13451345

13461346
// The bounds returned by `item_bounds` may contain duplicates after
13471347
// normalization, so try to deduplicate when possible to avoid

compiler/rustc_typeck/src/astconv/mod.rs

+2-4
Original file line numberDiff line numberDiff line change
@@ -2447,10 +2447,8 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
24472447
true,
24482448
None,
24492449
);
2450-
self.normalize_ty(
2451-
span,
2452-
EarlyBinder(tcx.at(span).type_of(def_id)).subst(tcx, substs),
2453-
)
2450+
EarlyBinder(self.normalize_ty(span, tcx.at(span).type_of(def_id)))
2451+
.subst(tcx, substs)
24542452
}
24552453
hir::TyKind::Array(ref ty, ref length) => {
24562454
let length = match length {

compiler/rustc_typeck/src/check/closure.rs

+34-24
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ use rustc_infer::infer::LateBoundRegionConversionTime;
1212
use rustc_infer::infer::{InferOk, InferResult};
1313
use rustc_middle::ty::fold::TypeFoldable;
1414
use rustc_middle::ty::subst::InternalSubsts;
15-
use rustc_middle::ty::{self, EarlyBinder, Ty};
15+
use rustc_middle::ty::{self, Ty};
1616
use rustc_span::source_map::Span;
1717
use rustc_span::DUMMY_SP;
1818
use rustc_target::spec::abi::Abi;
@@ -175,19 +175,25 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
175175
) -> (Option<ExpectedSig<'tcx>>, Option<ty::ClosureKind>) {
176176
match *expected_ty.kind() {
177177
ty::Opaque(def_id, substs) => {
178-
let bounds = self.tcx.explicit_item_bounds(def_id);
179-
let sig = bounds.iter().find_map(|(pred, span)| match pred.kind().skip_binder() {
180-
ty::PredicateKind::Projection(proj_predicate) => self
181-
.deduce_sig_from_projection(
182-
Some(*span),
183-
pred.kind().rebind(EarlyBinder(proj_predicate).subst(self.tcx, substs)),
184-
),
185-
_ => None,
186-
});
178+
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() {
183+
ty::PredicateKind::Projection(proj_predicate) => self
184+
.deduce_sig_from_projection(
185+
Some(span.0),
186+
pred.0.kind().rebind(
187+
pred.map_bound(|_| proj_predicate).subst(self.tcx, substs),
188+
),
189+
),
190+
_ => None,
191+
});
187192

188193
let kind = bounds
189-
.iter()
190-
.filter_map(|(pred, _)| match pred.kind().skip_binder() {
194+
.transpose_iter()
195+
.map(|e| e.map_bound(|e| *e).transpose_tuple2())
196+
.filter_map(|(pred, _)| match pred.0.kind().skip_binder() {
191197
ty::PredicateKind::Trait(tp) => {
192198
self.tcx.fn_trait_kind_from_lang_item(tp.def_id())
193199
}
@@ -668,25 +674,29 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
668674
),
669675
};
670676

671-
let item_bounds = self.tcx.explicit_item_bounds(def_id);
677+
let item_bounds = self.tcx.bound_explicit_item_bounds(def_id);
672678

673679
// Search for a pending obligation like
674680
//
675681
// `<R as Future>::Output = T`
676682
//
677683
// where R is the return type we are expecting. This type `T`
678684
// will be our output.
679-
let output_ty = item_bounds.iter().find_map(|&(predicate, span)| {
680-
let bound_predicate = EarlyBinder(predicate).subst(self.tcx, substs).kind();
681-
if let ty::PredicateKind::Projection(proj_predicate) = bound_predicate.skip_binder() {
682-
self.deduce_future_output_from_projection(
683-
span,
684-
bound_predicate.rebind(proj_predicate),
685-
)
686-
} else {
687-
None
688-
}
689-
});
685+
let output_ty = item_bounds
686+
.transpose_iter()
687+
.map(|e| e.map_bound(|e| *e).transpose_tuple2())
688+
.find_map(|(predicate, span)| {
689+
let bound_predicate = predicate.subst(self.tcx, substs).kind();
690+
if let ty::PredicateKind::Projection(proj_predicate) = bound_predicate.skip_binder()
691+
{
692+
self.deduce_future_output_from_projection(
693+
span.0,
694+
bound_predicate.rebind(proj_predicate),
695+
)
696+
} else {
697+
None
698+
}
699+
});
690700

691701
debug!("deduce_future_output_from_obligations: output_ty={:?}", output_ty);
692702
output_ty

compiler/rustc_typeck/src/check/compare_method.rs

+7-6
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ use rustc_infer::traits::util;
1010
use rustc_middle::ty::error::{ExpectedFound, TypeError};
1111
use rustc_middle::ty::subst::{InternalSubsts, Subst};
1212
use rustc_middle::ty::util::ExplicitSelf;
13-
use rustc_middle::ty::{self, DefIdTree, EarlyBinder};
13+
use rustc_middle::ty::{self, DefIdTree};
1414
use rustc_middle::ty::{GenericParamDefKind, ToPredicate, TyCtxt};
1515
use rustc_span::Span;
1616
use rustc_trait_selection::traits::error_reporting::InferCtxtExt;
@@ -1451,14 +1451,15 @@ pub fn check_type_bounds<'tcx>(
14511451
};
14521452

14531453
let obligations = tcx
1454-
.explicit_item_bounds(trait_ty.def_id)
1455-
.iter()
1456-
.map(|&(bound, span)| {
1454+
.bound_explicit_item_bounds(trait_ty.def_id)
1455+
.transpose_iter()
1456+
.map(|e| e.map_bound(|e| *e).transpose_tuple2())
1457+
.map(|(bound, span)| {
14571458
debug!(?bound);
1458-
let concrete_ty_bound = EarlyBinder(bound).subst(tcx, rebased_substs);
1459+
let concrete_ty_bound = bound.subst(tcx, rebased_substs);
14591460
debug!("check_type_bounds: concrete_ty_bound = {:?}", concrete_ty_bound);
14601461

1461-
traits::Obligation::new(mk_cause(span), param_env, concrete_ty_bound)
1462+
traits::Obligation::new(mk_cause(span.0), param_env, concrete_ty_bound)
14621463
})
14631464
.collect();
14641465
debug!("check_type_bounds: item_bounds={:?}", obligations);

0 commit comments

Comments
 (0)