@@ -9,14 +9,14 @@ use rustc_attr::{
9
9
self as attr, ConstStability , DefaultBodyStability , DeprecatedSince , Deprecation , Stability ,
10
10
} ;
11
11
use rustc_data_structures:: unord:: UnordMap ;
12
- use rustc_errors:: { Applicability , Diag } ;
12
+ use rustc_errors:: { Applicability , Diag , EmissionGuarantee } ;
13
13
use rustc_feature:: GateIssue ;
14
14
use rustc_hir:: def:: DefKind ;
15
15
use rustc_hir:: def_id:: { DefId , LocalDefId , LocalDefIdMap } ;
16
16
use rustc_hir:: { self as hir, HirId } ;
17
17
use rustc_middle:: ty:: print:: with_no_trimmed_paths;
18
18
use rustc_session:: lint:: builtin:: { DEPRECATED , DEPRECATED_IN_FUTURE , SOFT_UNSTABLE } ;
19
- use rustc_session:: lint:: { BuiltinLintDiag , Level , Lint , LintBuffer } ;
19
+ use rustc_session:: lint:: { BuiltinLintDiag , DeprecatedSinceKind , Level , Lint , LintBuffer } ;
20
20
use rustc_session:: parse:: feature_err_issue;
21
21
use rustc_session:: Session ;
22
22
use rustc_span:: symbol:: { sym, Symbol } ;
@@ -124,90 +124,114 @@ pub fn report_unstable(
124
124
}
125
125
}
126
126
127
- pub fn deprecation_suggestion (
128
- diag : & mut Diag < ' _ , ( ) > ,
129
- kind : & str ,
130
- suggestion : Option < Symbol > ,
131
- span : Span ,
132
- ) {
133
- if let Some ( suggestion) = suggestion {
134
- diag. span_suggestion_verbose (
135
- span,
136
- format ! ( "replace the use of the deprecated {kind}" ) ,
137
- suggestion,
138
- Applicability :: MachineApplicable ,
139
- ) ;
127
+ fn deprecation_lint ( is_in_effect : bool ) -> & ' static Lint {
128
+ if is_in_effect { DEPRECATED } else { DEPRECATED_IN_FUTURE }
129
+ }
130
+
131
+ #[ derive( Subdiagnostic ) ]
132
+ #[ suggestion(
133
+ middle_deprecated_suggestion,
134
+ code = "{suggestion}" ,
135
+ style = "verbose" ,
136
+ applicability = "machine-applicable"
137
+ ) ]
138
+ pub struct DeprecationSuggestion {
139
+ #[ primary_span]
140
+ pub span : Span ,
141
+
142
+ pub kind : String ,
143
+ pub suggestion : Symbol ,
144
+ }
145
+
146
+ pub struct Deprecated {
147
+ pub sub : Option < DeprecationSuggestion > ,
148
+
149
+ // FIXME: make this translatable
150
+ pub kind : String ,
151
+ pub path : String ,
152
+ pub note : Option < Symbol > ,
153
+ pub since_kind : DeprecatedSinceKind ,
154
+ }
155
+
156
+ impl Deprecated {
157
+ // FIXME: remove
158
+ pub fn msg_for_since_kind ( since_kind : & DeprecatedSinceKind ) -> rustc_errors:: DiagMessage {
159
+ match since_kind {
160
+ DeprecatedSinceKind :: InEffect => crate :: fluent_generated:: middle_deprecated,
161
+ DeprecatedSinceKind :: InFuture => crate :: fluent_generated:: middle_deprecated_in_future,
162
+ DeprecatedSinceKind :: InVersion ( _) => {
163
+ crate :: fluent_generated:: middle_deprecated_in_version
164
+ }
165
+ }
140
166
}
141
167
}
142
168
143
- fn deprecation_lint ( is_in_effect : bool ) -> & ' static Lint {
144
- if is_in_effect { DEPRECATED } else { DEPRECATED_IN_FUTURE }
169
+ impl < ' a , G : EmissionGuarantee > rustc_errors:: LintDiagnostic < ' a , G > for Deprecated {
170
+ fn decorate_lint < ' b > ( self , diag : & ' b mut Diag < ' a , G > ) {
171
+ diag. arg ( "kind" , self . kind ) ;
172
+ diag. arg ( "path" , self . path ) ;
173
+ if let DeprecatedSinceKind :: InVersion ( version) = self . since_kind {
174
+ diag. arg ( "version" , version) ;
175
+ }
176
+ if let Some ( note) = self . note {
177
+ diag. arg ( "has_note" , true ) ;
178
+ diag. arg ( "note" , note) ;
179
+ } else {
180
+ diag. arg ( "has_note" , false ) ;
181
+ }
182
+ if let Some ( sub) = self . sub {
183
+ diag. subdiagnostic ( diag. dcx , sub) ;
184
+ }
185
+ }
186
+
187
+ fn msg ( & self ) -> rustc_errors:: DiagMessage {
188
+ Self :: msg_for_since_kind ( & self . since_kind )
189
+ }
145
190
}
146
191
147
- fn deprecation_message (
148
- is_in_effect : bool ,
149
- since : DeprecatedSince ,
150
- note : Option < Symbol > ,
151
- kind : & str ,
152
- path : & str ,
153
- ) -> String {
154
- let message = if is_in_effect {
155
- format ! ( "use of deprecated {kind} `{path}`" )
192
+ fn deprecated_since_kind ( is_in_effect : bool , since : DeprecatedSince ) -> DeprecatedSinceKind {
193
+ if is_in_effect {
194
+ DeprecatedSinceKind :: InEffect
156
195
} else {
157
196
match since {
158
- DeprecatedSince :: RustcVersion ( version) => format ! (
159
- "use of {kind} `{path}` that will be deprecated in future version {version}"
160
- ) ,
161
- DeprecatedSince :: Future => {
162
- format ! ( "use of {kind} `{path}` that will be deprecated in a future Rust version" )
197
+ DeprecatedSince :: RustcVersion ( version) => {
198
+ DeprecatedSinceKind :: InVersion ( version. to_string ( ) )
163
199
}
200
+ DeprecatedSince :: Future => DeprecatedSinceKind :: InFuture ,
164
201
DeprecatedSince :: NonStandard ( _)
165
202
| DeprecatedSince :: Unspecified
166
203
| DeprecatedSince :: Err => {
167
204
unreachable ! ( "this deprecation is always in effect; {since:?}" )
168
205
}
169
206
}
170
- } ;
171
-
172
- match note {
173
- Some ( reason) => format ! ( "{message}: {reason}" ) ,
174
- None => message,
175
207
}
176
208
}
177
209
178
- pub fn deprecation_message_and_lint (
179
- depr : & Deprecation ,
180
- kind : & str ,
181
- path : & str ,
182
- ) -> ( String , & ' static Lint ) {
183
- let is_in_effect = depr. is_in_effect ( ) ;
184
- (
185
- deprecation_message ( is_in_effect, depr. since , depr. note , kind, path) ,
186
- deprecation_lint ( is_in_effect) ,
187
- )
188
- }
189
-
190
- pub fn early_report_deprecation (
210
+ pub fn early_report_macro_deprecation (
191
211
lint_buffer : & mut LintBuffer ,
192
- message : String ,
193
- suggestion : Option < Symbol > ,
194
- lint : & ' static Lint ,
212
+ depr : & Deprecation ,
195
213
span : Span ,
196
214
node_id : NodeId ,
215
+ path : String ,
197
216
) {
198
217
if span. in_derive_expansion ( ) {
199
218
return ;
200
219
}
201
220
202
- let diag = BuiltinLintDiag :: DeprecatedMacro { suggestion, span, message } ;
203
- lint_buffer. buffer_lint_with_diagnostic ( lint, node_id, span, diag) ;
221
+ let is_in_effect = depr. is_in_effect ( ) ;
222
+ let diag = BuiltinLintDiag :: DeprecatedMacro {
223
+ suggestion : depr. suggestion ,
224
+ suggestion_span : span,
225
+ note : depr. note ,
226
+ path,
227
+ since_kind : deprecated_since_kind ( is_in_effect, depr. since . clone ( ) ) ,
228
+ } ;
229
+ lint_buffer. buffer_lint_with_diagnostic ( deprecation_lint ( is_in_effect) , node_id, span, diag) ;
204
230
}
205
231
206
232
fn late_report_deprecation (
207
233
tcx : TyCtxt < ' _ > ,
208
- message : String ,
209
- suggestion : Option < Symbol > ,
210
- lint : & ' static Lint ,
234
+ depr : & Deprecation ,
211
235
span : Span ,
212
236
method_span : Option < Span > ,
213
237
hir_id : HirId ,
@@ -216,13 +240,26 @@ fn late_report_deprecation(
216
240
if span. in_derive_expansion ( ) {
217
241
return ;
218
242
}
243
+
244
+ let def_path = with_no_trimmed_paths ! ( tcx. def_path_str( def_id) ) ;
245
+ let def_kind = tcx. def_descr ( def_id) ;
246
+ let is_in_effect = depr. is_in_effect ( ) ;
247
+
219
248
let method_span = method_span. unwrap_or ( span) ;
220
- tcx. node_span_lint ( lint, hir_id, method_span, message, |diag| {
221
- if let hir:: Node :: Expr ( _) = tcx. hir_node ( hir_id) {
222
- let kind = tcx. def_descr ( def_id) ;
223
- deprecation_suggestion ( diag, kind, suggestion, method_span) ;
224
- }
225
- } ) ;
249
+ let suggestion =
250
+ if let hir:: Node :: Expr ( _) = tcx. hir_node ( hir_id) { depr. suggestion } else { None } ;
251
+ let diag = Deprecated {
252
+ sub : suggestion. map ( |suggestion| DeprecationSuggestion {
253
+ span : method_span,
254
+ kind : def_kind. to_owned ( ) ,
255
+ suggestion,
256
+ } ) ,
257
+ kind : def_kind. to_owned ( ) ,
258
+ path : def_path,
259
+ note : depr. note ,
260
+ since_kind : deprecated_since_kind ( is_in_effect, depr. since ) ,
261
+ } ;
262
+ tcx. emit_node_span_lint ( deprecation_lint ( is_in_effect) , hir_id, method_span, diag) ;
226
263
}
227
264
228
265
/// Result of `TyCtxt::eval_stability`.
@@ -351,28 +388,9 @@ impl<'tcx> TyCtxt<'tcx> {
351
388
// Calculating message for lint involves calling `self.def_path_str`.
352
389
// Which by default to calculate visible path will invoke expensive `visible_parent_map` query.
353
390
// So we skip message calculation altogether, if lint is allowed.
354
- let is_in_effect = depr_attr. is_in_effect ( ) ;
355
- let lint = deprecation_lint ( is_in_effect) ;
391
+ let lint = deprecation_lint ( depr_attr. is_in_effect ( ) ) ;
356
392
if self . lint_level_at_node ( lint, id) . 0 != Level :: Allow {
357
- let def_path = with_no_trimmed_paths ! ( self . def_path_str( def_id) ) ;
358
- let def_kind = self . def_descr ( def_id) ;
359
-
360
- late_report_deprecation (
361
- self ,
362
- deprecation_message (
363
- is_in_effect,
364
- depr_attr. since ,
365
- depr_attr. note ,
366
- def_kind,
367
- & def_path,
368
- ) ,
369
- depr_attr. suggestion ,
370
- lint,
371
- span,
372
- method_span,
373
- id,
374
- def_id,
375
- ) ;
393
+ late_report_deprecation ( self , depr_attr, span, method_span, id, def_id) ;
376
394
}
377
395
}
378
396
} ;
0 commit comments