aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_hir_expand
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_hir_expand')
-rw-r--r--crates/ra_hir_expand/src/builtin_derive.rs2
-rw-r--r--crates/ra_hir_expand/src/builtin_macro.rs8
-rw-r--r--crates/ra_hir_expand/src/db.rs39
-rw-r--r--crates/ra_hir_expand/src/hygiene.rs31
-rw-r--r--crates/ra_hir_expand/src/lib.rs2
5 files changed, 66 insertions, 16 deletions
diff --git a/crates/ra_hir_expand/src/builtin_derive.rs b/crates/ra_hir_expand/src/builtin_derive.rs
index e60f879a3..1dc9cac66 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..3bce8f673 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}
@@ -358,7 +360,7 @@ fn env_expand(
358 // However, we cannot use an empty string here, because for 360 // However, we cannot use an empty string here, because for
359 // `include!(concat!(env!("OUT_DIR"), "/foo.rs"))` will become 361 // `include!(concat!(env!("OUT_DIR"), "/foo.rs"))` will become
360 // `include!("foo.rs"), which might go to infinite loop 362 // `include!("foo.rs"), which might go to infinite loop
361 let s = get_env_inner(db, arg_id, &key).unwrap_or_else(|| "__RA_UNIMPLEMENTATED__".to_string()); 363 let s = get_env_inner(db, arg_id, &key).unwrap_or_else(|| "__RA_UNIMPLEMENTED__".to_string());
362 let expanded = quote! { #s }; 364 let expanded = quote! { #s };
363 365
364 Ok((expanded, FragmentKind::Expr)) 366 Ok((expanded, FragmentKind::Expr))
@@ -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();
@@ -504,7 +508,7 @@ mod tests {
504 "#, 508 "#,
505 ); 509 );
506 510
507 assert_eq!(expanded, "\"__RA_UNIMPLEMENTATED__\""); 511 assert_eq!(expanded, "\"__RA_UNIMPLEMENTED__\"");
508 } 512 }
509 513
510 #[test] 514 #[test]
diff --git a/crates/ra_hir_expand/src/db.rs b/crates/ra_hir_expand/src/db.rs
index 047452306..bf30d7151 100644
--- a/crates/ra_hir_expand/src/db.rs
+++ b/crates/ra_hir_expand/src/db.rs
@@ -34,7 +34,12 @@ impl TokenExpander {
34 // FIXME switch these to ExpandResult as well 34 // FIXME switch these to ExpandResult as well
35 TokenExpander::Builtin(it) => it.expand(db, id, tt).into(), 35 TokenExpander::Builtin(it) => it.expand(db, id, tt).into(),
36 TokenExpander::BuiltinDerive(it) => it.expand(db, id, tt).into(), 36 TokenExpander::BuiltinDerive(it) => it.expand(db, id, tt).into(),
37 TokenExpander::ProcMacro(it) => it.expand(db, id, tt).into(), 37 TokenExpander::ProcMacro(_) => {
38 // We store the result in salsa db to prevent non-determinisc behavior in
39 // some proc-macro implementation
40 // See #4315 for details
41 db.expand_proc_macro(id.into()).into()
42 }
38 } 43 }
39 } 44 }
40 45
@@ -75,6 +80,8 @@ pub trait AstDatabase: SourceDatabase {
75 80
76 #[salsa::interned] 81 #[salsa::interned]
77 fn intern_eager_expansion(&self, eager: EagerCallLoc) -> EagerMacroId; 82 fn intern_eager_expansion(&self, eager: EagerCallLoc) -> EagerMacroId;
83
84 fn expand_proc_macro(&self, call: MacroCallId) -> Result<tt::Subtree, mbe::ExpandError>;
78} 85}
79 86
80/// This expands the given macro call, but with different arguments. This is 87/// This expands the given macro call, but with different arguments. This is
@@ -216,6 +223,33 @@ fn macro_expand_with_arg(
216 (Some(Arc::new(tt)), err.map(|e| format!("{:?}", e))) 223 (Some(Arc::new(tt)), err.map(|e| format!("{:?}", e)))
217} 224}
218 225
226pub(crate) fn expand_proc_macro(
227 db: &dyn AstDatabase,
228 id: MacroCallId,
229) -> Result<tt::Subtree, mbe::ExpandError> {
230 let lazy_id = match id {
231 MacroCallId::LazyMacro(id) => id,
232 MacroCallId::EagerMacro(_) => unreachable!(),
233 };
234
235 let loc = db.lookup_intern_macro(lazy_id);
236 let macro_arg = match db.macro_arg(id) {
237 Some(it) => it,
238 None => {
239 return Err(
240 tt::ExpansionError::Unknown("No arguments for proc-macro".to_string()).into()
241 )
242 }
243 };
244
245 let expander = match loc.def.kind {
246 MacroDefKind::CustomDerive(expander) => expander,
247 _ => unreachable!(),
248 };
249
250 expander.expand(db, lazy_id, &macro_arg.0)
251}
252
219pub(crate) fn parse_or_expand(db: &dyn AstDatabase, file_id: HirFileId) -> Option<SyntaxNode> { 253pub(crate) fn parse_or_expand(db: &dyn AstDatabase, file_id: HirFileId) -> Option<SyntaxNode> {
220 match file_id.0 { 254 match file_id.0 {
221 HirFileIdRepr::FileId(file_id) => Some(db.parse(file_id).tree().syntax().clone()), 255 HirFileIdRepr::FileId(file_id) => Some(db.parse(file_id).tree().syntax().clone()),
@@ -330,7 +364,7 @@ fn to_fragment_kind(db: &dyn AstDatabase, id: MacroCallId) -> FragmentKind {
330 FragmentKind::Expr 364 FragmentKind::Expr
331 } 365 }
332 // FIXME: Expand to statements in appropriate positions; HIR lowering needs to handle that 366 // FIXME: Expand to statements in appropriate positions; HIR lowering needs to handle that
333 EXPR_STMT | BLOCK => FragmentKind::Expr, 367 EXPR_STMT | BLOCK_EXPR => FragmentKind::Expr,
334 ARG_LIST => FragmentKind::Expr, 368 ARG_LIST => FragmentKind::Expr,
335 TRY_EXPR => FragmentKind::Expr, 369 TRY_EXPR => FragmentKind::Expr,
336 TUPLE_EXPR => FragmentKind::Expr, 370 TUPLE_EXPR => FragmentKind::Expr,
@@ -342,7 +376,6 @@ fn to_fragment_kind(db: &dyn AstDatabase, id: MacroCallId) -> FragmentKind {
342 CONDITION => FragmentKind::Expr, 376 CONDITION => FragmentKind::Expr,
343 BREAK_EXPR => FragmentKind::Expr, 377 BREAK_EXPR => FragmentKind::Expr,
344 RETURN_EXPR => FragmentKind::Expr, 378 RETURN_EXPR => FragmentKind::Expr,
345 BLOCK_EXPR => FragmentKind::Expr,
346 MATCH_EXPR => FragmentKind::Expr, 379 MATCH_EXPR => FragmentKind::Expr,
347 MATCH_ARM => FragmentKind::Expr, 380 MATCH_ARM => FragmentKind::Expr,
348 MATCH_GUARD => FragmentKind::Expr, 381 MATCH_GUARD => FragmentKind::Expr,
diff --git a/crates/ra_hir_expand/src/hygiene.rs b/crates/ra_hir_expand/src/hygiene.rs
index 53866bbcb..6b482a60c 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 {