Skip to content

Commit c15fc9a

Browse files
authored
Merge pull request #19837 from ChayimFriedman2/stable-astid
Provide better incrementality when items are changed
2 parents 2095af2 + 9a1063f commit c15fc9a

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

57 files changed

+2256
-1945
lines changed

.typos.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ extend-ignore-re = [
1818
"INOUT",
1919
"optin",
2020
"=Pn",
21+
"\\[[0-9A-F]{4},", # AstId hex hashes
2122
# ignore `// spellchecker:off` until `// spellchecker:on`
2223
"(?s)(#|//)\\s*spellchecker:off.*?\\n\\s*(#|//)\\s*spellchecker:on",
2324
]

crates/hir-def/src/attr.rs

Lines changed: 92 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ use intern::{Symbol, sym};
1414
use la_arena::{ArenaMap, Idx, RawIdx};
1515
use mbe::DelimiterKind;
1616
use rustc_abi::ReprOptions;
17+
use span::AstIdNode;
1718
use syntax::{
1819
AstPtr,
1920
ast::{self, HasAttrs},
@@ -22,10 +23,10 @@ use triomphe::Arc;
2223
use tt::iter::{TtElement, TtIter};
2324

2425
use crate::{
25-
AdtId, AttrDefId, GenericParamId, HasModule, ItemTreeLoc, LocalFieldId, Lookup, MacroId,
26+
AdtId, AstIdLoc, AttrDefId, GenericParamId, HasModule, LocalFieldId, Lookup, MacroId,
2627
VariantId,
2728
db::DefDatabase,
28-
item_tree::{AttrOwner, FieldParent, ItemTreeNode},
29+
item_tree::AttrOwner,
2930
lang_item::LangItem,
3031
nameres::{ModuleOrigin, ModuleSource},
3132
src::{HasChildSource, HasSource},
@@ -42,6 +43,15 @@ pub struct AttrsWithOwner {
4243
}
4344

4445
impl Attrs {
46+
pub fn new(
47+
db: &dyn DefDatabase,
48+
owner: &dyn ast::HasAttrs,
49+
span_map: SpanMapRef<'_>,
50+
cfg_options: &CfgOptions,
51+
) -> Self {
52+
Attrs(RawAttrs::new_expanded(db, owner, span_map, cfg_options))
53+
}
54+
4555
pub fn get(&self, id: AttrId) -> Option<&Attr> {
4656
(**self).iter().find(|attr| attr.id == id)
4757
}
@@ -94,44 +104,64 @@ impl Attrs {
94104
v: VariantId,
95105
) -> Arc<ArenaMap<LocalFieldId, Attrs>> {
96106
let _p = tracing::info_span!("fields_attrs_query").entered();
97-
// FIXME: There should be some proper form of mapping between item tree field ids and hir field ids
98107
let mut res = ArenaMap::default();
99-
let item_tree;
100-
let (parent, fields, krate) = match v {
108+
let (fields, file_id, krate) = match v {
101109
VariantId::EnumVariantId(it) => {
102110
let loc = it.lookup(db);
103111
let krate = loc.parent.lookup(db).container.krate;
104-
item_tree = loc.id.item_tree(db);
105-
let variant = &item_tree[loc.id.value];
106-
(FieldParent::EnumVariant(loc.id.value), &variant.fields, krate)
112+
let source = loc.source(db);
113+
(source.value.field_list(), source.file_id, krate)
107114
}
108115
VariantId::StructId(it) => {
109116
let loc = it.lookup(db);
110117
let krate = loc.container.krate;
111-
item_tree = loc.id.item_tree(db);
112-
let struct_ = &item_tree[loc.id.value];
113-
(FieldParent::Struct(loc.id.value), &struct_.fields, krate)
118+
let source = loc.source(db);
119+
(source.value.field_list(), source.file_id, krate)
114120
}
115121
VariantId::UnionId(it) => {
116122
let loc = it.lookup(db);
117123
let krate = loc.container.krate;
118-
item_tree = loc.id.item_tree(db);
119-
let union_ = &item_tree[loc.id.value];
120-
(FieldParent::Union(loc.id.value), &union_.fields, krate)
124+
let source = loc.source(db);
125+
(
126+
source.value.record_field_list().map(ast::FieldList::RecordFieldList),
127+
source.file_id,
128+
krate,
129+
)
121130
}
122131
};
132+
let Some(fields) = fields else {
133+
return Arc::new(res);
134+
};
123135

124136
let cfg_options = krate.cfg_options(db);
125-
126-
let mut idx = 0;
127-
for (id, _field) in fields.iter().enumerate() {
128-
let attrs = item_tree.attrs(db, krate, AttrOwner::make_field_indexed(parent, id));
129-
if attrs.is_cfg_enabled(cfg_options) {
130-
res.insert(Idx::from_raw(RawIdx::from(idx)), attrs);
131-
idx += 1;
137+
let span_map = db.span_map(file_id);
138+
139+
match fields {
140+
ast::FieldList::RecordFieldList(fields) => {
141+
let mut idx = 0;
142+
for field in fields.fields() {
143+
let attrs =
144+
Attrs(RawAttrs::new_expanded(db, &field, span_map.as_ref(), cfg_options));
145+
if attrs.is_cfg_enabled(cfg_options).is_ok() {
146+
res.insert(Idx::from_raw(RawIdx::from(idx)), attrs);
147+
idx += 1;
148+
}
149+
}
150+
}
151+
ast::FieldList::TupleFieldList(fields) => {
152+
let mut idx = 0;
153+
for field in fields.fields() {
154+
let attrs =
155+
Attrs(RawAttrs::new_expanded(db, &field, span_map.as_ref(), cfg_options));
156+
if attrs.is_cfg_enabled(cfg_options).is_ok() {
157+
res.insert(Idx::from_raw(RawIdx::from(idx)), attrs);
158+
idx += 1;
159+
}
160+
}
132161
}
133162
}
134163

164+
res.shrink_to_fit();
135165
Arc::new(res)
136166
}
137167
}
@@ -167,11 +197,10 @@ impl Attrs {
167197
}
168198

169199
#[inline]
170-
pub(crate) fn is_cfg_enabled(&self, cfg_options: &CfgOptions) -> bool {
171-
match self.cfg() {
172-
None => true,
173-
Some(cfg) => cfg_options.check(&cfg) != Some(false),
174-
}
200+
pub(crate) fn is_cfg_enabled(&self, cfg_options: &CfgOptions) -> Result<(), CfgExpr> {
201+
self.cfgs().try_for_each(|cfg| {
202+
if cfg_options.check(&cfg) != Some(false) { Ok(()) } else { Err(cfg) }
203+
})
175204
}
176205

177206
#[inline]
@@ -488,12 +517,12 @@ impl AttrsWithOwner {
488517
pub(crate) fn attrs_query(db: &dyn DefDatabase, def: AttrDefId) -> Attrs {
489518
let _p = tracing::info_span!("attrs_query").entered();
490519
// FIXME: this should use `Trace` to avoid duplication in `source_map` below
491-
let raw_attrs = match def {
520+
match def {
492521
AttrDefId::ModuleId(module) => {
493522
let def_map = module.def_map(db);
494523
let mod_data = &def_map[module.local_id];
495524

496-
match mod_data.origin {
525+
let raw_attrs = match mod_data.origin {
497526
ModuleOrigin::File { definition, declaration_tree_id, .. } => {
498527
let decl_attrs = declaration_tree_id
499528
.item_tree(db)
@@ -515,77 +544,73 @@ impl AttrsWithOwner {
515544
let tree = db.block_item_tree(id);
516545
tree.raw_attrs(AttrOwner::TopLevel).clone()
517546
}
518-
}
519-
}
520-
AttrDefId::FieldId(it) => {
521-
return db.fields_attrs(it.parent)[it.local_id].clone();
547+
};
548+
Attrs::expand_cfg_attr(db, module.krate, raw_attrs)
522549
}
523-
AttrDefId::EnumVariantId(it) => attrs_from_item_tree_loc(db, it),
550+
AttrDefId::FieldId(it) => db.fields_attrs(it.parent)[it.local_id].clone(),
551+
AttrDefId::EnumVariantId(it) => attrs_from_ast_id_loc(db, it),
524552
AttrDefId::AdtId(it) => match it {
525-
AdtId::StructId(it) => attrs_from_item_tree_loc(db, it),
526-
AdtId::EnumId(it) => attrs_from_item_tree_loc(db, it),
527-
AdtId::UnionId(it) => attrs_from_item_tree_loc(db, it),
553+
AdtId::StructId(it) => attrs_from_ast_id_loc(db, it),
554+
AdtId::EnumId(it) => attrs_from_ast_id_loc(db, it),
555+
AdtId::UnionId(it) => attrs_from_ast_id_loc(db, it),
528556
},
529-
AttrDefId::TraitId(it) => attrs_from_item_tree_loc(db, it),
530-
AttrDefId::TraitAliasId(it) => attrs_from_item_tree_loc(db, it),
557+
AttrDefId::TraitId(it) => attrs_from_ast_id_loc(db, it),
558+
AttrDefId::TraitAliasId(it) => attrs_from_ast_id_loc(db, it),
531559
AttrDefId::MacroId(it) => match it {
532-
MacroId::Macro2Id(it) => attrs_from_item_tree_loc(db, it),
533-
MacroId::MacroRulesId(it) => attrs_from_item_tree_loc(db, it),
534-
MacroId::ProcMacroId(it) => attrs_from_item_tree_loc(db, it),
560+
MacroId::Macro2Id(it) => attrs_from_ast_id_loc(db, it),
561+
MacroId::MacroRulesId(it) => attrs_from_ast_id_loc(db, it),
562+
MacroId::ProcMacroId(it) => attrs_from_ast_id_loc(db, it),
535563
},
536-
AttrDefId::ImplId(it) => attrs_from_item_tree_loc(db, it),
537-
AttrDefId::ConstId(it) => attrs_from_item_tree_loc(db, it),
538-
AttrDefId::StaticId(it) => attrs_from_item_tree_loc(db, it),
539-
AttrDefId::FunctionId(it) => attrs_from_item_tree_loc(db, it),
540-
AttrDefId::TypeAliasId(it) => attrs_from_item_tree_loc(db, it),
564+
AttrDefId::ImplId(it) => attrs_from_ast_id_loc(db, it),
565+
AttrDefId::ConstId(it) => attrs_from_ast_id_loc(db, it),
566+
AttrDefId::StaticId(it) => attrs_from_ast_id_loc(db, it),
567+
AttrDefId::FunctionId(it) => attrs_from_ast_id_loc(db, it),
568+
AttrDefId::TypeAliasId(it) => attrs_from_ast_id_loc(db, it),
541569
AttrDefId::GenericParamId(it) => match it {
542570
GenericParamId::ConstParamId(it) => {
543571
let src = it.parent().child_source(db);
544572
// FIXME: We should be never getting `None` here.
545-
return Attrs(match src.value.get(it.local_id()) {
573+
Attrs(match src.value.get(it.local_id()) {
546574
Some(val) => RawAttrs::new_expanded(
547575
db,
548576
val,
549577
db.span_map(src.file_id).as_ref(),
550578
def.krate(db).cfg_options(db),
551579
),
552580
None => RawAttrs::EMPTY,
553-
});
581+
})
554582
}
555583
GenericParamId::TypeParamId(it) => {
556584
let src = it.parent().child_source(db);
557585
// FIXME: We should be never getting `None` here.
558-
return Attrs(match src.value.get(it.local_id()) {
586+
Attrs(match src.value.get(it.local_id()) {
559587
Some(val) => RawAttrs::new_expanded(
560588
db,
561589
val,
562590
db.span_map(src.file_id).as_ref(),
563591
def.krate(db).cfg_options(db),
564592
),
565593
None => RawAttrs::EMPTY,
566-
});
594+
})
567595
}
568596
GenericParamId::LifetimeParamId(it) => {
569597
let src = it.parent.child_source(db);
570598
// FIXME: We should be never getting `None` here.
571-
return Attrs(match src.value.get(it.local_id) {
599+
Attrs(match src.value.get(it.local_id) {
572600
Some(val) => RawAttrs::new_expanded(
573601
db,
574602
val,
575603
db.span_map(src.file_id).as_ref(),
576604
def.krate(db).cfg_options(db),
577605
),
578606
None => RawAttrs::EMPTY,
579-
});
607+
})
580608
}
581609
},
582-
AttrDefId::ExternBlockId(it) => attrs_from_item_tree_loc(db, it),
583-
AttrDefId::ExternCrateId(it) => attrs_from_item_tree_loc(db, it),
584-
AttrDefId::UseId(it) => attrs_from_item_tree_loc(db, it),
585-
};
586-
587-
let attrs = raw_attrs.expand_cfg_attr(db, def.krate(db));
588-
Attrs(attrs)
610+
AttrDefId::ExternBlockId(it) => attrs_from_ast_id_loc(db, it),
611+
AttrDefId::ExternCrateId(it) => attrs_from_ast_id_loc(db, it),
612+
AttrDefId::UseId(it) => attrs_from_ast_id_loc(db, it),
613+
}
589614
}
590615

591616
pub fn source_map(&self, db: &dyn DefDatabase) -> AttrSourceMap {
@@ -787,14 +812,15 @@ fn any_has_attrs<'db>(
787812
id.lookup(db).source(db).map(ast::AnyHasAttrs::new)
788813
}
789814

790-
fn attrs_from_item_tree_loc<'db, N: ItemTreeNode>(
815+
fn attrs_from_ast_id_loc<'db, N: AstIdNode + HasAttrs>(
791816
db: &(dyn DefDatabase + 'db),
792-
lookup: impl Lookup<Database = dyn DefDatabase, Data = impl ItemTreeLoc<Id = N>>,
793-
) -> RawAttrs {
794-
let id = lookup.lookup(db).item_tree_id();
795-
let tree = id.item_tree(db);
796-
let attr_owner = N::attr_owner(id.value);
797-
tree.raw_attrs(attr_owner).clone()
817+
lookup: impl Lookup<Database = dyn DefDatabase, Data = impl AstIdLoc<Ast = N> + HasModule>,
818+
) -> Attrs {
819+
let loc = lookup.lookup(db);
820+
let source = loc.source(db);
821+
let span_map = db.span_map(source.file_id);
822+
let cfg_options = loc.krate(db).cfg_options(db);
823+
Attrs(RawAttrs::new_expanded(db, &source.value, span_map.as_ref(), cfg_options))
798824
}
799825

800826
pub(crate) fn fields_attrs_source_map(

crates/hir-def/src/db.rs

Lines changed: 15 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,11 @@
11
//! Defines database & queries for name resolution.
22
use base_db::{Crate, RootQueryDb, SourceDatabase};
33
use either::Either;
4-
use hir_expand::{EditionedFileId, HirFileId, MacroCallId, MacroDefId, db::ExpandDatabase};
5-
use intern::sym;
4+
use hir_expand::{
5+
EditionedFileId, HirFileId, InFile, Lookup, MacroCallId, MacroDefId, MacroDefKind,
6+
db::ExpandDatabase,
7+
};
8+
use intern::{Symbol, sym};
69
use la_arena::ArenaMap;
710
use syntax::{AstPtr, ast};
811
use thin_vec::ThinVec;
@@ -11,8 +14,8 @@ use triomphe::Arc;
1114
use crate::{
1215
AttrDefId, BlockId, BlockLoc, ConstId, ConstLoc, DefWithBodyId, EnumId, EnumLoc, EnumVariantId,
1316
EnumVariantLoc, ExternBlockId, ExternBlockLoc, ExternCrateId, ExternCrateLoc, FunctionId,
14-
FunctionLoc, GenericDefId, ImplId, ImplLoc, LocalFieldId, Macro2Id, Macro2Loc, MacroId,
15-
MacroRulesId, MacroRulesLoc, MacroRulesLocFlags, ProcMacroId, ProcMacroLoc, StaticId,
17+
FunctionLoc, GenericDefId, ImplId, ImplLoc, LocalFieldId, Macro2Id, Macro2Loc, MacroExpander,
18+
MacroId, MacroRulesId, MacroRulesLoc, MacroRulesLocFlags, ProcMacroId, ProcMacroLoc, StaticId,
1619
StaticLoc, StructId, StructLoc, TraitAliasId, TraitAliasLoc, TraitId, TraitLoc, TypeAliasId,
1720
TypeAliasLoc, UnionId, UnionLoc, UseId, UseLoc, VariantId,
1821
attr::{Attrs, AttrsWithOwner},
@@ -123,6 +126,8 @@ pub trait DefDatabase: InternDatabase + ExpandDatabase + SourceDatabase {
123126
id: VariantId,
124127
) -> (Arc<VariantFields>, Arc<ExpressionStoreSourceMap>);
125128

129+
// FIXME: Should we make this transparent? The only unstable thing in `enum_variants_with_diagnostics()`
130+
// is ast ids, and ast ids are pretty stable now.
126131
#[salsa::tracked]
127132
fn enum_variants(&self, id: EnumId) -> Arc<EnumVariants> {
128133
self.enum_variants_with_diagnostics(id).0
@@ -263,6 +268,9 @@ pub trait DefDatabase: InternDatabase + ExpandDatabase + SourceDatabase {
263268
e: TypeAliasId,
264269
) -> (Arc<TypeAliasSignature>, Arc<ExpressionStoreSourceMap>);
265270

271+
#[salsa::invoke(crate::signatures::extern_block_abi_query)]
272+
fn extern_block_abi(&self, extern_block: ExternBlockId) -> Option<Symbol>;
273+
266274
// endregion:data
267275

268276
#[salsa::invoke(Body::body_with_source_map_query)]
@@ -399,10 +407,6 @@ fn crate_supports_no_std(db: &dyn DefDatabase, crate_id: Crate) -> bool {
399407
}
400408

401409
fn macro_def(db: &dyn DefDatabase, id: MacroId) -> MacroDefId {
402-
use hir_expand::InFile;
403-
404-
use crate::{Lookup, MacroDefKind, MacroExpander};
405-
406410
let kind = |expander, file_id, m| {
407411
let in_file = InFile::new(file_id, m);
408412
match expander {
@@ -418,11 +422,9 @@ fn macro_def(db: &dyn DefDatabase, id: MacroId) -> MacroDefId {
418422
MacroId::Macro2Id(it) => {
419423
let loc: Macro2Loc = it.lookup(db);
420424

421-
let item_tree = loc.id.item_tree(db);
422-
let makro = &item_tree[loc.id.value];
423425
MacroDefId {
424426
krate: loc.container.krate,
425-
kind: kind(loc.expander, loc.id.file_id(), makro.ast_id.upcast()),
427+
kind: kind(loc.expander, loc.id.file_id, loc.id.value.upcast()),
426428
local_inner: false,
427429
allow_internal_unsafe: loc.allow_internal_unsafe,
428430
edition: loc.edition,
@@ -431,11 +433,9 @@ fn macro_def(db: &dyn DefDatabase, id: MacroId) -> MacroDefId {
431433
MacroId::MacroRulesId(it) => {
432434
let loc: MacroRulesLoc = it.lookup(db);
433435

434-
let item_tree = loc.id.item_tree(db);
435-
let makro = &item_tree[loc.id.value];
436436
MacroDefId {
437437
krate: loc.container.krate,
438-
kind: kind(loc.expander, loc.id.file_id(), makro.ast_id.upcast()),
438+
kind: kind(loc.expander, loc.id.file_id, loc.id.value.upcast()),
439439
local_inner: loc.flags.contains(MacroRulesLocFlags::LOCAL_INNER),
440440
allow_internal_unsafe: loc
441441
.flags
@@ -446,15 +446,9 @@ fn macro_def(db: &dyn DefDatabase, id: MacroId) -> MacroDefId {
446446
MacroId::ProcMacroId(it) => {
447447
let loc = it.lookup(db);
448448

449-
let item_tree = loc.id.item_tree(db);
450-
let makro = &item_tree[loc.id.value];
451449
MacroDefId {
452450
krate: loc.container.krate,
453-
kind: MacroDefKind::ProcMacro(
454-
InFile::new(loc.id.file_id(), makro.ast_id),
455-
loc.expander,
456-
loc.kind,
457-
),
451+
kind: MacroDefKind::ProcMacro(loc.id, loc.expander, loc.kind),
458452
local_inner: false,
459453
allow_internal_unsafe: false,
460454
edition: loc.edition,

0 commit comments

Comments
 (0)