Use trait from submodule with same name as struct
Asked Answered
C

3

11

Trying to compile the following Rust code

mod traits {
    pub trait Dog {
        fn bark(&self) {
            println!("Bow");
        }
    }
}

struct Dog;

impl traits::Dog for Dog {}

fn main() {
    let dog = Dog;
    dog.bark();
}

gives the error message

error[E0599]: no method named `bark` found for type `Dog` in the current scope
  --> src/main.rs:15:9
   |
9  | struct Dog;
   | ----------- method `bark` not found for this
...
15 |     dog.bark();
   |         ^^^^
   |
   = 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 crate::traits::Dog;
   |

If I add use crate::traits::Dog;, the error becomes:

error[E0255]: the name `Dog` is defined multiple times
  --> src/main.rs:11:1
   |
1  | use crate::traits::Dog;
   |     ------------------ previous import of the trait `Dog` here
...
11 | struct Dog;
   | ^^^^^^^^^^^ `Dog` redefined here
   |
   = note: `Dog` must be defined only once in the type namespace of this module

If I rename trait Dog to trait DogTrait, everything works. How can I use a trait from a submodule that has the same name as a struct in my main module?

Cookery answered 6/6, 2015 at 17:18 Comment(0)
R
12

You could rename the trait when importing it to get the same result without renaming the trait globally:

use traits::Dog as DogTrait;

The compiler now even suggests this:

help: you can use `as` to change the binding name of the import
   |
1  | use crate::traits::Dog as OtherDog;
   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

documentation

Rhondarhondda answered 6/6, 2015 at 17:22 Comment(0)
T
8

If you don't wish to import both (or can't for whatever reason), you can use Fully Qualified Syntax (FQS) to use the trait's method directly:

fn main() {
    let dog = Dog;
    traits::Dog::bark(&dog);
}
Trajan answered 6/6, 2015 at 17:21 Comment(0)
B
2

Underscore Import appears to be all most suitable in such use cases.

mod traits {
    pub trait Dog {
        fn bark(&self) {
            println!("Bow");
        }
    }
}

struct Dog;
impl traits::Dog for Dog {}
use traits::Dog as _;

fn main() {
    let dog = Dog;
    dog.bark();
}

Run the code in the Rust Playground.

Bicker answered 3/7 at 8:47 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.