RFC 2027: "first draft" of implementation

These are a squashed series of commits.
This commit is contained in:
Mathias Blikstad 2019-01-08 22:14:04 +01:00 committed by Niko Matsakis
parent d28a9c38fe
commit ef5acdeceb
59 changed files with 847 additions and 105 deletions

View file

@ -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() {}

View file

@ -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`.

View file

@ -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`.

View file

@ -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() {}

View file

@ -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`.

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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`.

View file

@ -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() { }

View file

@ -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`

View file

@ -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`.

View file

@ -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() {

View file

@ -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

View file

@ -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`.

View file

@ -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 {

View file

@ -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

View file

@ -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`.

View file

@ -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() {}

View file

@ -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`.

View file

@ -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`.

View file

@ -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
}

View file

@ -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

View file

@ -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`.

View file

@ -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() {

View file

@ -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

View file

@ -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`.

View file

@ -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() {

View file

@ -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() {}

View file

@ -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!();
}
}

View file

@ -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>()
}

View file

@ -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`.

View file

@ -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`.

View file

@ -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() {

View file

@ -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

View file

@ -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

View file

@ -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
}

View file

@ -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`.

View file

@ -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
}

View file

@ -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`.

View file

@ -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,
};
}

View file

@ -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`.