Skip to content

Conflicing implementation through specialized default implementation #81376

Open
@vandenheuvel

Description

@vandenheuvel

In the following scenario, a local trait is default-implemented for a collection of types and once for a specific type.

#![feature([min_]specialization)]

use num::One;

trait Trait1 {
    fn f();
}

impl<T: One> Trait1 for T {
    default fn f() {}
}

impl Trait1 for u64 {
    fn f() {}
}

use std::num::NonZeroU64;
impl Trait1 for NonZeroU64 {
    fn f() {}
}

fn main() {
    let _: u64 = One::one(); // `One` is implemented for `u64`
}

This gives the error

error[E0119]: conflicting implementations of trait `Trait1` for type `std::num::NonZeroU64`:
  --> src/main.rs:19:1
   |
9  | impl<T: One> Trait1 for T {
   | ------------------------- first implementation here
...
19 | impl Trait1 for NonZeroU64 {
   | ^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `std::num::NonZeroU64`
   |
   = note: upstream crates may add a new impl of trait `num::One` for type `std::num::NonZeroU64` in future versions

Without the default keyword, the error makes sense: there would be a conflicting implementation if num::One were implemented for NonZeroU64 in the num crate. We however know that our impl Trait1 for NonZeroU64 implementation will always be more specific than the impl<T: One> Trait1 for T, so I believe that this should work.

It actually does work for u64, for which num::One is implemented. I think that this code should compile independently of whether num actually holds an implementation of num::One for the specific type. In this case it does for u64 (for which a specialization compiles) and not for NonZeroU64 (for which a specialization does is rejected).

Playground

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-specializationArea: Trait impl specializationC-bugCategory: This is a bug.F-specialization`#![feature(specialization)]`

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions