aboutsummaryrefslogtreecommitdiff
path: root/crates
diff options
context:
space:
mode:
authorEdwin Cheng <[email protected]>2020-05-01 04:23:03 +0100
committerEdwin Cheng <[email protected]>2020-05-01 04:23:03 +0100
commite4267967a8ee3b35d902931cecf06bb4e19f86c5 (patch)
tree9dc984e821a43da548a70648d1cfc4466d6e1ae9 /crates
parenta5f2b16366f027ad60c58266a66eb7fbdcbda9f9 (diff)
Support local_inner_macros
Diffstat (limited to 'crates')
-rw-r--r--crates/ra_hir/src/semantics/source_to_def.rs2
-rw-r--r--crates/ra_hir_def/src/body/lower.rs1
-rw-r--r--crates/ra_hir_def/src/nameres/collector.rs2
-rw-r--r--crates/ra_hir_def/src/nameres/raw.rs27
-rw-r--r--crates/ra_hir_def/src/path/lower.rs19
-rw-r--r--crates/ra_hir_expand/src/builtin_derive.rs2
-rw-r--r--crates/ra_hir_expand/src/builtin_macro.rs4
-rw-r--r--crates/ra_hir_expand/src/hygiene.rs31
-rw-r--r--crates/ra_hir_expand/src/lib.rs2
-rw-r--r--crates/ra_hir_ty/src/tests/macros.rs26
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};
12use ra_syntax::ast::{self, AstNode, TypeAscriptionOwner, TypeBoundsOwner}; 12use ra_syntax::{
13 ast::{self, AstNode, TypeAscriptionOwner, TypeBoundsOwner},
14 T,
15};
13 16
14use super::AssociatedTypeBinding; 17use super::AssociatedTypeBinding;
15use crate::{ 18use 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(&macro_calls[0]))), 409 ast_id: Some(AstId::new(file_id.into(), ast_id_map.ast_id(&macro_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(&macro_calls[0]))), 429 ast_id: Some(AstId::new(file_id.into(), ast_id_map.ast_id(&macro_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::{
16pub struct Hygiene { 16pub 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
21impl Hygiene { 24impl 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
209impl MacroDefId { 211impl 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]
391fn infer_local_inner_macros() {
392 let (db, pos) = TestDB::with_position(
393 r#"
394//- /main.rs crate:main deps:foo
395fn test() {
396 let x = foo::foo!(1);
397 x<|>;
398}
399
400//- /lib.rs crate:foo
401#[macro_export(local_inner_macros)]
402macro_rules! foo {
403 (1) => { bar!() };
404}
405
406#[macro_export]
407macro_rules! bar {
408 () => { 42 }
409}
410
411"#,
412 );
413 assert_eq!("i32", type_at_pos(&db, pos));
414}
415
416#[test]
391fn infer_builtin_macros_line() { 417fn infer_builtin_macros_line() {
392 assert_snapshot!( 418 assert_snapshot!(
393 infer(r#" 419 infer(r#"