Using enum in different modules

Hi, everyone!
Please help with the following problem.
In the next program:

pub enum Color {
    Red,
    Green,
    Blue,
} 

// mod2.rs
#[path = "mod1.rs"] mod mod1;
use mod1::Color;
pub fn get_color() -> Color {
    Color::Blue
}

// main.rs
mod mod1;
mod mod2;
use mod1::Color;
use mod2::get_color;
fn main() {
    let color: Color = get_color();
}``` 

I have the next error:
error[E0308]: mismatched types
 --> src\main.rs:8:24
  |
8 |     let color: Color = get_color();
  |                -----   ^^^^^^^^^^^ **expected enum `mod1::Color`, found enum `mod2::mod1::Color`**
  |                |
  |                expected due to this

How do I fix this error?

Please surround your code blocks with ``` to get appropriate formatting:

As for your question: you should declare each module with mod exactly once. Here you are declaring mod1 twice, once in mod2.rs and once in main.rs. This creates two different modules, as though you'd written this:

// main.rs
mod mod1 {
    pub enum Color { Red, Green, Blue }
}

mod mod2 {
    mod mod1 {
        // this is a different type!
        pub enum Color { Red, Green, Blue }

        // refers to the `Color` from this module
        fn get_color() -> Color { /* ... */ }
    }
}

Because the declaration of Color is repeated in two different modules, Rust sees two different types. (Note that the above is valid syntax, you can define modules "inline".) Rust has a "nominal" type system, so two types that are declared in different places are considered distinct even though they have the same name and shape.

A working structure for your example is

// mod1.rs
pub enum Color { Red, Green, Blue }

// mod2.rs
use crate::mod1::Color;

pub fn get_color() -> Color { Color::Blue }

// main.rs
mod mod1;
mod mod2;

use mod1::Color;
use mod2::get_color;

Each module is declared exactly once with mod, and then items from that module are imported into other modules with the use keyword.

1 Like

Thank you very much!

1 Like

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.