diff --git a/crates/hir_def/src/macro_expansion_tests/mbe.rs b/crates/hir_def/src/macro_expansion_tests/mbe.rs index df93298a356..dcd0a8880b8 100644 --- a/crates/hir_def/src/macro_expansion_tests/mbe.rs +++ b/crates/hir_def/src/macro_expansion_tests/mbe.rs @@ -1119,3 +1119,69 @@ ok!(); "#]], ); } + +#[test] +fn test_underscore() { + check( + r#" +macro_rules! m { ($_:tt) => { ok!(); } } +m! { => } +"#, + expect![[r#" +macro_rules! m { ($_:tt) => { ok!(); } } +ok!(); +"#]], + ); +} + +#[test] +fn test_underscore_not_greedily() { + check( + r#" +// `_` overlaps with `$a:ident` but rustc matches it under the `_` token. +macro_rules! m1 { + ($($a:ident)* _) => { ok!(); } +} +m1![a b c d _]; + +// `_ => ou` overlaps with `$a:expr => $b:ident` but rustc matches it under `_ => $c:expr`. +macro_rules! m2 { + ($($a:expr => $b:ident)* _ => $c:expr) => { ok!(); } +} +m2![a => b c => d _ => ou] +"#, + expect![[r#" +// `_` overlaps with `$a:ident` but rustc matches it under the `_` token. +macro_rules! m1 { + ($($a:ident)* _) => { ok!(); } +} +ok!(); + +// `_ => ou` overlaps with `$a:expr => $b:ident` but rustc matches it under `_ => $c:expr`. +macro_rules! m2 { + ($($a:expr => $b:ident)* _ => $c:expr) => { ok!(); } +} +ok!(); +"#]], + ); +} + +#[test] +fn test_underscore_flavors() { + check( + r#" +macro_rules! m1 { ($a:ty) => { ok!(); } } +m1![_]; + +macro_rules! m2 { ($a:lifetime) => { ok!(); } } +m2!['_]; +"#, + expect![[r#" +macro_rules! m1 { ($a:ty) => { ok!(); } } +ok!(); + +macro_rules! m2 { ($a:lifetime) => { ok!(); } } +ok!(); +"#]], + ); +} diff --git a/crates/mbe/src/tests/expand.rs b/crates/mbe/src/tests/expand.rs index 15a71840291..52a218ed116 100644 --- a/crates/mbe/src/tests/expand.rs +++ b/crates/mbe/src/tests/expand.rs @@ -101,60 +101,6 @@ fn test_attr_to_token_tree() { ); } -#[test] -fn test_underscore() { - parse_macro( - r#" - macro_rules! foo { - ($_:tt) => { 0 } - } - "#, - ) - .assert_expand_items(r#"foo! { => }"#, r#"0"#); -} - -#[test] -fn test_underscore_not_greedily() { - parse_macro( - r#" -macro_rules! q { - ($($a:ident)* _) => {0}; -} -"#, - ) - // `_` overlaps with `$a:ident` but rustc matches it under the `_` token - .assert_expand_items(r#"q![a b c d _]"#, r#"0"#); - - parse_macro( - r#" -macro_rules! q { - ($($a:expr => $b:ident)* _ => $c:expr) => {0}; -} -"#, - ) - // `_ => ou` overlaps with `$a:expr => $b:ident` but rustc matches it under `_ => $c:expr` - .assert_expand_items(r#"q![a => b c => d _ => ou]"#, r#"0"#); -} - -#[test] -fn test_underscore_as_type() { - parse_macro( - r#" -macro_rules! q { - ($a:ty) => {0}; -} -"#, - ) - // Underscore is a type - .assert_expand_items(r#"q![_]"#, r#"0"#); -} - -#[test] -fn test_underscore_lifetime() { - parse_macro(r#"macro_rules! q { ($a:lifetime) => {0}; }"#) - .assert_expand_items(r#"q!['_]"#, r#"0"#); -} - #[test] fn test_vertical_bar_with_pat() { parse_macro( diff --git a/crates/test_utils/src/fixture.rs b/crates/test_utils/src/fixture.rs index 5ea7a994b4f..3d303a1237d 100644 --- a/crates/test_utils/src/fixture.rs +++ b/crates/test_utils/src/fixture.rs @@ -147,6 +147,7 @@ impl Fixture { if line.starts_with("// ") && line.contains(':') && !line.contains("::") + && !line.contains(".") && line.chars().all(|it| !it.is_uppercase()) { panic!("looks like invalid metadata line: {:?}", line);