Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit a144333

Browse files
Alexander Regueirocrlf0710
authored andcommittedAug 2, 2021
Added tests.
1 parent b867376 commit a144333

File tree

10 files changed

+764
-0
lines changed

10 files changed

+764
-0
lines changed
 
Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
// run-pass
2+
3+
#![feature(trait_upcasting)]
4+
5+
trait Foo: PartialEq<i32> + std::fmt::Debug + Send + Sync {
6+
fn a(&self) -> i32 { 10 }
7+
8+
fn z(&self) -> i32 { 11 }
9+
10+
fn y(&self) -> i32 { 12 }
11+
}
12+
13+
trait Bar: Foo {
14+
fn b(&self) -> i32 { 20 }
15+
16+
fn w(&self) -> i32 { 21 }
17+
}
18+
19+
trait Baz: Bar {
20+
fn c(&self) -> i32 { 30 }
21+
}
22+
23+
impl Foo for i32 {
24+
fn a(&self) -> i32 { 100 }
25+
}
26+
27+
impl Bar for i32 {
28+
fn b(&self) -> i32 { 200 }
29+
}
30+
31+
impl Baz for i32 {
32+
fn c(&self) -> i32 { 300 }
33+
}
34+
35+
fn main() {
36+
let baz: &dyn Baz = &1;
37+
let _: &dyn std::fmt::Debug = baz;
38+
let _: &(dyn Send + Sync) = baz;
39+
let _: &dyn Send = baz;
40+
let _: &dyn Sync = baz;
41+
assert_eq!(*baz, 1);
42+
assert_eq!(baz.a(), 100);
43+
assert_eq!(baz.b(), 200);
44+
assert_eq!(baz.c(), 300);
45+
assert_eq!(baz.z(), 11);
46+
assert_eq!(baz.y(), 12);
47+
assert_eq!(baz.w(), 21);
48+
49+
let bar: &dyn Bar = baz;
50+
let _: &dyn std::fmt::Debug = bar;
51+
let _: &(dyn Send + Sync) = bar;
52+
let _: &dyn Send = bar;
53+
let _: &dyn Sync = bar;
54+
assert_eq!(*bar, 1);
55+
assert_eq!(bar.a(), 100);
56+
assert_eq!(bar.b(), 200);
57+
assert_eq!(bar.z(), 11);
58+
assert_eq!(bar.y(), 12);
59+
assert_eq!(bar.w(), 21);
60+
61+
let foo: &dyn Foo = baz;
62+
let _: &dyn std::fmt::Debug = foo;
63+
let _: &(dyn Send + Sync) = foo;
64+
let _: &dyn Send = foo;
65+
let _: &dyn Sync = foo;
66+
assert_eq!(*foo, 1);
67+
assert_eq!(foo.a(), 100);
68+
assert_eq!(foo.z(), 11);
69+
assert_eq!(foo.y(), 12);
70+
71+
let foo: &dyn Foo = bar;
72+
let _: &dyn std::fmt::Debug = foo;
73+
let _: &(dyn Send + Sync) = foo;
74+
let _: &dyn Send = foo;
75+
let _: &dyn Sync = foo;
76+
assert_eq!(*foo, 1);
77+
assert_eq!(foo.a(), 100);
78+
assert_eq!(foo.z(), 11);
79+
assert_eq!(foo.y(), 12);
80+
}
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
trait A: B + A {}
2+
//~^ ERROR cycle detected when computing the supertraits of `A` [E0391]
3+
4+
trait B {}
5+
6+
impl A for () {}
7+
8+
impl B for () {}
9+
10+
fn main() {
11+
let a: Box<dyn A> = Box::new(());
12+
let _b: Box<dyn B> = a;
13+
}
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
error[E0391]: cycle detected when computing the supertraits of `A`
2+
--> $DIR/cyclic-trait-resolution.rs:1:14
3+
|
4+
LL | trait A: B + A {}
5+
| ^
6+
|
7+
= note: ...which again requires computing the supertraits of `A`, completing the cycle
8+
note: cycle used when collecting item types in top-level module
9+
--> $DIR/cyclic-trait-resolution.rs:1:1
10+
|
11+
LL | trait A: B + A {}
12+
| ^^^^^^^^^^^^^^
13+
14+
error: aborting due to previous error
15+
16+
For more information about this error, try `rustc --explain E0391`.
Lines changed: 108 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,108 @@
1+
// run-pass
2+
3+
#![feature(trait_upcasting)]
4+
5+
trait Foo: PartialEq<i32> + std::fmt::Debug + Send + Sync {
6+
fn a(&self) -> i32 { 10 }
7+
8+
fn z(&self) -> i32 { 11 }
9+
10+
fn y(&self) -> i32 { 12 }
11+
}
12+
13+
trait Bar1: Foo {
14+
fn b(&self) -> i32 { 20 }
15+
16+
fn w(&self) -> i32 { 21 }
17+
}
18+
19+
trait Bar2: Foo {
20+
fn c(&self) -> i32 { 30 }
21+
22+
fn v(&self) -> i32 { 31 }
23+
}
24+
25+
trait Baz: Bar1 + Bar2 {
26+
fn d(&self) -> i32 { 40 }
27+
}
28+
29+
impl Foo for i32 {
30+
fn a(&self) -> i32 { 100 }
31+
}
32+
33+
impl Bar1 for i32 {
34+
fn b(&self) -> i32 { 200 }
35+
}
36+
37+
impl Bar2 for i32 {
38+
fn c(&self) -> i32 { 300 }
39+
}
40+
41+
impl Baz for i32 {
42+
fn d(&self) -> i32 { 400 }
43+
}
44+
45+
fn main() {
46+
let baz: &dyn Baz = &1;
47+
let _: &dyn std::fmt::Debug = baz;
48+
let _: &(dyn Send + Sync) = baz;
49+
let _: &dyn Send = baz;
50+
let _: &dyn Sync = baz;
51+
assert_eq!(*baz, 1);
52+
assert_eq!(baz.a(), 100);
53+
assert_eq!(baz.b(), 200);
54+
assert_eq!(baz.c(), 300);
55+
assert_eq!(baz.d(), 400);
56+
assert_eq!(baz.z(), 11);
57+
assert_eq!(baz.y(), 12);
58+
assert_eq!(baz.w(), 21);
59+
assert_eq!(baz.v(), 31);
60+
61+
let bar1: &dyn Bar1 = baz;
62+
let _: &dyn std::fmt::Debug = bar1;
63+
let _: &(dyn Send + Sync) = bar1;
64+
let _: &dyn Send = bar1;
65+
let _: &dyn Sync = bar1;
66+
assert_eq!(*bar1, 1);
67+
assert_eq!(bar1.a(), 100);
68+
assert_eq!(bar1.b(), 200);
69+
assert_eq!(bar1.z(), 11);
70+
assert_eq!(bar1.y(), 12);
71+
assert_eq!(bar1.w(), 21);
72+
73+
let bar2: &dyn Bar2 = baz;
74+
let _: &dyn std::fmt::Debug = bar2;
75+
let _: &(dyn Send + Sync) = bar2;
76+
let _: &dyn Send = bar2;
77+
let _: &dyn Sync = bar2;
78+
assert_eq!(*bar2, 1);
79+
assert_eq!(bar2.a(), 100);
80+
assert_eq!(bar2.c(), 300);
81+
assert_eq!(bar2.z(), 11);
82+
assert_eq!(bar2.y(), 12);
83+
assert_eq!(bar2.v(), 31);
84+
85+
let foo: &dyn Foo = baz;
86+
let _: &dyn std::fmt::Debug = foo;
87+
let _: &(dyn Send + Sync) = foo;
88+
let _: &dyn Send = foo;
89+
let _: &dyn Sync = foo;
90+
assert_eq!(*foo, 1);
91+
assert_eq!(foo.a(), 100);
92+
93+
let foo: &dyn Foo = bar1;
94+
let _: &dyn std::fmt::Debug = foo;
95+
let _: &(dyn Send + Sync) = foo;
96+
let _: &dyn Send = foo;
97+
let _: &dyn Sync = foo;
98+
assert_eq!(*foo, 1);
99+
assert_eq!(foo.a(), 100);
100+
101+
let foo: &dyn Foo = bar2;
102+
let _: &dyn std::fmt::Debug = foo;
103+
let _: &(dyn Send + Sync) = foo;
104+
let _: &dyn Send = foo;
105+
let _: &dyn Sync = foo;
106+
assert_eq!(*foo, 1);
107+
assert_eq!(foo.a(), 100);
108+
}
Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
#![feature(trait_upcasting)]
2+
3+
trait Foo {
4+
fn a(&self) -> i32 { 10 }
5+
6+
fn z(&self) -> i32 { 11 }
7+
8+
fn y(&self) -> i32 { 12 }
9+
}
10+
11+
trait Bar {
12+
fn b(&self) -> i32 { 20 }
13+
14+
fn w(&self) -> i32 { 21 }
15+
}
16+
17+
trait Baz {
18+
fn c(&self) -> i32 { 30 }
19+
}
20+
21+
impl Foo for i32 {
22+
fn a(&self) -> i32 { 100 }
23+
}
24+
25+
impl Bar for i32 {
26+
fn b(&self) -> i32 { 200 }
27+
}
28+
29+
impl Baz for i32 {
30+
fn c(&self) -> i32 { 300 }
31+
}
32+
33+
fn main() {
34+
let baz: &dyn Baz = &1;
35+
let _: &dyn std::fmt::Debug = baz;
36+
//~^ ERROR `dyn Baz` doesn't implement `std::fmt::Debug` [E0277]
37+
let _: &dyn Send = baz;
38+
//~^ ERROR `dyn Baz` cannot be sent between threads safely [E0277]
39+
let _: &dyn Sync = baz;
40+
//~^ ERROR `dyn Baz` cannot be shared between threads safely [E0277]
41+
42+
let bar: &dyn Bar = baz;
43+
//~^ ERROR the trait bound `dyn Baz: Bar` is not satisfied [E0277]
44+
let _: &dyn std::fmt::Debug = bar;
45+
//~^ ERROR `dyn Bar` doesn't implement `std::fmt::Debug` [E0277]
46+
let _: &dyn Send = bar;
47+
//~^ ERROR `dyn Bar` cannot be sent between threads safely [E0277]
48+
let _: &dyn Sync = bar;
49+
//~^ ERROR `dyn Bar` cannot be shared between threads safely [E0277]
50+
51+
let foo: &dyn Foo = baz;
52+
//~^ ERROR the trait bound `dyn Baz: Foo` is not satisfied [E0277]
53+
let _: &dyn std::fmt::Debug = foo;
54+
//~^ ERROR `dyn Foo` doesn't implement `std::fmt::Debug` [E0277]
55+
let _: &dyn Send = foo;
56+
//~^ ERROR `dyn Foo` cannot be sent between threads safely [E0277]
57+
let _: &dyn Sync = foo;
58+
//~^ ERROR `dyn Foo` cannot be shared between threads safely [E0277]
59+
60+
let foo: &dyn Foo = bar;
61+
//~^ ERROR the trait bound `dyn Bar: Foo` is not satisfied [E0277]
62+
let _: &dyn std::fmt::Debug = foo;
63+
//~^ ERROR `dyn Foo` doesn't implement `std::fmt::Debug` [E0277]
64+
let _: &dyn Send = foo;
65+
//~^ ERROR `dyn Foo` cannot be sent between threads safely [E0277]
66+
let _: &dyn Sync = foo;
67+
//~^ ERROR `dyn Foo` cannot be shared between threads safely [E0277]
68+
}
Lines changed: 135 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,135 @@
1+
error[E0277]: `dyn Baz` doesn't implement `std::fmt::Debug`
2+
--> $DIR/invalid-upcast.rs:35:35
3+
|
4+
LL | let _: &dyn std::fmt::Debug = baz;
5+
| ^^^ `dyn Baz` cannot be formatted using `{:?}` because it doesn't implement `std::fmt::Debug`
6+
|
7+
= help: the trait `std::fmt::Debug` is not implemented for `dyn Baz`
8+
= note: required for the cast to the object type `dyn std::fmt::Debug`
9+
10+
error[E0277]: `dyn Baz` cannot be sent between threads safely
11+
--> $DIR/invalid-upcast.rs:37:24
12+
|
13+
LL | let _: &dyn Send = baz;
14+
| ^^^ `dyn Baz` cannot be sent between threads safely
15+
|
16+
= help: the trait `std::marker::Send` is not implemented for `dyn Baz`
17+
= note: required for the cast to the object type `dyn std::marker::Send`
18+
19+
error[E0277]: `dyn Baz` cannot be shared between threads safely
20+
--> $DIR/invalid-upcast.rs:39:24
21+
|
22+
LL | let _: &dyn Sync = baz;
23+
| ^^^ `dyn Baz` cannot be shared between threads safely
24+
|
25+
= help: the trait `std::marker::Sync` is not implemented for `dyn Baz`
26+
= note: required for the cast to the object type `dyn std::marker::Sync`
27+
28+
error[E0277]: the trait bound `dyn Baz: Bar` is not satisfied
29+
--> $DIR/invalid-upcast.rs:42:25
30+
|
31+
LL | let bar: &dyn Bar = baz;
32+
| ^^^ the trait `Bar` is not implemented for `dyn Baz`
33+
|
34+
= note: required for the cast to the object type `dyn Bar`
35+
36+
error[E0277]: `dyn Bar` doesn't implement `std::fmt::Debug`
37+
--> $DIR/invalid-upcast.rs:44:35
38+
|
39+
LL | let _: &dyn std::fmt::Debug = bar;
40+
| ^^^ `dyn Bar` cannot be formatted using `{:?}` because it doesn't implement `std::fmt::Debug`
41+
|
42+
= help: the trait `std::fmt::Debug` is not implemented for `dyn Bar`
43+
= note: required for the cast to the object type `dyn std::fmt::Debug`
44+
45+
error[E0277]: `dyn Bar` cannot be sent between threads safely
46+
--> $DIR/invalid-upcast.rs:46:24
47+
|
48+
LL | let _: &dyn Send = bar;
49+
| ^^^ `dyn Bar` cannot be sent between threads safely
50+
|
51+
= help: the trait `std::marker::Send` is not implemented for `dyn Bar`
52+
= note: required for the cast to the object type `dyn std::marker::Send`
53+
54+
error[E0277]: `dyn Bar` cannot be shared between threads safely
55+
--> $DIR/invalid-upcast.rs:48:24
56+
|
57+
LL | let _: &dyn Sync = bar;
58+
| ^^^ `dyn Bar` cannot be shared between threads safely
59+
|
60+
= help: the trait `std::marker::Sync` is not implemented for `dyn Bar`
61+
= note: required for the cast to the object type `dyn std::marker::Sync`
62+
63+
error[E0277]: the trait bound `dyn Baz: Foo` is not satisfied
64+
--> $DIR/invalid-upcast.rs:51:25
65+
|
66+
LL | let foo: &dyn Foo = baz;
67+
| ^^^ the trait `Foo` is not implemented for `dyn Baz`
68+
|
69+
= note: required for the cast to the object type `dyn Foo`
70+
71+
error[E0277]: `dyn Foo` doesn't implement `std::fmt::Debug`
72+
--> $DIR/invalid-upcast.rs:53:35
73+
|
74+
LL | let _: &dyn std::fmt::Debug = foo;
75+
| ^^^ `dyn Foo` cannot be formatted using `{:?}` because it doesn't implement `std::fmt::Debug`
76+
|
77+
= help: the trait `std::fmt::Debug` is not implemented for `dyn Foo`
78+
= note: required for the cast to the object type `dyn std::fmt::Debug`
79+
80+
error[E0277]: `dyn Foo` cannot be sent between threads safely
81+
--> $DIR/invalid-upcast.rs:55:24
82+
|
83+
LL | let _: &dyn Send = foo;
84+
| ^^^ `dyn Foo` cannot be sent between threads safely
85+
|
86+
= help: the trait `std::marker::Send` is not implemented for `dyn Foo`
87+
= note: required for the cast to the object type `dyn std::marker::Send`
88+
89+
error[E0277]: `dyn Foo` cannot be shared between threads safely
90+
--> $DIR/invalid-upcast.rs:57:24
91+
|
92+
LL | let _: &dyn Sync = foo;
93+
| ^^^ `dyn Foo` cannot be shared between threads safely
94+
|
95+
= help: the trait `std::marker::Sync` is not implemented for `dyn Foo`
96+
= note: required for the cast to the object type `dyn std::marker::Sync`
97+
98+
error[E0277]: the trait bound `dyn Bar: Foo` is not satisfied
99+
--> $DIR/invalid-upcast.rs:60:25
100+
|
101+
LL | let foo: &dyn Foo = bar;
102+
| ^^^ the trait `Foo` is not implemented for `dyn Bar`
103+
|
104+
= note: required for the cast to the object type `dyn Foo`
105+
106+
error[E0277]: `dyn Foo` doesn't implement `std::fmt::Debug`
107+
--> $DIR/invalid-upcast.rs:62:35
108+
|
109+
LL | let _: &dyn std::fmt::Debug = foo;
110+
| ^^^ `dyn Foo` cannot be formatted using `{:?}` because it doesn't implement `std::fmt::Debug`
111+
|
112+
= help: the trait `std::fmt::Debug` is not implemented for `dyn Foo`
113+
= note: required for the cast to the object type `dyn std::fmt::Debug`
114+
115+
error[E0277]: `dyn Foo` cannot be sent between threads safely
116+
--> $DIR/invalid-upcast.rs:64:24
117+
|
118+
LL | let _: &dyn Send = foo;
119+
| ^^^ `dyn Foo` cannot be sent between threads safely
120+
|
121+
= help: the trait `std::marker::Send` is not implemented for `dyn Foo`
122+
= note: required for the cast to the object type `dyn std::marker::Send`
123+
124+
error[E0277]: `dyn Foo` cannot be shared between threads safely
125+
--> $DIR/invalid-upcast.rs:66:24
126+
|
127+
LL | let _: &dyn Sync = foo;
128+
| ^^^ `dyn Foo` cannot be shared between threads safely
129+
|
130+
= help: the trait `std::marker::Sync` is not implemented for `dyn Foo`
131+
= note: required for the cast to the object type `dyn std::marker::Sync`
132+
133+
error: aborting due to 15 previous errors
134+
135+
For more information about this error, try `rustc --explain E0277`.
Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
// run-pass
2+
3+
#![feature(trait_upcasting)]
4+
5+
trait Foo: PartialEq<i32> + std::fmt::Debug + Send + Sync {
6+
fn a(&self) -> i32 { 10 }
7+
8+
fn z(&self) -> i32 { 11 }
9+
10+
fn y(&self) -> i32 { 12 }
11+
}
12+
13+
trait Bar: Foo {
14+
fn b(&self) -> i32 { 20 }
15+
16+
fn w(&self) -> i32 { 21 }
17+
}
18+
19+
trait Baz: Bar {
20+
fn c(&self) -> i32 { 30 }
21+
}
22+
23+
impl Foo for i32 {
24+
fn a(&self) -> i32 { 100 }
25+
}
26+
27+
impl Bar for i32 {
28+
fn b(&self) -> i32 { 200 }
29+
}
30+
31+
impl Baz for i32 {
32+
fn c(&self) -> i32 { 300 }
33+
}
34+
35+
// Note: upcast lifetime means a shorter lifetime.
36+
fn upcast_baz<'a: 'b, 'b, T>(v: Box<dyn Baz + 'a>, _l: &'b T) -> Box<dyn Baz + 'b> { v }
37+
fn upcast_bar<'a: 'b, 'b, T>(v: Box<dyn Bar + 'a>, _l: &'b T) -> Box<dyn Bar + 'b> { v }
38+
fn upcast_foo<'a: 'b, 'b, T>(v: Box<dyn Foo + 'a>, _l: &'b T) -> Box<dyn Foo + 'b> { v }
39+
40+
fn main() {
41+
let v = Box::new(1);
42+
let l = &(); // dummy lifetime (shorter than `baz`)
43+
44+
let baz: Box<dyn Baz> = v.clone();
45+
let u = upcast_baz(baz, &l);
46+
assert_eq!(*u, 1);
47+
assert_eq!(u.a(), 100);
48+
assert_eq!(u.b(), 200);
49+
assert_eq!(u.c(), 300);
50+
51+
let baz: Box<dyn Baz> = v.clone();
52+
let bar: Box<dyn Bar> = baz;
53+
let u = upcast_bar(bar, &l);
54+
assert_eq!(*u, 1);
55+
assert_eq!(u.a(), 100);
56+
assert_eq!(u.b(), 200);
57+
58+
let baz: Box<dyn Baz> = v.clone();
59+
let foo: Box<dyn Foo> = baz;
60+
let u = upcast_foo(foo, &l);
61+
assert_eq!(*u, 1);
62+
assert_eq!(u.a(), 100);
63+
64+
let baz: Box<dyn Baz> = v.clone();
65+
let bar: Box<dyn Bar> = baz;
66+
let foo: Box<dyn Foo> = bar;
67+
let u = upcast_foo(foo, &l);
68+
assert_eq!(*u, 1);
69+
assert_eq!(u.a(), 100);
70+
}
Lines changed: 155 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,155 @@
1+
// run-pass
2+
3+
#![feature(trait_upcasting)]
4+
5+
use std::rc::Rc;
6+
use std::sync::Arc;
7+
8+
trait Foo: PartialEq<i32> + std::fmt::Debug + Send + Sync {
9+
fn a(&self) -> i32 { 10 }
10+
11+
fn z(&self) -> i32 { 11 }
12+
13+
fn y(&self) -> i32 { 12 }
14+
}
15+
16+
trait Bar: Foo {
17+
fn b(&self) -> i32 { 20 }
18+
19+
fn w(&self) -> i32 { 21 }
20+
}
21+
22+
trait Baz: Bar {
23+
fn c(&self) -> i32 { 30 }
24+
}
25+
26+
impl Foo for i32 {
27+
fn a(&self) -> i32 { 100 }
28+
}
29+
30+
impl Bar for i32 {
31+
fn b(&self) -> i32 { 200 }
32+
}
33+
34+
impl Baz for i32 {
35+
fn c(&self) -> i32 { 300 }
36+
}
37+
38+
fn test_box() {
39+
let v = Box::new(1);
40+
41+
let baz: Box<dyn Baz> = v.clone();
42+
assert_eq!(*baz, 1);
43+
assert_eq!(baz.a(), 100);
44+
assert_eq!(baz.b(), 200);
45+
assert_eq!(baz.c(), 300);
46+
assert_eq!(baz.z(), 11);
47+
assert_eq!(baz.y(), 12);
48+
assert_eq!(baz.w(), 21);
49+
50+
let baz: Box<dyn Baz> = v.clone();
51+
let bar: Box<dyn Bar> = baz;
52+
assert_eq!(*bar, 1);
53+
assert_eq!(bar.a(), 100);
54+
assert_eq!(bar.b(), 200);
55+
assert_eq!(bar.z(), 11);
56+
assert_eq!(bar.y(), 12);
57+
assert_eq!(bar.w(), 21);
58+
59+
let baz: Box<dyn Baz> = v.clone();
60+
let foo: Box<dyn Foo> = baz;
61+
assert_eq!(*foo, 1);
62+
assert_eq!(foo.a(), 100);
63+
assert_eq!(foo.z(), 11);
64+
assert_eq!(foo.y(), 12);
65+
66+
let baz: Box<dyn Baz> = v.clone();
67+
let bar: Box<dyn Bar> = baz;
68+
let foo: Box<dyn Foo> = bar;
69+
assert_eq!(*foo, 1);
70+
assert_eq!(foo.a(), 100);
71+
assert_eq!(foo.z(), 11);
72+
assert_eq!(foo.y(), 12);
73+
}
74+
75+
fn test_rc() {
76+
let v = Rc::new(1);
77+
78+
let baz: Rc<dyn Baz> = v.clone();
79+
assert_eq!(*baz, 1);
80+
assert_eq!(baz.a(), 100);
81+
assert_eq!(baz.b(), 200);
82+
assert_eq!(baz.c(), 300);
83+
assert_eq!(baz.z(), 11);
84+
assert_eq!(baz.y(), 12);
85+
assert_eq!(baz.w(), 21);
86+
87+
let baz: Rc<dyn Baz> = v.clone();
88+
let bar: Rc<dyn Bar> = baz;
89+
assert_eq!(*bar, 1);
90+
assert_eq!(bar.a(), 100);
91+
assert_eq!(bar.b(), 200);
92+
assert_eq!(bar.z(), 11);
93+
assert_eq!(bar.y(), 12);
94+
assert_eq!(bar.w(), 21);
95+
96+
let baz: Rc<dyn Baz> = v.clone();
97+
let foo: Rc<dyn Foo> = baz;
98+
assert_eq!(*foo, 1);
99+
assert_eq!(foo.a(), 100);
100+
assert_eq!(foo.z(), 11);
101+
assert_eq!(foo.y(), 12);
102+
103+
let baz: Rc<dyn Baz> = v.clone();
104+
let bar: Rc<dyn Bar> = baz;
105+
let foo: Rc<dyn Foo> = bar;
106+
assert_eq!(*foo, 1);
107+
assert_eq!(foo.a(), 100);
108+
assert_eq!(foo.z(), 11);
109+
assert_eq!(foo.y(), 12);
110+
assert_eq!(foo.z(), 11);
111+
assert_eq!(foo.y(), 12);
112+
}
113+
114+
fn test_arc() {
115+
let v = Arc::new(1);
116+
117+
let baz: Arc<dyn Baz> = v.clone();
118+
assert_eq!(*baz, 1);
119+
assert_eq!(baz.a(), 100);
120+
assert_eq!(baz.b(), 200);
121+
assert_eq!(baz.c(), 300);
122+
assert_eq!(baz.z(), 11);
123+
assert_eq!(baz.y(), 12);
124+
assert_eq!(baz.w(), 21);
125+
126+
let baz: Arc<dyn Baz> = v.clone();
127+
let bar: Arc<dyn Bar> = baz;
128+
assert_eq!(*bar, 1);
129+
assert_eq!(bar.a(), 100);
130+
assert_eq!(bar.b(), 200);
131+
assert_eq!(bar.z(), 11);
132+
assert_eq!(bar.y(), 12);
133+
assert_eq!(bar.w(), 21);
134+
135+
let baz: Arc<dyn Baz> = v.clone();
136+
let foo: Arc<dyn Foo> = baz;
137+
assert_eq!(*foo, 1);
138+
assert_eq!(foo.a(), 100);
139+
assert_eq!(foo.z(), 11);
140+
assert_eq!(foo.y(), 12);
141+
142+
let baz: Arc<dyn Baz> = v.clone();
143+
let bar: Arc<dyn Bar> = baz;
144+
let foo: Arc<dyn Foo> = bar;
145+
assert_eq!(*foo, 1);
146+
assert_eq!(foo.a(), 100);
147+
assert_eq!(foo.z(), 11);
148+
assert_eq!(foo.y(), 12);
149+
}
150+
151+
fn main() {
152+
test_box();
153+
test_rc();
154+
test_arc();
155+
}
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
#![feature(trait_upcasting)]
2+
3+
trait Foo: PartialEq<i32> + std::fmt::Debug + Send + Sync {
4+
fn a(&self) -> i32 { 10 }
5+
6+
fn z(&self) -> i32 { 11 }
7+
8+
fn y(&self) -> i32 { 12 }
9+
}
10+
11+
trait Bar: Foo {
12+
fn b(&self) -> i32 { 20 }
13+
14+
fn w(&self) -> i32 { 21 }
15+
}
16+
17+
trait Baz: Bar {
18+
fn c(&self) -> i32 { 30 }
19+
}
20+
21+
impl Foo for i32 {
22+
fn a(&self) -> i32 { 100 }
23+
}
24+
25+
impl Bar for i32 {
26+
fn b(&self) -> i32 { 200 }
27+
}
28+
29+
impl Baz for i32 {
30+
fn c(&self) -> i32 { 300 }
31+
}
32+
33+
fn main() {
34+
let baz: &dyn Baz = &1;
35+
36+
let bar: &dyn Bar = baz;
37+
bar.c();
38+
//~^ ERROR no method named `c` found for reference `&dyn Bar` in the current scope [E0599]
39+
40+
let foo: &dyn Foo = baz;
41+
foo.b();
42+
//~^ ERROR no method named `b` found for reference `&dyn Foo` in the current scope [E0599]
43+
foo.c();
44+
//~^ ERROR no method named `c` found for reference `&dyn Foo` in the current scope [E0599]
45+
46+
let foo: &dyn Foo = bar;
47+
foo.b();
48+
//~^ ERROR no method named `b` found for reference `&dyn Foo` in the current scope [E0599]
49+
foo.c();
50+
//~^ ERROR no method named `c` found for reference `&dyn Foo` in the current scope [E0599]
51+
}
Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
error[E0599]: no method named `c` found for reference `&dyn Bar` in the current scope
2+
--> $DIR/subtrait-method.rs:37:9
3+
|
4+
LL | bar.c();
5+
| ^ help: there is an associated function with a similar name: `a`
6+
|
7+
= help: items from traits can only be used if the trait is implemented and in scope
8+
note: `Baz` defines an item `c`, perhaps you need to implement it
9+
--> $DIR/subtrait-method.rs:17:1
10+
|
11+
LL | trait Baz: Bar {
12+
| ^^^^^^^^^^^^^^
13+
14+
error[E0599]: no method named `b` found for reference `&dyn Foo` in the current scope
15+
--> $DIR/subtrait-method.rs:41:9
16+
|
17+
LL | foo.b();
18+
| ^ help: there is an associated function with a similar name: `a`
19+
|
20+
= help: items from traits can only be used if the trait is implemented and in scope
21+
note: `Bar` defines an item `b`, perhaps you need to implement it
22+
--> $DIR/subtrait-method.rs:11:1
23+
|
24+
LL | trait Bar: Foo {
25+
| ^^^^^^^^^^^^^^
26+
27+
error[E0599]: no method named `c` found for reference `&dyn Foo` in the current scope
28+
--> $DIR/subtrait-method.rs:43:9
29+
|
30+
LL | foo.c();
31+
| ^ help: there is an associated function with a similar name: `a`
32+
|
33+
= help: items from traits can only be used if the trait is implemented and in scope
34+
note: `Baz` defines an item `c`, perhaps you need to implement it
35+
--> $DIR/subtrait-method.rs:17:1
36+
|
37+
LL | trait Baz: Bar {
38+
| ^^^^^^^^^^^^^^
39+
40+
error[E0599]: no method named `b` found for reference `&dyn Foo` in the current scope
41+
--> $DIR/subtrait-method.rs:47:9
42+
|
43+
LL | foo.b();
44+
| ^ help: there is an associated function with a similar name: `a`
45+
|
46+
= help: items from traits can only be used if the trait is implemented and in scope
47+
note: `Bar` defines an item `b`, perhaps you need to implement it
48+
--> $DIR/subtrait-method.rs:11:1
49+
|
50+
LL | trait Bar: Foo {
51+
| ^^^^^^^^^^^^^^
52+
53+
error[E0599]: no method named `c` found for reference `&dyn Foo` in the current scope
54+
--> $DIR/subtrait-method.rs:49:9
55+
|
56+
LL | foo.c();
57+
| ^ help: there is an associated function with a similar name: `a`
58+
|
59+
= help: items from traits can only be used if the trait is implemented and in scope
60+
note: `Baz` defines an item `c`, perhaps you need to implement it
61+
--> $DIR/subtrait-method.rs:17:1
62+
|
63+
LL | trait Baz: Bar {
64+
| ^^^^^^^^^^^^^^
65+
66+
error: aborting due to 5 previous errors
67+
68+
For more information about this error, try `rustc --explain E0599`.

0 commit comments

Comments
 (0)
Please sign in to comment.