How to correctly import and use trait across multiple crates

I have three crates, two lib crates and a binary crate.

The first lib crate A defines a trait in mod inner_a, below are the relevant lines from crate A.
src/lib.rs

pub mod inner_a;

src/inner_a.rs

pub trait DoThings {
    fn do_thing_1(&self);
    fn do_thing_2();
}

Then in the second lib crate that defines a struct that implies the crate.
crate B src/lib.rs

use A::inner_a::DoThings;
pub struct MyStruct {
    pub data: u32
}

impl DoThings for MyStruct {
    fn do_thing_1(&self) { println!(self.data); }
    fn do_thing_2() { todo!() }

in the binary crate I have

use A::inner_a::DoThings;
use B::MyStruct;
fn use_other_crates(my_struct: &MyStruct)  {
    my_struct.do_thing_1();
    MyStruct::do_thing_2();
}

But I get a compiler error E0599
error[E0599]: no method named do_thing_1 found for struct MyStruct in the current scope
= help: items from traits can only be used if the trait is in scope
help: the following trait is implemented but not in scope; perhaps add a use for it:
|
1 + use A::DoThing; | For more information about this error, try rustc --explain E0599.

This error occurs when a method is used on a type which doesn't implement it:

Erroneous code example:

struct Mouth;

let x = Mouth;
x.chocolate(); // error: no method named `chocolate` found for type `Mouth`                                                                                     
               //        in the current scope

In this case, you need to implement the chocolate method to fix the error:

struct Mouth;
                                                                                                                                                                
impl Mouth {
    fn chocolate(&self) { // We implement the `chocolate` method here.
        println!("Hmmm! I love chocolate!");
    }
}

let x = Mouth;
x.chocolate(); // ok!                                                                                                                                           

From what I can tell the trait is public, the struct it is implemented for is public, and there are use statements for both lib crates in the binary crate. So what am I missing?

It's a bit hard to tell whats happening based solely on your description, but based on the error message I think you may have imported the trait in the binary crate but not in the module you're using it in.

This compiles without issue. I'm using modules instead of crates so I had to tweak things a bit, but the principle is the same for crates.

mod A {
    pub mod inner_a {
        pub trait DoThings {
            fn do_thing_1(&self);
            fn do_thing_2();
        }
    }
}

mod B {
    use crate::A::inner_a::DoThings;
    pub struct MyStruct {
        pub data: u32,
    }

    impl DoThings for MyStruct {
        fn do_thing_1(&self) {
            println!("{}", self.data);
        }
        fn do_thing_2() {
            todo!()
        }
    }
}

use A::inner_a::DoThings;
use B::MyStruct;
fn use_other_crates(my_struct: &MyStruct) {
    my_struct.do_thing_1();
    MyStruct::do_thing_2();
}

If I tweak the part representing the binary crate to not import the trait for the scope where it needs to be used I get a similar error

use A::inner_a::DoThings;
mod C {
    use crate::B::MyStruct;
    fn use_other_crates(my_struct: &MyStruct) {
        my_struct.do_thing_1();
        MyStruct::do_thing_2();
    }
}

If you are already importing the trait directly into the module where you're trying to use it, you may need to create an example folder that reproduces the problem so we can get the full picture of what's happening.

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.