Import Resolution
This section specifies how an import path given to @import is resolved to a source file on disk, and how the set of loaded files is computed. The @import intrinsic's argument form and its error conditions are rules 4.13:79–4.13:89 in the intrinsics section.
Resolution Order
An import path P names exactly one candidate file:
- If
Pis exactly"std", the import resolves to the standard library (see 10.2:6). - If
Pends with the.rueextension, the import resolves to the file at exactly that relative path. - Otherwise, the import resolves to the directory-module facade
{P}/_{basename}.rue(wherebasenameis the final path component ofP), and to nothing else. A file module is imported only by its extensioned spelling; a sibling{P}.rueis never a candidate for the extensionless path, so both forms may coexist without ambiguity.
A relative candidate path is resolved against exactly one base directory: the directory containing the importing file. There is no fallback base; in particular, resolution never retries relative to the root file. Adding a file therefore either satisfies a previously failing import at its one candidate path or is irrelevant to it — it can never retarget an import that already resolves.
An import path is a relative path. An empty path names no candidate, and an absolute path — one beginning with the root separator / — is not resolved against the importing file's directory at all, so 10.2:1 and 10.2:2 give it no meaning. An absolute path would also bind the program to one machine's directory layout, which the project-root-relative identity of 10.2:4 exists to prevent: the same source tree, checked out elsewhere, would stop compiling. Either shape is a compile-time error (rule 4.13:133, error E0714), decided from the path text alone, and no filesystem probe is attempted for it. The reserved specifier "std" is not a path and is not subject to this rule (10.2:6).
Transitive Loading
Importing a module loads it transitively: imports appearing in an imported file are themselves resolved and loaded, and so on, into the root module's import graph. Loading a file through this graph makes it available as a module; it does not inject the file's declarations into the importing scope. The importer of a transitively loaded file — not the root file — is the base for that file's own relative imports (per 10.2:2).
Each source file is loaded at most once per compilation, after resolving the import path to the file's canonical location: its normalized path relative to the project root, the directory containing the root file. Rule 10.2:7 makes this identity total. Two import spellings denote the same module exactly when they normalize to the same project-root-relative path; an import that resolves to an already-loaded file refers to that same module. Import cycles are therefore legal: two modules may import each other, and a chain of imports may return to its starting file.
Mutually importing modules:
// a.rue
const b = @import("b.rue");
pub fn from_a() -> i32 { 1 }
pub fn a_uses_b() -> i32 { b.from_b() }
// b.rue
const a = @import("a.rue");
pub fn from_b() -> i32 { 42 }
// main.rue
fn main() -> i32 {
let a = @import("a.rue");
a.a_uses_b() // 42
}
Standard Library Resolution
std is a reserved specifier, not a relative path: it is never searched relative to the importing file. @import("std") resolves to the standard library facade _std.rue through a fixed precedence chain, taking the first that exists:
- the program's vendored copy,
std/_std.rueunder the project root; then - the toolchain installation default,
$RUE_STD_PATH/_std.rue, when theRUE_STD_PATHenvironment variable is set.
A standard library the program ships therefore cannot be replaced by ambient environment. If neither location holds a facade, the import is a compile-time error (E0705).
Project-Root Identity
Every relative candidate path lies within the project root. An import whose normalized candidate path would fall outside the root file's directory is rejected at compile time (rule 4.13:89, error E0713); no filesystem probe is attempted for it. Standard-library modules resolve within their own root under 10.2:6 and are not subject to this rule.