Skip to content

Commit b21bf25

Browse files
committed
Collect diagnostics in queries instead of nameres
1 parent 89107d5 commit b21bf25

File tree

5 files changed

+194
-116
lines changed

5 files changed

+194
-116
lines changed

crates/hir-def/src/adt.rs

Lines changed: 129 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ use base_db::CrateId;
66
use either::Either;
77
use hir_expand::{
88
name::{AsName, Name},
9-
InFile,
9+
HirFileId, InFile,
1010
};
1111
use la_arena::{Arena, ArenaMap};
1212
use syntax::ast::{self, HasName, HasVisibility};
@@ -17,13 +17,15 @@ use crate::{
1717
builtin_type::{BuiltinInt, BuiltinUint},
1818
db::DefDatabase,
1919
intern::Interned,
20-
item_tree::{AttrOwner, Field, Fields, ItemTree, ModItem, RawVisibilityId},
20+
item_tree::{AttrOwner, Field, FieldAstId, Fields, ItemTree, ModItem, RawVisibilityId},
21+
nameres::diagnostics::DefDiagnostic,
2122
src::HasChildSource,
2223
src::HasSource,
2324
trace::Trace,
2425
type_ref::TypeRef,
2526
visibility::RawVisibility,
26-
EnumId, LocalEnumVariantId, LocalFieldId, Lookup, ModuleId, StructId, UnionId, VariantId,
27+
EnumId, LocalEnumVariantId, LocalFieldId, LocalModuleId, Lookup, ModuleId, StructId, UnionId,
28+
VariantId,
2729
};
2830
use cfg::CfgOptions;
2931

@@ -143,43 +145,87 @@ fn parse_repr_tt(tt: &Subtree) -> Option<ReprData> {
143145

144146
impl StructData {
145147
pub(crate) fn struct_data_query(db: &dyn DefDatabase, id: StructId) -> Arc<StructData> {
148+
db.struct_data_with_diagnostics(id).0
149+
}
150+
151+
pub(crate) fn struct_data_with_diagnostics_query(
152+
db: &dyn DefDatabase,
153+
id: StructId,
154+
) -> (Arc<StructData>, Arc<Vec<DefDiagnostic>>) {
146155
let loc = id.lookup(db);
147156
let krate = loc.container.krate;
148157
let item_tree = loc.id.item_tree(db);
149158
let repr = repr_from_value(db, krate, &item_tree, ModItem::from(loc.id.value).into());
150159
let cfg_options = db.crate_graph()[loc.container.krate].cfg_options.clone();
151160

152161
let strukt = &item_tree[loc.id.value];
153-
let variant_data = lower_fields(db, krate, &item_tree, &cfg_options, &strukt.fields, None);
154-
Arc::new(StructData {
155-
name: strukt.name.clone(),
156-
variant_data: Arc::new(variant_data),
157-
repr,
158-
visibility: item_tree[strukt.visibility].clone(),
159-
})
162+
let (variant_data, diagnostics) = lower_fields(
163+
db,
164+
krate,
165+
loc.id.file_id(),
166+
loc.container.local_id,
167+
&item_tree,
168+
&cfg_options,
169+
&strukt.fields,
170+
None,
171+
);
172+
(
173+
Arc::new(StructData {
174+
name: strukt.name.clone(),
175+
variant_data: Arc::new(variant_data),
176+
repr,
177+
visibility: item_tree[strukt.visibility].clone(),
178+
}),
179+
Arc::new(diagnostics),
180+
)
160181
}
161182

162183
pub(crate) fn union_data_query(db: &dyn DefDatabase, id: UnionId) -> Arc<StructData> {
184+
db.union_data_with_diagnostics(id).0
185+
}
186+
187+
pub(crate) fn union_data_with_diagnostics_query(
188+
db: &dyn DefDatabase,
189+
id: UnionId,
190+
) -> (Arc<StructData>, Arc<Vec<DefDiagnostic>>) {
163191
let loc = id.lookup(db);
164192
let krate = loc.container.krate;
165193
let item_tree = loc.id.item_tree(db);
166194
let repr = repr_from_value(db, krate, &item_tree, ModItem::from(loc.id.value).into());
167195
let cfg_options = db.crate_graph()[loc.container.krate].cfg_options.clone();
168196

169197
let union = &item_tree[loc.id.value];
170-
let variant_data = lower_fields(db, krate, &item_tree, &cfg_options, &union.fields, None);
171-
172-
Arc::new(StructData {
173-
name: union.name.clone(),
174-
variant_data: Arc::new(variant_data),
175-
repr,
176-
visibility: item_tree[union.visibility].clone(),
177-
})
198+
let (variant_data, diagnostics) = lower_fields(
199+
db,
200+
krate,
201+
loc.id.file_id(),
202+
loc.container.local_id,
203+
&item_tree,
204+
&cfg_options,
205+
&union.fields,
206+
None,
207+
);
208+
(
209+
Arc::new(StructData {
210+
name: union.name.clone(),
211+
variant_data: Arc::new(variant_data),
212+
repr,
213+
visibility: item_tree[union.visibility].clone(),
214+
}),
215+
Arc::new(diagnostics),
216+
)
178217
}
179218
}
180219

181220
impl EnumData {
182221
pub(crate) fn enum_data_query(db: &dyn DefDatabase, e: EnumId) -> Arc<EnumData> {
222+
db.enum_data_with_diagnostics(e).0
223+
}
224+
225+
pub(crate) fn enum_data_with_diagnostics_query(
226+
db: &dyn DefDatabase,
227+
e: EnumId,
228+
) -> (Arc<EnumData>, Arc<Vec<DefDiagnostic>>) {
183229
let loc = e.lookup(db);
184230
let krate = loc.container.krate;
185231
let item_tree = loc.id.item_tree(db);
@@ -188,31 +234,46 @@ impl EnumData {
188234

189235
let enum_ = &item_tree[loc.id.value];
190236
let mut variants = Arena::new();
237+
let mut diagnostics = Vec::new();
191238
for tree_id in enum_.variants.clone() {
192-
if item_tree.attrs(db, krate, tree_id.into()).is_cfg_enabled(&cfg_options) {
193-
let var = &item_tree[tree_id];
194-
let var_data = lower_fields(
239+
let attrs = item_tree.attrs(db, krate, tree_id.into());
240+
let var = &item_tree[tree_id];
241+
if attrs.is_cfg_enabled(&cfg_options) {
242+
let (var_data, field_diagnostics) = lower_fields(
195243
db,
196244
krate,
245+
loc.id.file_id(),
246+
loc.container.local_id,
197247
&item_tree,
198248
&cfg_options,
199249
&var.fields,
200250
Some(enum_.visibility),
201251
);
252+
diagnostics.extend(field_diagnostics);
202253

203254
variants.alloc(EnumVariantData {
204255
name: var.name.clone(),
205256
variant_data: Arc::new(var_data),
206257
});
258+
} else {
259+
diagnostics.push(DefDiagnostic::unconfigured_code(
260+
loc.container.local_id,
261+
InFile::new(loc.id.file_id(), var.ast_id.upcast()),
262+
attrs.cfg().unwrap(),
263+
cfg_options.clone(),
264+
))
207265
}
208266
}
209267

210-
Arc::new(EnumData {
211-
name: enum_.name.clone(),
212-
variants,
213-
repr,
214-
visibility: item_tree[enum_.visibility].clone(),
215-
})
268+
(
269+
Arc::new(EnumData {
270+
name: enum_.name.clone(),
271+
variants,
272+
repr,
273+
visibility: item_tree[enum_.visibility].clone(),
274+
}),
275+
Arc::new(diagnostics),
276+
)
216277
}
217278

218279
pub fn variant(&self, name: &Name) -> Option<LocalEnumVariantId> {
@@ -384,31 +445,64 @@ fn lower_struct(
384445
fn lower_fields(
385446
db: &dyn DefDatabase,
386447
krate: CrateId,
448+
current_file_id: HirFileId,
449+
container: LocalModuleId,
387450
item_tree: &ItemTree,
388451
cfg_options: &CfgOptions,
389452
fields: &Fields,
390453
override_visibility: Option<RawVisibilityId>,
391-
) -> VariantData {
454+
) -> (VariantData, Vec<DefDiagnostic>) {
455+
let mut diagnostics = Vec::new();
392456
match fields {
393457
Fields::Record(flds) => {
394458
let mut arena = Arena::new();
395459
for field_id in flds.clone() {
396-
if item_tree.attrs(db, krate, field_id.into()).is_cfg_enabled(cfg_options) {
397-
arena.alloc(lower_field(item_tree, &item_tree[field_id], override_visibility));
460+
let attrs = item_tree.attrs(db, krate, field_id.into());
461+
let field = &item_tree[field_id];
462+
if attrs.is_cfg_enabled(cfg_options) {
463+
arena.alloc(lower_field(item_tree, field, override_visibility));
464+
} else {
465+
diagnostics.push(DefDiagnostic::unconfigured_code(
466+
container,
467+
InFile::new(
468+
current_file_id,
469+
match field.ast_id {
470+
FieldAstId::Record(it) => it.upcast(),
471+
FieldAstId::Tuple(it) => it.upcast(),
472+
},
473+
),
474+
attrs.cfg().unwrap(),
475+
cfg_options.clone(),
476+
))
398477
}
399478
}
400-
VariantData::Record(arena)
479+
(VariantData::Record(arena), diagnostics)
401480
}
402481
Fields::Tuple(flds) => {
403482
let mut arena = Arena::new();
404483
for field_id in flds.clone() {
405-
if item_tree.attrs(db, krate, field_id.into()).is_cfg_enabled(cfg_options) {
406-
arena.alloc(lower_field(item_tree, &item_tree[field_id], override_visibility));
484+
let attrs = item_tree.attrs(db, krate, field_id.into());
485+
let field = &item_tree[field_id];
486+
if attrs.is_cfg_enabled(cfg_options) {
487+
arena.alloc(lower_field(item_tree, field, override_visibility));
488+
} else {
489+
diagnostics.push(DefDiagnostic::unconfigured_code(
490+
container,
491+
InFile::new(
492+
current_file_id,
493+
match field.ast_id {
494+
FieldAstId::Record(it) => it.upcast(),
495+
FieldAstId::Tuple(it) => it.upcast(),
496+
},
497+
),
498+
attrs.cfg().unwrap(),
499+
cfg_options.clone(),
500+
))
407501
}
408502
}
409-
VariantData::Tuple(arena)
503+
(VariantData::Tuple(arena), diagnostics)
410504
}
411-
Fields::Unit => VariantData::Unit,
505+
Fields::Unit => (VariantData::Unit, diagnostics),
412506
}
413507
}
414508

crates/hir-def/src/db.rs

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,12 +97,27 @@ pub trait DefDatabase: InternDatabase + AstDatabase + Upcast<dyn AstDatabase> {
9797
#[salsa::invoke(StructData::struct_data_query)]
9898
fn struct_data(&self, id: StructId) -> Arc<StructData>;
9999

100+
#[salsa::invoke(StructData::struct_data_with_diagnostics_query)]
101+
fn struct_data_with_diagnostics(
102+
&self,
103+
id: StructId,
104+
) -> (Arc<StructData>, Arc<Vec<DefDiagnostic>>);
105+
100106
#[salsa::invoke(StructData::union_data_query)]
101107
fn union_data(&self, id: UnionId) -> Arc<StructData>;
102108

109+
#[salsa::invoke(StructData::union_data_with_diagnostics_query)]
110+
fn union_data_with_diagnostics(
111+
&self,
112+
id: UnionId,
113+
) -> (Arc<StructData>, Arc<Vec<DefDiagnostic>>);
114+
103115
#[salsa::invoke(EnumData::enum_data_query)]
104116
fn enum_data(&self, e: EnumId) -> Arc<EnumData>;
105117

118+
#[salsa::invoke(EnumData::enum_data_with_diagnostics_query)]
119+
fn enum_data_with_diagnostics(&self, e: EnumId) -> (Arc<EnumData>, Arc<Vec<DefDiagnostic>>);
120+
106121
#[salsa::invoke(ImplData::impl_data_query)]
107122
fn impl_data(&self, e: ImplId) -> Arc<ImplData>;
108123

0 commit comments

Comments
 (0)