@@ -20,9 +20,10 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
20
20
) -> Option < ErrorGuaranteed > {
21
21
let tcx = self . tcx ( ) ;
22
22
23
- let hir:: TyKind :: TraitObject ( [ poly_trait_ref, ..] , _, TraitObjectSyntax :: None ) =
24
- self_ty. kind
25
- else {
23
+ let hir:: TyKind :: TraitObject ( traits, _, TraitObjectSyntax :: None ) = self_ty. kind else {
24
+ return None ;
25
+ } ;
26
+ let [ poly_trait_ref, ..] = traits else {
26
27
return None ;
27
28
} ;
28
29
@@ -36,6 +37,11 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
36
37
37
38
let is_global = poly_trait_ref. trait_ref . path . is_global ( ) ;
38
39
40
+ let object_safe = traits. iter ( ) . all ( |ptr| match ptr. trait_ref . path . res {
41
+ Res :: Def ( DefKind :: Trait , def_id) => tcx. object_safety_violations ( def_id) . is_empty ( ) ,
42
+ _ => false ,
43
+ } ) ;
44
+
39
45
let mut sugg = vec ! [ (
40
46
self_ty. span. shrink_to_lo( ) ,
41
47
format!(
@@ -63,10 +69,9 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
63
69
rustc_errors:: struct_span_code_err!( tcx. dcx( ) , self_ty. span, E0782 , "{}" , msg) ;
64
70
let mut downgrade = false ;
65
71
if self_ty. span . can_be_used_for_suggestions ( ) {
66
- let ( non_object_safe, should_downgrade) =
67
- self . maybe_suggest_impl_trait ( self_ty, & mut diag) ;
72
+ let should_downgrade = self . maybe_suggest_impl_trait ( self_ty, & mut diag) ;
68
73
downgrade = should_downgrade;
69
- if !non_object_safe {
74
+ if object_safe {
70
75
// Only emit this suggestion if the trait is object safe.
71
76
diag. multipart_suggestion_verbose (
72
77
label,
@@ -89,12 +94,27 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
89
94
} else {
90
95
tcx. node_span_lint ( BARE_TRAIT_OBJECTS , self_ty. hir_id , self_ty. span , |lint| {
91
96
lint. primary_message ( "trait objects without an explicit `dyn` are deprecated" ) ;
92
- if self_ty. span . can_be_used_for_suggestions ( ) {
93
- lint. multipart_suggestion_verbose (
94
- "if this is an object-safe trait, use `dyn`" ,
95
- sugg,
96
- Applicability :: MachineApplicable ,
97
- ) ;
97
+ match ( object_safe, self_ty. span . can_be_used_for_suggestions ( ) ) {
98
+ ( true , true ) => {
99
+ lint. multipart_suggestion_verbose (
100
+ "as this is an \" object safe\" trait, write `dyn` in front of the \
101
+ trait",
102
+ sugg,
103
+ Applicability :: MachineApplicable ,
104
+ ) ;
105
+ }
106
+ ( true , false ) => {
107
+ lint. note (
108
+ "as this is an \" object safe\" trait, you can write `dyn` in front of \
109
+ the trait",
110
+ ) ;
111
+ }
112
+ ( false , _) => {
113
+ lint. note (
114
+ "you can't use write a trait object here because the trait isn't \
115
+ \" object safe\" ",
116
+ ) ;
117
+ }
98
118
}
99
119
self . maybe_suggest_blanket_trait_impl ( self_ty, lint) ;
100
120
} ) ;
@@ -170,7 +190,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
170
190
/// Make sure that we are in the condition to suggest `impl Trait`.
171
191
///
172
192
/// Returns whether a suggestion was provided and whether the error itself should not be emitted
173
- fn maybe_suggest_impl_trait ( & self , self_ty : & hir:: Ty < ' _ > , diag : & mut Diag < ' _ > ) -> ( bool , bool ) {
193
+ fn maybe_suggest_impl_trait ( & self , self_ty : & hir:: Ty < ' _ > , diag : & mut Diag < ' _ > ) -> bool {
174
194
let tcx = self . tcx ( ) ;
175
195
let parent_id = tcx. hir ( ) . get_parent_item ( self_ty. hir_id ) . def_id ;
176
196
// FIXME: If `type_alias_impl_trait` is enabled, also look for `Trait0<Ty = Trait1>`
@@ -185,10 +205,10 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
185
205
owner_id,
186
206
..
187
207
} ) => ( sig, generics, Some ( tcx. parent ( owner_id. to_def_id ( ) ) ) ) ,
188
- _ => return ( false , false ) ,
208
+ _ => return false ,
189
209
} ;
190
210
let Ok ( trait_name) = tcx. sess . source_map ( ) . span_to_snippet ( self_ty. span ) else {
191
- return ( false , false ) ;
211
+ return false ;
192
212
} ;
193
213
let impl_sugg = vec ! [ ( self_ty. span. shrink_to_lo( ) , "impl " . to_string( ) ) ] ;
194
214
let mut is_downgradable = true ;
@@ -201,7 +221,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
201
221
// For recursive traits, don't downgrade the error. (#119652)
202
222
is_downgradable = false ;
203
223
}
204
- tcx. check_is_object_safe ( id)
224
+ tcx. object_safety_violations ( id) . is_empty ( )
205
225
}
206
226
_ => false ,
207
227
} )
@@ -234,7 +254,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
234
254
// We'll emit the object safety error already, with a structured suggestion.
235
255
downgrade = true ;
236
256
}
237
- return ( true , downgrade) ;
257
+ return downgrade;
238
258
}
239
259
for ty in sig. decl . inputs {
240
260
if ty. hir_id != self_ty. hir_id {
@@ -279,9 +299,9 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
279
299
Applicability :: MachineApplicable ,
280
300
) ;
281
301
}
282
- return ( true , downgrade) ;
302
+ return downgrade;
283
303
}
284
- ( false , downgrade)
304
+ downgrade
285
305
}
286
306
287
307
fn maybe_suggest_assoc_ty_bound ( & self , self_ty : & hir:: Ty < ' _ > , diag : & mut Diag < ' _ > ) {
0 commit comments