Skip to content

Commit dd41cda

Browse files
authored
Merge pull request #19678 from Veykril/push-mkznvpsktnnz
Arena allocate `LifetimeRef`s
2 parents 5ff4ba3 + 61df8ec commit dd41cda

File tree

13 files changed

+126
-60
lines changed

13 files changed

+126
-60
lines changed

crates/hir-def/src/expr_store.rs

+25-1
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ use crate::{
3131
PatId, RecordFieldPat, Statement,
3232
},
3333
nameres::DefMap,
34-
type_ref::{PathId, TypeRef, TypeRefId},
34+
type_ref::{LifetimeRef, LifetimeRefId, PathId, TypeRef, TypeRefId},
3535
};
3636

3737
pub use self::body::{Body, BodySourceMap};
@@ -87,13 +87,17 @@ pub type MacroCallPtr = AstPtr<ast::MacroCall>;
8787
pub type TypePtr = AstPtr<ast::Type>;
8888
pub type TypeSource = InFile<TypePtr>;
8989

90+
pub type LifetimePtr = AstPtr<ast::Lifetime>;
91+
pub type LifetimeSource = InFile<LifetimePtr>;
92+
9093
#[derive(Debug, Eq, PartialEq)]
9194
pub struct ExpressionStore {
9295
pub exprs: Arena<Expr>,
9396
pub pats: Arena<Pat>,
9497
pub bindings: Arena<Binding>,
9598
pub labels: Arena<Label>,
9699
pub types: Arena<TypeRef>,
100+
pub lifetimes: Arena<LifetimeRef>,
97101
/// Id of the closure/coroutine that owns the corresponding binding. If a binding is owned by the
98102
/// top level expression, it will not be listed in here.
99103
pub binding_owners: FxHashMap<BindingId, ExprId>,
@@ -130,6 +134,9 @@ pub struct ExpressionStoreSourceMap {
130134
types_map_back: ArenaMap<TypeRefId, TypeSource>,
131135
types_map: FxHashMap<TypeSource, TypeRefId>,
132136

137+
lifetime_map_back: ArenaMap<LifetimeRefId, LifetimeSource>,
138+
lifetime_map: FxHashMap<LifetimeSource, LifetimeRefId>,
139+
133140
template_map: Option<Box<FormatTemplate>>,
134141

135142
pub expansions: FxHashMap<InFile<MacroCallPtr>, MacroCallId>,
@@ -146,6 +153,7 @@ pub struct ExpressionStoreBuilder {
146153
pub pats: Arena<Pat>,
147154
pub bindings: Arena<Binding>,
148155
pub labels: Arena<Label>,
156+
pub lifetimes: Arena<LifetimeRef>,
149157
pub binding_owners: FxHashMap<BindingId, ExprId>,
150158
pub types: Arena<TypeRef>,
151159
block_scopes: Vec<BlockId>,
@@ -187,6 +195,7 @@ impl ExpressionStoreBuilder {
187195
mut binding_owners,
188196
mut ident_hygiene,
189197
mut types,
198+
mut lifetimes,
190199
} = self;
191200
exprs.shrink_to_fit();
192201
labels.shrink_to_fit();
@@ -195,6 +204,7 @@ impl ExpressionStoreBuilder {
195204
binding_owners.shrink_to_fit();
196205
ident_hygiene.shrink_to_fit();
197206
types.shrink_to_fit();
207+
lifetimes.shrink_to_fit();
198208

199209
ExpressionStore {
200210
exprs,
@@ -203,6 +213,7 @@ impl ExpressionStoreBuilder {
203213
labels,
204214
binding_owners,
205215
types,
216+
lifetimes,
206217
block_scopes: block_scopes.into_boxed_slice(),
207218
ident_hygiene,
208219
}
@@ -604,6 +615,15 @@ impl Index<TypeRefId> for ExpressionStore {
604615
&self.types[b]
605616
}
606617
}
618+
619+
impl Index<LifetimeRefId> for ExpressionStore {
620+
type Output = LifetimeRef;
621+
622+
fn index(&self, b: LifetimeRefId) -> &LifetimeRef {
623+
&self.lifetimes[b]
624+
}
625+
}
626+
607627
impl Index<PathId> for ExpressionStore {
608628
type Output = Path;
609629

@@ -745,6 +765,8 @@ impl ExpressionStoreSourceMap {
745765
binding_definitions,
746766
types_map,
747767
types_map_back,
768+
lifetime_map_back,
769+
lifetime_map,
748770
} = self;
749771
if let Some(template_map) = template_map {
750772
let FormatTemplate {
@@ -769,5 +791,7 @@ impl ExpressionStoreSourceMap {
769791
binding_definitions.shrink_to_fit();
770792
types_map.shrink_to_fit();
771793
types_map_back.shrink_to_fit();
794+
lifetime_map.shrink_to_fit();
795+
lifetime_map_back.shrink_to_fit();
772796
}
773797
}

crates/hir-def/src/expr_store/lower.rs

+35-17
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,8 @@ use crate::{
3535
db::DefDatabase,
3636
expr_store::{
3737
Body, BodySourceMap, ExprPtr, ExpressionStore, ExpressionStoreBuilder,
38-
ExpressionStoreDiagnostics, ExpressionStoreSourceMap, HygieneId, LabelPtr, PatPtr, TypePtr,
38+
ExpressionStoreDiagnostics, ExpressionStoreSourceMap, HygieneId, LabelPtr, LifetimePtr,
39+
PatPtr, TypePtr,
3940
expander::Expander,
4041
lower::generics::ImplTraitLowerFn,
4142
path::{AssociatedTypeBinding, GenericArg, GenericArgs, GenericArgsParentheses, Path},
@@ -56,8 +57,8 @@ use crate::{
5657
lang_item::LangItem,
5758
nameres::{DefMap, LocalDefMap, MacroSubNs},
5859
type_ref::{
59-
ArrayType, ConstRef, FnType, LifetimeRef, Mutability, PathId, Rawness, RefType,
60-
TraitBoundModifier, TraitRef, TypeBound, TypeRef, TypeRefId, UseArgRef,
60+
ArrayType, ConstRef, FnType, LifetimeRef, LifetimeRefId, Mutability, PathId, Rawness,
61+
RefType, TraitBoundModifier, TraitRef, TypeBound, TypeRef, TypeRefId, UseArgRef,
6162
},
6263
};
6364

@@ -568,20 +569,21 @@ impl ExprCollector<'_> {
568569
}
569570
}
570571

571-
pub fn lower_lifetime_ref(&mut self, lifetime: ast::Lifetime) -> LifetimeRef {
572+
pub fn lower_lifetime_ref(&mut self, lifetime: ast::Lifetime) -> LifetimeRefId {
572573
// FIXME: Keyword check?
573-
match &*lifetime.text() {
574+
let lifetime_ref = match &*lifetime.text() {
574575
"" | "'" => LifetimeRef::Error,
575576
"'static" => LifetimeRef::Static,
576577
"'_" => LifetimeRef::Placeholder,
577578
text => LifetimeRef::Named(Name::new_lifetime(text)),
578-
}
579+
};
580+
self.alloc_lifetime_ref(lifetime_ref, AstPtr::new(&lifetime))
579581
}
580582

581-
pub fn lower_lifetime_ref_opt(&mut self, lifetime: Option<ast::Lifetime>) -> LifetimeRef {
583+
pub fn lower_lifetime_ref_opt(&mut self, lifetime: Option<ast::Lifetime>) -> LifetimeRefId {
582584
match lifetime {
583585
Some(lifetime) => self.lower_lifetime_ref(lifetime),
584-
None => LifetimeRef::Placeholder,
586+
None => self.alloc_lifetime_ref_desugared(LifetimeRef::Placeholder),
585587
}
586588
}
587589

@@ -735,6 +737,30 @@ impl ExprCollector<'_> {
735737
id
736738
}
737739

740+
fn alloc_lifetime_ref(
741+
&mut self,
742+
lifetime_ref: LifetimeRef,
743+
node: LifetimePtr,
744+
) -> LifetimeRefId {
745+
let id = self.store.lifetimes.alloc(lifetime_ref);
746+
let ptr = self.expander.in_file(node);
747+
self.source_map.lifetime_map_back.insert(id, ptr);
748+
self.source_map.lifetime_map.insert(ptr, id);
749+
id
750+
}
751+
752+
fn alloc_type_ref_desugared(&mut self, type_ref: TypeRef) -> TypeRefId {
753+
self.store.types.alloc(type_ref)
754+
}
755+
756+
fn alloc_lifetime_ref_desugared(&mut self, lifetime_ref: LifetimeRef) -> LifetimeRefId {
757+
self.store.lifetimes.alloc(lifetime_ref)
758+
}
759+
760+
fn alloc_error_type(&mut self) -> TypeRefId {
761+
self.store.types.alloc(TypeRef::Error)
762+
}
763+
738764
pub fn lower_path(
739765
&mut self,
740766
ast: ast::Path,
@@ -754,14 +780,6 @@ impl ExprCollector<'_> {
754780
result
755781
}
756782

757-
fn alloc_type_ref_desugared(&mut self, type_ref: TypeRef) -> TypeRefId {
758-
self.store.types.alloc(type_ref)
759-
}
760-
761-
fn alloc_error_type(&mut self) -> TypeRefId {
762-
self.store.types.alloc(TypeRef::Error)
763-
}
764-
765783
pub fn impl_trait_error_allocator(
766784
ec: &mut ExprCollector<'_>,
767785
ptr: TypePtr,
@@ -962,7 +980,7 @@ impl ExprCollector<'_> {
962980
.lifetime_params()
963981
.flat_map(|lp| lp.lifetime().map(|lt| Name::new_lifetime(&lt.text())))
964982
.collect(),
965-
None => Box::default(),
983+
None => ThinVec::default(),
966984
};
967985
let path = for_type.ty().and_then(|ty| match &ty {
968986
ast::Type::PathType(path_type) => {

crates/hir-def/src/expr_store/lower/generics.rs

+8-8
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ use crate::{
2020
ConstParamData, GenericParams, LifetimeParamData, TypeOrConstParamData, TypeParamData,
2121
TypeParamProvenance, WherePredicate,
2222
},
23-
type_ref::{LifetimeRef, TypeBound, TypeRef, TypeRefId},
23+
type_ref::{LifetimeRef, LifetimeRefId, TypeBound, TypeRef, TypeRefId},
2424
};
2525

2626
pub(crate) type ImplTraitLowerFn<'l> = &'l mut dyn for<'ec, 'db> FnMut(
@@ -149,14 +149,14 @@ impl GenericParamsCollector {
149149
let _idx = self.type_or_consts.alloc(param.into());
150150
}
151151
ast::GenericParam::LifetimeParam(lifetime_param) => {
152-
let lifetime_ref = ec.lower_lifetime_ref_opt(lifetime_param.lifetime());
153-
if let LifetimeRef::Named(name) = &lifetime_ref {
152+
let lifetime = ec.lower_lifetime_ref_opt(lifetime_param.lifetime());
153+
if let LifetimeRef::Named(name) = &ec.store.lifetimes[lifetime] {
154154
let param = LifetimeParamData { name: name.clone() };
155155
let _idx = self.lifetimes.alloc(param);
156156
self.lower_bounds(
157157
ec,
158158
lifetime_param.type_bound_list(),
159-
Either::Right(lifetime_ref),
159+
Either::Right(lifetime),
160160
);
161161
}
162162
}
@@ -192,7 +192,7 @@ impl GenericParamsCollector {
192192
.collect()
193193
});
194194
for bound in pred.type_bound_list().iter().flat_map(|l| l.bounds()) {
195-
self.lower_type_bound_as_predicate(ec, bound, lifetimes.as_deref(), target.clone());
195+
self.lower_type_bound_as_predicate(ec, bound, lifetimes.as_deref(), target);
196196
}
197197
}
198198
}
@@ -201,10 +201,10 @@ impl GenericParamsCollector {
201201
&mut self,
202202
ec: &mut ExprCollector<'_>,
203203
type_bounds: Option<ast::TypeBoundList>,
204-
target: Either<TypeRefId, LifetimeRef>,
204+
target: Either<TypeRefId, LifetimeRefId>,
205205
) {
206206
for bound in type_bounds.iter().flat_map(|type_bound_list| type_bound_list.bounds()) {
207-
self.lower_type_bound_as_predicate(ec, bound, None, target.clone());
207+
self.lower_type_bound_as_predicate(ec, bound, None, target);
208208
}
209209
}
210210

@@ -213,7 +213,7 @@ impl GenericParamsCollector {
213213
ec: &mut ExprCollector<'_>,
214214
bound: ast::TypeBound,
215215
hrtb_lifetimes: Option<&[Name]>,
216-
target: Either<TypeRefId, LifetimeRef>,
216+
target: Either<TypeRefId, LifetimeRefId>,
217217
) {
218218
let bound = ec.lower_type_bound(
219219
bound,

crates/hir-def/src/expr_store/path.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ use std::iter;
44

55
use crate::{
66
lang_item::LangItemTarget,
7-
type_ref::{ConstRef, LifetimeRef, TypeBound, TypeRefId},
7+
type_ref::{ConstRef, LifetimeRefId, TypeBound, TypeRefId},
88
};
99
use hir_expand::{
1010
mod_path::{ModPath, PathKind},
@@ -91,7 +91,7 @@ pub struct AssociatedTypeBinding {
9191
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
9292
pub enum GenericArg {
9393
Type(TypeRefId),
94-
Lifetime(LifetimeRef),
94+
Lifetime(LifetimeRefId),
9595
Const(ConstRef),
9696
}
9797

crates/hir-def/src/expr_store/pretty.rs

+15-9
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@ use hir_expand::{Lookup, mod_path::PathKind};
1010
use itertools::Itertools;
1111
use span::Edition;
1212

13-
use crate::signatures::StructFlags;
1413
use crate::{
1514
AdtId, DefWithBodyId, GenericDefId, ItemTreeLoc, TypeParamId, VariantId,
1615
expr_store::path::{GenericArg, GenericArgs},
@@ -22,6 +21,7 @@ use crate::{
2221
signatures::{FnFlags, FunctionSignature, StructSignature},
2322
type_ref::{ConstRef, LifetimeRef, Mutability, TraitBoundModifier, TypeBound, UseArgRef},
2423
};
24+
use crate::{LifetimeParamId, signatures::StructFlags};
2525
use crate::{item_tree::FieldsShape, signatures::FieldData};
2626

2727
use super::*;
@@ -342,9 +342,9 @@ fn print_where_clauses(db: &dyn DefDatabase, generic_params: &GenericParams, p:
342342
p.print_type_bounds(std::slice::from_ref(bound));
343343
}
344344
WherePredicate::Lifetime { target, bound } => {
345-
p.print_lifetime_ref(target);
345+
p.print_lifetime_ref(*target);
346346
w!(p, ": ");
347-
p.print_lifetime_ref(bound);
347+
p.print_lifetime_ref(*bound);
348348
}
349349
WherePredicate::ForLifetime { lifetimes, target, bound } => {
350350
w!(p, "for<");
@@ -1199,7 +1199,7 @@ impl Printer<'_> {
11991199
match arg {
12001200
GenericArg::Type(ty) => self.print_type_ref(*ty),
12011201
GenericArg::Const(ConstRef { expr }) => self.print_expr(*expr),
1202-
GenericArg::Lifetime(lt) => self.print_lifetime_ref(lt),
1202+
GenericArg::Lifetime(lt) => self.print_lifetime_ref(*lt),
12031203
}
12041204
}
12051205

@@ -1212,14 +1212,20 @@ impl Printer<'_> {
12121212
}
12131213
}
12141214

1215-
pub(crate) fn print_lifetime_ref(&mut self, lt_ref: &LifetimeRef) {
1216-
match lt_ref {
1215+
pub(crate) fn print_lifetime_param(&mut self, param: LifetimeParamId) {
1216+
let generic_params = self.db.generic_params(param.parent);
1217+
w!(self, "{}", generic_params[param.local_id].name.display(self.db, self.edition))
1218+
}
1219+
1220+
pub(crate) fn print_lifetime_ref(&mut self, lt_ref: LifetimeRefId) {
1221+
match &self.store[lt_ref] {
12171222
LifetimeRef::Static => w!(self, "'static"),
12181223
LifetimeRef::Named(lt) => {
12191224
w!(self, "{}", lt.display(self.db, self.edition))
12201225
}
12211226
LifetimeRef::Placeholder => w!(self, "'_"),
12221227
LifetimeRef::Error => w!(self, "'{{error}}"),
1228+
&LifetimeRef::Param(p) => self.print_lifetime_param(p),
12231229
}
12241230
}
12251231

@@ -1255,7 +1261,7 @@ impl Printer<'_> {
12551261
};
12561262
w!(self, "&");
12571263
if let Some(lt) = &ref_.lifetime {
1258-
self.print_lifetime_ref(lt);
1264+
self.print_lifetime_ref(*lt);
12591265
w!(self, " ");
12601266
}
12611267
w!(self, "{mtbl}");
@@ -1338,7 +1344,7 @@ impl Printer<'_> {
13381344
);
13391345
self.print_path(&self.store[*path]);
13401346
}
1341-
TypeBound::Lifetime(lt) => self.print_lifetime_ref(lt),
1347+
TypeBound::Lifetime(lt) => self.print_lifetime_ref(*lt),
13421348
TypeBound::Use(args) => {
13431349
w!(self, "use<");
13441350
let mut first = true;
@@ -1350,7 +1356,7 @@ impl Printer<'_> {
13501356
UseArgRef::Name(it) => {
13511357
w!(self, "{}", it.display(self.db, self.edition))
13521358
}
1353-
UseArgRef::Lifetime(it) => self.print_lifetime_ref(it),
1359+
UseArgRef::Lifetime(it) => self.print_lifetime_ref(*it),
13541360
}
13551361
}
13561362
w!(self, ">")

crates/hir-def/src/hir/generics.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ use crate::{
1111
AdtId, ConstParamId, GenericDefId, LifetimeParamId, TypeOrConstParamId, TypeParamId,
1212
db::DefDatabase,
1313
expr_store::{ExpressionStore, ExpressionStoreSourceMap},
14-
type_ref::{ConstRef, LifetimeRef, TypeBound, TypeRefId},
14+
type_ref::{ConstRef, LifetimeRefId, TypeBound, TypeRefId},
1515
};
1616

1717
pub type LocalTypeOrConstParamId = Idx<TypeOrConstParamData>;
@@ -171,7 +171,7 @@ impl ops::Index<LocalLifetimeParamId> for GenericParams {
171171
#[derive(Clone, PartialEq, Eq, Debug, Hash)]
172172
pub enum WherePredicate {
173173
TypeBound { target: TypeRefId, bound: TypeBound },
174-
Lifetime { target: LifetimeRef, bound: LifetimeRef },
174+
Lifetime { target: LifetimeRefId, bound: LifetimeRefId },
175175
ForLifetime { lifetimes: ThinVec<Name>, target: TypeRefId, bound: TypeBound },
176176
}
177177

0 commit comments

Comments
 (0)