// run-pass #![feature(trait_upcasting)] trait Foo: PartialEq + std::fmt::Debug + Send + Sync { fn a(&self) -> i32 { 10 } fn z(&self) -> i32 { 11 } fn y(&self) -> i32 { 12 } } trait Bar: Foo { fn b(&self) -> i32 { 20 } fn w(&self) -> i32 { 21 } } trait Baz: Bar { fn c(&self) -> i32 { 30 } } impl Foo for i32 { fn a(&self) -> i32 { 100 } } impl Bar for i32 { fn b(&self) -> i32 { 200 } } impl Baz for i32 { fn c(&self) -> i32 { 300 } } // Note: upcast lifetime means a shorter lifetime. fn upcast_baz<'a: 'b, 'b, T>(v: Box, _l: &'b T) -> Box { v } fn upcast_bar<'a: 'b, 'b, T>(v: Box, _l: &'b T) -> Box { v } fn upcast_foo<'a: 'b, 'b, T>(v: Box, _l: &'b T) -> Box { v } fn main() { let v = Box::new(1); let l = &(); // dummy lifetime (shorter than `baz`) let baz: Box = v.clone(); let u = upcast_baz(baz, &l); assert_eq!(*u, 1); assert_eq!(u.a(), 100); assert_eq!(u.b(), 200); assert_eq!(u.c(), 300); let baz: Box = v.clone(); let bar: Box = baz; let u = upcast_bar(bar, &l); assert_eq!(*u, 1); assert_eq!(u.a(), 100); assert_eq!(u.b(), 200); let baz: Box = v.clone(); let foo: Box = baz; let u = upcast_foo(foo, &l); assert_eq!(*u, 1); assert_eq!(u.a(), 100); let baz: Box = v.clone(); let bar: Box = baz; let foo: Box = bar; let u = upcast_foo(foo, &l); assert_eq!(*u, 1); assert_eq!(u.a(), 100); }