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.
A crate is a compilation unit in Rust. Whenever rustc some_file.rs is called, some_file.rs is treated as the crate file. If some_file.rs has mod declarations in it, then the contents of the module files would be inserted in places where mod declarations in the crate file are found, before running the compiler over it.
The crate root is a source file that the Rust compiler starts from and makes up the root module of your crate (we'll explain modules in depth in the “Defining Modules to Control Scope and Privacy” section). A package is a bundle of one or more crates that provides a set of functionality. A package contains a Cargo.
From the Rust reference: Note: Previous to rustc 1.30, using mod.rs files was the way to load a module with nested children. It is encouraged to use the new naming convention as it is more consistent, and avoids having many files named mod.rs within a project.
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
use
or extern mod
is an "item", including mod
s), and 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
.)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With