diff options
Diffstat (limited to 'crates/hir_def/src')
-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 | 33 | ||||
-rw-r--r-- | crates/hir_def/src/data.rs | 5 | ||||
-rw-r--r-- | crates/hir_def/src/db.rs | 7 | ||||
-rw-r--r-- | crates/hir_def/src/generics.rs | 9 | ||||
-rw-r--r-- | crates/hir_def/src/item_scope.rs | 2 | ||||
-rw-r--r-- | crates/hir_def/src/item_tree.rs | 43 | ||||
-rw-r--r-- | crates/hir_def/src/item_tree/lower.rs | 53 | ||||
-rw-r--r-- | crates/hir_def/src/lang_item.rs | 77 | ||||
-rw-r--r-- | crates/hir_def/src/lib.rs | 30 | ||||
-rw-r--r-- | crates/hir_def/src/nameres/collector.rs | 121 | ||||
-rw-r--r-- | crates/hir_def/src/nameres/tests/macros.rs | 31 | ||||
-rw-r--r-- | crates/hir_def/src/path/lower.rs | 4 | ||||
-rw-r--r-- | crates/hir_def/src/type_ref.rs | 10 |
16 files changed, 388 insertions, 247 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 c64b78445..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 | pub 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 bdba4c33e..0f404be1b 100644 --- a/crates/hir_def/src/body/lower.rs +++ b/crates/hir_def/src/body/lower.rs | |||
@@ -233,8 +233,7 @@ impl ExprCollector<'_> { | |||
233 | let res = self.collect_block(block); | 233 | let res = self.collect_block(block); |
234 | match &mut self.body.exprs[res] { | 234 | match &mut self.body.exprs[res] { |
235 | Expr::Block { label: block_label, .. } => { | 235 | Expr::Block { label: block_label, .. } => { |
236 | *block_label = | 236 | *block_label = label.lifetime().map(|t| Name::new_lifetime(&t)) |
237 | label.lifetime_token().map(|t| Name::new_lifetime(&t)) | ||
238 | } | 237 | } |
239 | _ => unreachable!(), | 238 | _ => unreachable!(), |
240 | } | 239 | } |
@@ -254,10 +253,7 @@ impl ExprCollector<'_> { | |||
254 | self.alloc_expr( | 253 | self.alloc_expr( |
255 | Expr::Loop { | 254 | Expr::Loop { |
256 | body, | 255 | body, |
257 | label: e | 256 | label: e.label().and_then(|l| l.lifetime()).map(|l| Name::new_lifetime(&l)), |
258 | .label() | ||
259 | .and_then(|l| l.lifetime_token()) | ||
260 | .map(|l| Name::new_lifetime(&l)), | ||
261 | }, | 257 | }, |
262 | syntax_ptr, | 258 | syntax_ptr, |
263 | ) | 259 | ) |
@@ -288,7 +284,7 @@ impl ExprCollector<'_> { | |||
288 | body: match_expr, | 284 | body: match_expr, |
289 | label: e | 285 | label: e |
290 | .label() | 286 | .label() |
291 | .and_then(|l| l.lifetime_token()) | 287 | .and_then(|l| l.lifetime()) |
292 | .map(|l| Name::new_lifetime(&l)), | 288 | .map(|l| Name::new_lifetime(&l)), |
293 | }, | 289 | }, |
294 | syntax_ptr, | 290 | syntax_ptr, |
@@ -301,10 +297,7 @@ impl ExprCollector<'_> { | |||
301 | Expr::While { | 297 | Expr::While { |
302 | condition, | 298 | condition, |
303 | body, | 299 | body, |
304 | label: e | 300 | label: e.label().and_then(|l| l.lifetime()).map(|l| Name::new_lifetime(&l)), |
305 | .label() | ||
306 | .and_then(|l| l.lifetime_token()) | ||
307 | .map(|l| Name::new_lifetime(&l)), | ||
308 | }, | 301 | }, |
309 | syntax_ptr, | 302 | syntax_ptr, |
310 | ) | 303 | ) |
@@ -318,10 +311,7 @@ impl ExprCollector<'_> { | |||
318 | iterable, | 311 | iterable, |
319 | pat, | 312 | pat, |
320 | body, | 313 | body, |
321 | label: e | 314 | label: e.label().and_then(|l| l.lifetime()).map(|l| Name::new_lifetime(&l)), |
322 | .label() | ||
323 | .and_then(|l| l.lifetime_token()) | ||
324 | .map(|l| Name::new_lifetime(&l)), | ||
325 | }, | 315 | }, |
326 | syntax_ptr, | 316 | syntax_ptr, |
327 | ) | 317 | ) |
@@ -380,13 +370,13 @@ impl ExprCollector<'_> { | |||
380 | self.alloc_expr(path, syntax_ptr) | 370 | self.alloc_expr(path, syntax_ptr) |
381 | } | 371 | } |
382 | ast::Expr::ContinueExpr(e) => self.alloc_expr( | 372 | ast::Expr::ContinueExpr(e) => self.alloc_expr( |
383 | Expr::Continue { label: e.lifetime_token().map(|l| Name::new_lifetime(&l)) }, | 373 | Expr::Continue { label: e.lifetime().map(|l| Name::new_lifetime(&l)) }, |
384 | syntax_ptr, | 374 | syntax_ptr, |
385 | ), | 375 | ), |
386 | ast::Expr::BreakExpr(e) => { | 376 | ast::Expr::BreakExpr(e) => { |
387 | let expr = e.expr().map(|e| self.collect_expr(e)); | 377 | let expr = e.expr().map(|e| self.collect_expr(e)); |
388 | self.alloc_expr( | 378 | self.alloc_expr( |
389 | Expr::Break { expr, label: e.lifetime_token().map(|l| Name::new_lifetime(&l)) }, | 379 | Expr::Break { expr, label: e.lifetime().map(|l| Name::new_lifetime(&l)) }, |
390 | syntax_ptr, | 380 | syntax_ptr, |
391 | ) | 381 | ) |
392 | } | 382 | } |
@@ -772,7 +762,10 @@ impl ExprCollector<'_> { | |||
772 | | ast::Item::Module(_) | 762 | | ast::Item::Module(_) |
773 | | ast::Item::MacroCall(_) => return None, | 763 | | ast::Item::MacroCall(_) => return None, |
774 | ast::Item::MacroRules(def) => { | 764 | ast::Item::MacroRules(def) => { |
775 | return Some(Either::Right(def)); | 765 | return Some(Either::Right(ast::Macro::from(def))); |
766 | } | ||
767 | ast::Item::MacroDef(def) => { | ||
768 | return Some(Either::Right(ast::Macro::from(def))); | ||
776 | } | 769 | } |
777 | }; | 770 | }; |
778 | 771 | ||
@@ -800,7 +793,7 @@ impl ExprCollector<'_> { | |||
800 | } | 793 | } |
801 | Either::Right(e) => { | 794 | Either::Right(e) => { |
802 | let mac = MacroDefId { | 795 | let mac = MacroDefId { |
803 | krate: Some(self.expander.module.krate), | 796 | krate: self.expander.module.krate, |
804 | ast_id: Some(self.expander.ast_id(&e)), | 797 | ast_id: Some(self.expander.ast_id(&e)), |
805 | kind: MacroDefKind::Declarative, | 798 | kind: MacroDefKind::Declarative, |
806 | local_inner: false, | 799 | local_inner: false, |
@@ -970,7 +963,7 @@ impl ExprCollector<'_> { | |||
970 | /// 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 |
971 | /// not. | 964 | /// not. |
972 | fn check_cfg(&mut self, owner: &dyn ast::AttrsOwner) -> Option<()> { | 965 | fn check_cfg(&mut self, owner: &dyn ast::AttrsOwner) -> Option<()> { |
973 | match self.expander.parse_attrs(owner).cfg() { | 966 | match self.expander.parse_attrs(self.db, owner).cfg() { |
974 | Some(cfg) => { | 967 | Some(cfg) => { |
975 | if self.expander.cfg_options().check(&cfg) != Some(false) { | 968 | if self.expander.cfg_options().check(&cfg) != Some(false) { |
976 | 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/db.rs b/crates/hir_def/src/db.rs index 7f250da33..d1a459066 100644 --- a/crates/hir_def/src/db.rs +++ b/crates/hir_def/src/db.rs | |||
@@ -16,8 +16,8 @@ use crate::{ | |||
16 | lang_item::{LangItemTarget, LangItems}, | 16 | lang_item::{LangItemTarget, LangItems}, |
17 | nameres::CrateDefMap, | 17 | nameres::CrateDefMap, |
18 | AttrDefId, ConstId, ConstLoc, DefWithBodyId, EnumId, EnumLoc, FunctionId, FunctionLoc, | 18 | AttrDefId, ConstId, ConstLoc, DefWithBodyId, EnumId, EnumLoc, FunctionId, FunctionLoc, |
19 | GenericDefId, ImplId, ImplLoc, ModuleId, StaticId, StaticLoc, StructId, StructLoc, TraitId, | 19 | GenericDefId, ImplId, ImplLoc, StaticId, StaticLoc, StructId, StructLoc, TraitId, TraitLoc, |
20 | TraitLoc, TypeAliasId, TypeAliasLoc, UnionId, UnionLoc, | 20 | TypeAliasId, TypeAliasLoc, UnionId, UnionLoc, |
21 | }; | 21 | }; |
22 | 22 | ||
23 | #[salsa::query_group(InternDatabaseStorage)] | 23 | #[salsa::query_group(InternDatabaseStorage)] |
@@ -95,9 +95,6 @@ pub trait DefDatabase: InternDatabase + AstDatabase + Upcast<dyn AstDatabase> { | |||
95 | #[salsa::invoke(Attrs::attrs_query)] | 95 | #[salsa::invoke(Attrs::attrs_query)] |
96 | fn attrs(&self, def: AttrDefId) -> Attrs; | 96 | fn attrs(&self, def: AttrDefId) -> Attrs; |
97 | 97 | ||
98 | #[salsa::invoke(LangItems::module_lang_items_query)] | ||
99 | fn module_lang_items(&self, module: ModuleId) -> Option<Arc<LangItems>>; | ||
100 | |||
101 | #[salsa::invoke(LangItems::crate_lang_items_query)] | 98 | #[salsa::invoke(LangItems::crate_lang_items_query)] |
102 | fn crate_lang_items(&self, krate: CrateId) -> Arc<LangItems>; | 99 | fn crate_lang_items(&self, krate: CrateId) -> Arc<LangItems>; |
103 | 100 | ||
diff --git a/crates/hir_def/src/generics.rs b/crates/hir_def/src/generics.rs index 924046435..41134d23b 100644 --- a/crates/hir_def/src/generics.rs +++ b/crates/hir_def/src/generics.rs | |||
@@ -260,9 +260,8 @@ impl GenericParams { | |||
260 | self.fill_bounds(&lower_ctx, &type_param, Either::Left(type_ref)); | 260 | self.fill_bounds(&lower_ctx, &type_param, Either::Left(type_ref)); |
261 | } | 261 | } |
262 | for lifetime_param in params.lifetime_params() { | 262 | for lifetime_param in params.lifetime_params() { |
263 | let name = lifetime_param | 263 | let name = |
264 | .lifetime_token() | 264 | lifetime_param.lifetime().map_or_else(Name::missing, |lt| Name::new_lifetime(<)); |
265 | .map_or_else(Name::missing, |tok| Name::new_lifetime(&tok)); | ||
266 | let param = LifetimeParamData { name: name.clone() }; | 265 | let param = LifetimeParamData { name: name.clone() }; |
267 | let param_id = self.lifetimes.alloc(param); | 266 | let param_id = self.lifetimes.alloc(param); |
268 | sm.lifetime_params.insert(param_id, lifetime_param.clone()); | 267 | sm.lifetime_params.insert(param_id, lifetime_param.clone()); |
@@ -275,8 +274,8 @@ impl GenericParams { | |||
275 | for pred in where_clause.predicates() { | 274 | for pred in where_clause.predicates() { |
276 | let target = if let Some(type_ref) = pred.ty() { | 275 | let target = if let Some(type_ref) = pred.ty() { |
277 | Either::Left(TypeRef::from_ast(lower_ctx, type_ref)) | 276 | Either::Left(TypeRef::from_ast(lower_ctx, type_ref)) |
278 | } else if let Some(lifetime_tok) = pred.lifetime_token() { | 277 | } else if let Some(lifetime) = pred.lifetime() { |
279 | Either::Right(LifetimeRef::from_token(lifetime_tok)) | 278 | Either::Right(LifetimeRef::new(&lifetime)) |
280 | } else { | 279 | } else { |
281 | continue; | 280 | continue; |
282 | }; | 281 | }; |
diff --git a/crates/hir_def/src/item_scope.rs b/crates/hir_def/src/item_scope.rs index a8b3fe844..62ab3b2bd 100644 --- a/crates/hir_def/src/item_scope.rs +++ b/crates/hir_def/src/item_scope.rs | |||
@@ -363,7 +363,7 @@ impl ItemInNs { | |||
363 | ModuleDefId::TypeAliasId(id) => id.lookup(db).module(db).krate, | 363 | ModuleDefId::TypeAliasId(id) => id.lookup(db).module(db).krate, |
364 | ModuleDefId::BuiltinType(_) => return None, | 364 | ModuleDefId::BuiltinType(_) => return None, |
365 | }, | 365 | }, |
366 | ItemInNs::Macros(id) => return id.krate, | 366 | ItemInNs::Macros(id) => return Some(id.krate), |
367 | }) | 367 | }) |
368 | } | 368 | } |
369 | } | 369 | } |
diff --git a/crates/hir_def/src/item_tree.rs b/crates/hir_def/src/item_tree.rs index 1c9babf37..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) => { |
@@ -143,6 +144,7 @@ impl ItemTree { | |||
143 | mods, | 144 | mods, |
144 | macro_calls, | 145 | macro_calls, |
145 | macro_rules, | 146 | macro_rules, |
147 | macro_defs, | ||
146 | exprs, | 148 | exprs, |
147 | vis, | 149 | vis, |
148 | generics, | 150 | generics, |
@@ -164,6 +166,7 @@ impl ItemTree { | |||
164 | mods.shrink_to_fit(); | 166 | mods.shrink_to_fit(); |
165 | macro_calls.shrink_to_fit(); | 167 | macro_calls.shrink_to_fit(); |
166 | macro_rules.shrink_to_fit(); | 168 | macro_rules.shrink_to_fit(); |
169 | macro_defs.shrink_to_fit(); | ||
167 | exprs.shrink_to_fit(); | 170 | exprs.shrink_to_fit(); |
168 | 171 | ||
169 | vis.arena.shrink_to_fit(); | 172 | vis.arena.shrink_to_fit(); |
@@ -178,12 +181,16 @@ impl ItemTree { | |||
178 | } | 181 | } |
179 | 182 | ||
180 | /// Returns the inner attributes of the source file. | 183 | /// Returns the inner attributes of the source file. |
181 | pub fn top_level_attrs(&self) -> &Attrs { | 184 | pub fn top_level_attrs(&self, db: &dyn DefDatabase, krate: CrateId) -> Attrs { |
182 | self.attrs.get(&AttrOwner::TopLevel).unwrap_or(&Attrs::EMPTY) | 185 | self.attrs.get(&AttrOwner::TopLevel).unwrap_or(&RawAttrs::EMPTY).clone().filter(db, krate) |
183 | } | 186 | } |
184 | 187 | ||
185 | pub fn attrs(&self, of: AttrOwner) -> &Attrs { | 188 | pub(crate) fn raw_attrs(&self, of: AttrOwner) -> &RawAttrs { |
186 | 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) | ||
187 | } | 194 | } |
188 | 195 | ||
189 | /// Returns the lowered inner items that `ast` corresponds to. | 196 | /// Returns the lowered inner items that `ast` corresponds to. |
@@ -283,6 +290,7 @@ struct ItemTreeData { | |||
283 | mods: Arena<Mod>, | 290 | mods: Arena<Mod>, |
284 | macro_calls: Arena<MacroCall>, | 291 | macro_calls: Arena<MacroCall>, |
285 | macro_rules: Arena<MacroRules>, | 292 | macro_rules: Arena<MacroRules>, |
293 | macro_defs: Arena<MacroDef>, | ||
286 | exprs: Arena<Expr>, | 294 | exprs: Arena<Expr>, |
287 | 295 | ||
288 | vis: ItemVisibilities, | 296 | vis: ItemVisibilities, |
@@ -431,6 +439,7 @@ mod_items! { | |||
431 | Mod in mods -> ast::Module, | 439 | Mod in mods -> ast::Module, |
432 | MacroCall in macro_calls -> ast::MacroCall, | 440 | MacroCall in macro_calls -> ast::MacroCall, |
433 | MacroRules in macro_rules -> ast::MacroRules, | 441 | MacroRules in macro_rules -> ast::MacroRules, |
442 | MacroDef in macro_defs -> ast::MacroDef, | ||
434 | } | 443 | } |
435 | 444 | ||
436 | macro_rules! impl_index { | 445 | macro_rules! impl_index { |
@@ -640,17 +649,19 @@ pub struct MacroCall { | |||
640 | 649 | ||
641 | #[derive(Debug, Clone, Eq, PartialEq)] | 650 | #[derive(Debug, Clone, Eq, PartialEq)] |
642 | pub struct MacroRules { | 651 | pub struct MacroRules { |
643 | /// For `macro_rules!` declarations, this is the name of the declared macro. | 652 | /// The name of the declared macro. |
644 | pub name: Name, | 653 | pub name: Name, |
645 | /// Has `#[macro_export]`. | ||
646 | pub is_export: bool, | ||
647 | /// Has `#[macro_export(local_inner_macros)]`. | ||
648 | pub is_local_inner: bool, | ||
649 | /// Has `#[rustc_builtin_macro]`. | ||
650 | pub is_builtin: bool, | ||
651 | pub ast_id: FileAstId<ast::MacroRules>, | 654 | pub ast_id: FileAstId<ast::MacroRules>, |
652 | } | 655 | } |
653 | 656 | ||
657 | /// "Macros 2.0" macro definition. | ||
658 | #[derive(Debug, Clone, Eq, PartialEq)] | ||
659 | pub struct MacroDef { | ||
660 | pub name: Name, | ||
661 | pub visibility: RawVisibilityId, | ||
662 | pub ast_id: FileAstId<ast::MacroDef>, | ||
663 | } | ||
664 | |||
654 | // NB: There's no `FileAstId` for `Expr`. The only case where this would be useful is for array | 665 | // NB: There's no `FileAstId` for `Expr`. The only case where this would be useful is for array |
655 | // lengths, but we don't do much with them yet. | 666 | // lengths, but we don't do much with them yet. |
656 | #[derive(Debug, Clone, Eq, PartialEq)] | 667 | #[derive(Debug, Clone, Eq, PartialEq)] |
@@ -680,7 +691,8 @@ impl ModItem { | |||
680 | | ModItem::Trait(_) | 691 | | ModItem::Trait(_) |
681 | | ModItem::Impl(_) | 692 | | ModItem::Impl(_) |
682 | | ModItem::Mod(_) | 693 | | ModItem::Mod(_) |
683 | | ModItem::MacroRules(_) => None, | 694 | | ModItem::MacroRules(_) |
695 | | ModItem::MacroDef(_) => None, | ||
684 | ModItem::MacroCall(call) => Some(AssocItem::MacroCall(*call)), | 696 | ModItem::MacroCall(call) => Some(AssocItem::MacroCall(*call)), |
685 | ModItem::Const(konst) => Some(AssocItem::Const(*konst)), | 697 | ModItem::Const(konst) => Some(AssocItem::Const(*konst)), |
686 | ModItem::TypeAlias(alias) => Some(AssocItem::TypeAlias(*alias)), | 698 | ModItem::TypeAlias(alias) => Some(AssocItem::TypeAlias(*alias)), |
@@ -708,6 +720,7 @@ impl ModItem { | |||
708 | ModItem::Mod(it) => tree[it.index].ast_id().upcast(), | 720 | ModItem::Mod(it) => tree[it.index].ast_id().upcast(), |
709 | ModItem::MacroCall(it) => tree[it.index].ast_id().upcast(), | 721 | ModItem::MacroCall(it) => tree[it.index].ast_id().upcast(), |
710 | ModItem::MacroRules(it) => tree[it.index].ast_id().upcast(), | 722 | ModItem::MacroRules(it) => tree[it.index].ast_id().upcast(), |
723 | ModItem::MacroDef(it) => tree[it.index].ast_id().upcast(), | ||
711 | } | 724 | } |
712 | } | 725 | } |
713 | } | 726 | } |
diff --git a/crates/hir_def/src/item_tree/lower.rs b/crates/hir_def/src/item_tree/lower.rs index b39d7fb7a..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 | }; |
@@ -101,10 +100,11 @@ impl Ctx { | |||
101 | | ast::Item::ExternCrate(_) | 100 | | ast::Item::ExternCrate(_) |
102 | | ast::Item::Use(_) | 101 | | ast::Item::Use(_) |
103 | | ast::Item::MacroCall(_) | 102 | | ast::Item::MacroCall(_) |
104 | | ast::Item::MacroRules(_) => {} | 103 | | ast::Item::MacroRules(_) |
104 | | ast::Item::MacroDef(_) => {} | ||
105 | }; | 105 | }; |
106 | 106 | ||
107 | let attrs = Attrs::new(item, &self.hygiene); | 107 | let attrs = RawAttrs::new(item, &self.hygiene); |
108 | let items = match item { | 108 | let items = match item { |
109 | ast::Item::Struct(ast) => self.lower_struct(ast).map(Into::into), | 109 | ast::Item::Struct(ast) => self.lower_struct(ast).map(Into::into), |
110 | ast::Item::Union(ast) => self.lower_union(ast).map(Into::into), | 110 | ast::Item::Union(ast) => self.lower_union(ast).map(Into::into), |
@@ -122,6 +122,7 @@ impl Ctx { | |||
122 | ast::Item::ExternCrate(ast) => self.lower_extern_crate(ast).map(Into::into), | 122 | ast::Item::ExternCrate(ast) => self.lower_extern_crate(ast).map(Into::into), |
123 | ast::Item::MacroCall(ast) => self.lower_macro_call(ast).map(Into::into), | 123 | ast::Item::MacroCall(ast) => self.lower_macro_call(ast).map(Into::into), |
124 | ast::Item::MacroRules(ast) => self.lower_macro_rules(ast).map(Into::into), | 124 | ast::Item::MacroRules(ast) => self.lower_macro_rules(ast).map(Into::into), |
125 | ast::Item::MacroDef(ast) => self.lower_macro_def(ast).map(Into::into), | ||
125 | ast::Item::ExternBlock(ast) => { | 126 | ast::Item::ExternBlock(ast) => { |
126 | Some(ModItems(self.lower_extern_block(ast).into_iter().collect::<SmallVec<_>>())) | 127 | Some(ModItems(self.lower_extern_block(ast).into_iter().collect::<SmallVec<_>>())) |
127 | } | 128 | } |
@@ -136,7 +137,7 @@ impl Ctx { | |||
136 | items | 137 | items |
137 | } | 138 | } |
138 | 139 | ||
139 | fn add_attrs(&mut self, item: AttrOwner, attrs: Attrs) { | 140 | fn add_attrs(&mut self, item: AttrOwner, attrs: RawAttrs) { |
140 | match self.tree.attrs.entry(item) { | 141 | match self.tree.attrs.entry(item) { |
141 | Entry::Occupied(mut entry) => { | 142 | Entry::Occupied(mut entry) => { |
142 | *entry.get_mut() = entry.get().merge(attrs); | 143 | *entry.get_mut() = entry.get().merge(attrs); |
@@ -203,7 +204,7 @@ impl Ctx { | |||
203 | for field in fields.fields() { | 204 | for field in fields.fields() { |
204 | if let Some(data) = self.lower_record_field(&field) { | 205 | if let Some(data) = self.lower_record_field(&field) { |
205 | let idx = self.data().fields.alloc(data); | 206 | let idx = self.data().fields.alloc(data); |
206 | self.add_attrs(idx.into(), Attrs::new(&field, &self.hygiene)); | 207 | self.add_attrs(idx.into(), RawAttrs::new(&field, &self.hygiene)); |
207 | } | 208 | } |
208 | } | 209 | } |
209 | let end = self.next_field_idx(); | 210 | let end = self.next_field_idx(); |
@@ -223,7 +224,7 @@ impl Ctx { | |||
223 | for (i, field) in fields.fields().enumerate() { | 224 | for (i, field) in fields.fields().enumerate() { |
224 | let data = self.lower_tuple_field(i, &field); | 225 | let data = self.lower_tuple_field(i, &field); |
225 | let idx = self.data().fields.alloc(data); | 226 | let idx = self.data().fields.alloc(data); |
226 | self.add_attrs(idx.into(), Attrs::new(&field, &self.hygiene)); | 227 | self.add_attrs(idx.into(), RawAttrs::new(&field, &self.hygiene)); |
227 | } | 228 | } |
228 | let end = self.next_field_idx(); | 229 | let end = self.next_field_idx(); |
229 | IdRange::new(start..end) | 230 | IdRange::new(start..end) |
@@ -268,7 +269,7 @@ impl Ctx { | |||
268 | for variant in variants.variants() { | 269 | for variant in variants.variants() { |
269 | if let Some(data) = self.lower_variant(&variant) { | 270 | if let Some(data) = self.lower_variant(&variant) { |
270 | let idx = self.data().variants.alloc(data); | 271 | let idx = self.data().variants.alloc(data); |
271 | self.add_attrs(idx.into(), Attrs::new(&variant, &self.hygiene)); | 272 | self.add_attrs(idx.into(), RawAttrs::new(&variant, &self.hygiene)); |
272 | } | 273 | } |
273 | } | 274 | } |
274 | let end = self.next_variant_idx(); | 275 | let end = self.next_variant_idx(); |
@@ -298,12 +299,12 @@ impl Ctx { | |||
298 | ast::SelfParamKind::Owned => self_type, | 299 | ast::SelfParamKind::Owned => self_type, |
299 | ast::SelfParamKind::Ref => TypeRef::Reference( | 300 | ast::SelfParamKind::Ref => TypeRef::Reference( |
300 | Box::new(self_type), | 301 | Box::new(self_type), |
301 | self_param.lifetime_token().map(LifetimeRef::from_token), | 302 | self_param.lifetime().as_ref().map(LifetimeRef::new), |
302 | Mutability::Shared, | 303 | Mutability::Shared, |
303 | ), | 304 | ), |
304 | ast::SelfParamKind::MutRef => TypeRef::Reference( | 305 | ast::SelfParamKind::MutRef => TypeRef::Reference( |
305 | Box::new(self_type), | 306 | Box::new(self_type), |
306 | self_param.lifetime_token().map(LifetimeRef::from_token), | 307 | self_param.lifetime().as_ref().map(LifetimeRef::new), |
307 | Mutability::Mut, | 308 | Mutability::Mut, |
308 | ), | 309 | ), |
309 | } | 310 | } |
@@ -436,7 +437,7 @@ impl Ctx { | |||
436 | self.with_inherited_visibility(visibility, |this| { | 437 | self.with_inherited_visibility(visibility, |this| { |
437 | list.assoc_items() | 438 | list.assoc_items() |
438 | .filter_map(|item| { | 439 | .filter_map(|item| { |
439 | let attrs = Attrs::new(&item, &this.hygiene); | 440 | let attrs = RawAttrs::new(&item, &this.hygiene); |
440 | this.collect_inner_items(item.syntax()); | 441 | this.collect_inner_items(item.syntax()); |
441 | this.lower_assoc_item(&item).map(|item| { | 442 | this.lower_assoc_item(&item).map(|item| { |
442 | this.add_attrs(ModItem::from(item).into(), attrs); | 443 | this.add_attrs(ModItem::from(item).into(), attrs); |
@@ -473,7 +474,7 @@ impl Ctx { | |||
473 | .filter_map(|item| { | 474 | .filter_map(|item| { |
474 | self.collect_inner_items(item.syntax()); | 475 | self.collect_inner_items(item.syntax()); |
475 | let assoc = self.lower_assoc_item(&item)?; | 476 | let assoc = self.lower_assoc_item(&item)?; |
476 | let attrs = Attrs::new(&item, &self.hygiene); | 477 | let attrs = RawAttrs::new(&item, &self.hygiene); |
477 | self.add_attrs(ModItem::from(assoc).into(), attrs); | 478 | self.add_attrs(ModItem::from(assoc).into(), attrs); |
478 | Some(assoc) | 479 | Some(assoc) |
479 | }) | 480 | }) |
@@ -537,28 +538,20 @@ impl Ctx { | |||
537 | 538 | ||
538 | fn lower_macro_rules(&mut self, m: &ast::MacroRules) -> Option<FileItemTreeId<MacroRules>> { | 539 | fn lower_macro_rules(&mut self, m: &ast::MacroRules) -> Option<FileItemTreeId<MacroRules>> { |
539 | let name = m.name().map(|it| it.as_name())?; | 540 | let name = m.name().map(|it| it.as_name())?; |
540 | let attrs = Attrs::new(m, &self.hygiene); | ||
541 | |||
542 | let ast_id = self.source_ast_id_map.ast_id(m); | 541 | let ast_id = self.source_ast_id_map.ast_id(m); |
543 | 542 | ||
544 | // FIXME: cfg_attr | 543 | let res = MacroRules { name, ast_id }; |
545 | let export_attr = attrs.by_key("macro_export"); | 544 | Some(id(self.data().macro_rules.alloc(res))) |
545 | } | ||
546 | 546 | ||
547 | let is_export = export_attr.exists(); | 547 | fn lower_macro_def(&mut self, m: &ast::MacroDef) -> Option<FileItemTreeId<MacroDef>> { |
548 | let is_local_inner = if is_export { | 548 | let name = m.name().map(|it| it.as_name())?; |
549 | export_attr.tt_values().map(|it| &it.token_trees).flatten().any(|it| match it { | ||
550 | tt::TokenTree::Leaf(tt::Leaf::Ident(ident)) => { | ||
551 | ident.text.contains("local_inner_macros") | ||
552 | } | ||
553 | _ => false, | ||
554 | }) | ||
555 | } else { | ||
556 | false | ||
557 | }; | ||
558 | 549 | ||
559 | let is_builtin = attrs.by_key("rustc_builtin_macro").exists(); | 550 | let ast_id = self.source_ast_id_map.ast_id(m); |
560 | let res = MacroRules { name, is_export, is_builtin, is_local_inner, ast_id }; | 551 | let visibility = self.lower_visibility(m); |
561 | Some(id(self.data().macro_rules.alloc(res))) | 552 | |
553 | let res = MacroDef { name, ast_id, visibility }; | ||
554 | Some(id(self.data().macro_defs.alloc(res))) | ||
562 | } | 555 | } |
563 | 556 | ||
564 | fn lower_extern_block(&mut self, block: &ast::ExternBlock) -> Vec<ModItem> { | 557 | fn lower_extern_block(&mut self, block: &ast::ExternBlock) -> Vec<ModItem> { |
@@ -566,7 +559,7 @@ impl Ctx { | |||
566 | list.extern_items() | 559 | list.extern_items() |
567 | .filter_map(|item| { | 560 | .filter_map(|item| { |
568 | self.collect_inner_items(item.syntax()); | 561 | self.collect_inner_items(item.syntax()); |
569 | let attrs = Attrs::new(&item, &self.hygiene); | 562 | let attrs = RawAttrs::new(&item, &self.hygiene); |
570 | let id: ModItem = match item { | 563 | let id: ModItem = match item { |
571 | ast::ExternItem::Fn(ast) => { | 564 | ast::ExternItem::Fn(ast) => { |
572 | let func_id = self.lower_function(&ast)?; | 565 | let func_id = self.lower_function(&ast)?; |
diff --git a/crates/hir_def/src/lang_item.rs b/crates/hir_def/src/lang_item.rs index 063eadccb..30188b740 100644 --- a/crates/hir_def/src/lang_item.rs +++ b/crates/hir_def/src/lang_item.rs | |||
@@ -8,8 +8,8 @@ use rustc_hash::FxHashMap; | |||
8 | use syntax::SmolStr; | 8 | use syntax::SmolStr; |
9 | 9 | ||
10 | use crate::{ | 10 | use crate::{ |
11 | db::DefDatabase, AdtId, AttrDefId, CrateId, EnumId, FunctionId, ImplId, ModuleDefId, ModuleId, | 11 | db::DefDatabase, AdtId, AttrDefId, CrateId, EnumId, FunctionId, ImplId, ModuleDefId, StaticId, |
12 | StaticId, StructId, TraitId, | 12 | StructId, TraitId, |
13 | }; | 13 | }; |
14 | 14 | ||
15 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] | 15 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] |
@@ -84,27 +84,34 @@ impl LangItems { | |||
84 | 84 | ||
85 | let crate_def_map = db.crate_def_map(krate); | 85 | let crate_def_map = db.crate_def_map(krate); |
86 | 86 | ||
87 | crate_def_map | 87 | for (_, module_data) in crate_def_map.modules.iter() { |
88 | .modules | 88 | for impl_def in module_data.scope.impls() { |
89 | .iter() | 89 | lang_items.collect_lang_item(db, impl_def, LangItemTarget::ImplDefId) |
90 | .filter_map(|(local_id, _)| db.module_lang_items(ModuleId { krate, local_id })) | 90 | } |
91 | .for_each(|it| lang_items.items.extend(it.items.iter().map(|(k, v)| (k.clone(), *v)))); | ||
92 | |||
93 | Arc::new(lang_items) | ||
94 | } | ||
95 | 91 | ||
96 | pub(crate) fn module_lang_items_query( | 92 | for def in module_data.scope.declarations() { |
97 | db: &dyn DefDatabase, | 93 | match def { |
98 | module: ModuleId, | 94 | ModuleDefId::TraitId(trait_) => { |
99 | ) -> Option<Arc<LangItems>> { | 95 | lang_items.collect_lang_item(db, trait_, LangItemTarget::TraitId) |
100 | let _p = profile::span("module_lang_items_query"); | 96 | } |
101 | let mut lang_items = LangItems::default(); | 97 | ModuleDefId::AdtId(AdtId::EnumId(e)) => { |
102 | lang_items.collect_lang_items(db, module); | 98 | lang_items.collect_lang_item(db, e, LangItemTarget::EnumId) |
103 | if lang_items.items.is_empty() { | 99 | } |
104 | None | 100 | ModuleDefId::AdtId(AdtId::StructId(s)) => { |
105 | } else { | 101 | lang_items.collect_lang_item(db, s, LangItemTarget::StructId) |
106 | Some(Arc::new(lang_items)) | 102 | } |
103 | ModuleDefId::FunctionId(f) => { | ||
104 | lang_items.collect_lang_item(db, f, LangItemTarget::FunctionId) | ||
105 | } | ||
106 | ModuleDefId::StaticId(s) => { | ||
107 | lang_items.collect_lang_item(db, s, LangItemTarget::StaticId) | ||
108 | } | ||
109 | _ => {} | ||
110 | } | ||
111 | } | ||
107 | } | 112 | } |
113 | |||
114 | Arc::new(lang_items) | ||
108 | } | 115 | } |
109 | 116 | ||
110 | /// Salsa query. Look for a lang item, starting from the specified crate and recursively | 117 | /// Salsa query. Look for a lang item, starting from the specified crate and recursively |
@@ -126,34 +133,6 @@ impl LangItems { | |||
126 | .find_map(|dep| db.lang_item(dep.crate_id, item.clone())) | 133 | .find_map(|dep| db.lang_item(dep.crate_id, item.clone())) |
127 | } | 134 | } |
128 | 135 | ||
129 | fn collect_lang_items(&mut self, db: &dyn DefDatabase, module: ModuleId) { | ||
130 | // Look for impl targets | ||
131 | let def_map = db.crate_def_map(module.krate); | ||
132 | let module_data = &def_map[module.local_id]; | ||
133 | for impl_def in module_data.scope.impls() { | ||
134 | self.collect_lang_item(db, impl_def, LangItemTarget::ImplDefId) | ||
135 | } | ||
136 | |||
137 | for def in module_data.scope.declarations() { | ||
138 | match def { | ||
139 | ModuleDefId::TraitId(trait_) => { | ||
140 | self.collect_lang_item(db, trait_, LangItemTarget::TraitId) | ||
141 | } | ||
142 | ModuleDefId::AdtId(AdtId::EnumId(e)) => { | ||
143 | self.collect_lang_item(db, e, LangItemTarget::EnumId) | ||
144 | } | ||
145 | ModuleDefId::AdtId(AdtId::StructId(s)) => { | ||
146 | self.collect_lang_item(db, s, LangItemTarget::StructId) | ||
147 | } | ||
148 | ModuleDefId::FunctionId(f) => { | ||
149 | self.collect_lang_item(db, f, LangItemTarget::FunctionId) | ||
150 | } | ||
151 | ModuleDefId::StaticId(s) => self.collect_lang_item(db, s, LangItemTarget::StaticId), | ||
152 | _ => {} | ||
153 | } | ||
154 | } | ||
155 | } | ||
156 | |||
157 | fn collect_lang_item<T>( | 136 | fn collect_lang_item<T>( |
158 | &mut self, | 137 | &mut self, |
159 | db: &dyn DefDatabase, | 138 | db: &dyn DefDatabase, |
diff --git a/crates/hir_def/src/lib.rs b/crates/hir_def/src/lib.rs index 7e2199a9c..ba09a9126 100644 --- a/crates/hir_def/src/lib.rs +++ b/crates/hir_def/src/lib.rs | |||
@@ -425,6 +425,16 @@ impl HasModule for AdtId { | |||
425 | } | 425 | } |
426 | } | 426 | } |
427 | 427 | ||
428 | impl HasModule for VariantId { | ||
429 | fn module(&self, db: &dyn db::DefDatabase) -> ModuleId { | ||
430 | match self { | ||
431 | VariantId::EnumVariantId(it) => it.parent.lookup(db).container.module(db), | ||
432 | VariantId::StructId(it) => it.lookup(db).container.module(db), | ||
433 | VariantId::UnionId(it) => it.lookup(db).container.module(db), | ||
434 | } | ||
435 | } | ||
436 | } | ||
437 | |||
428 | impl HasModule for DefWithBodyId { | 438 | impl HasModule for DefWithBodyId { |
429 | fn module(&self, db: &dyn db::DefDatabase) -> ModuleId { | 439 | fn module(&self, db: &dyn db::DefDatabase) -> ModuleId { |
430 | match self { | 440 | match self { |
@@ -465,6 +475,26 @@ impl HasModule for StaticLoc { | |||
465 | } | 475 | } |
466 | } | 476 | } |
467 | 477 | ||
478 | impl AttrDefId { | ||
479 | pub fn krate(&self, db: &dyn db::DefDatabase) -> CrateId { | ||
480 | match self { | ||
481 | AttrDefId::ModuleId(it) => it.krate, | ||
482 | AttrDefId::FieldId(it) => it.parent.module(db).krate, | ||
483 | AttrDefId::AdtId(it) => it.module(db).krate, | ||
484 | AttrDefId::FunctionId(it) => it.lookup(db).module(db).krate, | ||
485 | AttrDefId::EnumVariantId(it) => it.parent.lookup(db).container.module(db).krate, | ||
486 | AttrDefId::StaticId(it) => it.lookup(db).module(db).krate, | ||
487 | AttrDefId::ConstId(it) => it.lookup(db).module(db).krate, | ||
488 | AttrDefId::TraitId(it) => it.lookup(db).container.module(db).krate, | ||
489 | AttrDefId::TypeAliasId(it) => it.lookup(db).module(db).krate, | ||
490 | AttrDefId::ImplId(it) => it.lookup(db).container.module(db).krate, | ||
491 | // FIXME: `MacroDefId` should store the defining module, then this can implement | ||
492 | // `HasModule` | ||
493 | AttrDefId::MacroDefId(it) => it.krate, | ||
494 | } | ||
495 | } | ||
496 | } | ||
497 | |||
468 | /// A helper trait for converting to MacroCallId | 498 | /// A helper trait for converting to MacroCallId |
469 | pub trait AsMacroCall { | 499 | pub trait AsMacroCall { |
470 | fn as_call_id( | 500 | fn as_call_id( |
diff --git a/crates/hir_def/src/nameres/collector.rs b/crates/hir_def/src/nameres/collector.rs index 85cc342c4..b114a6fe4 100644 --- a/crates/hir_def/src/nameres/collector.rs +++ b/crates/hir_def/src/nameres/collector.rs | |||
@@ -26,7 +26,8 @@ use crate::{ | |||
26 | db::DefDatabase, | 26 | db::DefDatabase, |
27 | item_scope::{ImportType, PerNsGlobImports}, | 27 | item_scope::{ImportType, PerNsGlobImports}, |
28 | item_tree::{ | 28 | item_tree::{ |
29 | self, ItemTree, ItemTreeId, MacroCall, MacroRules, Mod, ModItem, ModKind, StructDefKind, | 29 | self, FileItemTreeId, ItemTree, ItemTreeId, MacroCall, MacroRules, Mod, ModItem, ModKind, |
30 | StructDefKind, | ||
30 | }, | 31 | }, |
31 | nameres::{ | 32 | nameres::{ |
32 | diagnostics::DefDiagnostic, mod_resolution::ModDir, path_resolution::ReachedFixedPoint, | 33 | diagnostics::DefDiagnostic, mod_resolution::ModDir, path_resolution::ReachedFixedPoint, |
@@ -220,17 +221,20 @@ impl DefCollector<'_> { | |||
220 | let item_tree = self.db.item_tree(file_id.into()); | 221 | let item_tree = self.db.item_tree(file_id.into()); |
221 | let module_id = self.def_map.root; | 222 | let module_id = self.def_map.root; |
222 | 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 }; |
223 | let mut root_collector = ModCollector { | 224 | if item_tree |
224 | def_collector: &mut *self, | 225 | .top_level_attrs(self.db, self.def_map.krate) |
225 | macro_depth: 0, | 226 | .cfg() |
226 | module_id, | 227 | .map_or(true, |cfg| self.cfg_options.check(&cfg) != Some(false)) |
227 | file_id: file_id.into(), | ||
228 | item_tree: &item_tree, | ||
229 | mod_dir: ModDir::root(), | ||
230 | }; | ||
231 | if item_tree.top_level_attrs().cfg().map_or(true, |cfg| root_collector.is_cfg_enabled(&cfg)) | ||
232 | { | 228 | { |
233 | 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()); | ||
234 | } | 238 | } |
235 | 239 | ||
236 | // main name resolution fixed-point loop. | 240 | // main name resolution fixed-point loop. |
@@ -309,13 +313,13 @@ impl DefCollector<'_> { | |||
309 | let macro_def = match self.proc_macros.iter().find(|(n, _)| n == name) { | 313 | let macro_def = match self.proc_macros.iter().find(|(n, _)| n == name) { |
310 | Some((_, expander)) => MacroDefId { | 314 | Some((_, expander)) => MacroDefId { |
311 | ast_id: None, | 315 | ast_id: None, |
312 | krate: Some(self.def_map.krate), | 316 | krate: self.def_map.krate, |
313 | kind: MacroDefKind::ProcMacro(*expander), | 317 | kind: MacroDefKind::ProcMacro(*expander), |
314 | local_inner: false, | 318 | local_inner: false, |
315 | }, | 319 | }, |
316 | None => MacroDefId { | 320 | None => MacroDefId { |
317 | ast_id: None, | 321 | ast_id: None, |
318 | krate: Some(self.def_map.krate), | 322 | krate: self.def_map.krate, |
319 | kind: MacroDefKind::ProcMacro(ProcMacroExpander::dummy(self.def_map.krate)), | 323 | kind: MacroDefKind::ProcMacro(ProcMacroExpander::dummy(self.def_map.krate)), |
320 | local_inner: false, | 324 | local_inner: false, |
321 | }, | 325 | }, |
@@ -784,14 +788,6 @@ impl DefCollector<'_> { | |||
784 | directive: &DeriveDirective, | 788 | directive: &DeriveDirective, |
785 | path: &ModPath, | 789 | path: &ModPath, |
786 | ) -> Option<MacroDefId> { | 790 | ) -> Option<MacroDefId> { |
787 | if let Some(name) = path.as_ident() { | ||
788 | // FIXME this should actually be handled with the normal name | ||
789 | // resolution; the std lib defines built-in stubs for the derives, | ||
790 | // but these are new-style `macro`s, which we don't support yet | ||
791 | if let Some(def_id) = find_builtin_derive(name) { | ||
792 | return Some(def_id); | ||
793 | } | ||
794 | } | ||
795 | let resolved_res = self.def_map.resolve_path_fp_with_macro( | 791 | let resolved_res = self.def_map.resolve_path_fp_with_macro( |
796 | self.db, | 792 | self.db, |
797 | ResolveMode::Other, | 793 | ResolveMode::Other, |
@@ -912,6 +908,8 @@ struct ModCollector<'a, 'b> { | |||
912 | 908 | ||
913 | impl ModCollector<'_, '_> { | 909 | impl ModCollector<'_, '_> { |
914 | fn collect(&mut self, items: &[ModItem]) { | 910 | fn collect(&mut self, items: &[ModItem]) { |
911 | let krate = self.def_collector.def_map.krate; | ||
912 | |||
915 | // 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 |
916 | // for macros. | 914 | // for macros. |
917 | 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()); |
@@ -928,7 +926,7 @@ impl ModCollector<'_, '_> { | |||
928 | // `#[macro_use] extern crate` is hoisted to imports macros before collecting | 926 | // `#[macro_use] extern crate` is hoisted to imports macros before collecting |
929 | // any other items. | 927 | // any other items. |
930 | for item in items { | 928 | for item in items { |
931 | let attrs = self.item_tree.attrs((*item).into()); | 929 | let attrs = self.item_tree.attrs(self.def_collector.db, krate, (*item).into()); |
932 | 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)) { |
933 | if let ModItem::ExternCrate(id) = item { | 931 | if let ModItem::ExternCrate(id) = item { |
934 | let import = self.item_tree[*id].clone(); | 932 | let import = self.item_tree[*id].clone(); |
@@ -940,7 +938,7 @@ impl ModCollector<'_, '_> { | |||
940 | } | 938 | } |
941 | 939 | ||
942 | for &item in items { | 940 | for &item in items { |
943 | let attrs = self.item_tree.attrs(item.into()); | 941 | let attrs = self.item_tree.attrs(self.def_collector.db, krate, item.into()); |
944 | if let Some(cfg) = attrs.cfg() { | 942 | if let Some(cfg) = attrs.cfg() { |
945 | if !self.is_cfg_enabled(&cfg) { | 943 | if !self.is_cfg_enabled(&cfg) { |
946 | self.emit_unconfigured_diagnostic(item, &cfg); | 944 | self.emit_unconfigured_diagnostic(item, &cfg); |
@@ -953,7 +951,7 @@ impl ModCollector<'_, '_> { | |||
953 | 951 | ||
954 | let mut def = None; | 952 | let mut def = None; |
955 | match item { | 953 | match item { |
956 | ModItem::Mod(m) => self.collect_module(&self.item_tree[m], attrs), | 954 | ModItem::Mod(m) => self.collect_module(&self.item_tree[m], &attrs), |
957 | ModItem::Import(import_id) => { | 955 | ModItem::Import(import_id) => { |
958 | self.def_collector.unresolved_imports.push(ImportDirective { | 956 | self.def_collector.unresolved_imports.push(ImportDirective { |
959 | module_id: self.module_id, | 957 | module_id: self.module_id, |
@@ -975,7 +973,41 @@ impl ModCollector<'_, '_> { | |||
975 | }) | 973 | }) |
976 | } | 974 | } |
977 | ModItem::MacroCall(mac) => self.collect_macro_call(&self.item_tree[mac]), | 975 | ModItem::MacroCall(mac) => self.collect_macro_call(&self.item_tree[mac]), |
978 | ModItem::MacroRules(mac) => self.collect_macro_rules(&self.item_tree[mac]), | 976 | ModItem::MacroRules(id) => self.collect_macro_rules(id), |
977 | ModItem::MacroDef(id) => { | ||
978 | let mac = &self.item_tree[id]; | ||
979 | let ast_id = InFile::new(self.file_id, mac.ast_id.upcast()); | ||
980 | |||
981 | // "Macro 2.0" is not currently supported by rust-analyzer, but libcore uses it | ||
982 | // to define builtin macros, so we support at least that part. | ||
983 | let attrs = self.item_tree.attrs( | ||
984 | self.def_collector.db, | ||
985 | krate, | ||
986 | ModItem::from(id).into(), | ||
987 | ); | ||
988 | if attrs.by_key("rustc_builtin_macro").exists() { | ||
989 | let krate = self.def_collector.def_map.krate; | ||
990 | let macro_id = find_builtin_macro(&mac.name, krate, ast_id) | ||
991 | .or_else(|| find_builtin_derive(&mac.name, krate, ast_id)); | ||
992 | if let Some(macro_id) = macro_id { | ||
993 | let vis = self | ||
994 | .def_collector | ||
995 | .def_map | ||
996 | .resolve_visibility( | ||
997 | self.def_collector.db, | ||
998 | self.module_id, | ||
999 | &self.item_tree[mac.visibility], | ||
1000 | ) | ||
1001 | .unwrap_or(Visibility::Public); | ||
1002 | self.def_collector.update( | ||
1003 | self.module_id, | ||
1004 | &[(Some(mac.name.clone()), PerNs::macros(macro_id, vis))], | ||
1005 | vis, | ||
1006 | ImportType::Named, | ||
1007 | ); | ||
1008 | } | ||
1009 | } | ||
1010 | } | ||
979 | ModItem::Impl(imp) => { | 1011 | ModItem::Impl(imp) => { |
980 | let module = ModuleId { | 1012 | let module = ModuleId { |
981 | krate: self.def_collector.def_map.krate, | 1013 | krate: self.def_collector.def_map.krate, |
@@ -989,7 +1021,7 @@ impl ModCollector<'_, '_> { | |||
989 | ModItem::Function(id) => { | 1021 | ModItem::Function(id) => { |
990 | let func = &self.item_tree[id]; | 1022 | let func = &self.item_tree[id]; |
991 | 1023 | ||
992 | self.collect_proc_macro_def(&func.name, attrs); | 1024 | self.collect_proc_macro_def(&func.name, &attrs); |
993 | 1025 | ||
994 | def = Some(DefData { | 1026 | def = Some(DefData { |
995 | id: FunctionLoc { | 1027 | id: FunctionLoc { |
@@ -1009,7 +1041,7 @@ impl ModCollector<'_, '_> { | |||
1009 | // 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; |
1010 | // 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 |
1011 | // macro invocation | 1043 | // macro invocation |
1012 | self.collect_derives(attrs, it.ast_id.upcast()); | 1044 | self.collect_derives(&attrs, it.ast_id.upcast()); |
1013 | 1045 | ||
1014 | def = Some(DefData { | 1046 | def = Some(DefData { |
1015 | id: StructLoc { container, id: ItemTreeId::new(self.file_id, id) } | 1047 | id: StructLoc { container, id: ItemTreeId::new(self.file_id, id) } |
@@ -1026,7 +1058,7 @@ impl ModCollector<'_, '_> { | |||
1026 | // 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; |
1027 | // 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 |
1028 | // macro invocation | 1060 | // macro invocation |
1029 | self.collect_derives(attrs, it.ast_id.upcast()); | 1061 | self.collect_derives(&attrs, it.ast_id.upcast()); |
1030 | 1062 | ||
1031 | def = Some(DefData { | 1063 | def = Some(DefData { |
1032 | id: UnionLoc { container, id: ItemTreeId::new(self.file_id, id) } | 1064 | id: UnionLoc { container, id: ItemTreeId::new(self.file_id, id) } |
@@ -1043,7 +1075,7 @@ impl ModCollector<'_, '_> { | |||
1043 | // 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; |
1044 | // 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 |
1045 | // macro invocation | 1077 | // macro invocation |
1046 | self.collect_derives(attrs, it.ast_id.upcast()); | 1078 | self.collect_derives(&attrs, it.ast_id.upcast()); |
1047 | 1079 | ||
1048 | def = Some(DefData { | 1080 | def = Some(DefData { |
1049 | id: EnumLoc { container, id: ItemTreeId::new(self.file_id, id) } | 1081 | id: EnumLoc { container, id: ItemTreeId::new(self.file_id, id) } |
@@ -1279,18 +1311,35 @@ impl ModCollector<'_, '_> { | |||
1279 | self.def_collector.resolve_proc_macro(¯o_name); | 1311 | self.def_collector.resolve_proc_macro(¯o_name); |
1280 | } | 1312 | } |
1281 | 1313 | ||
1282 | fn collect_macro_rules(&mut self, mac: &MacroRules) { | 1314 | fn collect_macro_rules(&mut self, id: FileItemTreeId<MacroRules>) { |
1283 | let ast_id = InFile::new(self.file_id, mac.ast_id); | 1315 | let krate = self.def_collector.def_map.krate; |
1316 | let mac = &self.item_tree[id]; | ||
1317 | let attrs = self.item_tree.attrs(self.def_collector.db, krate, ModItem::from(id).into()); | ||
1318 | let ast_id = InFile::new(self.file_id, mac.ast_id.upcast()); | ||
1319 | |||
1320 | let export_attr = attrs.by_key("macro_export"); | ||
1321 | |||
1322 | let is_export = export_attr.exists(); | ||
1323 | let is_local_inner = if is_export { | ||
1324 | export_attr.tt_values().map(|it| &it.token_trees).flatten().any(|it| match it { | ||
1325 | tt::TokenTree::Leaf(tt::Leaf::Ident(ident)) => { | ||
1326 | ident.text.contains("local_inner_macros") | ||
1327 | } | ||
1328 | _ => false, | ||
1329 | }) | ||
1330 | } else { | ||
1331 | false | ||
1332 | }; | ||
1284 | 1333 | ||
1285 | // Case 1: builtin macros | 1334 | // Case 1: builtin macros |
1286 | if mac.is_builtin { | 1335 | if attrs.by_key("rustc_builtin_macro").exists() { |
1287 | let krate = self.def_collector.def_map.krate; | 1336 | let krate = self.def_collector.def_map.krate; |
1288 | if let Some(macro_id) = find_builtin_macro(&mac.name, krate, ast_id) { | 1337 | if let Some(macro_id) = find_builtin_macro(&mac.name, krate, ast_id) { |
1289 | self.def_collector.define_macro( | 1338 | self.def_collector.define_macro( |
1290 | self.module_id, | 1339 | self.module_id, |
1291 | mac.name.clone(), | 1340 | mac.name.clone(), |
1292 | macro_id, | 1341 | macro_id, |
1293 | mac.is_export, | 1342 | is_export, |
1294 | ); | 1343 | ); |
1295 | return; | 1344 | return; |
1296 | } | 1345 | } |
@@ -1299,11 +1348,11 @@ impl ModCollector<'_, '_> { | |||
1299 | // Case 2: normal `macro_rules!` macro | 1348 | // Case 2: normal `macro_rules!` macro |
1300 | let macro_id = MacroDefId { | 1349 | let macro_id = MacroDefId { |
1301 | ast_id: Some(ast_id), | 1350 | ast_id: Some(ast_id), |
1302 | krate: Some(self.def_collector.def_map.krate), | 1351 | krate: self.def_collector.def_map.krate, |
1303 | kind: MacroDefKind::Declarative, | 1352 | kind: MacroDefKind::Declarative, |
1304 | local_inner: mac.is_local_inner, | 1353 | local_inner: is_local_inner, |
1305 | }; | 1354 | }; |
1306 | self.def_collector.define_macro(self.module_id, mac.name.clone(), macro_id, mac.is_export); | 1355 | self.def_collector.define_macro(self.module_id, mac.name.clone(), macro_id, is_export); |
1307 | } | 1356 | } |
1308 | 1357 | ||
1309 | fn collect_macro_call(&mut self, mac: &MacroCall) { | 1358 | fn collect_macro_call(&mut self, mac: &MacroCall) { |
diff --git a/crates/hir_def/src/nameres/tests/macros.rs b/crates/hir_def/src/nameres/tests/macros.rs index 305fca0f9..6fe2ee78a 100644 --- a/crates/hir_def/src/nameres/tests/macros.rs +++ b/crates/hir_def/src/nameres/tests/macros.rs | |||
@@ -633,15 +633,44 @@ pub struct bar; | |||
633 | fn expand_derive() { | 633 | fn expand_derive() { |
634 | let map = compute_crate_def_map( | 634 | let map = compute_crate_def_map( |
635 | " | 635 | " |
636 | //- /main.rs | 636 | //- /main.rs crate:main deps:core |
637 | use core::*; | ||
638 | |||
637 | #[derive(Copy, Clone)] | 639 | #[derive(Copy, Clone)] |
638 | struct Foo; | 640 | struct Foo; |
641 | |||
642 | //- /core.rs crate:core | ||
643 | #[rustc_builtin_macro] | ||
644 | pub macro Copy {} | ||
645 | |||
646 | #[rustc_builtin_macro] | ||
647 | pub macro Clone {} | ||
639 | ", | 648 | ", |
640 | ); | 649 | ); |
641 | assert_eq!(map.modules[map.root].scope.impls().len(), 2); | 650 | assert_eq!(map.modules[map.root].scope.impls().len(), 2); |
642 | } | 651 | } |
643 | 652 | ||
644 | #[test] | 653 | #[test] |
654 | fn resolve_builtin_derive() { | ||
655 | check( | ||
656 | r#" | ||
657 | //- /main.rs crate:main deps:core | ||
658 | use core::*; | ||
659 | |||
660 | //- /core.rs crate:core | ||
661 | #[rustc_builtin_macro] | ||
662 | pub macro Clone {} | ||
663 | |||
664 | pub trait Clone {} | ||
665 | "#, | ||
666 | expect![[r#" | ||
667 | crate | ||
668 | Clone: t m | ||
669 | "#]], | ||
670 | ); | ||
671 | } | ||
672 | |||
673 | #[test] | ||
645 | fn macro_expansion_overflow() { | 674 | fn macro_expansion_overflow() { |
646 | mark::check!(macro_expansion_overflow); | 675 | mark::check!(macro_expansion_overflow); |
647 | check( | 676 | check( |
diff --git a/crates/hir_def/src/path/lower.rs b/crates/hir_def/src/path/lower.rs index 609925012..8a01e6eea 100644 --- a/crates/hir_def/src/path/lower.rs +++ b/crates/hir_def/src/path/lower.rs | |||
@@ -169,8 +169,8 @@ pub(super) fn lower_generic_args( | |||
169 | } | 169 | } |
170 | } | 170 | } |
171 | ast::GenericArg::LifetimeArg(lifetime_arg) => { | 171 | ast::GenericArg::LifetimeArg(lifetime_arg) => { |
172 | if let Some(lifetime) = lifetime_arg.lifetime_token() { | 172 | if let Some(lifetime) = lifetime_arg.lifetime() { |
173 | let lifetime_ref = LifetimeRef::from_token(lifetime); | 173 | let lifetime_ref = LifetimeRef::new(&lifetime); |
174 | args.push(GenericArg::Lifetime(lifetime_ref)) | 174 | args.push(GenericArg::Lifetime(lifetime_ref)) |
175 | } | 175 | } |
176 | } | 176 | } |
diff --git a/crates/hir_def/src/type_ref.rs b/crates/hir_def/src/type_ref.rs index 347ceabb9..ae93d0d10 100644 --- a/crates/hir_def/src/type_ref.rs +++ b/crates/hir_def/src/type_ref.rs | |||
@@ -1,7 +1,7 @@ | |||
1 | //! HIR for references to types. Paths in these are not yet resolved. They can | 1 | //! HIR for references to types. Paths in these are not yet resolved. They can |
2 | //! be directly created from an ast::TypeRef, without further queries. | 2 | //! be directly created from an ast::TypeRef, without further queries. |
3 | use hir_expand::name::Name; | 3 | use hir_expand::name::Name; |
4 | use syntax::{ast, SyntaxToken}; | 4 | use syntax::ast; |
5 | 5 | ||
6 | use crate::{body::LowerCtx, path::Path}; | 6 | use crate::{body::LowerCtx, path::Path}; |
7 | 7 | ||
@@ -80,8 +80,8 @@ impl LifetimeRef { | |||
80 | LifetimeRef { name } | 80 | LifetimeRef { name } |
81 | } | 81 | } |
82 | 82 | ||
83 | pub(crate) fn from_token(token: SyntaxToken) -> Self { | 83 | pub(crate) fn new(lifetime: &ast::Lifetime) -> Self { |
84 | LifetimeRef { name: Name::new_lifetime(&token) } | 84 | LifetimeRef { name: Name::new_lifetime(lifetime) } |
85 | } | 85 | } |
86 | 86 | ||
87 | pub fn missing() -> LifetimeRef { | 87 | pub fn missing() -> LifetimeRef { |
@@ -127,7 +127,7 @@ impl TypeRef { | |||
127 | } | 127 | } |
128 | ast::Type::RefType(inner) => { | 128 | ast::Type::RefType(inner) => { |
129 | let inner_ty = TypeRef::from_ast_opt(&ctx, inner.ty()); | 129 | let inner_ty = TypeRef::from_ast_opt(&ctx, inner.ty()); |
130 | let lifetime = inner.lifetime_token().map(|t| LifetimeRef::from_token(t)); | 130 | let lifetime = inner.lifetime().map(|lt| LifetimeRef::new(<)); |
131 | let mutability = Mutability::from_mutable(inner.mut_token().is_some()); | 131 | let mutability = Mutability::from_mutable(inner.mut_token().is_some()); |
132 | TypeRef::Reference(Box::new(inner_ty), lifetime, mutability) | 132 | TypeRef::Reference(Box::new(inner_ty), lifetime, mutability) |
133 | } | 133 | } |
@@ -259,7 +259,7 @@ impl TypeBound { | |||
259 | } | 259 | } |
260 | ast::TypeBoundKind::ForType(_) => TypeBound::Error, // FIXME ForType | 260 | ast::TypeBoundKind::ForType(_) => TypeBound::Error, // FIXME ForType |
261 | ast::TypeBoundKind::Lifetime(lifetime) => { | 261 | ast::TypeBoundKind::Lifetime(lifetime) => { |
262 | TypeBound::Lifetime(LifetimeRef::from_token(lifetime)) | 262 | TypeBound::Lifetime(LifetimeRef::new(&lifetime)) |
263 | } | 263 | } |
264 | } | 264 | } |
265 | } | 265 | } |