From 8c04999226e4be90c46c370580c9e8cd7f0ccb05 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Tue, 24 Oct 2023 16:45:04 +0000 Subject: [PATCH] On object safety error, mention new enum as alternative When we encounter a `dyn Trait` that isn't object safe, look for its implementors. If there's one, mention using it directly If there are less than 9, mention the possibility of creating a new enum and using that instead. Account for object unsafe `impl Trait on dyn Trait {}`. Make a distinction between public and sealed traits. Fix #80194. --- .../src/traits/error_reporting/mod.rs | 64 ++++++++++++++++++- .../object-safety-err-ret.stderr | 1 + ...gate-dispatch-from-dyn-missing-impl.stderr | 2 + .../gat-in-trait-path.base.stderr | 3 + .../issue-76535.base.stderr | 4 ++ .../issue-79422.base.stderr | 6 ++ .../in-trait/foreign-dyn-error.stderr | 1 + .../impl-trait/in-trait/object-safety.stderr | 4 ++ ...-trait-in-return-position-dyn-trait.stderr | 6 ++ tests/ui/issues/issue-19380.stderr | 2 + tests/ui/object-safety/issue-19538.stderr | 2 + .../object-safety-issue-22040.stderr | 1 + .../object-safety-no-static.curr.stderr | 1 + ...-no-static.object_safe_for_dispatch.stderr | 1 + ...ary-self-types-not-object-safe.curr.stderr | 2 + ...bject-safe.object_safe_for_dispatch.stderr | 1 + tests/ui/traits/issue-38604.stderr | 2 + tests/ui/traits/item-privacy.stderr | 1 + .../supertrait-object-safety.stderr | 3 + tests/ui/traits/object/safety.stderr | 2 + tests/ui/traits/test-2.stderr | 9 +++ ...ter-defaults-referencing-Self-ppaux.stderr | 1 + .../wf/wf-convert-unsafe-trait-obj-box.stderr | 3 + .../ui/wf/wf-convert-unsafe-trait-obj.stderr | 3 + tests/ui/wf/wf-unsafe-trait-obj-match.stderr | 6 ++ 25 files changed, 130 insertions(+), 1 deletion(-) diff --git a/compiler/rustc_infer/src/traits/error_reporting/mod.rs b/compiler/rustc_infer/src/traits/error_reporting/mod.rs index 7a335827f37..32966011932 100644 --- a/compiler/rustc_infer/src/traits/error_reporting/mod.rs +++ b/compiler/rustc_infer/src/traits/error_reporting/mod.rs @@ -5,7 +5,8 @@ use rustc_data_structures::fx::FxIndexSet; use rustc_errors::{struct_span_err, DiagnosticBuilder, ErrorGuaranteed, MultiSpan}; use rustc_hir as hir; use rustc_hir::def_id::{DefId, LocalDefId}; -use rustc_middle::ty::TyCtxt; +use rustc_middle::ty::print::with_no_trimmed_paths; +use rustc_middle::ty::{self, TyCtxt}; use rustc_span::Span; use std::fmt; use std::iter; @@ -108,5 +109,66 @@ pub fn report_object_safety_error<'tcx>( violation.solution(&mut err); } } + + let impls_of = tcx.trait_impls_of(trait_def_id); + let impls = if impls_of.blanket_impls().is_empty() { + impls_of + .non_blanket_impls() + .values() + .flatten() + .filter(|def_id| { + !matches!(tcx.type_of(*def_id).instantiate_identity().kind(), ty::Dynamic(..)) + }) + .collect::>() + } else { + vec![] + }; + let externally_visible = if !impls.is_empty() + && let Some(def_id) = trait_def_id.as_local() + && tcx.effective_visibilities(()).is_exported(def_id) + { + true + } else { + false + }; + match &impls[..] { + [] => {} + _ if impls.len() > 9 => {} + [only] if externally_visible => { + err.help(with_no_trimmed_paths!(format!( + "only type `{}` is seen to implement the trait in this crate, consider using it \ + directly instead", + tcx.type_of(*only).instantiate_identity(), + ))); + } + [only] => { + err.help(with_no_trimmed_paths!(format!( + "only type `{}` implements the trait, consider using it directly instead", + tcx.type_of(*only).instantiate_identity(), + ))); + } + impls => { + let types = impls + .iter() + .map(|t| { + with_no_trimmed_paths!(format!(" {}", tcx.type_of(*t).instantiate_identity(),)) + }) + .collect::>(); + err.help(format!( + "the following types implement the trait, consider defining an enum where each \ + variant holds one of these types, implementing `{}` for this new enum and using \ + it instead:\n{}", + trait_str, + types.join("\n"), + )); + } + } + if externally_visible { + err.note(format!( + "`{trait_str}` can be implemented in other crates; if you want to support your users \ + passing their own types here, you can't refer to a specific type", + )); + } + err } diff --git a/tests/ui/const-generics/generic_const_exprs/object-safety-err-ret.stderr b/tests/ui/const-generics/generic_const_exprs/object-safety-err-ret.stderr index 7ce2b9ac95a..b7ec657120c 100644 --- a/tests/ui/const-generics/generic_const_exprs/object-safety-err-ret.stderr +++ b/tests/ui/const-generics/generic_const_exprs/object-safety-err-ret.stderr @@ -15,6 +15,7 @@ LL | fn test(&self) -> [u8; bar::()]; | ...because method `test` references the `Self` type in its `where` clause = help: consider moving `test` to another trait = help: consider moving `test` to another trait + = help: only type `()` implements the trait, consider using it directly instead error: aborting due to previous error diff --git a/tests/ui/feature-gates/feature-gate-dispatch-from-dyn-missing-impl.stderr b/tests/ui/feature-gates/feature-gate-dispatch-from-dyn-missing-impl.stderr index 303700c7ab4..00b8c0eef98 100644 --- a/tests/ui/feature-gates/feature-gate-dispatch-from-dyn-missing-impl.stderr +++ b/tests/ui/feature-gates/feature-gate-dispatch-from-dyn-missing-impl.stderr @@ -14,6 +14,7 @@ LL | trait Trait { | ----- this trait cannot be made into an object... LL | fn ptr(self: Ptr); | ^^^^^^^^^ ...because method `ptr`'s `self` parameter cannot be dispatched on + = help: only type `i32` implements the trait, consider using it directly instead error[E0038]: the trait `Trait` cannot be made into an object --> $DIR/feature-gate-dispatch-from-dyn-missing-impl.rs:32:5 @@ -31,6 +32,7 @@ LL | trait Trait { | ----- this trait cannot be made into an object... LL | fn ptr(self: Ptr); | ^^^^^^^^^ ...because method `ptr`'s `self` parameter cannot be dispatched on + = help: only type `i32` implements the trait, consider using it directly instead = note: required for the cast from `Ptr<{integer}>` to `Ptr` error: aborting due to 2 previous errors diff --git a/tests/ui/generic-associated-types/gat-in-trait-path.base.stderr b/tests/ui/generic-associated-types/gat-in-trait-path.base.stderr index fd54faaf37c..9013d429530 100644 --- a/tests/ui/generic-associated-types/gat-in-trait-path.base.stderr +++ b/tests/ui/generic-associated-types/gat-in-trait-path.base.stderr @@ -12,6 +12,9 @@ LL | trait Foo { LL | type A<'a> where Self: 'a; | ^ ...because it contains the generic associated type `A` = help: consider moving `A` to another trait + = help: the following types implement the trait, consider defining an enum where each variant holds one of these types, implementing `Foo` for this new enum and using it instead: + Fooy + Fooer error: aborting due to previous error diff --git a/tests/ui/generic-associated-types/issue-76535.base.stderr b/tests/ui/generic-associated-types/issue-76535.base.stderr index 370329b9f83..bb14e297174 100644 --- a/tests/ui/generic-associated-types/issue-76535.base.stderr +++ b/tests/ui/generic-associated-types/issue-76535.base.stderr @@ -28,6 +28,8 @@ LL | pub trait SuperTrait { LL | type SubType<'a>: SubTrait where Self: 'a; | ^^^^^^^ ...because it contains the generic associated type `SubType` = help: consider moving `SubType` to another trait + = help: only type `SuperStruct` is seen to implement the trait in this crate, consider using it directly instead + = note: `SuperTrait` can be implemented in other crates; if you want to support your users passing their own types here, you can't refer to a specific type error[E0038]: the trait `SuperTrait` cannot be made into an object --> $DIR/issue-76535.rs:39:57 @@ -43,6 +45,8 @@ LL | pub trait SuperTrait { LL | type SubType<'a>: SubTrait where Self: 'a; | ^^^^^^^ ...because it contains the generic associated type `SubType` = help: consider moving `SubType` to another trait + = help: only type `SuperStruct` is seen to implement the trait in this crate, consider using it directly instead + = note: `SuperTrait` can be implemented in other crates; if you want to support your users passing their own types here, you can't refer to a specific type = note: required for the cast from `Box` to `Box>>` error: aborting due to 3 previous errors diff --git a/tests/ui/generic-associated-types/issue-79422.base.stderr b/tests/ui/generic-associated-types/issue-79422.base.stderr index ad704f5e9f0..bcc6382cf7c 100644 --- a/tests/ui/generic-associated-types/issue-79422.base.stderr +++ b/tests/ui/generic-associated-types/issue-79422.base.stderr @@ -28,6 +28,9 @@ LL | trait MapLike { LL | type VRefCont<'a>: RefCont<'a, V> where Self: 'a; | ^^^^^^^^ ...because it contains the generic associated type `VRefCont` = help: consider moving `VRefCont` to another trait + = help: the following types implement the trait, consider defining an enum where each variant holds one of these types, implementing `MapLike` for this new enum and using it instead: + std::collections::BTreeMap + Source error[E0038]: the trait `MapLike` cannot be made into an object --> $DIR/issue-79422.rs:44:13 @@ -43,6 +46,9 @@ LL | trait MapLike { LL | type VRefCont<'a>: RefCont<'a, V> where Self: 'a; | ^^^^^^^^ ...because it contains the generic associated type `VRefCont` = help: consider moving `VRefCont` to another trait + = help: the following types implement the trait, consider defining an enum where each variant holds one of these types, implementing `MapLike` for this new enum and using it instead: + std::collections::BTreeMap + Source = note: required for the cast from `Box>` to `Box + 'static)>>` error: aborting due to 3 previous errors diff --git a/tests/ui/impl-trait/in-trait/foreign-dyn-error.stderr b/tests/ui/impl-trait/in-trait/foreign-dyn-error.stderr index bfb2be8cbc1..f29ec95d594 100644 --- a/tests/ui/impl-trait/in-trait/foreign-dyn-error.stderr +++ b/tests/ui/impl-trait/in-trait/foreign-dyn-error.stderr @@ -9,6 +9,7 @@ note: for a trait to be "object safe" it needs to allow building a vtable to all | LL | fn bar(self) -> impl Deref; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait cannot be made into an object because method `bar` references an `impl Trait` type in its return type + = help: only type `rpitit::Foreign` implements the trait, consider using it directly instead error: aborting due to previous error diff --git a/tests/ui/impl-trait/in-trait/object-safety.stderr b/tests/ui/impl-trait/in-trait/object-safety.stderr index 3271cb18d9f..a7be0516cd3 100644 --- a/tests/ui/impl-trait/in-trait/object-safety.stderr +++ b/tests/ui/impl-trait/in-trait/object-safety.stderr @@ -12,6 +12,7 @@ LL | trait Foo { LL | fn baz(&self) -> impl Debug; | ^^^^^^^^^^ ...because method `baz` references an `impl Trait` type in its return type = help: consider moving `baz` to another trait + = help: only type `u32` implements the trait, consider using it directly instead error[E0038]: the trait `Foo` cannot be made into an object --> $DIR/object-safety.rs:17:15 @@ -27,6 +28,7 @@ LL | trait Foo { LL | fn baz(&self) -> impl Debug; | ^^^^^^^^^^ ...because method `baz` references an `impl Trait` type in its return type = help: consider moving `baz` to another trait + = help: only type `u32` implements the trait, consider using it directly instead error[E0038]: the trait `Foo` cannot be made into an object --> $DIR/object-safety.rs:17:13 @@ -42,6 +44,7 @@ LL | trait Foo { LL | fn baz(&self) -> impl Debug; | ^^^^^^^^^^ ...because method `baz` references an `impl Trait` type in its return type = help: consider moving `baz` to another trait + = help: only type `u32` implements the trait, consider using it directly instead error[E0038]: the trait `Foo` cannot be made into an object --> $DIR/object-safety.rs:14:13 @@ -57,6 +60,7 @@ LL | trait Foo { LL | fn baz(&self) -> impl Debug; | ^^^^^^^^^^ ...because method `baz` references an `impl Trait` type in its return type = help: consider moving `baz` to another trait + = help: only type `u32` implements the trait, consider using it directly instead = note: required for the cast from `Box` to `Box` error: aborting due to 4 previous errors diff --git a/tests/ui/impl-trait/object-unsafe-trait-in-return-position-dyn-trait.stderr b/tests/ui/impl-trait/object-unsafe-trait-in-return-position-dyn-trait.stderr index 687dbe65e6c..37c96d9bc4e 100644 --- a/tests/ui/impl-trait/object-unsafe-trait-in-return-position-dyn-trait.stderr +++ b/tests/ui/impl-trait/object-unsafe-trait-in-return-position-dyn-trait.stderr @@ -11,6 +11,9 @@ LL | trait NotObjectSafe { | ------------- this trait cannot be made into an object... LL | fn foo() -> Self; | ^^^ ...because associated function `foo` has no `self` parameter + = help: the following types implement the trait, consider defining an enum where each variant holds one of these types, implementing `NotObjectSafe` for this new enum and using it instead: + A + B help: consider turning `foo` into a method by giving it a `&self` argument | LL | fn foo(&self) -> Self; @@ -33,6 +36,9 @@ LL | trait NotObjectSafe { | ------------- this trait cannot be made into an object... LL | fn foo() -> Self; | ^^^ ...because associated function `foo` has no `self` parameter + = help: the following types implement the trait, consider defining an enum where each variant holds one of these types, implementing `NotObjectSafe` for this new enum and using it instead: + A + B help: consider turning `foo` into a method by giving it a `&self` argument | LL | fn foo(&self) -> Self; diff --git a/tests/ui/issues/issue-19380.stderr b/tests/ui/issues/issue-19380.stderr index 37e280fbcc7..f6244d9d44f 100644 --- a/tests/ui/issues/issue-19380.stderr +++ b/tests/ui/issues/issue-19380.stderr @@ -11,6 +11,7 @@ LL | trait Qiz { | --- this trait cannot be made into an object... LL | fn qiz(); | ^^^ ...because associated function `qiz` has no `self` parameter + = help: only type `Foo` implements the trait, consider using it directly instead help: consider turning `qiz` into a method by giving it a `&self` argument | LL | fn qiz(&self); @@ -33,6 +34,7 @@ LL | trait Qiz { | --- this trait cannot be made into an object... LL | fn qiz(); | ^^^ ...because associated function `qiz` has no `self` parameter + = help: only type `Foo` implements the trait, consider using it directly instead = note: required for the cast from `&Foo` to `&'static (dyn Qiz + 'static)` help: consider turning `qiz` into a method by giving it a `&self` argument | diff --git a/tests/ui/object-safety/issue-19538.stderr b/tests/ui/object-safety/issue-19538.stderr index 183245b2322..31657501e25 100644 --- a/tests/ui/object-safety/issue-19538.stderr +++ b/tests/ui/object-safety/issue-19538.stderr @@ -13,6 +13,7 @@ LL | fn foo(&self, val: T); LL | trait Bar: Foo { } | --- this trait cannot be made into an object... = help: consider moving `foo` to another trait + = help: only type `Thing` implements the trait, consider using it directly instead error[E0038]: the trait `Bar` cannot be made into an object --> $DIR/issue-19538.rs:17:30 @@ -29,6 +30,7 @@ LL | fn foo(&self, val: T); LL | trait Bar: Foo { } | --- this trait cannot be made into an object... = help: consider moving `foo` to another trait + = help: only type `Thing` implements the trait, consider using it directly instead = note: required for the cast from `&mut Thing` to `&mut dyn Bar` error: aborting due to 2 previous errors diff --git a/tests/ui/object-safety/object-safety-issue-22040.stderr b/tests/ui/object-safety/object-safety-issue-22040.stderr index 0262d536246..2e59d88bdaf 100644 --- a/tests/ui/object-safety/object-safety-issue-22040.stderr +++ b/tests/ui/object-safety/object-safety-issue-22040.stderr @@ -11,6 +11,7 @@ LL | trait Expr: Debug + PartialEq { | ---- ^^^^^^^^^ ...because it uses `Self` as a type parameter | | | this trait cannot be made into an object... + = help: only type `SExpr<'x>` implements the trait, consider using it directly instead error: aborting due to previous error diff --git a/tests/ui/object-safety/object-safety-no-static.curr.stderr b/tests/ui/object-safety/object-safety-no-static.curr.stderr index 1b025229e54..b40470b457b 100644 --- a/tests/ui/object-safety/object-safety-no-static.curr.stderr +++ b/tests/ui/object-safety/object-safety-no-static.curr.stderr @@ -11,6 +11,7 @@ LL | trait Foo { | --- this trait cannot be made into an object... LL | fn foo() {} | ^^^ ...because associated function `foo` has no `self` parameter + = help: only type `Bar` implements the trait, consider using it directly instead help: consider turning `foo` into a method by giving it a `&self` argument | LL | fn foo(&self) {} 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 index befcef952a8..1eae9a9b9da 100644 --- 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 @@ -11,6 +11,7 @@ LL | trait Foo { | --- this trait cannot be made into an object... LL | fn foo() {} | ^^^ ...because associated function `foo` has no `self` parameter + = help: only type `Bar` implements the trait, consider using it directly instead = note: required for the cast from `Box` to `Box` help: consider turning `foo` into a method by giving it a `&self` argument | diff --git a/tests/ui/self/arbitrary-self-types-not-object-safe.curr.stderr b/tests/ui/self/arbitrary-self-types-not-object-safe.curr.stderr index 13591f5b635..fdd18c6b37b 100644 --- a/tests/ui/self/arbitrary-self-types-not-object-safe.curr.stderr +++ b/tests/ui/self/arbitrary-self-types-not-object-safe.curr.stderr @@ -14,6 +14,7 @@ LL | trait Foo { | --- this trait cannot be made into an object... LL | fn foo(self: &Rc) -> usize; | ^^^^^^^^^ ...because method `foo`'s `self` parameter cannot be dispatched on + = help: only type `usize` implements the trait, consider using it directly instead error[E0038]: the trait `Foo` cannot be made into an object --> $DIR/arbitrary-self-types-not-object-safe.rs:33:13 @@ -31,6 +32,7 @@ LL | trait Foo { | --- this trait cannot be made into an object... LL | fn foo(self: &Rc) -> usize; | ^^^^^^^^^ ...because method `foo`'s `self` parameter cannot be dispatched on + = help: only type `usize` implements the trait, consider using it directly instead = note: required for the cast from `Rc` to `Rc` error: aborting due to 2 previous errors diff --git a/tests/ui/self/arbitrary-self-types-not-object-safe.object_safe_for_dispatch.stderr b/tests/ui/self/arbitrary-self-types-not-object-safe.object_safe_for_dispatch.stderr index 593f705353a..0a567ddcc2e 100644 --- a/tests/ui/self/arbitrary-self-types-not-object-safe.object_safe_for_dispatch.stderr +++ b/tests/ui/self/arbitrary-self-types-not-object-safe.object_safe_for_dispatch.stderr @@ -14,6 +14,7 @@ LL | trait Foo { | --- this trait cannot be made into an object... LL | fn foo(self: &Rc) -> usize; | ^^^^^^^^^ ...because method `foo`'s `self` parameter cannot be dispatched on + = help: only type `usize` implements the trait, consider using it directly instead = note: required for the cast from `Rc` to `Rc` error: aborting due to previous error diff --git a/tests/ui/traits/issue-38604.stderr b/tests/ui/traits/issue-38604.stderr index d5327602430..3ab9af21bc4 100644 --- a/tests/ui/traits/issue-38604.stderr +++ b/tests/ui/traits/issue-38604.stderr @@ -11,6 +11,7 @@ LL | trait Foo where u32: Q { | --- ^^^^^^^ ...because it uses `Self` as a type parameter | | | this trait cannot be made into an object... + = help: only type `()` implements the trait, consider using it directly instead error[E0038]: the trait `Foo` cannot be made into an object --> $DIR/issue-38604.rs:15:9 @@ -25,6 +26,7 @@ LL | trait Foo where u32: Q { | --- ^^^^^^^ ...because it uses `Self` as a type parameter | | | this trait cannot be made into an object... + = help: only type `()` implements the trait, consider using it directly instead = note: required for the cast from `Box<()>` to `Box` error: aborting due to 2 previous errors diff --git a/tests/ui/traits/item-privacy.stderr b/tests/ui/traits/item-privacy.stderr index af2e0763212..d74be772660 100644 --- a/tests/ui/traits/item-privacy.stderr +++ b/tests/ui/traits/item-privacy.stderr @@ -143,6 +143,7 @@ LL | const C: u8 = 0; = help: consider moving `C` to another trait = help: consider moving `A` to another trait = help: consider moving `B` to another trait + = help: only type `S` implements the trait, consider using it directly instead error[E0223]: ambiguous associated type --> $DIR/item-privacy.rs:115:12 diff --git a/tests/ui/traits/non_lifetime_binders/supertrait-object-safety.stderr b/tests/ui/traits/non_lifetime_binders/supertrait-object-safety.stderr index d56519223f4..b6e540c5ffc 100644 --- a/tests/ui/traits/non_lifetime_binders/supertrait-object-safety.stderr +++ b/tests/ui/traits/non_lifetime_binders/supertrait-object-safety.stderr @@ -20,6 +20,7 @@ LL | trait Foo: for Bar {} | --- ^^^^^^^^^^^^^ ...because where clause cannot reference non-lifetime `for<...>` variables | | | this trait cannot be made into an object... + = help: only type `()` implements the trait, consider using it directly instead = note: required for the cast from `&()` to `&dyn Foo` error[E0038]: the trait `Foo` cannot be made into an object @@ -35,6 +36,7 @@ LL | trait Foo: for Bar {} | --- ^^^^^^^^^^^^^ ...because where clause cannot reference non-lifetime `for<...>` variables | | | this trait cannot be made into an object... + = help: only type `()` implements the trait, consider using it directly instead error[E0038]: the trait `Foo` cannot be made into an object --> $DIR/supertrait-object-safety.rs:22:5 @@ -49,6 +51,7 @@ LL | trait Foo: for Bar {} | --- ^^^^^^^^^^^^^ ...because where clause cannot reference non-lifetime `for<...>` variables | | | this trait cannot be made into an object... + = help: only type `()` implements the trait, consider using it directly instead error: aborting due to 3 previous errors; 1 warning emitted diff --git a/tests/ui/traits/object/safety.stderr b/tests/ui/traits/object/safety.stderr index a51b6975938..19a46a502c2 100644 --- a/tests/ui/traits/object/safety.stderr +++ b/tests/ui/traits/object/safety.stderr @@ -11,6 +11,7 @@ LL | trait Tr { | -- this trait cannot be made into an object... LL | fn foo(); | ^^^ ...because associated function `foo` has no `self` parameter + = help: only type `St` implements the trait, consider using it directly instead = note: required for the cast from `&St` to `&dyn Tr` help: consider turning `foo` into a method by giving it a `&self` argument | @@ -34,6 +35,7 @@ LL | trait Tr { | -- this trait cannot be made into an object... LL | fn foo(); | ^^^ ...because associated function `foo` has no `self` parameter + = help: only type `St` implements the trait, consider using it directly instead help: consider turning `foo` into a method by giving it a `&self` argument | LL | fn foo(&self); diff --git a/tests/ui/traits/test-2.stderr b/tests/ui/traits/test-2.stderr index 74a0fc42708..3972e539776 100644 --- a/tests/ui/traits/test-2.stderr +++ b/tests/ui/traits/test-2.stderr @@ -42,6 +42,9 @@ LL | trait bar { fn dup(&self) -> Self; fn blah(&self); } | this trait cannot be made into an object... = help: consider moving `dup` to another trait = help: consider moving `blah` to another trait + = help: the following types implement the trait, consider defining an enum where each variant holds one of these types, implementing `bar` for this new enum and using it instead: + i32 + u32 error[E0038]: the trait `bar` cannot be made into an object --> $DIR/test-2.rs:13:5 @@ -59,6 +62,9 @@ LL | trait bar { fn dup(&self) -> Self; fn blah(&self); } | this trait cannot be made into an object... = help: consider moving `dup` to another trait = help: consider moving `blah` to another trait + = help: the following types implement the trait, consider defining an enum where each variant holds one of these types, implementing `bar` for this new enum and using it instead: + i32 + u32 error[E0038]: the trait `bar` cannot be made into an object --> $DIR/test-2.rs:13:6 @@ -76,6 +82,9 @@ LL | trait bar { fn dup(&self) -> Self; fn blah(&self); } | this trait cannot be made into an object... = help: consider moving `dup` to another trait = help: consider moving `blah` to another trait + = help: the following types implement the trait, consider defining an enum where each variant holds one of these types, implementing `bar` for this new enum and using it instead: + i32 + u32 = note: required for the cast from `Box<{integer}>` to `Box` error: aborting due to 5 previous errors diff --git a/tests/ui/type/type-parameter-defaults-referencing-Self-ppaux.stderr b/tests/ui/type/type-parameter-defaults-referencing-Self-ppaux.stderr index 8a296dc7ee6..4412c49eadd 100644 --- a/tests/ui/type/type-parameter-defaults-referencing-Self-ppaux.stderr +++ b/tests/ui/type/type-parameter-defaults-referencing-Self-ppaux.stderr @@ -24,6 +24,7 @@ LL | trait MyAdd { fn add(&self, other: &Rhs) -> Self; } | | | this trait cannot be made into an object... = help: consider moving `add` to another trait + = help: only type `i32` implements the trait, consider using it directly instead error: aborting due to 2 previous errors diff --git a/tests/ui/wf/wf-convert-unsafe-trait-obj-box.stderr b/tests/ui/wf/wf-convert-unsafe-trait-obj-box.stderr index 40a25c7df6b..85f5073364f 100644 --- a/tests/ui/wf/wf-convert-unsafe-trait-obj-box.stderr +++ b/tests/ui/wf/wf-convert-unsafe-trait-obj-box.stderr @@ -11,6 +11,7 @@ LL | trait Trait: Sized {} | ----- ^^^^^ ...because it requires `Self: Sized` | | | this trait cannot be made into an object... + = help: only type `S` implements the trait, consider using it directly instead = note: required for the cast from `Box` to `Box` error[E0038]: the trait `Trait` cannot be made into an object @@ -26,6 +27,7 @@ LL | trait Trait: Sized {} | ----- ^^^^^ ...because it requires `Self: Sized` | | | this trait cannot be made into an object... + = help: only type `S` implements the trait, consider using it directly instead = note: required for the cast from `Box` to `Box<(dyn Trait + 'static)>` error[E0038]: the trait `Trait` cannot be made into an object @@ -41,6 +43,7 @@ LL | trait Trait: Sized {} | ----- ^^^^^ ...because it requires `Self: Sized` | | | this trait cannot be made into an object... + = help: only type `S` implements the trait, consider using it directly instead = note: required for the cast from `Box` to `Box` error: aborting due to 3 previous errors diff --git a/tests/ui/wf/wf-convert-unsafe-trait-obj.stderr b/tests/ui/wf/wf-convert-unsafe-trait-obj.stderr index e2c71df2feb..a2a19631649 100644 --- a/tests/ui/wf/wf-convert-unsafe-trait-obj.stderr +++ b/tests/ui/wf/wf-convert-unsafe-trait-obj.stderr @@ -11,6 +11,7 @@ LL | trait Trait: Sized {} | ----- ^^^^^ ...because it requires `Self: Sized` | | | this trait cannot be made into an object... + = help: only type `S` implements the trait, consider using it directly instead = note: required for the cast from `&S` to `&dyn Trait` error[E0038]: the trait `Trait` cannot be made into an object @@ -26,6 +27,7 @@ LL | trait Trait: Sized {} | ----- ^^^^^ ...because it requires `Self: Sized` | | | this trait cannot be made into an object... + = help: only type `S` implements the trait, consider using it directly instead = note: required for the cast from `&S` to `&dyn Trait` error[E0038]: the trait `Trait` cannot be made into an object @@ -41,6 +43,7 @@ LL | trait Trait: Sized {} | ----- ^^^^^ ...because it requires `Self: Sized` | | | this trait cannot be made into an object... + = help: only type `S` implements the trait, consider using it directly instead = note: required for the cast from `&S` to `&dyn Trait` error: aborting due to 3 previous errors diff --git a/tests/ui/wf/wf-unsafe-trait-obj-match.stderr b/tests/ui/wf/wf-unsafe-trait-obj-match.stderr index d5b23572ff5..a0279774abe 100644 --- a/tests/ui/wf/wf-unsafe-trait-obj-match.stderr +++ b/tests/ui/wf/wf-unsafe-trait-obj-match.stderr @@ -29,6 +29,9 @@ LL | trait Trait: Sized {} | ----- ^^^^^ ...because it requires `Self: Sized` | | | this trait cannot be made into an object... + = help: the following types implement the trait, consider defining an enum where each variant holds one of these types, implementing `Trait` for this new enum and using it instead: + S + R = note: required for the cast from `&S` to `&dyn Trait` error[E0038]: the trait `Trait` cannot be made into an object @@ -48,6 +51,9 @@ LL | trait Trait: Sized {} | ----- ^^^^^ ...because it requires `Self: Sized` | | | this trait cannot be made into an object... + = help: the following types implement the trait, consider defining an enum where each variant holds one of these types, implementing `Trait` for this new enum and using it instead: + S + R = note: required for the cast from `&R` to `&dyn Trait` error: aborting due to 3 previous errors