diff options
-rw-r--r-- | crates/ra_hir_def/src/adt.rs | 94 | ||||
-rw-r--r-- | crates/ra_hir_def/src/attr.rs | 2 | ||||
-rw-r--r-- | crates/ra_hir_def/src/data.rs | 4 | ||||
-rw-r--r-- | crates/ra_hir_def/src/item_tree.rs | 70 | ||||
-rw-r--r-- | crates/ra_hir_def/src/item_tree/lower.rs | 39 | ||||
-rw-r--r-- | crates/ra_hir_def/src/item_tree/tests.rs | 10 | ||||
-rw-r--r-- | crates/ra_hir_def/src/nameres/collector.rs | 4 |
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 | }; |
10 | use ra_arena::{map::ArenaMap, Arena}; | 10 | use ra_arena::{map::ArenaMap, Arena}; |
11 | use ra_prof::profile; | ||
12 | use ra_syntax::ast::{self, NameOwner, TypeAscriptionOwner, VisibilityOwner}; | 11 | use ra_syntax::ast::{self, NameOwner, TypeAscriptionOwner, VisibilityOwner}; |
13 | 12 | ||
14 | use crate::{ | 13 | use 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 | }; |
25 | use 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 | ||
60 | impl StructData { | 61 | impl 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 | ||
87 | impl EnumData { | 84 | impl 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 | |||
265 | fn 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 | |||
289 | fn 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 | |||
208 | fn attrs_from_item_tree<N: ItemTreeNode>(id: ItemTreeId<N>, db: &dyn DefDatabase) -> Attrs { | 208 | fn 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; | |||
5 | mod tests; | 5 | mod tests; |
6 | 6 | ||
7 | use std::{ | 7 | use 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)] |
285 | enum AttrOwner { | 286 | pub 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. | 297 | macro_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 | |||
309 | from_attrs!(ModItem(ModItem), Variant(Idx<Variant>), Field(Idx<Field>)); | ||
310 | |||
311 | /// Trait implemented by all item nodes in the item tree. | ||
294 | pub trait ItemTreeNode: Clone { | 312 | pub 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 | ||
702 | pub struct IdRange<T> { | ||
703 | range: Range<u32>, | ||
704 | _p: PhantomData<T>, | ||
705 | } | ||
706 | |||
707 | impl<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 | |||
713 | impl<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 | |||
720 | impl<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 | |||
726 | impl<T> Clone for IdRange<T> { | ||
727 | fn clone(&self) -> Self { | ||
728 | Self { range: self.range.clone(), _p: PhantomData } | ||
729 | } | ||
730 | } | ||
731 | |||
732 | impl<T> PartialEq for IdRange<T> { | ||
733 | fn eq(&self, other: &Self) -> bool { | ||
734 | self.range == other.range | ||
735 | } | ||
736 | } | ||
737 | |||
738 | impl<T> Eq for IdRange<T> {} | ||
739 | |||
684 | #[derive(Debug, Clone, PartialEq, Eq)] | 740 | #[derive(Debug, Clone, PartialEq, Eq)] |
685 | pub enum Fields { | 741 | pub 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 | ||
94 | fn fmt_mod_item(out: &mut String, tree: &ItemTree, item: ModItem) { | 94 | fn 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 }]) }] |
238 | Struct { 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 } | 238 | Struct { 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 }]) }] |
240 | Struct { 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 } | 240 | Struct { 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 }]) }] |
242 | Struct { 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 } | 242 | Struct { 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 }]) }] |
244 | Enum { 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) } | 244 | Enum { 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 }]) }] |
246 | Union { 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) } | 246 | Union { 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 }; |