1 // ignore-tidy-linelength
5 // There are five cfg's below. I explored the set of all non-empty combinations
6 // of the below five cfg's, which is 2^5 - 1 = 31 combinations.
8 // Of the 31, 11 resulted in ambiguous method resolutions; while it may be good
9 // to have a test for all of the eleven variations of that error, I am not sure
10 // this particular test is the best way to encode it. So they are skipped in
11 // this revisions list (but not in the expansion mapping the binary encoding to
12 // the corresponding cfg flags).
14 // Notable, here are the cases that will be incompatible if something does not override them first:
15 // {bar_for_foo, valbar_for_et_foo}: these are higher precedent than the `&mut self` method on `Foo`, and so no case matching bx1x1x is included.
16 // {mutbar_for_foo, valbar_for_etmut_foo} (which are lower precedent than the inherent `&mut self` method on `Foo`; e.g. b10101 *is* included.
18 // revisions: b00001 b00010 b00011 b00100 b00101 b00110 b00111 b01000 b01001 b01100 b01101 b10000 b10001 b10010 b10011 b10101 b10111 b11000 b11001 b11101
20 //[b00001]compile-flags: --cfg inherent_mut
21 //[b00010]compile-flags: --cfg bar_for_foo
22 //[b00011]compile-flags: --cfg inherent_mut --cfg bar_for_foo
23 //[b00100]compile-flags: --cfg mutbar_for_foo
24 //[b00101]compile-flags: --cfg inherent_mut --cfg mutbar_for_foo
25 //[b00110]compile-flags: --cfg bar_for_foo --cfg mutbar_for_foo
26 //[b00111]compile-flags: --cfg inherent_mut --cfg bar_for_foo --cfg mutbar_for_foo
27 //[b01000]compile-flags: --cfg valbar_for_et_foo
28 //[b01001]compile-flags: --cfg inherent_mut --cfg valbar_for_et_foo
29 //[b01010]compile-flags: --cfg bar_for_foo --cfg valbar_for_et_foo
30 //[b01011]compile-flags: --cfg inherent_mut --cfg bar_for_foo --cfg valbar_for_et_foo
31 //[b01100]compile-flags: --cfg mutbar_for_foo --cfg valbar_for_et_foo
32 //[b01101]compile-flags: --cfg inherent_mut --cfg mutbar_for_foo --cfg valbar_for_et_foo
33 //[b01110]compile-flags: --cfg bar_for_foo --cfg mutbar_for_foo --cfg valbar_for_et_foo
34 //[b01111]compile-flags: --cfg inherent_mut --cfg bar_for_foo --cfg mutbar_for_foo --cfg valbar_for_et_foo
35 //[b10000]compile-flags: --cfg valbar_for_etmut_foo
36 //[b10001]compile-flags: --cfg inherent_mut --cfg valbar_for_etmut_foo
37 //[b10010]compile-flags: --cfg bar_for_foo --cfg valbar_for_etmut_foo
38 //[b10011]compile-flags: --cfg inherent_mut --cfg bar_for_foo --cfg valbar_for_etmut_foo
39 //[b10100]compile-flags: --cfg mutbar_for_foo --cfg valbar_for_etmut_foo
40 //[b10101]compile-flags: --cfg inherent_mut --cfg mutbar_for_foo --cfg valbar_for_etmut_foo
41 //[b10110]compile-flags: --cfg bar_for_foo --cfg mutbar_for_foo --cfg valbar_for_etmut_foo
42 //[b10111]compile-flags: --cfg inherent_mut --cfg bar_for_foo --cfg mutbar_for_foo --cfg valbar_for_etmut_foo
43 //[b11000]compile-flags: --cfg valbar_for_et_foo --cfg valbar_for_etmut_foo
44 //[b11001]compile-flags: --cfg inherent_mut --cfg valbar_for_et_foo --cfg valbar_for_etmut_foo
45 //[b11010]compile-flags: --cfg bar_for_foo --cfg valbar_for_et_foo --cfg valbar_for_etmut_foo
46 //[b11011]compile-flags: --cfg inherent_mut --cfg bar_for_foo --cfg valbar_for_et_foo --cfg valbar_for_etmut_foo
47 //[b11100]compile-flags: --cfg mutbar_for_foo --cfg valbar_for_et_foo --cfg valbar_for_etmut_foo
48 //[b11101]compile-flags: --cfg inherent_mut --cfg mutbar_for_foo --cfg valbar_for_et_foo --cfg valbar_for_etmut_foo
49 //[b11110]compile-flags: --cfg bar_for_foo --cfg mutbar_for_foo --cfg valbar_for_et_foo --cfg valbar_for_etmut_foo
50 //[b11111]compile-flags: --cfg inherent_mut --cfg bar_for_foo --cfg mutbar_for_foo --cfg valbar_for_et_foo --cfg valbar_for_etmut_foo
54 type S = &'static str;
57 fn bar(&self, _: &str) -> S;
61 fn bar(&mut self, _: &str) -> S;
65 fn bar(self, _: &str) -> S;
70 fn bar(&mut self, _: &str) -> S {
77 fn bar(&self, _: &str) -> S {
78 "In trait &self impl!"
82 #[cfg(mutbar_for_foo)]
84 fn bar(&mut self, _: &str) -> S {
85 "In trait &mut self impl!"
89 #[cfg(valbar_for_et_foo)]
90 impl ValBar for &Foo {
91 fn bar(self, _: &str) -> S {
92 "In trait self impl for &Foo!"
96 #[cfg(valbar_for_etmut_foo)]
97 impl ValBar for &mut Foo {
98 fn bar(self, _: &str) -> S {
99 "In trait self impl for &mut Foo!"
104 #![allow(unused_mut)] // some of the impls above will want it.
106 #![allow(unreachable_patterns)] // the cfg-coding pattern below generates unreachable patterns.
109 macro_rules! all_variants_on_value {
113 x => assert_eq!(x, "In trait &self impl!"),
115 #[cfg(valbar_for_et_foo)]
116 x => assert_eq!(x, "In trait self impl for &Foo!"),
119 x => assert_eq!(x, "In struct impl!"),
121 #[cfg(mutbar_for_foo)]
122 x => assert_eq!(x, "In trait &mut self impl!"),
124 #[cfg(valbar_for_etmut_foo)]
125 x => assert_eq!(x, "In trait self impl for &mut Foo!"),
131 all_variants_on_value!(f.bar("f.bar"));
133 let f_mr = &mut Foo {};
134 all_variants_on_value!((*f_mr).bar("(*f_mr).bar"));
137 // This is sort of interesting: `&mut Foo` ends up with a significantly
138 // different resolution order than what was devised above. Presumably this
139 // is because we can get to a `&self` method by first a deref of the given
140 // `&mut Foo` and then an autoref, and that is a longer path than a mere
141 // auto-ref of a `Foo`.
144 let f_mr = &mut Foo {};
146 match f_mr.bar("f_mr.bar") {
148 x => assert_eq!(x, "In struct impl!"),
150 #[cfg(valbar_for_etmut_foo)]
151 x => assert_eq!(x, "In trait self impl for &mut Foo!"),
153 #[cfg(mutbar_for_foo)]
154 x => assert_eq!(x, "In trait &mut self impl!"),
156 #[cfg(valbar_for_et_foo)]
157 x => assert_eq!(x, "In trait self impl for &Foo!"),
160 x => assert_eq!(x, "In trait &self impl!"),
165 // Note that this isn't actually testing a resolution order; if both of these are
166 // enabled, it yields an ambiguous method resolution error. The test tries to embed
167 // that fact by testing *both* orders (and so the only way that can be right is if
168 // they are not actually compatible).
169 #[cfg(any(bar_for_foo, valbar_for_et_foo))]
173 match f_r.bar("f_r.bar") {
175 x => assert_eq!(x, "In trait &self impl!"),
177 #[cfg(valbar_for_et_foo)]
178 x => assert_eq!(x, "In trait self impl for &Foo!"),
181 match f_r.bar("f_r.bar") {
182 #[cfg(valbar_for_et_foo)]
183 x => assert_eq!(x, "In trait self impl for &Foo!"),
186 x => assert_eq!(x, "In trait &self impl!"),