Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.syntblaze.com/llms.txt

Use this file to discover all available pages before exploring further.

The :: operator, formally known as the path separator, is used to construct paths for namespace resolution. It instructs the compiler to traverse module trees, traits, enumerations, and structured types to locate specific items (functions, constants, types, or modules) within a defined scope. Mechanically, :: joins path segments. A path is resolved either relative to the current lexical scope or absolutely from a root.
Qualifier::NextSegment::TargetItem

Path Resolution Mechanics

1. Module Hierarchy Traversal and Scope Import The operator navigates the module tree. It is fundamentally used in use declarations to bind a full path to a local name in the current scope. Specific keywords act as root qualifiers to dictate the starting point of the path resolution:
  • crate:: resolves the path starting from the root of the current crate.
  • super:: resolves the path starting from the parent module.
  • self:: resolves the path starting from the current module.
  • A leading :: (e.g., ::std::...) indicates a global path where the first segment must be an external crate name present in the extern prelude. In modern Rust (2018 edition and later), the current crate is not automatically added to its own extern prelude. Attempting to reference the current crate by its actual name using a leading :: will result in a compilation error; crate:: must be used instead.
// Bringing an item into scope using the path separator
use std::collections::HashMap;

pub mod sibling_module {
    pub fn do_work() {}
}

pub mod current_module {
    pub fn example() {
        // Resolving from the parent module
        super::sibling_module::do_work();
        
        // Resolving from the crate root
        crate::current_module::example_helper();
        
        // Global path resolution starting with an external crate name
        let _map = ::std::collections::HashMap::<&str, i32>::new();
    }

    pub fn example_helper() {}
}
2. Associated Items Beyond modules, :: accesses items statically associated with specific types, traits, or enumerations. This applies to associated functions, associated constants, associated types, and enum variants. It does not access fields or methods on instantiated values (which use the . operator).
enum Status {
    Active,
    Inactive,
}

struct Counter;

impl Counter {
    // Associated constant
    const MAX_CAPACITY: u32 = 100;

    // Associated function
    fn new() -> Self {
        Counter
    }
}

trait Processor {
    // Associated type
    type Output;
}

impl Processor for Counter {
    type Output = i32;
}

fn main() {
    // Enum variant resolution
    let _state = Status::Active;
    
    // Associated function resolution
    let _counter = Counter::new();
    
    // Associated constant resolution
    let _max = Counter::MAX_CAPACITY;
    let _primitive_max = u32::MAX;

    // Associated type resolution
    let _result: <Counter as Processor>::Output = 42;
}
3. Fully Qualified Syntax When multiple traits implement an item with the exact same name for a single type, :: is used in conjunction with angle brackets to explicitly disambiguate the path. This guarantees the compiler resolves the exact trait implementation required.
trait Greeter {
    fn greet() -> &'static str;
}

struct Person;

impl Greeter for Person {
    fn greet() -> &'static str {
        "Hello"
    }
}

fn main() {
    // Fully qualified syntax for trait disambiguation
    let _greeting = <Person as Greeter>::greet();
}
4. Generic Type Instantiation (Turbofish) In expression contexts, the compiler’s type inference may lack sufficient context to determine generic type parameters. The :: operator is combined with angle brackets (::<T>) to explicitly bind generic parameters to concrete types. This specific mechanical application is known as the “turbofish” syntax.
fn main() {
    // Explicit generic binding for functions
    let _parsed = "42".parse::<i32>().unwrap();

    // Explicit generic binding for types
    let _list = std::vec::Vec::<u8>::new();
}
Master Rust with Deep Grasping Methodology!Learn More