Unnamed repository; edit this file 'description' to name the repository.
Merge #10507
10507: internal: move tests r=matklad a=matklad bors r+ 🤖 Co-authored-by: Aleksey Kladov <[email protected]>
bors[bot] 2021-10-10
parent cbe6662 · parent 3c9dda6 · commit 93c52f5
-rw-r--r--crates/hir_def/src/macro_expansion_tests.rs9
-rw-r--r--crates/hir_def/src/macro_expansion_tests/mbe.rs353
-rw-r--r--crates/hir_def/src/macro_expansion_tests/mbe/tt_conversion.rs10
-rw-r--r--crates/mbe/src/syntax_bridge.rs1
-rw-r--r--crates/mbe/src/tests/expand.rs309
5 files changed, 360 insertions, 322 deletions
diff --git a/crates/hir_def/src/macro_expansion_tests.rs b/crates/hir_def/src/macro_expansion_tests.rs
index e892ab5268..66874a674d 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::{self, IDENT, LIFETIME_IDENT},
+ SyntaxKind::{EOF, IDENT, LIFETIME_IDENT},
SyntaxNode, T,
};
@@ -109,7 +109,7 @@ fn reindent(indent: IndentLevel, pp: String) -> String {
fn pretty_print_macro_expansion(expn: SyntaxNode) -> String {
let mut res = String::new();
- let mut prev_kind = SyntaxKind::EOF;
+ let mut prev_kind = EOF;
let mut indent_level = 0;
for token in iter::successors(expn.first_token(), |t| t.next_token()) {
let curr_kind = token.kind();
@@ -128,6 +128,11 @@ fn pretty_print_macro_expansion(expn: SyntaxNode) -> String {
(T![>], _) if curr_kind.is_keyword() => " ",
(T![->], _) | (_, T![->]) => " ",
(T![&&], _) | (_, T![&&]) => " ",
+ (T![,], _) => " ",
+ (T![fn], T!['(']) => "",
+ (T![']'], _) if curr_kind.is_keyword() => " ",
+ (T![']'], T![#]) => "\n",
+ _ if prev_kind.is_keyword() => " ",
_ => "",
};
diff --git a/crates/hir_def/src/macro_expansion_tests/mbe.rs b/crates/hir_def/src/macro_expansion_tests/mbe.rs
index 958f2a1c33..df93298a35 100644
--- a/crates/hir_def/src/macro_expansion_tests/mbe.rs
+++ b/crates/hir_def/src/macro_expansion_tests/mbe.rs
@@ -403,15 +403,15 @@ fn test_match_group_in_group() {
check(
r#"
macro_rules! m {
- [ $( ( $($i:ident)* ) )* ] => [ x![$( ( $($i)* ) )*]; ]
+ [ $( ( $($i:ident)* ) )* ] => [ ok![$( ( $($i)* ) )*]; ]
}
m! ( (a b) );
"#,
expect![[r#"
macro_rules! m {
- [ $( ( $($i:ident)* ) )* ] => [ x![$( ( $($i)* ) )*]; ]
+ [ $( ( $($i:ident)* ) )* ] => [ ok![$( ( $($i)* ) )*]; ]
}
-x![(a b)];
+ok![(a b)];
"#]],
)
}
@@ -769,12 +769,353 @@ fn f() {
fn test_expr_with_attr() {
check(
r#"
-macro_rules! m { ($a:expr) => { x!(); } }
+macro_rules! m { ($a:expr) => { ok!(); } }
m!(#[allow(a)]());
"#,
expect![[r#"
-macro_rules! m { ($a:expr) => { x!(); } }
-x!();
+macro_rules! m { ($a:expr) => { ok!(); } }
+ok!();
"#]],
)
}
+
+#[test]
+fn test_ty() {
+ check(
+ r#"
+macro_rules! m {
+ ($t:ty) => ( fn bar() -> $t {} )
+}
+m! { Baz<u8> }
+"#,
+ expect![[r#"
+macro_rules! m {
+ ($t:ty) => ( fn bar() -> $t {} )
+}
+fn bar() -> Baz<u8> {}
+"#]],
+ )
+}
+
+#[test]
+fn test_ty_with_complex_type() {
+ check(
+ r#"
+macro_rules! m {
+ ($t:ty) => ( fn bar() -> $ t {} )
+}
+
+m! { &'a Baz<u8> }
+
+m! { extern "Rust" fn() -> Ret }
+"#,
+ expect![[r#"
+macro_rules! m {
+ ($t:ty) => ( fn bar() -> $ t {} )
+}
+
+fn bar() -> & 'a Baz<u8> {}
+
+fn bar() -> extern "Rust"fn() -> Ret {}
+"#]],
+ );
+}
+
+#[test]
+fn test_pat_() {
+ check(
+ r#"
+macro_rules! m {
+ ($p:pat) => { fn foo() { let $p; } }
+}
+m! { (a, b) }
+"#,
+ expect![[r#"
+macro_rules! m {
+ ($p:pat) => { fn foo() { let $p; } }
+}
+fn foo() {
+ let (a, b);
+}
+"#]],
+ );
+}
+
+#[test]
+fn test_stmt() {
+ check(
+ r#"
+macro_rules! m {
+ ($s:stmt) => ( fn bar() { $s; } )
+}
+m! { 2 }
+m! { let a = 0 }
+"#,
+ expect![[r#"
+macro_rules! m {
+ ($s:stmt) => ( fn bar() { $s; } )
+}
+fn bar() {
+ 2;
+}
+fn bar() {
+ let a = 0;
+}
+"#]],
+ )
+}
+
+#[test]
+fn test_single_item() {
+ check(
+ r#"
+macro_rules! m { ($i:item) => ( $i ) }
+m! { mod c {} }
+"#,
+ expect![[r#"
+macro_rules! m { ($i:item) => ( $i ) }
+mod c {}
+"#]],
+ )
+}
+
+#[test]
+fn test_all_items() {
+ check(
+ r#"
+macro_rules! m { ($($i:item)*) => ($($i )*) }
+m! {
+ extern crate a;
+ mod b;
+ mod c {}
+ use d;
+ const E: i32 = 0;
+ static F: i32 = 0;
+ impl G {}
+ struct H;
+ enum I { Foo }
+ trait J {}
+ fn h() {}
+ extern {}
+ type T = u8;
+}
+"#,
+ expect![[r#"
+macro_rules! m { ($($i:item)*) => ($($i )*) }
+extern crate a;
+mod b;
+mod c {}
+use d;
+const E:i32 = 0;
+static F:i32 = 0;
+impl G {}
+struct H;
+enum I {
+ Foo
+}
+trait J {}
+fn h() {}
+extern {}
+type T = u8;
+"#]],
+ );
+}
+
+#[test]
+fn test_block() {
+ check(
+ r#"
+macro_rules! m { ($b:block) => { fn foo() $b } }
+m! { { 1; } }
+"#,
+ expect![[r#"
+macro_rules! m { ($b:block) => { fn foo() $b } }
+fn foo() {
+ 1;
+}
+"#]],
+ );
+}
+
+#[test]
+fn test_meta() {
+ check(
+ r#"
+macro_rules! m {
+ ($m:meta) => ( #[$m] fn bar() {} )
+}
+m! { cfg(target_os = "windows") }
+m! { hello::world }
+"#,
+ expect![[r##"
+macro_rules! m {
+ ($m:meta) => ( #[$m] fn bar() {} )
+}
+#[cfg(target_os = "windows")] fn bar() {}
+#[hello::world] fn bar() {}
+"##]],
+ );
+}
+
+#[test]
+fn test_meta_doc_comments() {
+ cov_mark::check!(test_meta_doc_comments);
+ check(
+ r#"
+macro_rules! m {
+ ($(#[$m:meta])+) => ( $(#[$m])+ fn bar() {} )
+}
+m! {
+ /// Single Line Doc 1
+ /**
+ MultiLines Doc
+ */
+}
+"#,
+ expect![[r##"
+macro_rules! m {
+ ($(#[$m:meta])+) => ( $(#[$m])+ fn bar() {} )
+}
+#[doc = " Single Line Doc 1"]
+#[doc = "\n MultiLines Doc\n "] fn bar() {}
+"##]],
+ );
+}
+
+#[test]
+fn test_meta_extended_key_value_attributes() {
+ check(
+ r#"
+macro_rules! m {
+ (#[$m:meta]) => ( #[$m] fn bar() {} )
+}
+m! { #[doc = concat!("The `", "bla", "` lang item.")] }
+"#,
+ expect![[r##"
+macro_rules! m {
+ (#[$m:meta]) => ( #[$m] fn bar() {} )
+}
+#[doc = concat!("The `", "bla", "` lang item.")] fn bar() {}
+"##]],
+ );
+}
+
+#[test]
+fn test_meta_doc_comments_non_latin() {
+ check(
+ r#"
+macro_rules! m {
+ ($(#[$ m:meta])+) => ( $(#[$m])+ fn bar() {} )
+}
+m! {
+ /// 錦瑟無端五十弦,一弦一柱思華年。
+ /**
+ 莊生曉夢迷蝴蝶,望帝春心託杜鵑。
+ */
+}
+"#,
+ expect![[r##"
+macro_rules! m {
+ ($(#[$ m:meta])+) => ( $(#[$m])+ fn bar() {} )
+}
+#[doc = " 錦瑟無端五十弦,一弦一柱思華年。"]
+#[doc = "\n 莊生曉夢迷蝴蝶,望帝春心託杜鵑。\n "] fn bar() {}
+"##]],
+ );
+}
+
+#[test]
+fn test_meta_doc_comments_escaped_characters() {
+ check(
+ r#"
+macro_rules! m {
+ ($(#[$m:meta])+) => ( $(#[$m])+ fn bar() {} )
+}
+m! {
+ /// \ " '
+}
+"#,
+ expect![[r##"
+macro_rules! m {
+ ($(#[$m:meta])+) => ( $(#[$m])+ fn bar() {} )
+}
+#[doc = " \\ \" \'"] fn bar() {}
+"##]],
+ );
+}
+
+#[test]
+fn test_tt_block() {
+ check(
+ r#"
+macro_rules! m { ($tt:tt) => { fn foo() $tt } }
+m! { { 1; } }
+"#,
+ expect![[r#"
+macro_rules! m { ($tt:tt) => { fn foo() $tt } }
+fn foo() {
+ 1;
+}
+"#]],
+ );
+}
+
+#[test]
+fn test_tt_group() {
+ check(
+ r#"
+macro_rules! m { ($($tt:tt)*) => { $($tt)* } }
+m! { fn foo() {} }"
+"#,
+ expect![[r#"
+macro_rules! m { ($($tt:tt)*) => { $($tt)* } }
+fn foo() {}"
+"#]],
+ );
+}
+
+#[test]
+fn test_tt_composite() {
+ check(
+ r#"
+macro_rules! m { ($tt:tt) => { ok!(); } }
+m! { => }
+m! { = > }
+"#,
+ expect![[r#"
+macro_rules! m { ($tt:tt) => { ok!(); } }
+ok!();
+/* error: leftover tokens */ok!();
+"#]],
+ );
+}
+
+#[test]
+fn test_tt_composite2() {
+ check(
+ r#"
+macro_rules! m { ($($tt:tt)*) => { abs!(=> $($tt)*); } }
+m! {#}
+"#,
+ expect![[r##"
+macro_rules! m { ($($tt:tt)*) => { abs!(=> $($tt)*); } }
+abs!( = > #);
+"##]],
+ );
+}
+
+#[test]
+fn test_tt_with_composite_without_space() {
+ // Test macro input without any spaces
+ // See https://github.com/rust-analyzer/rust-analyzer/issues/6692
+ check(
+ r#"
+macro_rules! m { ($ op:tt, $j:path) => ( ok!(); ) }
+m!(==,Foo::Bool)
+"#,
+ expect![[r#"
+macro_rules! m { ($ op:tt, $j:path) => ( ok!(); ) }
+ok!();
+"#]],
+ );
+}
diff --git a/crates/hir_def/src/macro_expansion_tests/mbe/tt_conversion.rs b/crates/hir_def/src/macro_expansion_tests/mbe/tt_conversion.rs
index 3450cda3fd..291f99330f 100644
--- a/crates/hir_def/src/macro_expansion_tests/mbe/tt_conversion.rs
+++ b/crates/hir_def/src/macro_expansion_tests/mbe/tt_conversion.rs
@@ -53,11 +53,11 @@ macro_rules! m {
}
}
fn f() {
- let_ = 'c';
- let_ = 1000;
- let_ = 12E+99_f64;
- let_ = "rust1";
- let_ = -92;
+ let _ = 'c';
+ let _ = 1000;
+ let _ = 12E+99_f64;
+ let _ = "rust1";
+ let _ = -92;
}
"#]],
);
diff --git a/crates/mbe/src/syntax_bridge.rs b/crates/mbe/src/syntax_bridge.rs
index f3c9af1ccb..6bd57bb568 100644
--- a/crates/mbe/src/syntax_bridge.rs
+++ b/crates/mbe/src/syntax_bridge.rs
@@ -307,6 +307,7 @@ fn doc_comment_text(comment: &ast::Comment) -> SmolStr {
}
fn convert_doc_comment(token: &syntax::SyntaxToken) -> Option<Vec<tt::TokenTree>> {
+ cov_mark::hit!(test_meta_doc_comments);
let comment = ast::Comment::cast(token.clone())?;
let doc = comment.kind().doc?;
diff --git a/crates/mbe/src/tests/expand.rs b/crates/mbe/src/tests/expand.rs
index 01b5533522..15a7184029 100644
--- a/crates/mbe/src/tests/expand.rs
+++ b/crates/mbe/src/tests/expand.rs
@@ -102,315 +102,6 @@ fn test_attr_to_token_tree() {
}
#[test]
-fn test_ty() {
- parse_macro(
- r#"
- macro_rules! foo {
- ($ i:ty) => (
- fn bar() -> $ i { unimplemented!() }
- )
- }
-"#,
- )
- .assert_expand_items("foo! { Baz<u8> }", "fn bar () -> Baz < u8 > {unimplemented ! ()}");
-}
-
-#[test]
-fn test_ty_with_complex_type() {
- parse_macro(
- r#"
- macro_rules! foo {
- ($ i:ty) => (
- fn bar() -> $ i { unimplemented!() }
- )
- }
-"#,
- )
- // Reference lifetime struct with generic type
- .assert_expand_items(
- "foo! { &'a Baz<u8> }",
- "fn bar () -> & 'a Baz < u8 > {unimplemented ! ()}",
- )
- // extern "Rust" func type
- .assert_expand_items(
- r#"foo! { extern "Rust" fn() -> Ret }"#,
- r#"fn bar () -> extern "Rust" fn () -> Ret {unimplemented ! ()}"#,
- );
-}
-
-#[test]
-fn test_pat_() {
- parse_macro(
- r#"
- macro_rules! foo {
- ($ i:pat) => { fn foo() { let $ i; } }
- }
-"#,
- )
- .assert_expand_items("foo! { (a, b) }", "fn foo () {let (a , b) ;}");
-}
-
-#[test]
-fn test_stmt() {
- parse_macro(
- r#"
- macro_rules! foo {
- ($ i:stmt) => (
- fn bar() { $ i; }
- )
- }
-"#,
- )
- .assert_expand_items("foo! { 2 }", "fn bar () {2 ;}")
- .assert_expand_items("foo! { let a = 0 }", "fn bar () {let a = 0 ;}");
-}
-
-#[test]
-fn test_single_item() {
- parse_macro(
- r#"
- macro_rules! foo {
- ($ i:item) => (
- $ i
- )
- }
-"#,
- )
- .assert_expand_items("foo! {mod c {}}", "mod c {}");
-}
-
-#[test]
-fn test_all_items() {
- parse_macro(
- r#"
- macro_rules! foo {
- ($ ($ i:item)*) => ($ (
- $ i
- )*)
- }
-"#,
- ).
- assert_expand_items(
- r#"
- foo! {
- extern crate a;
- mod b;
- mod c {}
- use d;
- const E: i32 = 0;
- static F: i32 = 0;
- impl G {}
- struct H;
- enum I { Foo }
- trait J {}
- fn h() {}
- extern {}
- type T = u8;
- }
-"#,
- r#"extern crate a ; mod b ; mod c {} use d ; const E : i32 = 0 ; static F : i32 = 0 ; impl G {} struct H ; enum I {Foo} trait J {} fn h () {} extern {} type T = u8 ;"#,
- );
-}
-
-#[test]
-fn test_block() {
- parse_macro(
- r#"
- macro_rules! foo {
- ($ i:block) => { fn foo() $ i }
- }
-"#,
- )
- .assert_expand_statements("foo! { { 1; } }", "fn foo () {1 ;}");
-}
-
-#[test]
-fn test_meta() {
- parse_macro(
- r#"
- macro_rules! foo {
- ($ i:meta) => (
- #[$ i]
- fn bar() {}
- )
- }
-"#,
- )
- .assert_expand_items(
- r#"foo! { cfg(target_os = "windows") }"#,
- r#"# [cfg (target_os = "windows")] fn bar () {}"#,
- )
- .assert_expand_items(r#"foo! { hello::world }"#, r#"# [hello :: world] fn bar () {}"#);
-}
-
-#[test]
-fn test_meta_doc_comments() {
- parse_macro(
- r#"
- macro_rules! foo {
- ($(#[$ i:meta])+) => (
- $(#[$ i])+
- fn bar() {}
- )
- }
-"#,
- ).
- assert_expand_items(
- r#"foo! {
- /// Single Line Doc 1
- /**
- MultiLines Doc
- */
- }"#,
- "# [doc = \" Single Line Doc 1\"] # [doc = \"\\n MultiLines Doc\\n \"] fn bar () {}",
- );
-}
-
-#[test]
-fn test_meta_extended_key_value_attributes() {
- parse_macro(
- r#"
-macro_rules! foo {
- (#[$i:meta]) => (
- #[$ i]
- fn bar() {}
- )
-}
-"#,
- )
- .assert_expand_items(
- r#"foo! { #[doc = concat!("The `", "bla", "` lang item.")] }"#,
- r#"# [doc = concat ! ("The `" , "bla" , "` lang item.")] fn bar () {}"#,
- );
-}
-
-#[test]
-fn test_meta_doc_comments_non_latin() {
- parse_macro(
- r#"
- macro_rules! foo {
- ($(#[$ i:meta])+) => (
- $(#[$ i])+
- fn bar() {}
- )
- }
-"#,
- ).
- assert_expand_items(
- r#"foo! {
- /// 錦瑟無端五十弦,一弦一柱思華年。
- /**
- 莊生曉夢迷蝴蝶,望帝春心託杜鵑。
- */
- }"#,
- "# [doc = \" 錦瑟無端五十弦,一弦一柱思華年。\"] # [doc = \"\\n 莊生曉夢迷蝴蝶,望帝春心託杜鵑。\\n \"] fn bar () {}",
- );
-}
-
-#[test]
-fn test_meta_doc_comments_escaped_characters() {
- parse_macro(
- r#"
- macro_rules! foo {
- ($(#[$ i:meta])+) => (
- $(#[$ i])+
- fn bar() {}
- )
- }
-"#,
- )
- .assert_expand_items(
- r#"foo! {
- /// \ " '
- }"#,
- r#"# [doc = " \\ \" \'"] fn bar () {}"#,
- );
-}
-
-#[test]
-fn test_tt_block() {
- parse_macro(
- r#"
- macro_rules! foo {
- ($ i:tt) => { fn foo() $ i }
- }
- "#,
- )
- .assert_expand_items(r#"foo! { { 1; } }"#, r#"fn foo () {1 ;}"#);
-}
-
-#[test]
-fn test_tt_group() {
- parse_macro(
- r#"
- macro_rules! foo {
- ($($ i:tt)*) => { $($ i)* }
- }
- "#,
- )
- .assert_expand_items(r#"foo! { fn foo() {} }"#, r#"fn foo () {}"#);
-}
-
-#[test]
-fn test_tt_composite() {
- parse_macro(
- r#"
- macro_rules! foo {
- ($i:tt) => { 0 }
- }
- "#,
- )
- .assert_expand_items(r#"foo! { => }"#, r#"0"#);
-}
-
-#[test]
-fn test_tt_composite2() {
- let node = parse_macro(
- r#"
- macro_rules! foo {
- ($($tt:tt)*) => { abs!(=> $($tt)*) }
- }
- "#,
- )
- .expand_items(r#"foo!{#}"#);
-
- let res = format!("{:#?}", &node);
- assert_eq_text!(
- res.trim()
- );
-}
-
-#[test]
-fn test_tt_with_composite_without_space() {
- parse_macro(
- r#"
- macro_rules! foo {
- ($ op:tt, $j:path) => (
- 0
- )
- }
-"#,
- )
- // Test macro input without any spaces
- // See https://github.com/rust-analyzer/rust-analyzer/issues/6692
- .assert_expand_items("foo!(==,Foo::Bool)", "0");
-}
-
-#[test]
fn test_underscore() {
parse_macro(
r#"