1 #![feature(decl_macro)]
2 
3 #[derive(PartialEq, Eq, Debug)]
4 pub enum Method {
5     DefaultMacroCtxt,
6     DefaultRootCtxt,
7     OverrideMacroCtxt,
8     OverrideRootCtxt,
9 }
10 
11 #[rustfmt::skip]
12 macro x($macro_name:ident, $macro2_name:ident, $trait_name:ident, $method_name:ident) {
13     pub trait $trait_name {
method(&self) -> Method14         fn method(&self) -> Method {
15             Method::DefaultMacroCtxt
16         }
17 
18         fn $method_name(&self) -> Method {
19             Method::DefaultRootCtxt
20         }
21     }
22 
23     impl $trait_name for () {}
24     impl $trait_name for bool {
method(&self) -> Method25         fn method(&self) -> Method {
26             Method::OverrideMacroCtxt
27         }
28 
29         fn $method_name(&self) -> Method {
30             Method::OverrideRootCtxt
31         }
32     }
33 
34     #[macro_export]
35     macro_rules! $macro_name {
36         (check_resolutions) => {
37             assert_eq!(().method(), Method::DefaultMacroCtxt);
38             assert_eq!($trait_name::method(&()), Method::DefaultMacroCtxt);
39             assert_eq!(().$method_name(), Method::DefaultRootCtxt);
40             assert_eq!($trait_name::$method_name(&()), Method::DefaultRootCtxt);
41 
42             assert_eq!(false.method(), Method::OverrideMacroCtxt);
43             assert_eq!($trait_name::method(&false), Method::OverrideMacroCtxt);
44             assert_eq!(false.$method_name(), Method::OverrideRootCtxt);
45             assert_eq!($trait_name::$method_name(&false), Method::OverrideRootCtxt);
46 
47             assert_eq!('a'.method(), Method::DefaultMacroCtxt);
48             assert_eq!($trait_name::method(&'a'), Method::DefaultMacroCtxt);
49             assert_eq!('a'.$method_name(), Method::DefaultRootCtxt);
50             assert_eq!($trait_name::$method_name(&'a'), Method::DefaultRootCtxt);
51 
52             assert_eq!(1i32.method(), Method::OverrideMacroCtxt);
53             assert_eq!($trait_name::method(&1i32), Method::OverrideMacroCtxt);
54             assert_eq!(1i32.$method_name(), Method::OverrideRootCtxt);
55             assert_eq!($trait_name::$method_name(&1i32), Method::OverrideRootCtxt);
56 
57             assert_eq!(1i64.method(), Method::OverrideMacroCtxt);
58             assert_eq!($trait_name::method(&1i64), Method::OverrideMacroCtxt);
59             assert_eq!(1i64.$method_name(), Method::OverrideRootCtxt);
60             assert_eq!($trait_name::$method_name(&1i64), Method::OverrideRootCtxt);
61         };
62         (assert_no_override $v:expr) => {
63             assert_eq!($v.method(), Method::DefaultMacroCtxt);
64             assert_eq!($trait_name::method(&$v), Method::DefaultMacroCtxt);
65             assert_eq!($v.$method_name(), Method::DefaultRootCtxt);
66             assert_eq!($trait_name::$method_name(&$v), Method::DefaultRootCtxt);
67         };
68         (assert_override $v:expr) => {
69             assert_eq!($v.method(), Method::OverrideMacroCtxt);
70             assert_eq!($trait_name::method(&$v), Method::OverrideMacroCtxt);
71             assert_eq!($v.$method_name(), Method::OverrideRootCtxt);
72             assert_eq!($trait_name::$method_name(&$v), Method::OverrideRootCtxt);
73         };
74         (impl for $t:ty) => {
75             impl $trait_name for $t {
method(&self) -> Method76                 fn method(&self) -> Method {
77                     Method::OverrideMacroCtxt
78                 }
79 
80                 fn $method_name(&self) -> Method {
81                     Method::OverrideRootCtxt
82                 }
83             }
84         };
85     }
86 
87     pub macro $macro2_name {
88         (check_resolutions) => {
89             assert_eq!(().method(), Method::DefaultMacroCtxt);
90             assert_eq!($trait_name::method(&()), Method::DefaultMacroCtxt);
91             assert_eq!(().$method_name(), Method::DefaultRootCtxt);
92             assert_eq!($trait_name::$method_name(&()), Method::DefaultRootCtxt);
93 
94             assert_eq!(false.method(), Method::OverrideMacroCtxt);
95             assert_eq!($trait_name::method(&false), Method::OverrideMacroCtxt);
96             assert_eq!(false.$method_name(), Method::OverrideRootCtxt);
97             assert_eq!($trait_name::$method_name(&false), Method::OverrideRootCtxt);
98 
99             assert_eq!('a'.method(), Method::DefaultMacroCtxt);
100             assert_eq!($trait_name::method(&'a'), Method::DefaultMacroCtxt);
101             assert_eq!('a'.$method_name(), Method::DefaultRootCtxt);
102             assert_eq!($trait_name::$method_name(&'a'), Method::DefaultRootCtxt);
103 
104             assert_eq!(1i32.method(), Method::OverrideMacroCtxt);
105             assert_eq!($trait_name::method(&1i32), Method::OverrideMacroCtxt);
106             assert_eq!(1i32.$method_name(), Method::OverrideRootCtxt);
107             assert_eq!($trait_name::$method_name(&1i32), Method::OverrideRootCtxt);
108 
109             assert_eq!(1i64.method(), Method::OverrideMacroCtxt);
110             assert_eq!($trait_name::method(&1i64), Method::OverrideMacroCtxt);
111             assert_eq!(1i64.$method_name(), Method::OverrideRootCtxt);
112             assert_eq!($trait_name::$method_name(&1i64), Method::OverrideRootCtxt);
113         },
114         (assert_no_override $v:expr) => {
115             assert_eq!($v.method(), Method::DefaultMacroCtxt);
116             assert_eq!($trait_name::method(&$v), Method::DefaultMacroCtxt);
117             assert_eq!($v.$method_name(), Method::DefaultRootCtxt);
118             assert_eq!($trait_name::$method_name(&$v), Method::DefaultRootCtxt);
119         },
120         (assert_override $v:expr) => {
121             assert_eq!($v.method(), Method::OverrideMacroCtxt);
122             assert_eq!($trait_name::method(&$v), Method::OverrideMacroCtxt);
123             assert_eq!($v.$method_name(), Method::OverrideRootCtxt);
124             assert_eq!($trait_name::$method_name(&$v), Method::OverrideRootCtxt);
125         },
126         (impl for $t:ty) => {
127             impl $trait_name for $t {
method(&self) -> Method128                 fn method(&self) -> Method {
129                     Method::OverrideMacroCtxt
130                 }
131 
132                 fn $method_name(&self) -> Method {
133                     Method::OverrideRootCtxt
134                 }
135             }
136         }
137     }
138 }
139 
140 x!(test_trait, test_trait2, MyTrait, method);
141 
142 impl MyTrait for char {}
143 test_trait!(impl for i32);
144 test_trait2!(impl for i64);
145 
check_crate_local()146 pub fn check_crate_local() {
147     test_trait!(check_resolutions);
148     test_trait2!(check_resolutions);
149 }
150 
151 // Check that any comparison of idents at monomorphization time is correct
check_crate_local_generic<T: MyTrait, U: MyTrait>(t: T, u: U)152 pub fn check_crate_local_generic<T: MyTrait, U: MyTrait>(t: T, u: U) {
153     test_trait!(check_resolutions);
154     test_trait2!(check_resolutions);
155 
156     test_trait!(assert_no_override t);
157     test_trait2!(assert_no_override t);
158     test_trait!(assert_override u);
159     test_trait2!(assert_override u);
160 }
161