aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_hir_def
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_hir_def')
-rw-r--r--crates/ra_hir_def/src/body.rs9
-rw-r--r--crates/ra_hir_def/src/body/lower.rs12
2 files changed, 9 insertions, 12 deletions
diff --git a/crates/ra_hir_def/src/body.rs b/crates/ra_hir_def/src/body.rs
index 27a297e8b..5f9d53ecb 100644
--- a/crates/ra_hir_def/src/body.rs
+++ b/crates/ra_hir_def/src/body.rs
@@ -30,6 +30,7 @@ pub(crate) struct Expander {
30 hygiene: Hygiene, 30 hygiene: Hygiene,
31 ast_id_map: Arc<AstIdMap>, 31 ast_id_map: Arc<AstIdMap>,
32 module: ModuleId, 32 module: ModuleId,
33 recursive_limit: usize,
33} 34}
34 35
35impl Expander { 36impl Expander {
@@ -41,7 +42,7 @@ impl Expander {
41 let crate_def_map = db.crate_def_map(module.krate); 42 let crate_def_map = db.crate_def_map(module.krate);
42 let hygiene = Hygiene::new(db.upcast(), current_file_id); 43 let hygiene = Hygiene::new(db.upcast(), current_file_id);
43 let ast_id_map = db.ast_id_map(current_file_id); 44 let ast_id_map = db.ast_id_map(current_file_id);
44 Expander { crate_def_map, current_file_id, hygiene, ast_id_map, module } 45 Expander { crate_def_map, current_file_id, hygiene, ast_id_map, module, recursive_limit: 0 }
45 } 46 }
46 47
47 pub(crate) fn enter_expand<T: ast::AstNode>( 48 pub(crate) fn enter_expand<T: ast::AstNode>(
@@ -50,6 +51,10 @@ impl Expander {
50 local_scope: Option<&ItemScope>, 51 local_scope: Option<&ItemScope>,
51 macro_call: ast::MacroCall, 52 macro_call: ast::MacroCall,
52 ) -> Option<(Mark, T)> { 53 ) -> Option<(Mark, T)> {
54 if self.recursive_limit > 1024 {
55 return None;
56 }
57
53 let macro_call = InFile::new(self.current_file_id, &macro_call); 58 let macro_call = InFile::new(self.current_file_id, &macro_call);
54 59
55 if let Some(call_id) = macro_call.as_call_id(db, |path| { 60 if let Some(call_id) = macro_call.as_call_id(db, |path| {
@@ -73,6 +78,7 @@ impl Expander {
73 self.hygiene = Hygiene::new(db.upcast(), file_id); 78 self.hygiene = Hygiene::new(db.upcast(), file_id);
74 self.current_file_id = file_id; 79 self.current_file_id = file_id;
75 self.ast_id_map = db.ast_id_map(file_id); 80 self.ast_id_map = db.ast_id_map(file_id);
81 self.recursive_limit += 1;
76 82
77 return Some((mark, expr)); 83 return Some((mark, expr));
78 } 84 }
@@ -88,6 +94,7 @@ impl Expander {
88 self.hygiene = Hygiene::new(db.upcast(), mark.file_id); 94 self.hygiene = Hygiene::new(db.upcast(), mark.file_id);
89 self.current_file_id = mark.file_id; 95 self.current_file_id = mark.file_id;
90 self.ast_id_map = mem::take(&mut mark.ast_id_map); 96 self.ast_id_map = mem::take(&mut mark.ast_id_map);
97 self.recursive_limit -= 1;
91 mark.bomb.defuse(); 98 mark.bomb.defuse();
92 } 99 }
93 100
diff --git a/crates/ra_hir_def/src/body/lower.rs b/crates/ra_hir_def/src/body/lower.rs
index e8c58ed32..3cf0c66ea 100644
--- a/crates/ra_hir_def/src/body/lower.rs
+++ b/crates/ra_hir_def/src/body/lower.rs
@@ -453,7 +453,7 @@ impl ExprCollector<'_> {
453 } 453 }
454 } 454 }
455 ast::Expr::MacroCall(e) => { 455 ast::Expr::MacroCall(e) => {
456 if let Some(name) = is_macro_rules(&e) { 456 if let Some(name) = e.is_macro_rules().map(|it| it.as_name()) {
457 let mac = MacroDefId { 457 let mac = MacroDefId {
458 krate: Some(self.expander.module.krate), 458 krate: Some(self.expander.module.krate),
459 ast_id: Some(self.expander.ast_id(&e)), 459 ast_id: Some(self.expander.ast_id(&e)),
@@ -697,16 +697,6 @@ impl ExprCollector<'_> {
697 } 697 }
698} 698}
699 699
700fn is_macro_rules(m: &ast::MacroCall) -> Option<Name> {
701 let name = m.path()?.segment()?.name_ref()?.as_name();
702
703 if name == name![macro_rules] {
704 Some(m.name()?.as_name())
705 } else {
706 None
707 }
708}
709
710impl From<ast::BinOp> for BinaryOp { 700impl From<ast::BinOp> for BinaryOp {
711 fn from(ast_op: ast::BinOp) -> Self { 701 fn from(ast_op: ast::BinOp) -> Self {
712 match ast_op { 702 match ast_op {