summaryrefslogtreecommitdiffstats
path: root/src/test/ui/object-safety
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-17 12:02:58 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-17 12:02:58 +0000
commit698f8c2f01ea549d77d7dc3338a12e04c11057b9 (patch)
tree173a775858bd501c378080a10dca74132f05bc50 /src/test/ui/object-safety
parentInitial commit. (diff)
downloadrustc-698f8c2f01ea549d77d7dc3338a12e04c11057b9.tar.xz
rustc-698f8c2f01ea549d77d7dc3338a12e04c11057b9.zip
Adding upstream version 1.64.0+dfsg1.upstream/1.64.0+dfsg1
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'src/test/ui/object-safety')
-rw-r--r--src/test/ui/object-safety/issue-19538.rs20
-rw-r--r--src/test/ui/object-safety/issue-19538.stderr37
-rw-r--r--src/test/ui/object-safety/object-safety-associated-consts.curr.stderr18
-rw-r--r--src/test/ui/object-safety/object-safety-associated-consts.object_safe_for_dispatch.stderr20
-rw-r--r--src/test/ui/object-safety/object-safety-associated-consts.rs19
-rw-r--r--src/test/ui/object-safety/object-safety-bounds.rs12
-rw-r--r--src/test/ui/object-safety/object-safety-bounds.stderr17
-rw-r--r--src/test/ui/object-safety/object-safety-by-value-self-use.rs18
-rw-r--r--src/test/ui/object-safety/object-safety-by-value-self-use.stderr9
-rw-r--r--src/test/ui/object-safety/object-safety-by-value-self.rs46
-rw-r--r--src/test/ui/object-safety/object-safety-generics.curr.stderr33
-rw-r--r--src/test/ui/object-safety/object-safety-generics.object_safe_for_dispatch.stderr37
-rw-r--r--src/test/ui/object-safety/object-safety-generics.rs39
-rw-r--r--src/test/ui/object-safety/object-safety-issue-22040.rs42
-rw-r--r--src/test/ui/object-safety/object-safety-issue-22040.stderr17
-rw-r--r--src/test/ui/object-safety/object-safety-mentions-Self.curr.stderr33
-rw-r--r--src/test/ui/object-safety/object-safety-mentions-Self.object_safe_for_dispatch.stderr37
-rw-r--r--src/test/ui/object-safety/object-safety-mentions-Self.rs42
-rw-r--r--src/test/ui/object-safety/object-safety-no-static.curr.stderr25
-rw-r--r--src/test/ui/object-safety/object-safety-no-static.object_safe_for_dispatch.stderr27
-rw-r--r--src/test/ui/object-safety/object-safety-no-static.rs24
-rw-r--r--src/test/ui/object-safety/object-safety-phantom-fn.rs22
-rw-r--r--src/test/ui/object-safety/object-safety-sized-2.curr.stderr17
-rw-r--r--src/test/ui/object-safety/object-safety-sized-2.object_safe_for_dispatch.stderr19
-rw-r--r--src/test/ui/object-safety/object-safety-sized-2.rs21
-rw-r--r--src/test/ui/object-safety/object-safety-sized.curr.stderr17
-rw-r--r--src/test/ui/object-safety/object-safety-sized.object_safe_for_dispatch.stderr19
-rw-r--r--src/test/ui/object-safety/object-safety-sized.rs19
-rw-r--r--src/test/ui/object-safety/object-safety-supertrait-mentions-Self.rs21
-rw-r--r--src/test/ui/object-safety/object-safety-supertrait-mentions-Self.stderr17
30 files changed, 744 insertions, 0 deletions
diff --git a/src/test/ui/object-safety/issue-19538.rs b/src/test/ui/object-safety/issue-19538.rs
new file mode 100644
index 000000000..7054ef41b
--- /dev/null
+++ b/src/test/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/src/test/ui/object-safety/issue-19538.stderr b/src/test/ui/object-safety/issue-19538.stderr
new file mode 100644
index 000000000..7b37e1f95
--- /dev/null
+++ b/src/test/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 because of the requirements on the impl of `CoerceUnsized<&mut dyn Bar>` for `&mut Thing`
+ = 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/src/test/ui/object-safety/object-safety-associated-consts.curr.stderr b/src/test/ui/object-safety/object-safety-associated-consts.curr.stderr
new file mode 100644
index 000000000..9dd144fee
--- /dev/null
+++ b/src/test/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:30
+ |
+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/src/test/ui/object-safety/object-safety-associated-consts.object_safe_for_dispatch.stderr b/src/test/ui/object-safety/object-safety-associated-consts.object_safe_for_dispatch.stderr
new file mode 100644
index 000000000..9ba3b251e
--- /dev/null
+++ b/src/test/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 because of the requirements on the impl of `CoerceUnsized<&dyn Bar>` for `&T`
+ = 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/src/test/ui/object-safety/object-safety-associated-consts.rs b/src/test/ui/object-safety/object-safety-associated-consts.rs
new file mode 100644
index 000000000..e1a772e5a
--- /dev/null
+++ b/src/test/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/src/test/ui/object-safety/object-safety-bounds.rs b/src/test/ui/object-safety/object-safety-bounds.rs
new file mode 100644
index 000000000..44bd36932
--- /dev/null
+++ b/src/test/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/src/test/ui/object-safety/object-safety-bounds.stderr b/src/test/ui/object-safety/object-safety-bounds.stderr
new file mode 100644
index 000000000..89c4f8ced
--- /dev/null
+++ b/src/test/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:11
+ |
+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/src/test/ui/object-safety/object-safety-by-value-self-use.rs b/src/test/ui/object-safety/object-safety-by-value-self-use.rs
new file mode 100644
index 000000000..8e93c5382
--- /dev/null
+++ b/src/test/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/src/test/ui/object-safety/object-safety-by-value-self-use.stderr b/src/test/ui/object-safety/object-safety-by-value-self-use.stderr
new file mode 100644
index 000000000..94fdcdf26
--- /dev/null
+++ b/src/test/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/src/test/ui/object-safety/object-safety-by-value-self.rs b/src/test/ui/object-safety/object-safety-by-value-self.rs
new file mode 100644
index 000000000..c74a4d1cb
--- /dev/null
+++ b/src/test/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/src/test/ui/object-safety/object-safety-generics.curr.stderr b/src/test/ui/object-safety/object-safety-generics.curr.stderr
new file mode 100644
index 000000000..345950f1a
--- /dev/null
+++ b/src/test/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:30
+ |
+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:39
+ |
+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/src/test/ui/object-safety/object-safety-generics.object_safe_for_dispatch.stderr b/src/test/ui/object-safety/object-safety-generics.object_safe_for_dispatch.stderr
new file mode 100644
index 000000000..86355627c
--- /dev/null
+++ b/src/test/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 because of the requirements on the impl of `CoerceUnsized<&dyn Bar>` for `&T`
+ = 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 because of the requirements on the impl of `CoerceUnsized<&dyn Bar>` for `&T`
+ = 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/src/test/ui/object-safety/object-safety-generics.rs b/src/test/ui/object-safety/object-safety-generics.rs
new file mode 100644
index 000000000..63dcd1699
--- /dev/null
+++ b/src/test/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/src/test/ui/object-safety/object-safety-issue-22040.rs b/src/test/ui/object-safety/object-safety-issue-22040.rs
new file mode 100644
index 000000000..1fc5c5442
--- /dev/null
+++ b/src/test/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/src/test/ui/object-safety/object-safety-issue-22040.stderr b/src/test/ui/object-safety/object-safety-issue-22040.stderr
new file mode 100644
index 000000000..0262d5362
--- /dev/null
+++ b/src/test/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/src/test/ui/object-safety/object-safety-mentions-Self.curr.stderr b/src/test/ui/object-safety/object-safety-mentions-Self.curr.stderr
new file mode 100644
index 000000000..f91c9b985
--- /dev/null
+++ b/src/test/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:30
+ |
+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:30
+ |
+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/src/test/ui/object-safety/object-safety-mentions-Self.object_safe_for_dispatch.stderr b/src/test/ui/object-safety/object-safety-mentions-Self.object_safe_for_dispatch.stderr
new file mode 100644
index 000000000..f48628c9d
--- /dev/null
+++ b/src/test/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 because of the requirements on the impl of `CoerceUnsized<&dyn Bar>` for `&T`
+ = 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 because of the requirements on the impl of `CoerceUnsized<&dyn Baz>` for `&T`
+ = 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/src/test/ui/object-safety/object-safety-mentions-Self.rs b/src/test/ui/object-safety/object-safety-mentions-Self.rs
new file mode 100644
index 000000000..412d16ff3
--- /dev/null
+++ b/src/test/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/src/test/ui/object-safety/object-safety-no-static.curr.stderr b/src/test/ui/object-safety/object-safety-no-static.curr.stderr
new file mode 100644
index 000000000..bd8cf4e30
--- /dev/null
+++ b/src/test/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:18
+ |
+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/src/test/ui/object-safety/object-safety-no-static.object_safe_for_dispatch.stderr b/src/test/ui/object-safety/object-safety-no-static.object_safe_for_dispatch.stderr
new file mode 100644
index 000000000..ea1c575ff
--- /dev/null
+++ b/src/test/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 because of the requirements on the impl of `CoerceUnsized<Box<dyn Foo>>` for `Box<Bar>`
+ = 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/src/test/ui/object-safety/object-safety-no-static.rs b/src/test/ui/object-safety/object-safety-no-static.rs
new file mode 100644
index 000000000..03b622174
--- /dev/null
+++ b/src/test/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/src/test/ui/object-safety/object-safety-phantom-fn.rs b/src/test/ui/object-safety/object-safety-phantom-fn.rs
new file mode 100644
index 000000000..3ffeb81c1
--- /dev/null
+++ b/src/test/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/src/test/ui/object-safety/object-safety-sized-2.curr.stderr b/src/test/ui/object-safety/object-safety-sized-2.curr.stderr
new file mode 100644
index 000000000..71236c8e3
--- /dev/null
+++ b/src/test/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:30
+ |
+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/src/test/ui/object-safety/object-safety-sized-2.object_safe_for_dispatch.stderr b/src/test/ui/object-safety/object-safety-sized-2.object_safe_for_dispatch.stderr
new file mode 100644
index 000000000..b6e4903b0
--- /dev/null
+++ b/src/test/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 because of the requirements on the impl of `CoerceUnsized<&dyn Bar>` for `&T`
+ = 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/src/test/ui/object-safety/object-safety-sized-2.rs b/src/test/ui/object-safety/object-safety-sized-2.rs
new file mode 100644
index 000000000..1e79b8cd9
--- /dev/null
+++ b/src/test/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/src/test/ui/object-safety/object-safety-sized.curr.stderr b/src/test/ui/object-safety/object-safety-sized.curr.stderr
new file mode 100644
index 000000000..94b06ee93
--- /dev/null
+++ b/src/test/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:30
+ |
+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/src/test/ui/object-safety/object-safety-sized.object_safe_for_dispatch.stderr b/src/test/ui/object-safety/object-safety-sized.object_safe_for_dispatch.stderr
new file mode 100644
index 000000000..645852c7e
--- /dev/null
+++ b/src/test/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 because of the requirements on the impl of `CoerceUnsized<&dyn Bar>` for `&T`
+ = 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/src/test/ui/object-safety/object-safety-sized.rs b/src/test/ui/object-safety/object-safety-sized.rs
new file mode 100644
index 000000000..b424b892d
--- /dev/null
+++ b/src/test/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/src/test/ui/object-safety/object-safety-supertrait-mentions-Self.rs b/src/test/ui/object-safety/object-safety-supertrait-mentions-Self.rs
new file mode 100644
index 000000000..2445b33c8
--- /dev/null
+++ b/src/test/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/src/test/ui/object-safety/object-safety-supertrait-mentions-Self.stderr b/src/test/ui/object-safety/object-safety-supertrait-mentions-Self.stderr
new file mode 100644
index 000000000..a106ab995
--- /dev/null
+++ b/src/test/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`.