aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_hir_def/src/body/lower.rs
diff options
context:
space:
mode:
authorbors[bot] <26634292+bors[bot]@users.noreply.github.com>2020-03-15 12:15:09 +0000
committerGitHub <[email protected]>2020-03-15 12:15:09 +0000
commitefa72c899d0c1e628d2e944cac91ac3266da2c59 (patch)
tree5ddbf69ebecbba36403358829ba63c22a3046dd1 /crates/ra_hir_def/src/body/lower.rs
parent5429e6831c7a59425b37dec475f153848254a87d (diff)
parentfe78a14bbb9769c8ccd5cc41415702f5176a8e88 (diff)
Merge #3591
3591: Support local macro_rules r=matklad a=edwin0cheng This PR implement local `macro_rules` in function body, by adding following things: 1. While lowering, add a `MacroDefId` in body's `ItemScope` as a textual legacy macro. 2. Make `Expander::enter_expand` search with given `ItemScope`. 3. Make `Resolver::resolve_path_as_macro` search with `LocalItemScope`. Fix #2181 Co-authored-by: Edwin Cheng <[email protected]>
Diffstat (limited to 'crates/ra_hir_def/src/body/lower.rs')
-rw-r--r--crates/ra_hir_def/src/body/lower.rs48
1 files changed, 36 insertions, 12 deletions
diff --git a/crates/ra_hir_def/src/body/lower.rs b/crates/ra_hir_def/src/body/lower.rs
index ec1b0c2e7..54b5591d3 100644
--- a/crates/ra_hir_def/src/body/lower.rs
+++ b/crates/ra_hir_def/src/body/lower.rs
@@ -3,7 +3,10 @@
3 3
4use either::Either; 4use either::Either;
5 5
6use hir_expand::name::{name, AsName, Name}; 6use hir_expand::{
7 name::{name, AsName, Name},
8 MacroDefId, MacroDefKind,
9};
7use ra_arena::Arena; 10use ra_arena::Arena;
8use ra_syntax::{ 11use ra_syntax::{
9 ast::{ 12 ast::{
@@ -452,19 +455,30 @@ where
452 None => self.alloc_expr(Expr::Missing, syntax_ptr), 455 None => self.alloc_expr(Expr::Missing, syntax_ptr),
453 } 456 }
454 } 457 }
455 // FIXME expand to statements in statement position
456 ast::Expr::MacroCall(e) => { 458 ast::Expr::MacroCall(e) => {
457 let macro_call = self.expander.to_source(AstPtr::new(&e)); 459 if let Some(name) = is_macro_rules(&e) {
458 match self.expander.enter_expand(self.db, e) { 460 let mac = MacroDefId {
459 Some((mark, expansion)) => { 461 krate: Some(self.expander.module.krate),
460 self.source_map 462 ast_id: Some(self.expander.ast_id(&e)),
461 .expansions 463 kind: MacroDefKind::Declarative,
462 .insert(macro_call, self.expander.current_file_id); 464 };
463 let id = self.collect_expr(expansion); 465 self.body.item_scope.define_legacy_macro(name, mac);
464 self.expander.exit(self.db, mark); 466
465 id 467 // FIXME: do we still need to allocate this as missing ?
468 self.alloc_expr(Expr::Missing, syntax_ptr)
469 } else {
470 let macro_call = self.expander.to_source(AstPtr::new(&e));
471 match self.expander.enter_expand(self.db, Some(&self.body.item_scope), e) {
472 Some((mark, expansion)) => {
473 self.source_map
474 .expansions
475 .insert(macro_call, self.expander.current_file_id);
476 let id = self.collect_expr(expansion);
477 self.expander.exit(self.db, mark);
478 id
479 }
480 None => self.alloc_expr(Expr::Missing, syntax_ptr),
466 } 481 }
467 None => self.alloc_expr(Expr::Missing, syntax_ptr),
468 } 482 }
469 } 483 }
470 484
@@ -686,6 +700,16 @@ where
686 } 700 }
687} 701}
688 702
703fn is_macro_rules(m: &ast::MacroCall) -> Option<Name> {
704 let name = m.path()?.segment()?.name_ref()?.as_name();
705
706 if name == name![macro_rules] {
707 Some(m.name()?.as_name())
708 } else {
709 None
710 }
711}
712
689impl From<ast::BinOp> for BinaryOp { 713impl From<ast::BinOp> for BinaryOp {
690 fn from(ast_op: ast::BinOp) -> Self { 714 fn from(ast_op: ast::BinOp) -> Self {
691 match ast_op { 715 match ast_op {