diff options
author | bors[bot] <26634292+bors[bot]@users.noreply.github.com> | 2020-12-18 01:25:27 +0000 |
---|---|---|
committer | GitHub <[email protected]> | 2020-12-18 01:25:27 +0000 |
commit | 37e5f19373d6e4d639d0ee1125741f7b5c5c5b1a (patch) | |
tree | d60fc981c2dcc2fe5b78d73ac419c65a5574d027 | |
parent | a4e17a5a96d3a8c15c91e90adce9d9b8cdc48a46 (diff) | |
parent | 4f07d8dd587c24bca8622ee8c39e5a1e156825b4 (diff) |
Merge #6924
6924: Refactor attributes API to allow handling cfg_attr later r=jonas-schievink a=jonas-schievink
bors r+
Co-authored-by: Jonas Schievink <[email protected]>
-rw-r--r-- | crates/hir_def/src/adt.rs | 47 | ||||
-rw-r--r-- | crates/hir_def/src/attr.rs | 146 | ||||
-rw-r--r-- | crates/hir_def/src/body.rs | 17 | ||||
-rw-r--r-- | crates/hir_def/src/body/lower.rs | 2 | ||||
-rw-r--r-- | crates/hir_def/src/data.rs | 5 | ||||
-rw-r--r-- | crates/hir_def/src/item_tree.rs | 19 | ||||
-rw-r--r-- | crates/hir_def/src/item_tree/lower.rs | 17 | ||||
-rw-r--r-- | crates/hir_def/src/nameres/collector.rs | 48 |
8 files changed, 187 insertions, 114 deletions
diff --git a/crates/hir_def/src/adt.rs b/crates/hir_def/src/adt.rs index eafa3abb6..236d6f1b7 100644 --- a/crates/hir_def/src/adt.rs +++ b/crates/hir_def/src/adt.rs | |||
@@ -3,6 +3,7 @@ | |||
3 | use std::sync::Arc; | 3 | use std::sync::Arc; |
4 | 4 | ||
5 | use arena::{map::ArenaMap, Arena}; | 5 | use arena::{map::ArenaMap, Arena}; |
6 | use base_db::CrateId; | ||
6 | use either::Either; | 7 | use either::Either; |
7 | use hir_expand::{ | 8 | use hir_expand::{ |
8 | name::{AsName, Name}, | 9 | name::{AsName, Name}, |
@@ -66,8 +67,13 @@ pub enum ReprKind { | |||
66 | Other, | 67 | Other, |
67 | } | 68 | } |
68 | 69 | ||
69 | fn repr_from_value(item_tree: &ItemTree, of: AttrOwner) -> Option<ReprKind> { | 70 | fn repr_from_value( |
70 | item_tree.attrs(of).by_key("repr").tt_values().find_map(parse_repr_tt) | 71 | db: &dyn DefDatabase, |
72 | krate: CrateId, | ||
73 | item_tree: &ItemTree, | ||
74 | of: AttrOwner, | ||
75 | ) -> Option<ReprKind> { | ||
76 | item_tree.attrs(db, krate, of).by_key("repr").tt_values().find_map(parse_repr_tt) | ||
71 | } | 77 | } |
72 | 78 | ||
73 | fn parse_repr_tt(tt: &Subtree) -> Option<ReprKind> { | 79 | fn parse_repr_tt(tt: &Subtree) -> Option<ReprKind> { |
@@ -86,12 +92,13 @@ fn parse_repr_tt(tt: &Subtree) -> Option<ReprKind> { | |||
86 | impl StructData { | 92 | impl StructData { |
87 | pub(crate) fn struct_data_query(db: &dyn DefDatabase, id: StructId) -> Arc<StructData> { | 93 | pub(crate) fn struct_data_query(db: &dyn DefDatabase, id: StructId) -> Arc<StructData> { |
88 | let loc = id.lookup(db); | 94 | let loc = id.lookup(db); |
95 | let krate = loc.container.module(db).krate; | ||
89 | let item_tree = db.item_tree(loc.id.file_id); | 96 | let item_tree = db.item_tree(loc.id.file_id); |
90 | let repr = repr_from_value(&item_tree, ModItem::from(loc.id.value).into()); | 97 | let repr = repr_from_value(db, krate, &item_tree, ModItem::from(loc.id.value).into()); |
91 | let cfg_options = db.crate_graph()[loc.container.module(db).krate].cfg_options.clone(); | 98 | let cfg_options = db.crate_graph()[loc.container.module(db).krate].cfg_options.clone(); |
92 | 99 | ||
93 | let strukt = &item_tree[loc.id.value]; | 100 | let strukt = &item_tree[loc.id.value]; |
94 | let variant_data = lower_fields(&item_tree, &cfg_options, &strukt.fields, None); | 101 | let variant_data = lower_fields(db, krate, &item_tree, &cfg_options, &strukt.fields, None); |
95 | Arc::new(StructData { | 102 | Arc::new(StructData { |
96 | name: strukt.name.clone(), | 103 | name: strukt.name.clone(), |
97 | variant_data: Arc::new(variant_data), | 104 | variant_data: Arc::new(variant_data), |
@@ -100,12 +107,13 @@ impl StructData { | |||
100 | } | 107 | } |
101 | pub(crate) fn union_data_query(db: &dyn DefDatabase, id: UnionId) -> Arc<StructData> { | 108 | pub(crate) fn union_data_query(db: &dyn DefDatabase, id: UnionId) -> Arc<StructData> { |
102 | let loc = id.lookup(db); | 109 | let loc = id.lookup(db); |
110 | let krate = loc.container.module(db).krate; | ||
103 | let item_tree = db.item_tree(loc.id.file_id); | 111 | let item_tree = db.item_tree(loc.id.file_id); |
104 | let repr = repr_from_value(&item_tree, ModItem::from(loc.id.value).into()); | 112 | let repr = repr_from_value(db, krate, &item_tree, ModItem::from(loc.id.value).into()); |
105 | let cfg_options = db.crate_graph()[loc.container.module(db).krate].cfg_options.clone(); | 113 | let cfg_options = db.crate_graph()[loc.container.module(db).krate].cfg_options.clone(); |
106 | 114 | ||
107 | let union = &item_tree[loc.id.value]; | 115 | let union = &item_tree[loc.id.value]; |
108 | let variant_data = lower_fields(&item_tree, &cfg_options, &union.fields, None); | 116 | let variant_data = lower_fields(db, krate, &item_tree, &cfg_options, &union.fields, None); |
109 | 117 | ||
110 | Arc::new(StructData { | 118 | Arc::new(StructData { |
111 | name: union.name.clone(), | 119 | name: union.name.clone(), |
@@ -118,16 +126,23 @@ impl StructData { | |||
118 | impl EnumData { | 126 | impl EnumData { |
119 | pub(crate) fn enum_data_query(db: &dyn DefDatabase, e: EnumId) -> Arc<EnumData> { | 127 | pub(crate) fn enum_data_query(db: &dyn DefDatabase, e: EnumId) -> Arc<EnumData> { |
120 | let loc = e.lookup(db); | 128 | let loc = e.lookup(db); |
129 | let krate = loc.container.module(db).krate; | ||
121 | let item_tree = db.item_tree(loc.id.file_id); | 130 | let item_tree = db.item_tree(loc.id.file_id); |
122 | let cfg_options = db.crate_graph()[loc.container.module(db).krate].cfg_options.clone(); | 131 | let cfg_options = db.crate_graph()[krate].cfg_options.clone(); |
123 | 132 | ||
124 | let enum_ = &item_tree[loc.id.value]; | 133 | let enum_ = &item_tree[loc.id.value]; |
125 | let mut variants = Arena::new(); | 134 | let mut variants = Arena::new(); |
126 | for var_id in enum_.variants.clone() { | 135 | for var_id in enum_.variants.clone() { |
127 | if item_tree.attrs(var_id.into()).is_cfg_enabled(&cfg_options) { | 136 | if item_tree.attrs(db, krate, var_id.into()).is_cfg_enabled(&cfg_options) { |
128 | let var = &item_tree[var_id]; | 137 | let var = &item_tree[var_id]; |
129 | let var_data = | 138 | let var_data = lower_fields( |
130 | lower_fields(&item_tree, &cfg_options, &var.fields, Some(enum_.visibility)); | 139 | db, |
140 | krate, | ||
141 | &item_tree, | ||
142 | &cfg_options, | ||
143 | &var.fields, | ||
144 | Some(enum_.visibility), | ||
145 | ); | ||
131 | 146 | ||
132 | variants.alloc(EnumVariantData { | 147 | variants.alloc(EnumVariantData { |
133 | name: var.name.clone(), | 148 | name: var.name.clone(), |
@@ -170,7 +185,7 @@ fn lower_enum( | |||
170 | .variant_list() | 185 | .variant_list() |
171 | .into_iter() | 186 | .into_iter() |
172 | .flat_map(|it| it.variants()) | 187 | .flat_map(|it| it.variants()) |
173 | .filter(|var| expander.is_cfg_enabled(var)); | 188 | .filter(|var| expander.is_cfg_enabled(db, var)); |
174 | for var in variants { | 189 | for var in variants { |
175 | trace.alloc( | 190 | trace.alloc( |
176 | || var.clone(), | 191 | || var.clone(), |
@@ -262,7 +277,7 @@ fn lower_struct( | |||
262 | match &ast.value { | 277 | match &ast.value { |
263 | ast::StructKind::Tuple(fl) => { | 278 | ast::StructKind::Tuple(fl) => { |
264 | for (i, fd) in fl.fields().enumerate() { | 279 | for (i, fd) in fl.fields().enumerate() { |
265 | if !expander.is_cfg_enabled(&fd) { | 280 | if !expander.is_cfg_enabled(db, &fd) { |
266 | continue; | 281 | continue; |
267 | } | 282 | } |
268 | 283 | ||
@@ -279,7 +294,7 @@ fn lower_struct( | |||
279 | } | 294 | } |
280 | ast::StructKind::Record(fl) => { | 295 | ast::StructKind::Record(fl) => { |
281 | for fd in fl.fields() { | 296 | for fd in fl.fields() { |
282 | if !expander.is_cfg_enabled(&fd) { | 297 | if !expander.is_cfg_enabled(db, &fd) { |
283 | continue; | 298 | continue; |
284 | } | 299 | } |
285 | 300 | ||
@@ -299,6 +314,8 @@ fn lower_struct( | |||
299 | } | 314 | } |
300 | 315 | ||
301 | fn lower_fields( | 316 | fn lower_fields( |
317 | db: &dyn DefDatabase, | ||
318 | krate: CrateId, | ||
302 | item_tree: &ItemTree, | 319 | item_tree: &ItemTree, |
303 | cfg_options: &CfgOptions, | 320 | cfg_options: &CfgOptions, |
304 | fields: &Fields, | 321 | fields: &Fields, |
@@ -308,7 +325,7 @@ fn lower_fields( | |||
308 | Fields::Record(flds) => { | 325 | Fields::Record(flds) => { |
309 | let mut arena = Arena::new(); | 326 | let mut arena = Arena::new(); |
310 | for field_id in flds.clone() { | 327 | for field_id in flds.clone() { |
311 | if item_tree.attrs(field_id.into()).is_cfg_enabled(cfg_options) { | 328 | if item_tree.attrs(db, krate, field_id.into()).is_cfg_enabled(cfg_options) { |
312 | arena.alloc(lower_field(item_tree, &item_tree[field_id], override_visibility)); | 329 | arena.alloc(lower_field(item_tree, &item_tree[field_id], override_visibility)); |
313 | } | 330 | } |
314 | } | 331 | } |
@@ -317,7 +334,7 @@ fn lower_fields( | |||
317 | Fields::Tuple(flds) => { | 334 | Fields::Tuple(flds) => { |
318 | let mut arena = Arena::new(); | 335 | let mut arena = Arena::new(); |
319 | for field_id in flds.clone() { | 336 | for field_id in flds.clone() { |
320 | if item_tree.attrs(field_id.into()).is_cfg_enabled(cfg_options) { | 337 | if item_tree.attrs(db, krate, field_id.into()).is_cfg_enabled(cfg_options) { |
321 | arena.alloc(lower_field(item_tree, &item_tree[field_id], override_visibility)); | 338 | arena.alloc(lower_field(item_tree, &item_tree[field_id], override_visibility)); |
322 | } | 339 | } |
323 | } | 340 | } |
diff --git a/crates/hir_def/src/attr.rs b/crates/hir_def/src/attr.rs index 45313f335..9cd0b72aa 100644 --- a/crates/hir_def/src/attr.rs +++ b/crates/hir_def/src/attr.rs | |||
@@ -2,6 +2,7 @@ | |||
2 | 2 | ||
3 | use std::{ops, sync::Arc}; | 3 | use std::{ops, sync::Arc}; |
4 | 4 | ||
5 | use base_db::CrateId; | ||
5 | use cfg::{CfgExpr, CfgOptions}; | 6 | use cfg::{CfgExpr, CfgOptions}; |
6 | use either::Either; | 7 | use either::Either; |
7 | use hir_expand::{hygiene::Hygiene, AstId, InFile}; | 8 | use hir_expand::{hygiene::Hygiene, AstId, InFile}; |
@@ -38,12 +39,16 @@ impl From<Documentation> for String { | |||
38 | } | 39 | } |
39 | } | 40 | } |
40 | 41 | ||
42 | /// Syntactical attributes, without filtering of `cfg_attr`s. | ||
41 | #[derive(Default, Debug, Clone, PartialEq, Eq)] | 43 | #[derive(Default, Debug, Clone, PartialEq, Eq)] |
42 | pub struct Attrs { | 44 | pub struct RawAttrs { |
43 | entries: Option<Arc<[Attr]>>, | 45 | entries: Option<Arc<[Attr]>>, |
44 | } | 46 | } |
45 | 47 | ||
46 | impl ops::Deref for Attrs { | 48 | #[derive(Default, Debug, Clone, PartialEq, Eq)] |
49 | pub struct Attrs(RawAttrs); | ||
50 | |||
51 | impl ops::Deref for RawAttrs { | ||
47 | type Target = [Attr]; | 52 | type Target = [Attr]; |
48 | 53 | ||
49 | fn deref(&self) -> &[Attr] { | 54 | fn deref(&self) -> &[Attr] { |
@@ -54,19 +59,88 @@ impl ops::Deref for Attrs { | |||
54 | } | 59 | } |
55 | } | 60 | } |
56 | 61 | ||
62 | impl ops::Deref for Attrs { | ||
63 | type Target = [Attr]; | ||
64 | |||
65 | fn deref(&self) -> &[Attr] { | ||
66 | match &self.0.entries { | ||
67 | Some(it) => &*it, | ||
68 | None => &[], | ||
69 | } | ||
70 | } | ||
71 | } | ||
72 | |||
73 | impl RawAttrs { | ||
74 | pub const EMPTY: Self = Self { entries: None }; | ||
75 | |||
76 | pub(crate) fn new(owner: &dyn AttrsOwner, hygiene: &Hygiene) -> Self { | ||
77 | let (inner_attrs, inner_docs) = inner_attributes(owner.syntax()) | ||
78 | .map_or((None, None), |(attrs, docs)| ((Some(attrs), Some(docs)))); | ||
79 | |||
80 | let outer_attrs = owner.attrs().filter(|attr| attr.excl_token().is_none()); | ||
81 | let attrs = outer_attrs | ||
82 | .chain(inner_attrs.into_iter().flatten()) | ||
83 | .map(|attr| (attr.syntax().text_range().start(), Attr::from_src(attr, hygiene))); | ||
84 | |||
85 | let outer_docs = | ||
86 | ast::CommentIter::from_syntax_node(owner.syntax()).filter(ast::Comment::is_outer); | ||
87 | let docs = outer_docs.chain(inner_docs.into_iter().flatten()).map(|docs_text| { | ||
88 | ( | ||
89 | docs_text.syntax().text_range().start(), | ||
90 | docs_text.doc_comment().map(|doc| Attr { | ||
91 | input: Some(AttrInput::Literal(SmolStr::new(doc))), | ||
92 | path: ModPath::from(hir_expand::name!(doc)), | ||
93 | }), | ||
94 | ) | ||
95 | }); | ||
96 | // sort here by syntax node offset because the source can have doc attributes and doc strings be interleaved | ||
97 | let attrs: Vec<_> = docs.chain(attrs).sorted_by_key(|&(offset, _)| offset).collect(); | ||
98 | let entries = if attrs.is_empty() { | ||
99 | // Avoid heap allocation | ||
100 | None | ||
101 | } else { | ||
102 | Some(attrs.into_iter().flat_map(|(_, attr)| attr).collect()) | ||
103 | }; | ||
104 | Self { entries } | ||
105 | } | ||
106 | |||
107 | fn from_attrs_owner(db: &dyn DefDatabase, owner: InFile<&dyn AttrsOwner>) -> Self { | ||
108 | let hygiene = Hygiene::new(db.upcast(), owner.file_id); | ||
109 | Self::new(owner.value, &hygiene) | ||
110 | } | ||
111 | |||
112 | pub(crate) fn merge(&self, other: Self) -> Self { | ||
113 | match (&self.entries, &other.entries) { | ||
114 | (None, None) => Self::EMPTY, | ||
115 | (Some(entries), None) | (None, Some(entries)) => { | ||
116 | Self { entries: Some(entries.clone()) } | ||
117 | } | ||
118 | (Some(a), Some(b)) => { | ||
119 | Self { entries: Some(a.iter().chain(b.iter()).cloned().collect()) } | ||
120 | } | ||
121 | } | ||
122 | } | ||
123 | |||
124 | /// Processes `cfg_attr`s, returning the resulting semantic `Attrs`. | ||
125 | pub(crate) fn filter(self, _db: &dyn DefDatabase, _krate: CrateId) -> Attrs { | ||
126 | // FIXME actually implement this | ||
127 | Attrs(self) | ||
128 | } | ||
129 | } | ||
130 | |||
57 | impl Attrs { | 131 | impl Attrs { |
58 | pub const EMPTY: Attrs = Attrs { entries: None }; | 132 | pub const EMPTY: Self = Self(RawAttrs::EMPTY); |
59 | 133 | ||
60 | pub(crate) fn attrs_query(db: &dyn DefDatabase, def: AttrDefId) -> Attrs { | 134 | pub(crate) fn attrs_query(db: &dyn DefDatabase, def: AttrDefId) -> Attrs { |
61 | match def { | 135 | let raw_attrs = match def { |
62 | AttrDefId::ModuleId(module) => { | 136 | AttrDefId::ModuleId(module) => { |
63 | let def_map = db.crate_def_map(module.krate); | 137 | let def_map = db.crate_def_map(module.krate); |
64 | let mod_data = &def_map[module.local_id]; | 138 | let mod_data = &def_map[module.local_id]; |
65 | match mod_data.declaration_source(db) { | 139 | match mod_data.declaration_source(db) { |
66 | Some(it) => { | 140 | Some(it) => { |
67 | Attrs::from_attrs_owner(db, it.as_ref().map(|it| it as &dyn AttrsOwner)) | 141 | RawAttrs::from_attrs_owner(db, it.as_ref().map(|it| it as &dyn AttrsOwner)) |
68 | } | 142 | } |
69 | None => Attrs::from_attrs_owner( | 143 | None => RawAttrs::from_attrs_owner( |
70 | db, | 144 | db, |
71 | mod_data.definition_source(db).as_ref().map(|src| match src { | 145 | mod_data.definition_source(db).as_ref().map(|src| match src { |
72 | ModuleSource::SourceFile(file) => file as &dyn AttrsOwner, | 146 | ModuleSource::SourceFile(file) => file as &dyn AttrsOwner, |
@@ -78,14 +152,14 @@ impl Attrs { | |||
78 | AttrDefId::FieldId(it) => { | 152 | AttrDefId::FieldId(it) => { |
79 | let src = it.parent.child_source(db); | 153 | let src = it.parent.child_source(db); |
80 | match &src.value[it.local_id] { | 154 | match &src.value[it.local_id] { |
81 | Either::Left(_tuple) => Attrs::default(), | 155 | Either::Left(_tuple) => RawAttrs::default(), |
82 | Either::Right(record) => Attrs::from_attrs_owner(db, src.with_value(record)), | 156 | Either::Right(record) => RawAttrs::from_attrs_owner(db, src.with_value(record)), |
83 | } | 157 | } |
84 | } | 158 | } |
85 | AttrDefId::EnumVariantId(var_id) => { | 159 | AttrDefId::EnumVariantId(var_id) => { |
86 | let src = var_id.parent.child_source(db); | 160 | let src = var_id.parent.child_source(db); |
87 | let src = src.as_ref().map(|it| &it[var_id.local_id]); | 161 | let src = src.as_ref().map(|it| &it[var_id.local_id]); |
88 | Attrs::from_attrs_owner(db, src.map(|it| it as &dyn AttrsOwner)) | 162 | RawAttrs::from_attrs_owner(db, src.map(|it| it as &dyn AttrsOwner)) |
89 | } | 163 | } |
90 | AttrDefId::AdtId(it) => match it { | 164 | AttrDefId::AdtId(it) => match it { |
91 | AdtId::StructId(it) => attrs_from_item_tree(it.lookup(db).id, db), | 165 | AdtId::StructId(it) => attrs_from_item_tree(it.lookup(db).id, db), |
@@ -101,53 +175,19 @@ impl Attrs { | |||
101 | AttrDefId::StaticId(it) => attrs_from_item_tree(it.lookup(db).id, db), | 175 | AttrDefId::StaticId(it) => attrs_from_item_tree(it.lookup(db).id, db), |
102 | AttrDefId::FunctionId(it) => attrs_from_item_tree(it.lookup(db).id, db), | 176 | AttrDefId::FunctionId(it) => attrs_from_item_tree(it.lookup(db).id, db), |
103 | AttrDefId::TypeAliasId(it) => attrs_from_item_tree(it.lookup(db).id, db), | 177 | AttrDefId::TypeAliasId(it) => attrs_from_item_tree(it.lookup(db).id, db), |
104 | } | ||
105 | } | ||
106 | |||
107 | fn from_attrs_owner(db: &dyn DefDatabase, owner: InFile<&dyn AttrsOwner>) -> Attrs { | ||
108 | let hygiene = Hygiene::new(db.upcast(), owner.file_id); | ||
109 | Attrs::new(owner.value, &hygiene) | ||
110 | } | ||
111 | |||
112 | pub(crate) fn new(owner: &dyn AttrsOwner, hygiene: &Hygiene) -> Attrs { | ||
113 | let (inner_attrs, inner_docs) = inner_attributes(owner.syntax()) | ||
114 | .map_or((None, None), |(attrs, docs)| ((Some(attrs), Some(docs)))); | ||
115 | |||
116 | let outer_attrs = owner.attrs().filter(|attr| attr.excl_token().is_none()); | ||
117 | let attrs = outer_attrs | ||
118 | .chain(inner_attrs.into_iter().flatten()) | ||
119 | .map(|attr| (attr.syntax().text_range().start(), Attr::from_src(attr, hygiene))); | ||
120 | |||
121 | let outer_docs = | ||
122 | ast::CommentIter::from_syntax_node(owner.syntax()).filter(ast::Comment::is_outer); | ||
123 | let docs = outer_docs.chain(inner_docs.into_iter().flatten()).map(|docs_text| { | ||
124 | ( | ||
125 | docs_text.syntax().text_range().start(), | ||
126 | docs_text.doc_comment().map(|doc| Attr { | ||
127 | input: Some(AttrInput::Literal(SmolStr::new(doc))), | ||
128 | path: ModPath::from(hir_expand::name!(doc)), | ||
129 | }), | ||
130 | ) | ||
131 | }); | ||
132 | // sort here by syntax node offset because the source can have doc attributes and doc strings be interleaved | ||
133 | let attrs: Vec<_> = docs.chain(attrs).sorted_by_key(|&(offset, _)| offset).collect(); | ||
134 | let entries = if attrs.is_empty() { | ||
135 | // Avoid heap allocation | ||
136 | None | ||
137 | } else { | ||
138 | Some(attrs.into_iter().flat_map(|(_, attr)| attr).collect()) | ||
139 | }; | 178 | }; |
140 | Attrs { entries } | 179 | |
180 | raw_attrs.filter(db, def.krate(db)) | ||
141 | } | 181 | } |
142 | 182 | ||
143 | pub fn merge(&self, other: Attrs) -> Attrs { | 183 | pub fn merge(&self, other: Attrs) -> Attrs { |
144 | match (&self.entries, &other.entries) { | 184 | match (&self.0.entries, &other.0.entries) { |
145 | (None, None) => Attrs { entries: None }, | 185 | (None, None) => Attrs::EMPTY, |
146 | (Some(entries), None) | (None, Some(entries)) => { | 186 | (Some(entries), None) | (None, Some(entries)) => { |
147 | Attrs { entries: Some(entries.clone()) } | 187 | Attrs(RawAttrs { entries: Some(entries.clone()) }) |
148 | } | 188 | } |
149 | (Some(a), Some(b)) => { | 189 | (Some(a), Some(b)) => { |
150 | Attrs { entries: Some(a.iter().chain(b.iter()).cloned().collect()) } | 190 | Attrs(RawAttrs { entries: Some(a.iter().chain(b.iter()).cloned().collect()) }) |
151 | } | 191 | } |
152 | } | 192 | } |
153 | } | 193 | } |
@@ -291,16 +331,16 @@ impl<'a> AttrQuery<'a> { | |||
291 | } | 331 | } |
292 | } | 332 | } |
293 | 333 | ||
294 | fn attrs_from_ast<N>(src: AstId<N>, db: &dyn DefDatabase) -> Attrs | 334 | fn attrs_from_ast<N>(src: AstId<N>, db: &dyn DefDatabase) -> RawAttrs |
295 | where | 335 | where |
296 | N: ast::AttrsOwner, | 336 | N: ast::AttrsOwner, |
297 | { | 337 | { |
298 | let src = InFile::new(src.file_id, src.to_node(db.upcast())); | 338 | let src = InFile::new(src.file_id, src.to_node(db.upcast())); |
299 | Attrs::from_attrs_owner(db, src.as_ref().map(|it| it as &dyn AttrsOwner)) | 339 | RawAttrs::from_attrs_owner(db, src.as_ref().map(|it| it as &dyn AttrsOwner)) |
300 | } | 340 | } |
301 | 341 | ||
302 | fn attrs_from_item_tree<N: ItemTreeNode>(id: ItemTreeId<N>, db: &dyn DefDatabase) -> Attrs { | 342 | fn attrs_from_item_tree<N: ItemTreeNode>(id: ItemTreeId<N>, db: &dyn DefDatabase) -> RawAttrs { |
303 | let tree = db.item_tree(id.file_id); | 343 | let tree = db.item_tree(id.file_id); |
304 | let mod_item = N::id_to_mod_item(id.value); | 344 | let mod_item = N::id_to_mod_item(id.value); |
305 | tree.attrs(mod_item.into()).clone() | 345 | tree.raw_attrs(mod_item.into()).clone() |
306 | } | 346 | } |
diff --git a/crates/hir_def/src/body.rs b/crates/hir_def/src/body.rs index c5d6f5fb0..998b82601 100644 --- a/crates/hir_def/src/body.rs +++ b/crates/hir_def/src/body.rs | |||
@@ -24,7 +24,7 @@ use test_utils::mark; | |||
24 | pub(crate) use lower::LowerCtx; | 24 | pub(crate) use lower::LowerCtx; |
25 | 25 | ||
26 | use crate::{ | 26 | use crate::{ |
27 | attr::Attrs, | 27 | attr::{Attrs, RawAttrs}, |
28 | db::DefDatabase, | 28 | db::DefDatabase, |
29 | expr::{Expr, ExprId, Pat, PatId}, | 29 | expr::{Expr, ExprId, Pat, PatId}, |
30 | item_scope::BuiltinShadowMode, | 30 | item_scope::BuiltinShadowMode, |
@@ -40,6 +40,7 @@ use crate::{ | |||
40 | pub(crate) struct CfgExpander { | 40 | pub(crate) struct CfgExpander { |
41 | cfg_options: CfgOptions, | 41 | cfg_options: CfgOptions, |
42 | hygiene: Hygiene, | 42 | hygiene: Hygiene, |
43 | krate: CrateId, | ||
43 | } | 44 | } |
44 | 45 | ||
45 | pub(crate) struct Expander { | 46 | pub(crate) struct Expander { |
@@ -65,15 +66,15 @@ impl CfgExpander { | |||
65 | ) -> CfgExpander { | 66 | ) -> CfgExpander { |
66 | let hygiene = Hygiene::new(db.upcast(), current_file_id); | 67 | let hygiene = Hygiene::new(db.upcast(), current_file_id); |
67 | let cfg_options = db.crate_graph()[krate].cfg_options.clone(); | 68 | let cfg_options = db.crate_graph()[krate].cfg_options.clone(); |
68 | CfgExpander { cfg_options, hygiene } | 69 | CfgExpander { cfg_options, hygiene, krate } |
69 | } | 70 | } |
70 | 71 | ||
71 | pub(crate) fn parse_attrs(&self, owner: &dyn ast::AttrsOwner) -> Attrs { | 72 | pub(crate) fn parse_attrs(&self, db: &dyn DefDatabase, owner: &dyn ast::AttrsOwner) -> Attrs { |
72 | Attrs::new(owner, &self.hygiene) | 73 | RawAttrs::new(owner, &self.hygiene).filter(db, self.krate) |
73 | } | 74 | } |
74 | 75 | ||
75 | pub(crate) fn is_cfg_enabled(&self, owner: &dyn ast::AttrsOwner) -> bool { | 76 | pub(crate) fn is_cfg_enabled(&self, db: &dyn DefDatabase, owner: &dyn ast::AttrsOwner) -> bool { |
76 | let attrs = self.parse_attrs(owner); | 77 | let attrs = self.parse_attrs(db, owner); |
77 | attrs.is_cfg_enabled(&self.cfg_options) | 78 | attrs.is_cfg_enabled(&self.cfg_options) |
78 | } | 79 | } |
79 | } | 80 | } |
@@ -189,8 +190,8 @@ impl Expander { | |||
189 | InFile { file_id: self.current_file_id, value } | 190 | InFile { file_id: self.current_file_id, value } |
190 | } | 191 | } |
191 | 192 | ||
192 | pub(crate) fn parse_attrs(&self, owner: &dyn ast::AttrsOwner) -> Attrs { | 193 | pub(crate) fn parse_attrs(&self, db: &dyn DefDatabase, owner: &dyn ast::AttrsOwner) -> Attrs { |
193 | self.cfg_expander.parse_attrs(owner) | 194 | self.cfg_expander.parse_attrs(db, owner) |
194 | } | 195 | } |
195 | 196 | ||
196 | pub(crate) fn cfg_options(&self) -> &CfgOptions { | 197 | pub(crate) fn cfg_options(&self) -> &CfgOptions { |
diff --git a/crates/hir_def/src/body/lower.rs b/crates/hir_def/src/body/lower.rs index 3b3d74987..0f404be1b 100644 --- a/crates/hir_def/src/body/lower.rs +++ b/crates/hir_def/src/body/lower.rs | |||
@@ -963,7 +963,7 @@ impl ExprCollector<'_> { | |||
963 | /// Returns `None` (and emits diagnostics) when `owner` if `#[cfg]`d out, and `Some(())` when | 963 | /// Returns `None` (and emits diagnostics) when `owner` if `#[cfg]`d out, and `Some(())` when |
964 | /// not. | 964 | /// not. |
965 | fn check_cfg(&mut self, owner: &dyn ast::AttrsOwner) -> Option<()> { | 965 | fn check_cfg(&mut self, owner: &dyn ast::AttrsOwner) -> Option<()> { |
966 | match self.expander.parse_attrs(owner).cfg() { | 966 | match self.expander.parse_attrs(self.db, owner).cfg() { |
967 | Some(cfg) => { | 967 | Some(cfg) => { |
968 | if self.expander.cfg_options().check(&cfg) != Some(false) { | 968 | if self.expander.cfg_options().check(&cfg) != Some(false) { |
969 | return Some(()); | 969 | return Some(()); |
diff --git a/crates/hir_def/src/data.rs b/crates/hir_def/src/data.rs index dd3a906af..e7b7724f7 100644 --- a/crates/hir_def/src/data.rs +++ b/crates/hir_def/src/data.rs | |||
@@ -35,6 +35,7 @@ pub struct FunctionData { | |||
35 | impl FunctionData { | 35 | impl FunctionData { |
36 | pub(crate) fn fn_data_query(db: &dyn DefDatabase, func: FunctionId) -> Arc<FunctionData> { | 36 | pub(crate) fn fn_data_query(db: &dyn DefDatabase, func: FunctionId) -> Arc<FunctionData> { |
37 | let loc = func.lookup(db); | 37 | let loc = func.lookup(db); |
38 | let krate = loc.container.module(db).krate; | ||
38 | let item_tree = db.item_tree(loc.id.file_id); | 39 | let item_tree = db.item_tree(loc.id.file_id); |
39 | let func = &item_tree[loc.id.value]; | 40 | let func = &item_tree[loc.id.value]; |
40 | 41 | ||
@@ -42,7 +43,7 @@ impl FunctionData { | |||
42 | name: func.name.clone(), | 43 | name: func.name.clone(), |
43 | params: func.params.to_vec(), | 44 | params: func.params.to_vec(), |
44 | ret_type: func.ret_type.clone(), | 45 | ret_type: func.ret_type.clone(), |
45 | attrs: item_tree.attrs(ModItem::from(loc.id.value).into()).clone(), | 46 | attrs: item_tree.attrs(db, krate, ModItem::from(loc.id.value).into()).clone(), |
46 | has_self_param: func.has_self_param, | 47 | has_self_param: func.has_self_param, |
47 | has_body: func.has_body, | 48 | has_body: func.has_body, |
48 | is_unsafe: func.is_unsafe, | 49 | is_unsafe: func.is_unsafe, |
@@ -233,7 +234,7 @@ fn collect_items( | |||
233 | match item { | 234 | match item { |
234 | AssocItem::Function(id) => { | 235 | AssocItem::Function(id) => { |
235 | let item = &item_tree[id]; | 236 | let item = &item_tree[id]; |
236 | let attrs = item_tree.attrs(ModItem::from(id).into()); | 237 | let attrs = item_tree.attrs(db, module.krate, ModItem::from(id).into()); |
237 | if !attrs.is_cfg_enabled(&cfg_options) { | 238 | if !attrs.is_cfg_enabled(&cfg_options) { |
238 | continue; | 239 | continue; |
239 | } | 240 | } |
diff --git a/crates/hir_def/src/item_tree.rs b/crates/hir_def/src/item_tree.rs index b8e09e3af..5eb7cae7f 100644 --- a/crates/hir_def/src/item_tree.rs +++ b/crates/hir_def/src/item_tree.rs | |||
@@ -13,6 +13,7 @@ use std::{ | |||
13 | 13 | ||
14 | use arena::{Arena, Idx, RawId}; | 14 | use arena::{Arena, Idx, RawId}; |
15 | use ast::{AstNode, AttrsOwner, NameOwner, StructKind}; | 15 | use ast::{AstNode, AttrsOwner, NameOwner, StructKind}; |
16 | use base_db::CrateId; | ||
16 | use either::Either; | 17 | use either::Either; |
17 | use hir_expand::{ | 18 | use hir_expand::{ |
18 | ast_id_map::FileAstId, | 19 | ast_id_map::FileAstId, |
@@ -26,7 +27,7 @@ use syntax::{ast, match_ast}; | |||
26 | use test_utils::mark; | 27 | use test_utils::mark; |
27 | 28 | ||
28 | use crate::{ | 29 | use crate::{ |
29 | attr::Attrs, | 30 | attr::{Attrs, RawAttrs}, |
30 | db::DefDatabase, | 31 | db::DefDatabase, |
31 | generics::GenericParams, | 32 | generics::GenericParams, |
32 | path::{path, AssociatedTypeBinding, GenericArgs, ImportAlias, ModPath, Path, PathKind}, | 33 | path::{path, AssociatedTypeBinding, GenericArgs, ImportAlias, ModPath, Path, PathKind}, |
@@ -67,7 +68,7 @@ impl GenericParamsId { | |||
67 | #[derive(Debug, Eq, PartialEq)] | 68 | #[derive(Debug, Eq, PartialEq)] |
68 | pub struct ItemTree { | 69 | pub struct ItemTree { |
69 | top_level: SmallVec<[ModItem; 1]>, | 70 | top_level: SmallVec<[ModItem; 1]>, |
70 | attrs: FxHashMap<AttrOwner, Attrs>, | 71 | attrs: FxHashMap<AttrOwner, RawAttrs>, |
71 | inner_items: FxHashMap<FileAstId<ast::Item>, SmallVec<[ModItem; 1]>>, | 72 | inner_items: FxHashMap<FileAstId<ast::Item>, SmallVec<[ModItem; 1]>>, |
72 | 73 | ||
73 | data: Option<Box<ItemTreeData>>, | 74 | data: Option<Box<ItemTreeData>>, |
@@ -88,7 +89,7 @@ impl ItemTree { | |||
88 | let mut item_tree = match_ast! { | 89 | let mut item_tree = match_ast! { |
89 | match syntax { | 90 | match syntax { |
90 | ast::SourceFile(file) => { | 91 | ast::SourceFile(file) => { |
91 | top_attrs = Some(Attrs::new(&file, &hygiene)); | 92 | top_attrs = Some(RawAttrs::new(&file, &hygiene)); |
92 | ctx.lower_module_items(&file) | 93 | ctx.lower_module_items(&file) |
93 | }, | 94 | }, |
94 | ast::MacroItems(items) => { | 95 | ast::MacroItems(items) => { |
@@ -180,12 +181,16 @@ impl ItemTree { | |||
180 | } | 181 | } |
181 | 182 | ||
182 | /// Returns the inner attributes of the source file. | 183 | /// Returns the inner attributes of the source file. |
183 | pub fn top_level_attrs(&self) -> &Attrs { | 184 | pub fn top_level_attrs(&self, db: &dyn DefDatabase, krate: CrateId) -> Attrs { |
184 | self.attrs.get(&AttrOwner::TopLevel).unwrap_or(&Attrs::EMPTY) | 185 | self.attrs.get(&AttrOwner::TopLevel).unwrap_or(&RawAttrs::EMPTY).clone().filter(db, krate) |
185 | } | 186 | } |
186 | 187 | ||
187 | pub fn attrs(&self, of: AttrOwner) -> &Attrs { | 188 | pub(crate) fn raw_attrs(&self, of: AttrOwner) -> &RawAttrs { |
188 | self.attrs.get(&of).unwrap_or(&Attrs::EMPTY) | 189 | self.attrs.get(&of).unwrap_or(&RawAttrs::EMPTY) |
190 | } | ||
191 | |||
192 | pub fn attrs(&self, db: &dyn DefDatabase, krate: CrateId, of: AttrOwner) -> Attrs { | ||
193 | self.raw_attrs(of).clone().filter(db, krate) | ||
189 | } | 194 | } |
190 | 195 | ||
191 | /// Returns the lowered inner items that `ast` corresponds to. | 196 | /// Returns the lowered inner items that `ast` corresponds to. |
diff --git a/crates/hir_def/src/item_tree/lower.rs b/crates/hir_def/src/item_tree/lower.rs index 7de385ee8..c8f090c22 100644 --- a/crates/hir_def/src/item_tree/lower.rs +++ b/crates/hir_def/src/item_tree/lower.rs | |||
@@ -10,7 +10,6 @@ use syntax::{ | |||
10 | }; | 10 | }; |
11 | 11 | ||
12 | use crate::{ | 12 | use crate::{ |
13 | attr::Attrs, | ||
14 | generics::{GenericParams, TypeParamData, TypeParamProvenance}, | 13 | generics::{GenericParams, TypeParamData, TypeParamProvenance}, |
15 | type_ref::LifetimeRef, | 14 | type_ref::LifetimeRef, |
16 | }; | 15 | }; |
@@ -105,7 +104,7 @@ impl Ctx { | |||
105 | | ast::Item::MacroDef(_) => {} | 104 | | ast::Item::MacroDef(_) => {} |
106 | }; | 105 | }; |
107 | 106 | ||
108 | let attrs = Attrs::new(item, &self.hygiene); | 107 | let attrs = RawAttrs::new(item, &self.hygiene); |
109 | let items = match item { | 108 | let items = match item { |
110 | ast::Item::Struct(ast) => self.lower_struct(ast).map(Into::into), | 109 | ast::Item::Struct(ast) => self.lower_struct(ast).map(Into::into), |
111 | ast::Item::Union(ast) => self.lower_union(ast).map(Into::into), | 110 | ast::Item::Union(ast) => self.lower_union(ast).map(Into::into), |
@@ -138,7 +137,7 @@ impl Ctx { | |||
138 | items | 137 | items |
139 | } | 138 | } |
140 | 139 | ||
141 | fn add_attrs(&mut self, item: AttrOwner, attrs: Attrs) { | 140 | fn add_attrs(&mut self, item: AttrOwner, attrs: RawAttrs) { |
142 | match self.tree.attrs.entry(item) { | 141 | match self.tree.attrs.entry(item) { |
143 | Entry::Occupied(mut entry) => { | 142 | Entry::Occupied(mut entry) => { |
144 | *entry.get_mut() = entry.get().merge(attrs); | 143 | *entry.get_mut() = entry.get().merge(attrs); |
@@ -205,7 +204,7 @@ impl Ctx { | |||
205 | for field in fields.fields() { | 204 | for field in fields.fields() { |
206 | if let Some(data) = self.lower_record_field(&field) { | 205 | if let Some(data) = self.lower_record_field(&field) { |
207 | let idx = self.data().fields.alloc(data); | 206 | let idx = self.data().fields.alloc(data); |
208 | self.add_attrs(idx.into(), Attrs::new(&field, &self.hygiene)); | 207 | self.add_attrs(idx.into(), RawAttrs::new(&field, &self.hygiene)); |
209 | } | 208 | } |
210 | } | 209 | } |
211 | let end = self.next_field_idx(); | 210 | let end = self.next_field_idx(); |
@@ -225,7 +224,7 @@ impl Ctx { | |||
225 | for (i, field) in fields.fields().enumerate() { | 224 | for (i, field) in fields.fields().enumerate() { |
226 | let data = self.lower_tuple_field(i, &field); | 225 | let data = self.lower_tuple_field(i, &field); |
227 | let idx = self.data().fields.alloc(data); | 226 | let idx = self.data().fields.alloc(data); |
228 | self.add_attrs(idx.into(), Attrs::new(&field, &self.hygiene)); | 227 | self.add_attrs(idx.into(), RawAttrs::new(&field, &self.hygiene)); |
229 | } | 228 | } |
230 | let end = self.next_field_idx(); | 229 | let end = self.next_field_idx(); |
231 | IdRange::new(start..end) | 230 | IdRange::new(start..end) |
@@ -270,7 +269,7 @@ impl Ctx { | |||
270 | for variant in variants.variants() { | 269 | for variant in variants.variants() { |
271 | if let Some(data) = self.lower_variant(&variant) { | 270 | if let Some(data) = self.lower_variant(&variant) { |
272 | let idx = self.data().variants.alloc(data); | 271 | let idx = self.data().variants.alloc(data); |
273 | self.add_attrs(idx.into(), Attrs::new(&variant, &self.hygiene)); | 272 | self.add_attrs(idx.into(), RawAttrs::new(&variant, &self.hygiene)); |
274 | } | 273 | } |
275 | } | 274 | } |
276 | let end = self.next_variant_idx(); | 275 | let end = self.next_variant_idx(); |
@@ -438,7 +437,7 @@ impl Ctx { | |||
438 | self.with_inherited_visibility(visibility, |this| { | 437 | self.with_inherited_visibility(visibility, |this| { |
439 | list.assoc_items() | 438 | list.assoc_items() |
440 | .filter_map(|item| { | 439 | .filter_map(|item| { |
441 | let attrs = Attrs::new(&item, &this.hygiene); | 440 | let attrs = RawAttrs::new(&item, &this.hygiene); |
442 | this.collect_inner_items(item.syntax()); | 441 | this.collect_inner_items(item.syntax()); |
443 | this.lower_assoc_item(&item).map(|item| { | 442 | this.lower_assoc_item(&item).map(|item| { |
444 | this.add_attrs(ModItem::from(item).into(), attrs); | 443 | this.add_attrs(ModItem::from(item).into(), attrs); |
@@ -475,7 +474,7 @@ impl Ctx { | |||
475 | .filter_map(|item| { | 474 | .filter_map(|item| { |
476 | self.collect_inner_items(item.syntax()); | 475 | self.collect_inner_items(item.syntax()); |
477 | let assoc = self.lower_assoc_item(&item)?; | 476 | let assoc = self.lower_assoc_item(&item)?; |
478 | let attrs = Attrs::new(&item, &self.hygiene); | 477 | let attrs = RawAttrs::new(&item, &self.hygiene); |
479 | self.add_attrs(ModItem::from(assoc).into(), attrs); | 478 | self.add_attrs(ModItem::from(assoc).into(), attrs); |
480 | Some(assoc) | 479 | Some(assoc) |
481 | }) | 480 | }) |
@@ -560,7 +559,7 @@ impl Ctx { | |||
560 | list.extern_items() | 559 | list.extern_items() |
561 | .filter_map(|item| { | 560 | .filter_map(|item| { |
562 | self.collect_inner_items(item.syntax()); | 561 | self.collect_inner_items(item.syntax()); |
563 | let attrs = Attrs::new(&item, &self.hygiene); | 562 | let attrs = RawAttrs::new(&item, &self.hygiene); |
564 | let id: ModItem = match item { | 563 | let id: ModItem = match item { |
565 | ast::ExternItem::Fn(ast) => { | 564 | ast::ExternItem::Fn(ast) => { |
566 | let func_id = self.lower_function(&ast)?; | 565 | let func_id = self.lower_function(&ast)?; |
diff --git a/crates/hir_def/src/nameres/collector.rs b/crates/hir_def/src/nameres/collector.rs index 1936348fb..b114a6fe4 100644 --- a/crates/hir_def/src/nameres/collector.rs +++ b/crates/hir_def/src/nameres/collector.rs | |||
@@ -221,17 +221,20 @@ impl DefCollector<'_> { | |||
221 | let item_tree = self.db.item_tree(file_id.into()); | 221 | let item_tree = self.db.item_tree(file_id.into()); |
222 | let module_id = self.def_map.root; | 222 | let module_id = self.def_map.root; |
223 | self.def_map.modules[module_id].origin = ModuleOrigin::CrateRoot { definition: file_id }; | 223 | self.def_map.modules[module_id].origin = ModuleOrigin::CrateRoot { definition: file_id }; |
224 | let mut root_collector = ModCollector { | 224 | if item_tree |
225 | def_collector: &mut *self, | 225 | .top_level_attrs(self.db, self.def_map.krate) |
226 | macro_depth: 0, | 226 | .cfg() |
227 | module_id, | 227 | .map_or(true, |cfg| self.cfg_options.check(&cfg) != Some(false)) |
228 | file_id: file_id.into(), | ||
229 | item_tree: &item_tree, | ||
230 | mod_dir: ModDir::root(), | ||
231 | }; | ||
232 | if item_tree.top_level_attrs().cfg().map_or(true, |cfg| root_collector.is_cfg_enabled(&cfg)) | ||
233 | { | 228 | { |
234 | root_collector.collect(item_tree.top_level_items()); | 229 | ModCollector { |
230 | def_collector: &mut *self, | ||
231 | macro_depth: 0, | ||
232 | module_id, | ||
233 | file_id: file_id.into(), | ||
234 | item_tree: &item_tree, | ||
235 | mod_dir: ModDir::root(), | ||
236 | } | ||
237 | .collect(item_tree.top_level_items()); | ||
235 | } | 238 | } |
236 | 239 | ||
237 | // main name resolution fixed-point loop. | 240 | // main name resolution fixed-point loop. |
@@ -905,6 +908,8 @@ struct ModCollector<'a, 'b> { | |||
905 | 908 | ||
906 | impl ModCollector<'_, '_> { | 909 | impl ModCollector<'_, '_> { |
907 | fn collect(&mut self, items: &[ModItem]) { | 910 | fn collect(&mut self, items: &[ModItem]) { |
911 | let krate = self.def_collector.def_map.krate; | ||
912 | |||
908 | // Note: don't assert that inserted value is fresh: it's simply not true | 913 | // Note: don't assert that inserted value is fresh: it's simply not true |
909 | // for macros. | 914 | // for macros. |
910 | self.def_collector.mod_dirs.insert(self.module_id, self.mod_dir.clone()); | 915 | self.def_collector.mod_dirs.insert(self.module_id, self.mod_dir.clone()); |
@@ -921,7 +926,7 @@ impl ModCollector<'_, '_> { | |||
921 | // `#[macro_use] extern crate` is hoisted to imports macros before collecting | 926 | // `#[macro_use] extern crate` is hoisted to imports macros before collecting |
922 | // any other items. | 927 | // any other items. |
923 | for item in items { | 928 | for item in items { |
924 | let attrs = self.item_tree.attrs((*item).into()); | 929 | let attrs = self.item_tree.attrs(self.def_collector.db, krate, (*item).into()); |
925 | if attrs.cfg().map_or(true, |cfg| self.is_cfg_enabled(&cfg)) { | 930 | if attrs.cfg().map_or(true, |cfg| self.is_cfg_enabled(&cfg)) { |
926 | if let ModItem::ExternCrate(id) = item { | 931 | if let ModItem::ExternCrate(id) = item { |
927 | let import = self.item_tree[*id].clone(); | 932 | let import = self.item_tree[*id].clone(); |
@@ -933,7 +938,7 @@ impl ModCollector<'_, '_> { | |||
933 | } | 938 | } |
934 | 939 | ||
935 | for &item in items { | 940 | for &item in items { |
936 | let attrs = self.item_tree.attrs(item.into()); | 941 | let attrs = self.item_tree.attrs(self.def_collector.db, krate, item.into()); |
937 | if let Some(cfg) = attrs.cfg() { | 942 | if let Some(cfg) = attrs.cfg() { |
938 | if !self.is_cfg_enabled(&cfg) { | 943 | if !self.is_cfg_enabled(&cfg) { |
939 | self.emit_unconfigured_diagnostic(item, &cfg); | 944 | self.emit_unconfigured_diagnostic(item, &cfg); |
@@ -946,7 +951,7 @@ impl ModCollector<'_, '_> { | |||
946 | 951 | ||
947 | let mut def = None; | 952 | let mut def = None; |
948 | match item { | 953 | match item { |
949 | ModItem::Mod(m) => self.collect_module(&self.item_tree[m], attrs), | 954 | ModItem::Mod(m) => self.collect_module(&self.item_tree[m], &attrs), |
950 | ModItem::Import(import_id) => { | 955 | ModItem::Import(import_id) => { |
951 | self.def_collector.unresolved_imports.push(ImportDirective { | 956 | self.def_collector.unresolved_imports.push(ImportDirective { |
952 | module_id: self.module_id, | 957 | module_id: self.module_id, |
@@ -975,7 +980,11 @@ impl ModCollector<'_, '_> { | |||
975 | 980 | ||
976 | // "Macro 2.0" is not currently supported by rust-analyzer, but libcore uses it | 981 | // "Macro 2.0" is not currently supported by rust-analyzer, but libcore uses it |
977 | // to define builtin macros, so we support at least that part. | 982 | // to define builtin macros, so we support at least that part. |
978 | let attrs = self.item_tree.attrs(ModItem::from(id).into()); | 983 | let attrs = self.item_tree.attrs( |
984 | self.def_collector.db, | ||
985 | krate, | ||
986 | ModItem::from(id).into(), | ||
987 | ); | ||
979 | if attrs.by_key("rustc_builtin_macro").exists() { | 988 | if attrs.by_key("rustc_builtin_macro").exists() { |
980 | let krate = self.def_collector.def_map.krate; | 989 | let krate = self.def_collector.def_map.krate; |
981 | let macro_id = find_builtin_macro(&mac.name, krate, ast_id) | 990 | let macro_id = find_builtin_macro(&mac.name, krate, ast_id) |
@@ -1012,7 +1021,7 @@ impl ModCollector<'_, '_> { | |||
1012 | ModItem::Function(id) => { | 1021 | ModItem::Function(id) => { |
1013 | let func = &self.item_tree[id]; | 1022 | let func = &self.item_tree[id]; |
1014 | 1023 | ||
1015 | self.collect_proc_macro_def(&func.name, attrs); | 1024 | self.collect_proc_macro_def(&func.name, &attrs); |
1016 | 1025 | ||
1017 | def = Some(DefData { | 1026 | def = Some(DefData { |
1018 | id: FunctionLoc { | 1027 | id: FunctionLoc { |
@@ -1032,7 +1041,7 @@ impl ModCollector<'_, '_> { | |||
1032 | // FIXME: check attrs to see if this is an attribute macro invocation; | 1041 | // FIXME: check attrs to see if this is an attribute macro invocation; |
1033 | // in which case we don't add the invocation, just a single attribute | 1042 | // in which case we don't add the invocation, just a single attribute |
1034 | // macro invocation | 1043 | // macro invocation |
1035 | self.collect_derives(attrs, it.ast_id.upcast()); | 1044 | self.collect_derives(&attrs, it.ast_id.upcast()); |
1036 | 1045 | ||
1037 | def = Some(DefData { | 1046 | def = Some(DefData { |
1038 | id: StructLoc { container, id: ItemTreeId::new(self.file_id, id) } | 1047 | id: StructLoc { container, id: ItemTreeId::new(self.file_id, id) } |
@@ -1049,7 +1058,7 @@ impl ModCollector<'_, '_> { | |||
1049 | // FIXME: check attrs to see if this is an attribute macro invocation; | 1058 | // FIXME: check attrs to see if this is an attribute macro invocation; |
1050 | // in which case we don't add the invocation, just a single attribute | 1059 | // in which case we don't add the invocation, just a single attribute |
1051 | // macro invocation | 1060 | // macro invocation |
1052 | self.collect_derives(attrs, it.ast_id.upcast()); | 1061 | self.collect_derives(&attrs, it.ast_id.upcast()); |
1053 | 1062 | ||
1054 | def = Some(DefData { | 1063 | def = Some(DefData { |
1055 | id: UnionLoc { container, id: ItemTreeId::new(self.file_id, id) } | 1064 | id: UnionLoc { container, id: ItemTreeId::new(self.file_id, id) } |
@@ -1066,7 +1075,7 @@ impl ModCollector<'_, '_> { | |||
1066 | // FIXME: check attrs to see if this is an attribute macro invocation; | 1075 | // FIXME: check attrs to see if this is an attribute macro invocation; |
1067 | // in which case we don't add the invocation, just a single attribute | 1076 | // in which case we don't add the invocation, just a single attribute |
1068 | // macro invocation | 1077 | // macro invocation |
1069 | self.collect_derives(attrs, it.ast_id.upcast()); | 1078 | self.collect_derives(&attrs, it.ast_id.upcast()); |
1070 | 1079 | ||
1071 | def = Some(DefData { | 1080 | def = Some(DefData { |
1072 | id: EnumLoc { container, id: ItemTreeId::new(self.file_id, id) } | 1081 | id: EnumLoc { container, id: ItemTreeId::new(self.file_id, id) } |
@@ -1303,8 +1312,9 @@ impl ModCollector<'_, '_> { | |||
1303 | } | 1312 | } |
1304 | 1313 | ||
1305 | fn collect_macro_rules(&mut self, id: FileItemTreeId<MacroRules>) { | 1314 | fn collect_macro_rules(&mut self, id: FileItemTreeId<MacroRules>) { |
1315 | let krate = self.def_collector.def_map.krate; | ||
1306 | let mac = &self.item_tree[id]; | 1316 | let mac = &self.item_tree[id]; |
1307 | let attrs = self.item_tree.attrs(ModItem::from(id).into()); | 1317 | let attrs = self.item_tree.attrs(self.def_collector.db, krate, ModItem::from(id).into()); |
1308 | let ast_id = InFile::new(self.file_id, mac.ast_id.upcast()); | 1318 | let ast_id = InFile::new(self.file_id, mac.ast_id.upcast()); |
1309 | 1319 | ||
1310 | let export_attr = attrs.by_key("macro_export"); | 1320 | let export_attr = attrs.by_key("macro_export"); |