8039: Use SmallVec for Substs r=flodiebold a=flodiebold

Doesn't help as much as I hoped, but it helps a bit and I also did some
refactorings that were necessary anyway.

Co-authored-by: Florian Diebold <flodiebold@gmail.com>
This commit is contained in:
bors[bot] 2021-03-15 18:49:07 +00:00 committed by GitHub
commit c0a2b4e826
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 29 additions and 14 deletions

View File

@ -31,6 +31,7 @@ use hir_def::{
GenericDefId, HasModule, LifetimeParamId, Lookup, TraitId, TypeAliasId, TypeParamId, GenericDefId, HasModule, LifetimeParamId, Lookup, TraitId, TypeAliasId, TypeParamId,
}; };
use itertools::Itertools; use itertools::Itertools;
use smallvec::SmallVec;
use crate::{ use crate::{
db::HirDatabase, db::HirDatabase,
@ -272,7 +273,7 @@ impl Ty {
/// A list of substitutions for generic parameters. /// A list of substitutions for generic parameters.
#[derive(Clone, PartialEq, Eq, Debug, Hash)] #[derive(Clone, PartialEq, Eq, Debug, Hash)]
pub struct Substs(Arc<[Ty]>); pub struct Substs(SmallVec<[Ty; 2]>);
impl TypeWalk for Substs { impl TypeWalk for Substs {
fn walk(&self, f: &mut impl FnMut(&Ty)) { fn walk(&self, f: &mut impl FnMut(&Ty)) {
@ -286,19 +287,27 @@ impl TypeWalk for Substs {
f: &mut impl FnMut(&mut Ty, DebruijnIndex), f: &mut impl FnMut(&mut Ty, DebruijnIndex),
binders: DebruijnIndex, binders: DebruijnIndex,
) { ) {
for t in make_mut_slice(&mut self.0) { for t in &mut self.0 {
t.walk_mut_binders(f, binders); t.walk_mut_binders(f, binders);
} }
} }
} }
impl Substs { impl Substs {
pub fn interned(&self, _: &Interner) -> &[Ty] {
&self.0
}
pub fn empty() -> Substs { pub fn empty() -> Substs {
Substs(Arc::new([])) Substs(SmallVec::new())
} }
pub fn single(ty: Ty) -> Substs { 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 { pub fn prefix(&self, n: usize) -> Substs {
@ -316,6 +325,10 @@ impl Substs {
&self.0[0] &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`). /// Return Substs that replace each parameter by itself (i.e. `Ty::Param`).
pub(crate) fn type_params_for_generics( pub(crate) fn type_params_for_generics(
db: &dyn HirDatabase, db: &dyn HirDatabase,
@ -600,13 +613,13 @@ impl CallableSig {
pub fn from_fn_ptr(fn_ptr: &FnPointer) -> CallableSig { pub fn from_fn_ptr(fn_ptr: &FnPointer) -> CallableSig {
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, is_varargs: fn_ptr.sig.variadic,
} }
} }
pub fn from_substs(substs: &Substs) -> CallableSig { 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] { pub fn params(&self) -> &[Ty] {
@ -649,7 +662,7 @@ impl Ty {
TyKind::Function(FnPointer { TyKind::Function(FnPointer {
num_args: sig.params().len(), num_args: sig.params().len(),
sig: FnSig { abi: (), safety: Safety::Safe, variadic: sig.is_varargs }, 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) .intern(&Interner)
} }

View File

@ -31,7 +31,7 @@ use crate::{
traits::chalk::{Interner, ToChalk}, traits::chalk::{Interner, ToChalk},
utils::{ utils::{
all_super_trait_refs, associated_type_by_name_including_super_traits, generics, 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, AliasTy, Binders, BoundVar, CallableSig, DebruijnIndex, FnPointer, FnSig, GenericPredicate,
ImplTraitId, OpaqueTy, PolyFnSig, ProjectionPredicate, ProjectionTy, ReturnTypeImplTrait, ImplTraitId, OpaqueTy, PolyFnSig, ProjectionPredicate, ProjectionTy, ReturnTypeImplTrait,
@ -150,8 +150,9 @@ impl<'a> TyLoweringContext<'a> {
let ty = match type_ref { let ty = match type_ref {
TypeRef::Never => TyKind::Never.intern(&Interner), TypeRef::Never => TyKind::Never.intern(&Interner),
TypeRef::Tuple(inner) => { TypeRef::Tuple(inner) => {
let inner_tys: Arc<[Ty]> = inner.iter().map(|tr| self.lower_ty(tr)).collect(); let inner_tys = inner.iter().map(|tr| self.lower_ty(tr));
TyKind::Tuple(inner_tys.len(), Substs(inner_tys)).intern(&Interner) TyKind::Tuple(inner_tys.len(), Substs::from_iter(&Interner, inner_tys))
.intern(&Interner)
} }
TypeRef::Path(path) => { TypeRef::Path(path) => {
let (ty, res_) = self.lower_path(path); let (ty, res_) = self.lower_path(path);
@ -638,7 +639,7 @@ impl<'a> TyLoweringContext<'a> {
) -> TraitRef { ) -> TraitRef {
let mut substs = self.trait_ref_substs_from_path(segment, resolved); let mut substs = self.trait_ref_substs_from_path(segment, resolved);
if let Some(self_ty) = explicit_self_ty { 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 } TraitRef { trait_: resolved, substs }
} }

View File

@ -5,6 +5,7 @@ use super::tls;
use base_db::salsa::InternId; use base_db::salsa::InternId;
use chalk_ir::{GenericArg, Goal, GoalData}; use chalk_ir::{GenericArg, Goal, GoalData};
use hir_def::TypeAliasId; use hir_def::TypeAliasId;
use smallvec::SmallVec;
use std::{fmt, sync::Arc}; use std::{fmt, sync::Arc};
#[derive(Debug, Copy, Clone, Hash, PartialOrd, Ord, PartialEq, Eq)] #[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 InternedGenericArg = chalk_ir::GenericArgData<Self>;
type InternedGoal = Arc<GoalData<Self>>; type InternedGoal = Arc<GoalData<Self>>;
type InternedGoals = Vec<Goal<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 InternedProgramClause = Arc<chalk_ir::ProgramClauseData<Self>>;
type InternedProgramClauses = Arc<[chalk_ir::ProgramClause<Self>]>; type InternedProgramClauses = Arc<[chalk_ir::ProgramClause<Self>]>;
type InternedQuantifiedWhereClauses = Vec<chalk_ir::QuantifiedWhereClause<Self>>; type InternedQuantifiedWhereClauses = Vec<chalk_ir::QuantifiedWhereClause<Self>>;
@ -265,13 +266,13 @@ impl chalk_ir::interner::Interner for Interner {
fn intern_substitution<E>( fn intern_substitution<E>(
&self, &self,
data: impl IntoIterator<Item = Result<GenericArg<Self>, E>>, data: impl IntoIterator<Item = Result<GenericArg<Self>, E>>,
) -> Result<Vec<GenericArg<Self>>, E> { ) -> Result<Self::InternedSubstitution, E> {
data.into_iter().collect() data.into_iter().collect()
} }
fn substitution_data<'a>( fn substitution_data<'a>(
&self, &self,
substitution: &'a Vec<GenericArg<Self>>, substitution: &'a Self::InternedSubstitution,
) -> &'a [GenericArg<Self>] { ) -> &'a [GenericArg<Self>] {
substitution substitution
} }