1 // run-pass
2 // ignore-compare-mode-nll
3 
4 #![feature(trait_upcasting)]
5 #![allow(incomplete_features)]
6 
7 trait Foo: PartialEq<i32> + std::fmt::Debug + Send + Sync {
a(&self) -> i328     fn a(&self) -> i32 {
9         10
10     }
11 
z(&self) -> i3212     fn z(&self) -> i32 {
13         11
14     }
15 
y(&self) -> i3216     fn y(&self) -> i32 {
17         12
18     }
19 }
20 
21 trait Bar: Foo {
b(&self) -> i3222     fn b(&self) -> i32 {
23         20
24     }
25 
w(&self) -> i3226     fn w(&self) -> i32 {
27         21
28     }
29 }
30 
31 trait Baz: Bar {
c(&self) -> i3232     fn c(&self) -> i32 {
33         30
34     }
35 }
36 
37 impl Foo for i32 {
a(&self) -> i3238     fn a(&self) -> i32 {
39         100
40     }
41 }
42 
43 impl Bar for i32 {
b(&self) -> i3244     fn b(&self) -> i32 {
45         200
46     }
47 }
48 
49 impl Baz for i32 {
c(&self) -> i3250     fn c(&self) -> i32 {
51         300
52     }
53 }
54 
55 // Note: upcast lifetime means a shorter lifetime.
upcast_baz<'a: 'b, 'b, T>(v: Box<dyn Baz + 'a>, _l: &'b T) -> Box<dyn Baz + 'b>56 fn upcast_baz<'a: 'b, 'b, T>(v: Box<dyn Baz + 'a>, _l: &'b T) -> Box<dyn Baz + 'b> {
57     v
58 }
upcast_bar<'a: 'b, 'b, T>(v: Box<dyn Bar + 'a>, _l: &'b T) -> Box<dyn Bar + 'b>59 fn upcast_bar<'a: 'b, 'b, T>(v: Box<dyn Bar + 'a>, _l: &'b T) -> Box<dyn Bar + 'b> {
60     v
61 }
upcast_foo<'a: 'b, 'b, T>(v: Box<dyn Foo + 'a>, _l: &'b T) -> Box<dyn Foo + 'b>62 fn upcast_foo<'a: 'b, 'b, T>(v: Box<dyn Foo + 'a>, _l: &'b T) -> Box<dyn Foo + 'b> {
63     v
64 }
65 
main()66 fn main() {
67     let v = Box::new(1);
68     let l = &(); // dummy lifetime (shorter than `baz`)
69 
70     let baz: Box<dyn Baz> = v.clone();
71     let u = upcast_baz(baz, &l);
72     assert_eq!(*u, 1);
73     assert_eq!(u.a(), 100);
74     assert_eq!(u.b(), 200);
75     assert_eq!(u.c(), 300);
76 
77     let baz: Box<dyn Baz> = v.clone();
78     let bar: Box<dyn Bar> = baz;
79     let u = upcast_bar(bar, &l);
80     assert_eq!(*u, 1);
81     assert_eq!(u.a(), 100);
82     assert_eq!(u.b(), 200);
83 
84     let baz: Box<dyn Baz> = v.clone();
85     let foo: Box<dyn Foo> = baz;
86     let u = upcast_foo(foo, &l);
87     assert_eq!(*u, 1);
88     assert_eq!(u.a(), 100);
89 
90     let baz: Box<dyn Baz> = v.clone();
91     let bar: Box<dyn Bar> = baz;
92     let foo: Box<dyn Foo> = bar;
93     let u = upcast_foo(foo, &l);
94     assert_eq!(*u, 1);
95     assert_eq!(u.a(), 100);
96 }
97