Skip to content

Strange behavior when specializing over a generic trait parameter #91973

Open
@joergbrech

Description

@joergbrech

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`.

https://play.rust-lang.org/?version=nightly&mode=debug&edition=2021&gist=5b161930612fbcee70a522948c6a1fb6

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-specializationArea: Trait impl specializationC-bugCategory: This is a bug.F-specialization`#![feature(specialization)]`T-compilerRelevant to the compiler team, which will review and decide on the PR/issue.requires-nightlyThis issue requires a nightly compiler in some way.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions