2018 modules again

There is something wrong with rust module system. I made tests on darwin, arch and debian and I come to conclusion, that you cannot import file, that is on the same directory with main.rs

Crate type is binary, edition is set to 2018

On all systems latest stable update 1.31

Here is project tree:


name = "rust_2018"
version = "0.1.0"
edition = "2018"


use foo::call_foo;

fn main() {
    println!("Hello, world!");


pub fn call_foo() {

None of this did not make project to build:

use crate::foo::call_foo;
use self::foo::call_foo;
use super::foo::call_foo;
use rust_2018::foo::call_foo;

mod foo;
use foo::call_foo;

Errors are:

error[E0432]: unresolved import `crate::foo`
error[E0432]: unresolved import `self::foo`
error[E0433]: failed to resolve. There are too many initial `super`s.
error[E0433]: failed to resolve. Could not find `rust_2018` in `{{root}}`
error[E0432]: unresolved import `foo`

The only way to import foo module is to create lib.rs with
pub mod foo;
and import in main.rs
use rust_2018::foo:call_foo;
note that use self::foo::call_foo; is not working

What I’m missing? Maybe I misunderstood how are modules work in 2018 edition?

You always have to declare the module. Once declared, you can import references from it, e.g. use crate::foo::call_foo; The edition guide is the best source of info AFAIK. But it may need some improvement, if it’s still confusing?

For me it is not clear, what you mean by declare? Create lib.rs with pub mod foo or in the first line of foo.rs mod foo or something else? The No more mods section (https://rust-lang-nursery.github.io/edition-guide/rust-2018/module-system/path-clarity.html#no-more-modrs) tells that now we can omit mod.rs files. For my example, I assume that foo.rs would be enough for importing in main.rs

mod foo; is a declaration of a module named foo. The module may be inline, or in another file.

mod foo {
    pub fn bar() {
        println!("Hello, world!");

You can omit mod.rs files, but you cannot omit the mod keyword; the mod keyword declares the module and brings it into scope. See https://doc.rust-lang.org/reference/items/modules.html for documentation on the keyword, and some relevant information to the module system.

1 Like

mod foo works the same way as struct foo or fn foo – it creates a new item with that name in the module where you write that declaration. That name works as-is in the same module, but needs to be imported to be seen elsewhere.