RFC 2027: "first draft" of implementation
These are a squashed series of commits.
This commit is contained in:
parent
d28a9c38fe
commit
ef5acdeceb
59 changed files with 847 additions and 105 deletions
18
src/test/ui/coherence/coherence-unsafe-trait-object-impl.rs
Normal file
18
src/test/ui/coherence/coherence-unsafe-trait-object-impl.rs
Normal 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() {}
|
||||
|
|
@ -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`.
|
||||
|
|
@ -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`.
|
||||
|
|
@ -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() {}
|
||||
|
|
@ -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`.
|
||||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
@ -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`.
|
||||
|
|
@ -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() { }
|
||||
|
|
|
|||
|
|
@ -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`
|
||||
|
|
@ -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`.
|
||||
|
|
@ -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() {
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
@ -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`.
|
||||
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
@ -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`.
|
||||
|
|
@ -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() {}
|
||||
|
|
|
|||
|
|
@ -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`.
|
||||
|
|
@ -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`.
|
||||
|
|
@ -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
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
@ -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`.
|
||||
|
|
@ -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() {
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
@ -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`.
|
||||
|
|
@ -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() {
|
||||
|
|
|
|||
|
|
@ -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() {}
|
||||
|
|
@ -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!();
|
||||
}
|
||||
}
|
||||
|
|
@ -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>()
|
||||
}
|
||||
|
|
@ -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`.
|
||||
|
|
@ -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`.
|
||||
|
|
@ -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() {
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
18
src/test/ui/wf/wf-convert-unsafe-trait-obj-box.rs
Normal file
18
src/test/ui/wf/wf-convert-unsafe-trait-obj-box.rs
Normal 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
|
||||
}
|
||||
33
src/test/ui/wf/wf-convert-unsafe-trait-obj-box.stderr
Normal file
33
src/test/ui/wf/wf-convert-unsafe-trait-obj-box.stderr
Normal 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`.
|
||||
18
src/test/ui/wf/wf-convert-unsafe-trait-obj.rs
Normal file
18
src/test/ui/wf/wf-convert-unsafe-trait-obj.rs
Normal 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
|
||||
}
|
||||
33
src/test/ui/wf/wf-convert-unsafe-trait-obj.stderr
Normal file
33
src/test/ui/wf/wf-convert-unsafe-trait-obj.stderr
Normal 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`.
|
||||
29
src/test/ui/wf/wf-unsafe-trait-obj-match.rs
Normal file
29
src/test/ui/wf/wf-unsafe-trait-obj-match.rs
Normal 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,
|
||||
};
|
||||
}
|
||||
38
src/test/ui/wf/wf-unsafe-trait-obj-match.stderr
Normal file
38
src/test/ui/wf/wf-unsafe-trait-obj-match.stderr
Normal 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`.
|
||||
Loading…
Add table
Add a link
Reference in a new issue