Reputation: 754
I'm having a bit of a headache trying to use traits defined in separate files to the implementation and was hoping somebody could point out where I am going wrong.
My file structure is this
main.rs
file1.rs
thing.rs
Contents of main.rs
mod file1;
mod thing;
fn main() {
let item : Box<dyn file1::Trait1> = Box::new(thing::Thing {});
}
file1.rs
pub trait Trait1 {
}
thing.rs
mod file1 {
include!("file1.rs");
}
pub struct Thing {
}
impl file1::Trait1 for Thing {
}
The error on compilation is:
error[E0277]: the trait bound `thing::Thing: file1::Trait1` is not satisfied
--> src/main.rs:9:41
|
9 | let item : Box<dyn file1::Trait1> = Box::new(thing::Thing {});
| ^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `file1::Trait1` is not implemented for `thing::Thing`
|
= note: required for the cast to the object type `dyn file1::Trait1`
As far as I can tell file1::Trait1 is implemented. If not, what have I actually implemented?
Upvotes: 1
Views: 1853
Reputation: 43922
mod file1 {
include!("file1.rs");
}
By writing this in thing.rs
, you have created a module, thing::file1
, which is distinct from the top-level module file1
. Thus, you have two distinct versions of your trait, thing::file1::Trait1
and file1::Trait1
.
This is almost never the right thing. As a general principle, every .rs
file (except for main.rs
, lib.rs
, and other crate root files) should have exactly one mod
declaration.
Delete the above code from thing.rs
, and use use
instead of mod
, or a fully qualified path:
use crate::file1;
...
impl file1::Trait1 for Thing {
...
or
use crate::file1::Trait1;
...
impl Trait1 for Thing {
...
or
impl crate::file1::Trait1 for Thing {
...
In general, mod
defines a module, and use
brings items into scope. You write mod
only once per module, and use
wherever you want to refer to that module.
Upvotes: 5