Skip to content

Cow<'a, T> isn't specializable while FooCow<'a, T> is #106710

Open
@ryoqun

Description

@ryoqun

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

I tried this code:

#![feature(specialization)]

use std::borrow::Cow;
use std::clone::Clone;
use std::ops::Deref;
use std::fmt::Debug;

trait Example {
    fn example(); 
}

struct UserDefinedCow<'a, T> {
    aa: &'a T,
}

impl<T: Sized> Example for T {
    default fn example() {
        println!("default impl: {}", std::any::type_name::<Self>());
    }
}

trait JJ {
}

impl<'a, T: Example /*+ Clone */ +'a> Example for Cow<'a, T> {
    fn example() {
        println!("specialized impl (Cow): {}", std::any::type_name::<Self>());
    }
}

impl<'a, T: Example + /*JJ +*/ 'a> Example for UserDefinedCow<'a, T> {
    fn example() {
        println!("specialized impol (UserDefinedCow): {}", std::any::type_name::<Self>());
    }
}
/*
impl<T: Example> Example for Box<T> {
    fn example() {
        println!("Example from Box<T> impl: {}", std::any::type_name::<Self>());
    }
}

impl<'a, T: Example + 'a> Example for Vec<&'a T> {
    fn example() {
        println!("Example from Vec<T> impl: {}", std::any::type_name::<Self>());
    }
}
*/

fn main() {
    usize::example();
    //<Vec<&u8>>::example();
    //<Box<&u8>>::example();
    <Cow<'_, &u8>>::example();
    <UserDefinedCow<'_, &u8>>::example();
}

I expected to see this happen:

no compilation error and the output should be like this:

default impl: usize
specialized impl (Cow): alloc::borrow::Cow<&u8>
specialized impol (UserDefinedCow): playground::UserDefinedCow<&u8>

Instead, this happened:

error[[E0119]](https://doc.rust-lang.org/nightly/error-index.html#E0119): conflicting implementations of trait `Example` for type `Cow<'_, _>`
  --> src/main.rs:25:1
   |
16 | impl<T: Sized> Example for T {
   | ---------------------------- first implementation here
...
25 | impl<'a, T: Example /*+ Clone*/ +'a> Example for Cow<'a, T> {
   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `Cow<'_, _>`

Oddly enough, I found that you can specialize Cow if it's further bound with + Clone. (try to comment in), after fiddling with the code a bit.

Also, another specialization for identical type shape is allowed if it's user defined. so, i guess Cow is specially treated internally?

Meta

Nightly channel

Build using the Nightly version: 1.68.0-nightly

(2023-01-10 0442fbabe24ec43636a8)

originally found and reduced to a minimal test case above: solana-labs/solana#29596

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-specializationArea: Trait impl specializationC-bugCategory: This is a bug.F-specialization`#![feature(specialization)]`requires-incomplete-featuresThis issue requires the use of incomplete features.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions