aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorbors[bot] <26634292+bors[bot]@users.noreply.github.com>2020-06-25 16:18:35 +0100
committerGitHub <[email protected]>2020-06-25 16:18:35 +0100
commitba7286345256eb1140853dc0daa3c276e2ddcbbe (patch)
treee5f328bc2e9794cc93413ecba4a121f8f6f020ad
parent96d335d578984b42c2e00c715c924bceca391a6c (diff)
parentdad2f75b91bcc6ac7620326fec082aca7edea7ce (diff)
Merge #5063
5063: Store field/variant attrs in ItemTree and use it for adt.rs queries r=jonas-schievink a=jonas-schievink Co-authored-by: Jonas Schievink <[email protected]>
-rw-r--r--crates/ra_hir_def/src/adt.rs94
-rw-r--r--crates/ra_hir_def/src/attr.rs2
-rw-r--r--crates/ra_hir_def/src/data.rs4
-rw-r--r--crates/ra_hir_def/src/item_tree.rs70
-rw-r--r--crates/ra_hir_def/src/item_tree/lower.rs39
-rw-r--r--crates/ra_hir_def/src/item_tree/tests.rs10
-rw-r--r--crates/ra_hir_def/src/nameres/collector.rs4
7 files changed, 162 insertions, 61 deletions
diff --git a/crates/ra_hir_def/src/adt.rs b/crates/ra_hir_def/src/adt.rs
index 2bc34d449..4994a2125 100644
--- a/crates/ra_hir_def/src/adt.rs
+++ b/crates/ra_hir_def/src/adt.rs
@@ -8,12 +8,12 @@ use hir_expand::{
8 InFile, 8 InFile,
9}; 9};
10use ra_arena::{map::ArenaMap, Arena}; 10use ra_arena::{map::ArenaMap, Arena};
11use ra_prof::profile;
12use ra_syntax::ast::{self, NameOwner, TypeAscriptionOwner, VisibilityOwner}; 11use ra_syntax::ast::{self, NameOwner, TypeAscriptionOwner, VisibilityOwner};
13 12
14use crate::{ 13use crate::{
15 body::{CfgExpander, LowerCtx}, 14 body::{CfgExpander, LowerCtx},
16 db::DefDatabase, 15 db::DefDatabase,
16 item_tree::{Field, Fields, ItemTree},
17 src::HasChildSource, 17 src::HasChildSource,
18 src::HasSource, 18 src::HasSource,
19 trace::Trace, 19 trace::Trace,
@@ -22,6 +22,7 @@ use crate::{
22 EnumId, HasModule, LocalEnumVariantId, LocalFieldId, Lookup, ModuleId, StructId, UnionId, 22 EnumId, HasModule, LocalEnumVariantId, LocalFieldId, Lookup, ModuleId, StructId, UnionId,
23 VariantId, 23 VariantId,
24}; 24};
25use ra_cfg::CfgOptions;
25 26
26/// Note that we use `StructData` for unions as well! 27/// Note that we use `StructData` for unions as well!
27#[derive(Debug, Clone, PartialEq, Eq)] 28#[derive(Debug, Clone, PartialEq, Eq)]
@@ -59,39 +60,48 @@ pub struct FieldData {
59 60
60impl StructData { 61impl StructData {
61 pub(crate) fn struct_data_query(db: &dyn DefDatabase, id: StructId) -> Arc<StructData> { 62 pub(crate) fn struct_data_query(db: &dyn DefDatabase, id: StructId) -> Arc<StructData> {
62 let src = id.lookup(db).source(db); 63 let loc = id.lookup(db);
64 let item_tree = db.item_tree(loc.id.file_id);
65 let cfg_options = db.crate_graph()[loc.container.module(db).krate].cfg_options.clone();
63 66
64 let name = src.value.name().map_or_else(Name::missing, |n| n.as_name()); 67 let strukt = &item_tree[loc.id.value];
65 let variant_data = 68 let variant_data = lower_fields(&item_tree, &cfg_options, &strukt.fields);
66 VariantData::new(db, src.map(|s| s.kind()), id.lookup(db).container.module(db)); 69
67 let variant_data = Arc::new(variant_data); 70 Arc::new(StructData { name: strukt.name.clone(), variant_data: Arc::new(variant_data) })
68 Arc::new(StructData { name, variant_data })
69 } 71 }
70 pub(crate) fn union_data_query(db: &dyn DefDatabase, id: UnionId) -> Arc<StructData> { 72 pub(crate) fn union_data_query(db: &dyn DefDatabase, id: UnionId) -> Arc<StructData> {
71 let src = id.lookup(db).source(db); 73 let loc = id.lookup(db);
72 let name = src.value.name().map_or_else(Name::missing, |n| n.as_name()); 74 let item_tree = db.item_tree(loc.id.file_id);
73 let variant_data = VariantData::new( 75 let cfg_options = db.crate_graph()[loc.container.module(db).krate].cfg_options.clone();
74 db, 76
75 src.map(|s| { 77 let union = &item_tree[loc.id.value];
76 s.record_field_def_list() 78 let variant_data = lower_fields(&item_tree, &cfg_options, &union.fields);
77 .map(ast::StructKind::Record) 79
78 .unwrap_or(ast::StructKind::Unit) 80 Arc::new(StructData { name: union.name.clone(), variant_data: Arc::new(variant_data) })
79 }),
80 id.lookup(db).container.module(db),
81 );
82 let variant_data = Arc::new(variant_data);
83 Arc::new(StructData { name, variant_data })
84 } 81 }
85} 82}
86 83
87impl EnumData { 84impl EnumData {
88 pub(crate) fn enum_data_query(db: &dyn DefDatabase, e: EnumId) -> Arc<EnumData> { 85 pub(crate) fn enum_data_query(db: &dyn DefDatabase, e: EnumId) -> Arc<EnumData> {
89 let _p = profile("enum_data_query"); 86 let loc = e.lookup(db);
90 let src = e.lookup(db).source(db); 87 let item_tree = db.item_tree(loc.id.file_id);
91 let name = src.value.name().map_or_else(Name::missing, |n| n.as_name()); 88 let cfg_options = db.crate_graph()[loc.container.module(db).krate].cfg_options.clone();
92 let mut trace = Trace::new_for_arena(); 89
93 lower_enum(db, &mut trace, &src, e.lookup(db).container.module(db)); 90 let enum_ = &item_tree[loc.id.value];
94 Arc::new(EnumData { name, variants: trace.into_arena() }) 91 let mut variants = Arena::new();
92 for var_id in enum_.variants.clone() {
93 if item_tree.attrs(var_id.into()).is_cfg_enabled(&cfg_options) {
94 let var = &item_tree[var_id];
95 let var_data = lower_fields(&item_tree, &cfg_options, &var.fields);
96
97 variants.alloc(EnumVariantData {
98 name: var.name.clone(),
99 variant_data: Arc::new(var_data),
100 });
101 }
102 }
103
104 Arc::new(EnumData { name: enum_.name.clone(), variants })
95 } 105 }
96 106
97 pub fn variant(&self, name: &Name) -> Option<LocalEnumVariantId> { 107 pub fn variant(&self, name: &Name) -> Option<LocalEnumVariantId> {
@@ -251,3 +261,35 @@ fn lower_struct(
251 ast::StructKind::Unit => StructKind::Unit, 261 ast::StructKind::Unit => StructKind::Unit,
252 } 262 }
253} 263}
264
265fn lower_fields(item_tree: &ItemTree, cfg_options: &CfgOptions, fields: &Fields) -> VariantData {
266 match fields {
267 Fields::Record(flds) => {
268 let mut arena = Arena::new();
269 for field_id in flds.clone() {
270 if item_tree.attrs(field_id.into()).is_cfg_enabled(cfg_options) {
271 arena.alloc(lower_field(item_tree, &item_tree[field_id]));
272 }
273 }
274 VariantData::Record(arena)
275 }
276 Fields::Tuple(flds) => {
277 let mut arena = Arena::new();
278 for field_id in flds.clone() {
279 if item_tree.attrs(field_id.into()).is_cfg_enabled(cfg_options) {
280 arena.alloc(lower_field(item_tree, &item_tree[field_id]));
281 }
282 }
283 VariantData::Tuple(arena)
284 }
285 Fields::Unit => VariantData::Unit,
286 }
287}
288
289fn lower_field(item_tree: &ItemTree, field: &Field) -> FieldData {
290 FieldData {
291 name: field.name.clone(),
292 type_ref: field.type_ref.clone(),
293 visibility: item_tree[field.visibility].clone(),
294 }
295}
diff --git a/crates/ra_hir_def/src/attr.rs b/crates/ra_hir_def/src/attr.rs
index 197737ffc..e228e2145 100644
--- a/crates/ra_hir_def/src/attr.rs
+++ b/crates/ra_hir_def/src/attr.rs
@@ -208,5 +208,5 @@ where
208fn attrs_from_item_tree<N: ItemTreeNode>(id: ItemTreeId<N>, db: &dyn DefDatabase) -> Attrs { 208fn attrs_from_item_tree<N: ItemTreeNode>(id: ItemTreeId<N>, db: &dyn DefDatabase) -> Attrs {
209 let tree = db.item_tree(id.file_id); 209 let tree = db.item_tree(id.file_id);
210 let mod_item = N::id_to_mod_item(id.value); 210 let mod_item = N::id_to_mod_item(id.value);
211 tree.attrs(mod_item).clone() 211 tree.attrs(mod_item.into()).clone()
212} 212}
diff --git a/crates/ra_hir_def/src/data.rs b/crates/ra_hir_def/src/data.rs
index f9e5701db..282ade2a3 100644
--- a/crates/ra_hir_def/src/data.rs
+++ b/crates/ra_hir_def/src/data.rs
@@ -40,7 +40,7 @@ impl FunctionData {
40 name: func.name.clone(), 40 name: func.name.clone(),
41 params: func.params.to_vec(), 41 params: func.params.to_vec(),
42 ret_type: func.ret_type.clone(), 42 ret_type: func.ret_type.clone(),
43 attrs: item_tree.attrs(loc.id.value.into()).clone(), 43 attrs: item_tree.attrs(ModItem::from(loc.id.value).into()).clone(),
44 has_self_param: func.has_self_param, 44 has_self_param: func.has_self_param,
45 is_unsafe: func.is_unsafe, 45 is_unsafe: func.is_unsafe,
46 visibility: item_tree[func.visibility].clone(), 46 visibility: item_tree[func.visibility].clone(),
@@ -224,7 +224,7 @@ fn collect_items(
224 match item { 224 match item {
225 AssocItem::Function(id) => { 225 AssocItem::Function(id) => {
226 let item = &item_tree[id]; 226 let item = &item_tree[id];
227 let attrs = item_tree.attrs(id.into()); 227 let attrs = item_tree.attrs(ModItem::from(id).into());
228 if !attrs.is_cfg_enabled(&cfg_options) { 228 if !attrs.is_cfg_enabled(&cfg_options) {
229 continue; 229 continue;
230 } 230 }
diff --git a/crates/ra_hir_def/src/item_tree.rs b/crates/ra_hir_def/src/item_tree.rs
index d7bc64e6c..3e603bd55 100644
--- a/crates/ra_hir_def/src/item_tree.rs
+++ b/crates/ra_hir_def/src/item_tree.rs
@@ -5,6 +5,7 @@ mod lower;
5mod tests; 5mod tests;
6 6
7use std::{ 7use std::{
8 any::type_name,
8 fmt::{self, Debug}, 9 fmt::{self, Debug},
9 hash::{Hash, Hasher}, 10 hash::{Hash, Hasher},
10 marker::PhantomData, 11 marker::PhantomData,
@@ -178,8 +179,8 @@ impl ItemTree {
178 self.attrs.get(&AttrOwner::TopLevel).unwrap_or(&Attrs::EMPTY) 179 self.attrs.get(&AttrOwner::TopLevel).unwrap_or(&Attrs::EMPTY)
179 } 180 }
180 181
181 pub fn attrs(&self, of: ModItem) -> &Attrs { 182 pub fn attrs(&self, of: AttrOwner) -> &Attrs {
182 self.attrs.get(&AttrOwner::ModItem(of)).unwrap_or(&Attrs::EMPTY) 183 self.attrs.get(&of).unwrap_or(&Attrs::EMPTY)
183 } 184 }
184 185
185 /// Returns the lowered inner items that `ast` corresponds to. 186 /// Returns the lowered inner items that `ast` corresponds to.
@@ -282,15 +283,32 @@ struct ItemTreeData {
282} 283}
283 284
284#[derive(Debug, Eq, PartialEq, Hash)] 285#[derive(Debug, Eq, PartialEq, Hash)]
285enum AttrOwner { 286pub enum AttrOwner {
286 /// Attributes on an item. 287 /// Attributes on an item.
287 ModItem(ModItem), 288 ModItem(ModItem),
288 /// Inner attributes of the source file. 289 /// Inner attributes of the source file.
289 TopLevel, 290 TopLevel,
291
292 Variant(Idx<Variant>),
293 Field(Idx<Field>),
290 // FIXME: Store variant and field attrs, and stop reparsing them in `attrs_query`. 294 // FIXME: Store variant and field attrs, and stop reparsing them in `attrs_query`.
291} 295}
292 296
293/// Trait implemented by all nodes in the item tree. 297macro_rules! from_attrs {
298 ( $( $var:ident($t:ty) ),+ ) => {
299 $(
300 impl From<$t> for AttrOwner {
301 fn from(t: $t) -> AttrOwner {
302 AttrOwner::$var(t)
303 }
304 }
305 )+
306 };
307}
308
309from_attrs!(ModItem(ModItem), Variant(Idx<Variant>), Field(Idx<Field>));
310
311/// Trait implemented by all item nodes in the item tree.
294pub trait ItemTreeNode: Clone { 312pub trait ItemTreeNode: Clone {
295 type Source: AstNode + Into<ast::ModuleItem>; 313 type Source: AstNode + Into<ast::ModuleItem>;
296 314
@@ -523,7 +541,7 @@ pub struct Enum {
523 pub name: Name, 541 pub name: Name,
524 pub visibility: RawVisibilityId, 542 pub visibility: RawVisibilityId,
525 pub generic_params: GenericParamsId, 543 pub generic_params: GenericParamsId,
526 pub variants: Range<Idx<Variant>>, 544 pub variants: IdRange<Variant>,
527 pub ast_id: FileAstId<ast::EnumDef>, 545 pub ast_id: FileAstId<ast::EnumDef>,
528} 546}
529 547
@@ -681,10 +699,48 @@ pub struct Variant {
681 pub fields: Fields, 699 pub fields: Fields,
682} 700}
683 701
702pub struct IdRange<T> {
703 range: Range<u32>,
704 _p: PhantomData<T>,
705}
706
707impl<T> IdRange<T> {
708 fn new(range: Range<Idx<T>>) -> Self {
709 Self { range: range.start.into_raw().into()..range.end.into_raw().into(), _p: PhantomData }
710 }
711}
712
713impl<T> Iterator for IdRange<T> {
714 type Item = Idx<T>;
715 fn next(&mut self) -> Option<Self::Item> {
716 self.range.next().map(|raw| Idx::from_raw(raw.into()))
717 }
718}
719
720impl<T> fmt::Debug for IdRange<T> {
721 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
722 f.debug_tuple(&format!("IdRange::<{}>", type_name::<T>())).field(&self.range).finish()
723 }
724}
725
726impl<T> Clone for IdRange<T> {
727 fn clone(&self) -> Self {
728 Self { range: self.range.clone(), _p: PhantomData }
729 }
730}
731
732impl<T> PartialEq for IdRange<T> {
733 fn eq(&self, other: &Self) -> bool {
734 self.range == other.range
735 }
736}
737
738impl<T> Eq for IdRange<T> {}
739
684#[derive(Debug, Clone, PartialEq, Eq)] 740#[derive(Debug, Clone, PartialEq, Eq)]
685pub enum Fields { 741pub enum Fields {
686 Record(Range<Idx<Field>>), 742 Record(IdRange<Field>),
687 Tuple(Range<Idx<Field>>), 743 Tuple(IdRange<Field>),
688 Unit, 744 Unit,
689} 745}
690 746
diff --git a/crates/ra_hir_def/src/item_tree/lower.rs b/crates/ra_hir_def/src/item_tree/lower.rs
index f10ad25f7..5149dd141 100644
--- a/crates/ra_hir_def/src/item_tree/lower.rs
+++ b/crates/ra_hir_def/src/item_tree/lower.rs
@@ -126,15 +126,15 @@ impl Ctx {
126 126
127 if !attrs.is_empty() { 127 if !attrs.is_empty() {
128 for item in items.iter().flat_map(|items| &items.0) { 128 for item in items.iter().flat_map(|items| &items.0) {
129 self.add_attrs(*item, attrs.clone()); 129 self.add_attrs((*item).into(), attrs.clone());
130 } 130 }
131 } 131 }
132 132
133 items 133 items
134 } 134 }
135 135
136 fn add_attrs(&mut self, item: ModItem, attrs: Attrs) { 136 fn add_attrs(&mut self, item: AttrOwner, attrs: Attrs) {
137 match self.tree.attrs.entry(AttrOwner::ModItem(item)) { 137 match self.tree.attrs.entry(item) {
138 Entry::Occupied(mut entry) => { 138 Entry::Occupied(mut entry) => {
139 *entry.get_mut() = entry.get().merge(attrs); 139 *entry.get_mut() = entry.get().merge(attrs);
140 } 140 }
@@ -196,15 +196,16 @@ impl Ctx {
196 } 196 }
197 } 197 }
198 198
199 fn lower_record_fields(&mut self, fields: &ast::RecordFieldDefList) -> Range<Idx<Field>> { 199 fn lower_record_fields(&mut self, fields: &ast::RecordFieldDefList) -> IdRange<Field> {
200 let start = self.next_field_idx(); 200 let start = self.next_field_idx();
201 for field in fields.fields() { 201 for field in fields.fields() {
202 if let Some(data) = self.lower_record_field(&field) { 202 if let Some(data) = self.lower_record_field(&field) {
203 self.data().fields.alloc(data); 203 let idx = self.data().fields.alloc(data);
204 self.add_attrs(idx.into(), Attrs::new(&field, &self.hygiene));
204 } 205 }
205 } 206 }
206 let end = self.next_field_idx(); 207 let end = self.next_field_idx();
207 start..end 208 IdRange::new(start..end)
208 } 209 }
209 210
210 fn lower_record_field(&mut self, field: &ast::RecordFieldDef) -> Option<Field> { 211 fn lower_record_field(&mut self, field: &ast::RecordFieldDef) -> Option<Field> {
@@ -215,15 +216,16 @@ impl Ctx {
215 Some(res) 216 Some(res)
216 } 217 }
217 218
218 fn lower_tuple_fields(&mut self, fields: &ast::TupleFieldDefList) -> Range<Idx<Field>> { 219 fn lower_tuple_fields(&mut self, fields: &ast::TupleFieldDefList) -> IdRange<Field> {
219 let start = self.next_field_idx(); 220 let start = self.next_field_idx();
220 for (i, field) in fields.fields().enumerate() { 221 for (i, field) in fields.fields().enumerate() {
221 if let Some(data) = self.lower_tuple_field(i, &field) { 222 if let Some(data) = self.lower_tuple_field(i, &field) {
222 self.data().fields.alloc(data); 223 let idx = self.data().fields.alloc(data);
224 self.add_attrs(idx.into(), Attrs::new(&field, &self.hygiene));
223 } 225 }
224 } 226 }
225 let end = self.next_field_idx(); 227 let end = self.next_field_idx();
226 start..end 228 IdRange::new(start..end)
227 } 229 }
228 230
229 fn lower_tuple_field(&mut self, idx: usize, field: &ast::TupleFieldDef) -> Option<Field> { 231 fn lower_tuple_field(&mut self, idx: usize, field: &ast::TupleFieldDef) -> Option<Field> {
@@ -242,7 +244,7 @@ impl Ctx {
242 Some(record_field_def_list) => { 244 Some(record_field_def_list) => {
243 self.lower_fields(&StructKind::Record(record_field_def_list)) 245 self.lower_fields(&StructKind::Record(record_field_def_list))
244 } 246 }
245 None => Fields::Record(self.next_field_idx()..self.next_field_idx()), 247 None => Fields::Record(IdRange::new(self.next_field_idx()..self.next_field_idx())),
246 }; 248 };
247 let ast_id = self.source_ast_id_map.ast_id(union); 249 let ast_id = self.source_ast_id_map.ast_id(union);
248 let res = Union { name, visibility, generic_params, fields, ast_id }; 250 let res = Union { name, visibility, generic_params, fields, ast_id };
@@ -255,22 +257,23 @@ impl Ctx {
255 let generic_params = self.lower_generic_params(GenericsOwner::Enum, enum_); 257 let generic_params = self.lower_generic_params(GenericsOwner::Enum, enum_);
256 let variants = match &enum_.variant_list() { 258 let variants = match &enum_.variant_list() {
257 Some(variant_list) => self.lower_variants(variant_list), 259 Some(variant_list) => self.lower_variants(variant_list),
258 None => self.next_variant_idx()..self.next_variant_idx(), 260 None => IdRange::new(self.next_variant_idx()..self.next_variant_idx()),
259 }; 261 };
260 let ast_id = self.source_ast_id_map.ast_id(enum_); 262 let ast_id = self.source_ast_id_map.ast_id(enum_);
261 let res = Enum { name, visibility, generic_params, variants, ast_id }; 263 let res = Enum { name, visibility, generic_params, variants, ast_id };
262 Some(id(self.data().enums.alloc(res))) 264 Some(id(self.data().enums.alloc(res)))
263 } 265 }
264 266
265 fn lower_variants(&mut self, variants: &ast::EnumVariantList) -> Range<Idx<Variant>> { 267 fn lower_variants(&mut self, variants: &ast::EnumVariantList) -> IdRange<Variant> {
266 let start = self.next_variant_idx(); 268 let start = self.next_variant_idx();
267 for variant in variants.variants() { 269 for variant in variants.variants() {
268 if let Some(data) = self.lower_variant(&variant) { 270 if let Some(data) = self.lower_variant(&variant) {
269 self.data().variants.alloc(data); 271 let idx = self.data().variants.alloc(data);
272 self.add_attrs(idx.into(), Attrs::new(&variant, &self.hygiene));
270 } 273 }
271 } 274 }
272 let end = self.next_variant_idx(); 275 let end = self.next_variant_idx();
273 start..end 276 IdRange::new(start..end)
274 } 277 }
275 278
276 fn lower_variant(&mut self, variant: &ast::EnumVariant) -> Option<Variant> { 279 fn lower_variant(&mut self, variant: &ast::EnumVariant) -> Option<Variant> {
@@ -419,7 +422,7 @@ impl Ctx {
419 let attrs = Attrs::new(&item, &this.hygiene); 422 let attrs = Attrs::new(&item, &this.hygiene);
420 this.collect_inner_items(item.syntax()); 423 this.collect_inner_items(item.syntax());
421 this.lower_assoc_item(&item).map(|item| { 424 this.lower_assoc_item(&item).map(|item| {
422 this.add_attrs(item.into(), attrs); 425 this.add_attrs(ModItem::from(item).into(), attrs);
423 item 426 item
424 }) 427 })
425 }) 428 })
@@ -453,7 +456,7 @@ impl Ctx {
453 self.collect_inner_items(item.syntax()); 456 self.collect_inner_items(item.syntax());
454 let assoc = self.lower_assoc_item(&item)?; 457 let assoc = self.lower_assoc_item(&item)?;
455 let attrs = Attrs::new(&item, &self.hygiene); 458 let attrs = Attrs::new(&item, &self.hygiene);
456 self.add_attrs(assoc.into(), attrs); 459 self.add_attrs(ModItem::from(assoc).into(), attrs);
457 Some(assoc) 460 Some(assoc)
458 }) 461 })
459 .collect(); 462 .collect();
@@ -539,7 +542,7 @@ impl Ctx {
539 .filter_map(|item| { 542 .filter_map(|item| {
540 self.collect_inner_items(item.syntax()); 543 self.collect_inner_items(item.syntax());
541 let attrs = Attrs::new(&item, &self.hygiene); 544 let attrs = Attrs::new(&item, &self.hygiene);
542 let id = match item { 545 let id: ModItem = match item {
543 ast::ExternItem::FnDef(ast) => { 546 ast::ExternItem::FnDef(ast) => {
544 let func = self.lower_function(&ast)?; 547 let func = self.lower_function(&ast)?;
545 func.into() 548 func.into()
@@ -549,7 +552,7 @@ impl Ctx {
549 statik.into() 552 statik.into()
550 } 553 }
551 }; 554 };
552 self.add_attrs(id, attrs); 555 self.add_attrs(id.into(), attrs);
553 Some(id) 556 Some(id)
554 }) 557 })
555 .collect() 558 .collect()
diff --git a/crates/ra_hir_def/src/item_tree/tests.rs b/crates/ra_hir_def/src/item_tree/tests.rs
index dc035d809..08559fb92 100644
--- a/crates/ra_hir_def/src/item_tree/tests.rs
+++ b/crates/ra_hir_def/src/item_tree/tests.rs
@@ -92,7 +92,7 @@ fn print_item_tree(ra_fixture: &str) -> String {
92} 92}
93 93
94fn fmt_mod_item(out: &mut String, tree: &ItemTree, item: ModItem) { 94fn fmt_mod_item(out: &mut String, tree: &ItemTree, item: ModItem) {
95 let attrs = tree.attrs(item); 95 let attrs = tree.attrs(item.into());
96 if !attrs.is_empty() { 96 if !attrs.is_empty() {
97 format_to!(out, "#[{:?}]\n", attrs); 97 format_to!(out, "#[{:?}]\n", attrs);
98 } 98 }
@@ -237,13 +237,13 @@ Trait { name: Name(Text("Tr")), visibility: RawVisibilityId("pub(self)"), generi
237#[Attrs { entries: Some([Attr { path: ModPath { kind: Plain, segments: [Name(Text("struct0"))] }, input: None }]) }] 237#[Attrs { entries: Some([Attr { path: ModPath { kind: Plain, segments: [Name(Text("struct0"))] }, input: None }]) }]
238Struct { name: Name(Text("Struct0")), visibility: RawVisibilityId("pub(self)"), generic_params: GenericParamsId(1), fields: Unit, ast_id: FileAstId::<ra_syntax::ast::generated::nodes::StructDef>(3), kind: Unit } 238Struct { name: Name(Text("Struct0")), visibility: RawVisibilityId("pub(self)"), generic_params: GenericParamsId(1), fields: Unit, ast_id: FileAstId::<ra_syntax::ast::generated::nodes::StructDef>(3), kind: Unit }
239#[Attrs { entries: Some([Attr { path: ModPath { kind: Plain, segments: [Name(Text("struct1"))] }, input: None }]) }] 239#[Attrs { entries: Some([Attr { path: ModPath { kind: Plain, segments: [Name(Text("struct1"))] }, input: None }]) }]
240Struct { name: Name(Text("Struct1")), visibility: RawVisibilityId("pub(self)"), generic_params: GenericParamsId(2), fields: Tuple(Idx::<Field>(0)..Idx::<Field>(1)), ast_id: FileAstId::<ra_syntax::ast::generated::nodes::StructDef>(4), kind: Tuple } 240Struct { name: Name(Text("Struct1")), visibility: RawVisibilityId("pub(self)"), generic_params: GenericParamsId(2), fields: Tuple(IdRange::<ra_hir_def::item_tree::Field>(0..1)), ast_id: FileAstId::<ra_syntax::ast::generated::nodes::StructDef>(4), kind: Tuple }
241#[Attrs { entries: Some([Attr { path: ModPath { kind: Plain, segments: [Name(Text("struct2"))] }, input: None }]) }] 241#[Attrs { entries: Some([Attr { path: ModPath { kind: Plain, segments: [Name(Text("struct2"))] }, input: None }]) }]
242Struct { name: Name(Text("Struct2")), visibility: RawVisibilityId("pub(self)"), generic_params: GenericParamsId(3), fields: Record(Idx::<Field>(1)..Idx::<Field>(2)), ast_id: FileAstId::<ra_syntax::ast::generated::nodes::StructDef>(5), kind: Record } 242Struct { name: Name(Text("Struct2")), visibility: RawVisibilityId("pub(self)"), generic_params: GenericParamsId(3), fields: Record(IdRange::<ra_hir_def::item_tree::Field>(1..2)), ast_id: FileAstId::<ra_syntax::ast::generated::nodes::StructDef>(5), kind: Record }
243#[Attrs { entries: Some([Attr { path: ModPath { kind: Plain, segments: [Name(Text("en"))] }, input: None }]) }] 243#[Attrs { entries: Some([Attr { path: ModPath { kind: Plain, segments: [Name(Text("en"))] }, input: None }]) }]
244Enum { name: Name(Text("En")), visibility: RawVisibilityId("pub(self)"), generic_params: GenericParamsId(4294967295), variants: Idx::<Variant>(0)..Idx::<Variant>(1), ast_id: FileAstId::<ra_syntax::ast::generated::nodes::EnumDef>(6) } 244Enum { name: Name(Text("En")), visibility: RawVisibilityId("pub(self)"), generic_params: GenericParamsId(4294967295), variants: IdRange::<ra_hir_def::item_tree::Variant>(0..1), ast_id: FileAstId::<ra_syntax::ast::generated::nodes::EnumDef>(6) }
245#[Attrs { entries: Some([Attr { path: ModPath { kind: Plain, segments: [Name(Text("un"))] }, input: None }]) }] 245#[Attrs { entries: Some([Attr { path: ModPath { kind: Plain, segments: [Name(Text("un"))] }, input: None }]) }]
246Union { name: Name(Text("Un")), visibility: RawVisibilityId("pub(self)"), generic_params: GenericParamsId(4294967295), fields: Record(Idx::<Field>(3)..Idx::<Field>(4)), ast_id: FileAstId::<ra_syntax::ast::generated::nodes::UnionDef>(7) } 246Union { name: Name(Text("Un")), visibility: RawVisibilityId("pub(self)"), generic_params: GenericParamsId(4294967295), fields: Record(IdRange::<ra_hir_def::item_tree::Field>(3..4)), ast_id: FileAstId::<ra_syntax::ast::generated::nodes::UnionDef>(7) }
247 "###); 247 "###);
248} 248}
249 249
diff --git a/crates/ra_hir_def/src/nameres/collector.rs b/crates/ra_hir_def/src/nameres/collector.rs
index 94da700ad..2ced4f66b 100644
--- a/crates/ra_hir_def/src/nameres/collector.rs
+++ b/crates/ra_hir_def/src/nameres/collector.rs
@@ -742,7 +742,7 @@ impl ModCollector<'_, '_> {
742 // `#[macro_use] extern crate` is hoisted to imports macros before collecting 742 // `#[macro_use] extern crate` is hoisted to imports macros before collecting
743 // any other items. 743 // any other items.
744 for item in items { 744 for item in items {
745 if self.is_cfg_enabled(self.item_tree.attrs(*item)) { 745 if self.is_cfg_enabled(self.item_tree.attrs((*item).into())) {
746 if let ModItem::ExternCrate(id) = item { 746 if let ModItem::ExternCrate(id) = item {
747 let import = self.item_tree[*id].clone(); 747 let import = self.item_tree[*id].clone();
748 if import.is_macro_use { 748 if import.is_macro_use {
@@ -753,7 +753,7 @@ impl ModCollector<'_, '_> {
753 } 753 }
754 754
755 for &item in items { 755 for &item in items {
756 let attrs = self.item_tree.attrs(item); 756 let attrs = self.item_tree.attrs(item.into());
757 if self.is_cfg_enabled(attrs) { 757 if self.is_cfg_enabled(attrs) {
758 let module = 758 let module =
759 ModuleId { krate: self.def_collector.def_map.krate, local_id: self.module_id }; 759 ModuleId { krate: self.def_collector.def_map.krate, local_id: self.module_id };