// run-pass // Check that method matching does not make "guesses" depending on // Deref impls that don't eventually end up being picked. use std::ops::Deref; // An impl with less derefs will get called over an impl with more derefs, // so `(t: Foo<_>).my_fn()` will use ` as MyTrait1>::my_fn(t)`, // and does *not* force the `_` to equal `()`, because the Deref impl // was *not* used. trait MyTrait1 { fn my_fn(&self) {} } impl MyTrait1 for Foo {} struct Foo(#[allow(unused_tuple_struct_fields)] T); impl Deref for Foo<()> { type Target = dyn MyTrait1 + 'static; fn deref(&self) -> &(dyn MyTrait1 + 'static) { panic!() } } // ...but if there is no impl with less derefs, the "guess" will be // forced, so `(t: Bar<_>).my_fn2()` is `::my_fn2(*t)`, // and because the deref impl is used, the `_` is forced to equal `u8`. trait MyTrait2 { fn my_fn2(&self) {} } impl MyTrait2 for u32 {} struct Bar(#[allow(unused_tuple_struct_fields)] T, u32); impl Deref for Bar { type Target = dyn MyTrait2 + 'static; fn deref(&self) -> &(dyn MyTrait2 + 'static) { &self.1 } } // actually invoke things fn main() { let mut foo: Option> = None; let mut bar: Option> = None; let mut first_iter = true; loop { if !first_iter { foo.as_ref().unwrap().my_fn(); bar.as_ref().unwrap().my_fn2(); break; } foo = Some(Foo(0)); bar = Some(Bar(Default::default(), 0)); first_iter = false; } }