@@ -41,8 +41,8 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
41
41
else {
42
42
return ;
43
43
} ;
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 ( ) {
46
46
return ;
47
47
} ;
48
48
diag. multipart_suggestion (
@@ -56,12 +56,12 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
56
56
}
57
57
}
58
58
59
- fn generics_suggestion (
59
+ fn add_generic_param_suggestion (
60
60
& self ,
61
61
generics : & hir:: Generics < ' _ > ,
62
62
self_ty_span : Span ,
63
63
impl_trait_name : & str ,
64
- ) -> Option < Vec < ( Span , String ) > > {
64
+ ) -> Vec < ( Span , String ) > {
65
65
// check if the trait has generics, to make a correct suggestion
66
66
let param_name = generics. params . next_type_param_name ( None ) ;
67
67
@@ -70,7 +70,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
70
70
} else {
71
71
( generics. span , format ! ( "<{param_name}: {impl_trait_name}>" ) )
72
72
} ;
73
- Some ( vec ! [ ( self_ty_span, param_name) , add_generic_sugg] )
73
+ vec ! [ ( self_ty_span, param_name) , add_generic_sugg]
74
74
}
75
75
76
76
/// Make sure that we are in the condition to suggest `impl Trait`.
@@ -86,7 +86,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
86
86
else {
87
87
return false ;
88
88
} ;
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 {
90
90
return false ;
91
91
} ;
92
92
let impl_sugg = vec ! [ ( self_ty. span. shrink_to_lo( ) , "impl " . to_string( ) ) ] ;
@@ -98,19 +98,22 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
98
98
impl_sugg,
99
99
Applicability :: MachineApplicable ,
100
100
) ;
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
+ }
109
111
return true ;
110
112
}
111
113
for ty in sig. decl . inputs {
112
114
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 ( ) {
114
117
diag. multipart_suggestion_verbose (
115
118
format ! ( "use a new generic type parameter, constrained by `{trait_name}`" ) ,
116
119
sugg,
@@ -124,6 +127,9 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
124
127
Applicability :: MachineApplicable ,
125
128
) ;
126
129
}
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
+ }
127
133
let sugg = if let hir:: TyKind :: TraitObject ( [ _, _, ..] , _, _) = self_ty. kind {
128
134
// There are more than one trait bound, we need surrounding parentheses.
129
135
vec ! [
0 commit comments