summaryrefslogtreecommitdiffstats
path: root/tests/ui/object-safety
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-17 12:19:03 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-17 12:19:03 +0000
commit64d98f8ee037282c35007b64c2649055c56af1db (patch)
tree5492bcf97fce41ee1c0b1cc2add283f3e66cdab0 /tests/ui/object-safety
parentAdding debian version 1.67.1+dfsg1-1. (diff)
downloadrustc-64d98f8ee037282c35007b64c2649055c56af1db.tar.xz
rustc-64d98f8ee037282c35007b64c2649055c56af1db.zip
Merging upstream version 1.68.2+dfsg1.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'tests/ui/object-safety')
-rw-r--r--tests/ui/object-safety/issue-102762.rs26
-rw-r--r--tests/ui/object-safety/issue-102762.stderr20
-rw-r--r--tests/ui/object-safety/issue-102933.rs25
-rw-r--r--tests/ui/object-safety/issue-106247.rs9
-rw-r--r--tests/ui/object-safety/issue-19538.rs20
-rw-r--r--tests/ui/object-safety/issue-19538.stderr37
-rw-r--r--tests/ui/object-safety/object-safety-associated-consts.curr.stderr18
-rw-r--r--tests/ui/object-safety/object-safety-associated-consts.object_safe_for_dispatch.stderr20
-rw-r--r--tests/ui/object-safety/object-safety-associated-consts.rs19
-rw-r--r--tests/ui/object-safety/object-safety-bounds.rs12
-rw-r--r--tests/ui/object-safety/object-safety-bounds.stderr17
-rw-r--r--tests/ui/object-safety/object-safety-by-value-self-use.rs18
-rw-r--r--tests/ui/object-safety/object-safety-by-value-self-use.stderr9
-rw-r--r--tests/ui/object-safety/object-safety-by-value-self.rs46
-rw-r--r--tests/ui/object-safety/object-safety-generics.curr.stderr33
-rw-r--r--tests/ui/object-safety/object-safety-generics.object_safe_for_dispatch.stderr37
-rw-r--r--tests/ui/object-safety/object-safety-generics.rs39
-rw-r--r--tests/ui/object-safety/object-safety-issue-22040.rs42
-rw-r--r--tests/ui/object-safety/object-safety-issue-22040.stderr17
-rw-r--r--tests/ui/object-safety/object-safety-mentions-Self.curr.stderr33
-rw-r--r--tests/ui/object-safety/object-safety-mentions-Self.object_safe_for_dispatch.stderr37
-rw-r--r--tests/ui/object-safety/object-safety-mentions-Self.rs42
-rw-r--r--tests/ui/object-safety/object-safety-no-static.curr.stderr25
-rw-r--r--tests/ui/object-safety/object-safety-no-static.object_safe_for_dispatch.stderr27
-rw-r--r--tests/ui/object-safety/object-safety-no-static.rs24
-rw-r--r--tests/ui/object-safety/object-safety-phantom-fn.rs22
-rw-r--r--tests/ui/object-safety/object-safety-sized-2.curr.stderr17
-rw-r--r--tests/ui/object-safety/object-safety-sized-2.object_safe_for_dispatch.stderr19
-rw-r--r--tests/ui/object-safety/object-safety-sized-2.rs21
-rw-r--r--tests/ui/object-safety/object-safety-sized.curr.stderr17
-rw-r--r--tests/ui/object-safety/object-safety-sized.object_safe_for_dispatch.stderr19
-rw-r--r--tests/ui/object-safety/object-safety-sized.rs19
-rw-r--r--tests/ui/object-safety/object-safety-supertrait-mentions-GAT.rs15
-rw-r--r--tests/ui/object-safety/object-safety-supertrait-mentions-GAT.stderr43
-rw-r--r--tests/ui/object-safety/object-safety-supertrait-mentions-Self.rs21
-rw-r--r--tests/ui/object-safety/object-safety-supertrait-mentions-Self.stderr17
36 files changed, 882 insertions, 0 deletions
diff --git a/tests/ui/object-safety/issue-102762.rs b/tests/ui/object-safety/issue-102762.rs
new file mode 100644
index 000000000..4f4c36345
--- /dev/null
+++ b/tests/ui/object-safety/issue-102762.rs
@@ -0,0 +1,26 @@
+// compile-flags: --crate-type=lib
+// This test checks that the `where_clauses_object_safety` lint does not cause
+// other object safety *hard errors* to be suppressed, because we currently
+// only emit one object safety error per trait...
+
+use std::future::Future;
+use std::pin::Pin;
+
+pub trait Fetcher: Send + Sync {
+ fn get<'a>(self: &'a Box<Self>) -> Pin<Box<dyn Future<Output = Vec<u8>> + 'a>>
+ where
+ Self: Sync,
+ {
+ todo!()
+ }
+}
+
+fn fetcher() -> Box<dyn Fetcher> {
+ //~^ ERROR the trait `Fetcher` cannot be made into an object
+ todo!()
+}
+
+pub fn foo() {
+ let fetcher = fetcher();
+ let _ = fetcher.get();
+}
diff --git a/tests/ui/object-safety/issue-102762.stderr b/tests/ui/object-safety/issue-102762.stderr
new file mode 100644
index 000000000..5041ebe77
--- /dev/null
+++ b/tests/ui/object-safety/issue-102762.stderr
@@ -0,0 +1,20 @@
+error[E0038]: the trait `Fetcher` cannot be made into an object
+ --> $DIR/issue-102762.rs:18:21
+ |
+LL | fn get<'a>(self: &'a Box<Self>) -> Pin<Box<dyn Future<Output = Vec<u8>> + 'a>>
+ | ------------- help: consider changing method `get`'s `self` parameter to be `&self`: `&Self`
+...
+LL | fn fetcher() -> Box<dyn Fetcher> {
+ | ^^^^^^^^^^^ `Fetcher` cannot be made into an object
+ |
+note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
+ --> $DIR/issue-102762.rs:10:22
+ |
+LL | pub trait Fetcher: Send + Sync {
+ | ------- this trait cannot be made into an object...
+LL | fn get<'a>(self: &'a Box<Self>) -> Pin<Box<dyn Future<Output = Vec<u8>> + 'a>>
+ | ^^^^^^^^^^^^^ ...because method `get`'s `self` parameter cannot be dispatched on
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0038`.
diff --git a/tests/ui/object-safety/issue-102933.rs b/tests/ui/object-safety/issue-102933.rs
new file mode 100644
index 000000000..843391cff
--- /dev/null
+++ b/tests/ui/object-safety/issue-102933.rs
@@ -0,0 +1,25 @@
+// check-pass
+
+use std::future::Future;
+
+pub trait Service {
+ type Response;
+ type Future: Future<Output = Self::Response>;
+}
+
+pub trait A1: Service<Response = i32> {}
+
+pub trait A2: Service<Future = Box<dyn Future<Output = i32>>> + A1 {
+ fn foo(&self) {}
+}
+
+pub trait B1: Service<Future = Box<dyn Future<Output = i32>>> {}
+
+pub trait B2: Service<Response = i32> + B1 {
+ fn foo(&self) {}
+}
+
+fn main() {
+ let x: &dyn A2 = todo!();
+ let x: &dyn B2 = todo!();
+}
diff --git a/tests/ui/object-safety/issue-106247.rs b/tests/ui/object-safety/issue-106247.rs
new file mode 100644
index 000000000..64bf59e5d
--- /dev/null
+++ b/tests/ui/object-safety/issue-106247.rs
@@ -0,0 +1,9 @@
+// check-pass
+
+#![deny(where_clauses_object_safety)]
+
+pub trait Trait {
+ fn method(&self) where Self: Sync;
+}
+
+fn main() {}
diff --git a/tests/ui/object-safety/issue-19538.rs b/tests/ui/object-safety/issue-19538.rs
new file mode 100644
index 000000000..7054ef41b
--- /dev/null
+++ b/tests/ui/object-safety/issue-19538.rs
@@ -0,0 +1,20 @@
+trait Foo {
+ fn foo<T>(&self, val: T);
+}
+
+trait Bar: Foo { }
+
+pub struct Thing;
+
+impl Foo for Thing {
+ fn foo<T>(&self, val: T) { }
+}
+
+impl Bar for Thing { }
+
+fn main() {
+ let mut thing = Thing;
+ let test: &mut dyn Bar = &mut thing;
+ //~^ ERROR E0038
+ //~| ERROR E0038
+}
diff --git a/tests/ui/object-safety/issue-19538.stderr b/tests/ui/object-safety/issue-19538.stderr
new file mode 100644
index 000000000..8420637b3
--- /dev/null
+++ b/tests/ui/object-safety/issue-19538.stderr
@@ -0,0 +1,37 @@
+error[E0038]: the trait `Bar` cannot be made into an object
+ --> $DIR/issue-19538.rs:17:15
+ |
+LL | let test: &mut dyn Bar = &mut thing;
+ | ^^^^^^^^^^^^ `Bar` cannot be made into an object
+ |
+note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
+ --> $DIR/issue-19538.rs:2:8
+ |
+LL | fn foo<T>(&self, val: T);
+ | ^^^ ...because method `foo` has generic type parameters
+...
+LL | trait Bar: Foo { }
+ | --- this trait cannot be made into an object...
+ = help: consider moving `foo` to another trait
+
+error[E0038]: the trait `Bar` cannot be made into an object
+ --> $DIR/issue-19538.rs:17:30
+ |
+LL | let test: &mut dyn Bar = &mut thing;
+ | ^^^^^^^^^^ `Bar` cannot be made into an object
+ |
+note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
+ --> $DIR/issue-19538.rs:2:8
+ |
+LL | fn foo<T>(&self, val: T);
+ | ^^^ ...because method `foo` has generic type parameters
+...
+LL | trait Bar: Foo { }
+ | --- this trait cannot be made into an object...
+ = help: consider moving `foo` to another trait
+ = note: required for `&mut Thing` to implement `CoerceUnsized<&mut dyn Bar>`
+ = note: required by cast to type `&mut dyn Bar`
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0038`.
diff --git a/tests/ui/object-safety/object-safety-associated-consts.curr.stderr b/tests/ui/object-safety/object-safety-associated-consts.curr.stderr
new file mode 100644
index 000000000..5f94c9284
--- /dev/null
+++ b/tests/ui/object-safety/object-safety-associated-consts.curr.stderr
@@ -0,0 +1,18 @@
+error[E0038]: the trait `Bar` cannot be made into an object
+ --> $DIR/object-safety-associated-consts.rs:12:31
+ |
+LL | fn make_bar<T:Bar>(t: &T) -> &dyn Bar {
+ | ^^^^^^^ `Bar` cannot be made into an object
+ |
+note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
+ --> $DIR/object-safety-associated-consts.rs:9:11
+ |
+LL | trait Bar {
+ | --- this trait cannot be made into an object...
+LL | const X: usize;
+ | ^ ...because it contains this associated `const`
+ = help: consider moving `X` to another trait
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0038`.
diff --git a/tests/ui/object-safety/object-safety-associated-consts.object_safe_for_dispatch.stderr b/tests/ui/object-safety/object-safety-associated-consts.object_safe_for_dispatch.stderr
new file mode 100644
index 000000000..f44de07d5
--- /dev/null
+++ b/tests/ui/object-safety/object-safety-associated-consts.object_safe_for_dispatch.stderr
@@ -0,0 +1,20 @@
+error[E0038]: the trait `Bar` cannot be made into an object
+ --> $DIR/object-safety-associated-consts.rs:14:5
+ |
+LL | t
+ | ^ `Bar` cannot be made into an object
+ |
+note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
+ --> $DIR/object-safety-associated-consts.rs:9:11
+ |
+LL | trait Bar {
+ | --- this trait cannot be made into an object...
+LL | const X: usize;
+ | ^ ...because it contains this associated `const`
+ = help: consider moving `X` to another trait
+ = note: required for `&T` to implement `CoerceUnsized<&dyn Bar>`
+ = note: required by cast to type `&dyn Bar`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0038`.
diff --git a/tests/ui/object-safety/object-safety-associated-consts.rs b/tests/ui/object-safety/object-safety-associated-consts.rs
new file mode 100644
index 000000000..e1a772e5a
--- /dev/null
+++ b/tests/ui/object-safety/object-safety-associated-consts.rs
@@ -0,0 +1,19 @@
+// Check that we correctly prevent users from making trait objects
+// from traits with associated consts.
+//
+// revisions: curr object_safe_for_dispatch
+
+#![cfg_attr(object_safe_for_dispatch, feature(object_safe_for_dispatch))]
+
+trait Bar {
+ const X: usize;
+}
+
+fn make_bar<T:Bar>(t: &T) -> &dyn Bar {
+ //[curr]~^ ERROR E0038
+ t
+ //[object_safe_for_dispatch]~^ ERROR E0038
+}
+
+fn main() {
+}
diff --git a/tests/ui/object-safety/object-safety-bounds.rs b/tests/ui/object-safety/object-safety-bounds.rs
new file mode 100644
index 000000000..44bd36932
--- /dev/null
+++ b/tests/ui/object-safety/object-safety-bounds.rs
@@ -0,0 +1,12 @@
+// Traits with bounds mentioning `Self` are not object safe
+
+trait X {
+ type U: PartialEq<Self>;
+}
+
+fn f() -> Box<dyn X<U = u32>> {
+ //~^ ERROR the trait `X` cannot be made into an object
+ loop {}
+}
+
+fn main() {}
diff --git a/tests/ui/object-safety/object-safety-bounds.stderr b/tests/ui/object-safety/object-safety-bounds.stderr
new file mode 100644
index 000000000..29ffb5448
--- /dev/null
+++ b/tests/ui/object-safety/object-safety-bounds.stderr
@@ -0,0 +1,17 @@
+error[E0038]: the trait `X` cannot be made into an object
+ --> $DIR/object-safety-bounds.rs:7:15
+ |
+LL | fn f() -> Box<dyn X<U = u32>> {
+ | ^^^^^^^^^^^^^^ `X` cannot be made into an object
+ |
+note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
+ --> $DIR/object-safety-bounds.rs:4:13
+ |
+LL | trait X {
+ | - this trait cannot be made into an object...
+LL | type U: PartialEq<Self>;
+ | ^^^^^^^^^^^^^^^ ...because it uses `Self` as a type parameter
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0038`.
diff --git a/tests/ui/object-safety/object-safety-by-value-self-use.rs b/tests/ui/object-safety/object-safety-by-value-self-use.rs
new file mode 100644
index 000000000..8e93c5382
--- /dev/null
+++ b/tests/ui/object-safety/object-safety-by-value-self-use.rs
@@ -0,0 +1,18 @@
+// Check that while a trait with by-value self is object-safe, we
+// can't actually invoke it from an object (yet...?).
+
+#![feature(rustc_attrs)]
+
+trait Bar {
+ fn bar(self);
+}
+
+trait Baz {
+ fn baz(self: Self);
+}
+
+fn use_bar(t: Box<dyn Bar>) {
+ t.bar() //~ ERROR cannot move a value of type `dyn Bar`
+}
+
+fn main() { }
diff --git a/tests/ui/object-safety/object-safety-by-value-self-use.stderr b/tests/ui/object-safety/object-safety-by-value-self-use.stderr
new file mode 100644
index 000000000..94fdcdf26
--- /dev/null
+++ b/tests/ui/object-safety/object-safety-by-value-self-use.stderr
@@ -0,0 +1,9 @@
+error[E0161]: cannot move a value of type `dyn Bar`
+ --> $DIR/object-safety-by-value-self-use.rs:15:5
+ |
+LL | t.bar()
+ | ^^^^^^^ the size of `dyn Bar` cannot be statically determined
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0161`.
diff --git a/tests/ui/object-safety/object-safety-by-value-self.rs b/tests/ui/object-safety/object-safety-by-value-self.rs
new file mode 100644
index 000000000..c74a4d1cb
--- /dev/null
+++ b/tests/ui/object-safety/object-safety-by-value-self.rs
@@ -0,0 +1,46 @@
+// Check that a trait with by-value self is considered object-safe.
+
+// build-pass (FIXME(62277): could be check-pass?)
+#![allow(dead_code)]
+#![allow(trivial_casts)]
+
+trait Bar {
+ fn bar(self);
+}
+
+trait Baz {
+ fn baz(self: Self);
+}
+
+trait Quux {
+ // Legal because of the where clause:
+ fn baz(self: Self) where Self : Sized;
+}
+
+fn make_bar<T:Bar>(t: &T) -> &dyn Bar {
+ t // legal
+}
+
+fn make_bar_explicit<T:Bar>(t: &T) -> &dyn Bar {
+ t as &dyn Bar // legal
+}
+
+fn make_baz<T:Baz>(t: &T) -> &dyn Baz {
+ t // legal
+}
+
+fn make_baz_explicit<T:Baz>(t: &T) -> &dyn Baz {
+ t as &dyn Baz // legal
+}
+
+fn make_quux<T:Quux>(t: &T) -> &dyn Quux {
+ t
+}
+
+fn make_quux_explicit<T:Quux>(t: &T) -> &dyn Quux {
+ t as &dyn Quux
+}
+
+
+fn main() {
+}
diff --git a/tests/ui/object-safety/object-safety-generics.curr.stderr b/tests/ui/object-safety/object-safety-generics.curr.stderr
new file mode 100644
index 000000000..458103752
--- /dev/null
+++ b/tests/ui/object-safety/object-safety-generics.curr.stderr
@@ -0,0 +1,33 @@
+error[E0038]: the trait `Bar` cannot be made into an object
+ --> $DIR/object-safety-generics.rs:18:31
+ |
+LL | fn make_bar<T:Bar>(t: &T) -> &dyn Bar {
+ | ^^^^^^^ `Bar` cannot be made into an object
+ |
+note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
+ --> $DIR/object-safety-generics.rs:10:8
+ |
+LL | trait Bar {
+ | --- this trait cannot be made into an object...
+LL | fn bar<T>(&self, t: T);
+ | ^^^ ...because method `bar` has generic type parameters
+ = help: consider moving `bar` to another trait
+
+error[E0038]: the trait `Bar` cannot be made into an object
+ --> $DIR/object-safety-generics.rs:24:40
+ |
+LL | fn make_bar_explicit<T:Bar>(t: &T) -> &dyn Bar {
+ | ^^^^^^^ `Bar` cannot be made into an object
+ |
+note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
+ --> $DIR/object-safety-generics.rs:10:8
+ |
+LL | trait Bar {
+ | --- this trait cannot be made into an object...
+LL | fn bar<T>(&self, t: T);
+ | ^^^ ...because method `bar` has generic type parameters
+ = help: consider moving `bar` to another trait
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0038`.
diff --git a/tests/ui/object-safety/object-safety-generics.object_safe_for_dispatch.stderr b/tests/ui/object-safety/object-safety-generics.object_safe_for_dispatch.stderr
new file mode 100644
index 000000000..9a2d472d5
--- /dev/null
+++ b/tests/ui/object-safety/object-safety-generics.object_safe_for_dispatch.stderr
@@ -0,0 +1,37 @@
+error[E0038]: the trait `Bar` cannot be made into an object
+ --> $DIR/object-safety-generics.rs:20:5
+ |
+LL | t
+ | ^ `Bar` cannot be made into an object
+ |
+note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
+ --> $DIR/object-safety-generics.rs:10:8
+ |
+LL | trait Bar {
+ | --- this trait cannot be made into an object...
+LL | fn bar<T>(&self, t: T);
+ | ^^^ ...because method `bar` has generic type parameters
+ = help: consider moving `bar` to another trait
+ = note: required for `&T` to implement `CoerceUnsized<&dyn Bar>`
+ = note: required by cast to type `&dyn Bar`
+
+error[E0038]: the trait `Bar` cannot be made into an object
+ --> $DIR/object-safety-generics.rs:26:5
+ |
+LL | t as &dyn Bar
+ | ^ `Bar` cannot be made into an object
+ |
+note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
+ --> $DIR/object-safety-generics.rs:10:8
+ |
+LL | trait Bar {
+ | --- this trait cannot be made into an object...
+LL | fn bar<T>(&self, t: T);
+ | ^^^ ...because method `bar` has generic type parameters
+ = help: consider moving `bar` to another trait
+ = note: required for `&T` to implement `CoerceUnsized<&dyn Bar>`
+ = note: required by cast to type `&dyn Bar`
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0038`.
diff --git a/tests/ui/object-safety/object-safety-generics.rs b/tests/ui/object-safety/object-safety-generics.rs
new file mode 100644
index 000000000..63dcd1699
--- /dev/null
+++ b/tests/ui/object-safety/object-safety-generics.rs
@@ -0,0 +1,39 @@
+// Check that we correctly prevent users from making trait objects
+// from traits with generic methods, unless `where Self : Sized` is
+// present.
+// revisions: curr object_safe_for_dispatch
+
+#![cfg_attr(object_safe_for_dispatch, feature(object_safe_for_dispatch))]
+
+
+trait Bar {
+ fn bar<T>(&self, t: T);
+}
+
+trait Quux {
+ fn bar<T>(&self, t: T)
+ where Self : Sized;
+}
+
+fn make_bar<T:Bar>(t: &T) -> &dyn Bar {
+ //[curr]~^ ERROR E0038
+ t
+ //[object_safe_for_dispatch]~^ ERROR E0038
+}
+
+fn make_bar_explicit<T:Bar>(t: &T) -> &dyn Bar {
+ //[curr]~^ ERROR E0038
+ t as &dyn Bar
+ //[object_safe_for_dispatch]~^ ERROR E0038
+}
+
+fn make_quux<T:Quux>(t: &T) -> &dyn Quux {
+ t
+}
+
+fn make_quux_explicit<T:Quux>(t: &T) -> &dyn Quux {
+ t as &dyn Quux
+}
+
+fn main() {
+}
diff --git a/tests/ui/object-safety/object-safety-issue-22040.rs b/tests/ui/object-safety/object-safety-issue-22040.rs
new file mode 100644
index 000000000..1fc5c5442
--- /dev/null
+++ b/tests/ui/object-safety/object-safety-issue-22040.rs
@@ -0,0 +1,42 @@
+// Regression test for #22040.
+
+use std::fmt::Debug;
+
+trait Expr: Debug + PartialEq {
+ fn print_element_count(&self);
+}
+
+//#[derive(PartialEq)]
+#[derive(Debug)]
+struct SExpr<'x> {
+ elements: Vec<Box<dyn Expr + 'x>>,
+ //~^ ERROR E0038
+}
+
+impl<'x> PartialEq for SExpr<'x> {
+ fn eq(&self, other:&SExpr<'x>) -> bool {
+ println!("L1: {} L2: {}", self.elements.len(), other.elements.len());
+
+ let result = self.elements.len() == other.elements.len();
+
+ println!("Got compare {}", result);
+ return result;
+ }
+}
+
+impl <'x> SExpr<'x> {
+ fn new() -> SExpr<'x> { return SExpr{elements: Vec::new(),}; }
+}
+
+impl <'x> Expr for SExpr<'x> {
+ fn print_element_count(&self) {
+ println!("element count: {}", self.elements.len());
+ }
+}
+
+fn main() {
+ let a: Box<dyn Expr> = Box::new(SExpr::new());
+ let b: Box<dyn Expr> = Box::new(SExpr::new());
+
+ // assert_eq!(a , b);
+}
diff --git a/tests/ui/object-safety/object-safety-issue-22040.stderr b/tests/ui/object-safety/object-safety-issue-22040.stderr
new file mode 100644
index 000000000..0262d5362
--- /dev/null
+++ b/tests/ui/object-safety/object-safety-issue-22040.stderr
@@ -0,0 +1,17 @@
+error[E0038]: the trait `Expr` cannot be made into an object
+ --> $DIR/object-safety-issue-22040.rs:12:23
+ |
+LL | elements: Vec<Box<dyn Expr + 'x>>,
+ | ^^^^^^^^^^^^^ `Expr` cannot be made into an object
+ |
+note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
+ --> $DIR/object-safety-issue-22040.rs:5:21
+ |
+LL | trait Expr: Debug + PartialEq {
+ | ---- ^^^^^^^^^ ...because it uses `Self` as a type parameter
+ | |
+ | this trait cannot be made into an object...
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0038`.
diff --git a/tests/ui/object-safety/object-safety-mentions-Self.curr.stderr b/tests/ui/object-safety/object-safety-mentions-Self.curr.stderr
new file mode 100644
index 000000000..de430a89b
--- /dev/null
+++ b/tests/ui/object-safety/object-safety-mentions-Self.curr.stderr
@@ -0,0 +1,33 @@
+error[E0038]: the trait `Bar` cannot be made into an object
+ --> $DIR/object-safety-mentions-Self.rs:22:31
+ |
+LL | fn make_bar<T:Bar>(t: &T) -> &dyn Bar {
+ | ^^^^^^^ `Bar` cannot be made into an object
+ |
+note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
+ --> $DIR/object-safety-mentions-Self.rs:11:22
+ |
+LL | trait Bar {
+ | --- this trait cannot be made into an object...
+LL | fn bar(&self, x: &Self);
+ | ^^^^^ ...because method `bar` references the `Self` type in this parameter
+ = help: consider moving `bar` to another trait
+
+error[E0038]: the trait `Baz` cannot be made into an object
+ --> $DIR/object-safety-mentions-Self.rs:28:31
+ |
+LL | fn make_baz<T:Baz>(t: &T) -> &dyn Baz {
+ | ^^^^^^^ `Baz` cannot be made into an object
+ |
+note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
+ --> $DIR/object-safety-mentions-Self.rs:15:22
+ |
+LL | trait Baz {
+ | --- this trait cannot be made into an object...
+LL | fn baz(&self) -> Self;
+ | ^^^^ ...because method `baz` references the `Self` type in its return type
+ = help: consider moving `baz` to another trait
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0038`.
diff --git a/tests/ui/object-safety/object-safety-mentions-Self.object_safe_for_dispatch.stderr b/tests/ui/object-safety/object-safety-mentions-Self.object_safe_for_dispatch.stderr
new file mode 100644
index 000000000..40a298bd1
--- /dev/null
+++ b/tests/ui/object-safety/object-safety-mentions-Self.object_safe_for_dispatch.stderr
@@ -0,0 +1,37 @@
+error[E0038]: the trait `Bar` cannot be made into an object
+ --> $DIR/object-safety-mentions-Self.rs:24:5
+ |
+LL | t
+ | ^ `Bar` cannot be made into an object
+ |
+note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
+ --> $DIR/object-safety-mentions-Self.rs:11:22
+ |
+LL | trait Bar {
+ | --- this trait cannot be made into an object...
+LL | fn bar(&self, x: &Self);
+ | ^^^^^ ...because method `bar` references the `Self` type in this parameter
+ = help: consider moving `bar` to another trait
+ = note: required for `&T` to implement `CoerceUnsized<&dyn Bar>`
+ = note: required by cast to type `&dyn Bar`
+
+error[E0038]: the trait `Baz` cannot be made into an object
+ --> $DIR/object-safety-mentions-Self.rs:30:5
+ |
+LL | t
+ | ^ `Baz` cannot be made into an object
+ |
+note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
+ --> $DIR/object-safety-mentions-Self.rs:15:22
+ |
+LL | trait Baz {
+ | --- this trait cannot be made into an object...
+LL | fn baz(&self) -> Self;
+ | ^^^^ ...because method `baz` references the `Self` type in its return type
+ = help: consider moving `baz` to another trait
+ = note: required for `&T` to implement `CoerceUnsized<&dyn Baz>`
+ = note: required by cast to type `&dyn Baz`
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0038`.
diff --git a/tests/ui/object-safety/object-safety-mentions-Self.rs b/tests/ui/object-safety/object-safety-mentions-Self.rs
new file mode 100644
index 000000000..412d16ff3
--- /dev/null
+++ b/tests/ui/object-safety/object-safety-mentions-Self.rs
@@ -0,0 +1,42 @@
+// Check that we correctly prevent users from making trait objects
+// form traits that make use of `Self` in an argument or return
+// position, unless `where Self : Sized` is present..
+//
+// revisions: curr object_safe_for_dispatch
+
+#![cfg_attr(object_safe_for_dispatch, feature(object_safe_for_dispatch))]
+
+
+trait Bar {
+ fn bar(&self, x: &Self);
+}
+
+trait Baz {
+ fn baz(&self) -> Self;
+}
+
+trait Quux {
+ fn quux(&self, s: &Self) -> Self where Self : Sized;
+}
+
+fn make_bar<T:Bar>(t: &T) -> &dyn Bar {
+ //[curr]~^ ERROR E0038
+ t
+ //[object_safe_for_dispatch]~^ ERROR E0038
+}
+
+fn make_baz<T:Baz>(t: &T) -> &dyn Baz {
+ //[curr]~^ ERROR E0038
+ t
+ //[object_safe_for_dispatch]~^ ERROR E0038
+}
+
+fn make_quux<T:Quux>(t: &T) -> &dyn Quux {
+ t
+}
+
+fn make_quux_explicit<T:Quux>(t: &T) -> &dyn Quux {
+ t as &dyn Quux
+}
+
+fn main() {}
diff --git a/tests/ui/object-safety/object-safety-no-static.curr.stderr b/tests/ui/object-safety/object-safety-no-static.curr.stderr
new file mode 100644
index 000000000..1b025229e
--- /dev/null
+++ b/tests/ui/object-safety/object-safety-no-static.curr.stderr
@@ -0,0 +1,25 @@
+error[E0038]: the trait `Foo` cannot be made into an object
+ --> $DIR/object-safety-no-static.rs:12:22
+ |
+LL | fn diverges() -> Box<dyn Foo> {
+ | ^^^^^^^ `Foo` cannot be made into an object
+ |
+note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
+ --> $DIR/object-safety-no-static.rs:9:8
+ |
+LL | trait Foo {
+ | --- this trait cannot be made into an object...
+LL | fn foo() {}
+ | ^^^ ...because associated function `foo` has no `self` parameter
+help: consider turning `foo` into a method by giving it a `&self` argument
+ |
+LL | fn foo(&self) {}
+ | +++++
+help: alternatively, consider constraining `foo` so it does not apply to trait objects
+ |
+LL | fn foo() where Self: Sized {}
+ | +++++++++++++++++
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0038`.
diff --git a/tests/ui/object-safety/object-safety-no-static.object_safe_for_dispatch.stderr b/tests/ui/object-safety/object-safety-no-static.object_safe_for_dispatch.stderr
new file mode 100644
index 000000000..da87b58c9
--- /dev/null
+++ b/tests/ui/object-safety/object-safety-no-static.object_safe_for_dispatch.stderr
@@ -0,0 +1,27 @@
+error[E0038]: the trait `Foo` cannot be made into an object
+ --> $DIR/object-safety-no-static.rs:22:27
+ |
+LL | let b: Box<dyn Foo> = Box::new(Bar);
+ | ^^^^^^^^^^^^^ `Foo` cannot be made into an object
+ |
+note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
+ --> $DIR/object-safety-no-static.rs:9:8
+ |
+LL | trait Foo {
+ | --- this trait cannot be made into an object...
+LL | fn foo() {}
+ | ^^^ ...because associated function `foo` has no `self` parameter
+ = note: required for `Box<Bar>` to implement `CoerceUnsized<Box<dyn Foo>>`
+ = note: required by cast to type `Box<dyn Foo>`
+help: consider turning `foo` into a method by giving it a `&self` argument
+ |
+LL | fn foo(&self) {}
+ | +++++
+help: alternatively, consider constraining `foo` so it does not apply to trait objects
+ |
+LL | fn foo() where Self: Sized {}
+ | +++++++++++++++++
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0038`.
diff --git a/tests/ui/object-safety/object-safety-no-static.rs b/tests/ui/object-safety/object-safety-no-static.rs
new file mode 100644
index 000000000..03b622174
--- /dev/null
+++ b/tests/ui/object-safety/object-safety-no-static.rs
@@ -0,0 +1,24 @@
+// Check that we correctly prevent users from making trait objects
+// from traits with static methods.
+//
+// revisions: curr object_safe_for_dispatch
+
+#![cfg_attr(object_safe_for_dispatch, feature(object_safe_for_dispatch))]
+
+trait Foo {
+ fn foo() {}
+}
+
+fn diverges() -> Box<dyn Foo> {
+ //[curr]~^ ERROR E0038
+ loop { }
+}
+
+struct Bar;
+
+impl Foo for Bar {}
+
+fn main() {
+ let b: Box<dyn Foo> = Box::new(Bar);
+ //[object_safe_for_dispatch]~^ ERROR E0038
+}
diff --git a/tests/ui/object-safety/object-safety-phantom-fn.rs b/tests/ui/object-safety/object-safety-phantom-fn.rs
new file mode 100644
index 000000000..3ffeb81c1
--- /dev/null
+++ b/tests/ui/object-safety/object-safety-phantom-fn.rs
@@ -0,0 +1,22 @@
+// Check that `Self` appearing in a phantom fn does not make a trait not object safe.
+
+// build-pass (FIXME(62277): could be check-pass?)
+#![allow(dead_code)]
+
+trait Baz {
+}
+
+trait Bar<T> {
+}
+
+fn make_bar<T:Bar<u32>>(t: &T) -> &dyn Bar<u32> {
+ t
+}
+
+fn make_baz<T:Baz>(t: &T) -> &dyn Baz {
+ t
+}
+
+
+fn main() {
+}
diff --git a/tests/ui/object-safety/object-safety-sized-2.curr.stderr b/tests/ui/object-safety/object-safety-sized-2.curr.stderr
new file mode 100644
index 000000000..b01926412
--- /dev/null
+++ b/tests/ui/object-safety/object-safety-sized-2.curr.stderr
@@ -0,0 +1,17 @@
+error[E0038]: the trait `Bar` cannot be made into an object
+ --> $DIR/object-safety-sized-2.rs:14:31
+ |
+LL | fn make_bar<T:Bar>(t: &T) -> &dyn Bar {
+ | ^^^^^^^ `Bar` cannot be made into an object
+ |
+note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
+ --> $DIR/object-safety-sized-2.rs:9:18
+ |
+LL | trait Bar
+ | --- this trait cannot be made into an object...
+LL | where Self : Sized
+ | ^^^^^ ...because it requires `Self: Sized`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0038`.
diff --git a/tests/ui/object-safety/object-safety-sized-2.object_safe_for_dispatch.stderr b/tests/ui/object-safety/object-safety-sized-2.object_safe_for_dispatch.stderr
new file mode 100644
index 000000000..6c29c8d5f
--- /dev/null
+++ b/tests/ui/object-safety/object-safety-sized-2.object_safe_for_dispatch.stderr
@@ -0,0 +1,19 @@
+error[E0038]: the trait `Bar` cannot be made into an object
+ --> $DIR/object-safety-sized-2.rs:16:5
+ |
+LL | t
+ | ^ `Bar` cannot be made into an object
+ |
+note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
+ --> $DIR/object-safety-sized-2.rs:9:18
+ |
+LL | trait Bar
+ | --- this trait cannot be made into an object...
+LL | where Self : Sized
+ | ^^^^^ ...because it requires `Self: Sized`
+ = note: required for `&T` to implement `CoerceUnsized<&dyn Bar>`
+ = note: required by cast to type `&dyn Bar`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0038`.
diff --git a/tests/ui/object-safety/object-safety-sized-2.rs b/tests/ui/object-safety/object-safety-sized-2.rs
new file mode 100644
index 000000000..1e79b8cd9
--- /dev/null
+++ b/tests/ui/object-safety/object-safety-sized-2.rs
@@ -0,0 +1,21 @@
+// Check that we correctly prevent users from making trait objects
+// from traits where `Self : Sized`.
+//
+// revisions: curr object_safe_for_dispatch
+
+#![cfg_attr(object_safe_for_dispatch, feature(object_safe_for_dispatch))]
+
+trait Bar
+ where Self : Sized
+{
+ fn bar<T>(&self, t: T);
+}
+
+fn make_bar<T:Bar>(t: &T) -> &dyn Bar {
+ //[curr]~^ ERROR E0038
+ t
+ //[object_safe_for_dispatch]~^ ERROR E0038
+}
+
+fn main() {
+}
diff --git a/tests/ui/object-safety/object-safety-sized.curr.stderr b/tests/ui/object-safety/object-safety-sized.curr.stderr
new file mode 100644
index 000000000..974813121
--- /dev/null
+++ b/tests/ui/object-safety/object-safety-sized.curr.stderr
@@ -0,0 +1,17 @@
+error[E0038]: the trait `Bar` cannot be made into an object
+ --> $DIR/object-safety-sized.rs:12:31
+ |
+LL | fn make_bar<T:Bar>(t: &T) -> &dyn Bar {
+ | ^^^^^^^ `Bar` cannot be made into an object
+ |
+note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
+ --> $DIR/object-safety-sized.rs:8:13
+ |
+LL | trait Bar : Sized {
+ | --- ^^^^^ ...because it requires `Self: Sized`
+ | |
+ | this trait cannot be made into an object...
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0038`.
diff --git a/tests/ui/object-safety/object-safety-sized.object_safe_for_dispatch.stderr b/tests/ui/object-safety/object-safety-sized.object_safe_for_dispatch.stderr
new file mode 100644
index 000000000..70a44ed61
--- /dev/null
+++ b/tests/ui/object-safety/object-safety-sized.object_safe_for_dispatch.stderr
@@ -0,0 +1,19 @@
+error[E0038]: the trait `Bar` cannot be made into an object
+ --> $DIR/object-safety-sized.rs:14:5
+ |
+LL | t
+ | ^ `Bar` cannot be made into an object
+ |
+note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
+ --> $DIR/object-safety-sized.rs:8:13
+ |
+LL | trait Bar : Sized {
+ | --- ^^^^^ ...because it requires `Self: Sized`
+ | |
+ | this trait cannot be made into an object...
+ = note: required for `&T` to implement `CoerceUnsized<&dyn Bar>`
+ = note: required by cast to type `&dyn Bar`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0038`.
diff --git a/tests/ui/object-safety/object-safety-sized.rs b/tests/ui/object-safety/object-safety-sized.rs
new file mode 100644
index 000000000..b424b892d
--- /dev/null
+++ b/tests/ui/object-safety/object-safety-sized.rs
@@ -0,0 +1,19 @@
+// Check that we correctly prevent users from making trait objects
+// from traits where `Self : Sized`.
+//
+// revisions: curr object_safe_for_dispatch
+
+#![cfg_attr(object_safe_for_dispatch, feature(object_safe_for_dispatch))]
+
+trait Bar : Sized {
+ fn bar<T>(&self, t: T);
+}
+
+fn make_bar<T:Bar>(t: &T) -> &dyn Bar {
+ //[curr]~^ ERROR E0038
+ t
+ //[object_safe_for_dispatch]~^ ERROR E0038
+}
+
+fn main() {
+}
diff --git a/tests/ui/object-safety/object-safety-supertrait-mentions-GAT.rs b/tests/ui/object-safety/object-safety-supertrait-mentions-GAT.rs
new file mode 100644
index 000000000..14e00d2ef
--- /dev/null
+++ b/tests/ui/object-safety/object-safety-supertrait-mentions-GAT.rs
@@ -0,0 +1,15 @@
+//~ ERROR the parameter type `Self` may not live long enough
+
+trait GatTrait {
+ type Gat<'a>
+ where
+ Self: 'a;
+}
+
+trait SuperTrait<T>: for<'a> GatTrait<Gat<'a> = T> {
+ fn c(&self) -> dyn SuperTrait<T>;
+ //~^ ERROR associated item referring to unboxed trait object for its own trait
+ //~| ERROR the trait `SuperTrait` cannot be made into an object
+}
+
+fn main() {}
diff --git a/tests/ui/object-safety/object-safety-supertrait-mentions-GAT.stderr b/tests/ui/object-safety/object-safety-supertrait-mentions-GAT.stderr
new file mode 100644
index 000000000..f05b0cd65
--- /dev/null
+++ b/tests/ui/object-safety/object-safety-supertrait-mentions-GAT.stderr
@@ -0,0 +1,43 @@
+error[E0311]: the parameter type `Self` may not live long enough
+ |
+ = help: consider adding an explicit lifetime bound `Self: 'a`...
+ = note: ...so that the type `Self` will meet its required lifetime bounds...
+note: ...that is required by this bound
+ --> $DIR/object-safety-supertrait-mentions-GAT.rs:6:15
+ |
+LL | Self: 'a;
+ | ^^
+
+error: associated item referring to unboxed trait object for its own trait
+ --> $DIR/object-safety-supertrait-mentions-GAT.rs:10:20
+ |
+LL | trait SuperTrait<T>: for<'a> GatTrait<Gat<'a> = T> {
+ | ---------- in this trait
+LL | fn c(&self) -> dyn SuperTrait<T>;
+ | ^^^^^^^^^^^^^^^^^
+ |
+help: you might have meant to use `Self` to refer to the implementing type
+ |
+LL | fn c(&self) -> Self;
+ | ~~~~
+
+error[E0038]: the trait `SuperTrait` cannot be made into an object
+ --> $DIR/object-safety-supertrait-mentions-GAT.rs:10:20
+ |
+LL | fn c(&self) -> dyn SuperTrait<T>;
+ | ^^^^^^^^^^^^^^^^^ `SuperTrait` cannot be made into an object
+ |
+note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
+ --> $DIR/object-safety-supertrait-mentions-GAT.rs:4:10
+ |
+LL | type Gat<'a>
+ | ^^^ ...because it contains the generic associated type `Gat`
+...
+LL | trait SuperTrait<T>: for<'a> GatTrait<Gat<'a> = T> {
+ | ---------- this trait cannot be made into an object...
+ = help: consider moving `Gat` to another trait
+
+error: aborting due to 3 previous errors
+
+Some errors have detailed explanations: E0038, E0311.
+For more information about an error, try `rustc --explain E0038`.
diff --git a/tests/ui/object-safety/object-safety-supertrait-mentions-Self.rs b/tests/ui/object-safety/object-safety-supertrait-mentions-Self.rs
new file mode 100644
index 000000000..2445b33c8
--- /dev/null
+++ b/tests/ui/object-safety/object-safety-supertrait-mentions-Self.rs
@@ -0,0 +1,21 @@
+// Check that we correctly prevent users from making trait objects
+// form traits that make use of `Self` in an argument or return position.
+
+trait Bar<T> {
+ fn bar(&self, x: &T);
+}
+
+trait Baz : Bar<Self> {
+}
+
+fn make_bar<T:Bar<u32>>(t: &T) -> &dyn Bar<u32> {
+ t
+}
+
+fn make_baz<T:Baz>(t: &T) -> &dyn Baz {
+ //~^ ERROR E0038
+ t
+}
+
+fn main() {
+}
diff --git a/tests/ui/object-safety/object-safety-supertrait-mentions-Self.stderr b/tests/ui/object-safety/object-safety-supertrait-mentions-Self.stderr
new file mode 100644
index 000000000..a106ab995
--- /dev/null
+++ b/tests/ui/object-safety/object-safety-supertrait-mentions-Self.stderr
@@ -0,0 +1,17 @@
+error[E0038]: the trait `Baz` cannot be made into an object
+ --> $DIR/object-safety-supertrait-mentions-Self.rs:15:31
+ |
+LL | fn make_baz<T:Baz>(t: &T) -> &dyn Baz {
+ | ^^^^^^^ `Baz` cannot be made into an object
+ |
+note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
+ --> $DIR/object-safety-supertrait-mentions-Self.rs:8:13
+ |
+LL | trait Baz : Bar<Self> {
+ | --- ^^^^^^^^^ ...because it uses `Self` as a type parameter
+ | |
+ | this trait cannot be made into an object...
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0038`.