| #![feature(decl_macro)] |
| |
| #[derive(Copy, Clone, PartialEq, Debug)] |
| pub enum Field { |
| RootCtxt, |
| MacroCtxt, |
| } |
| |
| #[rustfmt::skip] |
| macro x( |
| $macro_name:ident, |
| $macro2_name:ident, |
| $type_name:ident, |
| $field_name:ident, |
| $const_name:ident |
| ) { |
| #[derive(Copy, Clone)] |
| pub struct $type_name { |
| pub field: Field, |
| pub $field_name: Field, |
| } |
| |
| pub const $const_name: $type_name = |
| $type_name { field: Field::MacroCtxt, $field_name: Field::RootCtxt }; |
| |
| #[macro_export] |
| macro_rules! $macro_name { |
| (check_fields_of $e:expr) => {{ |
| let e = $e; |
| assert_eq!(e.field, Field::MacroCtxt); |
| assert_eq!(e.$field_name, Field::RootCtxt); |
| }}; |
| (check_fields) => {{ |
| assert_eq!($const_name.field, Field::MacroCtxt); |
| assert_eq!($const_name.$field_name, Field::RootCtxt); |
| }}; |
| (construct) => { |
| $type_name { field: Field::MacroCtxt, $field_name: Field::RootCtxt } |
| }; |
| } |
| |
| pub macro $macro2_name { |
| (check_fields_of $e:expr) => {{ |
| let e = $e; |
| assert_eq!(e.field, Field::MacroCtxt); |
| assert_eq!(e.$field_name, Field::RootCtxt); |
| }}, |
| (check_fields) => {{ |
| assert_eq!($const_name.field, Field::MacroCtxt); |
| assert_eq!($const_name.$field_name, Field::RootCtxt); |
| }}, |
| (construct) => { |
| $type_name { field: Field::MacroCtxt, $field_name: Field::RootCtxt } |
| } |
| } |
| } |
| |
| x!(test_fields, test_fields2, MyStruct, field, MY_CONST); |
| |
| pub fn check_fields(s: MyStruct) { |
| test_fields!(check_fields_of s); |
| } |
| |
| pub fn check_fields_local() { |
| test_fields!(check_fields); |
| test_fields2!(check_fields); |
| |
| let s1 = test_fields!(construct); |
| test_fields!(check_fields_of s1); |
| |
| let s2 = test_fields2!(construct); |
| test_fields2!(check_fields_of s2); |
| } |