We can't find the internet
Attempting to reconnect
Something went wrong!
Attempting to reconnect
← Modules, Visibility, Testing and Docs step 2 of 22
Paths: absolute, relative, crate::, self::, super::
Once there is a tree, you need to name things in it. Rust gives you four ways to start a path, and getting them confused is the single most common early module failure.
pub fn canonicalize(current_module: &str, path: &str) -> Result<String, String>
Given the module a path is written in — always in canonical form, "crate",
"crate::a", "crate::a::b" — resolve the path to its canonical absolute form.
The four beginnings
| written | means |
|---|---|
crate::x::Y |
start again at the crate root |
self::helper |
the current module. Explicit, and sometimes required for clarity |
super::sibling |
the parent module — one hop up the tree |
helper |
relative to the current module, like self::helper |
They compose. super::super::top climbs twice. self::super::x is legal (and
redundant — self sets the anchor to where you already were, then super
climbs from there). What is not legal is climbing past the crate root:
super from crate is a hard error, not a silent no-op. Return
Err("above crate root".to_string()) for that, and
Err("empty path".to_string()) for a path that is empty or blank.
The fifth beginning, which is not in the tree at all
Since edition 2018 a bare leading identifier is resolved against the current
module and the extern prelude — the set of external crates linked into your
build. So std::collections::HashMap written inside crate::a::b does not mean
crate::a::b::std::…; it means the std crate.
Under this harness the extern prelude contains exactly std, core and
alloc, because there is no Cargo.toml and therefore no dependencies. Treat
an unqualified leading std / core / alloc as an external crate and
return the path unchanged. Note the word unqualified: self::std::thing names a
module of your own called std, and crate::std::thing likewise. That
distinction is exactly why self:: exists.
Three errors that beginners lump together
You will meet all three in real code, and they mean genuinely different things:
-
E0433 — failed to resolve. The name is not in the tree. You misspelled it,
or you never declared the
mod. -
E0432 — unresolved import. A
usedeclaration names something that does not exist at that path. - E0603 — is private. It exists, at exactly the path you wrote, and you are not allowed to see it. This is good news: the path is right and only the visibility is wrong.
Reading the code rather than the prose saves a lot of guessing. “Not found” and “found but forbidden” call for opposite fixes.
Contract
The qualifier run (crate / self / any number of super) only ever appears
at the front of a path; rustc rejects a::super::b long before a function like
this would see it, so you do not have to handle it. Segments are plain
identifiers separated by ::.
Stuck?
Rust reference solution
Sign in to attempt this problem and reveal the reference solution.