Conflicting Trait Implementations with Auto Traits

I tried to implement a trait for all types that implement a custom auto trait (also called OIBIT), and provide additional implementation for some specific other types that don’t implement the auto trait. This only works as long as the additional implementations are not generic.

For example (playground):

#![feature(optin_builtin_traits)]

trait MyTrait {
    fn foo(&self);
}

auto trait NotBox {}
impl<T> !NotBox for Box<T> {}

impl<T: NotBox> MyTrait for T {
    fn foo(&self) {
        println!("Copy type")
    }
}

impl MyTrait for Box<u32> {
    fn foo(&self) {
        println!("Box<T>")
    }
}

This compiles without problems, which means that the compiler understands that NotBox is not implemented for Box<u32> because of the negative implementation for Box<T>.

However, when I make the second impl block generic over all boxed values, the compiler throws a “conflicting implementations” error:

impl<T> MyTrait for Box<T> {
    fn foo(&self) {
        println!("Box<T>")
    }
}

Given that the compiler understands the negative trait bound in the Box<u32> example, I assumed that it also understands the above. However, the compiler throws the following error:

error[E0119]: conflicting implementations of trait `MyTrait` for type `std::boxed::Box<_>`:
  --> src/main.rs:32:1
   |
17 | impl<T: NotBox> MyTrait for T {
   | ----------------------------- first implementation here
...
32 | impl<T> MyTrait for Box<T> {
   | ^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `std::boxed::Box<_>`

Am I missing something here? Why does the compiler think that the first implementation is conflicting when it seems to understand the negative NotBox implementation for Box<T>?

Also, is there a workaround for this problem? I tried specialization but that didn’t work, I assume because the implementations are not overlapping.

3 Likes

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.