about summary refs log tree commit diff
path: root/tests/ui/macros/metavar-expressions/feature-gate-macro_metavar_expr.rs
diff options
context:
space:
mode:
Diffstat (limited to 'tests/ui/macros/metavar-expressions/feature-gate-macro_metavar_expr.rs')
-rw-r--r--tests/ui/macros/metavar-expressions/feature-gate-macro_metavar_expr.rs147
1 files changed, 147 insertions, 0 deletions
diff --git a/tests/ui/macros/metavar-expressions/feature-gate-macro_metavar_expr.rs b/tests/ui/macros/metavar-expressions/feature-gate-macro_metavar_expr.rs
new file mode 100644
index 00000000000..51445221c57
--- /dev/null
+++ b/tests/ui/macros/metavar-expressions/feature-gate-macro_metavar_expr.rs
@@ -0,0 +1,147 @@
+//@ run-pass
+
+#![feature(macro_metavar_expr)]
+
+/// Count the number of idents in a macro repetition.
+macro_rules! count_idents {
+    ( $( $i:ident ),* ) => {
+        ${count($i)}
+    };
+}
+
+/// Count the number of idents in a 2-dimensional macro repetition.
+macro_rules! count_idents_2 {
+    ( $( [ $( $i:ident ),* ] ),* ) => {
+        ${count($i)}
+    };
+}
+
+/// Mostly counts the number of OUTER-MOST repetitions
+macro_rules! count_depth_limits {
+    ( $( { $( [ $( $outer:ident : ( $( $inner:ident )* ) )* ] )* } )* ) => {
+        (
+            (
+                ${count($inner)},
+                ${count($inner, 0)},
+                ${count($inner, 1)},
+                ${count($inner, 2)},
+                ${count($inner, 3)},
+            ),
+            (
+                ${count($outer)},
+                ${count($outer, 0)},
+                ${count($outer, 1)},
+                ${count($outer, 2)},
+            ),
+        )
+    };
+}
+
+/// Produce (index, len) pairs for literals in a macro repetition.
+/// The literal is not included in the output, so this macro uses the
+/// `ignore` meta-variable expression to create a non-expanding
+/// repetition binding.
+macro_rules! enumerate_literals {
+    ( $( ($l:stmt) ),* ) => {
+        [$( ${ignore($l)} (${index()}, ${len()}) ),*]
+    };
+}
+
+/// Produce index and len tuples for literals in a 2-dimensional
+/// macro repetition.
+macro_rules! enumerate_literals_2 {
+    ( $( [ $( ($l:literal) ),* ] ),* ) => {
+        [
+            $(
+                $(
+                    (
+                        ${index(1)},
+                        ${len(1)},
+                        ${index(0)},
+                        ${len(0)},
+                        $l
+                    ),
+                )*
+            )*
+        ]
+    };
+}
+
+/// Generate macros that count idents and then add a constant number
+/// to the count.
+///
+/// This macro uses dollar escaping to make it unambiguous as to which
+/// macro the repetition belongs to.
+macro_rules! make_count_adders {
+    ( $( $i:ident, $b:literal );* ) => {
+        $(
+            macro_rules! $i {
+                ( $$( $$j:ident ),* ) => {
+                    $b + $${count($j)}
+                };
+            }
+        )*
+    };
+}
+
+make_count_adders! { plus_one, 1; plus_five, 5 }
+
+/// Generate a macro that allows selection of a particular literal
+/// from a sequence of inputs by their identifier.
+///
+/// This macro uses dollar escaping to make it unambiguous as to which
+/// macro the repetition belongs to, and to allow expansion of an
+/// identifier the name of which is not known in the definition
+/// of `make_picker`.
+macro_rules! make_picker {
+    ( $m:ident => $( $i:ident ),* ; $p:ident ) => {
+        macro_rules! $m {
+            ( $( $$ $i:literal ),* ) => {
+                $$ $p
+            };
+        }
+    };
+}
+
+make_picker!(first => a, b; a);
+
+make_picker!(second => a, b; b);
+
+fn main() {
+    assert_eq!(count_idents!(a, b, c), 3);
+    assert_eq!(count_idents_2!([a, b, c], [d, e], [f]), 6);
+    assert_eq!(
+        count_depth_limits! {
+            {
+                [ A: (a b c) D: (d e f) ]
+                [ G: (g h) I: (i j k l m) ]
+                [ N: (n) ]
+            }
+            {
+                [ O: (o) P: (p q) R: (r s) ]
+                [ T: (t u v w x y z) ]
+            }
+        },
+        ((26, 26, 9, 5, 2), (9, 9, 5, 2))
+    );
+    assert_eq!(enumerate_literals![("foo"), ("bar")], [(0, 2), (1, 2)]);
+    assert_eq!(
+        enumerate_literals_2![
+            [("foo"), ("bar"), ("baz")],
+            [("qux"), ("quux"), ("quuz"), ("xyzzy")]
+        ],
+        [
+            (0, 2, 0, 3, "foo"),
+            (0, 2, 1, 3, "bar"),
+            (0, 2, 2, 3, "baz"),
+            (1, 2, 0, 4, "qux"),
+            (1, 2, 1, 4, "quux"),
+            (1, 2, 2, 4, "quuz"),
+            (1, 2, 3, 4, "xyzzy"),
+        ]
+    );
+    assert_eq!(plus_one!(a, b, c), 4);
+    assert_eq!(plus_five!(a, b), 7);
+    assert_eq!(first!(1, 2), 1);
+    assert_eq!(second!(1, 2), 2);
+}