GenericDefId, HasModule, LifetimeParamId, Lookup, TraitId, TypeAliasId, TypeParamId,
};
use itertools::Itertools;
+use smallvec::SmallVec;
use crate::{
db::HirDatabase,
/// 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)) {
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 {
&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,
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] {
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)
}
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,
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);
) -> 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 }
}
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)]
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>>;
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
}