Search code examples
rusttraitsworkspacerust-crates

How can I use a trait implementation from another crate in the original crate?


I have a Rust project which divided among several crates in a workspace. One of these crates is a test crate which holds utilities for use in unit and integration tests within the other crates.

In one crate I define a trait that is implemented by a struct in the test crate. However, when I try to use the struct from the test crate in the original crate which defined the trait, I encounter errors when trying to use the trait's member functions.

Here is a short example:

In the project-trait crate:

trait Trait {
    fn do_something(&self)
}

In the project-test crate:

use project_trait::Trait;

pub struct TestObject;

impl Trait for TestObject {
    fn do_something(&self) {
        // ...
    }
}

Finally, back in the project-trait crate:

#[cfg(test)]
mod test {
    use crate::Trait;
    use project_test::TestObject;

    #[test]
    fn use_test_object() {
        let object = TestObject;
        object.do_something();
    }
}

When running cargo test in the project-trait crate, I get error E0599 which says I should import project_trait::Trait to use the do_something method. It seems Rust doesn't see that crate::Trait and project_trait::Trait are the same trait.

Is there any workaround for this?


Solution

  • There can't be cycles in the crate dependency graph. Therefore, whatever you've actually done in your project configuration, it can't be that the #[cfg(test)] code that is depending on project-test is using the same crate::Trait as what project-test sees as project_trait::Trait.

    You have probably done something that causes some of the code to be compiled as part of a different crate (such as misuse of mod so as to compile the same source file in two crates). The result of this is that you have two different traits that happen to both be named Trait. Thus, you get an error because the one that TestObject implements is not the same as the one you have imported.

    (In order to get a more precise explanation of what's going wrong, you'll need to provide a more complete example — preferably reproducible, i.e. "if I copy these files into a local folder they will be sufficient to demonstrate the problem".)

    In general, whatever code is needed to run project-trait's tests must be part of the project-trait crate or its dependencies — you can't split out test helpers into an independent library crate.