@@ -41,8 +41,8 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
4141 else {
4242 return ;
4343 } ;
44- let Some ( sugg) = self . generics_suggestion ( generics, self_ty. span , & impl_trait_name)
45- else {
44+ let sugg = self . add_generic_param_suggestion ( generics, self_ty. span , & impl_trait_name) ;
45+ if sugg . is_empty ( ) {
4646 return ;
4747 } ;
4848 diag. multipart_suggestion (
@@ -56,12 +56,12 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
5656 }
5757 }
5858
59- fn generics_suggestion (
59+ fn add_generic_param_suggestion (
6060 & self ,
6161 generics : & hir:: Generics < ' _ > ,
6262 self_ty_span : Span ,
6363 impl_trait_name : & str ,
64- ) -> Option < Vec < ( Span , String ) > > {
64+ ) -> Vec < ( Span , String ) > {
6565 // check if the trait has generics, to make a correct suggestion
6666 let param_name = generics. params . next_type_param_name ( None ) ;
6767
@@ -70,7 +70,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
7070 } else {
7171 ( generics. span , format ! ( "<{param_name}: {impl_trait_name}>" ) )
7272 } ;
73- Some ( vec ! [ ( self_ty_span, param_name) , add_generic_sugg] )
73+ vec ! [ ( self_ty_span, param_name) , add_generic_sugg]
7474 }
7575
7676 /// Make sure that we are in the condition to suggest `impl Trait`.
@@ -86,7 +86,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
8686 else {
8787 return false ;
8888 } ;
89- let Ok ( trait_name) = self . tcx ( ) . sess . source_map ( ) . span_to_snippet ( self_ty. span ) else {
89+ let Ok ( trait_name) = tcx. sess . source_map ( ) . span_to_snippet ( self_ty. span ) else {
9090 return false ;
9191 } ;
9292 let impl_sugg = vec ! [ ( self_ty. span. shrink_to_lo( ) , "impl " . to_string( ) ) ] ;
@@ -98,19 +98,22 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
9898 impl_sugg,
9999 Applicability :: MachineApplicable ,
100100 ) ;
101- diag. multipart_suggestion_verbose (
102- "alternatively, you can return an owned trait object" ,
103- vec ! [
104- ( ty. span. shrink_to_lo( ) , "Box<dyn " . to_string( ) ) ,
105- ( ty. span. shrink_to_hi( ) , ">" . to_string( ) ) ,
106- ] ,
107- Applicability :: MachineApplicable ,
108- ) ;
101+ if tcx. check_is_object_safe ( def_id) {
102+ diag. multipart_suggestion_verbose (
103+ "alternatively, you can return an owned trait object" ,
104+ vec ! [
105+ ( ty. span. shrink_to_lo( ) , "Box<dyn " . to_string( ) ) ,
106+ ( ty. span. shrink_to_hi( ) , ">" . to_string( ) ) ,
107+ ] ,
108+ Applicability :: MachineApplicable ,
109+ ) ;
110+ }
109111 return true ;
110112 }
111113 for ty in sig. decl . inputs {
112114 if ty. hir_id == self_ty. hir_id {
113- if let Some ( sugg) = self . generics_suggestion ( generics, self_ty. span , & trait_name) {
115+ let sugg = self . add_generic_param_suggestion ( generics, self_ty. span , & trait_name) ;
116+ if !sugg. is_empty ( ) {
114117 diag. multipart_suggestion_verbose (
115118 format ! ( "use a new generic type parameter, constrained by `{trait_name}`" ) ,
116119 sugg,
@@ -124,6 +127,9 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
124127 Applicability :: MachineApplicable ,
125128 ) ;
126129 }
130+ if !tcx. check_is_object_safe ( def_id) {
131+ diag. note ( format ! ( "it is not object safe, so it can't be `dyn`" ) ) ;
132+ }
127133 let sugg = if let hir:: TyKind :: TraitObject ( [ _, _, ..] , _, _) = self_ty. kind {
128134 // There are more than one trait bound, we need surrounding parentheses.
129135 vec ! [
0 commit comments