diff options
Diffstat (limited to 'crates')
-rw-r--r-- | crates/hir/src/lib.rs | 1 | ||||
-rw-r--r-- | crates/hir_def/src/nameres/collector.rs | 4 | ||||
-rw-r--r-- | crates/hir_expand/src/builtin_attr.rs | 67 | ||||
-rw-r--r-- | crates/hir_expand/src/db.rs | 14 | ||||
-rw-r--r-- | crates/hir_expand/src/eager.rs | 1 | ||||
-rw-r--r-- | crates/hir_expand/src/hygiene.rs | 1 | ||||
-rw-r--r-- | crates/hir_expand/src/lib.rs | 4 | ||||
-rw-r--r-- | crates/hir_expand/src/name.rs | 9 | ||||
-rw-r--r-- | crates/ide_completion/src/completions/qualified_path.rs | 26 | ||||
-rw-r--r-- | crates/ide_completion/src/completions/unqualified_path.rs | 12 |
10 files changed, 128 insertions, 11 deletions
diff --git a/crates/hir/src/lib.rs b/crates/hir/src/lib.rs index dba46df04..debc3ee62 100644 --- a/crates/hir/src/lib.rs +++ b/crates/hir/src/lib.rs | |||
@@ -1344,6 +1344,7 @@ impl MacroDef { | |||
1344 | MacroDefKind::Declarative(_) => MacroKind::Declarative, | 1344 | MacroDefKind::Declarative(_) => MacroKind::Declarative, |
1345 | MacroDefKind::BuiltIn(_, _) | MacroDefKind::BuiltInEager(_, _) => MacroKind::BuiltIn, | 1345 | MacroDefKind::BuiltIn(_, _) | MacroDefKind::BuiltInEager(_, _) => MacroKind::BuiltIn, |
1346 | MacroDefKind::BuiltInDerive(_, _) => MacroKind::Derive, | 1346 | MacroDefKind::BuiltInDerive(_, _) => MacroKind::Derive, |
1347 | MacroDefKind::BuiltInAttr(_, _) => MacroKind::Attr, | ||
1347 | MacroDefKind::ProcMacro(_, base_db::ProcMacroKind::CustomDerive, _) => { | 1348 | MacroDefKind::ProcMacro(_, base_db::ProcMacroKind::CustomDerive, _) => { |
1348 | MacroKind::Derive | 1349 | MacroKind::Derive |
1349 | } | 1350 | } |
diff --git a/crates/hir_def/src/nameres/collector.rs b/crates/hir_def/src/nameres/collector.rs index d019ba3a9..93f30f23d 100644 --- a/crates/hir_def/src/nameres/collector.rs +++ b/crates/hir_def/src/nameres/collector.rs | |||
@@ -9,6 +9,7 @@ use base_db::{CrateId, Edition, FileId, ProcMacroId}; | |||
9 | use cfg::{CfgExpr, CfgOptions}; | 9 | use cfg::{CfgExpr, CfgOptions}; |
10 | use hir_expand::{ | 10 | use hir_expand::{ |
11 | ast_id_map::FileAstId, | 11 | ast_id_map::FileAstId, |
12 | builtin_attr::find_builtin_attr, | ||
12 | builtin_derive::find_builtin_derive, | 13 | builtin_derive::find_builtin_derive, |
13 | builtin_macro::find_builtin_macro, | 14 | builtin_macro::find_builtin_macro, |
14 | name::{name, AsName, Name}, | 15 | name::{name, AsName, Name}, |
@@ -1836,7 +1837,8 @@ impl ModCollector<'_, '_> { | |||
1836 | let attrs = self.item_tree.attrs(self.def_collector.db, krate, ModItem::from(id).into()); | 1837 | let attrs = self.item_tree.attrs(self.def_collector.db, krate, ModItem::from(id).into()); |
1837 | if attrs.by_key("rustc_builtin_macro").exists() { | 1838 | if attrs.by_key("rustc_builtin_macro").exists() { |
1838 | let macro_id = find_builtin_macro(&mac.name, krate, ast_id) | 1839 | let macro_id = find_builtin_macro(&mac.name, krate, ast_id) |
1839 | .or_else(|| find_builtin_derive(&mac.name, krate, ast_id)); | 1840 | .or_else(|| find_builtin_derive(&mac.name, krate, ast_id)) |
1841 | .or_else(|| find_builtin_attr(&mac.name, krate, ast_id)); | ||
1840 | 1842 | ||
1841 | match macro_id { | 1843 | match macro_id { |
1842 | Some(macro_id) => { | 1844 | Some(macro_id) => { |
diff --git a/crates/hir_expand/src/builtin_attr.rs b/crates/hir_expand/src/builtin_attr.rs new file mode 100644 index 000000000..c8432005e --- /dev/null +++ b/crates/hir_expand/src/builtin_attr.rs | |||
@@ -0,0 +1,67 @@ | |||
1 | //! Builtin derives. | ||
2 | |||
3 | use syntax::ast; | ||
4 | |||
5 | use crate::{db::AstDatabase, name, AstId, CrateId, MacroCallId, MacroDefId, MacroDefKind}; | ||
6 | |||
7 | macro_rules! register_builtin { | ||
8 | ( $(($name:ident, $variant:ident) => $expand:ident),* ) => { | ||
9 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] | ||
10 | pub enum BuiltinAttrExpander { | ||
11 | $($variant),* | ||
12 | } | ||
13 | |||
14 | impl BuiltinAttrExpander { | ||
15 | pub fn expand( | ||
16 | &self, | ||
17 | db: &dyn AstDatabase, | ||
18 | id: MacroCallId, | ||
19 | tt: &tt::Subtree, | ||
20 | ) -> Result<tt::Subtree, mbe::ExpandError> { | ||
21 | let expander = match *self { | ||
22 | $( BuiltinAttrExpander::$variant => $expand, )* | ||
23 | }; | ||
24 | expander(db, id, tt) | ||
25 | } | ||
26 | |||
27 | fn find_by_name(name: &name::Name) -> Option<Self> { | ||
28 | match name { | ||
29 | $( id if id == &name::name![$name] => Some(BuiltinAttrExpander::$variant), )* | ||
30 | _ => None, | ||
31 | } | ||
32 | } | ||
33 | } | ||
34 | |||
35 | }; | ||
36 | } | ||
37 | |||
38 | register_builtin! { | ||
39 | (bench, Bench) => dummy_attr_expand, | ||
40 | (cfg_accessible, CfgAccessible) => dummy_attr_expand, | ||
41 | (cfg_eval, CfgEval) => dummy_attr_expand, | ||
42 | (derive, Derive) => dummy_attr_expand, | ||
43 | (global_allocator, GlobalAllocator) => dummy_attr_expand, | ||
44 | (test, Test) => dummy_attr_expand, | ||
45 | (test_case, TestCase) => dummy_attr_expand | ||
46 | } | ||
47 | |||
48 | pub fn find_builtin_attr( | ||
49 | ident: &name::Name, | ||
50 | krate: CrateId, | ||
51 | ast_id: AstId<ast::Macro>, | ||
52 | ) -> Option<MacroDefId> { | ||
53 | let expander = BuiltinAttrExpander::find_by_name(ident)?; | ||
54 | Some(MacroDefId { | ||
55 | krate, | ||
56 | kind: MacroDefKind::BuiltInAttr(expander, ast_id), | ||
57 | local_inner: false, | ||
58 | }) | ||
59 | } | ||
60 | |||
61 | fn dummy_attr_expand( | ||
62 | _db: &dyn AstDatabase, | ||
63 | _id: MacroCallId, | ||
64 | tt: &tt::Subtree, | ||
65 | ) -> Result<tt::Subtree, mbe::ExpandError> { | ||
66 | Ok(tt.clone()) | ||
67 | } | ||
diff --git a/crates/hir_expand/src/db.rs b/crates/hir_expand/src/db.rs index 18a05579f..45e6e446a 100644 --- a/crates/hir_expand/src/db.rs +++ b/crates/hir_expand/src/db.rs | |||
@@ -12,9 +12,9 @@ use syntax::{ | |||
12 | }; | 12 | }; |
13 | 13 | ||
14 | use crate::{ | 14 | use crate::{ |
15 | ast_id_map::AstIdMap, hygiene::HygieneFrame, input::process_macro_input, BuiltinDeriveExpander, | 15 | ast_id_map::AstIdMap, hygiene::HygieneFrame, input::process_macro_input, BuiltinAttrExpander, |
16 | BuiltinFnLikeExpander, HirFileId, HirFileIdRepr, MacroCallId, MacroCallKind, MacroCallLoc, | 16 | BuiltinDeriveExpander, BuiltinFnLikeExpander, HirFileId, HirFileIdRepr, MacroCallId, |
17 | MacroDefId, MacroDefKind, MacroFile, ProcMacroExpander, | 17 | MacroCallKind, MacroCallLoc, MacroDefId, MacroDefKind, MacroFile, ProcMacroExpander, |
18 | }; | 18 | }; |
19 | 19 | ||
20 | /// Total limit on the number of tokens produced by any macro invocation. | 20 | /// Total limit on the number of tokens produced by any macro invocation. |
@@ -31,6 +31,8 @@ pub enum TokenExpander { | |||
31 | MacroDef { mac: mbe::MacroDef, def_site_token_map: mbe::TokenMap }, | 31 | MacroDef { mac: mbe::MacroDef, def_site_token_map: mbe::TokenMap }, |
32 | /// Stuff like `line!` and `file!`. | 32 | /// Stuff like `line!` and `file!`. |
33 | Builtin(BuiltinFnLikeExpander), | 33 | Builtin(BuiltinFnLikeExpander), |
34 | /// `global_allocator` and such. | ||
35 | BuiltinAttr(BuiltinAttrExpander), | ||
34 | /// `derive(Copy)` and such. | 36 | /// `derive(Copy)` and such. |
35 | BuiltinDerive(BuiltinDeriveExpander), | 37 | BuiltinDerive(BuiltinDeriveExpander), |
36 | /// The thing we love the most here in rust-analyzer -- procedural macros. | 38 | /// The thing we love the most here in rust-analyzer -- procedural macros. |
@@ -49,6 +51,7 @@ impl TokenExpander { | |||
49 | TokenExpander::MacroDef { mac, .. } => mac.expand(tt), | 51 | TokenExpander::MacroDef { mac, .. } => mac.expand(tt), |
50 | TokenExpander::Builtin(it) => it.expand(db, id, tt), | 52 | TokenExpander::Builtin(it) => it.expand(db, id, tt), |
51 | // FIXME switch these to ExpandResult as well | 53 | // FIXME switch these to ExpandResult as well |
54 | TokenExpander::BuiltinAttr(it) => it.expand(db, id, tt).into(), | ||
52 | TokenExpander::BuiltinDerive(it) => it.expand(db, id, tt).into(), | 55 | TokenExpander::BuiltinDerive(it) => it.expand(db, id, tt).into(), |
53 | TokenExpander::ProcMacro(_) => { | 56 | TokenExpander::ProcMacro(_) => { |
54 | // We store the result in salsa db to prevent non-deterministic behavior in | 57 | // We store the result in salsa db to prevent non-deterministic behavior in |
@@ -64,6 +67,7 @@ impl TokenExpander { | |||
64 | TokenExpander::MacroRules { mac, .. } => mac.map_id_down(id), | 67 | TokenExpander::MacroRules { mac, .. } => mac.map_id_down(id), |
65 | TokenExpander::MacroDef { mac, .. } => mac.map_id_down(id), | 68 | TokenExpander::MacroDef { mac, .. } => mac.map_id_down(id), |
66 | TokenExpander::Builtin(..) | 69 | TokenExpander::Builtin(..) |
70 | | TokenExpander::BuiltinAttr(..) | ||
67 | | TokenExpander::BuiltinDerive(..) | 71 | | TokenExpander::BuiltinDerive(..) |
68 | | TokenExpander::ProcMacro(..) => id, | 72 | | TokenExpander::ProcMacro(..) => id, |
69 | } | 73 | } |
@@ -74,6 +78,7 @@ impl TokenExpander { | |||
74 | TokenExpander::MacroRules { mac, .. } => mac.map_id_up(id), | 78 | TokenExpander::MacroRules { mac, .. } => mac.map_id_up(id), |
75 | TokenExpander::MacroDef { mac, .. } => mac.map_id_up(id), | 79 | TokenExpander::MacroDef { mac, .. } => mac.map_id_up(id), |
76 | TokenExpander::Builtin(..) | 80 | TokenExpander::Builtin(..) |
81 | | TokenExpander::BuiltinAttr(..) | ||
77 | | TokenExpander::BuiltinDerive(..) | 82 | | TokenExpander::BuiltinDerive(..) |
78 | | TokenExpander::ProcMacro(..) => (id, mbe::Origin::Call), | 83 | | TokenExpander::ProcMacro(..) => (id, mbe::Origin::Call), |
79 | } | 84 | } |
@@ -299,6 +304,9 @@ fn macro_def(db: &dyn AstDatabase, id: MacroDefId) -> Option<Arc<TokenExpander>> | |||
299 | } | 304 | } |
300 | }, | 305 | }, |
301 | MacroDefKind::BuiltIn(expander, _) => Some(Arc::new(TokenExpander::Builtin(expander))), | 306 | MacroDefKind::BuiltIn(expander, _) => Some(Arc::new(TokenExpander::Builtin(expander))), |
307 | MacroDefKind::BuiltInAttr(expander, _) => { | ||
308 | Some(Arc::new(TokenExpander::BuiltinAttr(expander))) | ||
309 | } | ||
302 | MacroDefKind::BuiltInDerive(expander, _) => { | 310 | MacroDefKind::BuiltInDerive(expander, _) => { |
303 | Some(Arc::new(TokenExpander::BuiltinDerive(expander))) | 311 | Some(Arc::new(TokenExpander::BuiltinDerive(expander))) |
304 | } | 312 | } |
diff --git a/crates/hir_expand/src/eager.rs b/crates/hir_expand/src/eager.rs index 14af628a1..9093255f4 100644 --- a/crates/hir_expand/src/eager.rs +++ b/crates/hir_expand/src/eager.rs | |||
@@ -224,6 +224,7 @@ fn eager_macro_recur( | |||
224 | } | 224 | } |
225 | MacroDefKind::Declarative(_) | 225 | MacroDefKind::Declarative(_) |
226 | | MacroDefKind::BuiltIn(..) | 226 | | MacroDefKind::BuiltIn(..) |
227 | | MacroDefKind::BuiltInAttr(..) | ||
227 | | MacroDefKind::BuiltInDerive(..) | 228 | | MacroDefKind::BuiltInDerive(..) |
228 | | MacroDefKind::ProcMacro(..) => { | 229 | | MacroDefKind::ProcMacro(..) => { |
229 | let res = lazy_expand(db, &def, curr.with_value(child.clone()), krate); | 230 | let res = lazy_expand(db, &def, curr.with_value(child.clone()), krate); |
diff --git a/crates/hir_expand/src/hygiene.rs b/crates/hir_expand/src/hygiene.rs index d98913907..05c6c3fb1 100644 --- a/crates/hir_expand/src/hygiene.rs +++ b/crates/hir_expand/src/hygiene.rs | |||
@@ -192,6 +192,7 @@ impl HygieneFrame { | |||
192 | (info, Some(loc.def.krate), loc.def.local_inner) | 192 | (info, Some(loc.def.krate), loc.def.local_inner) |
193 | } | 193 | } |
194 | MacroDefKind::BuiltIn(..) => (info, Some(loc.def.krate), false), | 194 | MacroDefKind::BuiltIn(..) => (info, Some(loc.def.krate), false), |
195 | MacroDefKind::BuiltInAttr(..) => (info, None, false), | ||
195 | MacroDefKind::BuiltInDerive(..) => (info, None, false), | 196 | MacroDefKind::BuiltInDerive(..) => (info, None, false), |
196 | MacroDefKind::BuiltInEager(..) => (info, None, false), | 197 | MacroDefKind::BuiltInEager(..) => (info, None, false), |
197 | MacroDefKind::ProcMacro(..) => (info, None, false), | 198 | MacroDefKind::ProcMacro(..) => (info, None, false), |
diff --git a/crates/hir_expand/src/lib.rs b/crates/hir_expand/src/lib.rs index 618f26b95..623791b58 100644 --- a/crates/hir_expand/src/lib.rs +++ b/crates/hir_expand/src/lib.rs | |||
@@ -8,6 +8,7 @@ pub mod db; | |||
8 | pub mod ast_id_map; | 8 | pub mod ast_id_map; |
9 | pub mod name; | 9 | pub mod name; |
10 | pub mod hygiene; | 10 | pub mod hygiene; |
11 | pub mod builtin_attr; | ||
11 | pub mod builtin_derive; | 12 | pub mod builtin_derive; |
12 | pub mod builtin_macro; | 13 | pub mod builtin_macro; |
13 | pub mod proc_macro; | 14 | pub mod proc_macro; |
@@ -32,6 +33,7 @@ use syntax::{ | |||
32 | }; | 33 | }; |
33 | 34 | ||
34 | use crate::ast_id_map::FileAstId; | 35 | use crate::ast_id_map::FileAstId; |
36 | use crate::builtin_attr::BuiltinAttrExpander; | ||
35 | use crate::builtin_derive::BuiltinDeriveExpander; | 37 | use crate::builtin_derive::BuiltinDeriveExpander; |
36 | use crate::builtin_macro::{BuiltinFnLikeExpander, EagerExpander}; | 38 | use crate::builtin_macro::{BuiltinFnLikeExpander, EagerExpander}; |
37 | use crate::proc_macro::ProcMacroExpander; | 39 | use crate::proc_macro::ProcMacroExpander; |
@@ -206,6 +208,7 @@ impl MacroDefId { | |||
206 | let id = match &self.kind { | 208 | let id = match &self.kind { |
207 | MacroDefKind::Declarative(id) => id, | 209 | MacroDefKind::Declarative(id) => id, |
208 | MacroDefKind::BuiltIn(_, id) => id, | 210 | MacroDefKind::BuiltIn(_, id) => id, |
211 | MacroDefKind::BuiltInAttr(_, id) => id, | ||
209 | MacroDefKind::BuiltInDerive(_, id) => id, | 212 | MacroDefKind::BuiltInDerive(_, id) => id, |
210 | MacroDefKind::BuiltInEager(_, id) => id, | 213 | MacroDefKind::BuiltInEager(_, id) => id, |
211 | MacroDefKind::ProcMacro(.., id) => return Either::Right(*id), | 214 | MacroDefKind::ProcMacro(.., id) => return Either::Right(*id), |
@@ -223,6 +226,7 @@ pub enum MacroDefKind { | |||
223 | Declarative(AstId<ast::Macro>), | 226 | Declarative(AstId<ast::Macro>), |
224 | BuiltIn(BuiltinFnLikeExpander, AstId<ast::Macro>), | 227 | BuiltIn(BuiltinFnLikeExpander, AstId<ast::Macro>), |
225 | // FIXME: maybe just Builtin and rename BuiltinFnLikeExpander to BuiltinExpander | 228 | // FIXME: maybe just Builtin and rename BuiltinFnLikeExpander to BuiltinExpander |
229 | BuiltInAttr(BuiltinAttrExpander, AstId<ast::Macro>), | ||
226 | BuiltInDerive(BuiltinDeriveExpander, AstId<ast::Macro>), | 230 | BuiltInDerive(BuiltinDeriveExpander, AstId<ast::Macro>), |
227 | BuiltInEager(EagerExpander, AstId<ast::Macro>), | 231 | BuiltInEager(EagerExpander, AstId<ast::Macro>), |
228 | ProcMacro(ProcMacroExpander, ProcMacroKind, AstId<ast::Fn>), | 232 | ProcMacro(ProcMacroExpander, ProcMacroKind, AstId<ast::Fn>), |
diff --git a/crates/hir_expand/src/name.rs b/crates/hir_expand/src/name.rs index 00b8adc1e..376fe130f 100644 --- a/crates/hir_expand/src/name.rs +++ b/crates/hir_expand/src/name.rs | |||
@@ -160,7 +160,6 @@ pub mod known { | |||
160 | str, | 160 | str, |
161 | // Special names | 161 | // Special names |
162 | macro_rules, | 162 | macro_rules, |
163 | derive, | ||
164 | doc, | 163 | doc, |
165 | cfg, | 164 | cfg, |
166 | cfg_attr, | 165 | cfg_attr, |
@@ -240,6 +239,14 @@ pub mod known { | |||
240 | PartialOrd, | 239 | PartialOrd, |
241 | Eq, | 240 | Eq, |
242 | PartialEq, | 241 | PartialEq, |
242 | // Builtin attributes | ||
243 | bench, | ||
244 | cfg_accessible, | ||
245 | cfg_eval, | ||
246 | derive, | ||
247 | global_allocator, | ||
248 | test, | ||
249 | test_case, | ||
243 | // Safe intrinsics | 250 | // Safe intrinsics |
244 | abort, | 251 | abort, |
245 | size_of, | 252 | size_of, |
diff --git a/crates/ide_completion/src/completions/qualified_path.rs b/crates/ide_completion/src/completions/qualified_path.rs index 0b0a81410..58d4dd9ee 100644 --- a/crates/ide_completion/src/completions/qualified_path.rs +++ b/crates/ide_completion/src/completions/qualified_path.rs | |||
@@ -657,6 +657,32 @@ fn main() { let _ = crate::$0 } | |||
657 | } | 657 | } |
658 | 658 | ||
659 | #[test] | 659 | #[test] |
660 | fn does_not_complete_non_fn_macros() { | ||
661 | check( | ||
662 | r#" | ||
663 | mod m { | ||
664 | #[rustc_builtin_macro] | ||
665 | pub macro Clone {} | ||
666 | } | ||
667 | |||
668 | fn f() {m::$0} | ||
669 | "#, | ||
670 | expect![[r#""#]], | ||
671 | ); | ||
672 | check( | ||
673 | r#" | ||
674 | mod m { | ||
675 | #[rustc_builtin_macro] | ||
676 | pub macro bench {} | ||
677 | } | ||
678 | |||
679 | fn f() {m::$0} | ||
680 | "#, | ||
681 | expect![[r#""#]], | ||
682 | ); | ||
683 | } | ||
684 | |||
685 | #[test] | ||
660 | fn completes_in_assoc_item_list() { | 686 | fn completes_in_assoc_item_list() { |
661 | check( | 687 | check( |
662 | r#" | 688 | r#" |
diff --git a/crates/ide_completion/src/completions/unqualified_path.rs b/crates/ide_completion/src/completions/unqualified_path.rs index 1f6c4069f..b1e6b2b77 100644 --- a/crates/ide_completion/src/completions/unqualified_path.rs +++ b/crates/ide_completion/src/completions/unqualified_path.rs | |||
@@ -481,14 +481,14 @@ impl S { | |||
481 | ); | 481 | ); |
482 | check( | 482 | check( |
483 | r#" | 483 | r#" |
484 | mod m { | 484 | #[rustc_builtin_macro] |
485 | #[rustc_builtin_macro] | 485 | pub macro bench {} |
486 | pub macro Clone {} | ||
487 | } | ||
488 | 486 | ||
489 | fn f() {m::$0} | 487 | fn f() {$0} |
490 | "#, | 488 | "#, |
491 | expect![[r#""#]], | 489 | expect![[r#" |
490 | fn f() fn() | ||
491 | "#]], | ||
492 | ); | 492 | ); |
493 | } | 493 | } |
494 | 494 | ||