| //@ check-fail | |
| #![feature(specialization)] | |
| #![allow(incomplete_features)] | |
| // Tests that a `default impl` does not count as an *actual* impl, so it cannot | |
| // be used to satisfy trait bounds. | |
| // A `default impl` may omit trait items, but a real impl may not. | |
| trait Gapped { | |
| fn a(&self) -> u32; | |
| fn b(&self) -> u32; | |
| } | |
| default impl<T> Gapped for T { | |
| fn a(&self) -> u32 { | |
| 1 | |
| } | |
| } | |
| impl Gapped for u8 {} | |
| //~^ ERROR not all trait items implemented, missing: `b` | |
| // A `default impl` that defines *every* trait item is still not an impl. | |
| trait Foo { | |
| fn f(&self) -> u32; | |
| } | |
| default impl<T> Foo for T { | |
| fn f(&self) -> u32 { | |
| 1 | |
| } | |
| } | |
| fn need_foo<T: Foo>(t: &T) -> u32 { | |
| t.f() | |
| } | |
| trait Bar { | |
| fn b(&self) -> u32; | |
| } | |
| impl<T: Foo> Bar for T { | |
| fn b(&self) -> u32 { | |
| self.f() | |
| } | |
| } | |
| fn need_bar<T: Bar>(t: &T) -> u32 { | |
| t.b() | |
| } | |
| fn main() { | |
| // as a bound (UFCS `<u32 as Foo>::f` is the same trait-selection path, omitted) | |
| need_foo(&0u32); | |
| //~^ ERROR the trait bound `u32: Foo` is not satisfied | |
| // as a method-probe candidate | |
| 0u32.f(); | |
| //~^ ERROR no method named `f` found for type `u32` in the current scope | |
| // when building a vtable | |
| let _: &dyn Foo = &0u32; | |
| //~^ ERROR the trait bound `u32: Foo` is not satisfied | |
| // transitively, as another impl's where-clause | |
| need_bar(&0i64); | |
| //~^ ERROR the trait bound `i64: Bar` is not satisfied | |
| } |