about summary refs log tree commit diff
diff options
context:
space:
mode:
authorMichael Goulet <michael@errs.io>2024-06-21 13:55:21 -0400
committerMichael Goulet <michael@errs.io>2024-06-24 11:53:34 -0400
commit24e41f1d134fdd969308894baddced76ad79712d (patch)
treed9e18b0a9bd06842f367cafb5e7581ce5db3fc23
parentf26cc349d9b22272b4de474f78ac7829777a0649 (diff)
downloadrust-24e41f1d134fdd969308894baddced76ad79712d.tar.gz
rust-24e41f1d134fdd969308894baddced76ad79712d.zip
Replace Deref bounds on Interner in favor of a SliceLike trait
-rw-r--r--compiler/rustc_middle/src/ty/list.rs14
-rw-r--r--compiler/rustc_next_trait_solver/src/solve/assembly/mod.rs4
-rw-r--r--compiler/rustc_next_trait_solver/src/solve/assembly/structural_traits.rs33
-rw-r--r--compiler/rustc_next_trait_solver/src/solve/eval_ctxt/canonical.rs11
-rw-r--r--compiler/rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs4
-rw-r--r--compiler/rustc_next_trait_solver/src/solve/inspect/build.rs1
-rw-r--r--compiler/rustc_next_trait_solver/src/solve/mod.rs2
-rw-r--r--compiler/rustc_next_trait_solver/src/solve/normalizes_to/inherent.rs6
-rw-r--r--compiler/rustc_next_trait_solver/src/solve/normalizes_to/mod.rs20
-rw-r--r--compiler/rustc_next_trait_solver/src/solve/normalizes_to/opaque_types.rs4
-rw-r--r--compiler/rustc_next_trait_solver/src/solve/normalizes_to/weak_types.rs4
-rw-r--r--compiler/rustc_next_trait_solver/src/solve/trait_goals.rs27
-rw-r--r--compiler/rustc_type_ir/src/binder.rs35
-rw-r--r--compiler/rustc_type_ir/src/canonical.rs12
-rw-r--r--compiler/rustc_type_ir/src/inherent.rs107
-rw-r--r--compiler/rustc_type_ir/src/interner.rs20
-rw-r--r--compiler/rustc_type_ir/src/opaque_ty.rs10
-rw-r--r--compiler/rustc_type_ir/src/predicate.rs20
-rw-r--r--compiler/rustc_type_ir/src/relate.rs22
-rw-r--r--compiler/rustc_type_ir/src/ty_kind.rs6
-rw-r--r--compiler/rustc_type_ir/src/ty_kind/closure.rs16
-rw-r--r--src/tools/clippy/clippy_lints/src/needless_borrows_for_generic_args.rs2
22 files changed, 221 insertions, 159 deletions
diff --git a/compiler/rustc_middle/src/ty/list.rs b/compiler/rustc_middle/src/ty/list.rs
index 71a93cc520d..73eba93194e 100644
--- a/compiler/rustc_middle/src/ty/list.rs
+++ b/compiler/rustc_middle/src/ty/list.rs
@@ -133,6 +133,20 @@ impl<H, T> RawList<H, T> {
     }
 }
 
+impl<'a, H, T: Copy> rustc_type_ir::inherent::SliceLike for &'a RawList<H, T> {
+    type Item = T;
+
+    type IntoIter = iter::Copied<<&'a [T] as IntoIterator>::IntoIter>;
+
+    fn iter(self) -> Self::IntoIter {
+        (*self).iter()
+    }
+
+    fn as_slice(&self) -> &[Self::Item] {
+        (*self).as_slice()
+    }
+}
+
 macro_rules! impl_list_empty {
     ($header_ty:ty, $header_init:expr) => {
         impl<T> RawList<$header_ty, T> {
diff --git a/compiler/rustc_next_trait_solver/src/solve/assembly/mod.rs b/compiler/rustc_next_trait_solver/src/solve/assembly/mod.rs
index cae9c5c8567..ee7279a43b2 100644
--- a/compiler/rustc_next_trait_solver/src/solve/assembly/mod.rs
+++ b/compiler/rustc_next_trait_solver/src/solve/assembly/mod.rs
@@ -527,7 +527,7 @@ where
         };
 
         for assumption in
-            self.cx().item_bounds(alias_ty.def_id).iter_instantiated(self.cx(), &alias_ty.args)
+            self.cx().item_bounds(alias_ty.def_id).iter_instantiated(self.cx(), alias_ty.args)
         {
             candidates.extend(G::probe_and_consider_implied_clause(
                 self,
@@ -603,7 +603,7 @@ where
         // Consider all of the auto-trait and projection bounds, which don't
         // need to be recorded as a `BuiltinImplSource::Object` since they don't
         // really have a vtable base...
-        for bound in bounds {
+        for bound in bounds.iter() {
             match bound.skip_binder() {
                 ty::ExistentialPredicate::Trait(_) => {
                     // Skip principal
diff --git a/compiler/rustc_next_trait_solver/src/solve/assembly/structural_traits.rs b/compiler/rustc_next_trait_solver/src/solve/assembly/structural_traits.rs
index b10be5a9ba7..d4890e48032 100644
--- a/compiler/rustc_next_trait_solver/src/solve/assembly/structural_traits.rs
+++ b/compiler/rustc_next_trait_solver/src/solve/assembly/structural_traits.rs
@@ -58,7 +58,7 @@ where
 
         ty::Tuple(tys) => {
             // (T1, ..., Tn) -- meets any bound that all of T1...Tn meet
-            Ok(tys.into_iter().map(ty::Binder::dummy).collect())
+            Ok(tys.iter().map(ty::Binder::dummy).collect())
         }
 
         ty::Closure(_, args) => Ok(vec![ty::Binder::dummy(args.as_closure().tupled_upvars_ty())]),
@@ -79,23 +79,21 @@ where
             .cx()
             .bound_coroutine_hidden_types(def_id)
             .into_iter()
-            .map(|bty| bty.instantiate(tcx, &args))
+            .map(|bty| bty.instantiate(tcx, args))
             .collect()),
 
         // For `PhantomData<T>`, we pass `T`.
         ty::Adt(def, args) if def.is_phantom_data() => Ok(vec![ty::Binder::dummy(args.type_at(0))]),
 
-        ty::Adt(def, args) => Ok(def
-            .all_field_tys(tcx)
-            .iter_instantiated(tcx, &args)
-            .map(ty::Binder::dummy)
-            .collect()),
+        ty::Adt(def, args) => {
+            Ok(def.all_field_tys(tcx).iter_instantiated(tcx, args).map(ty::Binder::dummy).collect())
+        }
 
         ty::Alias(ty::Opaque, ty::AliasTy { def_id, args, .. }) => {
             // We can resolve the `impl Trait` to its concrete type,
             // which enforces a DAG between the functions requiring
             // the auto trait bounds in question.
-            Ok(vec![ty::Binder::dummy(tcx.type_of(def_id).instantiate(tcx, &args))])
+            Ok(vec![ty::Binder::dummy(tcx.type_of(def_id).instantiate(tcx, args))])
         }
     }
 }
@@ -147,7 +145,7 @@ where
 
         // impl Sized for ()
         // impl Sized for (T1, T2, .., Tn) where Tn: Sized if n >= 1
-        ty::Tuple(tys) => Ok(tys.last().map_or_else(Vec::new, |&ty| vec![ty::Binder::dummy(ty)])),
+        ty::Tuple(tys) => Ok(tys.last().map_or_else(Vec::new, |ty| vec![ty::Binder::dummy(ty)])),
 
         // impl Sized for Adt<Args...> where sized_constraint(Adt)<Args...>: Sized
         //   `sized_constraint(Adt)` is the deepest struct trail that can be determined
@@ -160,7 +158,7 @@ where
         //   if the ADT is sized for all possible args.
         ty::Adt(def, args) => {
             if let Some(sized_crit) = def.sized_constraint(ecx.cx()) {
-                Ok(vec![ty::Binder::dummy(sized_crit.instantiate(ecx.cx(), &args))])
+                Ok(vec![ty::Binder::dummy(sized_crit.instantiate(ecx.cx(), args))])
             } else {
                 Ok(vec![])
             }
@@ -213,7 +211,7 @@ where
         }
 
         // impl Copy/Clone for (T1, T2, .., Tn) where T1: Copy/Clone, T2: Copy/Clone, .. Tn: Copy/Clone
-        ty::Tuple(tys) => Ok(tys.into_iter().map(ty::Binder::dummy).collect()),
+        ty::Tuple(tys) => Ok(tys.iter().map(ty::Binder::dummy).collect()),
 
         // impl Copy/Clone for Closure where Self::TupledUpvars: Copy/Clone
         ty::Closure(_, args) => Ok(vec![ty::Binder::dummy(args.as_closure().tupled_upvars_ty())]),
@@ -242,7 +240,7 @@ where
             .cx()
             .bound_coroutine_hidden_types(def_id)
             .into_iter()
-            .map(|bty| bty.instantiate(ecx.cx(), &args))
+            .map(|bty| bty.instantiate(ecx.cx(), args))
             .collect()),
     }
 }
@@ -259,7 +257,7 @@ pub(in crate::solve) fn extract_tupled_inputs_and_output_from_callable<I: Intern
             let sig = tcx.fn_sig(def_id);
             if sig.skip_binder().is_fn_trait_compatible() && !tcx.has_target_features(def_id) {
                 Ok(Some(
-                    sig.instantiate(tcx, &args)
+                    sig.instantiate(tcx, args)
                         .map_bound(|sig| (Ty::new_tup(tcx, &sig.inputs()), sig.output())),
                 ))
             } else {
@@ -669,7 +667,7 @@ where
     let tcx = ecx.cx();
     let mut requirements = vec![];
     requirements
-        .extend(tcx.super_predicates_of(trait_ref.def_id).iter_instantiated(tcx, &trait_ref.args));
+        .extend(tcx.super_predicates_of(trait_ref.def_id).iter_instantiated(tcx, trait_ref.args));
 
     // FIXME(associated_const_equality): Also add associated consts to
     // the requirements here.
@@ -680,13 +678,12 @@ where
             continue;
         }
 
-        requirements.extend(
-            tcx.item_bounds(associated_type_def_id).iter_instantiated(tcx, &trait_ref.args),
-        );
+        requirements
+            .extend(tcx.item_bounds(associated_type_def_id).iter_instantiated(tcx, trait_ref.args));
     }
 
     let mut replace_projection_with = HashMap::default();
-    for bound in object_bounds {
+    for bound in object_bounds.iter() {
         if let ty::ExistentialPredicate::Projection(proj) = bound.skip_binder() {
             let proj = proj.with_self_ty(tcx, trait_ref.self_ty());
             let old_ty = replace_projection_with.insert(proj.def_id(), bound.rebind(proj));
diff --git a/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/canonical.rs b/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/canonical.rs
index f1d4864a84b..0a313c6a951 100644
--- a/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/canonical.rs
+++ b/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/canonical.rs
@@ -267,7 +267,9 @@ where
         // We therefore instantiate the existential variable in the canonical response with the
         // inference variable of the input right away, which is more performant.
         let mut opt_values = IndexVec::from_elem_n(None, response.variables.len());
-        for (original_value, result_value) in iter::zip(original_values, var_values.var_values) {
+        for (original_value, result_value) in
+            iter::zip(original_values, var_values.var_values.iter())
+        {
             match result_value.kind() {
                 ty::GenericArgKind::Type(t) => {
                     if let ty::Bound(debruijn, b) = t.kind() {
@@ -291,7 +293,7 @@ where
         }
 
         let var_values = delegate.cx().mk_args_from_iter(
-            response.variables.into_iter().enumerate().map(|(index, info)| {
+            response.variables.iter().enumerate().map(|(index, info)| {
                 if info.universe() != ty::UniverseIndex::ROOT {
                     // A variable from inside a binder of the query. While ideally these shouldn't
                     // exist at all (see the FIXME at the start of this method), we have to deal with
@@ -344,7 +346,7 @@ where
     ) {
         assert_eq!(original_values.len(), var_values.len());
 
-        for (&orig, response) in iter::zip(original_values, var_values.var_values) {
+        for (&orig, response) in iter::zip(original_values, var_values.var_values.iter()) {
             let goals =
                 delegate.eq_structurally_relating_aliases(param_env, orig, response).unwrap();
             assert!(goals.is_empty());
@@ -413,7 +415,8 @@ where
     // In case any fresh inference variables have been created between `state`
     // and the previous instantiation, extend `orig_values` for it.
     assert!(orig_values.len() <= state.value.var_values.len());
-    for &arg in &state.value.var_values.var_values[orig_values.len()..state.value.var_values.len()]
+    for &arg in &state.value.var_values.var_values.as_slice()
+        [orig_values.len()..state.value.var_values.len()]
     {
         // FIXME: This is so ugly.
         let unconstrained = delegate.fresh_var_for_kind_with_span(arg, span);
diff --git a/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs b/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs
index 687623d4408..04dce2780b0 100644
--- a/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs
+++ b/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/mod.rs
@@ -875,7 +875,7 @@ where
 
     pub(super) fn fresh_args_for_item(&mut self, def_id: I::DefId) -> I::GenericArgs {
         let args = self.delegate.fresh_args_for_item(def_id);
-        for arg in args {
+        for arg in args.iter() {
             self.inspect.add_var_value(arg);
         }
         args
@@ -979,7 +979,7 @@ where
                     result: *result,
                 })
                 .enter(|ecx| {
-                    for (a, b) in std::iter::zip(candidate_key.args, key.args) {
+                    for (a, b) in std::iter::zip(candidate_key.args.iter(), key.args.iter()) {
                         ecx.eq(param_env, a, b)?;
                     }
                     ecx.eq(param_env, candidate_ty, ty)?;
diff --git a/compiler/rustc_next_trait_solver/src/solve/inspect/build.rs b/compiler/rustc_next_trait_solver/src/solve/inspect/build.rs
index ae59f0c5e95..4fc58e06d67 100644
--- a/compiler/rustc_next_trait_solver/src/solve/inspect/build.rs
+++ b/compiler/rustc_next_trait_solver/src/solve/inspect/build.rs
@@ -7,6 +7,7 @@
 use std::marker::PhantomData;
 use std::mem;
 
+use rustc_type_ir::inherent::*;
 use rustc_type_ir::{self as ty, Interner};
 
 use crate::delegate::SolverDelegate;
diff --git a/compiler/rustc_next_trait_solver/src/solve/mod.rs b/compiler/rustc_next_trait_solver/src/solve/mod.rs
index b76b4c09852..e29ae7ac0a2 100644
--- a/compiler/rustc_next_trait_solver/src/solve/mod.rs
+++ b/compiler/rustc_next_trait_solver/src/solve/mod.rs
@@ -182,7 +182,7 @@ where
                 return self.evaluate_added_goals_and_make_canonical_response(Certainty::Yes);
             }
             ty::ConstKind::Unevaluated(uv) => {
-                self.cx().type_of(uv.def).instantiate(self.cx(), &uv.args)
+                self.cx().type_of(uv.def).instantiate(self.cx(), uv.args)
             }
             ty::ConstKind::Expr(_) => unimplemented!(
                 "`feature(generic_const_exprs)` is not supported in the new trait solver"
diff --git a/compiler/rustc_next_trait_solver/src/solve/normalizes_to/inherent.rs b/compiler/rustc_next_trait_solver/src/solve/normalizes_to/inherent.rs
index 827fe5f2ca4..004ecf2d2c4 100644
--- a/compiler/rustc_next_trait_solver/src/solve/normalizes_to/inherent.rs
+++ b/compiler/rustc_next_trait_solver/src/solve/normalizes_to/inherent.rs
@@ -29,7 +29,7 @@ where
         self.eq(
             goal.param_env,
             inherent.self_ty(),
-            tcx.type_of(impl_def_id).instantiate(tcx, &impl_args),
+            tcx.type_of(impl_def_id).instantiate(tcx, impl_args),
         )?;
 
         // Equate IAT with the RHS of the project goal
@@ -44,11 +44,11 @@ where
         self.add_goals(
             GoalSource::Misc,
             tcx.predicates_of(inherent.def_id)
-                .iter_instantiated(tcx, &inherent_args)
+                .iter_instantiated(tcx, inherent_args)
                 .map(|pred| goal.with(tcx, pred)),
         );
 
-        let normalized = tcx.type_of(inherent.def_id).instantiate(tcx, &inherent_args);
+        let normalized = tcx.type_of(inherent.def_id).instantiate(tcx, inherent_args);
         self.instantiate_normalizes_to_term(goal, normalized.into());
         self.evaluate_added_goals_and_make_canonical_response(Certainty::Yes)
     }
diff --git a/compiler/rustc_next_trait_solver/src/solve/normalizes_to/mod.rs b/compiler/rustc_next_trait_solver/src/solve/normalizes_to/mod.rs
index f58384d86cd..bc5233c4887 100644
--- a/compiler/rustc_next_trait_solver/src/solve/normalizes_to/mod.rs
+++ b/compiler/rustc_next_trait_solver/src/solve/normalizes_to/mod.rs
@@ -121,7 +121,7 @@ where
                     ecx.add_goals(
                         GoalSource::Misc,
                         tcx.own_predicates_of(goal.predicate.def_id())
-                            .iter_instantiated(tcx, &goal.predicate.alias.args)
+                            .iter_instantiated(tcx, goal.predicate.alias.args)
                             .map(|pred| goal.with(tcx, pred)),
                     );
 
@@ -163,13 +163,13 @@ where
 
         ecx.probe_trait_candidate(CandidateSource::Impl(impl_def_id)).enter(|ecx| {
             let impl_args = ecx.fresh_args_for_item(impl_def_id);
-            let impl_trait_ref = impl_trait_ref.instantiate(tcx, &impl_args);
+            let impl_trait_ref = impl_trait_ref.instantiate(tcx, impl_args);
 
             ecx.eq(goal.param_env, goal_trait_ref, impl_trait_ref)?;
 
             let where_clause_bounds = tcx
                 .predicates_of(impl_def_id)
-                .iter_instantiated(tcx, &impl_args)
+                .iter_instantiated(tcx, impl_args)
                 .map(|pred| goal.with(tcx, pred));
             ecx.add_goals(GoalSource::ImplWhereBound, where_clause_bounds);
 
@@ -177,7 +177,7 @@ where
             ecx.add_goals(
                 GoalSource::Misc,
                 tcx.own_predicates_of(goal.predicate.def_id())
-                    .iter_instantiated(tcx, &goal.predicate.alias.args)
+                    .iter_instantiated(tcx, goal.predicate.alias.args)
                     .map(|pred| goal.with(tcx, pred)),
             );
 
@@ -254,7 +254,7 @@ where
                 kind => panic!("expected projection, found {kind:?}"),
             };
 
-            ecx.instantiate_normalizes_to_term(goal, term.instantiate(tcx, &target_args));
+            ecx.instantiate_normalizes_to_term(goal, term.instantiate(tcx, target_args));
             ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes)
         })
     }
@@ -467,7 +467,7 @@ where
             tupled_inputs_ty,
             tupled_upvars_ty,
             coroutine_captures_by_ref_ty,
-        ] = **goal.predicate.alias.args
+        ] = *goal.predicate.alias.args.as_slice()
         else {
             panic!();
         };
@@ -567,14 +567,14 @@ where
                 ty::Adt(def, args) if def.is_struct() => match def.struct_tail_ty(tcx) {
                     None => Ty::new_unit(tcx),
                     Some(tail_ty) => {
-                        Ty::new_projection(tcx, metadata_def_id, [tail_ty.instantiate(tcx, &args)])
+                        Ty::new_projection(tcx, metadata_def_id, [tail_ty.instantiate(tcx, args)])
                     }
                 },
                 ty::Adt(_, _) => Ty::new_unit(tcx),
 
                 ty::Tuple(elements) => match elements.last() {
                     None => Ty::new_unit(tcx),
-                    Some(&tail_ty) => Ty::new_projection(tcx, metadata_def_id, [tail_ty]),
+                    Some(tail_ty) => Ty::new_projection(tcx, metadata_def_id, [tail_ty]),
                 },
 
                 ty::Infer(
@@ -895,7 +895,7 @@ where
         } else {
             let target_args = self.fresh_args_for_item(target_container_def_id);
             let target_trait_ref =
-                tcx.impl_trait_ref(target_container_def_id).instantiate(tcx, &target_args);
+                tcx.impl_trait_ref(target_container_def_id).instantiate(tcx, target_args);
             // Relate source impl to target impl by equating trait refs.
             self.eq(goal.param_env, impl_trait_ref, target_trait_ref)?;
             // Also add predicates since they may be needed to constrain the
@@ -903,7 +903,7 @@ where
             self.add_goals(
                 GoalSource::Misc,
                 tcx.predicates_of(target_container_def_id)
-                    .iter_instantiated(tcx, &target_args)
+                    .iter_instantiated(tcx, target_args)
                     .map(|pred| goal.with(tcx, pred)),
             );
             goal.predicate.alias.args.rebase_onto(tcx, impl_trait_ref.def_id, target_args)
diff --git a/compiler/rustc_next_trait_solver/src/solve/normalizes_to/opaque_types.rs b/compiler/rustc_next_trait_solver/src/solve/normalizes_to/opaque_types.rs
index f3494328d9e..a16f9e64f2f 100644
--- a/compiler/rustc_next_trait_solver/src/solve/normalizes_to/opaque_types.rs
+++ b/compiler/rustc_next_trait_solver/src/solve/normalizes_to/opaque_types.rs
@@ -86,7 +86,7 @@ where
             }
             (Reveal::All, _) => {
                 // FIXME: Add an assertion that opaque type storage is empty.
-                let actual = tcx.type_of(opaque_ty.def_id).instantiate(tcx, &opaque_ty.args);
+                let actual = tcx.type_of(opaque_ty.def_id).instantiate(tcx, opaque_ty.args);
                 self.eq(goal.param_env, expected, actual)?;
                 self.evaluate_added_goals_and_make_canonical_response(Certainty::Yes)
             }
@@ -102,7 +102,7 @@ pub fn uses_unique_placeholders_ignoring_regions<I: Interner>(
     args: I::GenericArgs,
 ) -> Result<(), NotUniqueParam<I>> {
     let mut seen = GrowableBitSet::default();
-    for arg in args {
+    for arg in args.iter() {
         match arg.kind() {
             // Ignore regions, since we can't resolve those in a canonicalized
             // query in the trait solver.
diff --git a/compiler/rustc_next_trait_solver/src/solve/normalizes_to/weak_types.rs b/compiler/rustc_next_trait_solver/src/solve/normalizes_to/weak_types.rs
index 27d5ae07729..ca90bc17cc7 100644
--- a/compiler/rustc_next_trait_solver/src/solve/normalizes_to/weak_types.rs
+++ b/compiler/rustc_next_trait_solver/src/solve/normalizes_to/weak_types.rs
@@ -25,11 +25,11 @@ where
         self.add_goals(
             GoalSource::Misc,
             tcx.predicates_of(weak_ty.def_id)
-                .iter_instantiated(tcx, &weak_ty.args)
+                .iter_instantiated(tcx, weak_ty.args)
                 .map(|pred| goal.with(tcx, pred)),
         );
 
-        let actual = tcx.type_of(weak_ty.def_id).instantiate(tcx, &weak_ty.args);
+        let actual = tcx.type_of(weak_ty.def_id).instantiate(tcx, weak_ty.args);
         self.instantiate_normalizes_to_term(goal, actual.into());
 
         self.evaluate_added_goals_and_make_canonical_response(Certainty::Yes)
diff --git a/compiler/rustc_next_trait_solver/src/solve/trait_goals.rs b/compiler/rustc_next_trait_solver/src/solve/trait_goals.rs
index 2ddb3c981db..9746c836aff 100644
--- a/compiler/rustc_next_trait_solver/src/solve/trait_goals.rs
+++ b/compiler/rustc_next_trait_solver/src/solve/trait_goals.rs
@@ -77,12 +77,12 @@ where
         ecx.probe_trait_candidate(CandidateSource::Impl(impl_def_id)).enter(|ecx| {
             let impl_args = ecx.fresh_args_for_item(impl_def_id);
             ecx.record_impl_args(impl_args);
-            let impl_trait_ref = impl_trait_ref.instantiate(tcx, &impl_args);
+            let impl_trait_ref = impl_trait_ref.instantiate(tcx, impl_args);
 
             ecx.eq(goal.param_env, goal.predicate.trait_ref, impl_trait_ref)?;
             let where_clause_bounds = tcx
                 .predicates_of(impl_def_id)
-                .iter_instantiated(tcx, &impl_args)
+                .iter_instantiated(tcx, impl_args)
                 .map(|pred| goal.with(tcx, pred));
             ecx.add_goals(GoalSource::ImplWhereBound, where_clause_bounds);
 
@@ -186,7 +186,7 @@ where
         ecx.probe_builtin_trait_candidate(BuiltinImplSource::Misc).enter(|ecx| {
             let nested_obligations = tcx
                 .predicates_of(goal.predicate.def_id())
-                .iter_instantiated(tcx, &goal.predicate.trait_ref.args)
+                .iter_instantiated(tcx, goal.predicate.trait_ref.args)
                 .map(|p| goal.with(tcx, p));
             // FIXME(-Znext-solver=coinductive): Should this be `GoalSource::ImplWhereBound`?
             ecx.add_goals(GoalSource::Misc, nested_obligations);
@@ -373,7 +373,7 @@ where
         ecx: &mut EvalCtxt<'_, D>,
         goal: Goal<I, Self>,
     ) -> Result<Candidate<I>, NoSolution> {
-        let [closure_fn_kind_ty, goal_kind_ty] = **goal.predicate.trait_ref.args else {
+        let [closure_fn_kind_ty, goal_kind_ty] = *goal.predicate.trait_ref.args.as_slice() else {
             panic!();
         };
 
@@ -783,7 +783,7 @@ where
             // (i.e. the principal, all of the associated types match, and any auto traits)
             ecx.add_goals(
                 GoalSource::ImplWhereBound,
-                b_data.into_iter().map(|pred| goal.with(tcx, pred.with_self_ty(tcx, a_ty))),
+                b_data.iter().map(|pred| goal.with(tcx, pred.with_self_ty(tcx, a_ty))),
             );
 
             // The type must be `Sized` to be unsized.
@@ -851,7 +851,7 @@ where
             };
 
         self.probe_trait_candidate(source).enter(|ecx| {
-            for bound in b_data {
+            for bound in b_data.iter() {
                 match bound.skip_binder() {
                     // Check that a's supertrait (upcast_principal) is compatible
                     // with the target (b_ty).
@@ -953,18 +953,15 @@ where
 
         let tail_field_ty = def.struct_tail_ty(tcx).unwrap();
 
-        let a_tail_ty = tail_field_ty.instantiate(tcx, &a_args);
-        let b_tail_ty = tail_field_ty.instantiate(tcx, &b_args);
+        let a_tail_ty = tail_field_ty.instantiate(tcx, a_args);
+        let b_tail_ty = tail_field_ty.instantiate(tcx, b_args);
 
         // Instantiate just the unsizing params from B into A. The type after
         // this instantiation must be equal to B. This is so we don't unsize
         // unrelated type parameters.
-        let new_a_args = tcx.mk_args_from_iter(
-            a_args
-                .iter()
-                .enumerate()
-                .map(|(i, a)| if unsizing_params.contains(i as u32) { b_args[i] } else { *a }),
-        );
+        let new_a_args = tcx.mk_args_from_iter(a_args.iter().enumerate().map(|(i, a)| {
+            if unsizing_params.contains(i as u32) { b_args.get(i).unwrap() } else { a }
+        }));
         let unsized_a_ty = Ty::new_adt(tcx, def, new_a_args);
 
         // Finally, we require that `TailA: Unsize<TailB>` for the tail field
@@ -1005,7 +1002,7 @@ where
         let Goal { predicate: (_a_ty, b_ty), .. } = goal;
 
         let (&a_last_ty, a_rest_tys) = a_tys.split_last().unwrap();
-        let &b_last_ty = b_tys.last().unwrap();
+        let b_last_ty = b_tys.last().unwrap();
 
         // Instantiate just the tail field of B., and require that they're equal.
         let unsized_a_ty =
diff --git a/compiler/rustc_type_ir/src/binder.rs b/compiler/rustc_type_ir/src/binder.rs
index 18b34f8d99b..491ef34430c 100644
--- a/compiler/rustc_type_ir/src/binder.rs
+++ b/compiler/rustc_type_ir/src/binder.rs
@@ -320,7 +320,7 @@ impl<I: Interner> TypeVisitor<I> for ValidateBoundVars<I> {
                 if self.bound_vars.len() <= idx {
                     panic!("Not enough bound vars: {:?} not found in {:?}", t, self.bound_vars);
                 }
-                bound_ty.assert_eq(self.bound_vars[idx]);
+                bound_ty.assert_eq(self.bound_vars.get(idx).unwrap());
             }
             _ => {}
         };
@@ -335,7 +335,7 @@ impl<I: Interner> TypeVisitor<I> for ValidateBoundVars<I> {
                 if self.bound_vars.len() <= idx {
                     panic!("Not enough bound vars: {:?} not found in {:?}", r, self.bound_vars);
                 }
-                br.assert_eq(self.bound_vars[idx]);
+                br.assert_eq(self.bound_vars.get(idx).unwrap());
             }
 
             _ => (),
@@ -435,15 +435,14 @@ impl<I: Interner, T> EarlyBinder<I, Option<T>> {
     }
 }
 
-impl<'s, I: Interner, Iter: IntoIterator> EarlyBinder<I, Iter>
+impl<I: Interner, Iter: IntoIterator> EarlyBinder<I, Iter>
 where
     Iter::Item: TypeFoldable<I>,
 {
-    pub fn iter_instantiated(
-        self,
-        tcx: I,
-        args: &'s [I::GenericArg],
-    ) -> IterInstantiated<'s, I, Iter> {
+    pub fn iter_instantiated<A>(self, tcx: I, args: A) -> IterInstantiated<I, Iter, A>
+    where
+        A: SliceLike<Item = I::GenericArg>,
+    {
         IterInstantiated { it: self.value.into_iter(), tcx, args }
     }
 
@@ -454,15 +453,16 @@ where
     }
 }
 
-pub struct IterInstantiated<'s, I: Interner, Iter: IntoIterator> {
+pub struct IterInstantiated<I: Interner, Iter: IntoIterator, A> {
     it: Iter::IntoIter,
     tcx: I,
-    args: &'s [I::GenericArg],
+    args: A,
 }
 
-impl<I: Interner, Iter: IntoIterator> Iterator for IterInstantiated<'_, I, Iter>
+impl<I: Interner, Iter: IntoIterator, A> Iterator for IterInstantiated<I, Iter, A>
 where
     Iter::Item: TypeFoldable<I>,
+    A: SliceLike<Item = I::GenericArg>,
 {
     type Item = Iter::Item;
 
@@ -478,10 +478,11 @@ where
     }
 }
 
-impl<I: Interner, Iter: IntoIterator> DoubleEndedIterator for IterInstantiated<'_, I, Iter>
+impl<I: Interner, Iter: IntoIterator, A> DoubleEndedIterator for IterInstantiated<I, Iter, A>
 where
     Iter::IntoIter: DoubleEndedIterator,
     Iter::Item: TypeFoldable<I>,
+    A: SliceLike<Item = I::GenericArg>,
 {
     fn next_back(&mut self) -> Option<Self::Item> {
         Some(
@@ -491,10 +492,11 @@ where
     }
 }
 
-impl<I: Interner, Iter: IntoIterator> ExactSizeIterator for IterInstantiated<'_, I, Iter>
+impl<I: Interner, Iter: IntoIterator, A> ExactSizeIterator for IterInstantiated<I, Iter, A>
 where
     Iter::IntoIter: ExactSizeIterator,
     Iter::Item: TypeFoldable<I>,
+    A: SliceLike<Item = I::GenericArg>,
 {
 }
 
@@ -589,8 +591,11 @@ impl<I: Interner, T: Iterator> Iterator for EarlyBinderIter<I, T> {
 }
 
 impl<I: Interner, T: TypeFoldable<I>> ty::EarlyBinder<I, T> {
-    pub fn instantiate(self, tcx: I, args: &[I::GenericArg]) -> T {
-        let mut folder = ArgFolder { tcx, args, binders_passed: 0 };
+    pub fn instantiate<A>(self, tcx: I, args: A) -> T
+    where
+        A: SliceLike<Item = I::GenericArg>,
+    {
+        let mut folder = ArgFolder { tcx, args: args.as_slice(), binders_passed: 0 };
         self.value.fold_with(&mut folder)
     }
 
diff --git a/compiler/rustc_type_ir/src/canonical.rs b/compiler/rustc_type_ir/src/canonical.rs
index 61ae36265ec..7b114f565f2 100644
--- a/compiler/rustc_type_ir/src/canonical.rs
+++ b/compiler/rustc_type_ir/src/canonical.rs
@@ -283,7 +283,7 @@ pub struct CanonicalVarValues<I: Interner> {
 
 impl<I: Interner> CanonicalVarValues<I> {
     pub fn is_identity(&self) -> bool {
-        self.var_values.into_iter().enumerate().all(|(bv, arg)| match arg.kind() {
+        self.var_values.iter().enumerate().all(|(bv, arg)| match arg.kind() {
             ty::GenericArgKind::Lifetime(r) => {
                 matches!(r.kind(), ty::ReBound(ty::INNERMOST, br) if br.var().as_usize() == bv)
             }
@@ -298,7 +298,7 @@ impl<I: Interner> CanonicalVarValues<I> {
 
     pub fn is_identity_modulo_regions(&self) -> bool {
         let mut var = ty::BoundVar::ZERO;
-        for arg in self.var_values {
+        for arg in self.var_values.iter() {
             match arg.kind() {
                 ty::GenericArgKind::Lifetime(r) => {
                     if matches!(r.kind(), ty::ReBound(ty::INNERMOST, br) if var == br.var()) {
@@ -332,7 +332,7 @@ impl<I: Interner> CanonicalVarValues<I> {
     // the identity response.
     pub fn make_identity(tcx: I, infos: I::CanonicalVars) -> CanonicalVarValues<I> {
         CanonicalVarValues {
-            var_values: tcx.mk_args_from_iter(infos.into_iter().enumerate().map(
+            var_values: tcx.mk_args_from_iter(infos.iter().enumerate().map(
                 |(i, info)| -> I::GenericArg {
                     match info.kind {
                         CanonicalVarKind::Ty(_) | CanonicalVarKind::PlaceholderTy(_) => {
@@ -371,10 +371,10 @@ impl<I: Interner> CanonicalVarValues<I> {
 
 impl<'a, I: Interner> IntoIterator for &'a CanonicalVarValues<I> {
     type Item = I::GenericArg;
-    type IntoIter = <I::GenericArgs as IntoIterator>::IntoIter;
+    type IntoIter = <I::GenericArgs as SliceLike>::IntoIter;
 
     fn into_iter(self) -> Self::IntoIter {
-        self.var_values.into_iter()
+        self.var_values.iter()
     }
 }
 
@@ -382,6 +382,6 @@ impl<I: Interner> Index<ty::BoundVar> for CanonicalVarValues<I> {
     type Output = I::GenericArg;
 
     fn index(&self, value: ty::BoundVar) -> &I::GenericArg {
-        &self.var_values[value.as_usize()]
+        &self.var_values.as_slice()[value.as_usize()]
     }
 }
diff --git a/compiler/rustc_type_ir/src/inherent.rs b/compiler/rustc_type_ir/src/inherent.rs
index 93ca7ab9280..a4e1a97d505 100644
--- a/compiler/rustc_type_ir/src/inherent.rs
+++ b/compiler/rustc_type_ir/src/inherent.rs
@@ -5,7 +5,6 @@
 
 use std::fmt::Debug;
 use std::hash::Hash;
-use std::ops::Deref;
 
 use rustc_ast_ir::Mutability;
 
@@ -128,7 +127,7 @@ pub trait Ty<I: Interner<Ty = Self>>:
     fn fn_sig(self, interner: I) -> ty::Binder<I, ty::FnSig<I>> {
         match self.kind() {
             ty::FnPtr(sig) => sig,
-            ty::FnDef(def_id, args) => interner.fn_sig(def_id).instantiate(interner, &args),
+            ty::FnDef(def_id, args) => interner.fn_sig(def_id).instantiate(interner, args),
             ty::Error(_) => {
                 // ignore errors (#54954)
                 ty::Binder::dummy(ty::FnSig {
@@ -190,14 +189,7 @@ pub trait Ty<I: Interner<Ty = Self>>:
 }
 
 pub trait Tys<I: Interner<Tys = Self>>:
-    Copy
-    + Debug
-    + Hash
-    + Eq
-    + IntoIterator<Item = I::Ty>
-    + Deref<Target: Deref<Target = [I::Ty]>>
-    + TypeFoldable<I>
-    + Default
+    Copy + Debug + Hash + Eq + SliceLike<Item = I::Ty> + TypeFoldable<I> + Default
 {
     fn split_inputs_and_output(self) -> (I::FnInputTys, I::Ty);
 }
@@ -362,14 +354,7 @@ pub trait Term<I: Interner<Term = Self>>:
 }
 
 pub trait GenericArgs<I: Interner<GenericArgs = Self>>:
-    Copy
-    + Debug
-    + Hash
-    + Eq
-    + IntoIterator<Item = I::GenericArg>
-    + Deref<Target: Deref<Target = [I::GenericArg]>>
-    + Default
-    + Relate<I>
+    Copy + Debug + Hash + Eq + SliceLike<Item = I::GenericArg> + Default + Relate<I>
 {
     fn rebase_onto(
         self,
@@ -561,12 +546,7 @@ pub trait DefId<I: Interner>: Copy + Debug + Hash + Eq + TypeFoldable<I> {
 }
 
 pub trait BoundExistentialPredicates<I: Interner>:
-    Copy
-    + Debug
-    + Hash
-    + Eq
-    + Relate<I>
-    + IntoIterator<Item = ty::Binder<I, ty::ExistentialPredicate<I>>>
+    Copy + Debug + Hash + Eq + Relate<I> + SliceLike<Item = ty::Binder<I, ty::ExistentialPredicate<I>>>
 {
     fn principal_def_id(self) -> Option<I::DefId>;
 
@@ -578,3 +558,82 @@ pub trait BoundExistentialPredicates<I: Interner>:
         self,
     ) -> impl IntoIterator<Item = ty::Binder<I, ty::ExistentialProjection<I>>>;
 }
+
+pub trait SliceLike: Sized + Copy {
+    type Item: Copy;
+    type IntoIter: Iterator<Item = Self::Item>;
+
+    fn iter(self) -> Self::IntoIter;
+
+    fn as_slice(&self) -> &[Self::Item];
+
+    fn get(self, idx: usize) -> Option<Self::Item> {
+        self.as_slice().get(idx).copied()
+    }
+
+    fn len(self) -> usize {
+        self.as_slice().len()
+    }
+
+    fn is_empty(self) -> bool {
+        self.len() == 0
+    }
+
+    fn contains(self, t: &Self::Item) -> bool
+    where
+        Self::Item: PartialEq,
+    {
+        self.as_slice().contains(t)
+    }
+
+    fn to_vec(self) -> Vec<Self::Item> {
+        self.as_slice().to_vec()
+    }
+
+    fn last(self) -> Option<Self::Item> {
+        self.as_slice().last().copied()
+    }
+
+    fn split_last(&self) -> Option<(&Self::Item, &[Self::Item])> {
+        self.as_slice().split_last()
+    }
+}
+
+impl<'a, T: Copy> SliceLike for &'a [T] {
+    type Item = T;
+    type IntoIter = std::iter::Copied<std::slice::Iter<'a, T>>;
+
+    fn iter(self) -> Self::IntoIter {
+        self.iter().copied()
+    }
+
+    fn as_slice(&self) -> &[Self::Item] {
+        *self
+    }
+}
+
+impl<'a, T: Copy, const N: usize> SliceLike for &'a [T; N] {
+    type Item = T;
+    type IntoIter = std::iter::Copied<std::slice::Iter<'a, T>>;
+
+    fn iter(self) -> Self::IntoIter {
+        self.into_iter().copied()
+    }
+
+    fn as_slice(&self) -> &[Self::Item] {
+        *self
+    }
+}
+
+impl<'a, S: SliceLike> SliceLike for &'a S {
+    type Item = S::Item;
+    type IntoIter = S::IntoIter;
+
+    fn iter(self) -> Self::IntoIter {
+        (*self).iter()
+    }
+
+    fn as_slice(&self) -> &[Self::Item] {
+        (*self).as_slice()
+    }
+}
diff --git a/compiler/rustc_type_ir/src/interner.rs b/compiler/rustc_type_ir/src/interner.rs
index 69693043fa7..3640a8dea54 100644
--- a/compiler/rustc_type_ir/src/interner.rs
+++ b/compiler/rustc_type_ir/src/interner.rs
@@ -34,16 +34,11 @@ pub trait Interner:
     type LocalDefId: Copy + Debug + Hash + Eq + Into<Self::DefId> + TypeFoldable<Self>;
 
     type GenericArgs: GenericArgs<Self>;
-    type GenericArgsSlice: Copy + Debug + Hash + Eq + Deref<Target = [Self::GenericArg]>;
+    type GenericArgsSlice: Copy + Debug + Hash + Eq + SliceLike<Item = Self::GenericArg>;
     type GenericArg: GenericArg<Self>;
     type Term: Term<Self>;
 
-    type BoundVarKinds: Copy
-        + Debug
-        + Hash
-        + Eq
-        + Deref<Target: Deref<Target = [Self::BoundVarKind]>>
-        + Default;
+    type BoundVarKinds: Copy + Debug + Hash + Eq + SliceLike<Item = Self::BoundVarKind> + Default;
     type BoundVarKind: Copy + Debug + Hash + Eq;
 
     type PredefinedOpaques: Copy
@@ -63,7 +58,7 @@ pub trait Interner:
         + Default
         + Eq
         + TypeVisitable<Self>
-        + Deref<Target: Deref<Target = [Self::LocalDefId]>>;
+        + SliceLike<Item = Self::LocalDefId>;
     type CanonicalGoalEvaluationStepRef: Copy
         + Debug
         + Hash
@@ -74,8 +69,7 @@ pub trait Interner:
         + Debug
         + Hash
         + Eq
-        + IntoIterator<Item = ty::CanonicalVarInfo<Self>>
-        + Deref<Target: Deref<Target = [ty::CanonicalVarInfo<Self>]>>
+        + SliceLike<Item = ty::CanonicalVarInfo<Self>>
         + Default;
     fn mk_canonical_var_infos(self, infos: &[ty::CanonicalVarInfo<Self>]) -> Self::CanonicalVars;
 
@@ -138,11 +132,7 @@ pub trait Interner:
     type GenericsOf: GenericsOf<Self>;
     fn generics_of(self, def_id: Self::DefId) -> Self::GenericsOf;
 
-    type VariancesOf: Copy
-        + Debug
-        + Deref<Target = [ty::Variance]>
-        // FIXME: This is terrible!
-        + IntoIterator<Item: Deref<Target = ty::Variance>>;
+    type VariancesOf: Copy + Debug + SliceLike<Item = ty::Variance>;
     fn variances_of(self, def_id: Self::DefId) -> Self::VariancesOf;
 
     fn type_of(self, def_id: Self::DefId) -> ty::EarlyBinder<Self, Self::Ty>;
diff --git a/compiler/rustc_type_ir/src/opaque_ty.rs b/compiler/rustc_type_ir/src/opaque_ty.rs
index 738350f1b34..d8ed4770e2d 100644
--- a/compiler/rustc_type_ir/src/opaque_ty.rs
+++ b/compiler/rustc_type_ir/src/opaque_ty.rs
@@ -24,13 +24,13 @@ pub struct OpaqueTypeKey<I: Interner> {
 impl<I: Interner> OpaqueTypeKey<I> {
     pub fn iter_captured_args(self, tcx: I) -> impl Iterator<Item = (usize, I::GenericArg)> {
         let variances = tcx.variances_of(self.def_id.into());
-        std::iter::zip(self.args, variances.into_iter()).enumerate().filter_map(|(i, (arg, v))| {
-            match (arg.kind(), *v) {
+        std::iter::zip(self.args.iter(), variances.iter()).enumerate().filter_map(
+            |(i, (arg, v))| match (arg.kind(), v) {
                 (_, ty::Invariant) => Some((i, arg)),
                 (ty::GenericArgKind::Lifetime(_), ty::Bivariant) => None,
                 _ => panic!("unexpected opaque type arg variance"),
-            }
-        })
+            },
+        )
     }
 
     pub fn fold_captured_lifetime_args(
@@ -41,7 +41,7 @@ impl<I: Interner> OpaqueTypeKey<I> {
         let Self { def_id, args } = self;
         let variances = tcx.variances_of(def_id.into());
         let args =
-            std::iter::zip(args, variances.into_iter()).map(|(arg, v)| match (arg.kind(), *v) {
+            std::iter::zip(args.iter(), variances.iter()).map(|(arg, v)| match (arg.kind(), v) {
                 (ty::GenericArgKind::Lifetime(_), ty::Bivariant) => arg,
                 (ty::GenericArgKind::Lifetime(lt), _) => f(lt).into(),
                 _ => arg,
diff --git a/compiler/rustc_type_ir/src/predicate.rs b/compiler/rustc_type_ir/src/predicate.rs
index 392b758eea1..e5bcbc67f94 100644
--- a/compiler/rustc_type_ir/src/predicate.rs
+++ b/compiler/rustc_type_ir/src/predicate.rs
@@ -85,7 +85,7 @@ impl<I: Interner> TraitRef<I> {
 
     pub fn from_method(interner: I, trait_id: I::DefId, args: I::GenericArgs) -> TraitRef<I> {
         let generics = interner.generics_of(trait_id);
-        TraitRef::new(interner, trait_id, args.into_iter().take(generics.count()))
+        TraitRef::new(interner, trait_id, args.iter().take(generics.count()))
     }
 
     /// Returns a `TraitRef` of the form `P0: Foo<P1..Pn>` where `Pi`
@@ -102,7 +102,7 @@ impl<I: Interner> TraitRef<I> {
         TraitRef::new(
             interner,
             self.def_id,
-            [self_ty.into()].into_iter().chain(self.args.into_iter().skip(1)),
+            [self_ty.into()].into_iter().chain(self.args.iter().skip(1)),
         )
     }
 
@@ -320,7 +320,7 @@ impl<I: Interner> ExistentialTraitRef<I> {
 
         ExistentialTraitRef {
             def_id: trait_ref.def_id,
-            args: interner.mk_args(&trait_ref.args[1..]),
+            args: interner.mk_args(&trait_ref.args.as_slice()[1..]),
         }
     }
 
@@ -332,11 +332,7 @@ impl<I: Interner> ExistentialTraitRef<I> {
         // otherwise the escaping vars would be captured by the binder
         // debug_assert!(!self_ty.has_escaping_bound_vars());
 
-        TraitRef::new(
-            interner,
-            self.def_id,
-            [self_ty.into()].into_iter().chain(self.args.into_iter()),
-        )
+        TraitRef::new(interner, self.def_id, [self_ty.into()].into_iter().chain(self.args.iter()))
     }
 }
 
@@ -379,7 +375,7 @@ impl<I: Interner> ExistentialProjection<I> {
     pub fn trait_ref(&self, interner: I) -> ExistentialTraitRef<I> {
         let def_id = interner.parent(self.def_id);
         let args_count = interner.generics_of(def_id).count() - 1;
-        let args = interner.mk_args(&self.args[..args_count]);
+        let args = interner.mk_args(&self.args.as_slice()[..args_count]);
         ExistentialTraitRef { def_id, args }
     }
 
@@ -391,7 +387,7 @@ impl<I: Interner> ExistentialProjection<I> {
             projection_term: AliasTerm::new(
                 interner,
                 self.def_id,
-                [self_ty.into()].into_iter().chain(self.args),
+                [self_ty.into()].iter().chain(self.args.iter()),
             ),
             term: self.term,
         }
@@ -403,7 +399,7 @@ impl<I: Interner> ExistentialProjection<I> {
 
         Self {
             def_id: projection_predicate.projection_term.def_id,
-            args: interner.mk_args(&projection_predicate.projection_term.args[1..]),
+            args: interner.mk_args(&projection_predicate.projection_term.args.as_slice()[1..]),
             term: projection_predicate.term,
         }
     }
@@ -578,7 +574,7 @@ impl<I: Interner> AliasTerm<I> {
         AliasTerm::new(
             interner,
             self.def_id,
-            [self_ty.into()].into_iter().chain(self.args.into_iter().skip(1)),
+            [self_ty.into()].into_iter().chain(self.args.iter().skip(1)),
         )
     }
 
diff --git a/compiler/rustc_type_ir/src/relate.rs b/compiler/rustc_type_ir/src/relate.rs
index 350d8093b86..c803d7e1794 100644
--- a/compiler/rustc_type_ir/src/relate.rs
+++ b/compiler/rustc_type_ir/src/relate.rs
@@ -82,7 +82,7 @@ pub trait TypeRelation<I: Interner>: Sized {
 
         let tcx = self.tcx();
         let opt_variances = tcx.variances_of(item_def_id);
-        relate_args_with_variances(self, item_def_id, &opt_variances, a_arg, b_arg, true)
+        relate_args_with_variances(self, item_def_id, opt_variances, a_arg, b_arg, true)
     }
 
     /// Switch variance for the purpose of relating `a` and `b`.
@@ -128,7 +128,7 @@ pub fn relate_args_invariantly<I: Interner, R: TypeRelation<I>>(
     a_arg: I::GenericArgs,
     b_arg: I::GenericArgs,
 ) -> RelateResult<I, I::GenericArgs> {
-    relation.tcx().mk_args_from_iter(iter::zip(a_arg, b_arg).map(|(a, b)| {
+    relation.tcx().mk_args_from_iter(iter::zip(a_arg.iter(), b_arg.iter()).map(|(a, b)| {
         relation.relate_with_variance(ty::Invariant, VarianceDiagInfo::default(), a, b)
     }))
 }
@@ -136,7 +136,7 @@ pub fn relate_args_invariantly<I: Interner, R: TypeRelation<I>>(
 pub fn relate_args_with_variances<I: Interner, R: TypeRelation<I>>(
     relation: &mut R,
     ty_def_id: I::DefId,
-    variances: &[ty::Variance],
+    variances: I::VariancesOf,
     a_arg: I::GenericArgs,
     b_arg: I::GenericArgs,
     fetch_ty_for_diag: bool,
@@ -144,11 +144,11 @@ pub fn relate_args_with_variances<I: Interner, R: TypeRelation<I>>(
     let tcx = relation.tcx();
 
     let mut cached_ty = None;
-    let params = iter::zip(a_arg, b_arg).enumerate().map(|(i, (a, b))| {
-        let variance = variances[i];
+    let params = iter::zip(a_arg.iter(), b_arg.iter()).enumerate().map(|(i, (a, b))| {
+        let variance = variances.get(i).unwrap();
         let variance_info = if variance == ty::Invariant && fetch_ty_for_diag {
             let ty =
-                *cached_ty.get_or_insert_with(|| tcx.type_of(ty_def_id).instantiate(tcx, &a_arg));
+                *cached_ty.get_or_insert_with(|| tcx.type_of(ty_def_id).instantiate(tcx, a_arg));
             VarianceDiagInfo::Invariant { ty, param_index: i.try_into().unwrap() }
         } else {
             VarianceDiagInfo::default()
@@ -249,7 +249,7 @@ impl<I: Interner> Relate<I> for ty::AliasTy<I> {
                 ty::Opaque => relate_args_with_variances(
                     relation,
                     a.def_id,
-                    &relation.tcx().variances_of(a.def_id),
+                    relation.tcx().variances_of(a.def_id),
                     a.args,
                     b.args,
                     false, // do not fetch `type_of(a_def_id)`, as it will cause a cycle
@@ -280,7 +280,7 @@ impl<I: Interner> Relate<I> for ty::AliasTerm<I> {
                 ty::AliasTermKind::OpaqueTy => relate_args_with_variances(
                     relation,
                     a.def_id,
-                    &relation.tcx().variances_of(a.def_id),
+                    relation.tcx().variances_of(a.def_id),
                     a.args,
                     b.args,
                     false, // do not fetch `type_of(a_def_id)`, as it will cause a cycle
@@ -525,7 +525,7 @@ pub fn structurally_relate_tys<I: Interner, R: TypeRelation<I>>(
             if as_.len() == bs.len() {
                 Ok(Ty::new_tup_from_iter(
                     tcx,
-                    iter::zip(as_, bs).map(|(a, b)| relation.relate(a, b)),
+                    iter::zip(as_.iter(), bs.iter()).map(|(a, b)| relation.relate(a, b)),
                 )?)
             } else if !(as_.is_empty() || bs.is_empty()) {
                 Err(TypeError::TupleSize(ExpectedFound::new(true, as_.len(), bs.len())))
@@ -607,8 +607,8 @@ pub fn structurally_relate_consts<I: Interner, R: TypeRelation<I>>(
         // be stabilized.
         (ty::ConstKind::Unevaluated(au), ty::ConstKind::Unevaluated(bu)) if au.def == bu.def => {
             if cfg!(debug_assertions) {
-                let a_ty = tcx.type_of(au.def).instantiate(tcx, &au.args);
-                let b_ty = tcx.type_of(bu.def).instantiate(tcx, &bu.args);
+                let a_ty = tcx.type_of(au.def).instantiate(tcx, au.args);
+                let b_ty = tcx.type_of(bu.def).instantiate(tcx, bu.args);
                 assert_eq!(a_ty, b_ty);
             }
 
diff --git a/compiler/rustc_type_ir/src/ty_kind.rs b/compiler/rustc_type_ir/src/ty_kind.rs
index 1c29fafc3cc..4782b8558d7 100644
--- a/compiler/rustc_type_ir/src/ty_kind.rs
+++ b/compiler/rustc_type_ir/src/ty_kind.rs
@@ -388,7 +388,7 @@ impl<I: Interner> fmt::Debug for TyKind<I> {
             Tuple(t) => {
                 write!(f, "(")?;
                 let mut count = 0;
-                for ty in *t {
+                for ty in t.iter() {
                     if count > 0 {
                         write!(f, ", ")?;
                     }
@@ -496,7 +496,7 @@ impl<I: Interner> AliasTy<I> {
         AliasTy::new(
             interner,
             self.def_id,
-            [self_ty.into()].into_iter().chain(self.args.into_iter().skip(1)),
+            [self_ty.into()].into_iter().chain(self.args.iter().skip(1)),
         )
     }
 
@@ -544,7 +544,7 @@ impl<I: Interner> AliasTy<I> {
         interner: I,
     ) -> I::GenericArgs {
         debug_assert_eq!(self.kind(interner), AliasTyKind::Inherent);
-        interner.mk_args_from_iter(impl_args.into_iter().chain(self.args.into_iter().skip(1)))
+        interner.mk_args_from_iter(impl_args.iter().chain(self.args.iter().skip(1)))
     }
 }
 
diff --git a/compiler/rustc_type_ir/src/ty_kind/closure.rs b/compiler/rustc_type_ir/src/ty_kind/closure.rs
index 3a17a27bd03..04aadfdabb4 100644
--- a/compiler/rustc_type_ir/src/ty_kind/closure.rs
+++ b/compiler/rustc_type_ir/src/ty_kind/closure.rs
@@ -138,7 +138,7 @@ impl<I: Interner> ClosureArgs<I> {
     /// for the closure parent, alongside additional closure-specific components.
     pub fn new(tcx: I, parts: ClosureArgsParts<I>) -> ClosureArgs<I> {
         ClosureArgs {
-            args: tcx.mk_args_from_iter(parts.parent_args.iter().copied().chain([
+            args: tcx.mk_args_from_iter(parts.parent_args.iter().chain([
                 parts.closure_kind_ty.into(),
                 parts.closure_sig_as_fn_ptr_ty.into(),
                 parts.tupled_upvars_ty.into(),
@@ -260,7 +260,7 @@ pub struct CoroutineClosureArgsParts<I: Interner> {
 impl<I: Interner> CoroutineClosureArgs<I> {
     pub fn new(tcx: I, parts: CoroutineClosureArgsParts<I>) -> CoroutineClosureArgs<I> {
         CoroutineClosureArgs {
-            args: tcx.mk_args_from_iter(parts.parent_args.iter().copied().chain([
+            args: tcx.mk_args_from_iter(parts.parent_args.iter().chain([
                 parts.closure_kind_ty.into(),
                 parts.signature_parts_ty.into(),
                 parts.tupled_upvars_ty.into(),
@@ -312,7 +312,7 @@ impl<I: Interner> CoroutineClosureArgs<I> {
             let [resume_ty, tupled_inputs_ty] = *sig.inputs() else {
                 panic!();
             };
-            let [yield_ty, return_ty] = **sig.output().tuple_fields() else { panic!() };
+            let [yield_ty, return_ty] = *sig.output().tuple_fields().as_slice() else { panic!() };
             CoroutineClosureSignature {
                 interior,
                 tupled_inputs_ty,
@@ -496,16 +496,16 @@ impl<I: Interner> CoroutineClosureSignature<I> {
                     tcx,
                     tupled_inputs_ty
                         .tuple_fields()
-                        .into_iter()
-                        .chain(coroutine_captures_by_ref_ty.tuple_fields()),
+                        .iter()
+                        .chain(coroutine_captures_by_ref_ty.tuple_fields().iter()),
                 )
             }
             ty::ClosureKind::FnOnce => Ty::new_tup_from_iter(
                 tcx,
                 tupled_inputs_ty
                     .tuple_fields()
-                    .into_iter()
-                    .chain(closure_tupled_upvars_ty.tuple_fields()),
+                    .iter()
+                    .chain(closure_tupled_upvars_ty.tuple_fields().iter()),
             ),
         }
     }
@@ -617,7 +617,7 @@ impl<I: Interner> CoroutineArgs<I> {
     /// for the coroutine parent, alongside additional coroutine-specific components.
     pub fn new(tcx: I, parts: CoroutineArgsParts<I>) -> CoroutineArgs<I> {
         CoroutineArgs {
-            args: tcx.mk_args_from_iter(parts.parent_args.iter().copied().chain([
+            args: tcx.mk_args_from_iter(parts.parent_args.iter().chain([
                 parts.kind_ty.into(),
                 parts.resume_ty.into(),
                 parts.yield_ty.into(),
diff --git a/src/tools/clippy/clippy_lints/src/needless_borrows_for_generic_args.rs b/src/tools/clippy/clippy_lints/src/needless_borrows_for_generic_args.rs
index 4f99eaa40c2..f4846a1753f 100644
--- a/src/tools/clippy/clippy_lints/src/needless_borrows_for_generic_args.rs
+++ b/src/tools/clippy/clippy_lints/src/needless_borrows_for_generic_args.rs
@@ -267,7 +267,7 @@ fn needless_borrow_count<'tcx>(
                 return false;
             }
 
-            let predicate = EarlyBinder::bind(predicate).instantiate(cx.tcx, &args_with_referent_ty);
+            let predicate = EarlyBinder::bind(predicate).instantiate(cx.tcx, &args_with_referent_ty[..]);
             let obligation = Obligation::new(cx.tcx, ObligationCause::dummy(), cx.param_env, predicate);
             let infcx = cx.tcx.infer_ctxt().build();
             infcx.predicate_must_hold_modulo_regions(&obligation)