5.5. use (imports)
The use keyword (keywords) brings items of other modules into the visible name space of the current module.
5.5.1. Basic form
use_stmt ::= "use" use_tree ";"
use_tree ::= path "::" "*"
| path "::" "**"
| path "::" "{" use_tree ("," use_tree)* ","? "}"
| path ("as" identifier)?
path ::= path_root ("::" identifier)*
path_root ::= "pkg" | "sup" | identifier
Globs (*, **) take no as alias: they import many items at once, so a single alias has no meaning. path ("as" identifier)? therefore applies only to single-item imports.
use foo::bar;
use rok::std::time::Duration;
use pkg::geom::Point;
The basic structure is use, a path, and a closing ;. The last identifier of the path becomes the item's name in the current module. After the use, the item can be referred to by short names such as bar, Duration, Point.
5.5.2. Multiple imports: {...}
Several items with the same prefix can be grouped on one line.
use foo::{a, b, c};
use rok::std::time::{Duration, Instant};
Each element of {..} continues the group's resolved prefix. The prefix may be empty (pkg::{..}, sup::{..} reaching the root). Thus use p::{a, b} is, in any module, exactly:
use foo::a;
use foo::b;
- Groups may nest and may contain
*,**, andas(use foo::{bar::{x, y as z}, baz::*};). selfinside a group is an error.- Each leaf must resolve to an item, an enum variant, or a module. Otherwise it is an "unresolved import" error at that leaf.
5.5.3. Aliases: as
The as keyword renames an imported item.
use foo::very_long_name as short;
use rok::std::collections::Dict as Map;
A new name follows as; in the current module only the new name is visible, and the original name is not.
It can also be used within a multiple import.
use foo::{a as alpha, b, c as charlie};
5.5.4. Glob: * (shallow)
Imports all visible items of a module at once.
use foo::*; // all visible items of foo
Rules: * must be the last token, so a form such as use foo::*::bar is an ERROR. Only items whose visibility the caller can see are imported (visibility): items that are pub, or pub(pkg) within the same package, and so on, whose reach includes the caller. Only the direct children of foo are imported; items of submodules are not (that is the role of **). A glob use in a block also reaches the headers of the items declared in that block (3.9.1). An item the module defines wins over a glob-imported item of the same name: the glob gives way, and nothing is reported (a named import of that name is an error instead, 5.5.12).
5.5.5. Recursive glob: ** (deep)
Imports recursively, including submodules.
use foo::**; // all items of foo + all items of foo's child modules + ...
It imports every visible item through submodules at once, so its scope is much wider than the shallow glob (*). It is often used as the prelude form of a large library. A recursive glob imports module items and enum variants, never the associated items of a type: under the implicit use rok::core::**; (5.5.10), a bare MAX does not name Duration::MAX.
5.5.6. Glob / recursive glob conflicts
When several globs import the same name, a conflict occurs.
use foo::*;
use bar::*;
// if both have a name 'item', that name is ambiguous and using it is an ERROR.
Resolve it by importing one explicitly or by giving an alias.
use foo::item; // explicit - only foo::item is visible
use bar::item as bar_item; // alias - both under different names
5.5.7. Path starting points
The first identifier of a path follows the rules of paths, in three cases. pkg:: starts from the current package's root. sup:: starts from the parent module, and can be chained as sup::sup::... to go up several levels. Otherwise an ordinary identifier is usable when it is a name currently visible (a child module, an already used name, etc.). Since a child of the same module is reachable by its identifier alone, there is no separate self::.
Importing enum variants
The variants of an enum are items under that enum, so they can be imported with use. A use path may also start with a currently visible type name.
use Shape::{Circle}; // a single variant
use Shape::{Square as Sq}; // alias
use Shape::*; // all variants
use Result::*; // starts with a visible type name
The implicit use rok::core::**; (5.5.10) also imports the variants under Result, so Ok / Err can be used without a prefix. When a bare name in a pattern resolves to an imported variant, the name matches that variant rather than creating a new binding.
match r {
Ok(v) => v,
Err(e) => fallback(e),
}
5.5.8. Where use may appear
use may appear at module level or at function body level.
// module level - visible throughout that module
use foo::bar;
fn f() {
// inside a function - visible only within that function
use foo::baz;
let x = baz();
}
A use inside a function is a local import of that function and is not exposed outside. A visibility keyword (pub) therefore has no meaning there.
5.5.9. Visibility of use
use foo::bar; // module-private - visible only within the same module
pub use foo::bar; // exposed outside - re-export
pub(pkg) use foo::bar; // exposed only within the same package
pub use is a re-export. Details are defined in visibility.
5.5.10. Automatic import of rok::core
The compiler implicitly applies use rok::core::**; at the start of every rok source. The foundation tier tree of the standard library is thus visible automatically, and the items of rok::core (the most common collection types, traits, operators, etc.) can be used by short names without writing a use.
The other two tiers besides rok::core - rok::bare (the hazardous area) and rok::std (target-dependent) - are excluded from automatic visibility and require an explicit import. Details are defined in standard library tiers.
Every module outside the standard library - external packages, user libraries - also requires an explicit import. A module named prelude is not pulled in automatically. It is merely a conventional name chosen by the library author, so users must import it explicitly, as in use my_lib::prelude::*;.
// library side
pub mod prelude {
pub use pkg::api::rok::*;
pub use pkg::api::ext::*;
}
// user side
use my_lib::prelude::*; // visible only when imported explicitly
5.5.11. Importing the same module / item twice: allowed
use foo::bar;
use foo::bar; // OK - duplicate import is harmless
A duplicate import of the same item has no side effects and is allowed. When an identity check confirms it is truly the same item, it passes.
5.5.12. Same name from different modules: conflict
use foo::Item;
use bar::Item; // ERROR - 'Item' already imported
Importing the same short name from different modules is a conflict. Resolve it by aliasing one.
use foo::Item;
use bar::Item as BarItem; // OK
A named import (use a::f;, use a::{f}, or use a::f as g; for g) and an item of the same name defined in the module, in a namespace the import fills, are a compile error (E102, 9.9.4): the item would hide the import unseen. Import it under another name (use a::f as a_f;) or remove the use. A type import beside a value item of its name does not collide, and a glob import gives way to the module's items (5.5.4).
use shapes::square;
fn square(x: f64) -> f64 { x * x } // ERROR - `square` is both imported from `shapes::square` and defined in this module
5.5.13. Evaluation / effect of use
use changes only compile-time name resolution information and has no direct effect on runtime behavior. use itself executes no code; it only adds an alias to the current module's name table.
5.5.14. Importing a module itself
use foo::geom; // imports the module foo::geom itself
let p = geom::Point { ... }; // use geom as a short name
Modules themselves, not only items, can be imported. The module's name (the last identifier) then becomes visible as a short name in the current module; this is commonly used to access items through a child module.