//! returns: 0 //! Test trait methods returning aggregate types. //! //! Exercises: trait methods that return structs (both small and larger //! than pointer size) and optionals via v-table dispatch. record Point { x: i32, y: i32, } record Vec3 { x: i32, y: i32, z: i32, } trait Geometry { fn (*Geometry) origin() -> Point; fn (*Geometry) center() -> Vec3; fn (*Geometry) maybe() -> ?i32; } record Circle { cx: i32, cy: i32, radius: i32, } instance Geometry for Circle { fn (c: *Circle) origin() -> Point { return Point { x: c.cx, y: c.cy }; } fn (c: *Circle) center() -> Vec3 { return Vec3 { x: c.cx, y: c.cy, z: 0 }; } fn (c: *Circle) maybe() -> ?i32 { if c.radius > 0 { return c.radius; } return nil; } } @default fn main() -> i32 { let c = Circle { cx: 10, cy: 20, radius: 5 }; let g: *opaque Geometry = &c; // Small struct return (Point, 8 bytes = pointer size). let p = g.origin(); assert p.x == 10; assert p.y == 20; // Larger struct return (Vec3, 12 bytes > pointer size). let v = g.center(); assert v.x == 10; assert v.y == 20; assert v.z == 0; // Optional return - Some case. let m = g.maybe(); if let val = m { assert val == 5; } else { return 7; } // Optional return - None case. let c2 = Circle { cx: 0, cy: 0, radius: 0 }; let g2: *opaque Geometry = &c2; let m2 = g2.maybe(); if let _ = m2 { return 8; } return 0; }