Fully Qualified Syntax
Fully qualified syntax (<Type as Trait>::item) explicitly specifies both the concrete type and the trait being referenced, resolving ambiguities when accessing associated functions, methods, associated types, or associated constants.
Syntax Form
<ConcreteType as TraitName>::function_or_item(arg1, arg2, ...)
| Syntax Form | Example | When Needed |
|---|---|---|
Method call (val.method()) |
x.clone() |
Unambiguous method with a self receiver |
Trait or Type path (Trait::func(x) or Type::func(x)) |
Clone::clone(&x) |
Disambiguating which trait's method to call when Self can be inferred |
Fully qualified (<Type as Trait>::func()) |
<Dog as Animal>::baby_name() |
Associated functions without a self parameter, or nested associated types (<T as Iterator>::Item) |
Disambiguating Associated Functions Without self
When both an inherent impl block and a trait impl block define an associated function with the same name and no self parameter, calling Type::func() invokes the inherent function, while calling Trait::func() fails because the compiler cannot infer which implementing type Self refers to. Fully qualified syntax resolves the ambiguity:
trait Widget {
fn default_label() -> String;
}
struct Button;
impl Button {
fn default_label() -> String {
String::from("Submit (Inherent)")
}
}
impl Widget for Button {
fn default_label() -> String {
String::from("Click Me (Widget Trait)")
}
}
fn main() {
println!("Inherent: {}", Button::default_label());
println!("Trait: {}", <Button as Widget>::default_label());
}
Inherent: Submit (Inherent)
Trait: Click Me (Widget Trait)
Calling Widget::default_label() without <Button as Widget> fails to compile with E0790:
// ❌ does not compile
trait Widget {
fn default_label() -> String;
}
struct Button;
impl Widget for Button {
fn default_label() -> String {
String::from("Click Me")
}
}
fn main() {
let s = Widget::default_label();
}
error[E0790]: cannot call associated function on trait without specifying the corresponding `impl` type
--> src/main.rs:14:13
|
2 | fn default_label() -> String;
| ----------------------------- `Widget::default_label` defined here
...
14 | let s = Widget::default_label();
| ^^^^^^^^^^^^^^^^^^^^^^^ cannot call associated function of trait
|
help: use the fully-qualified path to the only available implementation
|
14 | let s = <Button as Widget>::default_label();
| +++++++++++ +
Accessing Nested Associated Types
Fully qualified syntax is also required when projecting an associated type through another trait's associated type, such as <I::IntoIter as Iterator>::Item when a type T implements multiple traits that each define an associated type with the same name.