Modules and Visibility

Aliasing Imports

The as keyword in a use declaration (use path::Item as Alias;) binds an imported type, trait, function, or module to a different local name in the current scope, or imports a trait anonymously (use path::Trait as _;).

Why Alias Imports?

Scenario Example Purpose
Resolving name collisions use std::fmt::Result as FmtResult; and use std::io::Result as IoResult; Allows two identically named items from different modules to coexist in the same scope
Shortening long module or type paths use crate::network::protocol::v2 as proto; Keeps call sites concise (proto::Frame) without hiding the module boundary
Anonymous trait imports (as _) use std::io::Read as _; Brings a trait's methods into scope without binding the identifier Read (preventing conflicts with another Read type or trait)
Publicly renaming re-exported items pub use self::internal::ClientV2 as Client; Exposes a clean public name while keeping versioned internal names

Resolving Name Collisions with as

Importing two items with the same name in the same scope without as causes compiler error E0252 (the name Result is defined multiple times). Aliasing one or both with as resolves the collision cleanly:

use std::fmt::{self, Result as FmtResult};
use std::io::{self, Result as IoResult};

struct Report {
    title: String,
}

impl fmt::Display for Report {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> FmtResult {
        write!(f, "Report({})", self.title)
    }
}

fn save_to_buffer(report: &Report, mut out: impl io::Write) -> IoResult<usize> {
    let text = format!("{report}\n");
    out.write(text.as_bytes())
}

fn main() {
    let rpt = Report {
        title: String::from("Q4 Metrics"),
    };
    let mut buf = Vec::new();
    let bytes_written = save_to_buffer(&rpt, &mut buf).unwrap();
    println!("Wrote {bytes_written} bytes: {}", String::from_utf8_lossy(&buf).trim());
}
Wrote 19 bytes: Report(Q4 Metrics)

Anonymous Trait Imports (use Trait as _;)

When both std::fmt::Write and std::io::Write are needed in the same file, importing both by name collides on the identifier Write. Importing traits with as _ makes their methods callable without introducing any identifier into the namespace:

use std::fmt::Write as _; // Unlocks `String::write_fmt` without binding the name `Write`

fn main() {
    let mut s = String::new();
    write!(&mut s, "id = {}", 42).unwrap();
    println!("{s}");
}
id = 42

Aliasing Inside Grouped use Lists

The as keyword can also be used on individual entries inside a braced {...} import list:

use std::collections::{
    BTreeMap as OrderedMap,
    HashMap as FastMap,
};

fn main() {
    let mut fast = FastMap::new();
    fast.insert("a", 1);

    let mut ordered = OrderedMap::new();
    ordered.insert("a", 1);

    println!("fast: {fast:?}, ordered: {ordered:?}");
}
fast: {"a": 1}, ordered: {"a": 1}