Caution

You’re reading a draft of the Ferrocene Language Specification. Some parts of this document might be missing, incomplete or incorrect. Our aim is to have the specification ready by the end of 2022.

11. Implementations

Syntax

Implementation ::=
    InherentImplementation
  | TraitImplementation

InherentImplementation ::=
    impl GenericParameterList? ImplementingType WhereClause? {
      InnerAttributeOrDoc*
      AssociatedItem*
    }

TraitImplementation ::=
    unsafe? impl GenericParameterList? !? ImplementedTrait for ImplementingType WhereClause? {
      InnerAttributeOrDoc*
      AssociatedItem*
    }

ImplementingType ::=
    TypeSpecification

ImplementedTrait ::=
    TypePath

Legality Rules

11:1 An implementation is an item that supplements an implementing type by extending its functionality.

11:2 An implementing type is the type that the associated items of an implementation are associated with.

11:3 An inherent implementation is an implementation that adds direct functionality.

11:4 An implementing type may have multiple inherent implementations. Inherent implementations of the same implementing type share a common scope.

11:5 Inherent implementations of the same implementing type shall be defined within the same crate.

11:6 A trait implementation is an implementation that adds functionality specified by a trait.

11:7 An unsafe trait implementation is a trait implementation subject to keyword unsafe.

11:8 An implemented trait is a trait whose functionality has been implemented by an implementing type.

11:9 The type path of a trait implementation shall resolve to a trait.

11:10 A trait implementation shall be an unsafe trait implementation if and only if it implements an unsafe trait.

11:11 Trait implementations are subject to implementation coherence and implementation conformance.

11:12 Inherent implementations of the same implementing type shall not define more than one associated item with the same name in the same namespace.

Examples

trait Shape {
    fn area(self) -> f64;
}

11:13 Circle is an implementing type.

struct Circle {
    radius: f64
}

11:14 The following is an inherent implementation:

impl Circle {
    fn set_radius(mut self, new_radius: f64) {
        self.radius = new_radius;
    }
}

11:15 The following is a trait implementation:

impl Shape for Circle {
    fn area(self) -> f64 {
        self.radius.powi(2) * std::f64::consts::PI
    }
}

11.1. Implementation Coherence

Legality Rules

11.1:1 A trait implementation exhibits implementation coherence when it is valid and does not overlap with another trait implementation.

11.1:2 Two trait implementations of the same implemented trait overlap when the intersection of the implementing types is non-empty.

11.1:3 Given trait implementation impl<P1, P2, .., PN> Trait<T1, T2, .., TN> for T0, the trait implementation is considered valid when

11.1:8 A trait implementation shall be coherent.

11.2. Implementation Conformance

Legality Rules

11.2:1 A trait implementation exhibits implementation conformance when it satisfies the constraints of its implemented trait.

11.2:2 An associated trait constant is conformant with an associated constant of an implemented trait when

11.2:5 An associated trait function is conformant with an associated function of an implemented trait when the function signatures of both functions are the same.

11.2:8 An associated type of a trait implementation is conformant with an associated type of an implemented trait when:

11.2:11 A trait implementation is conformant with an implemented trait when:

11.2:15 A trait implementation shall be conformant.