@@ -9,14 +9,14 @@ use rustc_attr::{
99 self as attr, ConstStability , DefaultBodyStability , DeprecatedSince , Deprecation , Stability ,
1010} ;
1111use rustc_data_structures:: unord:: UnordMap ;
12- use rustc_errors:: { Applicability , Diag } ;
12+ use rustc_errors:: { Applicability , Diag , EmissionGuarantee } ;
1313use rustc_feature:: GateIssue ;
1414use rustc_hir:: def:: DefKind ;
1515use rustc_hir:: def_id:: { DefId , LocalDefId , LocalDefIdMap } ;
1616use rustc_hir:: { self as hir, HirId } ;
1717use rustc_middle:: ty:: print:: with_no_trimmed_paths;
1818use 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 } ;
2020use rustc_session:: parse:: feature_err_issue;
2121use rustc_session:: Session ;
2222use rustc_span:: symbol:: { sym, Symbol } ;
@@ -124,90 +124,114 @@ pub fn report_unstable(
124124 }
125125}
126126
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+ }
140166 }
141167}
142168
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+ }
145190}
146191
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
156195 } else {
157196 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 ( ) )
163199 }
200+ DeprecatedSince :: Future => DeprecatedSinceKind :: InFuture ,
164201 DeprecatedSince :: NonStandard ( _)
165202 | DeprecatedSince :: Unspecified
166203 | DeprecatedSince :: Err => {
167204 unreachable ! ( "this deprecation is always in effect; {since:?}" )
168205 }
169206 }
170- } ;
171-
172- match note {
173- Some ( reason) => format ! ( "{message}: {reason}" ) ,
174- None => message,
175207 }
176208}
177209
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 (
191211 lint_buffer : & mut LintBuffer ,
192- message : String ,
193- suggestion : Option < Symbol > ,
194- lint : & ' static Lint ,
212+ depr : & Deprecation ,
195213 span : Span ,
196214 node_id : NodeId ,
215+ path : String ,
197216) {
198217 if span. in_derive_expansion ( ) {
199218 return ;
200219 }
201220
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) ;
204230}
205231
206232fn late_report_deprecation (
207233 tcx : TyCtxt < ' _ > ,
208- message : String ,
209- suggestion : Option < Symbol > ,
210- lint : & ' static Lint ,
234+ depr : & Deprecation ,
211235 span : Span ,
212236 method_span : Option < Span > ,
213237 hir_id : HirId ,
@@ -216,13 +240,26 @@ fn late_report_deprecation(
216240 if span. in_derive_expansion ( ) {
217241 return ;
218242 }
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+
219248 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) ;
226263}
227264
228265/// Result of `TyCtxt::eval_stability`.
@@ -351,28 +388,9 @@ impl<'tcx> TyCtxt<'tcx> {
351388 // Calculating message for lint involves calling `self.def_path_str`.
352389 // Which by default to calculate visible path will invoke expensive `visible_parent_map` query.
353390 // 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 ( ) ) ;
356392 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) ;
376394 }
377395 }
378396 } ;
0 commit comments