diff options
author | Florian Diebold <[email protected]> | 2021-04-08 17:25:18 +0100 |
---|---|---|
committer | Florian Diebold <[email protected]> | 2021-04-08 21:48:47 +0100 |
commit | be03db0e3a75533f34d48c3014d532919b30a9e9 (patch) | |
tree | 3742a817b8238043a3a855d92532c7342815210e /crates | |
parent | a169fa6a832a513cd1534d1a6566e4584ca5fb6a (diff) |
Intern Substitutions
(Costs a bit of performance, reduces memory usage on RA by ~10%.)
Diffstat (limited to 'crates')
-rw-r--r-- | crates/hir/src/lib.rs | 2 | ||||
-rw-r--r-- | crates/hir_ty/src/display.rs | 20 | ||||
-rw-r--r-- | crates/hir_ty/src/infer/expr.rs | 2 | ||||
-rw-r--r-- | crates/hir_ty/src/infer/pat.rs | 4 | ||||
-rw-r--r-- | crates/hir_ty/src/infer/path.rs | 2 | ||||
-rw-r--r-- | crates/hir_ty/src/lib.rs | 4 | ||||
-rw-r--r-- | crates/hir_ty/src/traits/chalk/interner.rs | 23 | ||||
-rw-r--r-- | crates/hir_ty/src/traits/chalk/mapping.rs | 4 |
8 files changed, 34 insertions, 27 deletions
diff --git a/crates/hir/src/lib.rs b/crates/hir/src/lib.rs index 817a01db1..04875240b 100644 --- a/crates/hir/src/lib.rs +++ b/crates/hir/src/lib.rs | |||
@@ -1825,7 +1825,7 @@ impl Type { | |||
1825 | Solution::Unique(s) => s | 1825 | Solution::Unique(s) => s |
1826 | .value | 1826 | .value |
1827 | .subst | 1827 | .subst |
1828 | .interned() | 1828 | .as_slice(&Interner) |
1829 | .first() | 1829 | .first() |
1830 | .map(|ty| self.derived(ty.assert_ty_ref(&Interner).clone())), | 1830 | .map(|ty| self.derived(ty.assert_ty_ref(&Interner).clone())), |
1831 | Solution::Ambig(_) => None, | 1831 | Solution::Ambig(_) => None, |
diff --git a/crates/hir_ty/src/display.rs b/crates/hir_ty/src/display.rs index d7a3977e5..92224b46b 100644 --- a/crates/hir_ty/src/display.rs +++ b/crates/hir_ty/src/display.rs | |||
@@ -265,7 +265,7 @@ impl HirDisplay for ProjectionTy { | |||
265 | write!(f, " as {}", trait_.name)?; | 265 | write!(f, " as {}", trait_.name)?; |
266 | if self.substitution.len(&Interner) > 1 { | 266 | if self.substitution.len(&Interner) > 1 { |
267 | write!(f, "<")?; | 267 | write!(f, "<")?; |
268 | f.write_joined(&self.substitution.interned()[1..], ", ")?; | 268 | f.write_joined(&self.substitution.as_slice(&Interner)[1..], ", ")?; |
269 | write!(f, ">")?; | 269 | write!(f, ">")?; |
270 | } | 270 | } |
271 | write!(f, ">::{}", f.db.type_alias_data(from_assoc_type_id(self.associated_ty_id)).name)?; | 271 | write!(f, ">::{}", f.db.type_alias_data(from_assoc_type_id(self.associated_ty_id)).name)?; |
@@ -416,7 +416,7 @@ impl HirDisplay for Ty { | |||
416 | write!(f, ",)")?; | 416 | write!(f, ",)")?; |
417 | } else { | 417 | } else { |
418 | write!(f, "(")?; | 418 | write!(f, "(")?; |
419 | f.write_joined(&*substs.interned(), ", ")?; | 419 | f.write_joined(&*substs.as_slice(&Interner), ", ")?; |
420 | write!(f, ")")?; | 420 | write!(f, ")")?; |
421 | } | 421 | } |
422 | } | 422 | } |
@@ -444,7 +444,7 @@ impl HirDisplay for Ty { | |||
444 | // We print all params except implicit impl Trait params. Still a bit weird; should we leave out parent and self? | 444 | // We print all params except implicit impl Trait params. Still a bit weird; should we leave out parent and self? |
445 | if total_len > 0 { | 445 | if total_len > 0 { |
446 | write!(f, "<")?; | 446 | write!(f, "<")?; |
447 | f.write_joined(¶meters.interned()[..total_len], ", ")?; | 447 | f.write_joined(¶meters.as_slice(&Interner)[..total_len], ", ")?; |
448 | write!(f, ">")?; | 448 | write!(f, ">")?; |
449 | } | 449 | } |
450 | } | 450 | } |
@@ -491,7 +491,7 @@ impl HirDisplay for Ty { | |||
491 | .map(|generic_def_id| f.db.generic_defaults(generic_def_id)) | 491 | .map(|generic_def_id| f.db.generic_defaults(generic_def_id)) |
492 | .filter(|defaults| !defaults.is_empty()) | 492 | .filter(|defaults| !defaults.is_empty()) |
493 | { | 493 | { |
494 | None => parameters.interned().as_ref(), | 494 | None => parameters.as_slice(&Interner), |
495 | Some(default_parameters) => { | 495 | Some(default_parameters) => { |
496 | let mut default_from = 0; | 496 | let mut default_from = 0; |
497 | for (i, parameter) in parameters.iter(&Interner).enumerate() { | 497 | for (i, parameter) in parameters.iter(&Interner).enumerate() { |
@@ -515,11 +515,11 @@ impl HirDisplay for Ty { | |||
515 | } | 515 | } |
516 | } | 516 | } |
517 | } | 517 | } |
518 | ¶meters.interned()[0..default_from] | 518 | ¶meters.as_slice(&Interner)[0..default_from] |
519 | } | 519 | } |
520 | } | 520 | } |
521 | } else { | 521 | } else { |
522 | parameters.interned().as_ref() | 522 | parameters.as_slice(&Interner) |
523 | }; | 523 | }; |
524 | if !parameters_to_write.is_empty() { | 524 | if !parameters_to_write.is_empty() { |
525 | write!(f, "<")?; | 525 | write!(f, "<")?; |
@@ -542,7 +542,7 @@ impl HirDisplay for Ty { | |||
542 | write!(f, "{}::{}", trait_.name, type_alias_data.name)?; | 542 | write!(f, "{}::{}", trait_.name, type_alias_data.name)?; |
543 | if parameters.len(&Interner) > 0 { | 543 | if parameters.len(&Interner) > 0 { |
544 | write!(f, "<")?; | 544 | write!(f, "<")?; |
545 | f.write_joined(&*parameters.interned(), ", ")?; | 545 | f.write_joined(&*parameters.as_slice(&Interner), ", ")?; |
546 | write!(f, ">")?; | 546 | write!(f, ">")?; |
547 | } | 547 | } |
548 | } else { | 548 | } else { |
@@ -749,13 +749,13 @@ fn write_bounds_like_dyn_trait( | |||
749 | // existential) here, which is the only thing that's | 749 | // existential) here, which is the only thing that's |
750 | // possible in actual Rust, and hence don't print it | 750 | // possible in actual Rust, and hence don't print it |
751 | write!(f, "{}", f.db.trait_data(trait_).name)?; | 751 | 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) { |
753 | if is_fn_trait { | 753 | if is_fn_trait { |
754 | if let Some(args) = | 754 | if let Some(args) = |
755 | params.first().and_then(|it| it.assert_ty_ref(&Interner).as_tuple()) | 755 | params.first().and_then(|it| it.assert_ty_ref(&Interner).as_tuple()) |
756 | { | 756 | { |
757 | write!(f, "(")?; | 757 | write!(f, "(")?; |
758 | f.write_joined(&*args.interned(), ", ")?; | 758 | f.write_joined(args.as_slice(&Interner), ", ")?; |
759 | write!(f, ")")?; | 759 | write!(f, ")")?; |
760 | } | 760 | } |
761 | } else if !params.is_empty() { | 761 | } else if !params.is_empty() { |
@@ -814,7 +814,7 @@ fn fmt_trait_ref(tr: &TraitRef, f: &mut HirFormatter, use_as: bool) -> Result<() | |||
814 | write!(f, "{}", f.db.trait_data(tr.hir_trait_id()).name)?; | 814 | write!(f, "{}", f.db.trait_data(tr.hir_trait_id()).name)?; |
815 | if tr.substitution.len(&Interner) > 1 { | 815 | if tr.substitution.len(&Interner) > 1 { |
816 | write!(f, "<")?; | 816 | write!(f, "<")?; |
817 | f.write_joined(&tr.substitution.interned()[1..], ", ")?; | 817 | f.write_joined(&tr.substitution.as_slice(&Interner)[1..], ", ")?; |
818 | write!(f, ">")?; | 818 | write!(f, ">")?; |
819 | } | 819 | } |
820 | Ok(()) | 820 | Ok(()) |
diff --git a/crates/hir_ty/src/infer/expr.rs b/crates/hir_ty/src/infer/expr.rs index cbbfa8b5c..ee6763926 100644 --- a/crates/hir_ty/src/infer/expr.rs +++ b/crates/hir_ty/src/infer/expr.rs | |||
@@ -462,7 +462,7 @@ impl<'a> InferenceContext<'a> { | |||
462 | }; | 462 | }; |
463 | match canonicalized.decanonicalize_ty(derefed_ty.value).kind(&Interner) { | 463 | match canonicalized.decanonicalize_ty(derefed_ty.value).kind(&Interner) { |
464 | TyKind::Tuple(_, substs) => name.as_tuple_index().and_then(|idx| { | 464 | 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() |
466 | }), | 466 | }), |
467 | TyKind::Adt(AdtId(hir_def::AdtId::StructId(s)), parameters) => { | 467 | TyKind::Adt(AdtId(hir_def::AdtId::StructId(s)), parameters) => { |
468 | let local_id = self.db.struct_data(*s).variant_data.field(name)?; | 468 | let local_id = self.db.struct_data(*s).variant_data.field(name)?; |
diff --git a/crates/hir_ty/src/infer/pat.rs b/crates/hir_ty/src/infer/pat.rs index a41e8e116..aea354cde 100644 --- a/crates/hir_ty/src/infer/pat.rs +++ b/crates/hir_ty/src/infer/pat.rs | |||
@@ -122,7 +122,7 @@ impl<'a> InferenceContext<'a> { | |||
122 | let ty = match &body[pat] { | 122 | let ty = match &body[pat] { |
123 | &Pat::Tuple { ref args, ellipsis } => { | 123 | &Pat::Tuple { ref args, ellipsis } => { |
124 | let expectations = match expected.as_tuple() { | 124 | let expectations = match expected.as_tuple() { |
125 | Some(parameters) => &*parameters.interned().as_slice(), | 125 | Some(parameters) => &*parameters.as_slice(&Interner), |
126 | _ => &[], | 126 | _ => &[], |
127 | }; | 127 | }; |
128 | 128 | ||
@@ -242,7 +242,7 @@ impl<'a> InferenceContext<'a> { | |||
242 | let (inner_ty, alloc_ty) = match expected.as_adt() { | 242 | let (inner_ty, alloc_ty) = match expected.as_adt() { |
243 | Some((adt, subst)) if adt == box_adt => ( | 243 | Some((adt, subst)) if adt == box_adt => ( |
244 | subst.at(&Interner, 0).assert_ty_ref(&Interner).clone(), | 244 | 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()), |
246 | ), | 246 | ), |
247 | _ => (self.result.standard_types.unknown.clone(), None), | 247 | _ => (self.result.standard_types.unknown.clone(), None), |
248 | }; | 248 | }; |
diff --git a/crates/hir_ty/src/infer/path.rs b/crates/hir_ty/src/infer/path.rs index f8955aa32..495282eba 100644 --- a/crates/hir_ty/src/infer/path.rs +++ b/crates/hir_ty/src/infer/path.rs | |||
@@ -101,7 +101,7 @@ impl<'a> InferenceContext<'a> { | |||
101 | let substs = ctx.substs_from_path(path, typable, true); | 101 | let substs = ctx.substs_from_path(path, typable, true); |
102 | let ty = TyBuilder::value_ty(self.db, typable) | 102 | let ty = TyBuilder::value_ty(self.db, typable) |
103 | .use_parent_substs(&parent_substs) | 103 | .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()) |
105 | .build(); | 105 | .build(); |
106 | Some(ty) | 106 | Some(ty) |
107 | } | 107 | } |
diff --git a/crates/hir_ty/src/lib.rs b/crates/hir_ty/src/lib.rs index 874c95411..beb58d711 100644 --- a/crates/hir_ty/src/lib.rs +++ b/crates/hir_ty/src/lib.rs | |||
@@ -109,7 +109,7 @@ pub type WhereClause = chalk_ir::WhereClause<Interner>; | |||
109 | pub fn subst_prefix(s: &Substitution, n: usize) -> Substitution { | 109 | pub fn subst_prefix(s: &Substitution, n: usize) -> Substitution { |
110 | Substitution::from_iter( | 110 | Substitution::from_iter( |
111 | &Interner, | 111 | &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(), |
113 | ) | 113 | ) |
114 | } | 114 | } |
115 | 115 | ||
@@ -187,7 +187,7 @@ impl CallableSig { | |||
187 | .shifted_out_to(&Interner, DebruijnIndex::ONE) | 187 | .shifted_out_to(&Interner, DebruijnIndex::ONE) |
188 | .expect("unexpected lifetime vars in fn ptr") | 188 | .expect("unexpected lifetime vars in fn ptr") |
189 | .0 | 189 | .0 |
190 | .interned() | 190 | .as_slice(&Interner) |
191 | .iter() | 191 | .iter() |
192 | .map(|arg| arg.assert_ty_ref(&Interner).clone()) | 192 | .map(|arg| arg.assert_ty_ref(&Interner).clone()) |
193 | .collect(), | 193 | .collect(), |
diff --git a/crates/hir_ty/src/traits/chalk/interner.rs b/crates/hir_ty/src/traits/chalk/interner.rs index 7a3bd41d4..17e056f03 100644 --- a/crates/hir_ty/src/traits/chalk/interner.rs +++ b/crates/hir_ty/src/traits/chalk/interner.rs | |||
@@ -3,11 +3,12 @@ | |||
3 | 3 | ||
4 | use super::tls; | 4 | 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::{Goal, GoalData}; |
7 | use hir_def::{ | 7 | use hir_def::{ |
8 | intern::{impl_internable, InternStorage, Internable, Interned}, | 8 | intern::{impl_internable, InternStorage, Internable, Interned}, |
9 | TypeAliasId, | 9 | TypeAliasId, |
10 | }; | 10 | }; |
11 | use crate::GenericArg; | ||
11 | use smallvec::SmallVec; | 12 | use smallvec::SmallVec; |
12 | use std::{fmt, sync::Arc}; | 13 | use std::{fmt, sync::Arc}; |
13 | 14 | ||
@@ -32,7 +33,13 @@ pub(crate) type Variances = chalk_ir::Variances<Interner>; | |||
32 | #[derive(PartialEq, Eq, Hash, Debug)] | 33 | #[derive(PartialEq, Eq, Hash, Debug)] |
33 | pub struct InternedVariableKindsInner(Vec<chalk_ir::VariableKind<Interner>>); | 34 | pub struct InternedVariableKindsInner(Vec<chalk_ir::VariableKind<Interner>>); |
34 | 35 | ||
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 | ); | ||
36 | 43 | ||
37 | impl chalk_ir::interner::Interner for Interner { | 44 | impl chalk_ir::interner::Interner for Interner { |
38 | type InternedType = Arc<chalk_ir::TyData<Self>>; | 45 | type InternedType = Arc<chalk_ir::TyData<Self>>; |
@@ -42,7 +49,7 @@ impl chalk_ir::interner::Interner for Interner { | |||
42 | type InternedGenericArg = chalk_ir::GenericArgData<Self>; | 49 | type InternedGenericArg = chalk_ir::GenericArgData<Self>; |
43 | type InternedGoal = Arc<GoalData<Self>>; | 50 | type InternedGoal = Arc<GoalData<Self>>; |
44 | type InternedGoals = Vec<Goal<Self>>; | 51 | type InternedGoals = Vec<Goal<Self>>; |
45 | type InternedSubstitution = SmallVec<[GenericArg<Self>; 2]>; | 52 | type InternedSubstitution = Interned<InternedSubstitutionInner>; |
46 | type InternedProgramClause = Arc<chalk_ir::ProgramClauseData<Self>>; | 53 | type InternedProgramClause = Arc<chalk_ir::ProgramClauseData<Self>>; |
47 | type InternedProgramClauses = Arc<[chalk_ir::ProgramClause<Self>]>; | 54 | type InternedProgramClauses = Arc<[chalk_ir::ProgramClause<Self>]>; |
48 | type InternedQuantifiedWhereClauses = Vec<chalk_ir::QuantifiedWhereClause<Self>>; | 55 | type InternedQuantifiedWhereClauses = Vec<chalk_ir::QuantifiedWhereClause<Self>>; |
@@ -107,7 +114,7 @@ impl chalk_ir::interner::Interner for Interner { | |||
107 | } | 114 | } |
108 | 115 | ||
109 | fn debug_generic_arg( | 116 | fn debug_generic_arg( |
110 | parameter: &GenericArg<Interner>, | 117 | parameter: &GenericArg, |
111 | fmt: &mut fmt::Formatter<'_>, | 118 | fmt: &mut fmt::Formatter<'_>, |
112 | ) -> Option<fmt::Result> { | 119 | ) -> Option<fmt::Result> { |
113 | tls::with_current_program(|prog| Some(prog?.debug_generic_arg(parameter, fmt))) | 120 | tls::with_current_program(|prog| Some(prog?.debug_generic_arg(parameter, fmt))) |
@@ -272,16 +279,16 @@ impl chalk_ir::interner::Interner for Interner { | |||
272 | 279 | ||
273 | fn intern_substitution<E>( | 280 | fn intern_substitution<E>( |
274 | &self, | 281 | &self, |
275 | data: impl IntoIterator<Item = Result<GenericArg<Self>, E>>, | 282 | data: impl IntoIterator<Item = Result<GenericArg, E>>, |
276 | ) -> Result<Self::InternedSubstitution, E> { | 283 | ) -> Result<Self::InternedSubstitution, E> { |
277 | data.into_iter().collect() | 284 | Ok(Interned::new(InternedSubstitutionInner(data.into_iter().collect::<Result<SmallVec<_>, _>>()?))) |
278 | } | 285 | } |
279 | 286 | ||
280 | fn substitution_data<'a>( | 287 | fn substitution_data<'a>( |
281 | &self, | 288 | &self, |
282 | substitution: &'a Self::InternedSubstitution, | 289 | substitution: &'a Self::InternedSubstitution, |
283 | ) -> &'a [GenericArg<Self>] { | 290 | ) -> &'a [GenericArg] { |
284 | substitution | 291 | &substitution.as_ref().0 |
285 | } | 292 | } |
286 | 293 | ||
287 | fn intern_program_clause( | 294 | fn intern_program_clause( |
diff --git a/crates/hir_ty/src/traits/chalk/mapping.rs b/crates/hir_ty/src/traits/chalk/mapping.rs index 7818f6387..e78581ea5 100644 --- a/crates/hir_ty/src/traits/chalk/mapping.rs +++ b/crates/hir_ty/src/traits/chalk/mapping.rs | |||
@@ -99,7 +99,7 @@ pub(super) fn generic_predicate_to_inline_bound( | |||
99 | // have the expected self type | 99 | // have the expected self type |
100 | return None; | 100 | return None; |
101 | } | 101 | } |
102 | let args_no_self = trait_ref.substitution.interned()[1..] | 102 | let args_no_self = trait_ref.substitution.as_slice(&Interner)[1..] |
103 | .iter() | 103 | .iter() |
104 | .map(|ty| ty.clone().cast(&Interner)) | 104 | .map(|ty| ty.clone().cast(&Interner)) |
105 | .collect(); | 105 | .collect(); |
@@ -111,7 +111,7 @@ pub(super) fn generic_predicate_to_inline_bound( | |||
111 | return None; | 111 | return None; |
112 | } | 112 | } |
113 | let trait_ = projection_ty.trait_(db); | 113 | 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..] |
115 | .iter() | 115 | .iter() |
116 | .map(|ty| ty.clone().cast(&Interner)) | 116 | .map(|ty| ty.clone().cast(&Interner)) |
117 | .collect(); | 117 | .collect(); |