简体   繁体   中英

Rust can't find trait implementation

I'm trying to implement the Add trait for anything that implements another trait (in the example code the Test trait). I'm using references in the Add implementation because not everything that implements Test will be the same size. The code below compiles fine:

use std::ops::Add;

struct Foo(i32);
struct Bar(i64);

trait Test {}

impl Test for Foo {}
impl Test for Bar {}

impl<'a, 'b> Add<&'b Test> for &'a Test {
    type Output = Box<Test>;

    fn add(self, other: &'b Test) -> Box<Test> {
        if true {
            Box::new(Foo(5))
        } else {
            Box::new(Bar(5))
        }
    }   
}

When I try to actually use Add , as below, it says that the operation could not be applied because the implementation of Add for &Foo is missing.

fn test_add() {
    &Foo(5) + &Bar(5)
}

Have I defined the implementation incorrectly? Have I called it incorrectly? The goal is to make the function add take two references to objects which both implement Test , and return a reference (or box) to a new object that implements Test (and might not be the same underlying type as either of the inputs).

I found another approach that changes the behavior slightly, but works.

struct V<T>(T);

use std::ops::Add;
impl<T1: Test, T2: Test> Add<V<Box<T2>>> for V<Box<T1>> {
    type Output = V<Box<Test>>;
    fn add(self, other: V<Box<T2>>) -> Self::Output {
        unimplemented!()
    }
}

That allows it to return any type that implements Test , at the cost of wrapping everything in a Box and a dummy struct V . Not very elegant, and I still don't understand why my original code doesn't work, but at least this has the behavior I wanted.

The problem is that the compiler cannot implicitly convert from &Foo into &Test . If you explicitly convert it into &Test first, then the operator overloading works:

fn test_add() {
    let foo: &Test = &Foo(5);
    foo + &Bar(5);
}

Alternatively, you can use the fully qualified syntax :

fn test_add() {
    <&Test as Add<&Test>>::add(&Foo(5), &Bar(5));
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM