Change:
One of the big problems with the 2015-style trait object syntax (no ) was that users often write things like when what they really meant was . Back then, the error message would more often than not be some inscrutable message about , which would send them on a wild goose chase of adding bounds everywhere they could think of, leading to even more inscrutable messages. Now, the error message is clearer: it tells users they need to add for a trait object type. However, I find in many cases (most cases?) this is not what users actually want - what they actually want is the blanket impl. It would be helpful to have a note suggesting the correct syntax for a blanket impl, or better yet just presenting both correct syntaxes (impl for trait object and blanket impl) on equal footing and making it clear the difference between them. <!-- TRIAGEBOTSTART --<!-- TRIAGEBOTASSIGNSTART --<!-- TRIAGEBOTASSIGNDATASTARTTRIAGEBOTASSIGNDATAEND --<!-- TRIAGEBOTASSIGNEND --<!-- TRIAGEBOTEND --
claim
I work to reproduce this issue and start to understand what type of check we need to do, and in particular the work that we need to do is the following one: If the traits are local traits we can perform the suggestion of the blanket impls, for example in the following code But we need to skip the following suggestion in case we are using not local traits, like the following code here

Discussion:
use rustc_target::spec::abi; use rustc_trait_selection::traits; use rustc_trait_selection::traits::astconv_object_safety_violations; <del> use rustc_trait_selection::traits::error_reporting::report_object_safety_error; </del> <ins> use rustc_trait_selection::traits::error_reporting::{ report_object_safety_error, suggestions::NextTypeParamName, }; </ins> use rustc_trait_selection::traits::wf::object_region_bounds; use smallvec::SmallVec;

Some(r) } <ins> /// Make sure that we are in the condition to suggest the blanket implementation. fn maybe_lint_blanket_trait_impl<T: rustc_errors::EmissionGuarantee>( &self, self_ty: &hir::Ty<'_>, diag: &mut DiagnosticBuilder<'_, T>, ) { let tcx = self.tcx(); let parent_id = tcx.hir().get_parent_item(self_ty.hir_id); if let hir::Node::Item(hir::Item { kind: hir::ItemKind::Impl(hir::Impl { self_ty: impl_self_ty, of_trait: Some(of_trait_ref), generics, .. }), .. }) = tcx.hir().get_by_def_id(parent_id) && self_ty.hir_id == impl_self_ty.hir_id { if !of_trait_ref.trait_def_id().map_or(false, |def_id| def_id.is_local()) { return; } let of_trait_span = of_trait_ref.path.span; // make sure that we are not calling unwrap to abort during the compilation let Ok(impl_trait_name) = tcx.sess.source_map().span_to_snippet(self_ty.span) else { return; }; let Ok(of_trait_name) = tcx.sess.source_map().span_to_snippet(of_trait_span) else { return; }; // check if the trait has generics, to make a correct suggestion let param_name = generics.params.next_type_param_name(None); let add_generic_sugg = if let Some(span) = generics.span_for_param_suggestion() { (span, format!(", {}: {}", param_name, impl_trait_name)) } else { (generics.span, format!("<{}: {}>", param_name, impl_trait_name)) }; diag.multipart_suggestion( format!("alternatively use a blanket  implementation to implement `{of_trait_name}` for  all types that also implement `{impl_trait_name}`"), vec![ (self_ty.span, param_name), add_generic_sugg, ], Applicability::MaybeIncorrect, ); } } </ins> fn maybe_lint_bare_trait(&self, self_ty: &hir::Ty<'_>, in_path: bool) { let tcx = self.tcx(); if let hir::TyKind::TraitObject([poly_trait_ref, ..], _, TraitObjectSyntax::None) =

if self_ty.span.edition() >= Edition::Edition2021 { let msg = "trait objects must include the `dyn` keyword"; let label = "add `dyn` keyword before this trait"; <del> rustc_errors::struct_span_err!(tcx.sess, self_ty.span, E0782, "{}", msg) .multipart_suggestion_verbose(label, sugg, Applicability::MachineApplicable) .emit(); </del> <ins> let mut diag = rustc_errors::struct_span_err!(tcx.sess, self_ty.span, E0782, "{}", msg); diag.multipart_suggestion_verbose(label, sugg, Applicability::MachineApplicable); // check if the impl trait that we are considering is a impl of a local trait self.maybe_lint_blanket_trait_impl(&self_ty, &mut diag); diag.emit(); </ins> } else { let msg = "trait objects without an explicit `dyn` are deprecated"; tcx.struct_span_lint_hir(

self_ty.hir_id, self_ty.span, |lint| { <del> lint.build(msg) .multipart_suggestion_verbose( "use `dyn`", sugg, Applicability::MachineApplicable, ) .emit(); </del> <ins> let mut diag = lint.build(msg); diag.multipart_suggestion_verbose( "use `dyn`", sugg, Applicability::MachineApplicable, ); self.maybe_lint_blanket_trait_impl::<()>(&self_ty, &mut diag); diag.emit(); </ins> }, ); }

<ins> // Ensure that the compiler include the blanklet implementation suggestion // when inside a `impl` statment are used two local traits. // // edition:2021 use std::fmt; trait LocalTraitOne { } trait LocalTraitTwo { } trait GenericTrait<T> {} impl LocalTraitTwo for LocalTraitOne {} //~^ ERROR trait objects must include the `dyn` keyword //~| HELP add `dyn` keyword before this trait //~| HELP alternatively use a blanket implementation to implement `LocalTraitTwo` for all types that also implement `LocalTraitOne` impl fmt::Display for LocalTraitOne { //~^ ERROR trait objects must include the `dyn` keyword //~| HELP add `dyn` keyword before this trait fn fmt(&self, _f: &mut fmt::Formatter<'_>) -> fmt::Result { todo!(); } } impl fmt::Display for LocalTraitTwo + Send { //~^ ERROR trait objects must include the `dyn` keyword //~| HELP add `dyn` keyword before this trait fn fmt(&self, _f: &mut fmt::Formatter<'_>) -> fmt::Result { todo!(); } } impl LocalTraitOne for fmt::Display {} //~^ ERROR trait objects must include the `dyn` keyword //~| HELP add `dyn` keyword before this trait //~| HELP alternatively use a blanket implementation to implement `LocalTraitOne` for all types that also implement `fmt::Display` impl LocalTraitOne for fmt::Display + Send {} //~^ ERROR trait objects must include the `dyn` keyword //~| HELP add `dyn` keyword before this trait //~| HELP alternatively use a blanket implementation to implement `LocalTraitOne` for all types that also implement `fmt::Display + Send` impl<E> GenericTrait<E> for LocalTraitOne {} //~^ ERROR trait objects must include the `dyn` keyword //~| HELP add `dyn` keyword before this trait //~| HELP alternatively use a blanket implementation to implement `GenericTrait<E>` for all types that also implement `LocalTraitOne` trait GenericTraitTwo<T> {} impl<T, E> GenericTraitTwo<E> for GenericTrait<T> {} //~^ ERROR trait objects must include the `dyn` keyword //~| HELP add `dyn` keyword before this trait //~| HELP alternatively use a blanket implementation to implement `GenericTraitTwo<E>` for all types that also implement `GenericTrait<T>` fn main() {} </ins>

<ins> error[E0782]: trait objects must include the `dyn` keyword --> $DIR/suggest-blanket-impl-local-trait.rs:13:24 | LL | impl LocalTraitTwo for LocalTraitOne {} |                        ^^^^^^^^^^^^^ | help: add `dyn` keyword before this trait | LL - impl LocalTraitTwo for LocalTraitOne {} LL + impl LocalTraitTwo for dyn LocalTraitOne {} | help: alternatively use a blanket implementation to implement `LocalTraitTwo` for all types that also implement `LocalTraitOne` | LL | impl<T: LocalTraitOne> LocalTraitTwo for T {} |     ++++++++++++++++++                   ~ error[E0782]: trait objects must include the `dyn` keyword --> $DIR/suggest-blanket-impl-local-trait.rs:18:23 | LL | impl fmt::Display for LocalTraitOne { |                       ^^^^^^^^^^^^^ | help: add `dyn` keyword before this trait | LL - impl fmt::Display for LocalTraitOne { LL + impl fmt::Display for dyn LocalTraitOne { | error[E0782]: trait objects must include the `dyn` keyword --> $DIR/suggest-blanket-impl-local-trait.rs:26:23 | LL | impl fmt::Display for LocalTraitTwo + Send { |                       ^^^^^^^^^^^^^^^^^^^^ | help: add `dyn` keyword before this trait | LL - impl fmt::Display for LocalTraitTwo + Send { LL + impl fmt::Display for dyn LocalTraitTwo + Send { | error[E0782]: trait objects must include the `dyn` keyword --> $DIR/suggest-blanket-impl-local-trait.rs:34:24 | LL | impl LocalTraitOne for fmt::Display {} |                        ^^^^^^^^^^^^ | help: add `dyn` keyword before this trait | LL - impl LocalTraitOne for fmt::Display {} LL + impl LocalTraitOne for dyn fmt::Display {} | help: alternatively use a blanket implementation to implement `LocalTraitOne` for all types that also implement `fmt::Display` | LL | impl<T: fmt::Display> LocalTraitOne for T {} |     +++++++++++++++++                   ~ error[E0782]: trait objects must include the `dyn` keyword --> $DIR/suggest-blanket-impl-local-trait.rs:40:24 | LL | impl LocalTraitOne for fmt::Display + Send {} |                        ^^^^^^^^^^^^^^^^^^^ | help: add `dyn` keyword before this trait | LL - impl LocalTraitOne for fmt::Display + Send {} LL + impl LocalTraitOne for dyn fmt::Display + Send {} | help: alternatively use a blanket implementation to implement `LocalTraitOne` for all types that also implement `fmt::Display + Send` | LL | impl<T: fmt::Display + Send> LocalTraitOne for T {} |     ++++++++++++++++++++++++                   ~ error[E0782]: trait objects must include the `dyn` keyword --> $DIR/suggest-blanket-impl-local-trait.rs:46:29 | LL | impl<E> GenericTrait<E> for LocalTraitOne {} |                             ^^^^^^^^^^^^^ | help: add `dyn` keyword before this trait | LL - impl<E> GenericTrait<E> for LocalTraitOne {} LL + impl<E> GenericTrait<E> for dyn LocalTraitOne {} | help: alternatively use a blanket implementation to implement `GenericTrait<E>` for all types that also implement `LocalTraitOne` | LL | impl<E, T: LocalTraitOne> GenericTrait<E> for T {} |       ++++++++++++++++++                      ~ error[E0782]: trait objects must include the `dyn` keyword --> $DIR/suggest-blanket-impl-local-trait.rs:53:35 | LL | impl<T, E> GenericTraitTwo<E> for GenericTrait<T> {} |                                   ^^^^^^^^^^^^^^^ | help: add `dyn` keyword before this trait | LL - impl<T, E> GenericTraitTwo<E> for GenericTrait<T> {} LL + impl<T, E> GenericTraitTwo<E> for dyn GenericTrait<T> {} | help: alternatively use a blanket implementation to implement `GenericTraitTwo<E>` for all types that also implement `GenericTrait<T>` | LL | impl<T, E, U: GenericTrait<T>> GenericTraitTwo<E> for U {} |          ++++++++++++++++++++                         ~ error: aborting due to 7 previous errors For more information about this error, try `rustc --explain E0782`. </ins>