Unnamed repository; edit this file 'description' to name the repository.
Diffstat (limited to 'crates/hir-def/src/macro_expansion_tests/mbe/metavar_expr.rs')
-rw-r--r--crates/hir-def/src/macro_expansion_tests/mbe/metavar_expr.rs220
1 files changed, 220 insertions, 0 deletions
diff --git a/crates/hir-def/src/macro_expansion_tests/mbe/metavar_expr.rs b/crates/hir-def/src/macro_expansion_tests/mbe/metavar_expr.rs
index ae138529ea..967b5ad36b 100644
--- a/crates/hir-def/src/macro_expansion_tests/mbe/metavar_expr.rs
+++ b/crates/hir-def/src/macro_expansion_tests/mbe/metavar_expr.rs
@@ -89,3 +89,223 @@ const _: i32 = -0--1--2;
"#]],
);
}
+
+#[test]
+fn count_basic() {
+ check(
+ r#"
+macro_rules! m {
+ ($($t:ident),*) => {
+ ${count(t)}
+ }
+}
+
+fn test() {
+ m!();
+ m!(a);
+ m!(a, a);
+}
+"#,
+ expect![[r#"
+macro_rules! m {
+ ($($t:ident),*) => {
+ ${count(t)}
+ }
+}
+
+fn test() {
+ 0;
+ 1;
+ 2;
+}
+"#]],
+ );
+}
+
+#[test]
+fn count_with_depth() {
+ check(
+ r#"
+macro_rules! foo {
+ ($( $( $($t:ident)* ),* );*) => {
+ $(
+ {
+ let depth_none = ${count(t)};
+ let depth_zero = ${count(t, 0)};
+ let depth_one = ${count(t, 1)};
+ }
+ )*
+ }
+}
+
+fn bar() {
+ foo!(
+ a a a, a, a a;
+ a a a
+ )
+}
+"#,
+ expect![[r#"
+macro_rules! foo {
+ ($( $( $($t:ident)* ),* );*) => {
+ $(
+ {
+ let depth_none = ${count(t)};
+ let depth_zero = ${count(t, 0)};
+ let depth_one = ${count(t, 1)};
+ }
+ )*
+ }
+}
+
+fn bar() {
+ {
+ let depth_none = 6;
+ let depth_zero = 3;
+ let depth_one = 6;
+ } {
+ let depth_none = 3;
+ let depth_zero = 1;
+ let depth_one = 3;
+ }
+}
+"#]],
+ );
+}
+
+#[test]
+fn count_depth_out_of_bounds() {
+ check(
+ r#"
+macro_rules! foo {
+ ($($t:ident)*) => { ${count(t, 1)} };
+ ($( $( $l:literal )* );*) => { $(${count(l, 1)};)* }
+}
+macro_rules! bar {
+ ($($t:ident)*) => { ${count(t, 1024)} };
+ ($( $( $l:literal )* );*) => { $(${count(l, 8192)};)* }
+}
+
+fn test() {
+ foo!(a b);
+ foo!(1 2; 3);
+ bar!(a b);
+ bar!(1 2; 3);
+}
+"#,
+ expect![[r#"
+macro_rules! foo {
+ ($($t:ident)*) => { ${count(t, 1)} };
+ ($( $( $l:literal )* );*) => { $(${count(l, 1)};)* }
+}
+macro_rules! bar {
+ ($($t:ident)*) => { ${count(t, 1024)} };
+ ($( $( $l:literal )* );*) => { $(${count(l, 8192)};)* }
+}
+
+fn test() {
+ /* error: ${count} out of bounds */;
+ /* error: ${count} out of bounds */;
+ /* error: ${count} out of bounds */;
+ /* error: ${count} out of bounds */;
+}
+"#]],
+ );
+}
+
+#[test]
+fn misplaced_count() {
+ check(
+ r#"
+macro_rules! foo {
+ ($($t:ident)*) => { $(${count(t)})* };
+ ($l:literal) => { ${count(l)} }
+}
+
+fn test() {
+ foo!(a b c);
+ foo!(1);
+}
+"#,
+ expect![[r#"
+macro_rules! foo {
+ ($($t:ident)*) => { $(${count(t)})* };
+ ($l:literal) => { ${count(l)} }
+}
+
+fn test() {
+ /* error: ${count} misplaced */;
+ /* error: ${count} misplaced */;
+}
+"#]],
+ );
+}
+
+#[test]
+fn malformed_count() {
+ check(
+ r#"
+macro_rules! too_many_args {
+ ($($t:ident)*) => { ${count(t, 1, leftover)} }
+}
+macro_rules! depth_suffixed {
+ ($($t:ident)*) => { ${count(t, 0usize)} }
+}
+macro_rules! depth_too_large {
+ ($($t:ident)*) => { ${count(t, 18446744073709551616)} }
+}
+
+fn test() {
+ too_many_args!();
+ depth_suffixed!();
+ depth_too_large!();
+}
+"#,
+ expect![[r#"
+macro_rules! too_many_args {
+ ($($t:ident)*) => { ${count(t, 1, leftover)} }
+}
+macro_rules! depth_suffixed {
+ ($($t:ident)*) => { ${count(t, 0usize)} }
+}
+macro_rules! depth_too_large {
+ ($($t:ident)*) => { ${count(t, 18446744073709551616)} }
+}
+
+fn test() {
+ /* error: invalid macro definition: invalid metavariable expression */;
+ /* error: invalid macro definition: invalid metavariable expression */;
+ /* error: invalid macro definition: invalid metavariable expression */;
+}
+"#]],
+ );
+}
+
+#[test]
+fn count_interaction_with_empty_binding() {
+ // FIXME: Should this error? rustc currently accepts it.
+ check(
+ r#"
+macro_rules! m {
+ ($($t:ident),*) => {
+ ${count(t, 100)}
+ }
+}
+
+fn test() {
+ m!();
+}
+"#,
+ expect![[r#"
+macro_rules! m {
+ ($($t:ident),*) => {
+ ${count(t, 100)}
+ }
+}
+
+fn test() {
+ 0;
+}
+"#]],
+ );
+}