mirror of
				https://github.com/rust-lang/rust.git
				synced 2025-10-31 04:57:19 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			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(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 `<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(unused_tuple_struct_fields)] 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;
 | |
|     }
 | |
| }
 | 
