Unnamed repository; edit this file 'description' to name the repository.
-rw-r--r--crates/hir_def/src/macro_expansion_tests.rs29
-rw-r--r--crates/hir_def/src/macro_expansion_tests/mbe.rs117
-rw-r--r--crates/mbe/src/tests/expand.rs58
3 files changed, 140 insertions, 64 deletions
diff --git a/crates/hir_def/src/macro_expansion_tests.rs b/crates/hir_def/src/macro_expansion_tests.rs
index d113a2f504..f9527a4135 100644
--- a/crates/hir_def/src/macro_expansion_tests.rs
+++ b/crates/hir_def/src/macro_expansion_tests.rs
@@ -20,7 +20,7 @@ use stdx::format_to;
use syntax::{
ast::{self, edit::IndentLevel},
AstNode,
- SyntaxKind::{EOF, IDENT, LIFETIME_IDENT},
+ SyntaxKind::{COMMENT, EOF, IDENT, LIFETIME_IDENT},
SyntaxNode, T,
};
@@ -60,21 +60,36 @@ fn check(ra_fixture: &str, mut expect: Expect) {
let mut expanded_text = source_file.to_string();
for (call, exp) in expansions.into_iter().rev() {
+ let mut tree = false;
+ let mut expect_errors = false;
+ for comment in call.syntax().children_with_tokens().filter(|it| it.kind() == COMMENT) {
+ tree |= comment.to_string().contains("+tree");
+ expect_errors |= comment.to_string().contains("+errors");
+ }
+
let mut expn_text = String::new();
if let Some(err) = exp.err {
format_to!(expn_text, "/* error: {} */", err);
}
if let Some((parse, _token_map)) = exp.value {
- assert!(
- parse.errors().is_empty(),
- "parse errors in expansion: \n{:#?}",
- parse.errors()
- );
+ if expect_errors {
+ assert!(!parse.errors().is_empty(), "no parse errors in expansion");
+ for e in parse.errors() {
+ format_to!(expn_text, "/* parse error: {} */\n", e);
+ }
+ } else {
+ assert!(
+ parse.errors().is_empty(),
+ "parse errors in expansion: \n{:#?}",
+ parse.errors()
+ );
+ }
let pp = pretty_print_macro_expansion(parse.syntax_node());
let indent = IndentLevel::from_node(call.syntax());
let pp = reindent(indent, pp);
format_to!(expn_text, "{}", pp);
- if call.to_string().contains("// +tree") {
+
+ if tree {
let tree = format!("{:#?}", parse.syntax_node())
.split_inclusive("\n")
.map(|line| format!("// {}", line))
diff --git a/crates/hir_def/src/macro_expansion_tests/mbe.rs b/crates/hir_def/src/macro_expansion_tests/mbe.rs
index 4ed46a1325..7600b16ded 100644
--- a/crates/hir_def/src/macro_expansion_tests/mbe.rs
+++ b/crates/hir_def/src/macro_expansion_tests/mbe.rs
@@ -1310,3 +1310,120 @@ fn foo() {}
"#]],
);
}
+
+#[test]
+fn test_inner_macro_rules() {
+ check(
+ r#"
+macro_rules! m {
+ ($a:ident, $b:ident, $c:tt) => {
+ macro_rules! inner {
+ ($bi:ident) => { fn $bi() -> u8 { $c } }
+ }
+
+ inner!($a);
+ fn $b() -> u8 { $c }
+ }
+}
+m!(x, y, 1);
+"#,
+ expect![[r#"
+macro_rules! m {
+ ($a:ident, $b:ident, $c:tt) => {
+ macro_rules! inner {
+ ($bi:ident) => { fn $bi() -> u8 { $c } }
+ }
+
+ inner!($a);
+ fn $b() -> u8 { $c }
+ }
+}
+macro_rules !inner {
+ ($bi: ident) = > {
+ fn $bi()-> u8 {
+ 1
+ }
+ }
+}
+inner!(x);
+fn y() -> u8 {
+ 1
+}
+"#]],
+ );
+}
+
+#[test]
+fn test_expr_after_path_colons() {
+ check(
+ r#"
+macro_rules! m {
+ ($k:expr) => { fn f() { K::$k; } }
+}
+// +tree +errors
+m!(C("0"));
+"#,
+ expect![[r#"
+macro_rules! m {
+ ($k:expr) => { fn f() { K::$k; } }
+}
+/* parse error: expected identifier */
+/* parse error: expected SEMICOLON */
+fn f() {
+ K::C("0");
+}
+// [email protected] "\"0\""
+
+"#]],
+ );
+}
+
+#[test]
+fn test_match_is_not_greedy() {
+ check(
+ r#"
+macro_rules! foo {
+ ($($i:ident $(,)*),*) => {};
+}
+foo!(a,b);
+"#,
+ expect![[r#"
+macro_rules! foo {
+ ($($i:ident $(,)*),*) => {};
+}
+
+"#]],
+ );
+}
diff --git a/crates/mbe/src/tests/expand.rs b/crates/mbe/src/tests/expand.rs
index 51c3ba10da..79f0824b59 100644
--- a/crates/mbe/src/tests/expand.rs
+++ b/crates/mbe/src/tests/expand.rs
@@ -1,8 +1,5 @@
use ::parser::ParserEntryPoint;
-use syntax::{
- SyntaxKind::{ERROR, IDENT},
- T,
-};
+use syntax::{SyntaxKind::IDENT, T};
use test_utils::assert_eq_text;
use super::*;
@@ -101,59 +98,6 @@ fn test_attr_to_token_tree() {
);
}
-#[test]
-fn test_inner_macro_rules() {
- parse_macro(
- r#"
-macro_rules! foo {
- ($a:ident, $b:ident, $c:tt) => {
-
- macro_rules! bar {
- ($bi:ident) => {
- fn $bi() -> u8 {$c}
- }
- }
-
- bar!($a);
- fn $b() -> u8 {$c}
- }
-}
-"#,
- ).
- assert_expand_items(
- r#"foo!(x,y, 1);"#,
- r#"macro_rules ! bar {($ bi : ident) => {fn $ bi () -> u8 {1}}} bar ! (x) ; fn y () -> u8 {1}"#,
- );
-}
-
-#[test]
-fn test_expr_after_path_colons() {
- assert!(parse_macro(
- r#"
-macro_rules! m {
- ($k:expr) => {
- f(K::$k);
- }
-}
-"#,
- )
- .expand_statements(r#"m!(C("0"))"#)
- .descendants()
- .any(|token| token.kind() == ERROR));
-}
-
-#[test]
-fn test_match_is_not_greedy() {
- parse_macro(
- r#"
-macro_rules! foo {
- ($($i:ident $(,)*),*) => {};
-}
-"#,
- )
- .assert_expand_items(r#"foo!(a,b);"#, r#""#);
-}
-
// The following tests are based on real world situations
#[test]
fn test_vec() {