Skip to content

Commit be03db0

Browse files
committed
Intern Substitutions
(Costs a bit of performance, reduces memory usage on RA by ~10%.)
1 parent a169fa6 commit be03db0

File tree

8 files changed

+34
-27
lines changed

8 files changed

+34
-27
lines changed

crates/hir/src/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1825,7 +1825,7 @@ impl Type {
18251825
Solution::Unique(s) => s
18261826
.value
18271827
.subst
1828-
.interned()
1828+
.as_slice(&Interner)
18291829
.first()
18301830
.map(|ty| self.derived(ty.assert_ty_ref(&Interner).clone())),
18311831
Solution::Ambig(_) => None,

crates/hir_ty/src/display.rs

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -265,7 +265,7 @@ impl HirDisplay for ProjectionTy {
265265
write!(f, " as {}", trait_.name)?;
266266
if self.substitution.len(&Interner) > 1 {
267267
write!(f, "<")?;
268-
f.write_joined(&self.substitution.interned()[1..], ", ")?;
268+
f.write_joined(&self.substitution.as_slice(&Interner)[1..], ", ")?;
269269
write!(f, ">")?;
270270
}
271271
write!(f, ">::{}", f.db.type_alias_data(from_assoc_type_id(self.associated_ty_id)).name)?;
@@ -416,7 +416,7 @@ impl HirDisplay for Ty {
416416
write!(f, ",)")?;
417417
} else {
418418
write!(f, "(")?;
419-
f.write_joined(&*substs.interned(), ", ")?;
419+
f.write_joined(&*substs.as_slice(&Interner), ", ")?;
420420
write!(f, ")")?;
421421
}
422422
}
@@ -444,7 +444,7 @@ impl HirDisplay for Ty {
444444
// We print all params except implicit impl Trait params. Still a bit weird; should we leave out parent and self?
445445
if total_len > 0 {
446446
write!(f, "<")?;
447-
f.write_joined(&parameters.interned()[..total_len], ", ")?;
447+
f.write_joined(&parameters.as_slice(&Interner)[..total_len], ", ")?;
448448
write!(f, ">")?;
449449
}
450450
}
@@ -491,7 +491,7 @@ impl HirDisplay for Ty {
491491
.map(|generic_def_id| f.db.generic_defaults(generic_def_id))
492492
.filter(|defaults| !defaults.is_empty())
493493
{
494-
None => parameters.interned().as_ref(),
494+
None => parameters.as_slice(&Interner),
495495
Some(default_parameters) => {
496496
let mut default_from = 0;
497497
for (i, parameter) in parameters.iter(&Interner).enumerate() {
@@ -515,11 +515,11 @@ impl HirDisplay for Ty {
515515
}
516516
}
517517
}
518-
&parameters.interned()[0..default_from]
518+
&parameters.as_slice(&Interner)[0..default_from]
519519
}
520520
}
521521
} else {
522-
parameters.interned().as_ref()
522+
parameters.as_slice(&Interner)
523523
};
524524
if !parameters_to_write.is_empty() {
525525
write!(f, "<")?;
@@ -542,7 +542,7 @@ impl HirDisplay for Ty {
542542
write!(f, "{}::{}", trait_.name, type_alias_data.name)?;
543543
if parameters.len(&Interner) > 0 {
544544
write!(f, "<")?;
545-
f.write_joined(&*parameters.interned(), ", ")?;
545+
f.write_joined(&*parameters.as_slice(&Interner), ", ")?;
546546
write!(f, ">")?;
547547
}
548548
} else {
@@ -749,13 +749,13 @@ fn write_bounds_like_dyn_trait(
749749
// existential) here, which is the only thing that's
750750
// possible in actual Rust, and hence don't print it
751751
write!(f, "{}", f.db.trait_data(trait_).name)?;
752-
if let [_, params @ ..] = &*trait_ref.substitution.interned().as_slice() {
752+
if let [_, params @ ..] = &*trait_ref.substitution.as_slice(&Interner) {
753753
if is_fn_trait {
754754
if let Some(args) =
755755
params.first().and_then(|it| it.assert_ty_ref(&Interner).as_tuple())
756756
{
757757
write!(f, "(")?;
758-
f.write_joined(&*args.interned(), ", ")?;
758+
f.write_joined(args.as_slice(&Interner), ", ")?;
759759
write!(f, ")")?;
760760
}
761761
} else if !params.is_empty() {
@@ -814,7 +814,7 @@ fn fmt_trait_ref(tr: &TraitRef, f: &mut HirFormatter, use_as: bool) -> Result<()
814814
write!(f, "{}", f.db.trait_data(tr.hir_trait_id()).name)?;
815815
if tr.substitution.len(&Interner) > 1 {
816816
write!(f, "<")?;
817-
f.write_joined(&tr.substitution.interned()[1..], ", ")?;
817+
f.write_joined(&tr.substitution.as_slice(&Interner)[1..], ", ")?;
818818
write!(f, ">")?;
819819
}
820820
Ok(())

crates/hir_ty/src/infer/expr.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -462,7 +462,7 @@ impl<'a> InferenceContext<'a> {
462462
};
463463
match canonicalized.decanonicalize_ty(derefed_ty.value).kind(&Interner) {
464464
TyKind::Tuple(_, substs) => name.as_tuple_index().and_then(|idx| {
465-
substs.interned().get(idx).map(|a| a.assert_ty_ref(&Interner)).cloned()
465+
substs.as_slice(&Interner).get(idx).map(|a| a.assert_ty_ref(&Interner)).cloned()
466466
}),
467467
TyKind::Adt(AdtId(hir_def::AdtId::StructId(s)), parameters) => {
468468
let local_id = self.db.struct_data(*s).variant_data.field(name)?;

crates/hir_ty/src/infer/pat.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -122,7 +122,7 @@ impl<'a> InferenceContext<'a> {
122122
let ty = match &body[pat] {
123123
&Pat::Tuple { ref args, ellipsis } => {
124124
let expectations = match expected.as_tuple() {
125-
Some(parameters) => &*parameters.interned().as_slice(),
125+
Some(parameters) => &*parameters.as_slice(&Interner),
126126
_ => &[],
127127
};
128128

@@ -242,7 +242,7 @@ impl<'a> InferenceContext<'a> {
242242
let (inner_ty, alloc_ty) = match expected.as_adt() {
243243
Some((adt, subst)) if adt == box_adt => (
244244
subst.at(&Interner, 0).assert_ty_ref(&Interner).clone(),
245-
subst.interned().get(1).and_then(|a| a.ty(&Interner).cloned()),
245+
subst.as_slice(&Interner).get(1).and_then(|a| a.ty(&Interner).cloned()),
246246
),
247247
_ => (self.result.standard_types.unknown.clone(), None),
248248
};

crates/hir_ty/src/infer/path.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,7 @@ impl<'a> InferenceContext<'a> {
101101
let substs = ctx.substs_from_path(path, typable, true);
102102
let ty = TyBuilder::value_ty(self.db, typable)
103103
.use_parent_substs(&parent_substs)
104-
.fill(substs.interned()[parent_substs.len(&Interner)..].iter().cloned())
104+
.fill(substs.as_slice(&Interner)[parent_substs.len(&Interner)..].iter().cloned())
105105
.build();
106106
Some(ty)
107107
}

crates/hir_ty/src/lib.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -109,7 +109,7 @@ pub type WhereClause = chalk_ir::WhereClause<Interner>;
109109
pub fn subst_prefix(s: &Substitution, n: usize) -> Substitution {
110110
Substitution::from_iter(
111111
&Interner,
112-
s.interned()[..std::cmp::min(s.len(&Interner), n)].iter().cloned(),
112+
s.as_slice(&Interner)[..std::cmp::min(s.len(&Interner), n)].iter().cloned(),
113113
)
114114
}
115115

@@ -187,7 +187,7 @@ impl CallableSig {
187187
.shifted_out_to(&Interner, DebruijnIndex::ONE)
188188
.expect("unexpected lifetime vars in fn ptr")
189189
.0
190-
.interned()
190+
.as_slice(&Interner)
191191
.iter()
192192
.map(|arg| arg.assert_ty_ref(&Interner).clone())
193193
.collect(),

crates/hir_ty/src/traits/chalk/interner.rs

Lines changed: 15 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,12 @@
33
44
use super::tls;
55
use base_db::salsa::InternId;
6-
use chalk_ir::{GenericArg, Goal, GoalData};
6+
use chalk_ir::{Goal, GoalData};
77
use hir_def::{
88
intern::{impl_internable, InternStorage, Internable, Interned},
99
TypeAliasId,
1010
};
11+
use crate::GenericArg;
1112
use smallvec::SmallVec;
1213
use std::{fmt, sync::Arc};
1314

@@ -32,7 +33,13 @@ pub(crate) type Variances = chalk_ir::Variances<Interner>;
3233
#[derive(PartialEq, Eq, Hash, Debug)]
3334
pub struct InternedVariableKindsInner(Vec<chalk_ir::VariableKind<Interner>>);
3435

35-
impl_internable!(InternedVariableKindsInner,);
36+
#[derive(PartialEq, Eq, Hash, Debug)]
37+
pub struct InternedSubstitutionInner(SmallVec<[GenericArg; 2]>);
38+
39+
impl_internable!(
40+
InternedVariableKindsInner,
41+
InternedSubstitutionInner,
42+
);
3643

3744
impl chalk_ir::interner::Interner for Interner {
3845
type InternedType = Arc<chalk_ir::TyData<Self>>;
@@ -42,7 +49,7 @@ impl chalk_ir::interner::Interner for Interner {
4249
type InternedGenericArg = chalk_ir::GenericArgData<Self>;
4350
type InternedGoal = Arc<GoalData<Self>>;
4451
type InternedGoals = Vec<Goal<Self>>;
45-
type InternedSubstitution = SmallVec<[GenericArg<Self>; 2]>;
52+
type InternedSubstitution = Interned<InternedSubstitutionInner>;
4653
type InternedProgramClause = Arc<chalk_ir::ProgramClauseData<Self>>;
4754
type InternedProgramClauses = Arc<[chalk_ir::ProgramClause<Self>]>;
4855
type InternedQuantifiedWhereClauses = Vec<chalk_ir::QuantifiedWhereClause<Self>>;
@@ -107,7 +114,7 @@ impl chalk_ir::interner::Interner for Interner {
107114
}
108115

109116
fn debug_generic_arg(
110-
parameter: &GenericArg<Interner>,
117+
parameter: &GenericArg,
111118
fmt: &mut fmt::Formatter<'_>,
112119
) -> Option<fmt::Result> {
113120
tls::with_current_program(|prog| Some(prog?.debug_generic_arg(parameter, fmt)))
@@ -272,16 +279,16 @@ impl chalk_ir::interner::Interner for Interner {
272279

273280
fn intern_substitution<E>(
274281
&self,
275-
data: impl IntoIterator<Item = Result<GenericArg<Self>, E>>,
282+
data: impl IntoIterator<Item = Result<GenericArg, E>>,
276283
) -> Result<Self::InternedSubstitution, E> {
277-
data.into_iter().collect()
284+
Ok(Interned::new(InternedSubstitutionInner(data.into_iter().collect::<Result<SmallVec<_>, _>>()?)))
278285
}
279286

280287
fn substitution_data<'a>(
281288
&self,
282289
substitution: &'a Self::InternedSubstitution,
283-
) -> &'a [GenericArg<Self>] {
284-
substitution
290+
) -> &'a [GenericArg] {
291+
&substitution.as_ref().0
285292
}
286293

287294
fn intern_program_clause(

crates/hir_ty/src/traits/chalk/mapping.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,7 @@ pub(super) fn generic_predicate_to_inline_bound(
9999
// have the expected self type
100100
return None;
101101
}
102-
let args_no_self = trait_ref.substitution.interned()[1..]
102+
let args_no_self = trait_ref.substitution.as_slice(&Interner)[1..]
103103
.iter()
104104
.map(|ty| ty.clone().cast(&Interner))
105105
.collect();
@@ -111,7 +111,7 @@ pub(super) fn generic_predicate_to_inline_bound(
111111
return None;
112112
}
113113
let trait_ = projection_ty.trait_(db);
114-
let args_no_self = projection_ty.substitution.interned()[1..]
114+
let args_no_self = projection_ty.substitution.as_slice(&Interner)[1..]
115115
.iter()
116116
.map(|ty| ty.clone().cast(&Interner))
117117
.collect();

0 commit comments

Comments
 (0)