Skip to content

Derived trait shadows a blanket default impl, specialization unshadows but the generic impl ends up being used #55243

Open
@mzabaluev

Description

@mzabaluev

This example does not compile with 1.31.0-nightly (2018-10-20 155510e):

#![feature(specialization)]

use std::borrow::Borrow;

#[derive(PartialEq)]
struct MyString(String);

impl Borrow<str> for MyString {
    fn borrow(&self) -> &str {
        &self.0
    }
}

impl<Rhs> PartialEq<Rhs> for MyString
where
    Rhs: ?Sized + Borrow<str>,
{
    default fn eq(&self, rhs: &Rhs) -> bool {
        println!("default impl used");
        self.0 == rhs.borrow()
    }
}

#[cfg(never)]
impl PartialEq<str> for MyString {
    fn eq(&self, other: &str) -> bool {
        println!("specialized impl used");
        self.0 == other
    }
}

fn main() {
    let s = MyString(String::from("Hello, world!"));
    println!("{}", s == "Здравствуй, мир!");
}

The error output:

error[E0308]: mismatched types
  --> src/main.rs:34:25
   |
34 |     println!("{}", s == "Здравствуй, мир!");
   |                         ^^^^^^^^^^^^^^^^^^ expected struct `MyString`, found reference
   |
   = note: expected type `MyString`
              found type `&'static str`

Enabling the specialized impl PartialEq<str> makes the example work, but it prints "default impl used".

Removing the derive attribute also fixes the example, but only if the manually specialized impl is not present.

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