mirror of
https://github.com/rust-lang/rust.git
synced 2025-01-26 06:35:27 +00:00
Rollup merge of #94833 - c410-f3r:meta-take-2, r=petrochenkov
[2/2] Implement macro meta-variable expression Final part of https://github.com/rust-lang/rust/pull/93545#issuecomment-1050963295 r? `@petrochenkov`
This commit is contained in:
commit
8c87132103
@ -1,15 +1,15 @@
|
||||
use crate::base::ExtCtxt;
|
||||
use crate::mbe;
|
||||
use crate::mbe::macro_parser::{MatchedNonterminal, MatchedSeq, NamedMatch};
|
||||
|
||||
use crate::mbe::{self, MetaVarExpr};
|
||||
use rustc_ast::mut_visit::{self, MutVisitor};
|
||||
use rustc_ast::token::{self, NtTT, Token};
|
||||
use rustc_ast::token::{self, NtTT, Token, TokenKind};
|
||||
use rustc_ast::tokenstream::{DelimSpan, TokenStream, TokenTree, TreeAndSpacing};
|
||||
use rustc_data_structures::fx::FxHashMap;
|
||||
use rustc_data_structures::sync::Lrc;
|
||||
use rustc_errors::{pluralize, PResult};
|
||||
use rustc_errors::{DiagnosticBuilder, ErrorGuaranteed};
|
||||
use rustc_span::hygiene::{LocalExpnId, Transparency};
|
||||
use rustc_span::symbol::MacroRulesNormalizedIdent;
|
||||
use rustc_span::symbol::{sym, Ident, MacroRulesNormalizedIdent};
|
||||
use rustc_span::Span;
|
||||
|
||||
use smallvec::{smallvec, SmallVec};
|
||||
@ -411,13 +411,150 @@ fn lockstep_iter_size(
|
||||
}
|
||||
}
|
||||
|
||||
/// Used solely by the `count` meta-variable expression, counts the outer-most repetitions at a
|
||||
/// given optional nested depth.
|
||||
///
|
||||
/// For example, a macro parameter of `$( { $( $foo:ident ),* } )*` called with `{ a, b } { c }`:
|
||||
///
|
||||
/// * `[ $( ${count(foo)} ),* ]` will return [2, 1] with a, b = 2 and c = 1
|
||||
/// * `[ $( ${count(foo, 0)} ),* ]` will be the same as `[ $( ${count(foo)} ),* ]`
|
||||
/// * `[ $( ${count(foo, 1)} ),* ]` will return an error because `${count(foo, 1)}` is
|
||||
/// declared inside a single repetition and the index `1` implies two nested repetitions.
|
||||
fn count_repetitions<'a>(
|
||||
cx: &ExtCtxt<'a>,
|
||||
depth_opt: Option<usize>,
|
||||
mut matched: &NamedMatch,
|
||||
repeats: &[(usize, usize)],
|
||||
sp: &DelimSpan,
|
||||
) -> PResult<'a, usize> {
|
||||
// Recursively count the number of matches in `matched` at given depth
|
||||
// (or at the top-level of `matched` if no depth is given).
|
||||
fn count<'a>(
|
||||
cx: &ExtCtxt<'a>,
|
||||
declared_lhs_depth: usize,
|
||||
depth_opt: Option<usize>,
|
||||
matched: &NamedMatch,
|
||||
sp: &DelimSpan,
|
||||
) -> PResult<'a, usize> {
|
||||
match matched {
|
||||
MatchedNonterminal(_) => {
|
||||
if declared_lhs_depth == 0 {
|
||||
return Err(cx.struct_span_err(
|
||||
sp.entire(),
|
||||
"`count` can not be placed inside the inner-most repetition",
|
||||
));
|
||||
}
|
||||
match depth_opt {
|
||||
None => Ok(1),
|
||||
Some(_) => Err(out_of_bounds_err(cx, declared_lhs_depth, sp.entire(), "count")),
|
||||
}
|
||||
}
|
||||
MatchedSeq(ref named_matches) => {
|
||||
let new_declared_lhs_depth = declared_lhs_depth + 1;
|
||||
match depth_opt {
|
||||
None => named_matches
|
||||
.iter()
|
||||
.map(|elem| count(cx, new_declared_lhs_depth, None, elem, sp))
|
||||
.sum(),
|
||||
Some(0) => Ok(named_matches.len()),
|
||||
Some(depth) => named_matches
|
||||
.iter()
|
||||
.map(|elem| count(cx, new_declared_lhs_depth, Some(depth - 1), elem, sp))
|
||||
.sum(),
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// `repeats` records all of the nested levels at which we are currently
|
||||
// matching meta-variables. The meta-var-expr `count($x)` only counts
|
||||
// matches that occur in this "subtree" of the `NamedMatch` where we
|
||||
// are currently transcribing, so we need to descend to that subtree
|
||||
// before we start counting. `matched` contains the various levels of the
|
||||
// tree as we descend, and its final value is the subtree we are currently at.
|
||||
for &(idx, _) in repeats {
|
||||
if let MatchedSeq(ref ads) = matched {
|
||||
matched = &ads[idx];
|
||||
}
|
||||
}
|
||||
count(cx, 0, depth_opt, matched, sp)
|
||||
}
|
||||
|
||||
/// Returns a `NamedMatch` item declared on the RHS given an arbitrary [Ident]
|
||||
fn matched_from_ident<'ctx, 'interp, 'rslt>(
|
||||
cx: &ExtCtxt<'ctx>,
|
||||
ident: Ident,
|
||||
interp: &'interp FxHashMap<MacroRulesNormalizedIdent, NamedMatch>,
|
||||
) -> PResult<'ctx, &'rslt NamedMatch>
|
||||
where
|
||||
'interp: 'rslt,
|
||||
{
|
||||
let span = ident.span;
|
||||
let key = MacroRulesNormalizedIdent::new(ident);
|
||||
interp.get(&key).ok_or_else(|| {
|
||||
cx.struct_span_err(
|
||||
span,
|
||||
&format!("variable `{}` is not recognized in meta-variable expression", key),
|
||||
)
|
||||
})
|
||||
}
|
||||
|
||||
/// Used by meta-variable expressions when an user input is out of the actual declared bounds. For
|
||||
/// example, index(999999) in an repetition of only three elements.
|
||||
fn out_of_bounds_err<'a>(
|
||||
cx: &ExtCtxt<'a>,
|
||||
max: usize,
|
||||
span: Span,
|
||||
ty: &str,
|
||||
) -> DiagnosticBuilder<'a, ErrorGuaranteed> {
|
||||
cx.struct_span_err(span, &format!("{ty} depth must be less than {max}"))
|
||||
}
|
||||
|
||||
fn transcribe_metavar_expr<'a>(
|
||||
_cx: &ExtCtxt<'a>,
|
||||
_expr: mbe::MetaVarExpr,
|
||||
_interp: &FxHashMap<MacroRulesNormalizedIdent, NamedMatch>,
|
||||
_repeats: &[(usize, usize)],
|
||||
_result: &mut Vec<TreeAndSpacing>,
|
||||
_sp: &DelimSpan,
|
||||
cx: &ExtCtxt<'a>,
|
||||
expr: MetaVarExpr,
|
||||
interp: &FxHashMap<MacroRulesNormalizedIdent, NamedMatch>,
|
||||
repeats: &[(usize, usize)],
|
||||
result: &mut Vec<TreeAndSpacing>,
|
||||
sp: &DelimSpan,
|
||||
) -> PResult<'a, ()> {
|
||||
match expr {
|
||||
MetaVarExpr::Count(original_ident, depth_opt) => {
|
||||
let matched = matched_from_ident(cx, original_ident, interp)?;
|
||||
let count = count_repetitions(cx, depth_opt, matched, &repeats, sp)?;
|
||||
let tt = TokenTree::token(
|
||||
TokenKind::lit(token::Integer, sym::integer(count), None),
|
||||
sp.entire(),
|
||||
);
|
||||
result.push(tt.into());
|
||||
}
|
||||
MetaVarExpr::Ignore(original_ident) => {
|
||||
// Used to ensure that `original_ident` is present in the LHS
|
||||
let _ = matched_from_ident(cx, original_ident, interp)?;
|
||||
}
|
||||
MetaVarExpr::Index(depth) => match repeats.iter().nth_back(depth) {
|
||||
Some((index, _)) => {
|
||||
result.push(
|
||||
TokenTree::token(
|
||||
TokenKind::lit(token::Integer, sym::integer(*index), None),
|
||||
sp.entire(),
|
||||
)
|
||||
.into(),
|
||||
);
|
||||
}
|
||||
None => return Err(out_of_bounds_err(cx, repeats.len(), sp.entire(), "index")),
|
||||
},
|
||||
MetaVarExpr::Length(depth) => match repeats.iter().nth_back(depth) {
|
||||
Some((_, length)) => {
|
||||
result.push(
|
||||
TokenTree::token(
|
||||
TokenKind::lit(token::Integer, sym::integer(*length), None),
|
||||
sp.entire(),
|
||||
)
|
||||
.into(),
|
||||
);
|
||||
}
|
||||
None => return Err(out_of_bounds_err(cx, repeats.len(), sp.entire(), "length")),
|
||||
},
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
@ -0,0 +1,271 @@
|
||||
// run-pass
|
||||
|
||||
#![feature(macro_metavar_expr)]
|
||||
|
||||
fn main() {
|
||||
macro_rules! one_nested_count_and_length {
|
||||
( $( [ $( $l:literal ),* ] ),* ) => {
|
||||
[
|
||||
// outer-most repetition
|
||||
$(
|
||||
// inner-most repetition
|
||||
$(
|
||||
${ignore(l)} ${index()}, ${length()},
|
||||
)*
|
||||
${count(l)}, ${index()}, ${length()},
|
||||
)*
|
||||
${count(l)},
|
||||
]
|
||||
};
|
||||
}
|
||||
assert_eq!(
|
||||
one_nested_count_and_length!(["foo"], ["bar", "baz"]),
|
||||
[
|
||||
// # ["foo"]
|
||||
|
||||
// ## inner-most repetition (first iteration)
|
||||
//
|
||||
// `index` is 0 because this is the first inner-most iteration.
|
||||
// `length` is 1 because there is only one inner-most repetition, "foo".
|
||||
0, 1,
|
||||
|
||||
// ## outer-most repetition (first iteration)
|
||||
//
|
||||
// `count` is 1 because of "foo", i,e, `$l` has only one repetition,
|
||||
// `index` is 0 because this is the first outer-most iteration.
|
||||
// `length` is 2 because there are 2 outer-most repetitions, ["foo"] and ["bar", "baz"]
|
||||
1, 0, 2,
|
||||
|
||||
// # ["bar", "baz"]
|
||||
|
||||
// ## inner-most repetition (first iteration)
|
||||
//
|
||||
// `index` is 0 because this is the first inner-most iteration
|
||||
// `length` is 2 because there are repetitions, "bar" and "baz"
|
||||
0, 2,
|
||||
|
||||
// ## inner-most repetition (second iteration)
|
||||
//
|
||||
// `index` is 1 because this is the second inner-most iteration
|
||||
// `length` is 2 because there are repetitions, "bar" and "baz"
|
||||
1, 2,
|
||||
|
||||
// ## outer-most repetition (second iteration)
|
||||
//
|
||||
// `count` is 2 because of "bar" and "baz", i,e, `$l` has two repetitions,
|
||||
// `index` is 1 because this is the second outer-most iteration
|
||||
// `length` is 2 because there are 2 outer-most repetitions, ["foo"] and ["bar", "baz"]
|
||||
2, 1, 2,
|
||||
|
||||
// # last count
|
||||
|
||||
// Because there are a total of 3 repetitions of `$l`, "foo", "bar" and "baz"
|
||||
3,
|
||||
]
|
||||
);
|
||||
|
||||
// Based on the above explanation, the following macros should be straightforward
|
||||
|
||||
// Grouped from the outer-most to the inner-most
|
||||
macro_rules! three_nested_count {
|
||||
( $( { $( [ $( ( $( $i:ident )* ) )* ] )* } )* ) => {
|
||||
&[
|
||||
$( $( $(
|
||||
&[
|
||||
${ignore(i)} ${count(i, 0)},
|
||||
][..],
|
||||
)* )* )*
|
||||
|
||||
$( $(
|
||||
&[
|
||||
${ignore(i)} ${count(i, 0)},
|
||||
${ignore(i)} ${count(i, 1)},
|
||||
][..],
|
||||
)* )*
|
||||
|
||||
$(
|
||||
&[
|
||||
${ignore(i)} ${count(i, 0)},
|
||||
${ignore(i)} ${count(i, 1)},
|
||||
${ignore(i)} ${count(i, 2)},
|
||||
][..],
|
||||
)*
|
||||
|
||||
&[
|
||||
${count(i, 0)},
|
||||
${count(i, 1)},
|
||||
${count(i, 2)},
|
||||
${count(i, 3)},
|
||||
][..]
|
||||
][..]
|
||||
}
|
||||
}
|
||||
assert_eq!(
|
||||
three_nested_count!(
|
||||
{
|
||||
[ (a b c) (d e f) ]
|
||||
[ (g h) (i j k l m) ]
|
||||
[ (n) ]
|
||||
}
|
||||
{
|
||||
[ (o) (p q) (r s) ]
|
||||
[ (t u v w x y z) ]
|
||||
}
|
||||
),
|
||||
&[
|
||||
// a b c
|
||||
&[3][..],
|
||||
// d e f
|
||||
&[3][..],
|
||||
// g h
|
||||
&[2][..],
|
||||
// i j k l m
|
||||
&[5][..],
|
||||
// n
|
||||
&[1][..],
|
||||
// o
|
||||
&[1][..],
|
||||
// p q
|
||||
&[2][..],
|
||||
// r s
|
||||
&[2][..],
|
||||
// t u v w x y z
|
||||
&[7][..],
|
||||
|
||||
// (a b c) (d e f)
|
||||
&[2, 6][..],
|
||||
// (g h) (i j k l m)
|
||||
&[2, 7][..],
|
||||
// (n)
|
||||
&[1, 1][..],
|
||||
// (o) (p q) (r s)
|
||||
&[3, 5][..],
|
||||
// (t u v w x y z)
|
||||
&[1, 7][..],
|
||||
|
||||
// [ (a b c) (d e f) ]
|
||||
// [ (g h) (i j k l m) ]
|
||||
// [ (n) ]
|
||||
&[3, 5, 14][..],
|
||||
// [ (o) (p q) (r s) ]
|
||||
// [ (t u v w x y z) ]
|
||||
&[2, 4, 12][..],
|
||||
|
||||
// {
|
||||
// [ (a b c) (d e f) ]
|
||||
// [ (g h) (i j k l m) ]
|
||||
// [ (n) ]
|
||||
// }
|
||||
// {
|
||||
// [ (o) (p q) (r s) ]
|
||||
// [ (t u v w x y z) ]
|
||||
// }
|
||||
&[2, 5, 9, 26][..]
|
||||
][..]
|
||||
);
|
||||
|
||||
// Grouped from the outer-most to the inner-most
|
||||
macro_rules! three_nested_length {
|
||||
( $( { $( [ $( ( $( $i:ident )* ) )* ] )* } )* ) => {
|
||||
&[
|
||||
$( $( $( $(
|
||||
&[
|
||||
${ignore(i)} ${length(3)},
|
||||
${ignore(i)} ${length(2)},
|
||||
${ignore(i)} ${length(1)},
|
||||
${ignore(i)} ${length(0)},
|
||||
][..],
|
||||
)* )* )* )*
|
||||
|
||||
$( $( $(
|
||||
&[
|
||||
${ignore(i)} ${length(2)},
|
||||
${ignore(i)} ${length(1)},
|
||||
${ignore(i)} ${length(0)},
|
||||
][..],
|
||||
)* )* )*
|
||||
|
||||
$( $(
|
||||
&[
|
||||
${ignore(i)} ${length(1)},
|
||||
${ignore(i)} ${length(0)},
|
||||
][..],
|
||||
)* )*
|
||||
|
||||
$(
|
||||
&[
|
||||
${ignore(i)} ${length(0)},
|
||||
][..],
|
||||
)*
|
||||
][..]
|
||||
}
|
||||
}
|
||||
assert_eq!(
|
||||
three_nested_length!(
|
||||
{
|
||||
[ (a b c) (d e f) ]
|
||||
[ (g h) (i j k l m) ]
|
||||
[ (n) ]
|
||||
}
|
||||
{
|
||||
[ (o) (p q) (r s) ]
|
||||
[ (t u v w x y z) ]
|
||||
}
|
||||
),
|
||||
&[
|
||||
// a b c
|
||||
&[2, 3, 2, 3][..], &[2, 3, 2, 3][..], &[2, 3, 2, 3][..],
|
||||
// d e f
|
||||
&[2, 3, 2, 3][..], &[2, 3, 2, 3][..], &[2, 3, 2, 3][..],
|
||||
// g h
|
||||
&[2, 3, 2, 2][..], &[2, 3, 2, 2][..],
|
||||
// i j k l m
|
||||
&[2, 3, 2, 5][..], &[2, 3, 2, 5][..], &[2, 3, 2, 5][..], &[2, 3, 2, 5][..],
|
||||
&[2, 3, 2, 5][..],
|
||||
// n
|
||||
&[2, 3, 1, 1][..],
|
||||
// o
|
||||
&[2, 2, 3, 1][..],
|
||||
// p q
|
||||
&[2, 2, 3, 2][..], &[2, 2, 3, 2][..],
|
||||
// r s
|
||||
&[2, 2, 3, 2][..], &[2, 2, 3, 2][..],
|
||||
// t u v w x y z
|
||||
&[2, 2, 1, 7][..], &[2, 2, 1, 7][..], &[2, 2, 1, 7][..], &[2, 2, 1, 7][..],
|
||||
&[2, 2, 1, 7][..], &[2, 2, 1, 7][..], &[2, 2, 1, 7][..],
|
||||
|
||||
// (a b c) (d e f)
|
||||
&[2, 3, 2][..], &[2, 3, 2][..],
|
||||
// (g h) (i j k l m)
|
||||
&[2, 3, 2][..], &[2, 3, 2][..],
|
||||
// (n)
|
||||
&[2, 3, 1][..],
|
||||
// (o) (p q) (r s)
|
||||
&[2, 2, 3][..], &[2, 2, 3][..], &[2, 2, 3][..],
|
||||
// (t u v w x y z)
|
||||
&[2, 2, 1][..],
|
||||
|
||||
// [ (a b c) (d e f) ]
|
||||
// [ (g h) (i j k l m) ]
|
||||
// [ (n) ]
|
||||
&[2, 3][..], &[2, 3][..], &[2, 3,][..],
|
||||
// [ (o) (p q) (r s) ]
|
||||
// [ (t u v w x y z) ]
|
||||
&[2, 2][..], &[2, 2][..],
|
||||
|
||||
// {
|
||||
// [ (a b c) (d e f) ]
|
||||
// [ (g h) (i j k l m) ]
|
||||
// [ (n) ]
|
||||
// }
|
||||
// {
|
||||
// [ (o) (p q) (r s) ]
|
||||
// [ (t u v w x y z) ]
|
||||
// }
|
||||
&[2][..], &[2][..]
|
||||
][..]
|
||||
);
|
||||
|
||||
// It is possible to say, to some degree, that count is an "amalgamation" of length (see
|
||||
// each length line result and compare them with the count results)
|
||||
}
|
@ -2,13 +2,147 @@
|
||||
|
||||
#![feature(macro_metavar_expr)]
|
||||
|
||||
macro_rules! ignore {
|
||||
( $( $i:ident ),* ) => {{
|
||||
let array: [i32; 0] = [$( ${ignore(i)} )*];
|
||||
array
|
||||
}};
|
||||
/// Count the number of idents in a macro repetition.
|
||||
macro_rules! count_idents {
|
||||
( $( $i:ident ),* ) => {
|
||||
${count(i)}
|
||||
};
|
||||
}
|
||||
|
||||
fn main() {
|
||||
assert_eq!(ignore!(a, b, c), []);
|
||||
/// 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, length) 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()}, ${length()}) ),*]
|
||||
};
|
||||
}
|
||||
|
||||
/// Produce index and length tuples for literals in a 2-dimensional
|
||||
/// macro repetition.
|
||||
macro_rules! enumerate_literals_2 {
|
||||
( $( [ $( ($l:literal) ),* ] ),* ) => {
|
||||
[
|
||||
$(
|
||||
$(
|
||||
(
|
||||
${index(1)},
|
||||
${length(1)},
|
||||
${index(0)},
|
||||
${length(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, 2, 5, 9, 26), (9, 2, 5, 9))
|
||||
);
|
||||
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);
|
||||
}
|
||||
|
102
src/test/ui/macros/rfc-3086-metavar-expr/macro-expansion.rs
Normal file
102
src/test/ui/macros/rfc-3086-metavar-expr/macro-expansion.rs
Normal file
@ -0,0 +1,102 @@
|
||||
// run-pass
|
||||
|
||||
#![feature(macro_metavar_expr)]
|
||||
|
||||
#[derive(Debug)]
|
||||
struct Example<'a> {
|
||||
_indexes: &'a [(u32, u32)],
|
||||
_counts: &'a [u32],
|
||||
_nested: Vec<Example<'a>>,
|
||||
}
|
||||
|
||||
macro_rules! example {
|
||||
( $( [ $( ( $( $x:ident )* ) )* ] )* ) => {
|
||||
Example {
|
||||
_indexes: &[],
|
||||
_counts: &[${count(x, 0)}, ${count(x, 1)}, ${count(x, 2)}],
|
||||
_nested: vec![
|
||||
$(
|
||||
Example {
|
||||
_indexes: &[(${index()}, ${length()})],
|
||||
_counts: &[${count(x, 0)}, ${count(x, 1)}],
|
||||
_nested: vec![
|
||||
$(
|
||||
Example {
|
||||
_indexes: &[(${index(1)}, ${length(1)}), (${index()}, ${length()})],
|
||||
_counts: &[${count(x)}],
|
||||
_nested: vec![
|
||||
$(
|
||||
Example {
|
||||
_indexes: &[
|
||||
(${index(2)}, ${length(2)}),
|
||||
(${index(1)}, ${length(1)}),
|
||||
(${index()}, ${length()})
|
||||
],
|
||||
_counts: &[],
|
||||
_nested: vec![],
|
||||
${ignore(x)}
|
||||
}
|
||||
),*
|
||||
]
|
||||
}
|
||||
),*
|
||||
]
|
||||
}
|
||||
),*
|
||||
]
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
static EXPECTED: &str = concat!(
|
||||
"Example { _indexes: [], _counts: [2, 4, 13], _nested: [",
|
||||
concat!(
|
||||
"Example { _indexes: [(0, 2)], _counts: [3, 10], _nested: [",
|
||||
concat!(
|
||||
"Example { _indexes: [(0, 2), (0, 3)], _counts: [4], _nested: [",
|
||||
concat!(
|
||||
"Example { _indexes: [(0, 2), (0, 3), (0, 4)], _counts: [], _nested: [] }, ",
|
||||
"Example { _indexes: [(0, 2), (0, 3), (1, 4)], _counts: [], _nested: [] }, ",
|
||||
"Example { _indexes: [(0, 2), (0, 3), (2, 4)], _counts: [], _nested: [] }, ",
|
||||
"Example { _indexes: [(0, 2), (0, 3), (3, 4)], _counts: [], _nested: [] }",
|
||||
),
|
||||
"] }, ",
|
||||
"Example { _indexes: [(0, 2), (1, 3)], _counts: [4], _nested: [",
|
||||
concat!(
|
||||
"Example { _indexes: [(0, 2), (1, 3), (0, 4)], _counts: [], _nested: [] }, ",
|
||||
"Example { _indexes: [(0, 2), (1, 3), (1, 4)], _counts: [], _nested: [] }, ",
|
||||
"Example { _indexes: [(0, 2), (1, 3), (2, 4)], _counts: [], _nested: [] }, ",
|
||||
"Example { _indexes: [(0, 2), (1, 3), (3, 4)], _counts: [], _nested: [] }",
|
||||
),
|
||||
"] }, ",
|
||||
"Example { _indexes: [(0, 2), (2, 3)], _counts: [2], _nested: [",
|
||||
concat!(
|
||||
"Example { _indexes: [(0, 2), (2, 3), (0, 2)], _counts: [], _nested: [] }, ",
|
||||
"Example { _indexes: [(0, 2), (2, 3), (1, 2)], _counts: [], _nested: [] }",
|
||||
),
|
||||
"] }",
|
||||
),
|
||||
"] }, ",
|
||||
"Example { _indexes: [(1, 2)], _counts: [1, 3], _nested: [",
|
||||
concat!(
|
||||
"Example { _indexes: [(1, 2), (0, 1)], _counts: [3], _nested: [",
|
||||
concat!(
|
||||
"Example { _indexes: [(1, 2), (0, 1), (0, 3)], _counts: [], _nested: [] }, ",
|
||||
"Example { _indexes: [(1, 2), (0, 1), (1, 3)], _counts: [], _nested: [] }, ",
|
||||
"Example { _indexes: [(1, 2), (0, 1), (2, 3)], _counts: [], _nested: [] }",
|
||||
),
|
||||
"] }",
|
||||
),
|
||||
"] }",
|
||||
),
|
||||
"] }",
|
||||
);
|
||||
|
||||
fn main() {
|
||||
let e = example! {
|
||||
[ ( A B C D ) ( E F G H ) ( I J ) ]
|
||||
[ ( K L M ) ]
|
||||
};
|
||||
let debug = format!("{:?}", e);
|
||||
assert_eq!(debug, EXPECTED);
|
||||
}
|
@ -0,0 +1,44 @@
|
||||
#![feature(macro_metavar_expr)]
|
||||
|
||||
macro_rules! a {
|
||||
( $( { $( [ $( ( $( $foo:ident )* ) )* ] )* } )* ) => {
|
||||
(
|
||||
${count(foo, 0)},
|
||||
${count(foo, 10)},
|
||||
//~^ ERROR count depth must be less than 4
|
||||
)
|
||||
};
|
||||
}
|
||||
|
||||
macro_rules! b {
|
||||
( $( { $( [ $( $foo:ident )* ] )* } )* ) => {
|
||||
(
|
||||
$( $( $(
|
||||
${ignore(foo)}
|
||||
${index(0)},
|
||||
${index(10)},
|
||||
//~^ ERROR index depth must be less than 3
|
||||
)* )* )*
|
||||
)
|
||||
};
|
||||
}
|
||||
|
||||
macro_rules! c {
|
||||
( $( { $( $foo:ident )* } )* ) => {
|
||||
(
|
||||
$( $(
|
||||
${ignore(foo)}
|
||||
${length(0)}
|
||||
${length(10)}
|
||||
//~^ ERROR length depth must be less than 2
|
||||
)* )*
|
||||
)
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
fn main() {
|
||||
a!( { [ (a) ] [ (b c) ] } );
|
||||
b!( { [ a b ] } );
|
||||
c!( { a } );
|
||||
}
|
@ -0,0 +1,20 @@
|
||||
error: count depth must be less than 4
|
||||
--> $DIR/out-of-bounds-arguments.rs:7:14
|
||||
|
|
||||
LL | ${count(foo, 10)},
|
||||
| ^^^^^^^^^^^^^^^^
|
||||
|
||||
error: index depth must be less than 3
|
||||
--> $DIR/out-of-bounds-arguments.rs:19:18
|
||||
|
|
||||
LL | ${index(10)},
|
||||
| ^^^^^^^^^^^
|
||||
|
||||
error: length depth must be less than 2
|
||||
--> $DIR/out-of-bounds-arguments.rs:32:18
|
||||
|
|
||||
LL | ${length(10)}
|
||||
| ^^^^^^^^^^^^
|
||||
|
||||
error: aborting due to 3 previous errors
|
||||
|
@ -10,6 +10,7 @@ macro_rules! curly__no_rhs_dollar__round {
|
||||
|
||||
macro_rules! curly__no_rhs_dollar__no_round {
|
||||
( $i:ident ) => { ${ count(i) } };
|
||||
//~^ ERROR `count` can not be placed inside the inner-most repetition
|
||||
}
|
||||
|
||||
macro_rules! curly__rhs_dollar__round {
|
||||
@ -121,6 +122,20 @@ macro_rules! open_brackets_without_tokens {
|
||||
//~| ERROR expected identifier
|
||||
}
|
||||
|
||||
macro_rules! unknown_count_ident {
|
||||
( $( $i:ident )* ) => {
|
||||
${count(foo)}
|
||||
//~^ ERROR variable `foo` is not recognized in meta-variable expression
|
||||
};
|
||||
}
|
||||
|
||||
macro_rules! unknown_ignore_ident {
|
||||
( $( $i:ident )* ) => {
|
||||
${ignore(bar)}
|
||||
//~^ ERROR variable `bar` is not recognized in meta-variable expression
|
||||
};
|
||||
}
|
||||
|
||||
macro_rules! unknown_metavar {
|
||||
( $( $i:ident ),* ) => { ${ aaaaaaaaaaaaaa(i) } };
|
||||
//~^ ERROR unrecognized meta-variable expression
|
||||
@ -139,10 +154,12 @@ fn main() {
|
||||
//~^ ERROR cannot find value `a` in this scope
|
||||
|
||||
extra_garbage_after_metavar!(a);
|
||||
unknown_metavar!(a);
|
||||
metavar_without_parens!(a);
|
||||
metavar_token_without_ident!(a);
|
||||
metavar_depth_is_not_literal!(a);
|
||||
metavar_token_without_ident!(a);
|
||||
metavar_with_literal_suffix!(a);
|
||||
open_brackets_without_tokens!(a)
|
||||
metavar_without_parens!(a);
|
||||
open_brackets_without_tokens!(a);
|
||||
unknown_count_ident!(a);
|
||||
unknown_ignore_ident!(a);
|
||||
unknown_metavar!(a);
|
||||
}
|
||||
|
@ -1,203 +1,209 @@
|
||||
error: expected identifier, found `$`
|
||||
--> $DIR/syntax-errors.rs:16:33
|
||||
--> $DIR/syntax-errors.rs:17:33
|
||||
|
|
||||
LL | ( $( $i:ident ),* ) => { ${ count($i) } };
|
||||
| ^^^^^ - help: try removing `$`
|
||||
|
||||
error: expected identifier, found `$`
|
||||
--> $DIR/syntax-errors.rs:22:26
|
||||
--> $DIR/syntax-errors.rs:23:26
|
||||
|
|
||||
LL | ( $i:ident ) => { ${ count($i) } };
|
||||
| ^^^^^ - help: try removing `$`
|
||||
|
||||
error: unexpected token: $
|
||||
--> $DIR/syntax-errors.rs:52:8
|
||||
--> $DIR/syntax-errors.rs:53:8
|
||||
|
|
||||
LL | ( $$ $a:ident ) => {
|
||||
| ^
|
||||
|
||||
note: `$$` and meta-variable expressions are not allowed inside macro parameter definitions
|
||||
--> $DIR/syntax-errors.rs:52:8
|
||||
--> $DIR/syntax-errors.rs:53:8
|
||||
|
|
||||
LL | ( $$ $a:ident ) => {
|
||||
| ^
|
||||
|
||||
error: unexpected token: a
|
||||
--> $DIR/syntax-errors.rs:59:19
|
||||
--> $DIR/syntax-errors.rs:60:19
|
||||
|
|
||||
LL | ${count() a b c}
|
||||
| ^
|
||||
|
|
||||
note: meta-variable expression must not have trailing tokens
|
||||
--> $DIR/syntax-errors.rs:59:19
|
||||
--> $DIR/syntax-errors.rs:60:19
|
||||
|
|
||||
LL | ${count() a b c}
|
||||
| ^
|
||||
|
||||
error: unexpected token: a
|
||||
--> $DIR/syntax-errors.rs:62:19
|
||||
--> $DIR/syntax-errors.rs:63:19
|
||||
|
|
||||
LL | ${count(i a b c)}
|
||||
| ^
|
||||
|
|
||||
note: meta-variable expression must not have trailing tokens
|
||||
--> $DIR/syntax-errors.rs:62:19
|
||||
--> $DIR/syntax-errors.rs:63:19
|
||||
|
|
||||
LL | ${count(i a b c)}
|
||||
| ^
|
||||
|
||||
error: unexpected token: a
|
||||
--> $DIR/syntax-errors.rs:64:22
|
||||
--> $DIR/syntax-errors.rs:65:22
|
||||
|
|
||||
LL | ${count(i, 1 a b c)}
|
||||
| ^
|
||||
|
|
||||
note: meta-variable expression must not have trailing tokens
|
||||
--> $DIR/syntax-errors.rs:64:22
|
||||
--> $DIR/syntax-errors.rs:65:22
|
||||
|
|
||||
LL | ${count(i, 1 a b c)}
|
||||
| ^
|
||||
|
||||
error: unexpected token: a
|
||||
--> $DIR/syntax-errors.rs:66:20
|
||||
--> $DIR/syntax-errors.rs:67:20
|
||||
|
|
||||
LL | ${count(i) a b c}
|
||||
| ^
|
||||
|
|
||||
note: meta-variable expression must not have trailing tokens
|
||||
--> $DIR/syntax-errors.rs:66:20
|
||||
--> $DIR/syntax-errors.rs:67:20
|
||||
|
|
||||
LL | ${count(i) a b c}
|
||||
| ^
|
||||
|
||||
error: unexpected token: a
|
||||
--> $DIR/syntax-errors.rs:69:21
|
||||
--> $DIR/syntax-errors.rs:70:21
|
||||
|
|
||||
LL | ${ignore(i) a b c}
|
||||
| ^
|
||||
|
|
||||
note: meta-variable expression must not have trailing tokens
|
||||
--> $DIR/syntax-errors.rs:69:21
|
||||
--> $DIR/syntax-errors.rs:70:21
|
||||
|
|
||||
LL | ${ignore(i) a b c}
|
||||
| ^
|
||||
|
||||
error: unexpected token: a
|
||||
--> $DIR/syntax-errors.rs:71:20
|
||||
--> $DIR/syntax-errors.rs:72:20
|
||||
|
|
||||
LL | ${ignore(i a b c)}
|
||||
| ^
|
||||
|
|
||||
note: meta-variable expression must not have trailing tokens
|
||||
--> $DIR/syntax-errors.rs:71:20
|
||||
--> $DIR/syntax-errors.rs:72:20
|
||||
|
|
||||
LL | ${ignore(i a b c)}
|
||||
| ^
|
||||
|
||||
error: unexpected token: a
|
||||
--> $DIR/syntax-errors.rs:74:19
|
||||
--> $DIR/syntax-errors.rs:75:19
|
||||
|
|
||||
LL | ${index() a b c}
|
||||
| ^
|
||||
|
|
||||
note: meta-variable expression must not have trailing tokens
|
||||
--> $DIR/syntax-errors.rs:74:19
|
||||
--> $DIR/syntax-errors.rs:75:19
|
||||
|
|
||||
LL | ${index() a b c}
|
||||
| ^
|
||||
|
||||
error: unexpected token: a
|
||||
--> $DIR/syntax-errors.rs:76:19
|
||||
--> $DIR/syntax-errors.rs:77:19
|
||||
|
|
||||
LL | ${index(1 a b c)}
|
||||
| ^
|
||||
|
|
||||
note: meta-variable expression must not have trailing tokens
|
||||
--> $DIR/syntax-errors.rs:76:19
|
||||
--> $DIR/syntax-errors.rs:77:19
|
||||
|
|
||||
LL | ${index(1 a b c)}
|
||||
| ^
|
||||
|
||||
error: unexpected token: a
|
||||
--> $DIR/syntax-errors.rs:79:19
|
||||
--> $DIR/syntax-errors.rs:80:19
|
||||
|
|
||||
LL | ${index() a b c}
|
||||
| ^
|
||||
|
|
||||
note: meta-variable expression must not have trailing tokens
|
||||
--> $DIR/syntax-errors.rs:79:19
|
||||
--> $DIR/syntax-errors.rs:80:19
|
||||
|
|
||||
LL | ${index() a b c}
|
||||
| ^
|
||||
|
||||
error: unexpected token: a
|
||||
--> $DIR/syntax-errors.rs:81:19
|
||||
--> $DIR/syntax-errors.rs:82:19
|
||||
|
|
||||
LL | ${index(1 a b c)}
|
||||
| ^
|
||||
|
|
||||
note: meta-variable expression must not have trailing tokens
|
||||
--> $DIR/syntax-errors.rs:81:19
|
||||
--> $DIR/syntax-errors.rs:82:19
|
||||
|
|
||||
LL | ${index(1 a b c)}
|
||||
| ^
|
||||
|
||||
error: meta-variable expression depth must be a literal
|
||||
--> $DIR/syntax-errors.rs:88:33
|
||||
--> $DIR/syntax-errors.rs:89:33
|
||||
|
|
||||
LL | ( $( $i:ident ),* ) => { ${ index(IDX) } };
|
||||
| ^^^^^
|
||||
|
||||
error: unexpected token: {
|
||||
--> $DIR/syntax-errors.rs:94:8
|
||||
--> $DIR/syntax-errors.rs:95:8
|
||||
|
|
||||
LL | ( ${ length() } ) => {
|
||||
| ^^^^^^^^^^^^
|
||||
|
||||
note: `$$` and meta-variable expressions are not allowed inside macro parameter definitions
|
||||
--> $DIR/syntax-errors.rs:94:8
|
||||
--> $DIR/syntax-errors.rs:95:8
|
||||
|
|
||||
LL | ( ${ length() } ) => {
|
||||
| ^^^^^^^^^^^^
|
||||
|
||||
error: expected one of: `*`, `+`, or `?`
|
||||
--> $DIR/syntax-errors.rs:94:8
|
||||
--> $DIR/syntax-errors.rs:95:8
|
||||
|
|
||||
LL | ( ${ length() } ) => {
|
||||
| ^^^^^^^^^^^^
|
||||
|
||||
error: expected identifier
|
||||
--> $DIR/syntax-errors.rs:101:33
|
||||
--> $DIR/syntax-errors.rs:102:33
|
||||
|
|
||||
LL | ( $( $i:ident ),* ) => { ${ ignore() } };
|
||||
| ^^^^^^
|
||||
|
||||
error: only unsuffixes integer literals are supported in meta-variable expressions
|
||||
--> $DIR/syntax-errors.rs:107:33
|
||||
--> $DIR/syntax-errors.rs:108:33
|
||||
|
|
||||
LL | ( $( $i:ident ),* ) => { ${ index(1u32) } };
|
||||
| ^^^^^
|
||||
|
||||
error: meta-variable expression parameter must be wrapped in parentheses
|
||||
--> $DIR/syntax-errors.rs:113:33
|
||||
--> $DIR/syntax-errors.rs:114:33
|
||||
|
|
||||
LL | ( $( $i:ident ),* ) => { ${ count{i} } };
|
||||
| ^^^^^
|
||||
|
||||
error: expected identifier
|
||||
--> $DIR/syntax-errors.rs:119:31
|
||||
--> $DIR/syntax-errors.rs:120:31
|
||||
|
|
||||
LL | ( $( $i:ident ),* ) => { ${ {} } };
|
||||
| ^^^^^^
|
||||
|
||||
error: unrecognized meta-variable expression
|
||||
--> $DIR/syntax-errors.rs:125:33
|
||||
--> $DIR/syntax-errors.rs:140:33
|
||||
|
|
||||
LL | ( $( $i:ident ),* ) => { ${ aaaaaaaaaaaaaa(i) } };
|
||||
| ^^^^^^^^^^^^^^ help: supported expressions are count, ignore, index and length
|
||||
|
||||
error: `count` can not be placed inside the inner-most repetition
|
||||
--> $DIR/syntax-errors.rs:12:24
|
||||
|
|
||||
LL | ( $i:ident ) => { ${ count(i) } };
|
||||
| ^^^^^^^^^^^^
|
||||
|
||||
error: expected expression, found `$`
|
||||
--> $DIR/syntax-errors.rs:16:30
|
||||
--> $DIR/syntax-errors.rs:17:30
|
||||
|
|
||||
LL | ( $( $i:ident ),* ) => { ${ count($i) } };
|
||||
| ^ expected expression
|
||||
@ -208,7 +214,7 @@ LL | curly__rhs_dollar__round!(a, b, c);
|
||||
= note: this error originates in the macro `curly__rhs_dollar__round` (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||
|
||||
error: expected expression, found `$`
|
||||
--> $DIR/syntax-errors.rs:22:23
|
||||
--> $DIR/syntax-errors.rs:23:23
|
||||
|
|
||||
LL | ( $i:ident ) => { ${ count($i) } };
|
||||
| ^ expected expression
|
||||
@ -219,13 +225,13 @@ LL | curly__rhs_dollar__no_round!(a);
|
||||
= note: this error originates in the macro `curly__rhs_dollar__no_round` (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||
|
||||
error: variable 'i' is still repeating at this depth
|
||||
--> $DIR/syntax-errors.rs:40:36
|
||||
--> $DIR/syntax-errors.rs:41:36
|
||||
|
|
||||
LL | ( $( $i:ident ),* ) => { count($i) };
|
||||
| ^^
|
||||
|
||||
error: expected expression, found `$`
|
||||
--> $DIR/syntax-errors.rs:59:9
|
||||
--> $DIR/syntax-errors.rs:60:9
|
||||
|
|
||||
LL | ${count() a b c}
|
||||
| ^ expected expression
|
||||
@ -236,40 +242,7 @@ LL | extra_garbage_after_metavar!(a);
|
||||
= note: this error originates in the macro `extra_garbage_after_metavar` (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||
|
||||
error: expected expression, found `$`
|
||||
--> $DIR/syntax-errors.rs:125:30
|
||||
|
|
||||
LL | ( $( $i:ident ),* ) => { ${ aaaaaaaaaaaaaa(i) } };
|
||||
| ^ expected expression
|
||||
...
|
||||
LL | unknown_metavar!(a);
|
||||
| ------------------- in this macro invocation
|
||||
|
|
||||
= note: this error originates in the macro `unknown_metavar` (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||
|
||||
error: expected expression, found `$`
|
||||
--> $DIR/syntax-errors.rs:113:30
|
||||
|
|
||||
LL | ( $( $i:ident ),* ) => { ${ count{i} } };
|
||||
| ^ expected expression
|
||||
...
|
||||
LL | metavar_without_parens!(a);
|
||||
| -------------------------- in this macro invocation
|
||||
|
|
||||
= note: this error originates in the macro `metavar_without_parens` (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||
|
||||
error: expected expression, found `$`
|
||||
--> $DIR/syntax-errors.rs:101:30
|
||||
|
|
||||
LL | ( $( $i:ident ),* ) => { ${ ignore() } };
|
||||
| ^ expected expression
|
||||
...
|
||||
LL | metavar_token_without_ident!(a);
|
||||
| ------------------------------- in this macro invocation
|
||||
|
|
||||
= note: this error originates in the macro `metavar_token_without_ident` (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||
|
||||
error: expected expression, found `$`
|
||||
--> $DIR/syntax-errors.rs:88:30
|
||||
--> $DIR/syntax-errors.rs:89:30
|
||||
|
|
||||
LL | ( $( $i:ident ),* ) => { ${ index(IDX) } };
|
||||
| ^ expected expression
|
||||
@ -280,7 +253,18 @@ LL | metavar_depth_is_not_literal!(a);
|
||||
= note: this error originates in the macro `metavar_depth_is_not_literal` (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||
|
||||
error: expected expression, found `$`
|
||||
--> $DIR/syntax-errors.rs:107:30
|
||||
--> $DIR/syntax-errors.rs:102:30
|
||||
|
|
||||
LL | ( $( $i:ident ),* ) => { ${ ignore() } };
|
||||
| ^ expected expression
|
||||
...
|
||||
LL | metavar_token_without_ident!(a);
|
||||
| ------------------------------- in this macro invocation
|
||||
|
|
||||
= note: this error originates in the macro `metavar_token_without_ident` (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||
|
||||
error: expected expression, found `$`
|
||||
--> $DIR/syntax-errors.rs:108:30
|
||||
|
|
||||
LL | ( $( $i:ident ),* ) => { ${ index(1u32) } };
|
||||
| ^ expected expression
|
||||
@ -291,18 +275,52 @@ LL | metavar_with_literal_suffix!(a);
|
||||
= note: this error originates in the macro `metavar_with_literal_suffix` (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||
|
||||
error: expected expression, found `$`
|
||||
--> $DIR/syntax-errors.rs:119:30
|
||||
--> $DIR/syntax-errors.rs:114:30
|
||||
|
|
||||
LL | ( $( $i:ident ),* ) => { ${ count{i} } };
|
||||
| ^ expected expression
|
||||
...
|
||||
LL | metavar_without_parens!(a);
|
||||
| -------------------------- in this macro invocation
|
||||
|
|
||||
= note: this error originates in the macro `metavar_without_parens` (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||
|
||||
error: expected expression, found `$`
|
||||
--> $DIR/syntax-errors.rs:120:30
|
||||
|
|
||||
LL | ( $( $i:ident ),* ) => { ${ {} } };
|
||||
| ^ expected expression
|
||||
...
|
||||
LL | open_brackets_without_tokens!(a)
|
||||
LL | open_brackets_without_tokens!(a);
|
||||
| -------------------------------- in this macro invocation
|
||||
|
|
||||
= note: this error originates in the macro `open_brackets_without_tokens` (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||
|
||||
error: variable `foo` is not recognized in meta-variable expression
|
||||
--> $DIR/syntax-errors.rs:127:17
|
||||
|
|
||||
LL | ${count(foo)}
|
||||
| ^^^
|
||||
|
||||
error: variable `bar` is not recognized in meta-variable expression
|
||||
--> $DIR/syntax-errors.rs:134:18
|
||||
|
|
||||
LL | ${ignore(bar)}
|
||||
| ^^^
|
||||
|
||||
error: expected expression, found `$`
|
||||
--> $DIR/syntax-errors.rs:140:30
|
||||
|
|
||||
LL | ( $( $i:ident ),* ) => { ${ aaaaaaaaaaaaaa(i) } };
|
||||
| ^ expected expression
|
||||
...
|
||||
LL | unknown_metavar!(a);
|
||||
| ------------------- in this macro invocation
|
||||
|
|
||||
= note: this error originates in the macro `unknown_metavar` (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||
|
||||
error[E0425]: cannot find function `count` in this scope
|
||||
--> $DIR/syntax-errors.rs:28:30
|
||||
--> $DIR/syntax-errors.rs:29:30
|
||||
|
|
||||
LL | ( $( $i:ident ),* ) => { count(i) };
|
||||
| ^^^^^ not found in this scope
|
||||
@ -313,7 +331,7 @@ LL | no_curly__no_rhs_dollar__round!(a, b, c);
|
||||
= note: this error originates in the macro `no_curly__no_rhs_dollar__round` (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||
|
||||
error[E0425]: cannot find value `i` in this scope
|
||||
--> $DIR/syntax-errors.rs:28:36
|
||||
--> $DIR/syntax-errors.rs:29:36
|
||||
|
|
||||
LL | ( $( $i:ident ),* ) => { count(i) };
|
||||
| ^ not found in this scope
|
||||
@ -324,7 +342,7 @@ LL | no_curly__no_rhs_dollar__round!(a, b, c);
|
||||
= note: this error originates in the macro `no_curly__no_rhs_dollar__round` (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||
|
||||
error[E0425]: cannot find function `count` in this scope
|
||||
--> $DIR/syntax-errors.rs:34:23
|
||||
--> $DIR/syntax-errors.rs:35:23
|
||||
|
|
||||
LL | ( $i:ident ) => { count(i) };
|
||||
| ^^^^^ not found in this scope
|
||||
@ -335,7 +353,7 @@ LL | no_curly__no_rhs_dollar__no_round!(a);
|
||||
= note: this error originates in the macro `no_curly__no_rhs_dollar__no_round` (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||
|
||||
error[E0425]: cannot find value `i` in this scope
|
||||
--> $DIR/syntax-errors.rs:34:29
|
||||
--> $DIR/syntax-errors.rs:35:29
|
||||
|
|
||||
LL | ( $i:ident ) => { count(i) };
|
||||
| ^ not found in this scope
|
||||
@ -346,7 +364,7 @@ LL | no_curly__no_rhs_dollar__no_round!(a);
|
||||
= note: this error originates in the macro `no_curly__no_rhs_dollar__no_round` (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||
|
||||
error[E0425]: cannot find function `count` in this scope
|
||||
--> $DIR/syntax-errors.rs:45:23
|
||||
--> $DIR/syntax-errors.rs:46:23
|
||||
|
|
||||
LL | ( $i:ident ) => { count($i) };
|
||||
| ^^^^^ not found in this scope
|
||||
@ -357,11 +375,11 @@ LL | no_curly__rhs_dollar__no_round!(a);
|
||||
= note: this error originates in the macro `no_curly__rhs_dollar__no_round` (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||
|
||||
error[E0425]: cannot find value `a` in this scope
|
||||
--> $DIR/syntax-errors.rs:138:37
|
||||
--> $DIR/syntax-errors.rs:153:37
|
||||
|
|
||||
LL | no_curly__rhs_dollar__no_round!(a);
|
||||
| ^ not found in this scope
|
||||
|
||||
error: aborting due to 37 previous errors
|
||||
error: aborting due to 40 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0425`.
|
||||
|
Loading…
Reference in New Issue
Block a user