diff --git a/crates/hir-def/src/expr_store/lower/generics.rs b/crates/hir-def/src/expr_store/lower/generics.rs index 65877fb627f2..2e92aea417d2 100644 --- a/crates/hir-def/src/expr_store/lower/generics.rs +++ b/crates/hir-def/src/expr_store/lower/generics.rs @@ -86,10 +86,13 @@ impl GenericParamsCollector { pub(crate) fn finish(self) -> GenericParams { let Self { mut lifetimes, mut type_or_consts, where_predicates, parent: _ } = self; + let early_bound_lifetimes_len = + lifetimes.iter().filter(|(_, lt)| lt.is_early_bound()).count(); lifetimes.shrink_to_fit(); type_or_consts.shrink_to_fit(); GenericParams { + early_bound_lifetimes_len, type_or_consts, lifetimes, where_predicates: where_predicates.into_boxed_slice(), diff --git a/crates/hir-def/src/hir/generics.rs b/crates/hir-def/src/hir/generics.rs index 2e0b6f1ae1cd..9e1053baa0bc 100644 --- a/crates/hir-def/src/hir/generics.rs +++ b/crates/hir-def/src/hir/generics.rs @@ -44,9 +44,15 @@ pub enum LifetimeBoundType { } impl LifetimeParamData { + #[inline] pub fn is_late_bound(&self) -> bool { self.bound_type == LifetimeBoundType::LateBound } + + #[inline] + pub fn is_early_bound(&self) -> bool { + self.bound_type == LifetimeBoundType::EarlyBound + } } /// Data about a generic const parameter (to a function, struct, impl, ...). @@ -164,6 +170,7 @@ pub struct GenericParams { pub(crate) type_or_consts: Arena, pub(crate) lifetimes: Arena, pub(crate) where_predicates: Box<[WherePredicate]>, + pub(crate) early_bound_lifetimes_len: usize, } impl ops::Index for GenericParams { @@ -194,6 +201,7 @@ static EMPTY: LazyLock = LazyLock::new(|| GenericParams { type_or_consts: Arena::default(), lifetimes: Arena::default(), where_predicates: Box::default(), + early_bound_lifetimes_len: 0, }); impl GenericParams { @@ -304,14 +312,24 @@ impl GenericParams { self.type_or_consts.len() + self.lifetimes.len() } + #[inline] + pub fn len_no_late(&self) -> usize { + self.type_or_consts.len() + self.early_bound_lifetimes_len + } + #[inline] pub fn len_lifetimes(&self) -> usize { - self.lifetimes.len() - self.len_late_bound_lifetimes() + self.lifetimes.len() + } + + #[inline] + pub fn len_early_bound_lifetimes(&self) -> usize { + self.early_bound_lifetimes_len } #[inline] pub fn len_late_bound_lifetimes(&self) -> usize { - self.lifetimes.iter().filter(|(_, p)| p.bound_type == LifetimeBoundType::LateBound).count() + self.len_lifetimes() - self.len_early_bound_lifetimes() } #[inline] diff --git a/crates/hir-ty/src/builtin_derive.rs b/crates/hir-ty/src/builtin_derive.rs index 53a232adfc7a..f17ddb60e0a7 100644 --- a/crates/hir-ty/src/builtin_derive.rs +++ b/crates/hir-ty/src/builtin_derive.rs @@ -179,12 +179,12 @@ pub fn predicates(db: &dyn HirDatabase, impl_: BuiltinDeriveImplId) -> GenericPr simple_trait_predicates(interner, loc, generic_params, adt_predicates, trait_id) } BuiltinDeriveImplTrait::Reborrow => { - explicit_own_predicates(interner, adt_predicates.own_explicit_predicates()) + explicit_own_predicates(adt_predicates.own_explicit_predicates()) } BuiltinDeriveImplTrait::Default => { if matches!(loc.adt, AdtId::EnumId(_)) { // Enums don't have extra bounds. - explicit_own_predicates(interner, adt_predicates.own_explicit_predicates()) + explicit_own_predicates(adt_predicates.own_explicit_predicates()) } else { simple_trait_predicates(interner, loc, generic_params, adt_predicates, trait_id) } @@ -218,7 +218,6 @@ pub fn predicates(db: &dyn HirDatabase, impl_: BuiltinDeriveImplId) -> GenericPr }); GenericPredicates::from_explicit_own_predicates(StoredEarlyBinder::bind( Clauses::new_from_iter( - interner, adt_predicates .explicit_predicates() .iter_identity() @@ -233,11 +232,10 @@ pub fn predicates(db: &dyn HirDatabase, impl_: BuiltinDeriveImplId) -> GenericPr } fn explicit_own_predicates<'db>( - interner: DbInterner<'db>, predicates: EarlyBinder<'db, impl Iterator>>, ) -> GenericPredicates { GenericPredicates::from_explicit_own_predicates(StoredEarlyBinder::bind( - Clauses::new_from_iter(interner, predicates.skip_binder()).store(), + Clauses::new_from_iter(predicates.skip_binder()).store(), )) } @@ -292,8 +290,8 @@ fn simple_trait_predicates<'db>( parent: loc.adt.into(), local_id: param_idx, }); - let param_idx = - param_idx.into_raw().into_u32() + (generic_params.len_lifetimes() as u32); + let param_idx = param_idx.into_raw().into_u32() + + (generic_params.len_early_bound_lifetimes() as u32); let param_ty = Ty::new_param(interner, param_id, param_idx); let trait_args = trait_args(loc.trait_, param_ty); let trait_ref = TraitRef::new_from_args(interner, trait_id.into(), trait_args); @@ -329,7 +327,6 @@ fn simple_trait_predicates<'db>( } GenericPredicates::from_explicit_own_predicates(StoredEarlyBinder::bind( Clauses::new_from_iter( - interner, adt_predicates .explicit_predicates() .iter_identity() @@ -413,7 +410,7 @@ fn coerce_pointee_params<'db>( local_id: pointee_param, }); let pointee_param_idx = - pointee_param.into_raw().into_u32() + (generic_params.len_lifetimes() as u32); + pointee_param.into_raw().into_u32() + (generic_params.len_early_bound_lifetimes() as u32); let new_param_idx = generic_params.len() as u32; let new_param_id = coerce_pointee_new_type_param(trait_id); let new_param_ty = Ty::new_param(interner, new_param_id, new_param_idx); diff --git a/crates/hir-ty/src/consteval.rs b/crates/hir-ty/src/consteval.rs index a1ed1e71aecc..8144a4bbef58 100644 --- a/crates/hir-ty/src/consteval.rs +++ b/crates/hir-ty/src/consteval.rs @@ -125,7 +125,6 @@ fn intern_const_ref<'db>( { let u8_values = &interner.default_types().consts.u8_values; ValTreeKind::Branch(Consts::new_from_iter( - interner, value.as_str().as_bytes().iter().map(|&byte| u8_values[usize::from(byte)]), )) } diff --git a/crates/hir-ty/src/dyn_compatibility.rs b/crates/hir-ty/src/dyn_compatibility.rs index 4fd65398d0ba..8b4462b71ffe 100644 --- a/crates/hir-ty/src/dyn_compatibility.rs +++ b/crates/hir-ty/src/dyn_compatibility.rs @@ -454,7 +454,6 @@ fn receiver_is_dispatchable<'db>( ParamEnv { clauses: Clauses::new_from_iter( - interner, generic_predicates .iter_identity() .map(Unnormalized::skip_norm_wip) diff --git a/crates/hir-ty/src/generics.rs b/crates/hir-ty/src/generics.rs index f2ca060bb533..1ebaa3d12290 100644 --- a/crates/hir-ty/src/generics.rs +++ b/crates/hir-ty/src/generics.rs @@ -69,15 +69,11 @@ impl<'db> SingleGenerics<'db> { } pub(crate) fn len_lifetimes(&self) -> usize { - self.params.len_lifetimes() + self.params.len_early_bound_lifetimes() } pub(crate) fn len(&self, consider_late_bound: bool) -> usize { - if consider_late_bound { - self.params.len() - } else { - self.params.len() - self.params.len_late_bound_lifetimes() - } + if consider_late_bound { self.params.len() } else { self.params.len_no_late() } } fn iter_lifetimes(&self) -> impl Iterator { @@ -269,7 +265,7 @@ impl<'db> Generics<'db> { let parent_total = self.len_parent(); let owner = self.owner(); - let lifetimes = owner.params.len_lifetimes(); + let lifetimes = owner.params.len_early_bound_lifetimes(); let mut has_self_param = false; let mut non_impl_trait_type_params = 0; diff --git a/crates/hir-ty/src/infer/cast.rs b/crates/hir-ty/src/infer/cast.rs index dc0813908194..9177e335b75d 100644 --- a/crates/hir-ty/src/infer/cast.rs +++ b/crates/hir-ty/src/infer/cast.rs @@ -345,28 +345,26 @@ impl<'db> CastCheck<'db> { // We also need to skip auto traits to emit an FCW and not an error. let src_obj = Ty::new_dynamic( ctx.interner(), - BoundExistentialPredicates::new_from_iter( - ctx.interner(), - src_tty.iter().filter(|pred| { + BoundExistentialPredicates::new_from_iter(src_tty.iter().filter( + |pred| { !matches!( pred.skip_binder(), ExistentialPredicate::AutoTrait(_) ) - }), - ), + }, + )), Region::new_erased(ctx.interner()), ); let dst_obj = Ty::new_dynamic( ctx.interner(), - BoundExistentialPredicates::new_from_iter( - ctx.interner(), - dst_tty.iter().filter(|pred| { + BoundExistentialPredicates::new_from_iter(dst_tty.iter().filter( + |pred| { !matches!( pred.skip_binder(), ExistentialPredicate::AutoTrait(_) ) - }), - ), + }, + )), Region::new_erased(ctx.interner()), ); diff --git a/crates/hir-ty/src/infer/pat.rs b/crates/hir-ty/src/infer/pat.rs index 17c198879f26..24617c512966 100644 --- a/crates/hir-ty/src/infer/pat.rs +++ b/crates/hir-ty/src/infer/pat.rs @@ -1120,7 +1120,7 @@ impl<'db> InferenceContext<'db> { let element_tys_iter = (0..max_len).map(|i| { self.table.next_ty_var(elements.get(i).copied().map(Span::PatId).unwrap_or(Span::Dummy)) }); - let element_tys = Tys::new_from_iter(interner, element_tys_iter); + let element_tys = Tys::new_from_iter(element_tys_iter); let pat_ty = Ty::new(interner, TyKind::Tuple(element_tys)); if self.demand_eqtype(pat.into(), expected, pat_ty).is_err() { let expected = if let TyKind::Tuple(tys) = diff --git a/crates/hir-ty/src/lower.rs b/crates/hir-ty/src/lower.rs index 04e453fde3b9..36230f5748c6 100644 --- a/crates/hir-ty/src/lower.rs +++ b/crates/hir-ty/src/lower.rs @@ -247,7 +247,7 @@ impl<'db, 'a> TyLoweringContext<'db, 'a> { let in_binders = DebruijnIndex::ZERO; let interner = DbInterner::new_with(db, resolver.krate()); let bound_vars = - vec![(Vec::new(), TyLoweringContext::bound_vars(db, interner, generic_def, generics))]; + vec![(Vec::new(), TyLoweringContext::bound_vars(db, generic_def, generics))]; Self { db, // Can provide no block since we don't use it for trait solving. @@ -374,12 +374,10 @@ impl<'db, 'a> TyLoweringContext<'db, 'a> { } fn push_bound_vars(&mut self, binder: &[Name]) { - let bound_vars = BoundVarKinds::new_from_iter( - self.interner, - binder.iter().map(|_| { + let bound_vars = + BoundVarKinds::new_from_iter(binder.iter().map(|_| { BoundVariableKind::Region(BoundRegionKind::Named(self.generic_def.into())) - }), - ); + })); self.bound_vars.push((binder.to_vec(), bound_vars)); } @@ -393,7 +391,6 @@ impl<'db, 'a> TyLoweringContext<'db, 'a> { fn bound_vars( db: &'db dyn HirDatabase, - interner: DbInterner<'db>, def: GenericDefId, generic: &'a OnceCell>, ) -> BoundVarKinds<'db> { @@ -410,7 +407,7 @@ impl<'db, 'a> TyLoweringContext<'db, 'a> { } }); - BoundVarKinds::new_from_iter(interner, args) + BoundVarKinds::new_from_iter(args) } fn take_defined_opaques(&mut self) -> Option>> { @@ -737,7 +734,6 @@ impl<'db, 'a> TyLoweringContext<'db, 'a> { hir_def::hir::Pat::NotNull => rustc_type_ir::PatternKind::NotNull, hir_def::hir::Pat::Or(ref pats) => rustc_type_ir::PatternKind::Or( PatList::new_from_iter( - self.interner, pats.iter().map(|&pat| self.lower_pattern_type(pat, ty).ok_or(())), ) .ok()?, @@ -1263,7 +1259,6 @@ impl<'db, 'a> TyLoweringContext<'db, 'a> { // N.b. principal, projections, auto traits Some(BoundExistentialPredicates::new_from_iter( - interner, principal.into_iter().chain(projections).chain(auto_traits), )) }; @@ -2491,7 +2486,7 @@ pub(crate) fn param_env_from_predicates<'db>( interner, predicates.all_predicates().iter_identity().map(Unnormalized::skip_norm_wip), ); - let clauses = Clauses::new_from_iter(interner, clauses); + let clauses = Clauses::new_from_iter(clauses); // FIXME: We should normalize projections here, like rustc does. ParamEnv { clauses } @@ -2852,11 +2847,11 @@ pub(crate) fn fn_sig_for_fn<'db>( }; let impl_traits = ctx_ret.take_defined_opaques(); - let inputs_and_output = Tys::new_from_iter(interner, params.chain(Some(ret))); + let inputs_and_output = Tys::new_from_iter(params.chain(Some(ret))); ctx_params.diagnostics.extend(ctx_ret.diagnostics); ctx_params.defined_anon_consts.extend(ctx_ret.defined_anon_consts); - let binder = TyLoweringContext::bound_vars(db, interner, def.into(), &generics); + let binder = TyLoweringContext::bound_vars(db, def.into(), &generics); let result = StoredEarlyBinder::bind(StoredPolyFnSig::new(Binder::bind_with_vars( FnSig { inputs_and_output, @@ -2887,8 +2882,7 @@ fn ctor_signature( let params = field_tys.iter().map(|(_, field)| field.ty().skip_binder()); let ret = type_for_adt(db, adt).skip_binder(); - let inputs_and_output = - Tys::new_from_iter(DbInterner::new_no_crate(db), params.chain(Some(ret))); + let inputs_and_output = Tys::new_from_iter(params.chain(Some(ret))); StoredEarlyBinder::bind(StoredPolyFnSig::new(Binder::dummy(FnSig { fn_sig_kind: FnSigKind::new(ExternAbi::Rust, Safety::Safe, false), inputs_and_output, diff --git a/crates/hir-ty/src/lower/path.rs b/crates/hir-ty/src/lower/path.rs index 7e55ef296316..4e89aa2b3c8d 100644 --- a/crates/hir-ty/src/lower/path.rs +++ b/crates/hir-ty/src/lower/path.rs @@ -214,7 +214,6 @@ impl<'a, 'b, 'db> PathLoweringContext<'a, 'b, 'db> { span, ); let args = GenericArgs::new_from_iter( - self.ctx.interner, trait_ref .args .iter() @@ -544,7 +543,6 @@ impl<'a, 'b, 'db> PathLoweringContext<'a, 'b, 'db> { let substs = self.substs_from_path_segment(assoc_type.into(), infer_args, None, true, span); let substs = GenericArgs::new_from_iter( - interner, trait_args.iter().chain(substs.iter().skip(trait_args.len())), ); @@ -928,7 +926,6 @@ impl<'a, 'b, 'db> PathLoweringContext<'a, 'b, 'db> { ) }); let args = GenericArgs::new_from_iter( - interner, super_trait_args.iter().chain(args.iter().skip(super_trait_args.len())), ); let projection_term = AliasTerm::new_from_args( diff --git a/crates/hir-ty/src/method_resolution.rs b/crates/hir-ty/src/method_resolution.rs index 37e29b10cd5a..2db1a856c708 100644 --- a/crates/hir-ty/src/method_resolution.rs +++ b/crates/hir-ty/src/method_resolution.rs @@ -450,10 +450,7 @@ pub(crate) fn lookup_impl_method_query<'db>( ( impl_fn, - GenericArgs::new_from_iter( - interner, - impl_subst.iter().chain(fn_subst.iter().skip(trait_params)), - ), + GenericArgs::new_from_iter(impl_subst.iter().chain(fn_subst.iter().skip(trait_params))), ) } diff --git a/crates/hir-ty/src/mir.rs b/crates/hir-ty/src/mir.rs index 433fc274ea95..0566eedd33dc 100644 --- a/crates/hir-ty/src/mir.rs +++ b/crates/hir-ty/src/mir.rs @@ -6,13 +6,12 @@ use hir_def::{ FieldId, LocalFieldId, StaticId, UnionId, VariantId, hir::{BindingId, Expr, ExprId, Ordering, PatId}, }; -use intern::{InternedSlice, InternedSliceRef, impl_slice_internable}; use la_arena::{Arena, ArenaMap, Idx, RawIdx}; use macros::{TypeFoldable, TypeVisitable}; use rustc_ast_ir::Mutability; use rustc_hash::FxHashMap; use rustc_type_ir::{ - CollectAndApply, GenericTypeVisitable, + GenericTypeVisitable, inherent::{GenericArgs as _, IntoKind, Ty as _}, }; use salsa::SalsaValue; @@ -26,8 +25,8 @@ use crate::{ next_solver::{ Allocation, AllocationData, DbInterner, ErrorGuaranteed, GenericArgs, ParamEnv, StoredAllocation, StoredConst, StoredGenericArgs, StoredTy, Ty, TyKind, - impl_stored_interned_slice, infer::{InferCtxt, traits::ObligationCause}, + interned_slice, obligation_ctxt::ObligationCtxt, }, }; @@ -220,52 +219,14 @@ impl GenericTypeVisitable for PlaceElem fn generic_visit_with(&self, _: &mut W) {} } -impl_slice_internable!(gc; ProjectionStorage, (), PlaceElem); -impl_stored_interned_slice!(ProjectionStorage, Projection, StoredProjection); - -#[derive(Clone, Copy, PartialEq, Eq, Hash)] -pub struct Projection<'db> { - interned: InternedSliceRef<'db, ProjectionStorage>, -} - -impl<'db> std::fmt::Debug for Projection<'db> { - fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - (*self).as_slice().fmt(fmt) - } -} +interned_slice!(ProjectionStorage, Projection, StoredProjection, projection, PlaceElem, PlaceElem); impl<'db> Projection<'db> { - pub fn new_from_iter(args: I) -> T::Output - where - I: IntoIterator, - T: CollectAndApply, - { - CollectAndApply::collect_and_apply(args.into_iter(), Self::new_from_slice) - } - - #[inline] - pub fn new_from_slice(slice: &[PlaceElem]) -> Self { - Self { interned: InternedSlice::from_header_and_slice((), slice) } - } - - #[inline] - pub fn as_slice(self) -> &'db [PlaceElem] { - &self.interned.get().slice - } - pub fn project(self, projection: PlaceElem) -> Projection<'db> { Projection::new_from_iter(self.as_slice().iter().copied().chain([projection])) } } -impl<'db> std::ops::Deref for Projection<'db> { - type Target = [PlaceElem]; - - fn deref(&self) -> &Self::Target { - self.as_slice() - } -} - impl StoredProjection { pub fn as_slice(&self) -> &[PlaceElem] { self.as_ref().as_slice() diff --git a/crates/hir-ty/src/mir/eval.rs b/crates/hir-ty/src/mir/eval.rs index 37f3e2763181..798d57420d19 100644 --- a/crates/hir-ty/src/mir/eval.rs +++ b/crates/hir-ty/src/mir/eval.rs @@ -2900,7 +2900,6 @@ impl<'a, 'db> Evaluator<'a, 'db> { ty, }; let generics_for_target = GenericArgs::new_from_iter( - self.interner(), generic_args .iter() .enumerate() diff --git a/crates/hir-ty/src/next_solver.rs b/crates/hir-ty/src/next_solver.rs index 626357128672..24122da4c981 100644 --- a/crates/hir-ty/src/next_solver.rs +++ b/crates/hir-ty/src/next_solver.rs @@ -165,79 +165,79 @@ pub fn default_types<'db>() -> &'db DefaultAny<'db> { ty.as_ref() }; let create_generic_args = |slice| { - let ty = GenericArgs::new_from_slice(slice); + let ty = GenericArgs::new_from_slice_no_empty_check(slice); // We need to increase the refcount (forever), so that the types won't be freed. let ty = ManuallyDrop::new(ty.store()); ty.as_ref() }; let create_bound_var_kinds = |slice| { - let ty = BoundVarKinds::new_from_slice(slice); + let ty = BoundVarKinds::new_from_slice_no_empty_check(slice); // We need to increase the refcount (forever), so that the types won't be freed. let ty = ManuallyDrop::new(ty.store()); ty.as_ref() }; let create_canonical_vars = |slice| { - let ty = CanonicalVarKinds::new_from_slice(slice); + let ty = CanonicalVarKinds::new_from_slice_no_empty_check(slice); // We need to increase the refcount (forever), so that the types won't be freed. let ty = ManuallyDrop::new(ty.store()); ty.as_ref() }; let create_variances_of = |slice| { - let ty = VariancesOf::new_from_slice(slice); + let ty = VariancesOf::new_from_slice_no_empty_check(slice); // We need to increase the refcount (forever), so that the types won't be freed. let ty = ManuallyDrop::new(ty.store()); ty.as_ref() }; let create_pat_list = |slice| { - let ty = PatList::new_from_slice(slice); + let ty = PatList::new_from_slice_no_empty_check(slice); // We need to increase the refcount (forever), so that the types won't be freed. let ty = ManuallyDrop::new(ty.store()); ty.as_ref() }; let create_predefined_opaques = |slice| { - let ty = PredefinedOpaques::new_from_slice(slice); + let ty = PredefinedOpaques::new_from_slice_no_empty_check(slice); // We need to increase the refcount (forever), so that the types won't be freed. let ty = ManuallyDrop::new(ty.store()); ty.as_ref() }; let create_solver_def_ids = |slice| { - let ty = SolverDefIds::new_from_slice(slice); + let ty = SolverDefIds::new_from_slice_no_empty_check(slice); // We need to increase the refcount (forever), so that the types won't be freed. let ty = ManuallyDrop::new(ty.store()); ty.as_ref() }; let create_bound_existential_predicates = |slice| { - let ty = BoundExistentialPredicates::new_from_slice(slice); + let ty = BoundExistentialPredicates::new_from_slice_no_empty_check(slice); // We need to increase the refcount (forever), so that the types won't be freed. let ty = ManuallyDrop::new(ty.store()); ty.as_ref() }; let create_clauses = |slice| { - let ty = Clauses::new_from_slice(slice); + let ty = Clauses::new_from_slice_no_empty_check(slice); // We need to increase the refcount (forever), so that the types won't be freed. let ty = ManuallyDrop::new(ty.store()); ty.as_ref() }; let create_region_assumptions = |slice| { - let ty = RegionAssumptions::new_from_slice(slice); + let ty = RegionAssumptions::new_from_slice_no_empty_check(slice); // We need to increase the refcount (forever), so that the types won't be freed. let ty = ManuallyDrop::new(ty.store()); ty.as_ref() }; let create_tys = |slice| { - let ty = Tys::new_from_slice(slice); + let ty = Tys::new_from_slice_no_empty_check(slice); // We need to increase the refcount (forever), so that the types won't be freed. let ty = ManuallyDrop::new(ty.store()); ty.as_ref() }; let create_consts = |slice| { - let ty = Consts::new_from_slice(slice); + let ty = Consts::new_from_slice_no_empty_check(slice); // We need to increase the refcount (forever), so that the types won't be freed. let ty = ManuallyDrop::new(ty.store()); ty.as_ref() }; let create_projection = |slice| { - let it = crate::mir::Projection::new_from_slice(slice); + let it = crate::mir::Projection::new_from_slice_no_empty_check(slice); // We need to increase the refcount (forever), so that the types won't be freed. let it = ManuallyDrop::new(it.store()); it.as_ref() diff --git a/crates/hir-ty/src/next_solver/consts/valtree.rs b/crates/hir-ty/src/next_solver/consts/valtree.rs index 70db32e09b74..cc4318e6f32a 100644 --- a/crates/hir-ty/src/next_solver/consts/valtree.rs +++ b/crates/hir-ty/src/next_solver/consts/valtree.rs @@ -127,7 +127,6 @@ pub(super) fn allocation_to_const<'db>( }; let u8_values = &interner.default_types().consts.u8_values; ValTreeKind::Branch(Consts::new_from_iter( - interner, bytes.iter().map(|&byte| u8_values[usize::from(byte)]), )) } @@ -154,7 +153,7 @@ pub(super) fn allocation_to_const<'db>( let bytes = &bytes[offset..offset + size_one]; allocation_to_const(interner, ty, bytes, memory_map, param_env) }); - ValTreeKind::Branch(Consts::new_from_iter(interner, items)) + ValTreeKind::Branch(Consts::new_from_iter(items)) } TyKind::Dynamic(_, _) => { let addr = usize::from_le_bytes(memory[0..memory.len() / 2].try_into().unwrap()); @@ -215,7 +214,7 @@ pub(super) fn allocation_to_const<'db>( param_env, ) }); - ValTreeKind::Branch(Consts::new_from_iter(interner, items)) + ValTreeKind::Branch(Consts::new_from_iter(items)) } TyKind::Adt(..) => { // FIXME: This requires `adt_const_params`. @@ -249,7 +248,7 @@ pub(super) fn allocation_to_const<'db>( param_env, ) }); - ValTreeKind::Branch(Consts::new_from_iter(interner, items)) + ValTreeKind::Branch(Consts::new_from_iter(items)) } TyKind::Never => return Const::error(interner), // FIXME: diff --git a/crates/hir-ty/src/next_solver/generic_arg.rs b/crates/hir-ty/src/next_solver/generic_arg.rs index 483811f9e6f0..81d36c2bb037 100644 --- a/crates/hir-ty/src/next_solver/generic_arg.rs +++ b/crates/hir-ty/src/next_solver/generic_arg.rs @@ -623,17 +623,9 @@ impl<'db> rustc_type_ir::relate::Relate> for GenericArgs<'db> { a: Self, b: Self, ) -> rustc_type_ir::relate::RelateResult, Self> { - GenericArgs::new_from_iter( - relation.cx(), - std::iter::zip(a.iter(), b.iter()).map(|(a, b)| { - relation.relate_with_variance( - Variance::Invariant, - VarianceDiagInfo::default(), - a, - b, - ) - }), - ) + GenericArgs::new_from_iter(std::iter::zip(a.iter(), b.iter()).map(|(a, b)| { + relation.relate_with_variance(Variance::Invariant, VarianceDiagInfo::default(), a, b) + })) } } diff --git a/crates/hir-ty/src/next_solver/interner.rs b/crates/hir-ty/src/next_solver/interner.rs index df7c9bfe1ec4..34d3ef8fdb09 100644 --- a/crates/hir-ty/src/next_solver/interner.rs +++ b/crates/hir-ty/src/next_solver/interner.rs @@ -96,12 +96,24 @@ macro_rules! interned_slice { #[inline] pub fn new_from_slice(slice: &[$ty_db]) -> Self { + if slice.is_empty() { + // Common case: avoid looking up the empty slice. + Self::empty() + } else { + Self::new_from_slice_no_empty_check(slice) + } + } + + /// Same as [`Self::new_from_slice()`] but won't use the global empty slice `slice.is_empty()`, because someone + /// needs to intern the global slice as well. + #[inline] + pub(crate) fn new_from_slice_no_empty_check(slice: &[$ty_db]) -> Self { let slice = unsafe { ::std::mem::transmute::<&[$ty_db], &[$ty_static]>(slice) }; Self { interned: ::intern::InternedSlice::from_header_and_slice((), slice) } } #[inline] - pub fn new_from_iter(_interner: DbInterner<'db>, args: I) -> T::Output + pub fn new_from_iter(args: I) -> T::Output where I: IntoIterator, T: ::rustc_type_ir::CollectAndApply<$ty_db, Self>, @@ -247,13 +259,13 @@ macro_rules! impl_foldable_for_interned_slice { self, folder: &mut F, ) -> Result { - Self::new_from_iter(folder.cx(), self.iter().map(|it| it.try_fold_with(folder))) + Self::new_from_iter(self.iter().map(|it| it.try_fold_with(folder))) } fn fold_with>>( self, folder: &mut F, ) -> Self { - Self::new_from_iter(folder.cx(), self.iter().map(|it| it.fold_with(folder))) + Self::new_from_iter(self.iter().map(|it| it.fold_with(folder))) } } }; @@ -847,7 +859,6 @@ impl<'db> rustc_type_ir::relate::Relate> for Pattern<'db> { return Err(TypeError::Mismatch); } let pats = PatList::new_from_iter( - relation.cx(), std::iter::zip(a.iter(), b.iter()).map(|(a, b)| relation.relate(a, b)), )?; Ok(Pattern::new(tcx, PatternKind::Or(pats))) @@ -1014,7 +1025,7 @@ impl<'db> Interner for DbInterner<'db> { I: Iterator, T: rustc_type_ir::CollectAndApply, { - GenericArgs::new_from_iter(self, args) + GenericArgs::new_from_iter(args) } type UnsizingParams = UnsizingParams; @@ -1075,7 +1086,6 @@ impl<'db> Interner for DbInterner<'db> { // We compute them based on the only `Ty` level info in rustc, // move `variances_of_opaque` into `rustc_next_trait_solver` for reuse. return VariancesOf::new_from_iter( - self, (0..self.generics_of(def_id).count()).map(|_| Variance::Invariant), ); } @@ -1161,12 +1171,9 @@ impl<'db> Interner for DbInterner<'db> { def_id: Self::TraitAssocTermId, args: Self::GenericArgs, ) -> (rustc_type_ir::TraitRef, Self::GenericArgsSlice) { - let trait_def_id = self.projection_parent(def_id).0; - let trait_generics = crate::generics::generics(self.db, trait_def_id.into()); - let trait_generics_len = trait_generics.len(true); - let trait_args = GenericArgs::new_from_slice(&args.as_slice()[..trait_generics_len]); - let alias_args = &args.as_slice()[trait_generics_len..]; - (TraitRef::new_from_args(self, trait_def_id.into(), trait_args), alias_args) + let trait_def_id = self.projection_parent(def_id); + let trait_ref = TraitRef::from_assoc(self, trait_def_id, args); + (trait_ref, &args.as_slice()[trait_ref.args.len()..]) } fn check_args_compatible(self, def_id: Self::DefId, args: Self::GenericArgs) -> bool { @@ -1196,7 +1203,7 @@ impl<'db> Interner for DbInterner<'db> { I: Iterator, T: rustc_type_ir::CollectAndApply, { - Tys::new_from_iter(self, args) + Tys::new_from_iter(args) } fn projection_parent(self, def_id: Self::TraitAssocTermId) -> Self::TraitId { @@ -1347,10 +1354,7 @@ impl<'db> Interner for DbInterner<'db> { if all_bounds.len() == own_bounds.len() { EarlyBinder::bind(Clauses::empty()) } else { - EarlyBinder::bind(Clauses::new_from_iter( - self, - all_bounds.difference(&own_bounds).cloned(), - )) + EarlyBinder::bind(Clauses::new_from_iter(all_bounds.difference(&own_bounds).cloned())) } } @@ -1978,7 +1982,7 @@ impl<'db> Interner for DbInterner<'db> { let mut map = Default::default(); let delegate = Anonymize { interner: self, map: &mut map }; let inner = self.replace_escaping_bound_vars_uncached(value.skip_binder(), delegate); - let bound_vars = BoundVarKinds::new_from_iter(self, map.into_values()); + let bound_vars = BoundVarKinds::new_from_iter(map.into_values()); Binder::bind_with_vars(inner, bound_vars) } @@ -2292,7 +2296,6 @@ impl<'db> DbInterner<'db> { { FnSig { inputs_and_output: Tys::new_from_iter( - self, inputs.into_iter().chain(std::iter::once(output)), ), fn_sig_kind: FnSigKind::new(abi, safety, c_variadic), diff --git a/crates/hir-ty/src/next_solver/predicate.rs b/crates/hir-ty/src/next_solver/predicate.rs index a1e249eaf951..460e266999ed 100644 --- a/crates/hir-ty/src/next_solver/predicate.rs +++ b/crates/hir-ty/src/next_solver/predicate.rs @@ -136,8 +136,6 @@ impl<'db> rustc_type_ir::relate::Relate> for BoundExistentialPre a: Self, b: Self, ) -> rustc_type_ir::relate::RelateResult, Self> { - let interner = relation.cx(); - // We need to perform this deduplication as we sometimes generate duplicate projections in `a`. let mut a_v: Vec<_> = a.into_iter().collect(); let mut b_v: Vec<_> = b.into_iter().collect(); @@ -180,7 +178,7 @@ impl<'db> rustc_type_ir::relate::Relate> for BoundExistentialPre }, ); - BoundExistentialPredicates::new_from_iter(interner, v) + BoundExistentialPredicates::new_from_iter(v) } } @@ -280,6 +278,18 @@ impl<'db> Clauses<'db> { #[inline] pub fn new_from_slice(slice: &[Clause<'db>]) -> Self { + if slice.is_empty() { + // Common case: avoid looking up the empty slice. + Self::empty() + } else { + Self::new_from_slice_no_empty_check(slice) + } + } + + /// Same as [`Self::new_from_slice()`] but won't use the global empty slice `slice.is_empty()`, because someone + /// needs to intern the global slice as well. + #[inline] + pub(crate) fn new_from_slice_no_empty_check(slice: &[Clause<'db>]) -> Self { let slice = unsafe { ::std::mem::transmute::<&[Clause<'db>], &[Clause<'static>]>(slice) }; let flags = FlagComputation::>::for_clauses(slice); let flags = ClausesCachedTypeInfo(WithCachedTypeInfo { @@ -291,7 +301,7 @@ impl<'db> Clauses<'db> { } #[inline] - pub fn new_from_iter(_interner: DbInterner<'db>, args: I) -> T::Output + pub fn new_from_iter(args: I) -> T::Output where I: IntoIterator, T: CollectAndApply, Self>, @@ -369,14 +379,14 @@ impl<'db> rustc_type_ir::TypeSuperFoldable> for Clauses<'db> { self, folder: &mut F, ) -> Result { - Clauses::new_from_iter(folder.cx(), self.iter().map(|clause| clause.try_fold_with(folder))) + Clauses::new_from_iter(self.iter().map(|clause| clause.try_fold_with(folder))) } fn super_fold_with>>( self, folder: &mut F, ) -> Self { - Clauses::new_from_iter(folder.cx(), self.iter().map(|clause| clause.fold_with(folder))) + Clauses::new_from_iter(self.iter().map(|clause| clause.fold_with(folder))) } } @@ -891,7 +901,7 @@ impl<'db> rustc_type_ir::inherent::Clause> for Clause<'db> { .skip_norm_wip(); // 3) ['x] + ['b] -> ['x, 'b] let bound_vars = - BoundVarKinds::new_from_iter(cx, trait_bound_vars.iter().chain(pred_bound_vars.iter())); + BoundVarKinds::new_from_iter(trait_bound_vars.iter().chain(pred_bound_vars.iter())); let predicate: Predicate<'db> = ty::Binder::bind_with_vars(PredicateKind::Clause(new), bound_vars).upcast(cx); diff --git a/crates/hir-ty/src/next_solver/ty.rs b/crates/hir-ty/src/next_solver/ty.rs index c1810bc659c0..84f21c96c9b0 100644 --- a/crates/hir-ty/src/next_solver/ty.rs +++ b/crates/hir-ty/src/next_solver/ty.rs @@ -610,7 +610,6 @@ impl<'db> Ty<'db> { ); FnSig { inputs_and_output: Tys::new_from_iter( - interner, sig.tupled_inputs_ty .tuple_fields() .iter() diff --git a/crates/hir-ty/src/representability.rs b/crates/hir-ty/src/representability.rs index 9a31443b25af..37c79257e3af 100644 --- a/crates/hir-ty/src/representability.rs +++ b/crates/hir-ty/src/representability.rs @@ -89,7 +89,8 @@ fn representability_adt_ty<'db>( fn params_in_repr(db: &dyn HirDatabase, def_id: AdtId) -> Box<[bool]> { let generics = GenericParams::of(db, def_id.into()); - let mut params_in_repr = (0..generics.len_lifetimes() + generics.len_type_or_consts()) + let mut params_in_repr = (0..generics.len_early_bound_lifetimes() + + generics.len_type_or_consts()) .map(|_| false) .collect::>(); let mut handle_variant = |variant| { diff --git a/crates/hir-ty/src/variance.rs b/crates/hir-ty/src/variance.rs index cce1b4caf44a..8b96fe348b9b 100644 --- a/crates/hir-ty/src/variance.rs +++ b/crates/hir-ty/src/variance.rs @@ -25,8 +25,8 @@ use crate::{ db::HirDatabase, generics::{Generics, generics}, next_solver::{ - Const, ConstKind, DbInterner, ExistentialPredicate, GenericArgKind, GenericArgs, Pattern, - PatternKind, Region, RegionKind, StoredVariancesOf, TermKind, Ty, TyKind, VariancesOf, + Const, ConstKind, ExistentialPredicate, GenericArgKind, GenericArgs, Pattern, PatternKind, + Region, RegionKind, StoredVariancesOf, TermKind, Ty, TyKind, VariancesOf, }, }; @@ -106,11 +106,10 @@ pub(crate) fn variances_of_cycle_initial( _: salsa::Id, def: GenericDefId, ) -> StoredVariancesOf { - let interner = DbInterner::new_no_crate(db); let generics = generics(db, def); let count = generics.len(true); - VariancesOf::new_from_iter(interner, std::iter::repeat_n(Variance::Bivariant, count)).store() + VariancesOf::new_from_iter(std::iter::repeat_n(Variance::Bivariant, count)).store() } struct Context<'db> {