From 64d98f8ee037282c35007b64c2649055c56af1db Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Wed, 17 Apr 2024 14:19:03 +0200 Subject: Merging upstream version 1.68.2+dfsg1. Signed-off-by: Daniel Baumann --- tests/ui/object-safety/issue-102762.rs | 26 ++++++++++++ tests/ui/object-safety/issue-102762.stderr | 20 ++++++++++ tests/ui/object-safety/issue-102933.rs | 25 ++++++++++++ tests/ui/object-safety/issue-106247.rs | 9 +++++ tests/ui/object-safety/issue-19538.rs | 20 ++++++++++ tests/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 +++++++++ tests/ui/object-safety/object-safety-bounds.rs | 12 ++++++ tests/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 +++++++++++++++++ tests/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 +++++++++++++ tests/ui/object-safety/object-safety-no-static.rs | 24 +++++++++++ tests/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 +++++++++ tests/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 +++++++++ tests/ui/object-safety/object-safety-sized.rs | 19 +++++++++ .../object-safety-supertrait-mentions-GAT.rs | 15 +++++++ .../object-safety-supertrait-mentions-GAT.stderr | 43 ++++++++++++++++++++ .../object-safety-supertrait-mentions-Self.rs | 21 ++++++++++ .../object-safety-supertrait-mentions-Self.stderr | 17 ++++++++ 36 files changed, 882 insertions(+) create mode 100644 tests/ui/object-safety/issue-102762.rs create mode 100644 tests/ui/object-safety/issue-102762.stderr create mode 100644 tests/ui/object-safety/issue-102933.rs create mode 100644 tests/ui/object-safety/issue-106247.rs create mode 100644 tests/ui/object-safety/issue-19538.rs create mode 100644 tests/ui/object-safety/issue-19538.stderr create mode 100644 tests/ui/object-safety/object-safety-associated-consts.curr.stderr create mode 100644 tests/ui/object-safety/object-safety-associated-consts.object_safe_for_dispatch.stderr create mode 100644 tests/ui/object-safety/object-safety-associated-consts.rs create mode 100644 tests/ui/object-safety/object-safety-bounds.rs create mode 100644 tests/ui/object-safety/object-safety-bounds.stderr create mode 100644 tests/ui/object-safety/object-safety-by-value-self-use.rs create mode 100644 tests/ui/object-safety/object-safety-by-value-self-use.stderr create mode 100644 tests/ui/object-safety/object-safety-by-value-self.rs create mode 100644 tests/ui/object-safety/object-safety-generics.curr.stderr create mode 100644 tests/ui/object-safety/object-safety-generics.object_safe_for_dispatch.stderr create mode 100644 tests/ui/object-safety/object-safety-generics.rs create mode 100644 tests/ui/object-safety/object-safety-issue-22040.rs create mode 100644 tests/ui/object-safety/object-safety-issue-22040.stderr create mode 100644 tests/ui/object-safety/object-safety-mentions-Self.curr.stderr create mode 100644 tests/ui/object-safety/object-safety-mentions-Self.object_safe_for_dispatch.stderr create mode 100644 tests/ui/object-safety/object-safety-mentions-Self.rs create mode 100644 tests/ui/object-safety/object-safety-no-static.curr.stderr create mode 100644 tests/ui/object-safety/object-safety-no-static.object_safe_for_dispatch.stderr create mode 100644 tests/ui/object-safety/object-safety-no-static.rs create mode 100644 tests/ui/object-safety/object-safety-phantom-fn.rs create mode 100644 tests/ui/object-safety/object-safety-sized-2.curr.stderr create mode 100644 tests/ui/object-safety/object-safety-sized-2.object_safe_for_dispatch.stderr create mode 100644 tests/ui/object-safety/object-safety-sized-2.rs create mode 100644 tests/ui/object-safety/object-safety-sized.curr.stderr create mode 100644 tests/ui/object-safety/object-safety-sized.object_safe_for_dispatch.stderr create mode 100644 tests/ui/object-safety/object-safety-sized.rs create mode 100644 tests/ui/object-safety/object-safety-supertrait-mentions-GAT.rs create mode 100644 tests/ui/object-safety/object-safety-supertrait-mentions-GAT.stderr create mode 100644 tests/ui/object-safety/object-safety-supertrait-mentions-Self.rs create mode 100644 tests/ui/object-safety/object-safety-supertrait-mentions-Self.stderr (limited to 'tests/ui/object-safety') diff --git a/tests/ui/object-safety/issue-102762.rs b/tests/ui/object-safety/issue-102762.rs new file mode 100644 index 000000000..4f4c36345 --- /dev/null +++ b/tests/ui/object-safety/issue-102762.rs @@ -0,0 +1,26 @@ +// compile-flags: --crate-type=lib +// This test checks that the `where_clauses_object_safety` lint does not cause +// other object safety *hard errors* to be suppressed, because we currently +// only emit one object safety error per trait... + +use std::future::Future; +use std::pin::Pin; + +pub trait Fetcher: Send + Sync { + fn get<'a>(self: &'a Box) -> Pin> + 'a>> + where + Self: Sync, + { + todo!() + } +} + +fn fetcher() -> Box { + //~^ ERROR the trait `Fetcher` cannot be made into an object + todo!() +} + +pub fn foo() { + let fetcher = fetcher(); + let _ = fetcher.get(); +} diff --git a/tests/ui/object-safety/issue-102762.stderr b/tests/ui/object-safety/issue-102762.stderr new file mode 100644 index 000000000..5041ebe77 --- /dev/null +++ b/tests/ui/object-safety/issue-102762.stderr @@ -0,0 +1,20 @@ +error[E0038]: the trait `Fetcher` cannot be made into an object + --> $DIR/issue-102762.rs:18:21 + | +LL | fn get<'a>(self: &'a Box) -> Pin> + 'a>> + | ------------- help: consider changing method `get`'s `self` parameter to be `&self`: `&Self` +... +LL | fn fetcher() -> Box { + | ^^^^^^^^^^^ `Fetcher` 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-102762.rs:10:22 + | +LL | pub trait Fetcher: Send + Sync { + | ------- this trait cannot be made into an object... +LL | fn get<'a>(self: &'a Box) -> Pin> + 'a>> + | ^^^^^^^^^^^^^ ...because method `get`'s `self` parameter cannot be dispatched on + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0038`. diff --git a/tests/ui/object-safety/issue-102933.rs b/tests/ui/object-safety/issue-102933.rs new file mode 100644 index 000000000..843391cff --- /dev/null +++ b/tests/ui/object-safety/issue-102933.rs @@ -0,0 +1,25 @@ +// check-pass + +use std::future::Future; + +pub trait Service { + type Response; + type Future: Future; +} + +pub trait A1: Service {} + +pub trait A2: Service>> + A1 { + fn foo(&self) {} +} + +pub trait B1: Service>> {} + +pub trait B2: Service + B1 { + fn foo(&self) {} +} + +fn main() { + let x: &dyn A2 = todo!(); + let x: &dyn B2 = todo!(); +} diff --git a/tests/ui/object-safety/issue-106247.rs b/tests/ui/object-safety/issue-106247.rs new file mode 100644 index 000000000..64bf59e5d --- /dev/null +++ b/tests/ui/object-safety/issue-106247.rs @@ -0,0 +1,9 @@ +// check-pass + +#![deny(where_clauses_object_safety)] + +pub trait Trait { + fn method(&self) where Self: Sync; +} + +fn main() {} diff --git a/tests/ui/object-safety/issue-19538.rs b/tests/ui/object-safety/issue-19538.rs new file mode 100644 index 000000000..7054ef41b --- /dev/null +++ b/tests/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/tests/ui/object-safety/issue-19538.stderr b/tests/ui/object-safety/issue-19538.stderr new file mode 100644 index 000000000..8420637b3 --- /dev/null +++ b/tests/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 for `&mut Thing` to implement `CoerceUnsized<&mut dyn Bar>` + = 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/tests/ui/object-safety/object-safety-associated-consts.curr.stderr b/tests/ui/object-safety/object-safety-associated-consts.curr.stderr new file mode 100644 index 000000000..5f94c9284 --- /dev/null +++ b/tests/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:31 + | +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/tests/ui/object-safety/object-safety-associated-consts.object_safe_for_dispatch.stderr b/tests/ui/object-safety/object-safety-associated-consts.object_safe_for_dispatch.stderr new file mode 100644 index 000000000..f44de07d5 --- /dev/null +++ b/tests/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 for `&T` to implement `CoerceUnsized<&dyn Bar>` + = 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/tests/ui/object-safety/object-safety-associated-consts.rs b/tests/ui/object-safety/object-safety-associated-consts.rs new file mode 100644 index 000000000..e1a772e5a --- /dev/null +++ b/tests/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/tests/ui/object-safety/object-safety-bounds.rs b/tests/ui/object-safety/object-safety-bounds.rs new file mode 100644 index 000000000..44bd36932 --- /dev/null +++ b/tests/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/tests/ui/object-safety/object-safety-bounds.stderr b/tests/ui/object-safety/object-safety-bounds.stderr new file mode 100644 index 000000000..29ffb5448 --- /dev/null +++ b/tests/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:15 + | +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/tests/ui/object-safety/object-safety-by-value-self-use.rs b/tests/ui/object-safety/object-safety-by-value-self-use.rs new file mode 100644 index 000000000..8e93c5382 --- /dev/null +++ b/tests/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/tests/ui/object-safety/object-safety-by-value-self-use.stderr b/tests/ui/object-safety/object-safety-by-value-self-use.stderr new file mode 100644 index 000000000..94fdcdf26 --- /dev/null +++ b/tests/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/tests/ui/object-safety/object-safety-by-value-self.rs b/tests/ui/object-safety/object-safety-by-value-self.rs new file mode 100644 index 000000000..c74a4d1cb --- /dev/null +++ b/tests/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/tests/ui/object-safety/object-safety-generics.curr.stderr b/tests/ui/object-safety/object-safety-generics.curr.stderr new file mode 100644 index 000000000..458103752 --- /dev/null +++ b/tests/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:31 + | +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:40 + | +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/tests/ui/object-safety/object-safety-generics.object_safe_for_dispatch.stderr b/tests/ui/object-safety/object-safety-generics.object_safe_for_dispatch.stderr new file mode 100644 index 000000000..9a2d472d5 --- /dev/null +++ b/tests/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 for `&T` to implement `CoerceUnsized<&dyn Bar>` + = 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 for `&T` to implement `CoerceUnsized<&dyn Bar>` + = 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/tests/ui/object-safety/object-safety-generics.rs b/tests/ui/object-safety/object-safety-generics.rs new file mode 100644 index 000000000..63dcd1699 --- /dev/null +++ b/tests/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/tests/ui/object-safety/object-safety-issue-22040.rs b/tests/ui/object-safety/object-safety-issue-22040.rs new file mode 100644 index 000000000..1fc5c5442 --- /dev/null +++ b/tests/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/tests/ui/object-safety/object-safety-issue-22040.stderr b/tests/ui/object-safety/object-safety-issue-22040.stderr new file mode 100644 index 000000000..0262d5362 --- /dev/null +++ b/tests/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/tests/ui/object-safety/object-safety-mentions-Self.curr.stderr b/tests/ui/object-safety/object-safety-mentions-Self.curr.stderr new file mode 100644 index 000000000..de430a89b --- /dev/null +++ b/tests/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:31 + | +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: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-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/tests/ui/object-safety/object-safety-mentions-Self.object_safe_for_dispatch.stderr b/tests/ui/object-safety/object-safety-mentions-Self.object_safe_for_dispatch.stderr new file mode 100644 index 000000000..40a298bd1 --- /dev/null +++ b/tests/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 for `&T` to implement `CoerceUnsized<&dyn Bar>` + = 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 for `&T` to implement `CoerceUnsized<&dyn Baz>` + = 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/tests/ui/object-safety/object-safety-mentions-Self.rs b/tests/ui/object-safety/object-safety-mentions-Self.rs new file mode 100644 index 000000000..412d16ff3 --- /dev/null +++ b/tests/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/tests/ui/object-safety/object-safety-no-static.curr.stderr b/tests/ui/object-safety/object-safety-no-static.curr.stderr new file mode 100644 index 000000000..1b025229e --- /dev/null +++ b/tests/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:22 + | +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/tests/ui/object-safety/object-safety-no-static.object_safe_for_dispatch.stderr b/tests/ui/object-safety/object-safety-no-static.object_safe_for_dispatch.stderr new file mode 100644 index 000000000..da87b58c9 --- /dev/null +++ b/tests/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 for `Box` to implement `CoerceUnsized>` + = 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/tests/ui/object-safety/object-safety-no-static.rs b/tests/ui/object-safety/object-safety-no-static.rs new file mode 100644 index 000000000..03b622174 --- /dev/null +++ b/tests/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/tests/ui/object-safety/object-safety-phantom-fn.rs b/tests/ui/object-safety/object-safety-phantom-fn.rs new file mode 100644 index 000000000..3ffeb81c1 --- /dev/null +++ b/tests/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/tests/ui/object-safety/object-safety-sized-2.curr.stderr b/tests/ui/object-safety/object-safety-sized-2.curr.stderr new file mode 100644 index 000000000..b01926412 --- /dev/null +++ b/tests/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:31 + | +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/tests/ui/object-safety/object-safety-sized-2.object_safe_for_dispatch.stderr b/tests/ui/object-safety/object-safety-sized-2.object_safe_for_dispatch.stderr new file mode 100644 index 000000000..6c29c8d5f --- /dev/null +++ b/tests/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 for `&T` to implement `CoerceUnsized<&dyn Bar>` + = 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/tests/ui/object-safety/object-safety-sized-2.rs b/tests/ui/object-safety/object-safety-sized-2.rs new file mode 100644 index 000000000..1e79b8cd9 --- /dev/null +++ b/tests/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/tests/ui/object-safety/object-safety-sized.curr.stderr b/tests/ui/object-safety/object-safety-sized.curr.stderr new file mode 100644 index 000000000..974813121 --- /dev/null +++ b/tests/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:31 + | +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/tests/ui/object-safety/object-safety-sized.object_safe_for_dispatch.stderr b/tests/ui/object-safety/object-safety-sized.object_safe_for_dispatch.stderr new file mode 100644 index 000000000..70a44ed61 --- /dev/null +++ b/tests/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 for `&T` to implement `CoerceUnsized<&dyn Bar>` + = 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/tests/ui/object-safety/object-safety-sized.rs b/tests/ui/object-safety/object-safety-sized.rs new file mode 100644 index 000000000..b424b892d --- /dev/null +++ b/tests/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/tests/ui/object-safety/object-safety-supertrait-mentions-GAT.rs b/tests/ui/object-safety/object-safety-supertrait-mentions-GAT.rs new file mode 100644 index 000000000..14e00d2ef --- /dev/null +++ b/tests/ui/object-safety/object-safety-supertrait-mentions-GAT.rs @@ -0,0 +1,15 @@ +//~ ERROR the parameter type `Self` may not live long enough + +trait GatTrait { + type Gat<'a> + where + Self: 'a; +} + +trait SuperTrait: for<'a> GatTrait = T> { + fn c(&self) -> dyn SuperTrait; + //~^ ERROR associated item referring to unboxed trait object for its own trait + //~| ERROR the trait `SuperTrait` cannot be made into an object +} + +fn main() {} diff --git a/tests/ui/object-safety/object-safety-supertrait-mentions-GAT.stderr b/tests/ui/object-safety/object-safety-supertrait-mentions-GAT.stderr new file mode 100644 index 000000000..f05b0cd65 --- /dev/null +++ b/tests/ui/object-safety/object-safety-supertrait-mentions-GAT.stderr @@ -0,0 +1,43 @@ +error[E0311]: the parameter type `Self` may not live long enough + | + = help: consider adding an explicit lifetime bound `Self: 'a`... + = note: ...so that the type `Self` will meet its required lifetime bounds... +note: ...that is required by this bound + --> $DIR/object-safety-supertrait-mentions-GAT.rs:6:15 + | +LL | Self: 'a; + | ^^ + +error: associated item referring to unboxed trait object for its own trait + --> $DIR/object-safety-supertrait-mentions-GAT.rs:10:20 + | +LL | trait SuperTrait: for<'a> GatTrait = T> { + | ---------- in this trait +LL | fn c(&self) -> dyn SuperTrait; + | ^^^^^^^^^^^^^^^^^ + | +help: you might have meant to use `Self` to refer to the implementing type + | +LL | fn c(&self) -> Self; + | ~~~~ + +error[E0038]: the trait `SuperTrait` cannot be made into an object + --> $DIR/object-safety-supertrait-mentions-GAT.rs:10:20 + | +LL | fn c(&self) -> dyn SuperTrait; + | ^^^^^^^^^^^^^^^^^ `SuperTrait` 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-GAT.rs:4:10 + | +LL | type Gat<'a> + | ^^^ ...because it contains the generic associated type `Gat` +... +LL | trait SuperTrait: for<'a> GatTrait = T> { + | ---------- this trait cannot be made into an object... + = help: consider moving `Gat` to another trait + +error: aborting due to 3 previous errors + +Some errors have detailed explanations: E0038, E0311. +For more information about an error, try `rustc --explain E0038`. diff --git a/tests/ui/object-safety/object-safety-supertrait-mentions-Self.rs b/tests/ui/object-safety/object-safety-supertrait-mentions-Self.rs new file mode 100644 index 000000000..2445b33c8 --- /dev/null +++ b/tests/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/tests/ui/object-safety/object-safety-supertrait-mentions-Self.stderr b/tests/ui/object-safety/object-safety-supertrait-mentions-Self.stderr new file mode 100644 index 000000000..a106ab995 --- /dev/null +++ b/tests/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