Characteristic implementation for reference and non-reference types causes conflicting implementations

I am trying to create a tag and provide one implementation for all types without a reference, and another for all reference types.

This will not compile:

trait Foo {}
impl<T> Foo for T {}
impl<'a, T> Foo for &'a mut T {}

This does not fail

error[E0119]: conflicting implementations of trait `Foo` for type `&mut _`:
 --> src/main.rs:3:1
  |
2 | impl<T> Foo for T {}
  | -------------------- first implementation here
3 | impl<'a, T> Foo for &'a mut T {}
  | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `&mut _`

Oddly enough, this works:

trait Bar {}

impl<T> Bar for T
where
    T: Clone,
{}

impl<'a, T> Bar for &'a mut T
where
    T: Clone + 'static,
{}

Why does the limited version work Cloneand how can I make it work without it?

+4
source share
2 answers

As you know, a common one Tcan be anything¹, therefore Fooimpls overlaps (conflicts) whenever Tin the first implementation &'a mut U, because the second impl also covers this case (when T U).

Clone , &mut Clone, T where T: Clone &'a mut TBar (&), , Clone.

[H] ow ?

"" , , , Rust , struct, enum s: ( Rust).

, , , , , " ", , , :

impl Foo for u32 { ... }
impl Foo for i32 { ... }
impl<'a, T> Foo for &'a T where T: Foo + 'a { ... }
impl<'a, T> Foo for &'a mut T where T: Foo + 'a { ... }

¹ , , Sized, . ?Sized, , .

² where T: Clone + 'static , &'a mut T Clone, T.

+6

Clone , , , .

.

trait Foo {
    fn hi(&self){
        println!("Hi");
    }
}

Foo T impl<T> Foo for T {}, Foo. :

fn say_hi<'a>(b: &'a mut Foo){
    b.hi();
}

fn main(){
    let mut five = 5;

    five.hi(); // integer using Foo
    say_hi(&mut five); // &'a mut Foo
}

, impl<'a,T> Foo for &'a mut T {}, impl<T> Foo for T {} , , .

, , , , Clone , T, Clone &'a mut T, Clone+static

+2

Source: https://habr.com/ru/post/1692674/


All Articles