Specialization over generic trait parameter

I have been trying to understand the features of min_specialization and specialization on nightly and noticed something that is weird to me.

Consider the following code:

#![feature(min_specialization)]

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"); }
}

fn main() {
    Foo.myfunc(true);
    Foo.myfunc(42);
}

(Playground)

Errors:

   Compiling playground v0.0.1 (/playground)
error[E0308]: mismatched types
  --> src/main.rs:22:16
   |
22 |     Foo.myfunc(42);
   |                ^^ expected `bool`, found integer

For more information about this error, try `rustc --explain E0308`.
error: could not compile `playground` due to previous error

I would have hoped that Foo.myfunc(42) falls back to the default implementation, because (bool, Foo) is a subset of (T, Foo).

The weird thing is, if I add a second special implementation for f64 the code all of a sudden compiles and works as expected:

impl Bar<f64> for Foo
{
    fn myfunc(&self, _: f64) { println!("f64"); }
}

fn main() {
    Foo.myfunc(true);
    Foo.myfunc(42);
    Foo.myfunc(42.);
}

https://play.rust-lang.org/?version=nightly&mode=debug&edition=2018&gist=b5e65963e31da7d4cef58627be336bcc

So I have A = (T, Foo), B = (bool, Foo) and C = (f64, 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, which is completely independent of B?

Is this a bug in min_specialization? Or is there a rationale behind it that I don't understand?

Seems to be a bug. I opened an issue.

1 Like

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.