diff --git a/examples/generics/phantom/testcase_units/input.md b/examples/generics/phantom/testcase_units/input.md index 373c219dd4..86a2d32246 100644 --- a/examples/generics/phantom/testcase_units/input.md +++ b/examples/generics/phantom/testcase_units/input.md @@ -2,21 +2,17 @@ A useful method of unit conversions can be examined by implementing `Add` for a phantom type. The `Add` `trait` is examined below: ```rust -// This construction would impose: `Self + RHS = Output`. +// This construction would impose: `Self + RHS = Output` +// where RHS defaults to Self if not specified in the implementation. pub trait Add { type Output; fn add(self, rhs: RHS) -> Self::Output; } -// So, `Output` must be `T` and therefore, `T + T = T`. -impl Add for T {} - -// Similarly, this imposes: `S + S = S` can be -// added only when `T + T = T`. -impl> Add for S where - T: Add { - type Output = S; +// `Output` must be `T` so that `T + T = T`. +impl Add for T { + type Output = T; ... } ``` diff --git a/examples/generics/phantom/testcase_units/units.rs b/examples/generics/phantom/testcase_units/units.rs index 38e332d037..1002e02640 100644 --- a/examples/generics/phantom/testcase_units/units.rs +++ b/examples/generics/phantom/testcase_units/units.rs @@ -1,42 +1,48 @@ use std::ops::Add; use std::marker::PhantomData; -/// Null enumerations to define unit types +/// Null enumerations define unit types. #[derive(Debug, Clone, Copy)] struct Inch; #[derive(Debug, Clone, Copy)] struct Mm; -/// Length is phantom type with hidden parameter `Unit` +/// `Length` is phantom type with hidden parameter `Unit`. +/// +/// `f64` already implements the `Clone` and `Copy` traits. #[derive(Debug, Clone, Copy)] -struct Length(T,PhantomData); +struct Length(f64,PhantomData); -// This is similar to the header except `T` must also -// implement `Clone` and `Copy. -impl Add> for Length where - T: Add + Clone + Copy { - type Output = Length; +/// The `Add` trait defines the behavior of the `+` operator. +impl Add for Length { + type Output = Length; - fn add(self, r: Length) -> Length { - Length(self.0 + r.0, PhantomData) + // add() returns a new `Length` struct containing the sum. + fn add(self, rhs: Length) -> Length { + // `+` calls the `Add` implementation for `f64`. + Length(self.0 + rhs.0, PhantomData) } } fn main() { - // Specialize one_foot to have hidden parameter `Inch` - let one_foot: Length = Length(12.0, PhantomData); - // one_meter has hidden parameter `Mm` - let one_meter: Length = Length(1000.0, PhantomData); - + // Specializes `one_foot` to have hidden parameter `Inch`. + let one_foot: Length = Length(12.0, PhantomData); + // `one_meter` has hidden parameter `Mm`. + let one_meter: Length = Length(1000.0, PhantomData); + + // `+` calls the `add()` method we implemented for `Length`. + // + // Since `Length` implements `Clone` + `Copy`, `add()` does not consume + // `one_foot` and `one_meter` but makes a copy of them in `self` and `rhs`. let two_feet = one_foot + one_foot; let two_meters = one_meter + one_meter; - // Addition works + // Addition works. println!("one foot + one_foot = {:?}", two_feet); println!("one meter + one_meter = {:?}", two_meters); - // Nonsensical operations fail as they should - // Error: type mismatch + // Nonsensical operations fail as they should: + // Error: type mismatch. //let one_feter = one_foot + one_meter; }