6

I'm trying to figure out how to compile multi-file crates in Rust, but I keep getting a compile error.

I have the file I want to import into the crate thing.rs:

mod asdf {
    pub enum stuff {
        One,
        Two,
        Three
    }
}

And my crate file test.rc:

mod thing;

use thing::asdf::*;

fn main(){

} 

When I run rust build test.rc I get:

test.rc:3:0: 3:19 error: `use` and `extern mod` declarations must precede items
test.rc:3 use thing::asdf::*;
          ^~~~~~~~~~~~~~~~~~~
error: aborting due to previous error

There's obviously something simple about how modules, crates and use work that I'm just not getting. My understanding was that mod something; for files in the same directory or extern mod something; for libraries on the library path caused the object file to be linked. Then use would allow you to import parts of the module into the current file, function or module. This seems to work for stuff in the core library.

This is with version 0.6 of the rust compiler.

4

1 回答 1

9

You just need to put the use at the top of the file:

use thing::asdf::*;

mod thing;

fn main() {}

This looks very strange, but

  1. It's what the error message says (anything that you can put at the top level that is not use or extern mod is an "item", including mods), and
  2. It's how Rust name resolution works. use is always relative to the top of the crate, and the whole crate is loaded before name resolution happens, so use thing::asdf::*; makes rustc look for thing as a submodule of the crate (which it finds), and then asdf as a submodule of that, etc.

To illustrate this last point better (and demonstrate the two special names in use, super and self, which import directly from the parent and current module respectively):

// crate.rs

pub mod foo {
    // use bar::baz; // (an error, there is no bar at the top level)

    use foo::bar::baz; // (fine)
    // use self::bar::baz; // (also fine)

    pub mod bar {
        use super::qux; // equivalent to
        // use foo::qux; 

        pub mod baz {}
    }
    pub mod qux {}
}

fn main() {}

(Also, tangentially, the .rc file extension no longer has any special meaning to any Rust tools (including in 0.6), and is deprecated, e.g. all the .rc files in the compiler source tree were recently renamed to .rs.)

于 2013-06-27T12:24:10.100 回答