Skip to content

Commit a28ee25

Browse files
committed
Add more tests to cover more corner cases of type-checking.
1 parent fb4e0a0 commit a28ee25

8 files changed

+342
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
#![feature(trait_upcasting)]
2+
#![allow(incomplete_features)]
3+
4+
trait Foo: Bar<i32> + Bar<u32> {}
5+
trait Bar<T> {
6+
fn bar(&self) -> Option<T> {
7+
None
8+
}
9+
}
10+
11+
fn test_specific(x: &dyn Foo) {
12+
let _ = x as &dyn Bar<i32>; // FIXME: OK, eventually
13+
//~^ ERROR non-primitive cast
14+
//~^^ ERROR the trait bound `&dyn Foo: Bar<i32>` is not satisfied
15+
let _ = x as &dyn Bar<u32>; // FIXME: OK, eventually
16+
//~^ ERROR non-primitive cast
17+
//~^^ ERROR the trait bound `&dyn Foo: Bar<u32>` is not satisfied
18+
}
19+
20+
fn test_unknown_version(x: &dyn Foo) {
21+
let _ = x as &dyn Bar<_>; // Ambiguous
22+
//~^ ERROR non-primitive cast
23+
//~^^ ERROR the trait bound `&dyn Foo: Bar<_>` is not satisfied
24+
}
25+
26+
fn test_infer_version(x: &dyn Foo) {
27+
let a = x as &dyn Bar<_>; // FIXME: OK, eventually
28+
//~^ ERROR non-primitive cast
29+
//~^^ ERROR the trait bound `&dyn Foo: Bar<u32>` is not satisfied
30+
let _: Option<u32> = a.bar();
31+
}
32+
33+
fn main() {}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
error[E0605]: non-primitive cast: `&dyn Foo` as `&dyn Bar<i32>`
2+
--> $DIR/type-checking-test-1.rs:12:13
3+
|
4+
LL | let _ = x as &dyn Bar<i32>; // FIXME: OK, eventually
5+
| ^^^^^^^^^^^^^^^^^^ invalid cast
6+
|
7+
help: consider borrowing the value
8+
|
9+
LL | let _ = &x as &dyn Bar<i32>; // FIXME: OK, eventually
10+
| ^
11+
12+
error[E0605]: non-primitive cast: `&dyn Foo` as `&dyn Bar<u32>`
13+
--> $DIR/type-checking-test-1.rs:15:13
14+
|
15+
LL | let _ = x as &dyn Bar<u32>; // FIXME: OK, eventually
16+
| ^^^^^^^^^^^^^^^^^^ invalid cast
17+
|
18+
help: consider borrowing the value
19+
|
20+
LL | let _ = &x as &dyn Bar<u32>; // FIXME: OK, eventually
21+
| ^
22+
23+
error[E0277]: the trait bound `&dyn Foo: Bar<i32>` is not satisfied
24+
--> $DIR/type-checking-test-1.rs:12:13
25+
|
26+
LL | let _ = x as &dyn Bar<i32>; // FIXME: OK, eventually
27+
| ^ the trait `Bar<i32>` is not implemented for `&dyn Foo`
28+
|
29+
= note: required for the cast to the object type `dyn Bar<i32>`
30+
31+
error[E0277]: the trait bound `&dyn Foo: Bar<u32>` is not satisfied
32+
--> $DIR/type-checking-test-1.rs:15:13
33+
|
34+
LL | let _ = x as &dyn Bar<u32>; // FIXME: OK, eventually
35+
| ^ the trait `Bar<u32>` is not implemented for `&dyn Foo`
36+
|
37+
= note: required for the cast to the object type `dyn Bar<u32>`
38+
39+
error[E0605]: non-primitive cast: `&dyn Foo` as `&dyn Bar<_>`
40+
--> $DIR/type-checking-test-1.rs:21:13
41+
|
42+
LL | let _ = x as &dyn Bar<_>; // Ambiguous
43+
| ^^^^^^^^^^^^^^^^ invalid cast
44+
|
45+
help: consider borrowing the value
46+
|
47+
LL | let _ = &x as &dyn Bar<_>; // Ambiguous
48+
| ^
49+
50+
error[E0277]: the trait bound `&dyn Foo: Bar<_>` is not satisfied
51+
--> $DIR/type-checking-test-1.rs:21:13
52+
|
53+
LL | let _ = x as &dyn Bar<_>; // Ambiguous
54+
| ^ the trait `Bar<_>` is not implemented for `&dyn Foo`
55+
|
56+
= note: required for the cast to the object type `dyn Bar<_>`
57+
58+
error[E0605]: non-primitive cast: `&dyn Foo` as `&dyn Bar<u32>`
59+
--> $DIR/type-checking-test-1.rs:27:13
60+
|
61+
LL | let a = x as &dyn Bar<_>; // FIXME: OK, eventually
62+
| ^^^^^^^^^^^^^^^^ invalid cast
63+
|
64+
help: consider borrowing the value
65+
|
66+
LL | let a = &x as &dyn Bar<_>; // FIXME: OK, eventually
67+
| ^
68+
69+
error[E0277]: the trait bound `&dyn Foo: Bar<u32>` is not satisfied
70+
--> $DIR/type-checking-test-1.rs:27:13
71+
|
72+
LL | let a = x as &dyn Bar<_>; // FIXME: OK, eventually
73+
| ^ the trait `Bar<u32>` is not implemented for `&dyn Foo`
74+
|
75+
= note: required for the cast to the object type `dyn Bar<u32>`
76+
77+
error: aborting due to 8 previous errors
78+
79+
Some errors have detailed explanations: E0277, E0605.
80+
For more information about an error, try `rustc --explain E0277`.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
#![feature(trait_upcasting)]
2+
#![allow(incomplete_features)]
3+
4+
trait Foo<T>: Bar<i32> + Bar<T> {}
5+
trait Bar<T> {
6+
fn bar(&self) -> Option<T> {
7+
None
8+
}
9+
}
10+
11+
fn test_specific(x: &dyn Foo<i32>) {
12+
let _ = x as &dyn Bar<i32>; // OK
13+
}
14+
15+
fn test_specific2(x: &dyn Foo<u32>) {
16+
let _ = x as &dyn Bar<i32>; // FIXME: OK, eventually
17+
//~^ ERROR non-primitive cast
18+
//~^^ ERROR the trait bound `&dyn Foo<u32>: Bar<i32>` is not satisfied
19+
}
20+
21+
fn test_specific3(x: &dyn Foo<i32>) {
22+
let _ = x as &dyn Bar<u32>; // Error
23+
//~^ ERROR non-primitive cast
24+
//~^^ ERROR the trait bound `&dyn Foo<i32>: Bar<u32>` is not satisfied
25+
}
26+
27+
fn test_infer_arg(x: &dyn Foo<u32>) {
28+
let a = x as &dyn Bar<_>; // Ambiguous
29+
//~^ ERROR non-primitive cast
30+
//~^^ ERROR the trait bound `&dyn Foo<u32>: Bar<_>` is not satisfied
31+
let _ = a.bar();
32+
}
33+
34+
fn main() {}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
error[E0605]: non-primitive cast: `&dyn Foo<u32>` as `&dyn Bar<i32>`
2+
--> $DIR/type-checking-test-2.rs:16:13
3+
|
4+
LL | let _ = x as &dyn Bar<i32>; // FIXME: OK, eventually
5+
| ^^^^^^^^^^^^^^^^^^ invalid cast
6+
|
7+
help: consider borrowing the value
8+
|
9+
LL | let _ = &x as &dyn Bar<i32>; // FIXME: OK, eventually
10+
| ^
11+
12+
error[E0277]: the trait bound `&dyn Foo<u32>: Bar<i32>` is not satisfied
13+
--> $DIR/type-checking-test-2.rs:16:13
14+
|
15+
LL | let _ = x as &dyn Bar<i32>; // FIXME: OK, eventually
16+
| ^ the trait `Bar<i32>` is not implemented for `&dyn Foo<u32>`
17+
|
18+
= note: required for the cast to the object type `dyn Bar<i32>`
19+
20+
error[E0605]: non-primitive cast: `&dyn Foo<i32>` as `&dyn Bar<u32>`
21+
--> $DIR/type-checking-test-2.rs:22:13
22+
|
23+
LL | let _ = x as &dyn Bar<u32>; // Error
24+
| ^^^^^^^^^^^^^^^^^^ invalid cast
25+
|
26+
help: consider borrowing the value
27+
|
28+
LL | let _ = &x as &dyn Bar<u32>; // Error
29+
| ^
30+
31+
error[E0277]: the trait bound `&dyn Foo<i32>: Bar<u32>` is not satisfied
32+
--> $DIR/type-checking-test-2.rs:22:13
33+
|
34+
LL | let _ = x as &dyn Bar<u32>; // Error
35+
| ^ the trait `Bar<u32>` is not implemented for `&dyn Foo<i32>`
36+
|
37+
= note: required for the cast to the object type `dyn Bar<u32>`
38+
39+
error[E0605]: non-primitive cast: `&dyn Foo<u32>` as `&dyn Bar<_>`
40+
--> $DIR/type-checking-test-2.rs:28:13
41+
|
42+
LL | let a = x as &dyn Bar<_>; // Ambiguous
43+
| ^^^^^^^^^^^^^^^^ invalid cast
44+
|
45+
help: consider borrowing the value
46+
|
47+
LL | let a = &x as &dyn Bar<_>; // Ambiguous
48+
| ^
49+
50+
error[E0277]: the trait bound `&dyn Foo<u32>: Bar<_>` is not satisfied
51+
--> $DIR/type-checking-test-2.rs:28:13
52+
|
53+
LL | let a = x as &dyn Bar<_>; // Ambiguous
54+
| ^ the trait `Bar<_>` is not implemented for `&dyn Foo<u32>`
55+
|
56+
= note: required for the cast to the object type `dyn Bar<_>`
57+
58+
error: aborting due to 6 previous errors
59+
60+
Some errors have detailed explanations: E0277, E0605.
61+
For more information about an error, try `rustc --explain E0277`.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
// ignore-compare-mode-nll
2+
#![feature(trait_upcasting)]
3+
#![allow(incomplete_features)]
4+
5+
trait Foo<'a>: Bar<'a> {}
6+
trait Bar<'a> {}
7+
8+
fn test_correct(x: &dyn Foo<'static>) {
9+
let _ = x as &dyn Bar<'static>;
10+
}
11+
12+
fn test_wrong1<'a>(x: &dyn Foo<'static>, y: &'a u32) {
13+
let _ = x as &dyn Bar<'a>; // Error
14+
//~^ ERROR mismatched types
15+
}
16+
17+
fn test_wrong2<'a>(x: &dyn Foo<'a>) {
18+
let _ = x as &dyn Bar<'static>; // Error
19+
//~^ ERROR mismatched types
20+
}
21+
22+
fn main() {}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
error[E0308]: mismatched types
2+
--> $DIR/type-checking-test-3.rs:13:13
3+
|
4+
LL | let _ = x as &dyn Bar<'a>; // Error
5+
| ^ lifetime mismatch
6+
|
7+
= note: expected trait object `dyn Bar<'a>`
8+
found trait object `dyn Bar<'static>`
9+
note: the lifetime `'a` as defined on the function body at 12:16...
10+
--> $DIR/type-checking-test-3.rs:12:16
11+
|
12+
LL | fn test_wrong1<'a>(x: &dyn Foo<'static>, y: &'a u32) {
13+
| ^^
14+
= note: ...does not necessarily outlive the static lifetime
15+
16+
error[E0308]: mismatched types
17+
--> $DIR/type-checking-test-3.rs:18:13
18+
|
19+
LL | let _ = x as &dyn Bar<'static>; // Error
20+
| ^ lifetime mismatch
21+
|
22+
= note: expected trait object `dyn Bar<'static>`
23+
found trait object `dyn Bar<'a>`
24+
note: the lifetime `'a` as defined on the function body at 17:16...
25+
--> $DIR/type-checking-test-3.rs:17:16
26+
|
27+
LL | fn test_wrong2<'a>(x: &dyn Foo<'a>) {
28+
| ^^
29+
= note: ...does not necessarily outlive the static lifetime
30+
31+
error: aborting due to 2 previous errors
32+
33+
For more information about this error, try `rustc --explain E0308`.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
// ignore-compare-mode-nll
2+
#![feature(trait_upcasting)]
3+
#![allow(incomplete_features)]
4+
5+
trait Foo<'a>: Bar<'a, 'a> {}
6+
trait Bar<'a, 'b> {
7+
fn get_b(&self) -> Option<&'a u32> {
8+
None
9+
}
10+
}
11+
12+
fn test_correct(x: &dyn Foo<'static>) {
13+
let _ = x as &dyn Bar<'static, 'static>;
14+
}
15+
16+
fn test_wrong1<'a>(x: &dyn Foo<'static>, y: &'a u32) {
17+
let _ = x as &dyn Bar<'static, 'a>; // Error
18+
//~^ ERROR mismatched types
19+
}
20+
21+
fn test_wrong2<'a>(x: &dyn Foo<'static>, y: &'a u32) {
22+
let _ = x as &dyn Bar<'a, 'static>; // Error
23+
//~^ ERROR mismatched types
24+
}
25+
26+
fn test_wrong3<'a>(x: &dyn Foo<'a>) -> Option<&'static u32> {
27+
let y = x as &dyn Bar<'_, '_>;
28+
//~^ ERROR `x` has lifetime `'a` but it needs to satisfy a `'static` lifetime requirement
29+
y.get_b() // ERROR
30+
}
31+
32+
fn main() {}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
error[E0308]: mismatched types
2+
--> $DIR/type-checking-test-4.rs:17:13
3+
|
4+
LL | let _ = x as &dyn Bar<'static, 'a>; // Error
5+
| ^ lifetime mismatch
6+
|
7+
= note: expected trait object `dyn Bar<'static, 'a>`
8+
found trait object `dyn Bar<'static, 'static>`
9+
note: the lifetime `'a` as defined on the function body at 16:16...
10+
--> $DIR/type-checking-test-4.rs:16:16
11+
|
12+
LL | fn test_wrong1<'a>(x: &dyn Foo<'static>, y: &'a u32) {
13+
| ^^
14+
= note: ...does not necessarily outlive the static lifetime
15+
16+
error[E0308]: mismatched types
17+
--> $DIR/type-checking-test-4.rs:22:13
18+
|
19+
LL | let _ = x as &dyn Bar<'a, 'static>; // Error
20+
| ^ lifetime mismatch
21+
|
22+
= note: expected trait object `dyn Bar<'a, 'static>`
23+
found trait object `dyn Bar<'static, 'static>`
24+
note: the lifetime `'a` as defined on the function body at 21:16...
25+
--> $DIR/type-checking-test-4.rs:21:16
26+
|
27+
LL | fn test_wrong2<'a>(x: &dyn Foo<'static>, y: &'a u32) {
28+
| ^^
29+
= note: ...does not necessarily outlive the static lifetime
30+
31+
error[E0759]: `x` has lifetime `'a` but it needs to satisfy a `'static` lifetime requirement
32+
--> $DIR/type-checking-test-4.rs:27:27
33+
|
34+
LL | fn test_wrong3<'a>(x: &dyn Foo<'a>) -> Option<&'static u32> {
35+
| ------------ this data with lifetime `'a`...
36+
LL | let y = x as &dyn Bar<'_, '_>;
37+
| - ^^
38+
| |
39+
| ...is captured here...
40+
LL |
41+
LL | y.get_b() // ERROR
42+
| --------- ...and is required to live as long as `'static` here
43+
44+
error: aborting due to 3 previous errors
45+
46+
Some errors have detailed explanations: E0308, E0759.
47+
For more information about an error, try `rustc --explain E0308`.

0 commit comments

Comments
 (0)