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