From 698f8c2f01ea549d77d7dc3338a12e04c11057b9 Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Wed, 17 Apr 2024 14:02:58 +0200 Subject: Adding upstream version 1.64.0+dfsg1. Signed-off-by: Daniel Baumann --- src/test/ui/object-safety/issue-19538.rs | 20 ++++++++++ src/test/ui/object-safety/issue-19538.stderr | 37 +++++++++++++++++ .../object-safety-associated-consts.curr.stderr | 18 +++++++++ ...sociated-consts.object_safe_for_dispatch.stderr | 20 ++++++++++ .../object-safety-associated-consts.rs | 19 +++++++++ src/test/ui/object-safety/object-safety-bounds.rs | 12 ++++++ .../ui/object-safety/object-safety-bounds.stderr | 17 ++++++++ .../object-safety-by-value-self-use.rs | 18 +++++++++ .../object-safety-by-value-self-use.stderr | 9 +++++ .../object-safety/object-safety-by-value-self.rs | 46 ++++++++++++++++++++++ .../object-safety-generics.curr.stderr | 33 ++++++++++++++++ ...safety-generics.object_safe_for_dispatch.stderr | 37 +++++++++++++++++ .../ui/object-safety/object-safety-generics.rs | 39 ++++++++++++++++++ .../ui/object-safety/object-safety-issue-22040.rs | 42 ++++++++++++++++++++ .../object-safety/object-safety-issue-22040.stderr | 17 ++++++++ .../object-safety-mentions-Self.curr.stderr | 33 ++++++++++++++++ ...y-mentions-Self.object_safe_for_dispatch.stderr | 37 +++++++++++++++++ .../object-safety/object-safety-mentions-Self.rs | 42 ++++++++++++++++++++ .../object-safety-no-static.curr.stderr | 25 ++++++++++++ ...afety-no-static.object_safe_for_dispatch.stderr | 27 +++++++++++++ .../ui/object-safety/object-safety-no-static.rs | 24 +++++++++++ .../ui/object-safety/object-safety-phantom-fn.rs | 22 +++++++++++ .../object-safety-sized-2.curr.stderr | 17 ++++++++ ...-safety-sized-2.object_safe_for_dispatch.stderr | 19 +++++++++ src/test/ui/object-safety/object-safety-sized-2.rs | 21 ++++++++++ .../object-safety/object-safety-sized.curr.stderr | 17 ++++++++ ...ct-safety-sized.object_safe_for_dispatch.stderr | 19 +++++++++ src/test/ui/object-safety/object-safety-sized.rs | 19 +++++++++ .../object-safety-supertrait-mentions-Self.rs | 21 ++++++++++ .../object-safety-supertrait-mentions-Self.stderr | 17 ++++++++ 30 files changed, 744 insertions(+) create mode 100644 src/test/ui/object-safety/issue-19538.rs create mode 100644 src/test/ui/object-safety/issue-19538.stderr create mode 100644 src/test/ui/object-safety/object-safety-associated-consts.curr.stderr create mode 100644 src/test/ui/object-safety/object-safety-associated-consts.object_safe_for_dispatch.stderr create mode 100644 src/test/ui/object-safety/object-safety-associated-consts.rs create mode 100644 src/test/ui/object-safety/object-safety-bounds.rs create mode 100644 src/test/ui/object-safety/object-safety-bounds.stderr create mode 100644 src/test/ui/object-safety/object-safety-by-value-self-use.rs create mode 100644 src/test/ui/object-safety/object-safety-by-value-self-use.stderr create mode 100644 src/test/ui/object-safety/object-safety-by-value-self.rs create mode 100644 src/test/ui/object-safety/object-safety-generics.curr.stderr create mode 100644 src/test/ui/object-safety/object-safety-generics.object_safe_for_dispatch.stderr create mode 100644 src/test/ui/object-safety/object-safety-generics.rs create mode 100644 src/test/ui/object-safety/object-safety-issue-22040.rs create mode 100644 src/test/ui/object-safety/object-safety-issue-22040.stderr create mode 100644 src/test/ui/object-safety/object-safety-mentions-Self.curr.stderr create mode 100644 src/test/ui/object-safety/object-safety-mentions-Self.object_safe_for_dispatch.stderr create mode 100644 src/test/ui/object-safety/object-safety-mentions-Self.rs create mode 100644 src/test/ui/object-safety/object-safety-no-static.curr.stderr create mode 100644 src/test/ui/object-safety/object-safety-no-static.object_safe_for_dispatch.stderr create mode 100644 src/test/ui/object-safety/object-safety-no-static.rs create mode 100644 src/test/ui/object-safety/object-safety-phantom-fn.rs create mode 100644 src/test/ui/object-safety/object-safety-sized-2.curr.stderr create mode 100644 src/test/ui/object-safety/object-safety-sized-2.object_safe_for_dispatch.stderr create mode 100644 src/test/ui/object-safety/object-safety-sized-2.rs create mode 100644 src/test/ui/object-safety/object-safety-sized.curr.stderr create mode 100644 src/test/ui/object-safety/object-safety-sized.object_safe_for_dispatch.stderr create mode 100644 src/test/ui/object-safety/object-safety-sized.rs create mode 100644 src/test/ui/object-safety/object-safety-supertrait-mentions-Self.rs create mode 100644 src/test/ui/object-safety/object-safety-supertrait-mentions-Self.stderr (limited to 'src/test/ui/object-safety') diff --git a/src/test/ui/object-safety/issue-19538.rs b/src/test/ui/object-safety/issue-19538.rs new file mode 100644 index 000000000..7054ef41b --- /dev/null +++ b/src/test/ui/object-safety/issue-19538.rs @@ -0,0 +1,20 @@ +trait Foo { + fn foo(&self, val: T); +} + +trait Bar: Foo { } + +pub struct Thing; + +impl Foo for Thing { + fn foo(&self, val: T) { } +} + +impl Bar for Thing { } + +fn main() { + let mut thing = Thing; + let test: &mut dyn Bar = &mut thing; + //~^ ERROR E0038 + //~| ERROR E0038 +} diff --git a/src/test/ui/object-safety/issue-19538.stderr b/src/test/ui/object-safety/issue-19538.stderr new file mode 100644 index 000000000..7b37e1f95 --- /dev/null +++ b/src/test/ui/object-safety/issue-19538.stderr @@ -0,0 +1,37 @@ +error[E0038]: the trait `Bar` cannot be made into an object + --> $DIR/issue-19538.rs:17:15 + | +LL | let test: &mut dyn Bar = &mut thing; + | ^^^^^^^^^^^^ `Bar` cannot be made into an object + | +note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit + --> $DIR/issue-19538.rs:2:8 + | +LL | fn foo(&self, val: T); + | ^^^ ...because method `foo` has generic type parameters +... +LL | trait Bar: Foo { } + | --- this trait cannot be made into an object... + = help: consider moving `foo` to another trait + +error[E0038]: the trait `Bar` cannot be made into an object + --> $DIR/issue-19538.rs:17:30 + | +LL | let test: &mut dyn Bar = &mut thing; + | ^^^^^^^^^^ `Bar` cannot be made into an object + | +note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit + --> $DIR/issue-19538.rs:2:8 + | +LL | fn foo(&self, val: T); + | ^^^ ...because method `foo` has generic type parameters +... +LL | trait Bar: Foo { } + | --- this trait cannot be made into an object... + = help: consider moving `foo` to another trait + = note: required because of the requirements on the impl of `CoerceUnsized<&mut dyn Bar>` for `&mut Thing` + = note: required by cast to type `&mut dyn Bar` + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0038`. diff --git a/src/test/ui/object-safety/object-safety-associated-consts.curr.stderr b/src/test/ui/object-safety/object-safety-associated-consts.curr.stderr new file mode 100644 index 000000000..9dd144fee --- /dev/null +++ b/src/test/ui/object-safety/object-safety-associated-consts.curr.stderr @@ -0,0 +1,18 @@ +error[E0038]: the trait `Bar` cannot be made into an object + --> $DIR/object-safety-associated-consts.rs:12:30 + | +LL | fn make_bar(t: &T) -> &dyn Bar { + | ^^^^^^^^ `Bar` cannot be made into an object + | +note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit + --> $DIR/object-safety-associated-consts.rs:9:11 + | +LL | trait Bar { + | --- this trait cannot be made into an object... +LL | const X: usize; + | ^ ...because it contains this associated `const` + = help: consider moving `X` to another trait + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0038`. diff --git a/src/test/ui/object-safety/object-safety-associated-consts.object_safe_for_dispatch.stderr b/src/test/ui/object-safety/object-safety-associated-consts.object_safe_for_dispatch.stderr new file mode 100644 index 000000000..9ba3b251e --- /dev/null +++ b/src/test/ui/object-safety/object-safety-associated-consts.object_safe_for_dispatch.stderr @@ -0,0 +1,20 @@ +error[E0038]: the trait `Bar` cannot be made into an object + --> $DIR/object-safety-associated-consts.rs:14:5 + | +LL | t + | ^ `Bar` cannot be made into an object + | +note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit + --> $DIR/object-safety-associated-consts.rs:9:11 + | +LL | trait Bar { + | --- this trait cannot be made into an object... +LL | const X: usize; + | ^ ...because it contains this associated `const` + = help: consider moving `X` to another trait + = note: required because of the requirements on the impl of `CoerceUnsized<&dyn Bar>` for `&T` + = note: required by cast to type `&dyn Bar` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0038`. diff --git a/src/test/ui/object-safety/object-safety-associated-consts.rs b/src/test/ui/object-safety/object-safety-associated-consts.rs new file mode 100644 index 000000000..e1a772e5a --- /dev/null +++ b/src/test/ui/object-safety/object-safety-associated-consts.rs @@ -0,0 +1,19 @@ +// Check that we correctly prevent users from making trait objects +// from traits with associated consts. +// +// revisions: curr object_safe_for_dispatch + +#![cfg_attr(object_safe_for_dispatch, feature(object_safe_for_dispatch))] + +trait Bar { + const X: usize; +} + +fn make_bar(t: &T) -> &dyn Bar { + //[curr]~^ ERROR E0038 + t + //[object_safe_for_dispatch]~^ ERROR E0038 +} + +fn main() { +} diff --git a/src/test/ui/object-safety/object-safety-bounds.rs b/src/test/ui/object-safety/object-safety-bounds.rs new file mode 100644 index 000000000..44bd36932 --- /dev/null +++ b/src/test/ui/object-safety/object-safety-bounds.rs @@ -0,0 +1,12 @@ +// Traits with bounds mentioning `Self` are not object safe + +trait X { + type U: PartialEq; +} + +fn f() -> Box> { + //~^ ERROR the trait `X` cannot be made into an object + loop {} +} + +fn main() {} diff --git a/src/test/ui/object-safety/object-safety-bounds.stderr b/src/test/ui/object-safety/object-safety-bounds.stderr new file mode 100644 index 000000000..89c4f8ced --- /dev/null +++ b/src/test/ui/object-safety/object-safety-bounds.stderr @@ -0,0 +1,17 @@ +error[E0038]: the trait `X` cannot be made into an object + --> $DIR/object-safety-bounds.rs:7:11 + | +LL | fn f() -> Box> { + | ^^^^^^^^^^^^^^^^^^^ `X` cannot be made into an object + | +note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit + --> $DIR/object-safety-bounds.rs:4:13 + | +LL | trait X { + | - this trait cannot be made into an object... +LL | type U: PartialEq; + | ^^^^^^^^^^^^^^^ ...because it uses `Self` as a type parameter + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0038`. diff --git a/src/test/ui/object-safety/object-safety-by-value-self-use.rs b/src/test/ui/object-safety/object-safety-by-value-self-use.rs new file mode 100644 index 000000000..8e93c5382 --- /dev/null +++ b/src/test/ui/object-safety/object-safety-by-value-self-use.rs @@ -0,0 +1,18 @@ +// Check that while a trait with by-value self is object-safe, we +// can't actually invoke it from an object (yet...?). + +#![feature(rustc_attrs)] + +trait Bar { + fn bar(self); +} + +trait Baz { + fn baz(self: Self); +} + +fn use_bar(t: Box) { + t.bar() //~ ERROR cannot move a value of type `dyn Bar` +} + +fn main() { } diff --git a/src/test/ui/object-safety/object-safety-by-value-self-use.stderr b/src/test/ui/object-safety/object-safety-by-value-self-use.stderr new file mode 100644 index 000000000..94fdcdf26 --- /dev/null +++ b/src/test/ui/object-safety/object-safety-by-value-self-use.stderr @@ -0,0 +1,9 @@ +error[E0161]: cannot move a value of type `dyn Bar` + --> $DIR/object-safety-by-value-self-use.rs:15:5 + | +LL | t.bar() + | ^^^^^^^ the size of `dyn Bar` cannot be statically determined + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0161`. diff --git a/src/test/ui/object-safety/object-safety-by-value-self.rs b/src/test/ui/object-safety/object-safety-by-value-self.rs new file mode 100644 index 000000000..c74a4d1cb --- /dev/null +++ b/src/test/ui/object-safety/object-safety-by-value-self.rs @@ -0,0 +1,46 @@ +// Check that a trait with by-value self is considered object-safe. + +// build-pass (FIXME(62277): could be check-pass?) +#![allow(dead_code)] +#![allow(trivial_casts)] + +trait Bar { + fn bar(self); +} + +trait Baz { + fn baz(self: Self); +} + +trait Quux { + // Legal because of the where clause: + fn baz(self: Self) where Self : Sized; +} + +fn make_bar(t: &T) -> &dyn Bar { + t // legal +} + +fn make_bar_explicit(t: &T) -> &dyn Bar { + t as &dyn Bar // legal +} + +fn make_baz(t: &T) -> &dyn Baz { + t // legal +} + +fn make_baz_explicit(t: &T) -> &dyn Baz { + t as &dyn Baz // legal +} + +fn make_quux(t: &T) -> &dyn Quux { + t +} + +fn make_quux_explicit(t: &T) -> &dyn Quux { + t as &dyn Quux +} + + +fn main() { +} diff --git a/src/test/ui/object-safety/object-safety-generics.curr.stderr b/src/test/ui/object-safety/object-safety-generics.curr.stderr new file mode 100644 index 000000000..345950f1a --- /dev/null +++ b/src/test/ui/object-safety/object-safety-generics.curr.stderr @@ -0,0 +1,33 @@ +error[E0038]: the trait `Bar` cannot be made into an object + --> $DIR/object-safety-generics.rs:18:30 + | +LL | fn make_bar(t: &T) -> &dyn Bar { + | ^^^^^^^^ `Bar` cannot be made into an object + | +note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit + --> $DIR/object-safety-generics.rs:10:8 + | +LL | trait Bar { + | --- this trait cannot be made into an object... +LL | fn bar(&self, t: T); + | ^^^ ...because method `bar` has generic type parameters + = help: consider moving `bar` to another trait + +error[E0038]: the trait `Bar` cannot be made into an object + --> $DIR/object-safety-generics.rs:24:39 + | +LL | fn make_bar_explicit(t: &T) -> &dyn Bar { + | ^^^^^^^^ `Bar` cannot be made into an object + | +note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit + --> $DIR/object-safety-generics.rs:10:8 + | +LL | trait Bar { + | --- this trait cannot be made into an object... +LL | fn bar(&self, t: T); + | ^^^ ...because method `bar` has generic type parameters + = help: consider moving `bar` to another trait + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0038`. diff --git a/src/test/ui/object-safety/object-safety-generics.object_safe_for_dispatch.stderr b/src/test/ui/object-safety/object-safety-generics.object_safe_for_dispatch.stderr new file mode 100644 index 000000000..86355627c --- /dev/null +++ b/src/test/ui/object-safety/object-safety-generics.object_safe_for_dispatch.stderr @@ -0,0 +1,37 @@ +error[E0038]: the trait `Bar` cannot be made into an object + --> $DIR/object-safety-generics.rs:20:5 + | +LL | t + | ^ `Bar` cannot be made into an object + | +note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit + --> $DIR/object-safety-generics.rs:10:8 + | +LL | trait Bar { + | --- this trait cannot be made into an object... +LL | fn bar(&self, t: T); + | ^^^ ...because method `bar` has generic type parameters + = help: consider moving `bar` to another trait + = note: required because of the requirements on the impl of `CoerceUnsized<&dyn Bar>` for `&T` + = note: required by cast to type `&dyn Bar` + +error[E0038]: the trait `Bar` cannot be made into an object + --> $DIR/object-safety-generics.rs:26:5 + | +LL | t as &dyn Bar + | ^ `Bar` cannot be made into an object + | +note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit + --> $DIR/object-safety-generics.rs:10:8 + | +LL | trait Bar { + | --- this trait cannot be made into an object... +LL | fn bar(&self, t: T); + | ^^^ ...because method `bar` has generic type parameters + = help: consider moving `bar` to another trait + = note: required because of the requirements on the impl of `CoerceUnsized<&dyn Bar>` for `&T` + = note: required by cast to type `&dyn Bar` + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0038`. diff --git a/src/test/ui/object-safety/object-safety-generics.rs b/src/test/ui/object-safety/object-safety-generics.rs new file mode 100644 index 000000000..63dcd1699 --- /dev/null +++ b/src/test/ui/object-safety/object-safety-generics.rs @@ -0,0 +1,39 @@ +// Check that we correctly prevent users from making trait objects +// from traits with generic methods, unless `where Self : Sized` is +// present. +// revisions: curr object_safe_for_dispatch + +#![cfg_attr(object_safe_for_dispatch, feature(object_safe_for_dispatch))] + + +trait Bar { + fn bar(&self, t: T); +} + +trait Quux { + fn bar(&self, t: T) + where Self : Sized; +} + +fn make_bar(t: &T) -> &dyn Bar { + //[curr]~^ ERROR E0038 + t + //[object_safe_for_dispatch]~^ ERROR E0038 +} + +fn make_bar_explicit(t: &T) -> &dyn Bar { + //[curr]~^ ERROR E0038 + t as &dyn Bar + //[object_safe_for_dispatch]~^ ERROR E0038 +} + +fn make_quux(t: &T) -> &dyn Quux { + t +} + +fn make_quux_explicit(t: &T) -> &dyn Quux { + t as &dyn Quux +} + +fn main() { +} diff --git a/src/test/ui/object-safety/object-safety-issue-22040.rs b/src/test/ui/object-safety/object-safety-issue-22040.rs new file mode 100644 index 000000000..1fc5c5442 --- /dev/null +++ b/src/test/ui/object-safety/object-safety-issue-22040.rs @@ -0,0 +1,42 @@ +// Regression test for #22040. + +use std::fmt::Debug; + +trait Expr: Debug + PartialEq { + fn print_element_count(&self); +} + +//#[derive(PartialEq)] +#[derive(Debug)] +struct SExpr<'x> { + elements: Vec>, + //~^ ERROR E0038 +} + +impl<'x> PartialEq for SExpr<'x> { + fn eq(&self, other:&SExpr<'x>) -> bool { + println!("L1: {} L2: {}", self.elements.len(), other.elements.len()); + + let result = self.elements.len() == other.elements.len(); + + println!("Got compare {}", result); + return result; + } +} + +impl <'x> SExpr<'x> { + fn new() -> SExpr<'x> { return SExpr{elements: Vec::new(),}; } +} + +impl <'x> Expr for SExpr<'x> { + fn print_element_count(&self) { + println!("element count: {}", self.elements.len()); + } +} + +fn main() { + let a: Box = Box::new(SExpr::new()); + let b: Box = Box::new(SExpr::new()); + + // assert_eq!(a , b); +} diff --git a/src/test/ui/object-safety/object-safety-issue-22040.stderr b/src/test/ui/object-safety/object-safety-issue-22040.stderr new file mode 100644 index 000000000..0262d5362 --- /dev/null +++ b/src/test/ui/object-safety/object-safety-issue-22040.stderr @@ -0,0 +1,17 @@ +error[E0038]: the trait `Expr` cannot be made into an object + --> $DIR/object-safety-issue-22040.rs:12:23 + | +LL | elements: Vec>, + | ^^^^^^^^^^^^^ `Expr` cannot be made into an object + | +note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit + --> $DIR/object-safety-issue-22040.rs:5:21 + | +LL | trait Expr: Debug + PartialEq { + | ---- ^^^^^^^^^ ...because it uses `Self` as a type parameter + | | + | this trait cannot be made into an object... + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0038`. diff --git a/src/test/ui/object-safety/object-safety-mentions-Self.curr.stderr b/src/test/ui/object-safety/object-safety-mentions-Self.curr.stderr new file mode 100644 index 000000000..f91c9b985 --- /dev/null +++ b/src/test/ui/object-safety/object-safety-mentions-Self.curr.stderr @@ -0,0 +1,33 @@ +error[E0038]: the trait `Bar` cannot be made into an object + --> $DIR/object-safety-mentions-Self.rs:22:30 + | +LL | fn make_bar(t: &T) -> &dyn Bar { + | ^^^^^^^^ `Bar` cannot be made into an object + | +note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit + --> $DIR/object-safety-mentions-Self.rs:11:22 + | +LL | trait Bar { + | --- this trait cannot be made into an object... +LL | fn bar(&self, x: &Self); + | ^^^^^ ...because method `bar` references the `Self` type in this parameter + = help: consider moving `bar` to another trait + +error[E0038]: the trait `Baz` cannot be made into an object + --> $DIR/object-safety-mentions-Self.rs:28:30 + | +LL | fn make_baz(t: &T) -> &dyn Baz { + | ^^^^^^^^ `Baz` cannot be made into an object + | +note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit + --> $DIR/object-safety-mentions-Self.rs:15:22 + | +LL | trait Baz { + | --- this trait cannot be made into an object... +LL | fn baz(&self) -> Self; + | ^^^^ ...because method `baz` references the `Self` type in its return type + = help: consider moving `baz` to another trait + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0038`. diff --git a/src/test/ui/object-safety/object-safety-mentions-Self.object_safe_for_dispatch.stderr b/src/test/ui/object-safety/object-safety-mentions-Self.object_safe_for_dispatch.stderr new file mode 100644 index 000000000..f48628c9d --- /dev/null +++ b/src/test/ui/object-safety/object-safety-mentions-Self.object_safe_for_dispatch.stderr @@ -0,0 +1,37 @@ +error[E0038]: the trait `Bar` cannot be made into an object + --> $DIR/object-safety-mentions-Self.rs:24:5 + | +LL | t + | ^ `Bar` cannot be made into an object + | +note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit + --> $DIR/object-safety-mentions-Self.rs:11:22 + | +LL | trait Bar { + | --- this trait cannot be made into an object... +LL | fn bar(&self, x: &Self); + | ^^^^^ ...because method `bar` references the `Self` type in this parameter + = help: consider moving `bar` to another trait + = note: required because of the requirements on the impl of `CoerceUnsized<&dyn Bar>` for `&T` + = note: required by cast to type `&dyn Bar` + +error[E0038]: the trait `Baz` cannot be made into an object + --> $DIR/object-safety-mentions-Self.rs:30:5 + | +LL | t + | ^ `Baz` cannot be made into an object + | +note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit + --> $DIR/object-safety-mentions-Self.rs:15:22 + | +LL | trait Baz { + | --- this trait cannot be made into an object... +LL | fn baz(&self) -> Self; + | ^^^^ ...because method `baz` references the `Self` type in its return type + = help: consider moving `baz` to another trait + = note: required because of the requirements on the impl of `CoerceUnsized<&dyn Baz>` for `&T` + = note: required by cast to type `&dyn Baz` + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0038`. diff --git a/src/test/ui/object-safety/object-safety-mentions-Self.rs b/src/test/ui/object-safety/object-safety-mentions-Self.rs new file mode 100644 index 000000000..412d16ff3 --- /dev/null +++ b/src/test/ui/object-safety/object-safety-mentions-Self.rs @@ -0,0 +1,42 @@ +// Check that we correctly prevent users from making trait objects +// form traits that make use of `Self` in an argument or return +// position, unless `where Self : Sized` is present.. +// +// revisions: curr object_safe_for_dispatch + +#![cfg_attr(object_safe_for_dispatch, feature(object_safe_for_dispatch))] + + +trait Bar { + fn bar(&self, x: &Self); +} + +trait Baz { + fn baz(&self) -> Self; +} + +trait Quux { + fn quux(&self, s: &Self) -> Self where Self : Sized; +} + +fn make_bar(t: &T) -> &dyn Bar { + //[curr]~^ ERROR E0038 + t + //[object_safe_for_dispatch]~^ ERROR E0038 +} + +fn make_baz(t: &T) -> &dyn Baz { + //[curr]~^ ERROR E0038 + t + //[object_safe_for_dispatch]~^ ERROR E0038 +} + +fn make_quux(t: &T) -> &dyn Quux { + t +} + +fn make_quux_explicit(t: &T) -> &dyn Quux { + t as &dyn Quux +} + +fn main() {} diff --git a/src/test/ui/object-safety/object-safety-no-static.curr.stderr b/src/test/ui/object-safety/object-safety-no-static.curr.stderr new file mode 100644 index 000000000..bd8cf4e30 --- /dev/null +++ b/src/test/ui/object-safety/object-safety-no-static.curr.stderr @@ -0,0 +1,25 @@ +error[E0038]: the trait `Foo` cannot be made into an object + --> $DIR/object-safety-no-static.rs:12:18 + | +LL | fn diverges() -> Box { + | ^^^^^^^^^^^^ `Foo` cannot be made into an object + | +note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit + --> $DIR/object-safety-no-static.rs:9:8 + | +LL | trait Foo { + | --- this trait cannot be made into an object... +LL | fn foo() {} + | ^^^ ...because associated function `foo` has no `self` parameter +help: consider turning `foo` into a method by giving it a `&self` argument + | +LL | fn foo(&self) {} + | +++++ +help: alternatively, consider constraining `foo` so it does not apply to trait objects + | +LL | fn foo() where Self: Sized {} + | +++++++++++++++++ + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0038`. diff --git a/src/test/ui/object-safety/object-safety-no-static.object_safe_for_dispatch.stderr b/src/test/ui/object-safety/object-safety-no-static.object_safe_for_dispatch.stderr new file mode 100644 index 000000000..ea1c575ff --- /dev/null +++ b/src/test/ui/object-safety/object-safety-no-static.object_safe_for_dispatch.stderr @@ -0,0 +1,27 @@ +error[E0038]: the trait `Foo` cannot be made into an object + --> $DIR/object-safety-no-static.rs:22:27 + | +LL | let b: Box = Box::new(Bar); + | ^^^^^^^^^^^^^ `Foo` cannot be made into an object + | +note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit + --> $DIR/object-safety-no-static.rs:9:8 + | +LL | trait Foo { + | --- this trait cannot be made into an object... +LL | fn foo() {} + | ^^^ ...because associated function `foo` has no `self` parameter + = note: required because of the requirements on the impl of `CoerceUnsized>` for `Box` + = note: required by cast to type `Box` +help: consider turning `foo` into a method by giving it a `&self` argument + | +LL | fn foo(&self) {} + | +++++ +help: alternatively, consider constraining `foo` so it does not apply to trait objects + | +LL | fn foo() where Self: Sized {} + | +++++++++++++++++ + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0038`. diff --git a/src/test/ui/object-safety/object-safety-no-static.rs b/src/test/ui/object-safety/object-safety-no-static.rs new file mode 100644 index 000000000..03b622174 --- /dev/null +++ b/src/test/ui/object-safety/object-safety-no-static.rs @@ -0,0 +1,24 @@ +// Check that we correctly prevent users from making trait objects +// from traits with static methods. +// +// revisions: curr object_safe_for_dispatch + +#![cfg_attr(object_safe_for_dispatch, feature(object_safe_for_dispatch))] + +trait Foo { + fn foo() {} +} + +fn diverges() -> Box { + //[curr]~^ ERROR E0038 + loop { } +} + +struct Bar; + +impl Foo for Bar {} + +fn main() { + let b: Box = Box::new(Bar); + //[object_safe_for_dispatch]~^ ERROR E0038 +} diff --git a/src/test/ui/object-safety/object-safety-phantom-fn.rs b/src/test/ui/object-safety/object-safety-phantom-fn.rs new file mode 100644 index 000000000..3ffeb81c1 --- /dev/null +++ b/src/test/ui/object-safety/object-safety-phantom-fn.rs @@ -0,0 +1,22 @@ +// Check that `Self` appearing in a phantom fn does not make a trait not object safe. + +// build-pass (FIXME(62277): could be check-pass?) +#![allow(dead_code)] + +trait Baz { +} + +trait Bar { +} + +fn make_bar>(t: &T) -> &dyn Bar { + t +} + +fn make_baz(t: &T) -> &dyn Baz { + t +} + + +fn main() { +} diff --git a/src/test/ui/object-safety/object-safety-sized-2.curr.stderr b/src/test/ui/object-safety/object-safety-sized-2.curr.stderr new file mode 100644 index 000000000..71236c8e3 --- /dev/null +++ b/src/test/ui/object-safety/object-safety-sized-2.curr.stderr @@ -0,0 +1,17 @@ +error[E0038]: the trait `Bar` cannot be made into an object + --> $DIR/object-safety-sized-2.rs:14:30 + | +LL | fn make_bar(t: &T) -> &dyn Bar { + | ^^^^^^^^ `Bar` cannot be made into an object + | +note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit + --> $DIR/object-safety-sized-2.rs:9:18 + | +LL | trait Bar + | --- this trait cannot be made into an object... +LL | where Self : Sized + | ^^^^^ ...because it requires `Self: Sized` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0038`. diff --git a/src/test/ui/object-safety/object-safety-sized-2.object_safe_for_dispatch.stderr b/src/test/ui/object-safety/object-safety-sized-2.object_safe_for_dispatch.stderr new file mode 100644 index 000000000..b6e4903b0 --- /dev/null +++ b/src/test/ui/object-safety/object-safety-sized-2.object_safe_for_dispatch.stderr @@ -0,0 +1,19 @@ +error[E0038]: the trait `Bar` cannot be made into an object + --> $DIR/object-safety-sized-2.rs:16:5 + | +LL | t + | ^ `Bar` cannot be made into an object + | +note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit + --> $DIR/object-safety-sized-2.rs:9:18 + | +LL | trait Bar + | --- this trait cannot be made into an object... +LL | where Self : Sized + | ^^^^^ ...because it requires `Self: Sized` + = note: required because of the requirements on the impl of `CoerceUnsized<&dyn Bar>` for `&T` + = note: required by cast to type `&dyn Bar` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0038`. diff --git a/src/test/ui/object-safety/object-safety-sized-2.rs b/src/test/ui/object-safety/object-safety-sized-2.rs new file mode 100644 index 000000000..1e79b8cd9 --- /dev/null +++ b/src/test/ui/object-safety/object-safety-sized-2.rs @@ -0,0 +1,21 @@ +// Check that we correctly prevent users from making trait objects +// from traits where `Self : Sized`. +// +// revisions: curr object_safe_for_dispatch + +#![cfg_attr(object_safe_for_dispatch, feature(object_safe_for_dispatch))] + +trait Bar + where Self : Sized +{ + fn bar(&self, t: T); +} + +fn make_bar(t: &T) -> &dyn Bar { + //[curr]~^ ERROR E0038 + t + //[object_safe_for_dispatch]~^ ERROR E0038 +} + +fn main() { +} diff --git a/src/test/ui/object-safety/object-safety-sized.curr.stderr b/src/test/ui/object-safety/object-safety-sized.curr.stderr new file mode 100644 index 000000000..94b06ee93 --- /dev/null +++ b/src/test/ui/object-safety/object-safety-sized.curr.stderr @@ -0,0 +1,17 @@ +error[E0038]: the trait `Bar` cannot be made into an object + --> $DIR/object-safety-sized.rs:12:30 + | +LL | fn make_bar(t: &T) -> &dyn Bar { + | ^^^^^^^^ `Bar` cannot be made into an object + | +note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit + --> $DIR/object-safety-sized.rs:8:13 + | +LL | trait Bar : Sized { + | --- ^^^^^ ...because it requires `Self: Sized` + | | + | this trait cannot be made into an object... + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0038`. diff --git a/src/test/ui/object-safety/object-safety-sized.object_safe_for_dispatch.stderr b/src/test/ui/object-safety/object-safety-sized.object_safe_for_dispatch.stderr new file mode 100644 index 000000000..645852c7e --- /dev/null +++ b/src/test/ui/object-safety/object-safety-sized.object_safe_for_dispatch.stderr @@ -0,0 +1,19 @@ +error[E0038]: the trait `Bar` cannot be made into an object + --> $DIR/object-safety-sized.rs:14:5 + | +LL | t + | ^ `Bar` cannot be made into an object + | +note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit + --> $DIR/object-safety-sized.rs:8:13 + | +LL | trait Bar : Sized { + | --- ^^^^^ ...because it requires `Self: Sized` + | | + | this trait cannot be made into an object... + = note: required because of the requirements on the impl of `CoerceUnsized<&dyn Bar>` for `&T` + = note: required by cast to type `&dyn Bar` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0038`. diff --git a/src/test/ui/object-safety/object-safety-sized.rs b/src/test/ui/object-safety/object-safety-sized.rs new file mode 100644 index 000000000..b424b892d --- /dev/null +++ b/src/test/ui/object-safety/object-safety-sized.rs @@ -0,0 +1,19 @@ +// Check that we correctly prevent users from making trait objects +// from traits where `Self : Sized`. +// +// revisions: curr object_safe_for_dispatch + +#![cfg_attr(object_safe_for_dispatch, feature(object_safe_for_dispatch))] + +trait Bar : Sized { + fn bar(&self, t: T); +} + +fn make_bar(t: &T) -> &dyn Bar { + //[curr]~^ ERROR E0038 + t + //[object_safe_for_dispatch]~^ ERROR E0038 +} + +fn main() { +} diff --git a/src/test/ui/object-safety/object-safety-supertrait-mentions-Self.rs b/src/test/ui/object-safety/object-safety-supertrait-mentions-Self.rs new file mode 100644 index 000000000..2445b33c8 --- /dev/null +++ b/src/test/ui/object-safety/object-safety-supertrait-mentions-Self.rs @@ -0,0 +1,21 @@ +// Check that we correctly prevent users from making trait objects +// form traits that make use of `Self` in an argument or return position. + +trait Bar { + fn bar(&self, x: &T); +} + +trait Baz : Bar { +} + +fn make_bar>(t: &T) -> &dyn Bar { + t +} + +fn make_baz(t: &T) -> &dyn Baz { + //~^ ERROR E0038 + t +} + +fn main() { +} diff --git a/src/test/ui/object-safety/object-safety-supertrait-mentions-Self.stderr b/src/test/ui/object-safety/object-safety-supertrait-mentions-Self.stderr new file mode 100644 index 000000000..a106ab995 --- /dev/null +++ b/src/test/ui/object-safety/object-safety-supertrait-mentions-Self.stderr @@ -0,0 +1,17 @@ +error[E0038]: the trait `Baz` cannot be made into an object + --> $DIR/object-safety-supertrait-mentions-Self.rs:15:31 + | +LL | fn make_baz(t: &T) -> &dyn Baz { + | ^^^^^^^ `Baz` cannot be made into an object + | +note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit + --> $DIR/object-safety-supertrait-mentions-Self.rs:8:13 + | +LL | trait Baz : Bar { + | --- ^^^^^^^^^ ...because it uses `Self` as a type parameter + | | + | this trait cannot be made into an object... + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0038`. -- cgit v1.2.3