diff options
-rw-r--r-- | crates/ra_hir/src/semantics/source_to_def.rs | 2 | ||||
-rw-r--r-- | crates/ra_hir_def/src/body/lower.rs | 1 | ||||
-rw-r--r-- | crates/ra_hir_def/src/nameres/collector.rs | 2 | ||||
-rw-r--r-- | crates/ra_hir_def/src/nameres/raw.rs | 27 | ||||
-rw-r--r-- | crates/ra_hir_def/src/path/lower.rs | 19 | ||||
-rw-r--r-- | crates/ra_hir_expand/src/builtin_derive.rs | 2 | ||||
-rw-r--r-- | crates/ra_hir_expand/src/builtin_macro.rs | 4 | ||||
-rw-r--r-- | crates/ra_hir_expand/src/hygiene.rs | 31 | ||||
-rw-r--r-- | crates/ra_hir_expand/src/lib.rs | 2 | ||||
-rw-r--r-- | crates/ra_hir_ty/src/tests/macros.rs | 26 |
10 files changed, 97 insertions, 19 deletions
diff --git a/crates/ra_hir/src/semantics/source_to_def.rs b/crates/ra_hir/src/semantics/source_to_def.rs index 6f3b5b2da..8af64fdc1 100644 --- a/crates/ra_hir/src/semantics/source_to_def.rs +++ b/crates/ra_hir/src/semantics/source_to_def.rs | |||
@@ -151,7 +151,7 @@ impl SourceToDefCtx<'_, '_> { | |||
151 | let krate = self.file_to_def(file_id)?.krate; | 151 | let krate = self.file_to_def(file_id)?.krate; |
152 | let file_ast_id = self.db.ast_id_map(src.file_id).ast_id(&src.value); | 152 | let file_ast_id = self.db.ast_id_map(src.file_id).ast_id(&src.value); |
153 | let ast_id = Some(AstId::new(src.file_id, file_ast_id)); | 153 | let ast_id = Some(AstId::new(src.file_id, file_ast_id)); |
154 | Some(MacroDefId { krate: Some(krate), ast_id, kind }) | 154 | Some(MacroDefId { krate: Some(krate), ast_id, kind, local_inner: false }) |
155 | } | 155 | } |
156 | 156 | ||
157 | pub(super) fn find_container(&mut self, src: InFile<&SyntaxNode>) -> Option<ChildContainer> { | 157 | pub(super) fn find_container(&mut self, src: InFile<&SyntaxNode>) -> Option<ChildContainer> { |
diff --git a/crates/ra_hir_def/src/body/lower.rs b/crates/ra_hir_def/src/body/lower.rs index f467ed3fe..8c1aefbf5 100644 --- a/crates/ra_hir_def/src/body/lower.rs +++ b/crates/ra_hir_def/src/body/lower.rs | |||
@@ -430,6 +430,7 @@ impl ExprCollector<'_> { | |||
430 | krate: Some(self.expander.module.krate), | 430 | krate: Some(self.expander.module.krate), |
431 | ast_id: Some(self.expander.ast_id(&e)), | 431 | ast_id: Some(self.expander.ast_id(&e)), |
432 | kind: MacroDefKind::Declarative, | 432 | kind: MacroDefKind::Declarative, |
433 | local_inner: false, | ||
433 | }; | 434 | }; |
434 | self.body.item_scope.define_legacy_macro(name, mac); | 435 | self.body.item_scope.define_legacy_macro(name, mac); |
435 | 436 | ||
diff --git a/crates/ra_hir_def/src/nameres/collector.rs b/crates/ra_hir_def/src/nameres/collector.rs index 98c74fe25..bf3968bd6 100644 --- a/crates/ra_hir_def/src/nameres/collector.rs +++ b/crates/ra_hir_def/src/nameres/collector.rs | |||
@@ -204,6 +204,7 @@ impl DefCollector<'_> { | |||
204 | ast_id: None, | 204 | ast_id: None, |
205 | krate: Some(krate), | 205 | krate: Some(krate), |
206 | kind: MacroDefKind::CustomDerive(expander), | 206 | kind: MacroDefKind::CustomDerive(expander), |
207 | local_inner: false, | ||
207 | }; | 208 | }; |
208 | 209 | ||
209 | self.define_proc_macro(name.clone(), macro_id); | 210 | self.define_proc_macro(name.clone(), macro_id); |
@@ -941,6 +942,7 @@ impl ModCollector<'_, '_> { | |||
941 | ast_id: Some(ast_id.ast_id), | 942 | ast_id: Some(ast_id.ast_id), |
942 | krate: Some(self.def_collector.def_map.krate), | 943 | krate: Some(self.def_collector.def_map.krate), |
943 | kind: MacroDefKind::Declarative, | 944 | kind: MacroDefKind::Declarative, |
945 | local_inner: mac.local_inner, | ||
944 | }; | 946 | }; |
945 | self.def_collector.define_macro(self.module_id, name.clone(), macro_id, mac.export); | 947 | self.def_collector.define_macro(self.module_id, name.clone(), macro_id, mac.export); |
946 | } | 948 | } |
diff --git a/crates/ra_hir_def/src/nameres/raw.rs b/crates/ra_hir_def/src/nameres/raw.rs index 39b011ad7..aed9dcc72 100644 --- a/crates/ra_hir_def/src/nameres/raw.rs +++ b/crates/ra_hir_def/src/nameres/raw.rs | |||
@@ -188,6 +188,7 @@ pub(super) struct MacroData { | |||
188 | pub(super) path: ModPath, | 188 | pub(super) path: ModPath, |
189 | pub(super) name: Option<Name>, | 189 | pub(super) name: Option<Name>, |
190 | pub(super) export: bool, | 190 | pub(super) export: bool, |
191 | pub(super) local_inner: bool, | ||
191 | pub(super) builtin: bool, | 192 | pub(super) builtin: bool, |
192 | } | 193 | } |
193 | 194 | ||
@@ -401,14 +402,28 @@ impl RawItemsCollector { | |||
401 | 402 | ||
402 | let name = m.name().map(|it| it.as_name()); | 403 | let name = m.name().map(|it| it.as_name()); |
403 | let ast_id = self.source_ast_id_map.ast_id(&m); | 404 | let ast_id = self.source_ast_id_map.ast_id(&m); |
404 | // FIXME: cfg_attr | ||
405 | let export = m.attrs().filter_map(|x| x.simple_name()).any(|name| name == "macro_export"); | ||
406 | 405 | ||
407 | // FIXME: cfg_attr | 406 | // FIXME: cfg_attr |
408 | let builtin = | 407 | let export = attrs.by_key("macro_export").exists(); |
409 | m.attrs().filter_map(|x| x.simple_name()).any(|name| name == "rustc_builtin_macro"); | 408 | let local_inner = |
410 | 409 | attrs.by_key("macro_export").tt_values().map(|it| &it.token_trees).flatten().any( | |
411 | let m = self.raw_items.macros.alloc(MacroData { ast_id, path, name, export, builtin }); | 410 | |it| match it { |
411 | tt::TokenTree::Leaf(tt::Leaf::Ident(ident)) => { | ||
412 | ident.text.contains("local_inner_macros") | ||
413 | } | ||
414 | _ => false, | ||
415 | }, | ||
416 | ); | ||
417 | let builtin = attrs.by_key("rustc_builtin_macro").exists(); | ||
418 | |||
419 | let m = self.raw_items.macros.alloc(MacroData { | ||
420 | ast_id, | ||
421 | path, | ||
422 | name, | ||
423 | export, | ||
424 | local_inner, | ||
425 | builtin, | ||
426 | }); | ||
412 | self.push_item(current_module, attrs, RawItemKind::Macro(m)); | 427 | self.push_item(current_module, attrs, RawItemKind::Macro(m)); |
413 | } | 428 | } |
414 | 429 | ||
diff --git a/crates/ra_hir_def/src/path/lower.rs b/crates/ra_hir_def/src/path/lower.rs index 9ec2e0dcd..e632f1afb 100644 --- a/crates/ra_hir_def/src/path/lower.rs +++ b/crates/ra_hir_def/src/path/lower.rs | |||
@@ -9,7 +9,10 @@ use hir_expand::{ | |||
9 | hygiene::Hygiene, | 9 | hygiene::Hygiene, |
10 | name::{name, AsName}, | 10 | name::{name, AsName}, |
11 | }; | 11 | }; |
12 | use ra_syntax::ast::{self, AstNode, TypeAscriptionOwner, TypeBoundsOwner}; | 12 | use ra_syntax::{ |
13 | ast::{self, AstNode, TypeAscriptionOwner, TypeBoundsOwner}, | ||
14 | T, | ||
15 | }; | ||
13 | 16 | ||
14 | use super::AssociatedTypeBinding; | 17 | use super::AssociatedTypeBinding; |
15 | use crate::{ | 18 | use crate::{ |
@@ -113,6 +116,20 @@ pub(super) fn lower_path(mut path: ast::Path, hygiene: &Hygiene) -> Option<Path> | |||
113 | } | 116 | } |
114 | segments.reverse(); | 117 | segments.reverse(); |
115 | generic_args.reverse(); | 118 | generic_args.reverse(); |
119 | |||
120 | // handle local_inner_macros : | ||
121 | // Basically, even in rustc it is quite hacky: | ||
122 | // https://github.com/rust-lang/rust/blob/614f273e9388ddd7804d5cbc80b8865068a3744e/src/librustc_resolve/macros.rs#L456 | ||
123 | // We follow what it did anyway :) | ||
124 | if segments.len() == 1 && kind == PathKind::Plain { | ||
125 | let next = path.syntax().last_token().and_then(|it| it.next_token()); | ||
126 | if next.map_or(false, |it| it.kind() == T![!]) { | ||
127 | if let Some(crate_id) = hygiene.local_inner_macros() { | ||
128 | kind = PathKind::DollarCrate(crate_id); | ||
129 | } | ||
130 | } | ||
131 | } | ||
132 | |||
116 | let mod_path = ModPath { kind, segments }; | 133 | let mod_path = ModPath { kind, segments }; |
117 | return Some(Path { type_anchor, mod_path, generic_args }); | 134 | return Some(Path { type_anchor, mod_path, generic_args }); |
118 | 135 | ||
diff --git a/crates/ra_hir_expand/src/builtin_derive.rs b/crates/ra_hir_expand/src/builtin_derive.rs index e60f879a3..25bb5cee3 100644 --- a/crates/ra_hir_expand/src/builtin_derive.rs +++ b/crates/ra_hir_expand/src/builtin_derive.rs | |||
@@ -38,7 +38,7 @@ macro_rules! register_builtin { | |||
38 | _ => return None, | 38 | _ => return None, |
39 | }; | 39 | }; |
40 | 40 | ||
41 | Some(MacroDefId { krate: None, ast_id: None, kind: MacroDefKind::BuiltInDerive(kind) }) | 41 | Some(MacroDefId { krate: None, ast_id: None, kind: MacroDefKind::BuiltInDerive(kind),local_inner:false }) |
42 | } | 42 | } |
43 | }; | 43 | }; |
44 | } | 44 | } |
diff --git a/crates/ra_hir_expand/src/builtin_macro.rs b/crates/ra_hir_expand/src/builtin_macro.rs index e0fef613d..d8b3d342c 100644 --- a/crates/ra_hir_expand/src/builtin_macro.rs +++ b/crates/ra_hir_expand/src/builtin_macro.rs | |||
@@ -73,11 +73,13 @@ pub fn find_builtin_macro( | |||
73 | krate: Some(krate), | 73 | krate: Some(krate), |
74 | ast_id: Some(ast_id), | 74 | ast_id: Some(ast_id), |
75 | kind: MacroDefKind::BuiltIn(kind), | 75 | kind: MacroDefKind::BuiltIn(kind), |
76 | local_inner: false, | ||
76 | }), | 77 | }), |
77 | Either::Right(kind) => Some(MacroDefId { | 78 | Either::Right(kind) => Some(MacroDefId { |
78 | krate: Some(krate), | 79 | krate: Some(krate), |
79 | ast_id: Some(ast_id), | 80 | ast_id: Some(ast_id), |
80 | kind: MacroDefKind::BuiltInEager(kind), | 81 | kind: MacroDefKind::BuiltInEager(kind), |
82 | local_inner: false, | ||
81 | }), | 83 | }), |
82 | } | 84 | } |
83 | } | 85 | } |
@@ -406,6 +408,7 @@ mod tests { | |||
406 | krate: Some(CrateId(0)), | 408 | krate: Some(CrateId(0)), |
407 | ast_id: Some(AstId::new(file_id.into(), ast_id_map.ast_id(¯o_calls[0]))), | 409 | ast_id: Some(AstId::new(file_id.into(), ast_id_map.ast_id(¯o_calls[0]))), |
408 | kind: MacroDefKind::BuiltIn(expander), | 410 | kind: MacroDefKind::BuiltIn(expander), |
411 | local_inner: false, | ||
409 | }; | 412 | }; |
410 | 413 | ||
411 | let loc = MacroCallLoc { | 414 | let loc = MacroCallLoc { |
@@ -425,6 +428,7 @@ mod tests { | |||
425 | krate: Some(CrateId(0)), | 428 | krate: Some(CrateId(0)), |
426 | ast_id: Some(AstId::new(file_id.into(), ast_id_map.ast_id(¯o_calls[0]))), | 429 | ast_id: Some(AstId::new(file_id.into(), ast_id_map.ast_id(¯o_calls[0]))), |
427 | kind: MacroDefKind::BuiltInEager(expander), | 430 | kind: MacroDefKind::BuiltInEager(expander), |
431 | local_inner: false, | ||
428 | }; | 432 | }; |
429 | 433 | ||
430 | let args = macro_calls[1].token_tree().unwrap(); | 434 | let args = macro_calls[1].token_tree().unwrap(); |
diff --git a/crates/ra_hir_expand/src/hygiene.rs b/crates/ra_hir_expand/src/hygiene.rs index 0b41d0e95..3da93de21 100644 --- a/crates/ra_hir_expand/src/hygiene.rs +++ b/crates/ra_hir_expand/src/hygiene.rs | |||
@@ -16,31 +16,34 @@ use crate::{ | |||
16 | pub struct Hygiene { | 16 | pub struct Hygiene { |
17 | // This is what `$crate` expands to | 17 | // This is what `$crate` expands to |
18 | def_crate: Option<CrateId>, | 18 | def_crate: Option<CrateId>, |
19 | |||
20 | // Indiciate this is a local inner macro | ||
21 | local_inner: bool, | ||
19 | } | 22 | } |
20 | 23 | ||
21 | impl Hygiene { | 24 | impl Hygiene { |
22 | pub fn new(db: &dyn AstDatabase, file_id: HirFileId) -> Hygiene { | 25 | pub fn new(db: &dyn AstDatabase, file_id: HirFileId) -> Hygiene { |
23 | let def_crate = match file_id.0 { | 26 | let (def_crate, local_inner) = match file_id.0 { |
24 | HirFileIdRepr::FileId(_) => None, | 27 | HirFileIdRepr::FileId(_) => (None, false), |
25 | HirFileIdRepr::MacroFile(macro_file) => match macro_file.macro_call_id { | 28 | HirFileIdRepr::MacroFile(macro_file) => match macro_file.macro_call_id { |
26 | MacroCallId::LazyMacro(id) => { | 29 | MacroCallId::LazyMacro(id) => { |
27 | let loc = db.lookup_intern_macro(id); | 30 | let loc = db.lookup_intern_macro(id); |
28 | match loc.def.kind { | 31 | match loc.def.kind { |
29 | MacroDefKind::Declarative => loc.def.krate, | 32 | MacroDefKind::Declarative => (loc.def.krate, loc.def.local_inner), |
30 | MacroDefKind::BuiltIn(_) => None, | 33 | MacroDefKind::BuiltIn(_) => (None, false), |
31 | MacroDefKind::BuiltInDerive(_) => None, | 34 | MacroDefKind::BuiltInDerive(_) => (None, false), |
32 | MacroDefKind::BuiltInEager(_) => None, | 35 | MacroDefKind::BuiltInEager(_) => (None, false), |
33 | MacroDefKind::CustomDerive(_) => None, | 36 | MacroDefKind::CustomDerive(_) => (None, false), |
34 | } | 37 | } |
35 | } | 38 | } |
36 | MacroCallId::EagerMacro(_id) => None, | 39 | MacroCallId::EagerMacro(_id) => (None, false), |
37 | }, | 40 | }, |
38 | }; | 41 | }; |
39 | Hygiene { def_crate } | 42 | Hygiene { def_crate, local_inner } |
40 | } | 43 | } |
41 | 44 | ||
42 | pub fn new_unhygienic() -> Hygiene { | 45 | pub fn new_unhygienic() -> Hygiene { |
43 | Hygiene { def_crate: None } | 46 | Hygiene { def_crate: None, local_inner: false } |
44 | } | 47 | } |
45 | 48 | ||
46 | // FIXME: this should just return name | 49 | // FIXME: this should just return name |
@@ -52,4 +55,12 @@ impl Hygiene { | |||
52 | } | 55 | } |
53 | Either::Left(name_ref.as_name()) | 56 | Either::Left(name_ref.as_name()) |
54 | } | 57 | } |
58 | |||
59 | pub fn local_inner_macros(&self) -> Option<CrateId> { | ||
60 | if self.local_inner { | ||
61 | self.def_crate | ||
62 | } else { | ||
63 | None | ||
64 | } | ||
65 | } | ||
55 | } | 66 | } |
diff --git a/crates/ra_hir_expand/src/lib.rs b/crates/ra_hir_expand/src/lib.rs index 754a0f005..f440c073b 100644 --- a/crates/ra_hir_expand/src/lib.rs +++ b/crates/ra_hir_expand/src/lib.rs | |||
@@ -204,6 +204,8 @@ pub struct MacroDefId { | |||
204 | pub krate: Option<CrateId>, | 204 | pub krate: Option<CrateId>, |
205 | pub ast_id: Option<AstId<ast::MacroCall>>, | 205 | pub ast_id: Option<AstId<ast::MacroCall>>, |
206 | pub kind: MacroDefKind, | 206 | pub kind: MacroDefKind, |
207 | |||
208 | pub local_inner: bool, | ||
207 | } | 209 | } |
208 | 210 | ||
209 | impl MacroDefId { | 211 | impl MacroDefId { |
diff --git a/crates/ra_hir_ty/src/tests/macros.rs b/crates/ra_hir_ty/src/tests/macros.rs index 5ddecbdc6..70e17bc94 100644 --- a/crates/ra_hir_ty/src/tests/macros.rs +++ b/crates/ra_hir_ty/src/tests/macros.rs | |||
@@ -388,6 +388,32 @@ fn main() { | |||
388 | } | 388 | } |
389 | 389 | ||
390 | #[test] | 390 | #[test] |
391 | fn infer_local_inner_macros() { | ||
392 | let (db, pos) = TestDB::with_position( | ||
393 | r#" | ||
394 | //- /main.rs crate:main deps:foo | ||
395 | fn test() { | ||
396 | let x = foo::foo!(1); | ||
397 | x<|>; | ||
398 | } | ||
399 | |||
400 | //- /lib.rs crate:foo | ||
401 | #[macro_export(local_inner_macros)] | ||
402 | macro_rules! foo { | ||
403 | (1) => { bar!() }; | ||
404 | } | ||
405 | |||
406 | #[macro_export] | ||
407 | macro_rules! bar { | ||
408 | () => { 42 } | ||
409 | } | ||
410 | |||
411 | "#, | ||
412 | ); | ||
413 | assert_eq!("i32", type_at_pos(&db, pos)); | ||
414 | } | ||
415 | |||
416 | #[test] | ||
391 | fn infer_builtin_macros_line() { | 417 | fn infer_builtin_macros_line() { |
392 | assert_snapshot!( | 418 | assert_snapshot!( |
393 | infer(r#" | 419 | infer(r#" |