]> git.lizzy.rs Git - rust.git/commitdiff
Use SmallVec for Substs
authorFlorian Diebold <flodiebold@gmail.com>
Mon, 15 Mar 2021 18:13:49 +0000 (19:13 +0100)
committerFlorian Diebold <flodiebold@gmail.com>
Mon, 15 Mar 2021 18:48:03 +0000 (19:48 +0100)
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
crates/hir_ty/src/lower.rs
crates/hir_ty/src/traits/chalk/interner.rs

index 503910dde28bd90544bddfbda2ee303b80cb4b87..8503852802aa7502db2d39d16394e9c88d8938de 100644 (file)
@@ -31,6 +31,7 @@ macro_rules! eprintln {
     GenericDefId, HasModule, LifetimeParamId, Lookup, TraitId, TypeAliasId, TypeParamId,
 };
 use itertools::Itertools;
+use smallvec::SmallVec;
 
 use crate::{
     db::HirDatabase,
@@ -272,7 +273,7 @@ pub fn into_inner(self) -> TyKind {
 
 /// 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 @@ fn walk_mut_binders(
         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 @@ pub fn as_single(&self) -> &Ty {
         &self.0[0]
     }
 
+    pub fn from_iter(_interner: &Interner, elements: impl IntoIterator<Item = Ty>) -> 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 @@ pub fn from_params_and_return(mut params: Vec<Ty>, ret: Ty, is_varargs: bool) ->
 
     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 @@ pub fn fn_ptr(sig: CallableSig) -> Self {
         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)
     }
index b4c650fa1ecc2c4957b54163fc8f1c9b5504d161..6ab757bfcd4ba59657dce61355e2c8f28f80bede 100644 (file)
@@ -31,7 +31,7 @@
     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 @@ fn lower_ty_ext(&self, type_ref: &TypeRef) -> (Ty, Option<TypeNs>) {
         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 @@ pub(crate) fn lower_trait_ref_from_resolved_path(
     ) -> 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 }
     }
index 1dc3f497d484eadfc14bc6e1b26b3c8bcbfb6bb6..94e94a26df41fbfe68359af284d2b7a658511a5c 100644 (file)
@@ -5,6 +5,7 @@
 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<Self>;
     type InternedGoal = Arc<GoalData<Self>>;
     type InternedGoals = Vec<Goal<Self>>;
-    type InternedSubstitution = Vec<GenericArg<Self>>;
+    type InternedSubstitution = SmallVec<[GenericArg<Self>; 2]>;
     type InternedProgramClause = Arc<chalk_ir::ProgramClauseData<Self>>;
     type InternedProgramClauses = Arc<[chalk_ir::ProgramClause<Self>]>;
     type InternedQuantifiedWhereClauses = Vec<chalk_ir::QuantifiedWhereClause<Self>>;
@@ -265,13 +266,13 @@ fn goals_data<'a>(&self, goals: &'a Vec<Goal<Interner>>) -> &'a [Goal<Interner>]
     fn intern_substitution<E>(
         &self,
         data: impl IntoIterator<Item = Result<GenericArg<Self>, E>>,
-    ) -> Result<Vec<GenericArg<Self>>, E> {
+    ) -> Result<Self::InternedSubstitution, E> {
         data.into_iter().collect()
     }
 
     fn substitution_data<'a>(
         &self,
-        substitution: &'a Vec<GenericArg<Self>>,
+        substitution: &'a Self::InternedSubstitution,
     ) -> &'a [GenericArg<Self>] {
         substitution
     }