From 455e755bb011fff6d1389701063956fbf16daaf1 Mon Sep 17 00:00:00 2001 From: Florian Diebold Date: Mon, 15 Mar 2021 19:13:49 +0100 Subject: Use SmallVec for Substs Doesn't help as much as I hoped, but it helps a bit and I also did some refactorings that were necessary anyway. --- crates/hir_ty/src/lib.rs | 27 ++++++++++++++++++++------- crates/hir_ty/src/lower.rs | 9 +++++---- crates/hir_ty/src/traits/chalk/interner.rs | 7 ++++--- 3 files changed, 29 insertions(+), 14 deletions(-) diff --git a/crates/hir_ty/src/lib.rs b/crates/hir_ty/src/lib.rs index 503910dde..850385280 100644 --- a/crates/hir_ty/src/lib.rs +++ b/crates/hir_ty/src/lib.rs @@ -31,6 +31,7 @@ use hir_def::{ GenericDefId, HasModule, LifetimeParamId, Lookup, TraitId, TypeAliasId, TypeParamId, }; use itertools::Itertools; +use smallvec::SmallVec; use crate::{ db::HirDatabase, @@ -272,7 +273,7 @@ impl Ty { /// A list of substitutions for generic parameters. #[derive(Clone, PartialEq, Eq, Debug, Hash)] -pub struct Substs(Arc<[Ty]>); +pub struct Substs(SmallVec<[Ty; 2]>); impl TypeWalk for Substs { fn walk(&self, f: &mut impl FnMut(&Ty)) { @@ -286,19 +287,27 @@ impl TypeWalk for Substs { f: &mut impl FnMut(&mut Ty, DebruijnIndex), binders: DebruijnIndex, ) { - for t in make_mut_slice(&mut self.0) { + for t in &mut self.0 { t.walk_mut_binders(f, binders); } } } impl Substs { + pub fn interned(&self, _: &Interner) -> &[Ty] { + &self.0 + } + pub fn empty() -> Substs { - Substs(Arc::new([])) + Substs(SmallVec::new()) } pub fn single(ty: Ty) -> Substs { - Substs(Arc::new([ty])) + Substs({ + let mut v = SmallVec::new(); + v.push(ty); + v + }) } pub fn prefix(&self, n: usize) -> Substs { @@ -316,6 +325,10 @@ impl Substs { &self.0[0] } + pub fn from_iter(_interner: &Interner, elements: impl IntoIterator) -> Self { + Substs(elements.into_iter().collect()) + } + /// Return Substs that replace each parameter by itself (i.e. `Ty::Param`). pub(crate) fn type_params_for_generics( db: &dyn HirDatabase, @@ -600,13 +613,13 @@ impl CallableSig { pub fn from_fn_ptr(fn_ptr: &FnPointer) -> CallableSig { CallableSig { - params_and_return: Arc::clone(&fn_ptr.substs.0), + params_and_return: fn_ptr.substs.interned(&Interner).iter().cloned().collect(), is_varargs: fn_ptr.sig.variadic, } } pub fn from_substs(substs: &Substs) -> CallableSig { - CallableSig { params_and_return: Arc::clone(&substs.0), is_varargs: false } + CallableSig { params_and_return: substs.iter().cloned().collect(), is_varargs: false } } pub fn params(&self) -> &[Ty] { @@ -649,7 +662,7 @@ impl Ty { TyKind::Function(FnPointer { num_args: sig.params().len(), sig: FnSig { abi: (), safety: Safety::Safe, variadic: sig.is_varargs }, - substs: Substs(sig.params_and_return), + substs: Substs::from_iter(&Interner, sig.params_and_return.iter().cloned()), }) .intern(&Interner) } diff --git a/crates/hir_ty/src/lower.rs b/crates/hir_ty/src/lower.rs index b4c650fa1..6ab757bfc 100644 --- a/crates/hir_ty/src/lower.rs +++ b/crates/hir_ty/src/lower.rs @@ -31,7 +31,7 @@ use crate::{ traits::chalk::{Interner, ToChalk}, utils::{ all_super_trait_refs, associated_type_by_name_including_super_traits, generics, - make_mut_slice, variant_data, + variant_data, }, AliasTy, Binders, BoundVar, CallableSig, DebruijnIndex, FnPointer, FnSig, GenericPredicate, ImplTraitId, OpaqueTy, PolyFnSig, ProjectionPredicate, ProjectionTy, ReturnTypeImplTrait, @@ -150,8 +150,9 @@ impl<'a> TyLoweringContext<'a> { let ty = match type_ref { TypeRef::Never => TyKind::Never.intern(&Interner), TypeRef::Tuple(inner) => { - let inner_tys: Arc<[Ty]> = inner.iter().map(|tr| self.lower_ty(tr)).collect(); - TyKind::Tuple(inner_tys.len(), Substs(inner_tys)).intern(&Interner) + let inner_tys = inner.iter().map(|tr| self.lower_ty(tr)); + TyKind::Tuple(inner_tys.len(), Substs::from_iter(&Interner, inner_tys)) + .intern(&Interner) } TypeRef::Path(path) => { let (ty, res_) = self.lower_path(path); @@ -638,7 +639,7 @@ impl<'a> TyLoweringContext<'a> { ) -> TraitRef { let mut substs = self.trait_ref_substs_from_path(segment, resolved); if let Some(self_ty) = explicit_self_ty { - make_mut_slice(&mut substs.0)[0] = self_ty; + substs.0[0] = self_ty; } TraitRef { trait_: resolved, substs } } diff --git a/crates/hir_ty/src/traits/chalk/interner.rs b/crates/hir_ty/src/traits/chalk/interner.rs index 1dc3f497d..94e94a26d 100644 --- a/crates/hir_ty/src/traits/chalk/interner.rs +++ b/crates/hir_ty/src/traits/chalk/interner.rs @@ -5,6 +5,7 @@ use super::tls; use base_db::salsa::InternId; use chalk_ir::{GenericArg, Goal, GoalData}; use hir_def::TypeAliasId; +use smallvec::SmallVec; use std::{fmt, sync::Arc}; #[derive(Debug, Copy, Clone, Hash, PartialOrd, Ord, PartialEq, Eq)] @@ -33,7 +34,7 @@ impl chalk_ir::interner::Interner for Interner { type InternedGenericArg = chalk_ir::GenericArgData; type InternedGoal = Arc>; type InternedGoals = Vec>; - type InternedSubstitution = Vec>; + type InternedSubstitution = SmallVec<[GenericArg; 2]>; type InternedProgramClause = Arc>; type InternedProgramClauses = Arc<[chalk_ir::ProgramClause]>; type InternedQuantifiedWhereClauses = Vec>; @@ -265,13 +266,13 @@ impl chalk_ir::interner::Interner for Interner { fn intern_substitution( &self, data: impl IntoIterator, E>>, - ) -> Result>, E> { + ) -> Result { data.into_iter().collect() } fn substitution_data<'a>( &self, - substitution: &'a Vec>, + substitution: &'a Self::InternedSubstitution, ) -> &'a [GenericArg] { substitution } -- cgit v1.2.3