diff options
author | Florian Diebold <[email protected]> | 2021-03-15 18:13:49 +0000 |
---|---|---|
committer | Florian Diebold <[email protected]> | 2021-03-15 18:48:03 +0000 |
commit | 455e755bb011fff6d1389701063956fbf16daaf1 (patch) | |
tree | 400efb6e39a557454edd99184c005b413ae25af3 | |
parent | 47b74cadf9774f624ff13f8c7929c66be8247fc8 (diff) |
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.
-rw-r--r-- | crates/hir_ty/src/lib.rs | 27 | ||||
-rw-r--r-- | crates/hir_ty/src/lower.rs | 9 | ||||
-rw-r--r-- | 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::{ | |||
31 | GenericDefId, HasModule, LifetimeParamId, Lookup, TraitId, TypeAliasId, TypeParamId, | 31 | GenericDefId, HasModule, LifetimeParamId, Lookup, TraitId, TypeAliasId, TypeParamId, |
32 | }; | 32 | }; |
33 | use itertools::Itertools; | 33 | use itertools::Itertools; |
34 | use smallvec::SmallVec; | ||
34 | 35 | ||
35 | use crate::{ | 36 | use crate::{ |
36 | db::HirDatabase, | 37 | db::HirDatabase, |
@@ -272,7 +273,7 @@ impl Ty { | |||
272 | 273 | ||
273 | /// A list of substitutions for generic parameters. | 274 | /// A list of substitutions for generic parameters. |
274 | #[derive(Clone, PartialEq, Eq, Debug, Hash)] | 275 | #[derive(Clone, PartialEq, Eq, Debug, Hash)] |
275 | pub struct Substs(Arc<[Ty]>); | 276 | pub struct Substs(SmallVec<[Ty; 2]>); |
276 | 277 | ||
277 | impl TypeWalk for Substs { | 278 | impl TypeWalk for Substs { |
278 | fn walk(&self, f: &mut impl FnMut(&Ty)) { | 279 | fn walk(&self, f: &mut impl FnMut(&Ty)) { |
@@ -286,19 +287,27 @@ impl TypeWalk for Substs { | |||
286 | f: &mut impl FnMut(&mut Ty, DebruijnIndex), | 287 | f: &mut impl FnMut(&mut Ty, DebruijnIndex), |
287 | binders: DebruijnIndex, | 288 | binders: DebruijnIndex, |
288 | ) { | 289 | ) { |
289 | for t in make_mut_slice(&mut self.0) { | 290 | for t in &mut self.0 { |
290 | t.walk_mut_binders(f, binders); | 291 | t.walk_mut_binders(f, binders); |
291 | } | 292 | } |
292 | } | 293 | } |
293 | } | 294 | } |
294 | 295 | ||
295 | impl Substs { | 296 | impl Substs { |
297 | pub fn interned(&self, _: &Interner) -> &[Ty] { | ||
298 | &self.0 | ||
299 | } | ||
300 | |||
296 | pub fn empty() -> Substs { | 301 | pub fn empty() -> Substs { |
297 | Substs(Arc::new([])) | 302 | Substs(SmallVec::new()) |
298 | } | 303 | } |
299 | 304 | ||
300 | pub fn single(ty: Ty) -> Substs { | 305 | pub fn single(ty: Ty) -> Substs { |
301 | Substs(Arc::new([ty])) | 306 | Substs({ |
307 | let mut v = SmallVec::new(); | ||
308 | v.push(ty); | ||
309 | v | ||
310 | }) | ||
302 | } | 311 | } |
303 | 312 | ||
304 | pub fn prefix(&self, n: usize) -> Substs { | 313 | pub fn prefix(&self, n: usize) -> Substs { |
@@ -316,6 +325,10 @@ impl Substs { | |||
316 | &self.0[0] | 325 | &self.0[0] |
317 | } | 326 | } |
318 | 327 | ||
328 | pub fn from_iter(_interner: &Interner, elements: impl IntoIterator<Item = Ty>) -> Self { | ||
329 | Substs(elements.into_iter().collect()) | ||
330 | } | ||
331 | |||
319 | /// Return Substs that replace each parameter by itself (i.e. `Ty::Param`). | 332 | /// Return Substs that replace each parameter by itself (i.e. `Ty::Param`). |
320 | pub(crate) fn type_params_for_generics( | 333 | pub(crate) fn type_params_for_generics( |
321 | db: &dyn HirDatabase, | 334 | db: &dyn HirDatabase, |
@@ -600,13 +613,13 @@ impl CallableSig { | |||
600 | 613 | ||
601 | pub fn from_fn_ptr(fn_ptr: &FnPointer) -> CallableSig { | 614 | pub fn from_fn_ptr(fn_ptr: &FnPointer) -> CallableSig { |
602 | CallableSig { | 615 | CallableSig { |
603 | params_and_return: Arc::clone(&fn_ptr.substs.0), | 616 | params_and_return: fn_ptr.substs.interned(&Interner).iter().cloned().collect(), |
604 | is_varargs: fn_ptr.sig.variadic, | 617 | is_varargs: fn_ptr.sig.variadic, |
605 | } | 618 | } |
606 | } | 619 | } |
607 | 620 | ||
608 | pub fn from_substs(substs: &Substs) -> CallableSig { | 621 | pub fn from_substs(substs: &Substs) -> CallableSig { |
609 | CallableSig { params_and_return: Arc::clone(&substs.0), is_varargs: false } | 622 | CallableSig { params_and_return: substs.iter().cloned().collect(), is_varargs: false } |
610 | } | 623 | } |
611 | 624 | ||
612 | pub fn params(&self) -> &[Ty] { | 625 | pub fn params(&self) -> &[Ty] { |
@@ -649,7 +662,7 @@ impl Ty { | |||
649 | TyKind::Function(FnPointer { | 662 | TyKind::Function(FnPointer { |
650 | num_args: sig.params().len(), | 663 | num_args: sig.params().len(), |
651 | sig: FnSig { abi: (), safety: Safety::Safe, variadic: sig.is_varargs }, | 664 | sig: FnSig { abi: (), safety: Safety::Safe, variadic: sig.is_varargs }, |
652 | substs: Substs(sig.params_and_return), | 665 | substs: Substs::from_iter(&Interner, sig.params_and_return.iter().cloned()), |
653 | }) | 666 | }) |
654 | .intern(&Interner) | 667 | .intern(&Interner) |
655 | } | 668 | } |
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::{ | |||
31 | traits::chalk::{Interner, ToChalk}, | 31 | traits::chalk::{Interner, ToChalk}, |
32 | utils::{ | 32 | utils::{ |
33 | all_super_trait_refs, associated_type_by_name_including_super_traits, generics, | 33 | all_super_trait_refs, associated_type_by_name_including_super_traits, generics, |
34 | make_mut_slice, variant_data, | 34 | variant_data, |
35 | }, | 35 | }, |
36 | AliasTy, Binders, BoundVar, CallableSig, DebruijnIndex, FnPointer, FnSig, GenericPredicate, | 36 | AliasTy, Binders, BoundVar, CallableSig, DebruijnIndex, FnPointer, FnSig, GenericPredicate, |
37 | ImplTraitId, OpaqueTy, PolyFnSig, ProjectionPredicate, ProjectionTy, ReturnTypeImplTrait, | 37 | ImplTraitId, OpaqueTy, PolyFnSig, ProjectionPredicate, ProjectionTy, ReturnTypeImplTrait, |
@@ -150,8 +150,9 @@ impl<'a> TyLoweringContext<'a> { | |||
150 | let ty = match type_ref { | 150 | let ty = match type_ref { |
151 | TypeRef::Never => TyKind::Never.intern(&Interner), | 151 | TypeRef::Never => TyKind::Never.intern(&Interner), |
152 | TypeRef::Tuple(inner) => { | 152 | TypeRef::Tuple(inner) => { |
153 | let inner_tys: Arc<[Ty]> = inner.iter().map(|tr| self.lower_ty(tr)).collect(); | 153 | let inner_tys = inner.iter().map(|tr| self.lower_ty(tr)); |
154 | TyKind::Tuple(inner_tys.len(), Substs(inner_tys)).intern(&Interner) | 154 | TyKind::Tuple(inner_tys.len(), Substs::from_iter(&Interner, inner_tys)) |
155 | .intern(&Interner) | ||
155 | } | 156 | } |
156 | TypeRef::Path(path) => { | 157 | TypeRef::Path(path) => { |
157 | let (ty, res_) = self.lower_path(path); | 158 | let (ty, res_) = self.lower_path(path); |
@@ -638,7 +639,7 @@ impl<'a> TyLoweringContext<'a> { | |||
638 | ) -> TraitRef { | 639 | ) -> TraitRef { |
639 | let mut substs = self.trait_ref_substs_from_path(segment, resolved); | 640 | let mut substs = self.trait_ref_substs_from_path(segment, resolved); |
640 | if let Some(self_ty) = explicit_self_ty { | 641 | if let Some(self_ty) = explicit_self_ty { |
641 | make_mut_slice(&mut substs.0)[0] = self_ty; | 642 | substs.0[0] = self_ty; |
642 | } | 643 | } |
643 | TraitRef { trait_: resolved, substs } | 644 | TraitRef { trait_: resolved, substs } |
644 | } | 645 | } |
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; | |||
5 | use base_db::salsa::InternId; | 5 | use base_db::salsa::InternId; |
6 | use chalk_ir::{GenericArg, Goal, GoalData}; | 6 | use chalk_ir::{GenericArg, Goal, GoalData}; |
7 | use hir_def::TypeAliasId; | 7 | use hir_def::TypeAliasId; |
8 | use smallvec::SmallVec; | ||
8 | use std::{fmt, sync::Arc}; | 9 | use std::{fmt, sync::Arc}; |
9 | 10 | ||
10 | #[derive(Debug, Copy, Clone, Hash, PartialOrd, Ord, PartialEq, Eq)] | 11 | #[derive(Debug, Copy, Clone, Hash, PartialOrd, Ord, PartialEq, Eq)] |
@@ -33,7 +34,7 @@ impl chalk_ir::interner::Interner for Interner { | |||
33 | type InternedGenericArg = chalk_ir::GenericArgData<Self>; | 34 | type InternedGenericArg = chalk_ir::GenericArgData<Self>; |
34 | type InternedGoal = Arc<GoalData<Self>>; | 35 | type InternedGoal = Arc<GoalData<Self>>; |
35 | type InternedGoals = Vec<Goal<Self>>; | 36 | type InternedGoals = Vec<Goal<Self>>; |
36 | type InternedSubstitution = Vec<GenericArg<Self>>; | 37 | type InternedSubstitution = SmallVec<[GenericArg<Self>; 2]>; |
37 | type InternedProgramClause = Arc<chalk_ir::ProgramClauseData<Self>>; | 38 | type InternedProgramClause = Arc<chalk_ir::ProgramClauseData<Self>>; |
38 | type InternedProgramClauses = Arc<[chalk_ir::ProgramClause<Self>]>; | 39 | type InternedProgramClauses = Arc<[chalk_ir::ProgramClause<Self>]>; |
39 | type InternedQuantifiedWhereClauses = Vec<chalk_ir::QuantifiedWhereClause<Self>>; | 40 | type InternedQuantifiedWhereClauses = Vec<chalk_ir::QuantifiedWhereClause<Self>>; |
@@ -265,13 +266,13 @@ impl chalk_ir::interner::Interner for Interner { | |||
265 | fn intern_substitution<E>( | 266 | fn intern_substitution<E>( |
266 | &self, | 267 | &self, |
267 | data: impl IntoIterator<Item = Result<GenericArg<Self>, E>>, | 268 | data: impl IntoIterator<Item = Result<GenericArg<Self>, E>>, |
268 | ) -> Result<Vec<GenericArg<Self>>, E> { | 269 | ) -> Result<Self::InternedSubstitution, E> { |
269 | data.into_iter().collect() | 270 | data.into_iter().collect() |
270 | } | 271 | } |
271 | 272 | ||
272 | fn substitution_data<'a>( | 273 | fn substitution_data<'a>( |
273 | &self, | 274 | &self, |
274 | substitution: &'a Vec<GenericArg<Self>>, | 275 | substitution: &'a Self::InternedSubstitution, |
275 | ) -> &'a [GenericArg<Self>] { | 276 | ) -> &'a [GenericArg<Self>] { |
276 | substitution | 277 | substitution |
277 | } | 278 | } |