]> git.lizzy.rs Git - rust.git/commitdiff
Merge #2365
authorbors[bot] <26634292+bors[bot]@users.noreply.github.com>
Sun, 24 Nov 2019 08:39:29 +0000 (08:39 +0000)
committerGitHub <noreply@github.com>
Sun, 24 Nov 2019 08:39:29 +0000 (08:39 +0000)
2365: Make expand-macro more flexible r=matklad a=edwin0cheng

Due to lack of implementation or other types of errors, some macros do not expand correctly in the current situation. The PR attempts to make `expand-macro` more flexible in error situations by ignoring internal failed macro expansion.

Co-authored-by: Edwin Cheng <edwin0cheng@gmail.com>
crates/ra_ide_api/src/expand_macro.rs

index 673301b10ade100ab4cef509d8389a95417e4d2e..0b540b8cdead6a1e67446103b414838a2ac73c32 100644 (file)
@@ -47,15 +47,15 @@ fn expand_macro_recur(
 
     for child in children.into_iter() {
         let node = hir::Source::new(macro_file_id, &child);
-        let new_node = expand_macro_recur(db, source, node)?;
-
-        // Replace the whole node if it is root
-        // `replace_descendants` will not replace the parent node
-        // but `SyntaxNode::descendants include itself
-        if expanded == *child.syntax() {
-            expanded = new_node;
-        } else {
-            replaces.insert(child.syntax().clone().into(), new_node.into());
+        if let Some(new_node) = expand_macro_recur(db, source, node) {
+            // Replace the whole node if it is root
+            // `replace_descendants` will not replace the parent node
+            // but `SyntaxNode::descendants include itself
+            if expanded == *child.syntax() {
+                expanded = new_node;
+            } else {
+                replaces.insert(child.syntax().clone().into(), new_node.into());
+            }
         }
     }
 
@@ -247,4 +247,26 @@ fn main() {
         assert_eq!(res.name, "match_ast");
         assert_snapshot!(res.expansion, @r###"{}"###);
     }
+
+    #[test]
+    fn macro_expand_inner_macro_fail_to_expand() {
+        let res = check_expand_macro(
+            r#"
+        //- /lib.rs
+        macro_rules! bar {
+            (BAD) => {};
+        }
+        macro_rules! foo {
+            () => {bar!()};
+        }        
+
+        fn main() {        
+            let res = fo<|>o!();
+        }
+        "#,
+        );
+
+        assert_eq!(res.name, "foo");
+        assert_snapshot!(res.expansion, @r###"bar!()"###);
+    }
 }