about summary refs log tree commit diff
path: root/src/test
diff options
context:
space:
mode:
authorMathias Blikstad <mathias@blikstad.se>2019-01-08 22:14:04 +0100
committerNiko Matsakis <niko@alum.mit.edu>2019-10-22 15:24:33 -0400
commitef5acdecebb48a02cb34d19fa17d1bd59e41a4d3 (patch)
treecb6e20d78485549efc93763e17677eefe09ab6fc /src/test
parentd28a9c38fe14396e86ae274c7847e20ee0f78ca9 (diff)
downloadrust-ef5acdecebb48a02cb34d19fa17d1bd59e41a4d3.tar.gz
rust-ef5acdecebb48a02cb34d19fa17d1bd59e41a4d3.zip
RFC 2027: "first draft" of implementation
These are a squashed series of commits.
Diffstat (limited to 'src/test')
-rw-r--r--src/test/ui/coherence/coherence-unsafe-trait-object-impl.rs18
-rw-r--r--src/test/ui/coherence/coherence-unsafe-trait-object-impl.stderr12
-rw-r--r--src/test/ui/feature-gates/feature-gate-exhaustive-patterns.nll.stderr16
-rw-r--r--src/test/ui/feature-gates/feature-gate-object_safe_for_dispatch.rs41
-rw-r--r--src/test/ui/feature-gates/feature-gate-object_safe_for_dispatch.stderr46
-rw-r--r--src/test/ui/issues/issue-19538.stderr1
-rw-r--r--src/test/ui/issues/issue-20692.stderr1
-rw-r--r--src/test/ui/issues/issue-38604.stderr1
-rw-r--r--src/test/ui/kindck/kindck-inherited-copy-bound.curr.stderr (renamed from src/test/ui/kindck/kindck-inherited-copy-bound.stderr)7
-rw-r--r--src/test/ui/kindck/kindck-inherited-copy-bound.object_safe_for_dispatch.stderr25
-rw-r--r--src/test/ui/kindck/kindck-inherited-copy-bound.rs11
-rw-r--r--src/test/ui/object-safety/object-safety-associated-consts.curr.stderr (renamed from src/test/ui/object-safety/object-safety-associated-consts.stderr)2
-rw-r--r--src/test/ui/object-safety/object-safety-associated-consts.object_safe_for_dispatch.stderr15
-rw-r--r--src/test/ui/object-safety/object-safety-associated-consts.rs6
-rw-r--r--src/test/ui/object-safety/object-safety-generics.curr.stderr (renamed from src/test/ui/object-safety/object-safety-generics.stderr)4
-rw-r--r--src/test/ui/object-safety/object-safety-generics.object_safe_for_dispatch.stderr27
-rw-r--r--src/test/ui/object-safety/object-safety-generics.rs10
-rw-r--r--src/test/ui/object-safety/object-safety-mentions-Self.curr.stderr (renamed from src/test/ui/object-safety/object-safety-mentions-Self.stderr)8
-rw-r--r--src/test/ui/object-safety/object-safety-mentions-Self.object_safe_for_dispatch.stderr27
-rw-r--r--src/test/ui/object-safety/object-safety-mentions-Self.rs20
-rw-r--r--src/test/ui/object-safety/object-safety-no-static.curr.stderr12
-rw-r--r--src/test/ui/object-safety/object-safety-no-static.object_safe_for_dispatch.stderr15
-rw-r--r--src/test/ui/object-safety/object-safety-no-static.rs16
-rw-r--r--src/test/ui/object-safety/object-safety-sized-2.curr.stderr (renamed from src/test/ui/object-safety/object-safety-sized-2.stderr)2
-rw-r--r--src/test/ui/object-safety/object-safety-sized-2.object_safe_for_dispatch.stderr13
-rw-r--r--src/test/ui/object-safety/object-safety-sized-2.rs9
-rw-r--r--src/test/ui/object-safety/object-safety-sized.curr.stderr (renamed from src/test/ui/object-safety/object-safety-sized.stderr)2
-rw-r--r--src/test/ui/object-safety/object-safety-sized.object_safe_for_dispatch.stderr13
-rw-r--r--src/test/ui/object-safety/object-safety-sized.rs7
-rw-r--r--src/test/ui/rfc-2027-object-safe-for-dispatch/downcast-unsafe-trait-objects.rs23
-rw-r--r--src/test/ui/rfc-2027-object-safe-for-dispatch/manual-self-impl-for-unsafe-obj.rs69
-rw-r--r--src/test/ui/rfc-2027-object-safe-for-dispatch/static-dispatch-unsafe-object.rs37
-rw-r--r--src/test/ui/self/arbitrary-self-types-not-object-safe.curr.stderr24
-rw-r--r--src/test/ui/self/arbitrary-self-types-not-object-safe.object_safe_for_dispatch.stderr15
-rw-r--r--src/test/ui/self/arbitrary-self-types-not-object-safe.rs8
-rw-r--r--src/test/ui/traits/trait-object-safety.stderr1
-rw-r--r--src/test/ui/traits/trait-test-2.stderr1
-rw-r--r--src/test/ui/wf/wf-convert-unsafe-trait-obj-box.rs18
-rw-r--r--src/test/ui/wf/wf-convert-unsafe-trait-obj-box.stderr33
-rw-r--r--src/test/ui/wf/wf-convert-unsafe-trait-obj.rs18
-rw-r--r--src/test/ui/wf/wf-convert-unsafe-trait-obj.stderr33
-rw-r--r--src/test/ui/wf/wf-unsafe-trait-obj-match.rs29
-rw-r--r--src/test/ui/wf/wf-unsafe-trait-obj-match.stderr38
43 files changed, 685 insertions, 49 deletions
diff --git a/src/test/ui/coherence/coherence-unsafe-trait-object-impl.rs b/src/test/ui/coherence/coherence-unsafe-trait-object-impl.rs
new file mode 100644
index 00000000000..9859a226efd
--- /dev/null
+++ b/src/test/ui/coherence/coherence-unsafe-trait-object-impl.rs
@@ -0,0 +1,18 @@
+// Check that unsafe trait object do not implement themselves
+// automatically
+
+#![feature(object_safe_for_dispatch)]
+
+trait Trait: Sized {
+    fn call(&self);
+}
+
+fn takes_t<S: Trait>(s: S) {
+    s.call();
+}
+
+fn takes_t_obj(t: &dyn Trait) {
+    takes_t(t); //~ ERROR E0277
+}
+
+fn main() {}
diff --git a/src/test/ui/coherence/coherence-unsafe-trait-object-impl.stderr b/src/test/ui/coherence/coherence-unsafe-trait-object-impl.stderr
new file mode 100644
index 00000000000..b5a86acfb97
--- /dev/null
+++ b/src/test/ui/coherence/coherence-unsafe-trait-object-impl.stderr
@@ -0,0 +1,12 @@
+error[E0277]: the trait bound `&dyn Trait: Trait` is not satisfied
+  --> $DIR/coherence-unsafe-trait-object-impl.rs:15:13
+   |
+LL | fn takes_t<S: Trait>(s: S) {
+   |    -------    ----- required by this bound in `takes_t`
+...
+LL |     takes_t(t);
+   |             ^ the trait `Trait` is not implemented for `&dyn Trait`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/src/test/ui/feature-gates/feature-gate-exhaustive-patterns.nll.stderr b/src/test/ui/feature-gates/feature-gate-exhaustive-patterns.nll.stderr
deleted file mode 100644
index d77fbc1e823..00000000000
--- a/src/test/ui/feature-gates/feature-gate-exhaustive-patterns.nll.stderr
+++ /dev/null
@@ -1,16 +0,0 @@
-error[E0005]: refutable pattern in local binding: `Err(_)` not covered
-  --> $DIR/feature-gate-exhaustive-patterns.rs:7:9
-   |
-LL |     let Ok(_x) = foo();
-   |         ^^^^^^ pattern `Err(_)` not covered
-   |
-   = note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant
-   = note: for more information, visit https://doc.rust-lang.org/book/ch18-02-refutability.html
-help: you might want to use `if let` to ignore the variant that isn't matched
-   |
-LL |     if let Ok(_x) = foo() { /* */ }
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-error: aborting due to previous error
-
-For more information about this error, try `rustc --explain E0005`.
diff --git a/src/test/ui/feature-gates/feature-gate-object_safe_for_dispatch.rs b/src/test/ui/feature-gates/feature-gate-object_safe_for_dispatch.rs
new file mode 100644
index 00000000000..8945360b7be
--- /dev/null
+++ b/src/test/ui/feature-gates/feature-gate-object_safe_for_dispatch.rs
@@ -0,0 +1,41 @@
+// Test that the use of the non object-safe trait objects
+// are gated by `object_safe_for_dispatch` feature gate.
+
+trait NonObjectSafe1: Sized {}
+
+trait NonObjectSafe2 {
+    fn static_fn() {}
+}
+
+trait NonObjectSafe3 {
+    fn foo<T>(&self);
+}
+
+trait NonObjectSafe4 {
+    fn foo(&self, &Self);
+}
+
+fn takes_non_object_safe_ref<T>(obj: &dyn NonObjectSafe1) {
+    //~^ ERROR E0038
+}
+
+fn return_non_object_safe_ref() -> &'static dyn NonObjectSafe2 {
+    //~^ ERROR E0038
+    loop {}
+}
+
+fn takes_non_object_safe_box(obj: Box<dyn NonObjectSafe3>) {
+    //~^ ERROR E0038
+}
+
+fn return_non_object_safe_rc() -> std::rc::Rc<dyn NonObjectSafe4> {
+    //~^ ERROR E0038
+    loop {}
+}
+
+trait Trait {}
+
+impl Trait for dyn NonObjectSafe1 {}
+//~^ ERROR E0038
+
+fn main() {}
diff --git a/src/test/ui/feature-gates/feature-gate-object_safe_for_dispatch.stderr b/src/test/ui/feature-gates/feature-gate-object_safe_for_dispatch.stderr
new file mode 100644
index 00000000000..54e64e2fc1b
--- /dev/null
+++ b/src/test/ui/feature-gates/feature-gate-object_safe_for_dispatch.stderr
@@ -0,0 +1,46 @@
+error[E0038]: the trait `NonObjectSafe1` cannot be made into an object
+  --> $DIR/feature-gate-object_safe_for_dispatch.rs:18:1
+   |
+LL | fn takes_non_object_safe_ref<T>(obj: &dyn NonObjectSafe1) {
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `NonObjectSafe1` cannot be made into an object
+   |
+   = note: the trait cannot require that `Self : Sized`
+
+error[E0038]: the trait `NonObjectSafe2` cannot be made into an object
+  --> $DIR/feature-gate-object_safe_for_dispatch.rs:22:1
+   |
+LL |     fn static_fn() {}
+   |        --------- associated function `static_fn` has no `self` parameter
+...
+LL | fn return_non_object_safe_ref() -> &'static dyn NonObjectSafe2 {
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `NonObjectSafe2` cannot be made into an object
+
+error[E0038]: the trait `NonObjectSafe3` cannot be made into an object
+  --> $DIR/feature-gate-object_safe_for_dispatch.rs:27:1
+   |
+LL |     fn foo<T>(&self);
+   |        --- method `foo` has generic type parameters
+...
+LL | fn takes_non_object_safe_box(obj: Box<dyn NonObjectSafe3>) {
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `NonObjectSafe3` cannot be made into an object
+
+error[E0038]: the trait `NonObjectSafe4` cannot be made into an object
+  --> $DIR/feature-gate-object_safe_for_dispatch.rs:31:1
+   |
+LL |     fn foo(&self, &Self);
+   |        --- method `foo` references the `Self` type in its parameters or return type
+...
+LL | fn return_non_object_safe_rc() -> std::rc::Rc<dyn NonObjectSafe4> {
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `NonObjectSafe4` cannot be made into an object
+
+error[E0038]: the trait `NonObjectSafe1` cannot be made into an object
+  --> $DIR/feature-gate-object_safe_for_dispatch.rs:38:6
+   |
+LL | impl Trait for dyn NonObjectSafe1 {}
+   |      ^^^^^ the trait `NonObjectSafe1` cannot be made into an object
+   |
+   = note: the trait cannot require that `Self : Sized`
+
+error: aborting due to 5 previous errors
+
+For more information about this error, try `rustc --explain E0038`.
diff --git a/src/test/ui/issues/issue-19538.stderr b/src/test/ui/issues/issue-19538.stderr
index 5415a45f7d6..83c03b514dd 100644
--- a/src/test/ui/issues/issue-19538.stderr
+++ b/src/test/ui/issues/issue-19538.stderr
@@ -17,6 +17,7 @@ LL |     let test: &mut dyn Bar = &mut thing;
    |                              ^^^^^^^^^^ the trait `Bar` cannot be made into an object
    |
    = note: required because of the requirements on the impl of `std::ops::CoerceUnsized<&mut dyn Bar>` for `&mut Thing`
+   = note: required by cast to type `&mut dyn Bar`
 
 error: aborting due to 2 previous errors
 
diff --git a/src/test/ui/issues/issue-20692.stderr b/src/test/ui/issues/issue-20692.stderr
index 66309394a42..06c83f65be2 100644
--- a/src/test/ui/issues/issue-20692.stderr
+++ b/src/test/ui/issues/issue-20692.stderr
@@ -14,6 +14,7 @@ LL |     let _ = x
    |
    = note: the trait cannot require that `Self : Sized`
    = note: required because of the requirements on the impl of `std::ops::CoerceUnsized<&dyn Array>` for `&T`
+   = note: required by cast to type `&dyn Array`
 
 error: aborting due to 2 previous errors
 
diff --git a/src/test/ui/issues/issue-38604.stderr b/src/test/ui/issues/issue-38604.stderr
index 8ef7d346cb3..8b923a2c6b2 100644
--- a/src/test/ui/issues/issue-38604.stderr
+++ b/src/test/ui/issues/issue-38604.stderr
@@ -14,6 +14,7 @@ LL |         Box::new(());
    |
    = note: the trait cannot use `Self` as a type parameter in the supertraits or where-clauses
    = note: required because of the requirements on the impl of `std::ops::CoerceUnsized<std::boxed::Box<dyn Foo>>` for `std::boxed::Box<()>`
+   = note: required by cast to type `std::boxed::Box<dyn Foo>`
 
 error: aborting due to 2 previous errors
 
diff --git a/src/test/ui/kindck/kindck-inherited-copy-bound.stderr b/src/test/ui/kindck/kindck-inherited-copy-bound.curr.stderr
index 27901d06927..a93f4686496 100644
--- a/src/test/ui/kindck/kindck-inherited-copy-bound.stderr
+++ b/src/test/ui/kindck/kindck-inherited-copy-bound.curr.stderr
@@ -1,5 +1,5 @@
 error[E0277]: the trait bound `std::boxed::Box<{integer}>: std::marker::Copy` is not satisfied
-  --> $DIR/kindck-inherited-copy-bound.rs:18:16
+  --> $DIR/kindck-inherited-copy-bound.rs:21:16
    |
 LL | fn take_param<T:Foo>(foo: &T) { }
    |    ----------   --- required by this bound in `take_param`
@@ -10,7 +10,7 @@ LL |     take_param(&x);
    = note: required because of the requirements on the impl of `Foo` for `std::boxed::Box<{integer}>`
 
 error[E0038]: the trait `Foo` cannot be made into an object
-  --> $DIR/kindck-inherited-copy-bound.rs:24:19
+  --> $DIR/kindck-inherited-copy-bound.rs:28:19
    |
 LL |     let z = &x as &dyn Foo;
    |                   ^^^^^^^^ the trait `Foo` cannot be made into an object
@@ -18,13 +18,14 @@ LL |     let z = &x as &dyn Foo;
    = note: the trait cannot require that `Self : Sized`
 
 error[E0038]: the trait `Foo` cannot be made into an object
-  --> $DIR/kindck-inherited-copy-bound.rs:24:13
+  --> $DIR/kindck-inherited-copy-bound.rs:28:13
    |
 LL |     let z = &x as &dyn Foo;
    |             ^^ the trait `Foo` cannot be made into an object
    |
    = note: the trait cannot require that `Self : Sized`
    = note: required because of the requirements on the impl of `std::ops::CoerceUnsized<&dyn Foo>` for `&std::boxed::Box<{integer}>`
+   = note: required by cast to type `&dyn Foo`
 
 error: aborting due to 3 previous errors
 
diff --git a/src/test/ui/kindck/kindck-inherited-copy-bound.object_safe_for_dispatch.stderr b/src/test/ui/kindck/kindck-inherited-copy-bound.object_safe_for_dispatch.stderr
new file mode 100644
index 00000000000..7c67c5f9e95
--- /dev/null
+++ b/src/test/ui/kindck/kindck-inherited-copy-bound.object_safe_for_dispatch.stderr
@@ -0,0 +1,25 @@
+error[E0277]: the trait bound `std::boxed::Box<{integer}>: std::marker::Copy` is not satisfied
+  --> $DIR/kindck-inherited-copy-bound.rs:21:16
+   |
+LL | fn take_param<T:Foo>(foo: &T) { }
+   |    ----------   --- required by this bound in `take_param`
+...
+LL |     take_param(&x);
+   |                ^^ the trait `std::marker::Copy` is not implemented for `std::boxed::Box<{integer}>`
+   |
+   = note: required because of the requirements on the impl of `Foo` for `std::boxed::Box<{integer}>`
+
+error[E0038]: the trait `Foo` cannot be made into an object
+  --> $DIR/kindck-inherited-copy-bound.rs:28:13
+   |
+LL |     let z = &x as &dyn Foo;
+   |             ^^ the trait `Foo` cannot be made into an object
+   |
+   = note: the trait cannot require that `Self : Sized`
+   = note: required because of the requirements on the impl of `std::ops::CoerceUnsized<&dyn Foo>` for `&std::boxed::Box<i32>`
+   = note: required by cast to type `&dyn Foo`
+
+error: aborting due to 2 previous errors
+
+Some errors have detailed explanations: E0038, E0277.
+For more information about an error, try `rustc --explain E0038`.
diff --git a/src/test/ui/kindck/kindck-inherited-copy-bound.rs b/src/test/ui/kindck/kindck-inherited-copy-bound.rs
index 61e72908248..aad693e5b19 100644
--- a/src/test/ui/kindck/kindck-inherited-copy-bound.rs
+++ b/src/test/ui/kindck/kindck-inherited-copy-bound.rs
@@ -1,5 +1,8 @@
 // Test that Copy bounds inherited by trait are checked.
+//
+// revisions: curr object_safe_for_dispatch
 
+#![cfg_attr(object_safe_for_dispatch, feature(object_safe_for_dispatch))]
 #![feature(box_syntax)]
 
 use std::any::Any;
@@ -15,15 +18,17 @@ fn take_param<T:Foo>(foo: &T) { }
 
 fn a() {
     let x: Box<_> = box 3;
-    take_param(&x); //~ ERROR E0277
+    take_param(&x); //[curr]~ ERROR E0277
+    //[object_safe_for_dispatch]~^ ERROR E0277
 }
 
 fn b() {
     let x: Box<_> = box 3;
     let y = &x;
     let z = &x as &dyn Foo;
-    //~^ ERROR E0038
-    //~| ERROR E0038
+    //[curr]~^ ERROR E0038
+    //[curr]~| ERROR E0038
+    //[object_safe_for_dispatch]~^^^ ERROR E0038
 }
 
 fn main() { }
diff --git a/src/test/ui/object-safety/object-safety-associated-consts.stderr b/src/test/ui/object-safety/object-safety-associated-consts.curr.stderr
index 7d5aa00356e..67ef7a62f10 100644
--- a/src/test/ui/object-safety/object-safety-associated-consts.stderr
+++ b/src/test/ui/object-safety/object-safety-associated-consts.curr.stderr
@@ -1,5 +1,5 @@
 error[E0038]: the trait `Bar` cannot be made into an object
-  --> $DIR/object-safety-associated-consts.rs:9:1
+  --> $DIR/object-safety-associated-consts.rs:12:1
    |
 LL |     const X: usize;
    |           - the trait cannot contain associated consts like `X`
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 00000000000..20993a680ba
--- /dev/null
+++ b/src/test/ui/object-safety/object-safety-associated-consts.object_safe_for_dispatch.stderr
@@ -0,0 +1,15 @@
+error[E0038]: the trait `Bar` cannot be made into an object
+  --> $DIR/object-safety-associated-consts.rs:14:5
+   |
+LL |     const X: usize;
+   |           - the trait cannot contain associated consts like `X`
+...
+LL |     t
+   |     ^ the trait `Bar` cannot be made into an object
+   |
+   = note: required because of the requirements on the impl of `std::ops::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
index 5900019ea91..e1a772e5ab2 100644
--- a/src/test/ui/object-safety/object-safety-associated-consts.rs
+++ b/src/test/ui/object-safety/object-safety-associated-consts.rs
@@ -1,14 +1,18 @@
 // 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 {
-    //~^ ERROR E0038
+    //[curr]~^ ERROR E0038
     t
+    //[object_safe_for_dispatch]~^ ERROR E0038
 }
 
 fn main() {
diff --git a/src/test/ui/object-safety/object-safety-generics.stderr b/src/test/ui/object-safety/object-safety-generics.curr.stderr
index b25e0052e41..8ae9236a5c3 100644
--- a/src/test/ui/object-safety/object-safety-generics.stderr
+++ b/src/test/ui/object-safety/object-safety-generics.curr.stderr
@@ -1,5 +1,5 @@
 error[E0038]: the trait `Bar` cannot be made into an object
-  --> $DIR/object-safety-generics.rs:14:1
+  --> $DIR/object-safety-generics.rs:18:1
    |
 LL |     fn bar<T>(&self, t: T);
    |        --- method `bar` has generic type parameters
@@ -8,7 +8,7 @@ LL | fn make_bar<T:Bar>(t: &T) -> &dyn Bar {
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Bar` cannot be made into an object
 
 error[E0038]: the trait `Bar` cannot be made into an object
-  --> $DIR/object-safety-generics.rs:19:1
+  --> $DIR/object-safety-generics.rs:24:1
    |
 LL |     fn bar<T>(&self, t: T);
    |        --- method `bar` has generic type parameters
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 00000000000..d3d8d368888
--- /dev/null
+++ b/src/test/ui/object-safety/object-safety-generics.object_safe_for_dispatch.stderr
@@ -0,0 +1,27 @@
+error[E0038]: the trait `Bar` cannot be made into an object
+  --> $DIR/object-safety-generics.rs:20:5
+   |
+LL |     fn bar<T>(&self, t: T);
+   |        --- method `bar` has generic type parameters
+...
+LL |     t
+   |     ^ the trait `Bar` cannot be made into an object
+   |
+   = note: required because of the requirements on the impl of `std::ops::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 |     fn bar<T>(&self, t: T);
+   |        --- method `bar` has generic type parameters
+...
+LL |     t as &dyn Bar
+   |     ^ the trait `Bar` cannot be made into an object
+   |
+   = note: required because of the requirements on the impl of `std::ops::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
index d63ea28c8f2..63dcd169925 100644
--- a/src/test/ui/object-safety/object-safety-generics.rs
+++ b/src/test/ui/object-safety/object-safety-generics.rs
@@ -1,6 +1,10 @@
 // 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);
@@ -12,13 +16,15 @@ trait Quux {
 }
 
 fn make_bar<T:Bar>(t: &T) -> &dyn Bar {
-        //~^ ERROR E0038
+    //[curr]~^ ERROR E0038
     t
+    //[object_safe_for_dispatch]~^ ERROR E0038
 }
 
 fn make_bar_explicit<T:Bar>(t: &T) -> &dyn Bar {
-    //~^ ERROR E0038
+    //[curr]~^ ERROR E0038
     t as &dyn Bar
+    //[object_safe_for_dispatch]~^ ERROR E0038
 }
 
 fn make_quux<T:Quux>(t: &T) -> &dyn Quux {
diff --git a/src/test/ui/object-safety/object-safety-mentions-Self.stderr b/src/test/ui/object-safety/object-safety-mentions-Self.curr.stderr
index 971e79cb021..297cd876187 100644
--- a/src/test/ui/object-safety/object-safety-mentions-Self.stderr
+++ b/src/test/ui/object-safety/object-safety-mentions-Self.curr.stderr
@@ -1,5 +1,5 @@
 error[E0038]: the trait `Bar` cannot be made into an object
-  --> $DIR/object-safety-mentions-Self.rs:17:1
+  --> $DIR/object-safety-mentions-Self.rs:22:1
    |
 LL |     fn bar(&self, x: &Self);
    |        --- method `bar` references the `Self` type in its parameters or return type
@@ -8,10 +8,10 @@ LL | fn make_bar<T:Bar>(t: &T) -> &dyn Bar {
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Bar` cannot be made into an object
 
 error[E0038]: the trait `Baz` cannot be made into an object
-  --> $DIR/object-safety-mentions-Self.rs:22:1
+  --> $DIR/object-safety-mentions-Self.rs:28:1
    |
-LL |     fn bar(&self) -> Self;
-   |        --- method `bar` references the `Self` type in its parameters or return type
+LL |     fn baz(&self) -> Self;
+   |        --- method `baz` references the `Self` type in its parameters or return type
 ...
 LL | fn make_baz<T:Baz>(t: &T) -> &dyn Baz {
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Baz` cannot be made into an object
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 00000000000..03b2b8da075
--- /dev/null
+++ b/src/test/ui/object-safety/object-safety-mentions-Self.object_safe_for_dispatch.stderr
@@ -0,0 +1,27 @@
+error[E0038]: the trait `Bar` cannot be made into an object
+  --> $DIR/object-safety-mentions-Self.rs:24:5
+   |
+LL |     fn bar(&self, x: &Self);
+   |        --- method `bar` references the `Self` type in its parameters or return type
+...
+LL |     t
+   |     ^ the trait `Bar` cannot be made into an object
+   |
+   = note: required because of the requirements on the impl of `std::ops::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 |     fn baz(&self) -> Self;
+   |        --- method `baz` references the `Self` type in its parameters or return type
+...
+LL |     t
+   |     ^ the trait `Baz` cannot be made into an object
+   |
+   = note: required because of the requirements on the impl of `std::ops::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
index f13ffe53626..412d16ff3c7 100644
--- a/src/test/ui/object-safety/object-safety-mentions-Self.rs
+++ b/src/test/ui/object-safety/object-safety-mentions-Self.rs
@@ -1,27 +1,34 @@
 // 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 bar(&self) -> Self;
+    fn baz(&self) -> Self;
 }
 
 trait Quux {
-    fn get(&self, s: &Self) -> Self where Self : Sized;
+    fn quux(&self, s: &Self) -> Self where Self : Sized;
 }
 
 fn make_bar<T:Bar>(t: &T) -> &dyn Bar {
-        //~^ ERROR E0038
-    loop { }
+    //[curr]~^ ERROR E0038
+    t
+    //[object_safe_for_dispatch]~^ ERROR E0038
 }
 
 fn make_baz<T:Baz>(t: &T) -> &dyn Baz {
-        //~^ ERROR E0038
+    //[curr]~^ ERROR E0038
     t
+    //[object_safe_for_dispatch]~^ ERROR E0038
 }
 
 fn make_quux<T:Quux>(t: &T) -> &dyn Quux {
@@ -32,5 +39,4 @@ fn make_quux_explicit<T:Quux>(t: &T) -> &dyn Quux {
     t as &dyn Quux
 }
 
-fn main() {
-}
+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 00000000000..1641ce57771
--- /dev/null
+++ b/src/test/ui/object-safety/object-safety-no-static.curr.stderr
@@ -0,0 +1,12 @@
+error[E0038]: the trait `Foo` cannot be made into an object
+  --> $DIR/object-safety-no-static.rs:12:1
+   |
+LL |     fn foo() {}
+   |        --- associated function `foo` has no `self` parameter
+...
+LL | fn diverges() -> Box<dyn Foo> {
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Foo` 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-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 00000000000..91a9285b63c
--- /dev/null
+++ b/src/test/ui/object-safety/object-safety-no-static.object_safe_for_dispatch.stderr
@@ -0,0 +1,15 @@
+error[E0038]: the trait `Foo` cannot be made into an object
+  --> $DIR/object-safety-no-static.rs:22:27
+   |
+LL |     fn foo() {}
+   |        --- associated function `foo` has no `self` parameter
+...
+LL |     let b: Box<dyn Foo> = Box::new(Bar);
+   |                           ^^^^^^^^^^^^^ the trait `Foo` cannot be made into an object
+   |
+   = note: required because of the requirements on the impl of `std::ops::CoerceUnsized<std::boxed::Box<dyn Foo>>` for `std::boxed::Box<Bar>`
+   = note: required by cast to type `std::boxed::Box<dyn Foo>`
+
+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
index 55d31ce8087..03b62217483 100644
--- a/src/test/ui/object-safety/object-safety-no-static.rs
+++ b/src/test/ui/object-safety/object-safety-no-static.rs
@@ -1,14 +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 foo() {}
 }
 
-fn foo_implicit<T:Foo+'static>(b: Box<T>) -> Box<dyn Foo + 'static> {
-    //~^ ERROR E0038
+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-sized-2.stderr b/src/test/ui/object-safety/object-safety-sized-2.curr.stderr
index dcaf2ff0bc2..1e1d2bf64c4 100644
--- a/src/test/ui/object-safety/object-safety-sized-2.stderr
+++ b/src/test/ui/object-safety/object-safety-sized-2.curr.stderr
@@ -1,5 +1,5 @@
 error[E0038]: the trait `Bar` cannot be made into an object
-  --> $DIR/object-safety-sized-2.rs:10:1
+  --> $DIR/object-safety-sized-2.rs:14:1
    |
 LL | fn make_bar<T:Bar>(t: &T) -> &dyn Bar {
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Bar` cannot be made into an object
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 00000000000..06ecfd019c8
--- /dev/null
+++ b/src/test/ui/object-safety/object-safety-sized-2.object_safe_for_dispatch.stderr
@@ -0,0 +1,13 @@
+error[E0038]: the trait `Bar` cannot be made into an object
+  --> $DIR/object-safety-sized-2.rs:16:5
+   |
+LL |     t
+   |     ^ the trait `Bar` cannot be made into an object
+   |
+   = note: the trait cannot require that `Self : Sized`
+   = note: required because of the requirements on the impl of `std::ops::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
index 7235b22404e..1e79b8cd917 100644
--- a/src/test/ui/object-safety/object-safety-sized-2.rs
+++ b/src/test/ui/object-safety/object-safety-sized-2.rs
@@ -1,5 +1,9 @@
 // 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
@@ -8,8 +12,9 @@ trait Bar
 }
 
 fn make_bar<T:Bar>(t: &T) -> &dyn Bar {
-        //~^ ERROR E0038
-    loop { }
+    //[curr]~^ ERROR E0038
+    t
+    //[object_safe_for_dispatch]~^ ERROR E0038
 }
 
 fn main() {
diff --git a/src/test/ui/object-safety/object-safety-sized.stderr b/src/test/ui/object-safety/object-safety-sized.curr.stderr
index 98bc73e38d4..1a67e79e83d 100644
--- a/src/test/ui/object-safety/object-safety-sized.stderr
+++ b/src/test/ui/object-safety/object-safety-sized.curr.stderr
@@ -1,5 +1,5 @@
 error[E0038]: the trait `Bar` cannot be made into an object
-  --> $DIR/object-safety-sized.rs:8:1
+  --> $DIR/object-safety-sized.rs:12:1
    |
 LL | fn make_bar<T:Bar>(t: &T) -> &dyn Bar {
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Bar` cannot be made into an object
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 00000000000..3d88dfc40ed
--- /dev/null
+++ b/src/test/ui/object-safety/object-safety-sized.object_safe_for_dispatch.stderr
@@ -0,0 +1,13 @@
+error[E0038]: the trait `Bar` cannot be made into an object
+  --> $DIR/object-safety-sized.rs:14:5
+   |
+LL |     t
+   |     ^ the trait `Bar` cannot be made into an object
+   |
+   = note: the trait cannot require that `Self : Sized`
+   = note: required because of the requirements on the impl of `std::ops::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
index 1312bb34717..b424b892d3b 100644
--- a/src/test/ui/object-safety/object-safety-sized.rs
+++ b/src/test/ui/object-safety/object-safety-sized.rs
@@ -1,13 +1,18 @@
 // 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 {
-        //~^ ERROR E0038
+    //[curr]~^ ERROR E0038
     t
+    //[object_safe_for_dispatch]~^ ERROR E0038
 }
 
 fn main() {
diff --git a/src/test/ui/rfc-2027-object-safe-for-dispatch/downcast-unsafe-trait-objects.rs b/src/test/ui/rfc-2027-object-safe-for-dispatch/downcast-unsafe-trait-objects.rs
new file mode 100644
index 00000000000..fa04f4b12d5
--- /dev/null
+++ b/src/test/ui/rfc-2027-object-safe-for-dispatch/downcast-unsafe-trait-objects.rs
@@ -0,0 +1,23 @@
+// Check that we if we get ahold of an object unsafe trait
+// object with auto traits and lifetimes, we can downcast it
+//
+// check-pass
+
+#![feature(object_safe_for_dispatch)]
+
+trait Trait: Sized {}
+
+fn downcast_auto(t: &(dyn Trait + Send)) -> &dyn Trait {
+    t
+}
+
+fn downcast_lifetime<'a, 'b, 't>(t: &'a (dyn Trait + 't))
+                                 -> &'b (dyn Trait + 't)
+where
+    'a: 'b,
+    't: 'a + 'b,
+{
+    t
+}
+
+fn main() {}
diff --git a/src/test/ui/rfc-2027-object-safe-for-dispatch/manual-self-impl-for-unsafe-obj.rs b/src/test/ui/rfc-2027-object-safe-for-dispatch/manual-self-impl-for-unsafe-obj.rs
new file mode 100644
index 00000000000..1dea4012265
--- /dev/null
+++ b/src/test/ui/rfc-2027-object-safe-for-dispatch/manual-self-impl-for-unsafe-obj.rs
@@ -0,0 +1,69 @@
+// Check that we can manually implement an object
+// unsafe trait for its trait object
+//
+// run-pass
+
+#![feature(object_safe_for_dispatch)]
+
+trait Bad {
+    fn stat() -> char {
+        'A'
+    }
+    fn virt(&self) -> char {
+        'B'
+    }
+    fn indirect(&self) -> char {
+        Self::stat()
+    }
+}
+
+trait Good {
+    fn good_virt(&self) -> char {
+        panic!()
+    }
+    fn good_indirect(&self) -> char {
+        panic!()
+    }
+}
+
+impl<'a> Bad for dyn Bad + 'a {
+    fn stat() -> char {
+        'C'
+    }
+    fn virt(&self) -> char {
+        'D'
+    }
+}
+
+struct Struct {}
+
+impl Bad for Struct {}
+
+impl Good for Struct {}
+
+fn main() {
+    let s = Struct {};
+
+    let mut res = String::new();
+
+    // Directly call static
+    res.push(Struct::stat()); // "A"
+    res.push(<dyn Bad>::stat()); // "AC"
+
+    let good: &dyn Good = &s;
+
+    // These look similar enough...
+    let bad = unsafe { std::mem::transmute::<&dyn Good, &dyn Bad>(good) };
+
+    // Call virtual
+    res.push(s.virt()); // "ACB"
+    res.push(bad.virt()); // "ACBD"
+
+    // Indirectly call static
+    res.push(s.indirect()); // "ACBDA"
+    res.push(bad.indirect()); // "ACBDAC"
+
+    if &res != "ACBDAC" {
+        panic!();
+    }
+}
diff --git a/src/test/ui/rfc-2027-object-safe-for-dispatch/static-dispatch-unsafe-object.rs b/src/test/ui/rfc-2027-object-safe-for-dispatch/static-dispatch-unsafe-object.rs
new file mode 100644
index 00000000000..df97d2c1327
--- /dev/null
+++ b/src/test/ui/rfc-2027-object-safe-for-dispatch/static-dispatch-unsafe-object.rs
@@ -0,0 +1,37 @@
+// Check that we can statically dispatch methods for object
+// unsafe trait objects, directly and indirectly
+//
+// check-pass
+
+#![feature(object_safe_for_dispatch)]
+
+trait Statics {
+    fn plain() {}
+    fn generic<T>() {}
+}
+
+trait Trait: Sized {}
+
+impl<'a> Statics for dyn Trait + 'a {}
+
+fn static_poly<T: Statics + ?Sized>() {
+    T::plain();
+    T::generic::<usize>();
+}
+
+fn inferred_poly<T: Statics + ?Sized>(t: &T) {
+    static_poly::<T>();
+    T::plain();
+    T::generic::<usize>();
+}
+
+fn call(t: &dyn Trait) {
+    static_poly::<dyn Trait>();
+    inferred_poly(t);
+}
+
+fn main() {
+    static_poly::<dyn Trait>();
+    <dyn Trait>::plain();
+    <dyn Trait>::generic::<usize>()
+}
diff --git a/src/test/ui/self/arbitrary-self-types-not-object-safe.curr.stderr b/src/test/ui/self/arbitrary-self-types-not-object-safe.curr.stderr
new file mode 100644
index 00000000000..cdffc1d86ed
--- /dev/null
+++ b/src/test/ui/self/arbitrary-self-types-not-object-safe.curr.stderr
@@ -0,0 +1,24 @@
+error[E0038]: the trait `Foo` cannot be made into an object
+  --> $DIR/arbitrary-self-types-not-object-safe.rs:34:32
+   |
+LL |     fn foo(self: &Rc<Self>) -> usize;
+   |        --- method `foo`'s `self` parameter cannot be dispatched on
+...
+LL |     let x = Rc::new(5usize) as Rc<dyn Foo>;
+   |                                ^^^^^^^^^^^ the trait `Foo` cannot be made into an object
+
+error[E0038]: the trait `Foo` cannot be made into an object
+  --> $DIR/arbitrary-self-types-not-object-safe.rs:34:13
+   |
+LL |     fn foo(self: &Rc<Self>) -> usize;
+   |        --- method `foo`'s `self` parameter cannot be dispatched on
+...
+LL |     let x = Rc::new(5usize) as Rc<dyn Foo>;
+   |             ^^^^^^^^^^^^^^^ the trait `Foo` cannot be made into an object
+   |
+   = note: required because of the requirements on the impl of `std::ops::CoerceUnsized<std::rc::Rc<dyn Foo>>` for `std::rc::Rc<usize>`
+   = note: required by cast to type `std::rc::Rc<dyn Foo>`
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0038`.
diff --git a/src/test/ui/self/arbitrary-self-types-not-object-safe.object_safe_for_dispatch.stderr b/src/test/ui/self/arbitrary-self-types-not-object-safe.object_safe_for_dispatch.stderr
new file mode 100644
index 00000000000..725632a1212
--- /dev/null
+++ b/src/test/ui/self/arbitrary-self-types-not-object-safe.object_safe_for_dispatch.stderr
@@ -0,0 +1,15 @@
+error[E0038]: the trait `Foo` cannot be made into an object
+  --> $DIR/arbitrary-self-types-not-object-safe.rs:34:13
+   |
+LL |     fn foo(self: &Rc<Self>) -> usize;
+   |        --- method `foo`'s `self` parameter cannot be dispatched on
+...
+LL |     let x = Rc::new(5usize) as Rc<dyn Foo>;
+   |             ^^^^^^^^^^^^^^^ the trait `Foo` cannot be made into an object
+   |
+   = note: required because of the requirements on the impl of `std::ops::CoerceUnsized<std::rc::Rc<dyn Foo>>` for `std::rc::Rc<usize>`
+   = note: required by cast to type `std::rc::Rc<dyn Foo>`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0038`.
diff --git a/src/test/ui/self/arbitrary-self-types-not-object-safe.rs b/src/test/ui/self/arbitrary-self-types-not-object-safe.rs
index 7443d888c9e..2eeabad28db 100644
--- a/src/test/ui/self/arbitrary-self-types-not-object-safe.rs
+++ b/src/test/ui/self/arbitrary-self-types-not-object-safe.rs
@@ -1,3 +1,6 @@
+// revisions: curr object_safe_for_dispatch
+
+#![cfg_attr(object_safe_for_dispatch, feature(object_safe_for_dispatch))]
 #![feature(arbitrary_self_types)]
 
 use std::rc::Rc;
@@ -29,8 +32,9 @@ impl Bar for usize {
 
 fn make_foo() {
     let x = Rc::new(5usize) as Rc<dyn Foo>;
-    //~^ ERROR E0038
-    //~| ERROR E0038
+    //[curr]~^ ERROR E0038
+    //[curr]~| ERROR E0038
+    //[object_safe_for_dispatch]~^^^ ERROR E0038
 }
 
 fn make_bar() {
diff --git a/src/test/ui/traits/trait-object-safety.stderr b/src/test/ui/traits/trait-object-safety.stderr
index 3ac1e96b30c..028e9eedd64 100644
--- a/src/test/ui/traits/trait-object-safety.stderr
+++ b/src/test/ui/traits/trait-object-safety.stderr
@@ -8,6 +8,7 @@ LL |     let _: &dyn Tr = &St;
    |                      ^^^ the trait `Tr` cannot be made into an object
    |
    = note: required because of the requirements on the impl of `std::ops::CoerceUnsized<&dyn Tr>` for `&St`
+   = note: required by cast to type `&dyn Tr`
 
 error[E0038]: the trait `Tr` cannot be made into an object
   --> $DIR/trait-object-safety.rs:15:12
diff --git a/src/test/ui/traits/trait-test-2.stderr b/src/test/ui/traits/trait-test-2.stderr
index 83c2c065274..9b750d382ec 100644
--- a/src/test/ui/traits/trait-test-2.stderr
+++ b/src/test/ui/traits/trait-test-2.stderr
@@ -33,6 +33,7 @@ LL |     (box 10 as Box<dyn bar>).dup();
    |      ^^^^^^ the trait `bar` cannot be made into an object
    |
    = note: required because of the requirements on the impl of `std::ops::CoerceUnsized<std::boxed::Box<dyn bar>>` for `std::boxed::Box<{integer}>`
+   = note: required by cast to type `std::boxed::Box<dyn bar>`
 
 error: aborting due to 4 previous errors
 
diff --git a/src/test/ui/wf/wf-convert-unsafe-trait-obj-box.rs b/src/test/ui/wf/wf-convert-unsafe-trait-obj-box.rs
new file mode 100644
index 00000000000..ffdb49a3be5
--- /dev/null
+++ b/src/test/ui/wf/wf-convert-unsafe-trait-obj-box.rs
@@ -0,0 +1,18 @@
+// Check that we do not allow casts or coercions
+// to object unsafe trait objects inside a Box
+
+#![feature(object_safe_for_dispatch)]
+
+trait Trait: Sized {}
+
+struct S;
+
+impl Trait for S {}
+
+fn takes_box(t: Box<dyn Trait>) {}
+
+fn main() {
+    Box::new(S) as Box<dyn Trait>; //~ ERROR E0038
+    let t_box: Box<dyn Trait> = Box::new(S); //~ ERROR E0038
+    takes_box(Box::new(S)); //~ ERROR E0038
+}
diff --git a/src/test/ui/wf/wf-convert-unsafe-trait-obj-box.stderr b/src/test/ui/wf/wf-convert-unsafe-trait-obj-box.stderr
new file mode 100644
index 00000000000..0b63aef2bce
--- /dev/null
+++ b/src/test/ui/wf/wf-convert-unsafe-trait-obj-box.stderr
@@ -0,0 +1,33 @@
+error[E0038]: the trait `Trait` cannot be made into an object
+  --> $DIR/wf-convert-unsafe-trait-obj-box.rs:16:33
+   |
+LL |     let t_box: Box<dyn Trait> = Box::new(S);
+   |                                 ^^^^^^^^^^^ the trait `Trait` cannot be made into an object
+   |
+   = note: the trait cannot require that `Self : Sized`
+   = note: required because of the requirements on the impl of `std::ops::CoerceUnsized<std::boxed::Box<dyn Trait>>` for `std::boxed::Box<S>`
+   = note: required by cast to type `std::boxed::Box<dyn Trait>`
+
+error[E0038]: the trait `Trait` cannot be made into an object
+  --> $DIR/wf-convert-unsafe-trait-obj-box.rs:17:15
+   |
+LL |     takes_box(Box::new(S));
+   |               ^^^^^^^^^^^ the trait `Trait` cannot be made into an object
+   |
+   = note: the trait cannot require that `Self : Sized`
+   = note: required because of the requirements on the impl of `std::ops::CoerceUnsized<std::boxed::Box<dyn Trait>>` for `std::boxed::Box<S>`
+   = note: required by cast to type `std::boxed::Box<(dyn Trait + 'static)>`
+
+error[E0038]: the trait `Trait` cannot be made into an object
+  --> $DIR/wf-convert-unsafe-trait-obj-box.rs:15:5
+   |
+LL |     Box::new(S) as Box<dyn Trait>;
+   |     ^^^^^^^^^^^ the trait `Trait` cannot be made into an object
+   |
+   = note: the trait cannot require that `Self : Sized`
+   = note: required because of the requirements on the impl of `std::ops::CoerceUnsized<std::boxed::Box<dyn Trait>>` for `std::boxed::Box<S>`
+   = note: required by cast to type `std::boxed::Box<dyn Trait>`
+
+error: aborting due to 3 previous errors
+
+For more information about this error, try `rustc --explain E0038`.
diff --git a/src/test/ui/wf/wf-convert-unsafe-trait-obj.rs b/src/test/ui/wf/wf-convert-unsafe-trait-obj.rs
new file mode 100644
index 00000000000..143b854ed6b
--- /dev/null
+++ b/src/test/ui/wf/wf-convert-unsafe-trait-obj.rs
@@ -0,0 +1,18 @@
+// Check that we do not allow casts or coercions
+// to object unsafe trait objects by ref
+
+#![feature(object_safe_for_dispatch)]
+
+trait Trait: Sized {}
+
+struct S;
+
+impl Trait for S {}
+
+fn takes_trait(t: &dyn Trait) {}
+
+fn main() {
+    &S as &dyn Trait; //~ ERROR E0038
+    let t: &dyn Trait = &S; //~ ERROR E0038
+    takes_trait(&S); //~ ERROR E0038
+}
diff --git a/src/test/ui/wf/wf-convert-unsafe-trait-obj.stderr b/src/test/ui/wf/wf-convert-unsafe-trait-obj.stderr
new file mode 100644
index 00000000000..7aeefd731fb
--- /dev/null
+++ b/src/test/ui/wf/wf-convert-unsafe-trait-obj.stderr
@@ -0,0 +1,33 @@
+error[E0038]: the trait `Trait` cannot be made into an object
+  --> $DIR/wf-convert-unsafe-trait-obj.rs:16:25
+   |
+LL |     let t: &dyn Trait = &S;
+   |                         ^^ the trait `Trait` cannot be made into an object
+   |
+   = note: the trait cannot require that `Self : Sized`
+   = note: required because of the requirements on the impl of `std::ops::CoerceUnsized<&dyn Trait>` for `&S`
+   = note: required by cast to type `&dyn Trait`
+
+error[E0038]: the trait `Trait` cannot be made into an object
+  --> $DIR/wf-convert-unsafe-trait-obj.rs:17:17
+   |
+LL |     takes_trait(&S);
+   |                 ^^ the trait `Trait` cannot be made into an object
+   |
+   = note: the trait cannot require that `Self : Sized`
+   = note: required because of the requirements on the impl of `std::ops::CoerceUnsized<&dyn Trait>` for `&S`
+   = note: required by cast to type `&dyn Trait`
+
+error[E0038]: the trait `Trait` cannot be made into an object
+  --> $DIR/wf-convert-unsafe-trait-obj.rs:15:5
+   |
+LL |     &S as &dyn Trait;
+   |     ^^ the trait `Trait` cannot be made into an object
+   |
+   = note: the trait cannot require that `Self : Sized`
+   = note: required because of the requirements on the impl of `std::ops::CoerceUnsized<&dyn Trait>` for `&S`
+   = note: required by cast to type `&dyn Trait`
+
+error: aborting due to 3 previous errors
+
+For more information about this error, try `rustc --explain E0038`.
diff --git a/src/test/ui/wf/wf-unsafe-trait-obj-match.rs b/src/test/ui/wf/wf-unsafe-trait-obj-match.rs
new file mode 100644
index 00000000000..c8731a8ecaf
--- /dev/null
+++ b/src/test/ui/wf/wf-unsafe-trait-obj-match.rs
@@ -0,0 +1,29 @@
+// Check that we do not allow coercions to object
+// unsafe trait objects in match arms
+
+#![feature(object_safe_for_dispatch)]
+
+trait Trait: Sized {}
+
+struct S;
+
+impl Trait for S {}
+
+struct R;
+
+impl Trait for R {}
+
+fn opt() -> Option<()> {
+    Some(())
+}
+
+fn main() {
+    match opt() {
+        Some(()) => &S,
+        None => &R,  //~ ERROR E0308
+    }
+    let t: &dyn Trait = match opt() { //~ ERROR E0038
+        Some(()) => &S, //~ ERROR E0038
+        None => &R,
+    };
+}
diff --git a/src/test/ui/wf/wf-unsafe-trait-obj-match.stderr b/src/test/ui/wf/wf-unsafe-trait-obj-match.stderr
new file mode 100644
index 00000000000..185b1e6c36b
--- /dev/null
+++ b/src/test/ui/wf/wf-unsafe-trait-obj-match.stderr
@@ -0,0 +1,38 @@
+error[E0308]: match arms have incompatible types
+  --> $DIR/wf-unsafe-trait-obj-match.rs:23:17
+   |
+LL | /     match opt() {
+LL | |         Some(()) => &S,
+   | |                     -- this is found to be of type `&S`
+LL | |         None => &R,
+   | |                 ^^ expected struct `S`, found struct `R`
+LL | |     }
+   | |_____- `match` arms have incompatible types
+   |
+   = note: expected type `&S`
+              found type `&R`
+
+error[E0038]: the trait `Trait` cannot be made into an object
+  --> $DIR/wf-unsafe-trait-obj-match.rs:26:21
+   |
+LL |         Some(()) => &S,
+   |                     ^^ the trait `Trait` cannot be made into an object
+   |
+   = note: the trait cannot require that `Self : Sized`
+   = note: required because of the requirements on the impl of `std::ops::CoerceUnsized<&dyn Trait>` for `&S`
+   = note: required by cast to type `&dyn Trait`
+
+error[E0038]: the trait `Trait` cannot be made into an object
+  --> $DIR/wf-unsafe-trait-obj-match.rs:25:25
+   |
+LL |     let t: &dyn Trait = match opt() {
+   |                         ^^^^^^^^^^^ the trait `Trait` cannot be made into an object
+   |
+   = note: the trait cannot require that `Self : Sized`
+   = note: required because of the requirements on the impl of `std::ops::CoerceUnsized<&dyn Trait>` for `&R`
+   = note: required by cast to type `&dyn Trait`
+
+error: aborting due to 3 previous errors
+
+Some errors have detailed explanations: E0038, E0308.
+For more information about an error, try `rustc --explain E0038`.