//! returns: 0 //! Test passing trait objects as function parameters. //! //! Exercises: trait objects passed to non-method functions, including //! both mutable and immutable trait object pointers as arguments. record Circle: Copy { radius: i32, } record Square: Copy { side: i32, } trait Shape { fn (*Shape) area() -> i32; } trait Scalable { fn (*mut Scalable) scale(factor: i32); } instance Shape for Circle { fn (c: *Circle) area() -> i32 { return c.radius * c.radius * 3; } } instance Shape for Square { fn (s: *Square) area() -> i32 { return s.side * s.side; } } instance Scalable for Circle { fn (c: *mut Circle) scale(factor: i32) { set c.radius = c.radius * factor; } } /// Accept an immutable trait object parameter. fn getArea(s: *opaque Shape) -> i32 { return s.area(); } /// Accept a mutable trait object parameter. fn doubleSize(s: *mut opaque Scalable) { s.scale(2); } /// Accept two trait object parameters. fn totalArea(a: *opaque Shape, b: *opaque Shape) -> i32 { return a.area() + b.area(); } @default fn main() -> i32 { let c = Circle { radius: 5 }; let s = Square { side: 4 }; // Pass immutable trait objects to function. let cs: *opaque Shape = &c; let ca = getArea(cs); assert ca == 75; let ss: *opaque Shape = &s; let sa = getArea(ss); assert sa == 16; // Pass two different trait objects to same function. let total = totalArea(cs, ss); assert total == 91; // Pass mutable trait object to function. let mut c2 = Circle { radius: 3 }; let sc: *mut opaque Scalable = &mut c2; doubleSize(sc); assert c2.radius == 6; return 0; }