Add more tests to cover more corner cases of type-checking.
This commit is contained in:
parent
fb4e0a0972
commit
a28ee25483
8 changed files with 342 additions and 0 deletions
33
src/test/ui/traits/trait-upcasting/type-checking-test-1.rs
Normal file
33
src/test/ui/traits/trait-upcasting/type-checking-test-1.rs
Normal file
|
@ -0,0 +1,33 @@
|
||||||
|
#![feature(trait_upcasting)]
|
||||||
|
#![allow(incomplete_features)]
|
||||||
|
|
||||||
|
trait Foo: Bar<i32> + Bar<u32> {}
|
||||||
|
trait Bar<T> {
|
||||||
|
fn bar(&self) -> Option<T> {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn test_specific(x: &dyn Foo) {
|
||||||
|
let _ = x as &dyn Bar<i32>; // FIXME: OK, eventually
|
||||||
|
//~^ ERROR non-primitive cast
|
||||||
|
//~^^ ERROR the trait bound `&dyn Foo: Bar<i32>` is not satisfied
|
||||||
|
let _ = x as &dyn Bar<u32>; // FIXME: OK, eventually
|
||||||
|
//~^ ERROR non-primitive cast
|
||||||
|
//~^^ ERROR the trait bound `&dyn Foo: Bar<u32>` is not satisfied
|
||||||
|
}
|
||||||
|
|
||||||
|
fn test_unknown_version(x: &dyn Foo) {
|
||||||
|
let _ = x as &dyn Bar<_>; // Ambiguous
|
||||||
|
//~^ ERROR non-primitive cast
|
||||||
|
//~^^ ERROR the trait bound `&dyn Foo: Bar<_>` is not satisfied
|
||||||
|
}
|
||||||
|
|
||||||
|
fn test_infer_version(x: &dyn Foo) {
|
||||||
|
let a = x as &dyn Bar<_>; // FIXME: OK, eventually
|
||||||
|
//~^ ERROR non-primitive cast
|
||||||
|
//~^^ ERROR the trait bound `&dyn Foo: Bar<u32>` is not satisfied
|
||||||
|
let _: Option<u32> = a.bar();
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {}
|
|
@ -0,0 +1,80 @@
|
||||||
|
error[E0605]: non-primitive cast: `&dyn Foo` as `&dyn Bar<i32>`
|
||||||
|
--> $DIR/type-checking-test-1.rs:12:13
|
||||||
|
|
|
||||||
|
LL | let _ = x as &dyn Bar<i32>; // FIXME: OK, eventually
|
||||||
|
| ^^^^^^^^^^^^^^^^^^ invalid cast
|
||||||
|
|
|
||||||
|
help: consider borrowing the value
|
||||||
|
|
|
||||||
|
LL | let _ = &x as &dyn Bar<i32>; // FIXME: OK, eventually
|
||||||
|
| ^
|
||||||
|
|
||||||
|
error[E0605]: non-primitive cast: `&dyn Foo` as `&dyn Bar<u32>`
|
||||||
|
--> $DIR/type-checking-test-1.rs:15:13
|
||||||
|
|
|
||||||
|
LL | let _ = x as &dyn Bar<u32>; // FIXME: OK, eventually
|
||||||
|
| ^^^^^^^^^^^^^^^^^^ invalid cast
|
||||||
|
|
|
||||||
|
help: consider borrowing the value
|
||||||
|
|
|
||||||
|
LL | let _ = &x as &dyn Bar<u32>; // FIXME: OK, eventually
|
||||||
|
| ^
|
||||||
|
|
||||||
|
error[E0277]: the trait bound `&dyn Foo: Bar<i32>` is not satisfied
|
||||||
|
--> $DIR/type-checking-test-1.rs:12:13
|
||||||
|
|
|
||||||
|
LL | let _ = x as &dyn Bar<i32>; // FIXME: OK, eventually
|
||||||
|
| ^ the trait `Bar<i32>` is not implemented for `&dyn Foo`
|
||||||
|
|
|
||||||
|
= note: required for the cast to the object type `dyn Bar<i32>`
|
||||||
|
|
||||||
|
error[E0277]: the trait bound `&dyn Foo: Bar<u32>` is not satisfied
|
||||||
|
--> $DIR/type-checking-test-1.rs:15:13
|
||||||
|
|
|
||||||
|
LL | let _ = x as &dyn Bar<u32>; // FIXME: OK, eventually
|
||||||
|
| ^ the trait `Bar<u32>` is not implemented for `&dyn Foo`
|
||||||
|
|
|
||||||
|
= note: required for the cast to the object type `dyn Bar<u32>`
|
||||||
|
|
||||||
|
error[E0605]: non-primitive cast: `&dyn Foo` as `&dyn Bar<_>`
|
||||||
|
--> $DIR/type-checking-test-1.rs:21:13
|
||||||
|
|
|
||||||
|
LL | let _ = x as &dyn Bar<_>; // Ambiguous
|
||||||
|
| ^^^^^^^^^^^^^^^^ invalid cast
|
||||||
|
|
|
||||||
|
help: consider borrowing the value
|
||||||
|
|
|
||||||
|
LL | let _ = &x as &dyn Bar<_>; // Ambiguous
|
||||||
|
| ^
|
||||||
|
|
||||||
|
error[E0277]: the trait bound `&dyn Foo: Bar<_>` is not satisfied
|
||||||
|
--> $DIR/type-checking-test-1.rs:21:13
|
||||||
|
|
|
||||||
|
LL | let _ = x as &dyn Bar<_>; // Ambiguous
|
||||||
|
| ^ the trait `Bar<_>` is not implemented for `&dyn Foo`
|
||||||
|
|
|
||||||
|
= note: required for the cast to the object type `dyn Bar<_>`
|
||||||
|
|
||||||
|
error[E0605]: non-primitive cast: `&dyn Foo` as `&dyn Bar<u32>`
|
||||||
|
--> $DIR/type-checking-test-1.rs:27:13
|
||||||
|
|
|
||||||
|
LL | let a = x as &dyn Bar<_>; // FIXME: OK, eventually
|
||||||
|
| ^^^^^^^^^^^^^^^^ invalid cast
|
||||||
|
|
|
||||||
|
help: consider borrowing the value
|
||||||
|
|
|
||||||
|
LL | let a = &x as &dyn Bar<_>; // FIXME: OK, eventually
|
||||||
|
| ^
|
||||||
|
|
||||||
|
error[E0277]: the trait bound `&dyn Foo: Bar<u32>` is not satisfied
|
||||||
|
--> $DIR/type-checking-test-1.rs:27:13
|
||||||
|
|
|
||||||
|
LL | let a = x as &dyn Bar<_>; // FIXME: OK, eventually
|
||||||
|
| ^ the trait `Bar<u32>` is not implemented for `&dyn Foo`
|
||||||
|
|
|
||||||
|
= note: required for the cast to the object type `dyn Bar<u32>`
|
||||||
|
|
||||||
|
error: aborting due to 8 previous errors
|
||||||
|
|
||||||
|
Some errors have detailed explanations: E0277, E0605.
|
||||||
|
For more information about an error, try `rustc --explain E0277`.
|
34
src/test/ui/traits/trait-upcasting/type-checking-test-2.rs
Normal file
34
src/test/ui/traits/trait-upcasting/type-checking-test-2.rs
Normal file
|
@ -0,0 +1,34 @@
|
||||||
|
#![feature(trait_upcasting)]
|
||||||
|
#![allow(incomplete_features)]
|
||||||
|
|
||||||
|
trait Foo<T>: Bar<i32> + Bar<T> {}
|
||||||
|
trait Bar<T> {
|
||||||
|
fn bar(&self) -> Option<T> {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn test_specific(x: &dyn Foo<i32>) {
|
||||||
|
let _ = x as &dyn Bar<i32>; // OK
|
||||||
|
}
|
||||||
|
|
||||||
|
fn test_specific2(x: &dyn Foo<u32>) {
|
||||||
|
let _ = x as &dyn Bar<i32>; // FIXME: OK, eventually
|
||||||
|
//~^ ERROR non-primitive cast
|
||||||
|
//~^^ ERROR the trait bound `&dyn Foo<u32>: Bar<i32>` is not satisfied
|
||||||
|
}
|
||||||
|
|
||||||
|
fn test_specific3(x: &dyn Foo<i32>) {
|
||||||
|
let _ = x as &dyn Bar<u32>; // Error
|
||||||
|
//~^ ERROR non-primitive cast
|
||||||
|
//~^^ ERROR the trait bound `&dyn Foo<i32>: Bar<u32>` is not satisfied
|
||||||
|
}
|
||||||
|
|
||||||
|
fn test_infer_arg(x: &dyn Foo<u32>) {
|
||||||
|
let a = x as &dyn Bar<_>; // Ambiguous
|
||||||
|
//~^ ERROR non-primitive cast
|
||||||
|
//~^^ ERROR the trait bound `&dyn Foo<u32>: Bar<_>` is not satisfied
|
||||||
|
let _ = a.bar();
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {}
|
|
@ -0,0 +1,61 @@
|
||||||
|
error[E0605]: non-primitive cast: `&dyn Foo<u32>` as `&dyn Bar<i32>`
|
||||||
|
--> $DIR/type-checking-test-2.rs:16:13
|
||||||
|
|
|
||||||
|
LL | let _ = x as &dyn Bar<i32>; // FIXME: OK, eventually
|
||||||
|
| ^^^^^^^^^^^^^^^^^^ invalid cast
|
||||||
|
|
|
||||||
|
help: consider borrowing the value
|
||||||
|
|
|
||||||
|
LL | let _ = &x as &dyn Bar<i32>; // FIXME: OK, eventually
|
||||||
|
| ^
|
||||||
|
|
||||||
|
error[E0277]: the trait bound `&dyn Foo<u32>: Bar<i32>` is not satisfied
|
||||||
|
--> $DIR/type-checking-test-2.rs:16:13
|
||||||
|
|
|
||||||
|
LL | let _ = x as &dyn Bar<i32>; // FIXME: OK, eventually
|
||||||
|
| ^ the trait `Bar<i32>` is not implemented for `&dyn Foo<u32>`
|
||||||
|
|
|
||||||
|
= note: required for the cast to the object type `dyn Bar<i32>`
|
||||||
|
|
||||||
|
error[E0605]: non-primitive cast: `&dyn Foo<i32>` as `&dyn Bar<u32>`
|
||||||
|
--> $DIR/type-checking-test-2.rs:22:13
|
||||||
|
|
|
||||||
|
LL | let _ = x as &dyn Bar<u32>; // Error
|
||||||
|
| ^^^^^^^^^^^^^^^^^^ invalid cast
|
||||||
|
|
|
||||||
|
help: consider borrowing the value
|
||||||
|
|
|
||||||
|
LL | let _ = &x as &dyn Bar<u32>; // Error
|
||||||
|
| ^
|
||||||
|
|
||||||
|
error[E0277]: the trait bound `&dyn Foo<i32>: Bar<u32>` is not satisfied
|
||||||
|
--> $DIR/type-checking-test-2.rs:22:13
|
||||||
|
|
|
||||||
|
LL | let _ = x as &dyn Bar<u32>; // Error
|
||||||
|
| ^ the trait `Bar<u32>` is not implemented for `&dyn Foo<i32>`
|
||||||
|
|
|
||||||
|
= note: required for the cast to the object type `dyn Bar<u32>`
|
||||||
|
|
||||||
|
error[E0605]: non-primitive cast: `&dyn Foo<u32>` as `&dyn Bar<_>`
|
||||||
|
--> $DIR/type-checking-test-2.rs:28:13
|
||||||
|
|
|
||||||
|
LL | let a = x as &dyn Bar<_>; // Ambiguous
|
||||||
|
| ^^^^^^^^^^^^^^^^ invalid cast
|
||||||
|
|
|
||||||
|
help: consider borrowing the value
|
||||||
|
|
|
||||||
|
LL | let a = &x as &dyn Bar<_>; // Ambiguous
|
||||||
|
| ^
|
||||||
|
|
||||||
|
error[E0277]: the trait bound `&dyn Foo<u32>: Bar<_>` is not satisfied
|
||||||
|
--> $DIR/type-checking-test-2.rs:28:13
|
||||||
|
|
|
||||||
|
LL | let a = x as &dyn Bar<_>; // Ambiguous
|
||||||
|
| ^ the trait `Bar<_>` is not implemented for `&dyn Foo<u32>`
|
||||||
|
|
|
||||||
|
= note: required for the cast to the object type `dyn Bar<_>`
|
||||||
|
|
||||||
|
error: aborting due to 6 previous errors
|
||||||
|
|
||||||
|
Some errors have detailed explanations: E0277, E0605.
|
||||||
|
For more information about an error, try `rustc --explain E0277`.
|
22
src/test/ui/traits/trait-upcasting/type-checking-test-3.rs
Normal file
22
src/test/ui/traits/trait-upcasting/type-checking-test-3.rs
Normal file
|
@ -0,0 +1,22 @@
|
||||||
|
// ignore-compare-mode-nll
|
||||||
|
#![feature(trait_upcasting)]
|
||||||
|
#![allow(incomplete_features)]
|
||||||
|
|
||||||
|
trait Foo<'a>: Bar<'a> {}
|
||||||
|
trait Bar<'a> {}
|
||||||
|
|
||||||
|
fn test_correct(x: &dyn Foo<'static>) {
|
||||||
|
let _ = x as &dyn Bar<'static>;
|
||||||
|
}
|
||||||
|
|
||||||
|
fn test_wrong1<'a>(x: &dyn Foo<'static>, y: &'a u32) {
|
||||||
|
let _ = x as &dyn Bar<'a>; // Error
|
||||||
|
//~^ ERROR mismatched types
|
||||||
|
}
|
||||||
|
|
||||||
|
fn test_wrong2<'a>(x: &dyn Foo<'a>) {
|
||||||
|
let _ = x as &dyn Bar<'static>; // Error
|
||||||
|
//~^ ERROR mismatched types
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {}
|
|
@ -0,0 +1,33 @@
|
||||||
|
error[E0308]: mismatched types
|
||||||
|
--> $DIR/type-checking-test-3.rs:13:13
|
||||||
|
|
|
||||||
|
LL | let _ = x as &dyn Bar<'a>; // Error
|
||||||
|
| ^ lifetime mismatch
|
||||||
|
|
|
||||||
|
= note: expected trait object `dyn Bar<'a>`
|
||||||
|
found trait object `dyn Bar<'static>`
|
||||||
|
note: the lifetime `'a` as defined on the function body at 12:16...
|
||||||
|
--> $DIR/type-checking-test-3.rs:12:16
|
||||||
|
|
|
||||||
|
LL | fn test_wrong1<'a>(x: &dyn Foo<'static>, y: &'a u32) {
|
||||||
|
| ^^
|
||||||
|
= note: ...does not necessarily outlive the static lifetime
|
||||||
|
|
||||||
|
error[E0308]: mismatched types
|
||||||
|
--> $DIR/type-checking-test-3.rs:18:13
|
||||||
|
|
|
||||||
|
LL | let _ = x as &dyn Bar<'static>; // Error
|
||||||
|
| ^ lifetime mismatch
|
||||||
|
|
|
||||||
|
= note: expected trait object `dyn Bar<'static>`
|
||||||
|
found trait object `dyn Bar<'a>`
|
||||||
|
note: the lifetime `'a` as defined on the function body at 17:16...
|
||||||
|
--> $DIR/type-checking-test-3.rs:17:16
|
||||||
|
|
|
||||||
|
LL | fn test_wrong2<'a>(x: &dyn Foo<'a>) {
|
||||||
|
| ^^
|
||||||
|
= note: ...does not necessarily outlive the static lifetime
|
||||||
|
|
||||||
|
error: aborting due to 2 previous errors
|
||||||
|
|
||||||
|
For more information about this error, try `rustc --explain E0308`.
|
32
src/test/ui/traits/trait-upcasting/type-checking-test-4.rs
Normal file
32
src/test/ui/traits/trait-upcasting/type-checking-test-4.rs
Normal file
|
@ -0,0 +1,32 @@
|
||||||
|
// ignore-compare-mode-nll
|
||||||
|
#![feature(trait_upcasting)]
|
||||||
|
#![allow(incomplete_features)]
|
||||||
|
|
||||||
|
trait Foo<'a>: Bar<'a, 'a> {}
|
||||||
|
trait Bar<'a, 'b> {
|
||||||
|
fn get_b(&self) -> Option<&'a u32> {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn test_correct(x: &dyn Foo<'static>) {
|
||||||
|
let _ = x as &dyn Bar<'static, 'static>;
|
||||||
|
}
|
||||||
|
|
||||||
|
fn test_wrong1<'a>(x: &dyn Foo<'static>, y: &'a u32) {
|
||||||
|
let _ = x as &dyn Bar<'static, 'a>; // Error
|
||||||
|
//~^ ERROR mismatched types
|
||||||
|
}
|
||||||
|
|
||||||
|
fn test_wrong2<'a>(x: &dyn Foo<'static>, y: &'a u32) {
|
||||||
|
let _ = x as &dyn Bar<'a, 'static>; // Error
|
||||||
|
//~^ ERROR mismatched types
|
||||||
|
}
|
||||||
|
|
||||||
|
fn test_wrong3<'a>(x: &dyn Foo<'a>) -> Option<&'static u32> {
|
||||||
|
let y = x as &dyn Bar<'_, '_>;
|
||||||
|
//~^ ERROR `x` has lifetime `'a` but it needs to satisfy a `'static` lifetime requirement
|
||||||
|
y.get_b() // ERROR
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {}
|
|
@ -0,0 +1,47 @@
|
||||||
|
error[E0308]: mismatched types
|
||||||
|
--> $DIR/type-checking-test-4.rs:17:13
|
||||||
|
|
|
||||||
|
LL | let _ = x as &dyn Bar<'static, 'a>; // Error
|
||||||
|
| ^ lifetime mismatch
|
||||||
|
|
|
||||||
|
= note: expected trait object `dyn Bar<'static, 'a>`
|
||||||
|
found trait object `dyn Bar<'static, 'static>`
|
||||||
|
note: the lifetime `'a` as defined on the function body at 16:16...
|
||||||
|
--> $DIR/type-checking-test-4.rs:16:16
|
||||||
|
|
|
||||||
|
LL | fn test_wrong1<'a>(x: &dyn Foo<'static>, y: &'a u32) {
|
||||||
|
| ^^
|
||||||
|
= note: ...does not necessarily outlive the static lifetime
|
||||||
|
|
||||||
|
error[E0308]: mismatched types
|
||||||
|
--> $DIR/type-checking-test-4.rs:22:13
|
||||||
|
|
|
||||||
|
LL | let _ = x as &dyn Bar<'a, 'static>; // Error
|
||||||
|
| ^ lifetime mismatch
|
||||||
|
|
|
||||||
|
= note: expected trait object `dyn Bar<'a, 'static>`
|
||||||
|
found trait object `dyn Bar<'static, 'static>`
|
||||||
|
note: the lifetime `'a` as defined on the function body at 21:16...
|
||||||
|
--> $DIR/type-checking-test-4.rs:21:16
|
||||||
|
|
|
||||||
|
LL | fn test_wrong2<'a>(x: &dyn Foo<'static>, y: &'a u32) {
|
||||||
|
| ^^
|
||||||
|
= note: ...does not necessarily outlive the static lifetime
|
||||||
|
|
||||||
|
error[E0759]: `x` has lifetime `'a` but it needs to satisfy a `'static` lifetime requirement
|
||||||
|
--> $DIR/type-checking-test-4.rs:27:27
|
||||||
|
|
|
||||||
|
LL | fn test_wrong3<'a>(x: &dyn Foo<'a>) -> Option<&'static u32> {
|
||||||
|
| ------------ this data with lifetime `'a`...
|
||||||
|
LL | let y = x as &dyn Bar<'_, '_>;
|
||||||
|
| - ^^
|
||||||
|
| |
|
||||||
|
| ...is captured here...
|
||||||
|
LL |
|
||||||
|
LL | y.get_b() // ERROR
|
||||||
|
| --------- ...and is required to live as long as `'static` here
|
||||||
|
|
||||||
|
error: aborting due to 3 previous errors
|
||||||
|
|
||||||
|
Some errors have detailed explanations: E0308, E0759.
|
||||||
|
For more information about an error, try `rustc --explain E0308`.
|
Loading…
Reference in a new issue