Associated Types and Advanced Traits

Trait Implementation Conflicts

A trait implementation conflict (E0119) occurs when two impl blocks for the same trait could apply to the same concrete type, violating Rust's coherence guarantee that at most one implementation of a trait exists for any given type.

Blanket vs. Concrete Implementation Overlap (E0119)

If a trait has a blanket implementation impl<T: Bound> MyTrait for T, you cannot also write a separate impl MyTrait for SpecificType if SpecificType implements (or could in the future implement) Bound:

// ❌ does not compile
use std::fmt::Display;

trait Describe {
    fn describe(&self) -> String;
}

impl<T: Display> Describe for T {
    fn describe(&self) -> String {
        format!("value: {self}")
    }
}

// Conflicts because `String` already implements `Display`!
impl Describe for String {
    fn describe(&self) -> String {
        format!("string ({} bytes): {self}", self.len())
    }
}

fn main() {}
error[E0119]: conflicting implementations of trait `Describe` for type `String`
  --> src/main.rs:14:1
   |
8  | impl<T: Display> Describe for T {
   | ------------------------------- first implementation here
...
14 | impl Describe for String {
   | ^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `String`

Two Blanket Implementations with Overlapping Bounds (E0119)

Even if no type in your crate currently implements both TraitA and TraitB, the compiler rejects two blanket implementations impl<T: TraitA> Target for T and impl<T: TraitB> Target for T because a downstream or future type could implement both TraitA and TraitB:

// ❌ does not compile
trait FastSerialize {}
trait CompactSerialize {}

trait WireFormat {
    fn encode(&self) -> Vec<u8>;
}

impl<T: FastSerialize> WireFormat for T {
    fn encode(&self) -> Vec<u8> {
        vec![1]
    }
}

impl<T: CompactSerialize> WireFormat for T {
    fn encode(&self) -> Vec<u8> {
        vec![2]
    }
}

fn main() {}
error[E0119]: conflicting implementations of trait `WireFormat`
  --> src/main.rs:14:1
   |
8  | impl<T: FastSerialize> WireFormat for T {
   | --------------------------------------- first implementation here
...
14 | impl<T: CompactSerialize> WireFormat for T {
   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation

Upstream Blanket Implementation Hazard (impl<T: UpstreamTrait> MyTrait for T)

Rust even rejects a blanket impl<T: Copy> MyTrait for Vec<T> alongside impl MyTrait for Vec<String>, or impl<T: Display> MyTrait for T alongside impl MyTrait for MyNonDisplayStruct when the bound is a foreign trait that the foreign crate could theoretically implement for that type in a minor release.

Resolving Implementation Conflicts with Newtypes or Marker Wrappers

To provide distinct behavior for two families of types without triggering E0119, wrap the values in explicit newtypes or selector structs instead of writing overlapping blanket implementations:

use std::fmt::{Debug, Display};

trait Render {
    fn render(&self) -> String;
}

struct AsDisplay<T>(pub T);
struct AsDebug<T>(pub T);

impl<T: Display> Render for AsDisplay<T> {
    fn render(&self) -> String {
        format!("{}", self.0)
    }
}

impl<T: Debug> Render for AsDebug<T> {
    fn render(&self) -> String {
        format!("{:?}", self.0)
    }
}

fn main() {
    let text = "hello";
    println!("Display wrapper: {}", AsDisplay(text).render());
    println!("Debug wrapper:   {}", AsDebug(text).render());
}
Display wrapper: hello
Debug wrapper:   "hello"