Auto merge of #93505 - lcnr:substsref-vs-ty-list, r=michaelwoerister
safely `transmute<&List<Ty<'tcx>>, &List<GenericArg<'tcx>>>` This PR has 3 relevant steps which are is split in distinct commits. The first commit now interns `List<Ty<'tcx>>` and `List<GenericArg<'tcx>>` together, potentially reusing memory while allowing free conversions between these two using `List<Ty<'tcx>>::as_substs()` and `SubstsRef<'tcx>::try_as_type_list()`. Using this, we then use `&'tcx List<Ty<'tcx>>` instead of a `SubstsRef<'tcx>` for tuple fields, simplifying a bunch of code. Finally, as tuple fields and other generic arguments now use a different `TypeFoldable<'tcx>` impl, we optimize the impl for `List<Ty<'tcx>>` improving perf by slightly less than 1% in tuple heavy benchmarks.
This commit is contained in:
@@ -1015,9 +1015,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
||||
|
||||
// Check that the source tuple with the target's
|
||||
// last element is equal to the target.
|
||||
let new_tuple = tcx.mk_tup(
|
||||
a_mid.iter().map(|k| k.expect_ty()).chain(iter::once(b_last.expect_ty())),
|
||||
);
|
||||
let new_tuple = tcx.mk_tup(a_mid.iter().copied().chain(iter::once(b_last)));
|
||||
let InferOk { obligations, .. } = self
|
||||
.infcx
|
||||
.at(&obligation.cause, obligation.param_env)
|
||||
@@ -1033,8 +1031,8 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
||||
obligation.cause.clone(),
|
||||
obligation.predicate.def_id(),
|
||||
obligation.recursion_depth + 1,
|
||||
a_last.expect_ty(),
|
||||
&[b_last],
|
||||
a_last,
|
||||
&[b_last.into()],
|
||||
)
|
||||
}));
|
||||
}
|
||||
@@ -1097,7 +1095,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
||||
stack.push(ty);
|
||||
}
|
||||
ty::Tuple(tys) => {
|
||||
stack.extend(tys.iter().map(|ty| ty.expect_ty()));
|
||||
stack.extend(tys.iter());
|
||||
}
|
||||
ty::Closure(_, substs) => {
|
||||
stack.push(substs.as_closure().tupled_upvars_ty());
|
||||
|
||||
@@ -1852,9 +1852,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
||||
ty::Str | ty::Slice(_) | ty::Dynamic(..) | ty::Foreign(..) => None,
|
||||
|
||||
ty::Tuple(tys) => Where(
|
||||
obligation
|
||||
.predicate
|
||||
.rebind(tys.last().into_iter().map(|k| k.expect_ty()).collect()),
|
||||
obligation.predicate.rebind(tys.last().map_or_else(Vec::new, |&last| vec![last])),
|
||||
),
|
||||
|
||||
ty::Adt(def, substs) => {
|
||||
@@ -1917,7 +1915,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
||||
|
||||
ty::Tuple(tys) => {
|
||||
// (*) binder moved here
|
||||
Where(obligation.predicate.rebind(tys.iter().map(|k| k.expect_ty()).collect()))
|
||||
Where(obligation.predicate.rebind(tys.iter().collect()))
|
||||
}
|
||||
|
||||
ty::Closure(_, substs) => {
|
||||
@@ -1997,7 +1995,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
||||
|
||||
ty::Tuple(ref tys) => {
|
||||
// (T1, ..., Tn) -- meets any bound that all of T1...Tn meet
|
||||
t.rebind(tys.iter().map(|k| k.expect_ty()).collect())
|
||||
t.rebind(tys.iter().collect())
|
||||
}
|
||||
|
||||
ty::Closure(_, ref substs) => {
|
||||
|
||||
Reference in New Issue
Block a user