From 24e41f1d134fdd969308894baddced76ad79712d Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Fri, 21 Jun 2024 13:55:21 -0400 Subject: [PATCH] Replace Deref bounds on Interner in favor of a SliceLike trait --- compiler/rustc_middle/src/ty/list.rs | 14 +++ .../src/solve/assembly/mod.rs | 4 +- .../src/solve/assembly/structural_traits.rs | 33 +++--- .../src/solve/eval_ctxt/canonical.rs | 11 +- .../src/solve/eval_ctxt/mod.rs | 4 +- .../src/solve/inspect/build.rs | 1 + .../rustc_next_trait_solver/src/solve/mod.rs | 2 +- .../src/solve/normalizes_to/inherent.rs | 6 +- .../src/solve/normalizes_to/mod.rs | 20 ++-- .../src/solve/normalizes_to/opaque_types.rs | 4 +- .../src/solve/normalizes_to/weak_types.rs | 4 +- .../src/solve/trait_goals.rs | 27 ++--- compiler/rustc_type_ir/src/binder.rs | 35 +++--- compiler/rustc_type_ir/src/canonical.rs | 12 +- compiler/rustc_type_ir/src/inherent.rs | 107 ++++++++++++++---- compiler/rustc_type_ir/src/interner.rs | 20 +--- compiler/rustc_type_ir/src/opaque_ty.rs | 10 +- compiler/rustc_type_ir/src/predicate.rs | 20 ++-- compiler/rustc_type_ir/src/relate.rs | 22 ++-- compiler/rustc_type_ir/src/ty_kind.rs | 6 +- compiler/rustc_type_ir/src/ty_kind/closure.rs | 16 +-- .../src/needless_borrows_for_generic_args.rs | 2 +- 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 71a93cc520d5..73eba93194e1 100644 --- a/compiler/rustc_middle/src/ty/list.rs +++ b/compiler/rustc_middle/src/ty/list.rs @@ -133,6 +133,20 @@ impl RawList { } } +impl<'a, H, T: Copy> rustc_type_ir::inherent::SliceLike for &'a RawList { + 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 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 cae9c5c85678..ee7279a43b2c 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 b10be5a9ba70..d4890e48032f 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`, 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 where sized_constraint(Adt): 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 { 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 687623d44084..04dce2780b07 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 ae59f0c5e957..4fc58e06d67d 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 b76b4c098523..e29ae7ac0a26 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 827fe5f2ca40..004ecf2d2c4f 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 f58384d86cd6..bc5233c4887f 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 f3494328d9e4..a16f9e64f2f7 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( args: I::GenericArgs, ) -> Result<(), NotUniqueParam> { 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 27d5ae07729a..ca90bc17cc7d 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 2ddb3c981db9..9746c836aff5 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, ) -> Result, 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` 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 18b34f8d99b9..491ef34430c1 100644 --- a/compiler/rustc_type_ir/src/binder.rs +++ b/compiler/rustc_type_ir/src/binder.rs @@ -320,7 +320,7 @@ impl TypeVisitor for ValidateBoundVars { 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 TypeVisitor for ValidateBoundVars { 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 EarlyBinder> { } } -impl<'s, I: Interner, Iter: IntoIterator> EarlyBinder +impl EarlyBinder where Iter::Item: TypeFoldable, { - pub fn iter_instantiated( - self, - tcx: I, - args: &'s [I::GenericArg], - ) -> IterInstantiated<'s, I, Iter> { + pub fn iter_instantiated(self, tcx: I, args: A) -> IterInstantiated + where + A: SliceLike, + { IterInstantiated { it: self.value.into_iter(), tcx, args } } @@ -454,15 +453,16 @@ where } } -pub struct IterInstantiated<'s, I: Interner, Iter: IntoIterator> { +pub struct IterInstantiated { it: Iter::IntoIter, tcx: I, - args: &'s [I::GenericArg], + args: A, } -impl Iterator for IterInstantiated<'_, I, Iter> +impl Iterator for IterInstantiated where Iter::Item: TypeFoldable, + A: SliceLike, { type Item = Iter::Item; @@ -478,10 +478,11 @@ where } } -impl DoubleEndedIterator for IterInstantiated<'_, I, Iter> +impl DoubleEndedIterator for IterInstantiated where Iter::IntoIter: DoubleEndedIterator, Iter::Item: TypeFoldable, + A: SliceLike, { fn next_back(&mut self) -> Option { Some( @@ -491,10 +492,11 @@ where } } -impl ExactSizeIterator for IterInstantiated<'_, I, Iter> +impl ExactSizeIterator for IterInstantiated where Iter::IntoIter: ExactSizeIterator, Iter::Item: TypeFoldable, + A: SliceLike, { } @@ -589,8 +591,11 @@ impl Iterator for EarlyBinderIter { } impl> ty::EarlyBinder { - pub fn instantiate(self, tcx: I, args: &[I::GenericArg]) -> T { - let mut folder = ArgFolder { tcx, args, binders_passed: 0 }; + pub fn instantiate(self, tcx: I, args: A) -> T + where + A: SliceLike, + { + 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 61ae36265ec7..7b114f565f29 100644 --- a/compiler/rustc_type_ir/src/canonical.rs +++ b/compiler/rustc_type_ir/src/canonical.rs @@ -283,7 +283,7 @@ pub struct CanonicalVarValues { impl CanonicalVarValues { 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 CanonicalVarValues { 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 CanonicalVarValues { // the identity response. pub fn make_identity(tcx: I, infos: I::CanonicalVars) -> CanonicalVarValues { 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 CanonicalVarValues { impl<'a, I: Interner> IntoIterator for &'a CanonicalVarValues { type Item = I::GenericArg; - type IntoIter = ::IntoIter; + type IntoIter = ::IntoIter; fn into_iter(self) -> Self::IntoIter { - self.var_values.into_iter() + self.var_values.iter() } } @@ -382,6 +382,6 @@ impl Index for CanonicalVarValues { 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 93ca7ab9280b..a4e1a97d5058 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>: fn fn_sig(self, interner: I) -> ty::Binder> { 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>: } pub trait Tys>: - Copy - + Debug - + Hash - + Eq - + IntoIterator - + Deref> - + TypeFoldable - + Default + Copy + Debug + Hash + Eq + SliceLike + TypeFoldable + Default { fn split_inputs_and_output(self) -> (I::FnInputTys, I::Ty); } @@ -362,14 +354,7 @@ pub trait Term>: } pub trait GenericArgs>: - Copy - + Debug - + Hash - + Eq - + IntoIterator - + Deref> - + Default - + Relate + Copy + Debug + Hash + Eq + SliceLike + Default + Relate { fn rebase_onto( self, @@ -561,12 +546,7 @@ pub trait DefId: Copy + Debug + Hash + Eq + TypeFoldable { } pub trait BoundExistentialPredicates: - Copy - + Debug - + Hash - + Eq - + Relate - + IntoIterator>> + Copy + Debug + Hash + Eq + Relate + SliceLike>> { fn principal_def_id(self) -> Option; @@ -578,3 +558,82 @@ pub trait BoundExistentialPredicates: self, ) -> impl IntoIterator>>; } + +pub trait SliceLike: Sized + Copy { + type Item: Copy; + type IntoIter: Iterator; + + fn iter(self) -> Self::IntoIter; + + fn as_slice(&self) -> &[Self::Item]; + + fn get(self, idx: usize) -> Option { + 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.as_slice().to_vec() + } + + fn last(self) -> Option { + 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>; + + 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>; + + 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 69693043fa73..3640a8dea544 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 + TypeFoldable; type GenericArgs: GenericArgs; - type GenericArgsSlice: Copy + Debug + Hash + Eq + Deref; + type GenericArgsSlice: Copy + Debug + Hash + Eq + SliceLike; type GenericArg: GenericArg; type Term: Term; - type BoundVarKinds: Copy - + Debug - + Hash - + Eq - + Deref> - + Default; + type BoundVarKinds: Copy + Debug + Hash + Eq + SliceLike + Default; type BoundVarKind: Copy + Debug + Hash + Eq; type PredefinedOpaques: Copy @@ -63,7 +58,7 @@ pub trait Interner: + Default + Eq + TypeVisitable - + Deref>; + + SliceLike; type CanonicalGoalEvaluationStepRef: Copy + Debug + Hash @@ -74,8 +69,7 @@ pub trait Interner: + Debug + Hash + Eq - + IntoIterator> - + Deref]>> + + SliceLike> + Default; fn mk_canonical_var_infos(self, infos: &[ty::CanonicalVarInfo]) -> Self::CanonicalVars; @@ -138,11 +132,7 @@ pub trait Interner: type GenericsOf: GenericsOf; fn generics_of(self, def_id: Self::DefId) -> Self::GenericsOf; - type VariancesOf: Copy - + Debug - + Deref - // FIXME: This is terrible! - + IntoIterator>; + type VariancesOf: Copy + Debug + SliceLike; fn variances_of(self, def_id: Self::DefId) -> Self::VariancesOf; fn type_of(self, def_id: Self::DefId) -> ty::EarlyBinder; diff --git a/compiler/rustc_type_ir/src/opaque_ty.rs b/compiler/rustc_type_ir/src/opaque_ty.rs index 738350f1b34f..d8ed4770e2dc 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 { impl OpaqueTypeKey { pub fn iter_captured_args(self, tcx: I) -> impl Iterator { 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 OpaqueTypeKey { 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 392b758eea16..e5bcbc67f946 100644 --- a/compiler/rustc_type_ir/src/predicate.rs +++ b/compiler/rustc_type_ir/src/predicate.rs @@ -85,7 +85,7 @@ impl TraitRef { pub fn from_method(interner: I, trait_id: I::DefId, args: I::GenericArgs) -> TraitRef { 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` where `Pi` @@ -102,7 +102,7 @@ impl TraitRef { 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 ExistentialTraitRef { 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 ExistentialTraitRef { // 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 ExistentialProjection { pub fn trait_ref(&self, interner: I) -> ExistentialTraitRef { 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 ExistentialProjection { 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 ExistentialProjection { 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 AliasTerm { 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 350d8093b864..c803d7e17942 100644 --- a/compiler/rustc_type_ir/src/relate.rs +++ b/compiler/rustc_type_ir/src/relate.rs @@ -82,7 +82,7 @@ pub trait TypeRelation: 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>( a_arg: I::GenericArgs, b_arg: I::GenericArgs, ) -> RelateResult { - 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>( pub fn relate_args_with_variances>( 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>( 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 Relate for ty::AliasTy { 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 Relate for ty::AliasTerm { 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>( 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>( // 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 1c29fafc3cca..4782b8558d78 100644 --- a/compiler/rustc_type_ir/src/ty_kind.rs +++ b/compiler/rustc_type_ir/src/ty_kind.rs @@ -388,7 +388,7 @@ impl fmt::Debug for TyKind { 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 AliasTy { 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 AliasTy { 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 3a17a27bd03b..04aadfdabb48 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 ClosureArgs { /// for the closure parent, alongside additional closure-specific components. pub fn new(tcx: I, parts: ClosureArgsParts) -> ClosureArgs { 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 { impl CoroutineClosureArgs { pub fn new(tcx: I, parts: CoroutineClosureArgsParts) -> CoroutineClosureArgs { 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 CoroutineClosureArgs { 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 CoroutineClosureSignature { 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 CoroutineArgs { /// for the coroutine parent, alongside additional coroutine-specific components. pub fn new(tcx: I, parts: CoroutineArgsParts) -> CoroutineArgs { 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 4f99eaa40c29..f4846a1753f7 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)