Conflicting implementation for struct

Hello, can't find a similar example to understand/fix
conflicting implementation for Person<_>
I've read you can't implement same behaviour twice, but how to define it better?

pub trait Animal{
    fn feed_meal(&self)->&str;
 }

 pub trait Plant {
   fn give_water(&self)->&str;  
 }

 #[derive(Debug)]
pub struct Dog{}

impl Animal for Dog{
fn feed_meal(&self)->&str {
            "give meat"
    }
}

pub struct Rose{}

impl Plant for Rose {
    fn give_water(&self)->&str {
        "pour water"
    }
}
 
pub trait Owner {
    fn take_care(&self)->&str;
}

#[derive(Debug)]
pub struct Person<T>{
    pub pet: T,
}

impl<T> Owner for Person<T> where T: Animal {
    fn take_care(&self)->&str {
        &self.pet.feed_meal()
    }
}

impl<T> Owner for Person<T> where T: Plant {
    fn take_care(&self)->&str {
        &self.pet.give_water()
    }
}


fn main() {
    let person1 = Person{pet: Rose{}};
    print!("person1={:?}", person1.take_care());

    let person2 = Person{pet: Dog{}};
    print!("person2={:?}", person2.take_care());
}

You'd need negative trait bounds for this, which don't really exist yet except for so calles auto traits which are themself unstable.

1 Like

Rust allows a type to implement multiple traits, so there can be a T that implements both Plant and Animal. You can't forbid this.

Rust doesn't have specialization, and only allows one implementation of a trait for any type. In your case there could be two different Person.take_care possible implementations, and this is not allowed.

You will need PlantOwner and AnimalOwner traits to disambiguate them. Alternatively, do not create the Owner trait at all, and use non-trait implementation:

impl<T: Plant> Person<T> {
   pub fn water_my_plant(&self) {…}
}

Rust doesn't have classes, and the example above is why. You can have many different impl blocks for the same type, and each impl can have different requirements and be available only sometimes.

1 Like

Aha, thanks for explanation, now makes sense

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.