Traits

Supertraits

A supertrait is a prerequisite trait declared on another trait (trait Sub: Super), requiring every type that implements Sub to also implement Super.

Declaring Single and Multiple Supertraits

List one or more supertraits after a colon (:) on the trait header, separated by + (or write where Self: SuperA + SuperB):

use std::fmt::Display;

trait Positioned {
    fn coords(&self) -> (i32, i32);
}

// `MapMarker` has two supertraits: `Positioned` and `Display`
trait MapMarker: Positioned + Display {
    fn render_pin(&self) -> String {
        let (x, y) = self.coords();
        format!("{self} @ ({x}, {y})")
    }
}

struct Waypoint {
    label: &'static str,
    x: i32,
    y: i32,
}

impl Positioned for Waypoint {
    fn coords(&self) -> (i32, i32) {
        (self.x, self.y)
    }
}

impl Display for Waypoint {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        write!(f, "[{}]", self.label)
    }
}

impl MapMarker for Waypoint {}

fn main() {
    let wp = Waypoint {
        label: "Summit",
        x: 120,
        y: -45,
    };
    println!("{}", wp.render_pin());
}
[Summit] @ (120, -45)

Missing Supertrait Implementation Error (E0277)

Attempting to implement a subtrait for a type that does not implement all of its supertraits fails at compile time with E0277:

// ❌ does not compile
trait Base {
    fn id(&self) -> u32;
}

trait Derived: Base {}

struct Item;

impl Derived for Item {}

fn main() {}
error[E0277]: the trait bound `Item: Base` is not satisfied
  --> src/main.rs:10:18
   |
10 | impl Derived for Item {}
   |                  ^^^^ the trait `Base` is not implemented for `Item`
   |
note: required by a bound in `Derived`
  --> src/main.rs:6:16
   |
6  | trait Derived: Base {}
   |                ^^^^ required by this bound in `Derived`

Standard Library Supertrait Hierarchies

Many core traits in the standard library are linked by supertrait relationships:

Subtrait Supertrait(s) Additional Guarantee or Capability
Copy Clone Bitwise memcpy semantics in addition to explicit .clone()
Eq PartialEq Reflexivity (a == a is always true) in addition to symmetric/transitive equality
Ord Eq + PartialOrd Total ordering across all values of Self
std::error::Error Debug + Display Human-readable and developer-readable formatting for every error
Fn FnMut (which has supertrait FnOnce) Shared-reference invocation implies mutable-reference and by-value invocation
ExactSizeIterator Iterator Known exact remaining length (len()) on an iterator

Trait Object Upcasting (&dyn Sub to &dyn Super)

In modern stable Rust (since Rust 1.86 / 2024 edition), a trait object reference or smart pointer for a subtrait (&dyn Sub or Box<dyn Sub>) can be upcast directly to a trait object of any of its dyn-compatible supertraits (&dyn Super or Box<dyn Super>):

trait Device {
    fn device_name(&self) -> &str;
}

trait NetworkDevice: Device {
    fn ip_address(&self) -> &str;
}

struct Router;

impl Device for Router {
    fn device_name(&self) -> &str {
        "core-router-01"
    }
}

impl NetworkDevice for Router {
    fn ip_address(&self) -> &str {
        "10.0.0.1"
    }
}

fn inspect_device(dev: &dyn Device) {
    println!("Device name: {}", dev.device_name());
}

fn main() {
    let router = Router;
    let net_dev: &dyn NetworkDevice = &router;

    println!("IP: {}", net_dev.ip_address());
    // Implicitly upcasts `&dyn NetworkDevice` to `&dyn Device`:
    inspect_device(net_dev);
}
IP: 10.0.0.1
Device name: core-router-01