Rust-1.79

142. Path::absolute — Make a Path Absolute Without Touching the Filesystem

Need an absolute path for a log line, an error message, or a “files will land here” preview — but the file might not exist yet? fs::canonicalize will refuse. std::path::absolute (stable since Rust 1.79) gives you the absolute form without ever opening the disk.

The canonicalize trap

The instinctive choice for “turn this into a full path” is fs::canonicalize. It works — until it doesn’t:

1
2
3
4
use std::fs;

let p = fs::canonicalize("does_not_exist.toml");
assert!(p.is_err()); // canonicalize requires the path to exist

It also resolves symlinks and walks every .. component against the real directory tree. That’s the right behaviour for finding a file. It’s wrong for printing one back to the user before you’ve written it.

path::absolute does the syntactic thing

std::path::absolute joins a relative path with the current working directory and normalises the result. No syscalls beyond looking up the CWD; the file doesn’t have to exist:

1
2
3
4
5
use std::path::absolute;

let p = absolute("config/app.toml").unwrap();
assert!(p.is_absolute());
// e.g. "/work/config/app.toml" — without ever opening anything

If the path is already absolute it’s left alone (modulo platform-specific normalisation). .. components are resolved syntactically, without consulting the filesystem for what each directory really is.

Useful for nicely-formatted output

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
use std::path::{absolute, PathBuf};

fn describe(relative: &str) -> String {
    let abs: PathBuf = absolute(relative).unwrap();
    format!("writing to {}", abs.display())
}

let msg = describe("logs/today.log");
assert!(msg.contains("logs/today.log"));
assert!(msg.starts_with("writing to "));

When you’re echoing the user’s choices back to them, or building helpful error messages, this is usually what you want — the path they meant, not whatever the filesystem turned it into.

When to reach for it

Use path::absolute for log lines, config previews, default-location calculations, or any “this is where it will go” message about a file that might not exist yet. Stick with fs::canonicalize when you actually want to follow symlinks and prove the file exists — that’s its job.

Stabilised in Rust 1.79 (June 2024).