@@ -9,8 +9,83 @@ use rustc_trait_selection::traits::error_reporting::suggestions::NextTypeParamNa
9
9
use super :: HirTyLowerer ;
10
10
11
11
impl < ' tcx > dyn HirTyLowerer < ' tcx > + ' _ {
12
+ /// Prohibit or lint against *bare* trait object types depending on the edition.
13
+ ///
14
+ /// *Bare* trait object types are ones that aren't preceeded by the keyword `dyn`.
15
+ /// In edition 2021 and onward we emit a hard error for them.
16
+ pub ( super ) fn prohibit_or_lint_bare_trait_object_ty (
17
+ & self ,
18
+ self_ty : & hir:: Ty < ' _ > ,
19
+ in_path : bool ,
20
+ ) {
21
+ let tcx = self . tcx ( ) ;
22
+
23
+ let hir:: TyKind :: TraitObject ( [ poly_trait_ref, ..] , _, TraitObjectSyntax :: None ) =
24
+ self_ty. kind
25
+ else {
26
+ return ;
27
+ } ;
28
+
29
+ let needs_bracket = in_path
30
+ && !tcx
31
+ . sess
32
+ . source_map ( )
33
+ . span_to_prev_source ( self_ty. span )
34
+ . ok ( )
35
+ . is_some_and ( |s| s. trim_end ( ) . ends_with ( '<' ) ) ;
36
+
37
+ let is_global = poly_trait_ref. trait_ref . path . is_global ( ) ;
38
+
39
+ let mut sugg = vec ! [ (
40
+ self_ty. span. shrink_to_lo( ) ,
41
+ format!(
42
+ "{}dyn {}" ,
43
+ if needs_bracket { "<" } else { "" } ,
44
+ if is_global { "(" } else { "" } ,
45
+ ) ,
46
+ ) ] ;
47
+
48
+ if is_global || needs_bracket {
49
+ sugg. push ( (
50
+ self_ty. span . shrink_to_hi ( ) ,
51
+ format ! (
52
+ "{}{}" ,
53
+ if is_global { ")" } else { "" } ,
54
+ if needs_bracket { ">" } else { "" } ,
55
+ ) ,
56
+ ) ) ;
57
+ }
58
+
59
+ if self_ty. span . edition ( ) . at_least_rust_2021 ( ) {
60
+ let msg = "trait objects must include the `dyn` keyword" ;
61
+ let label = "add `dyn` keyword before this trait" ;
62
+ let mut diag =
63
+ rustc_errors:: struct_span_code_err!( tcx. dcx( ) , self_ty. span, E0782 , "{}" , msg) ;
64
+ if self_ty. span . can_be_used_for_suggestions ( )
65
+ && !self . maybe_suggest_impl_trait ( self_ty, & mut diag)
66
+ {
67
+ diag. multipart_suggestion_verbose ( label, sugg, Applicability :: MachineApplicable ) ;
68
+ }
69
+ // Check if the impl trait that we are considering is an impl of a local trait.
70
+ self . maybe_suggest_blanket_trait_impl ( self_ty, & mut diag) ;
71
+ diag. stash ( self_ty. span , StashKey :: TraitMissingMethod ) ;
72
+ } else {
73
+ let msg = "trait objects without an explicit `dyn` are deprecated" ;
74
+ tcx. node_span_lint ( BARE_TRAIT_OBJECTS , self_ty. hir_id , self_ty. span , msg, |lint| {
75
+ if self_ty. span . can_be_used_for_suggestions ( ) {
76
+ lint. multipart_suggestion_verbose (
77
+ "if this is an object-safe trait, use `dyn`" ,
78
+ sugg,
79
+ Applicability :: MachineApplicable ,
80
+ ) ;
81
+ }
82
+ self . maybe_suggest_blanket_trait_impl ( self_ty, lint) ;
83
+ } ) ;
84
+ }
85
+ }
86
+
12
87
/// Make sure that we are in the condition to suggest the blanket implementation.
13
- pub ( super ) fn maybe_lint_blanket_trait_impl < G : EmissionGuarantee > (
88
+ fn maybe_suggest_blanket_trait_impl < G : EmissionGuarantee > (
14
89
& self ,
15
90
self_ty : & hir:: Ty < ' _ > ,
16
91
diag : & mut Diag < ' _ , G > ,
@@ -75,7 +150,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
75
150
}
76
151
77
152
/// Make sure that we are in the condition to suggest `impl Trait`.
78
- fn maybe_lint_impl_trait ( & self , self_ty : & hir:: Ty < ' _ > , diag : & mut Diag < ' _ > ) -> bool {
153
+ fn maybe_suggest_impl_trait ( & self , self_ty : & hir:: Ty < ' _ > , diag : & mut Diag < ' _ > ) -> bool {
79
154
let tcx = self . tcx ( ) ;
80
155
let parent_id = tcx. hir ( ) . get_parent_item ( self_ty. hir_id ) . def_id ;
81
156
let ( sig, generics, owner) = match tcx. hir_node_by_def_id ( parent_id) {
@@ -185,72 +260,4 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
185
260
}
186
261
false
187
262
}
188
-
189
- pub ( super ) fn maybe_lint_bare_trait ( & self , self_ty : & hir:: Ty < ' _ > , in_path : bool ) {
190
- let tcx = self . tcx ( ) ;
191
- if let hir:: TyKind :: TraitObject ( [ poly_trait_ref, ..] , _, TraitObjectSyntax :: None ) =
192
- self_ty. kind
193
- {
194
- let needs_bracket = in_path
195
- && !tcx
196
- . sess
197
- . source_map ( )
198
- . span_to_prev_source ( self_ty. span )
199
- . ok ( )
200
- . is_some_and ( |s| s. trim_end ( ) . ends_with ( '<' ) ) ;
201
-
202
- let is_global = poly_trait_ref. trait_ref . path . is_global ( ) ;
203
-
204
- let mut sugg = Vec :: from_iter ( [ (
205
- self_ty. span . shrink_to_lo ( ) ,
206
- format ! (
207
- "{}dyn {}" ,
208
- if needs_bracket { "<" } else { "" } ,
209
- if is_global { "(" } else { "" } ,
210
- ) ,
211
- ) ] ) ;
212
-
213
- if is_global || needs_bracket {
214
- sugg. push ( (
215
- self_ty. span . shrink_to_hi ( ) ,
216
- format ! (
217
- "{}{}" ,
218
- if is_global { ")" } else { "" } ,
219
- if needs_bracket { ">" } else { "" } ,
220
- ) ,
221
- ) ) ;
222
- }
223
-
224
- if self_ty. span . edition ( ) . at_least_rust_2021 ( ) {
225
- let msg = "trait objects must include the `dyn` keyword" ;
226
- let label = "add `dyn` keyword before this trait" ;
227
- let mut diag =
228
- rustc_errors:: struct_span_code_err!( tcx. dcx( ) , self_ty. span, E0782 , "{}" , msg) ;
229
- if self_ty. span . can_be_used_for_suggestions ( )
230
- && !self . maybe_lint_impl_trait ( self_ty, & mut diag)
231
- {
232
- diag. multipart_suggestion_verbose (
233
- label,
234
- sugg,
235
- Applicability :: MachineApplicable ,
236
- ) ;
237
- }
238
- // check if the impl trait that we are considering is a impl of a local trait
239
- self . maybe_lint_blanket_trait_impl ( self_ty, & mut diag) ;
240
- diag. stash ( self_ty. span , StashKey :: TraitMissingMethod ) ;
241
- } else {
242
- let msg = "trait objects without an explicit `dyn` are deprecated" ;
243
- tcx. node_span_lint ( BARE_TRAIT_OBJECTS , self_ty. hir_id , self_ty. span , msg, |lint| {
244
- if self_ty. span . can_be_used_for_suggestions ( ) {
245
- lint. multipart_suggestion_verbose (
246
- "if this is an object-safe trait, use `dyn`" ,
247
- sugg,
248
- Applicability :: MachineApplicable ,
249
- ) ;
250
- }
251
- self . maybe_lint_blanket_trait_impl ( self_ty, lint) ;
252
- } ) ;
253
- }
254
- }
255
- }
256
263
}
0 commit comments