mirror of https://github.com/rust-lang/rust
61 lines
1.5 KiB
Rust
61 lines
1.5 KiB
Rust
//@ 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 `<Foo<u32> 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<u32> {}
|
|
|
|
struct Foo<T>(#[allow(dead_code)] 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 `<dyn MyTrait2 as MyTrait2>::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<T>(#[allow(dead_code)] T, u32);
|
|
impl Deref for Bar<u8> {
|
|
type Target = dyn MyTrait2 + 'static;
|
|
fn deref(&self) -> &(dyn MyTrait2 + 'static) {
|
|
&self.1
|
|
}
|
|
}
|
|
|
|
// actually invoke things
|
|
|
|
fn main() {
|
|
let mut foo: Option<Foo<_>> = None;
|
|
let mut bar: Option<Bar<_>> = 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;
|
|
}
|
|
}
|