]> git.proxmox.com Git - rustc.git/blame - src/test/ui/methods/method-probe-no-guessing-dyn-trait.rs
New upstream version 1.67.1+dfsg1
[rustc.git] / src / test / ui / methods / method-probe-no-guessing-dyn-trait.rs
CommitLineData
416331ca 1// run-pass
0731742a
XL
2// Check that method matching does not make "guesses" depending on
3// Deref impls that don't eventually end up being picked.
4
5use std::ops::Deref;
6
7// An impl with less derefs will get called over an impl with more derefs,
8// so `(t: Foo<_>).my_fn()` will use `<Foo<u32> as MyTrait1>::my_fn(t)`,
9// and does *not* force the `_` to equal `()`, because the Deref impl
10// was *not* used.
11
12trait MyTrait1 {
13 fn my_fn(&self) {}
14}
15
16impl MyTrait1 for Foo<u32> {}
17
064997fb 18struct Foo<T>(#[allow(unused_tuple_struct_fields)] T);
0731742a
XL
19
20impl Deref for Foo<()> {
21 type Target = dyn MyTrait1 + 'static;
22 fn deref(&self) -> &(dyn MyTrait1 + 'static) {
23 panic!()
24 }
25}
26
27// ...but if there is no impl with less derefs, the "guess" will be
28// forced, so `(t: Bar<_>).my_fn2()` is `<dyn MyTrait2 as MyTrait2>::my_fn2(*t)`,
29// and because the deref impl is used, the `_` is forced to equal `u8`.
30
31trait MyTrait2 {
32 fn my_fn2(&self) {}
33}
34
35impl MyTrait2 for u32 {}
064997fb 36struct Bar<T>(#[allow(unused_tuple_struct_fields)] T, u32);
0731742a
XL
37impl Deref for Bar<u8> {
38 type Target = dyn MyTrait2 + 'static;
39 fn deref(&self) -> &(dyn MyTrait2 + 'static) {
40 &self.1
41 }
42}
43
44// actually invoke things
45
46fn main() {
47 let mut foo: Option<Foo<_>> = None;
48 let mut bar: Option<Bar<_>> = None;
49 let mut first_iter = true;
50 loop {
51 if !first_iter {
52 foo.as_ref().unwrap().my_fn();
53 bar.as_ref().unwrap().my_fn2();
54 break;
55 }
56 foo = Some(Foo(0));
57 bar = Some(Bar(Default::default(), 0));
58 first_iter = false;
59 }
60}