Open
Description
Consider the following code:
#![feature(min_specialization, never_type)]
pub struct Foo;
pub trait Bar<T>
{
fn myfunc(&self, _: T);
}
impl<T> Bar<T> for Foo
{
default fn myfunc(&self, _: T) { println!("default"); }
}
impl Bar<bool> for Foo
{
fn myfunc(&self, _: bool) { println!("bool"); }
}
// uncommenting the following impl will fix the compiler error
// impl Bar<!> for Foo
// {
// fn myfunc(&self, _: !) {}
// }
fn main() {
Foo.myfunc(true);
Foo.myfunc(42);
}
The compiler errors with
error[E0308]: mismatched types
--> src/main.rs:28:16
|
28 | Foo.myfunc(42);
| ^^ expected `bool`, found integer
For more information about this error, try `rustc --explain E0308`.
I would have expected that Foo.myfunc(42)
falls back to the default implementation. The weird thing is, if I uncomment the second special implementation for any other type (e.g. !
) the code all of a sudden compiles and works as expected.
So I have A = (T, Foo)
, B = (bool, Foo)
and C = (!, Foo)
, where B and C do not overlap and are both subsets of A. Why do I need the specialization C to get the specialization B to work, when C is completely independent of B?
Originally posted by @joergbrech in #31844 (comment) and https://users.rust-lang.org/t/specialization-over-generic-trait-parameter/68838