about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorCharles Lew <crlf0710@gmail.com>2021-07-31 00:46:43 +0800
committerCharles Lew <crlf0710@gmail.com>2021-07-31 10:42:11 +0800
commita28ee25483d92b7924752651d9c751ae2c4f2c34 (patch)
treeb085c9f7256de7093c2f783227009e91e8d182d1 /src
parentfb4e0a097238c309220d97d1a62350bafd953083 (diff)
downloadrust-a28ee25483d92b7924752651d9c751ae2c4f2c34.tar.gz
rust-a28ee25483d92b7924752651d9c751ae2c4f2c34.zip
Add more tests to cover more corner cases of type-checking.
Diffstat (limited to 'src')
-rw-r--r--src/test/ui/traits/trait-upcasting/type-checking-test-1.rs33
-rw-r--r--src/test/ui/traits/trait-upcasting/type-checking-test-1.stderr80
-rw-r--r--src/test/ui/traits/trait-upcasting/type-checking-test-2.rs34
-rw-r--r--src/test/ui/traits/trait-upcasting/type-checking-test-2.stderr61
-rw-r--r--src/test/ui/traits/trait-upcasting/type-checking-test-3.rs22
-rw-r--r--src/test/ui/traits/trait-upcasting/type-checking-test-3.stderr33
-rw-r--r--src/test/ui/traits/trait-upcasting/type-checking-test-4.rs32
-rw-r--r--src/test/ui/traits/trait-upcasting/type-checking-test-4.stderr47
8 files changed, 342 insertions, 0 deletions
diff --git a/src/test/ui/traits/trait-upcasting/type-checking-test-1.rs b/src/test/ui/traits/trait-upcasting/type-checking-test-1.rs
new file mode 100644
index 00000000000..1a0e5072843
--- /dev/null
+++ b/src/test/ui/traits/trait-upcasting/type-checking-test-1.rs
@@ -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() {}
diff --git a/src/test/ui/traits/trait-upcasting/type-checking-test-1.stderr b/src/test/ui/traits/trait-upcasting/type-checking-test-1.stderr
new file mode 100644
index 00000000000..6aaa8a4a904
--- /dev/null
+++ b/src/test/ui/traits/trait-upcasting/type-checking-test-1.stderr
@@ -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`.
diff --git a/src/test/ui/traits/trait-upcasting/type-checking-test-2.rs b/src/test/ui/traits/trait-upcasting/type-checking-test-2.rs
new file mode 100644
index 00000000000..326df74211e
--- /dev/null
+++ b/src/test/ui/traits/trait-upcasting/type-checking-test-2.rs
@@ -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() {}
diff --git a/src/test/ui/traits/trait-upcasting/type-checking-test-2.stderr b/src/test/ui/traits/trait-upcasting/type-checking-test-2.stderr
new file mode 100644
index 00000000000..a38f8a14604
--- /dev/null
+++ b/src/test/ui/traits/trait-upcasting/type-checking-test-2.stderr
@@ -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`.
diff --git a/src/test/ui/traits/trait-upcasting/type-checking-test-3.rs b/src/test/ui/traits/trait-upcasting/type-checking-test-3.rs
new file mode 100644
index 00000000000..49c24e404dc
--- /dev/null
+++ b/src/test/ui/traits/trait-upcasting/type-checking-test-3.rs
@@ -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() {}
diff --git a/src/test/ui/traits/trait-upcasting/type-checking-test-3.stderr b/src/test/ui/traits/trait-upcasting/type-checking-test-3.stderr
new file mode 100644
index 00000000000..593ee0a3430
--- /dev/null
+++ b/src/test/ui/traits/trait-upcasting/type-checking-test-3.stderr
@@ -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`.
diff --git a/src/test/ui/traits/trait-upcasting/type-checking-test-4.rs b/src/test/ui/traits/trait-upcasting/type-checking-test-4.rs
new file mode 100644
index 00000000000..9b27fd46f7a
--- /dev/null
+++ b/src/test/ui/traits/trait-upcasting/type-checking-test-4.rs
@@ -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() {}
diff --git a/src/test/ui/traits/trait-upcasting/type-checking-test-4.stderr b/src/test/ui/traits/trait-upcasting/type-checking-test-4.stderr
new file mode 100644
index 00000000000..811e524eda7
--- /dev/null
+++ b/src/test/ui/traits/trait-upcasting/type-checking-test-4.stderr
@@ -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`.