|  | //@ edition: 2021 | 
|  |  | 
|  | #![feature(macro_metavar_expr_concat)] | 
|  |  | 
|  | macro_rules! syntax_errors { | 
|  | ($ex:expr) => { | 
|  | ${concat()} | 
|  | //~^ ERROR expected identifier | 
|  |  | 
|  | ${concat(aaaa)} | 
|  | //~^ ERROR `concat` must have at least two elements | 
|  |  | 
|  | ${concat(aaaa,)} | 
|  | //~^ ERROR expected identifier | 
|  |  | 
|  | ${concat(_, aaaa)} | 
|  |  | 
|  | ${concat(aaaa aaaa)} | 
|  | //~^ ERROR expected comma | 
|  |  | 
|  | ${concat($ex)} | 
|  | //~^ ERROR `concat` must have at least two elements | 
|  |  | 
|  | ${concat($ex, aaaa)} | 
|  | //~^ ERROR metavariables of `${concat(..)}` must be of type | 
|  |  | 
|  | ${concat($ex, aaaa 123)} | 
|  | //~^ ERROR expected comma | 
|  |  | 
|  | ${concat($ex, aaaa,)} | 
|  | //~^ ERROR expected identifier | 
|  | }; | 
|  | } | 
|  |  | 
|  | macro_rules! dollar_sign_without_referenced_ident { | 
|  | ($ident:ident) => { | 
|  | const ${concat(FOO, $foo)}: i32 = 2; | 
|  | //~^ ERROR variable `foo` is not recognized in meta-variable expression | 
|  | }; | 
|  | } | 
|  |  | 
|  | macro_rules! starting_number { | 
|  | ($ident:ident) => {{ | 
|  | let ${concat("1", $ident)}: () = (); | 
|  | //~^ ERROR `${concat(..)}` is not generating a valid identifier | 
|  | }}; | 
|  | } | 
|  |  | 
|  | macro_rules! starting_valid_unicode { | 
|  | ($ident:ident) => {{ | 
|  | let ${concat("Ý", $ident)}: () = (); | 
|  | }}; | 
|  | } | 
|  |  | 
|  | macro_rules! starting_invalid_unicode { | 
|  | ($ident:ident) => {{ | 
|  | let ${concat("\u{00BD}", $ident)}: () = (); | 
|  | //~^ ERROR `${concat(..)}` is not generating a valid identifier | 
|  | }}; | 
|  | } | 
|  |  | 
|  | macro_rules! ending_number { | 
|  | ($ident:ident) => {{ | 
|  | let ${concat($ident, "1")}: () = (); | 
|  | }}; | 
|  | } | 
|  |  | 
|  | macro_rules! ending_valid_unicode { | 
|  | ($ident:ident) => {{ | 
|  | let ${concat($ident, "Ý")}: () = (); | 
|  | }}; | 
|  | } | 
|  |  | 
|  | macro_rules! ending_invalid_unicode { | 
|  | ($ident:ident) => {{ | 
|  | let ${concat($ident, "\u{00BD}")}: () = (); | 
|  | //~^ ERROR `${concat(..)}` is not generating a valid identifier | 
|  | }}; | 
|  | } | 
|  |  | 
|  | macro_rules! empty { | 
|  | () => {{ | 
|  | let ${concat("", "")}: () = (); | 
|  | //~^ ERROR `${concat(..)}` is not generating a valid identifier | 
|  | }}; | 
|  | } | 
|  |  | 
|  | macro_rules! unsupported_literals { | 
|  | ($ident:ident) => {{ | 
|  | let ${concat(_a, 'b')}: () = (); | 
|  | //~^ ERROR expected identifier or string literal | 
|  | //~| ERROR expected pattern | 
|  | let ${concat(_a, 1)}: () = (); | 
|  | //~^ ERROR expected identifier or string literal | 
|  | let ${concat(_a, 1.5)}: () = (); | 
|  | //~^ ERROR expected identifier or string literal | 
|  | let ${concat(_a, c"hi")}: () = (); | 
|  | //~^ ERROR expected identifier or string literal | 
|  | let ${concat(_a, b"hi")}: () = (); | 
|  | //~^ ERROR expected identifier or string literal | 
|  | let ${concat(_a, b'b')}: () = (); | 
|  | //~^ ERROR expected identifier or string literal | 
|  | let ${concat(_a, b'b')}: () = (); | 
|  | //~^ ERROR expected identifier or string literal | 
|  |  | 
|  | let ${concat($ident, 'b')}: () = (); | 
|  | //~^ ERROR expected identifier or string literal | 
|  | let ${concat($ident, 1)}: () = (); | 
|  | //~^ ERROR expected identifier or string literal | 
|  | let ${concat($ident, 1.5)}: () = (); | 
|  | //~^ ERROR expected identifier or string literal | 
|  | let ${concat($ident, c"hi")}: () = (); | 
|  | //~^ ERROR expected identifier or string literal | 
|  | let ${concat($ident, b"hi")}: () = (); | 
|  | //~^ ERROR expected identifier or string literal | 
|  | let ${concat($ident, b'b')}: () = (); | 
|  | //~^ ERROR expected identifier or string literal | 
|  | let ${concat($ident, b'b')}: () = (); | 
|  | //~^ ERROR expected identifier or string literal | 
|  | }}; | 
|  | } | 
|  |  | 
|  | macro_rules! bad_literal_string { | 
|  | ($literal:literal) => { | 
|  | const ${concat(_foo, $literal)}: () = (); | 
|  | //~^ ERROR `${concat(..)}` is not generating a valid identifier | 
|  | //~| ERROR `${concat(..)}` is not generating a valid identifier | 
|  | //~| ERROR `${concat(..)}` is not generating a valid identifier | 
|  | //~| ERROR `${concat(..)}` is not generating a valid identifier | 
|  | //~| ERROR `${concat(..)}` is not generating a valid identifier | 
|  | //~| ERROR `${concat(..)}` is not generating a valid identifier | 
|  | //~| ERROR `${concat(..)}` is not generating a valid identifier | 
|  | } | 
|  | } | 
|  |  | 
|  | macro_rules! bad_literal_non_string { | 
|  | ($literal:literal) => { | 
|  | const ${concat(_foo, $literal)}: () = (); | 
|  | //~^ ERROR metavariables of `${concat(..)}` must be of type | 
|  | //~| ERROR metavariables of `${concat(..)}` must be of type | 
|  | //~| ERROR metavariables of `${concat(..)}` must be of type | 
|  | //~| ERROR metavariables of `${concat(..)}` must be of type | 
|  | //~| ERROR floats are not supported as metavariables of `${concat(..)}` | 
|  | //~| ERROR integer metavariables of `${concat(..)}` must not be suffixed | 
|  | //~| ERROR integer metavariables of `${concat(..)}` must not be suffixed | 
|  | } | 
|  | } | 
|  |  | 
|  | macro_rules! bad_tt_literal { | 
|  | ($tt:tt) => { | 
|  | const ${concat(_foo, $tt)}: () = (); | 
|  | //~^ ERROR metavariables of `${concat(..)}` must be of type | 
|  | //~| ERROR metavariables of `${concat(..)}` must be of type | 
|  | } | 
|  | } | 
|  |  | 
|  | fn main() { | 
|  | syntax_errors!(1); | 
|  |  | 
|  | dollar_sign_without_referenced_ident!(VAR); | 
|  |  | 
|  | starting_number!(_abc); | 
|  | starting_valid_unicode!(_abc); | 
|  | starting_invalid_unicode!(_abc); | 
|  |  | 
|  | ending_number!(_abc); | 
|  | ending_valid_unicode!(_abc); | 
|  | ending_invalid_unicode!(_abc); | 
|  | unsupported_literals!(_abc); | 
|  |  | 
|  | empty!(); | 
|  |  | 
|  | bad_literal_string!("\u{00BD}"); | 
|  | bad_literal_string!("\x41"); | 
|  | bad_literal_string!("🤷"); | 
|  | bad_literal_string!("d[-_-]b"); | 
|  |  | 
|  | bad_literal_string!("-1"); | 
|  | bad_literal_string!("1.0"); | 
|  | bad_literal_string!("'1'"); | 
|  |  | 
|  | bad_literal_non_string!(-1); | 
|  | bad_literal_non_string!(1.0); | 
|  | bad_literal_non_string!('1'); | 
|  | bad_literal_non_string!(false); | 
|  | bad_literal_non_string!(4f64); | 
|  | bad_literal_non_string!(5u8); | 
|  | bad_literal_non_string!(6_u8); | 
|  |  | 
|  | bad_tt_literal!(1.0); | 
|  | bad_tt_literal!('1'); | 
|  | } |