diff --git a/crates/hir_def/src/macro_expansion_tests.rs b/crates/hir_def/src/macro_expansion_tests.rs index 76bd0299fb4..96957471c83 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}, + SyntaxKind::{self, IDENT, LIFETIME_IDENT}, SyntaxNode, T, }; @@ -102,8 +102,9 @@ fn pretty_print_macro_expansion(expn: SyntaxNode) -> String { let space = match (prev_kind, curr_kind) { _ if prev_kind.is_trivia() || curr_kind.is_trivia() => "", (T![=], _) | (_, T![=]) => " ", - (T![;], _) => "\n", - (IDENT, IDENT) => " ", + (_, T!['{']) => " ", + (T![;] | T!['}'], _) => "\n", + (IDENT | LIFETIME_IDENT, IDENT | LIFETIME_IDENT) => " ", (IDENT, _) if curr_kind.is_keyword() => " ", (_, IDENT) 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 cc6551f8aa6..c57e9cd838d 100644 --- a/crates/hir_def/src/macro_expansion_tests/mbe.rs +++ b/crates/hir_def/src/macro_expansion_tests/mbe.rs @@ -46,3 +46,116 @@ macro_rules! m { "#]], ); } + +#[test] +fn match_by_first_token_literally() { + check( + r#" +macro_rules! m { + ($ i:ident) => ( mod $ i {} ); + (= $ i:ident) => ( fn $ i() {} ); + (+ $ i:ident) => ( struct $ i; ) +} +m! { foo } +m! { = bar } +m! { + Baz } +"#, + expect![[r#" +macro_rules! m { + ($ i:ident) => ( mod $ i {} ); + (= $ i:ident) => ( fn $ i() {} ); + (+ $ i:ident) => ( struct $ i; ) +} +mod foo {} +fn bar() {} +struct Baz; +"#]], + ); +} + +#[test] +fn match_by_last_token_literally() { + check( + r#" +macro_rules! m { + ($ i:ident) => ( mod $ i {} ); + ($ i:ident =) => ( fn $ i() {} ); + ($ i:ident +) => ( struct $ i; ) +} +m! { foo } +m! { bar = } +m! { Baz + } +"#, + expect![[r#" +macro_rules! m { + ($ i:ident) => ( mod $ i {} ); + ($ i:ident =) => ( fn $ i() {} ); + ($ i:ident +) => ( struct $ i; ) +} +mod foo {} +fn bar() {} +struct Baz; +"#]], + ); +} + +#[test] +fn match_by_ident() { + check( + r#" +macro_rules! m { + ($ i:ident) => ( mod $ i {} ); + (spam $ i:ident) => ( fn $ i() {} ); + (eggs $ i:ident) => ( struct $ i; ) +} +m! { foo } +m! { spam bar } +m! { eggs Baz } +"#, + expect![[r#" +macro_rules! m { + ($ i:ident) => ( mod $ i {} ); + (spam $ i:ident) => ( fn $ i() {} ); + (eggs $ i:ident) => ( struct $ i; ) +} +mod foo {} +fn bar() {} +struct Baz; +"#]], + ); +} + +#[test] +fn match_by_separator_token() { + check( + r#" +macro_rules! m { + ($ ($ i:ident),*) => ($ ( mod $ i {} )*); + ($ ($ i:ident)#*) => ($ ( fn $ i() {} )*); + ($ i:ident ,# $ j:ident) => ( struct $ i; struct $ j; ) +} + +m! { foo, bar } + +m! { foo# bar } + +m! { Foo,# Bar } +"#, + expect![[r##" +macro_rules! m { + ($ ($ i:ident),*) => ($ ( mod $ i {} )*); + ($ ($ i:ident)#*) => ($ ( fn $ i() {} )*); + ($ i:ident ,# $ j:ident) => ( struct $ i; struct $ j; ) +} + +mod foo {} +mod bar {} + +fn foo() {} +fn bar() {} + +struct Foo; +struct Bar; +"##]], + ); +} 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 a24fe9bee2c..3450cda3fda 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 @@ -63,6 +63,24 @@ fn f() { ); } +#[test] +fn roundtrip_lifetime() { + check( + r#" +macro_rules! m { + ($($t:tt)*) => { $($t)*} +} +m!(static bar: &'static str = "hello";); +"#, + expect![[r#" +macro_rules! m { + ($($t:tt)*) => { $($t)*} +} +static bar: & 'static str = "hello"; +"#]], + ); +} + #[test] fn broken_parenthesis_sequence() { check( diff --git a/crates/mbe/src/tests/expand.rs b/crates/mbe/src/tests/expand.rs index df374aea981..7becaa6658f 100644 --- a/crates/mbe/src/tests/expand.rs +++ b/crates/mbe/src/tests/expand.rs @@ -166,33 +166,6 @@ SUBTREE $ ); } -#[test] -fn test_lifetime_split() { - parse_macro( - r#" -macro_rules! foo { - ($($t:tt)*) => { $($t)*} -} -"#, - ) - .assert_expand( - r#"foo!(static bar: &'static str = "hello";);"#, - r#" -SUBTREE $ - IDENT static 17 - IDENT bar 18 - PUNCH : [alone] 19 - PUNCH & [alone] 20 - PUNCH ' [joint] 21 - IDENT static 22 - IDENT str 23 - PUNCH = [alone] 24 - LITERAL "hello" 25 - PUNCH ; [joint] 26 -"#, - ); -} - #[test] fn test_expr_order() { let expanded = parse_macro( @@ -236,95 +209,6 @@ fn test_expr_order() { ); } -#[test] -fn test_fail_match_pattern_by_first_token() { - parse_macro( - r#" - macro_rules! foo { - ($ i:ident) => ( - mod $ i {} - ); - (= $ i:ident) => ( - fn $ i() {} - ); - (+ $ i:ident) => ( - struct $ i; - ) - } -"#, - ) - .assert_expand_items("foo! { foo }", "mod foo {}") - .assert_expand_items("foo! { = bar }", "fn bar () {}") - .assert_expand_items("foo! { + Baz }", "struct Baz ;"); -} - -#[test] -fn test_fail_match_pattern_by_last_token() { - parse_macro( - r#" - macro_rules! foo { - ($ i:ident) => ( - mod $ i {} - ); - ($ i:ident =) => ( - fn $ i() {} - ); - ($ i:ident +) => ( - struct $ i; - ) - } -"#, - ) - .assert_expand_items("foo! { foo }", "mod foo {}") - .assert_expand_items("foo! { bar = }", "fn bar () {}") - .assert_expand_items("foo! { Baz + }", "struct Baz ;"); -} - -#[test] -fn test_fail_match_pattern_by_word_token() { - parse_macro( - r#" - macro_rules! foo { - ($ i:ident) => ( - mod $ i {} - ); - (spam $ i:ident) => ( - fn $ i() {} - ); - (eggs $ i:ident) => ( - struct $ i; - ) - } -"#, - ) - .assert_expand_items("foo! { foo }", "mod foo {}") - .assert_expand_items("foo! { spam bar }", "fn bar () {}") - .assert_expand_items("foo! { eggs Baz }", "struct Baz ;"); -} - -#[test] -fn test_match_group_pattern_by_separator_token() { - parse_macro( - r#" - macro_rules! foo { - ($ ($ i:ident),*) => ($ ( - mod $ i {} - )*); - ($ ($ i:ident)#*) => ($ ( - fn $ i() {} - )*); - ($ i:ident ,# $ j:ident) => ( - struct $ i; - struct $ j; - ) - } -"#, - ) - .assert_expand_items("foo! { foo, bar }", "mod foo {} mod bar {}") - .assert_expand_items("foo! { foo# bar }", "fn foo () {} fn bar () {}") - .assert_expand_items("foo! { Foo,# Bar }", "struct Foo ; struct Bar ;"); -} - #[test] fn test_match_group_pattern_with_multiple_defs() { parse_macro(