@@ -9,15 +9,15 @@ 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 } ;
17- use rustc_macros:: { Decodable , Encodable , HashStable } ;
17+ use rustc_macros:: { Decodable , Encodable , HashStable , Subdiagnostic } ;
1818use rustc_middle:: ty:: print:: with_no_trimmed_paths;
1919use rustc_session:: lint:: builtin:: { DEPRECATED , DEPRECATED_IN_FUTURE , SOFT_UNSTABLE } ;
20- use rustc_session:: lint:: { BuiltinLintDiag , Level , Lint , LintBuffer } ;
20+ use rustc_session:: lint:: { BuiltinLintDiag , DeprecatedSinceKind , Level , Lint , LintBuffer } ;
2121use rustc_session:: parse:: feature_err_issue;
2222use rustc_session:: Session ;
2323use rustc_span:: symbol:: { sym, Symbol } ;
@@ -125,90 +125,114 @@ pub fn report_unstable(
125125 }
126126}
127127
128- pub fn deprecation_suggestion (
129- diag : & mut Diag < ' _ , ( ) > ,
130- kind : & str ,
131- suggestion : Option < Symbol > ,
132- span : Span ,
133- ) {
134- if let Some ( suggestion) = suggestion {
135- diag. span_suggestion_verbose (
136- span,
137- format ! ( "replace the use of the deprecated {kind}" ) ,
138- suggestion,
139- Applicability :: MachineApplicable ,
140- ) ;
128+ fn deprecation_lint ( is_in_effect : bool ) -> & ' static Lint {
129+ if is_in_effect { DEPRECATED } else { DEPRECATED_IN_FUTURE }
130+ }
131+
132+ #[ derive( Subdiagnostic ) ]
133+ #[ suggestion(
134+ middle_deprecated_suggestion,
135+ code = "{suggestion}" ,
136+ style = "verbose" ,
137+ applicability = "machine-applicable"
138+ ) ]
139+ pub struct DeprecationSuggestion {
140+ #[ primary_span]
141+ pub span : Span ,
142+
143+ pub kind : String ,
144+ pub suggestion : Symbol ,
145+ }
146+
147+ pub struct Deprecated {
148+ pub sub : Option < DeprecationSuggestion > ,
149+
150+ // FIXME: make this translatable
151+ pub kind : String ,
152+ pub path : String ,
153+ pub note : Option < Symbol > ,
154+ pub since_kind : DeprecatedSinceKind ,
155+ }
156+
157+ impl Deprecated {
158+ // FIXME: remove
159+ pub fn msg_for_since_kind ( since_kind : & DeprecatedSinceKind ) -> rustc_errors:: DiagMessage {
160+ match since_kind {
161+ DeprecatedSinceKind :: InEffect => crate :: fluent_generated:: middle_deprecated,
162+ DeprecatedSinceKind :: InFuture => crate :: fluent_generated:: middle_deprecated_in_future,
163+ DeprecatedSinceKind :: InVersion ( _) => {
164+ crate :: fluent_generated:: middle_deprecated_in_version
165+ }
166+ }
141167 }
142168}
143169
144- fn deprecation_lint ( is_in_effect : bool ) -> & ' static Lint {
145- if is_in_effect { DEPRECATED } else { DEPRECATED_IN_FUTURE }
170+ impl < ' a , G : EmissionGuarantee > rustc_errors:: LintDiagnostic < ' a , G > for Deprecated {
171+ fn decorate_lint < ' b > ( self , diag : & ' b mut Diag < ' a , G > ) {
172+ diag. arg ( "kind" , self . kind ) ;
173+ diag. arg ( "path" , self . path ) ;
174+ if let DeprecatedSinceKind :: InVersion ( version) = self . since_kind {
175+ diag. arg ( "version" , version) ;
176+ }
177+ if let Some ( note) = self . note {
178+ diag. arg ( "has_note" , true ) ;
179+ diag. arg ( "note" , note) ;
180+ } else {
181+ diag. arg ( "has_note" , false ) ;
182+ }
183+ if let Some ( sub) = self . sub {
184+ diag. subdiagnostic ( diag. dcx , sub) ;
185+ }
186+ }
187+
188+ fn msg ( & self ) -> rustc_errors:: DiagMessage {
189+ Self :: msg_for_since_kind ( & self . since_kind )
190+ }
146191}
147192
148- fn deprecation_message (
149- is_in_effect : bool ,
150- since : DeprecatedSince ,
151- note : Option < Symbol > ,
152- kind : & str ,
153- path : & str ,
154- ) -> String {
155- let message = if is_in_effect {
156- format ! ( "use of deprecated {kind} `{path}`" )
193+ fn deprecated_since_kind ( is_in_effect : bool , since : DeprecatedSince ) -> DeprecatedSinceKind {
194+ if is_in_effect {
195+ DeprecatedSinceKind :: InEffect
157196 } else {
158197 match since {
159- DeprecatedSince :: RustcVersion ( version) => format ! (
160- "use of {kind} `{path}` that will be deprecated in future version {version}"
161- ) ,
162- DeprecatedSince :: Future => {
163- format ! ( "use of {kind} `{path}` that will be deprecated in a future Rust version" )
198+ DeprecatedSince :: RustcVersion ( version) => {
199+ DeprecatedSinceKind :: InVersion ( version. to_string ( ) )
164200 }
201+ DeprecatedSince :: Future => DeprecatedSinceKind :: InFuture ,
165202 DeprecatedSince :: NonStandard ( _)
166203 | DeprecatedSince :: Unspecified
167204 | DeprecatedSince :: Err => {
168205 unreachable ! ( "this deprecation is always in effect; {since:?}" )
169206 }
170207 }
171- } ;
172-
173- match note {
174- Some ( reason) => format ! ( "{message}: {reason}" ) ,
175- None => message,
176208 }
177209}
178210
179- pub fn deprecation_message_and_lint (
180- depr : & Deprecation ,
181- kind : & str ,
182- path : & str ,
183- ) -> ( String , & ' static Lint ) {
184- let is_in_effect = depr. is_in_effect ( ) ;
185- (
186- deprecation_message ( is_in_effect, depr. since , depr. note , kind, path) ,
187- deprecation_lint ( is_in_effect) ,
188- )
189- }
190-
191- pub fn early_report_deprecation (
211+ pub fn early_report_macro_deprecation (
192212 lint_buffer : & mut LintBuffer ,
193- message : String ,
194- suggestion : Option < Symbol > ,
195- lint : & ' static Lint ,
213+ depr : & Deprecation ,
196214 span : Span ,
197215 node_id : NodeId ,
216+ path : String ,
198217) {
199218 if span. in_derive_expansion ( ) {
200219 return ;
201220 }
202221
203- let diag = BuiltinLintDiag :: DeprecatedMacro { suggestion, span, message } ;
204- lint_buffer. buffer_lint_with_diagnostic ( lint, node_id, span, diag) ;
222+ let is_in_effect = depr. is_in_effect ( ) ;
223+ let diag = BuiltinLintDiag :: DeprecatedMacro {
224+ suggestion : depr. suggestion ,
225+ suggestion_span : span,
226+ note : depr. note ,
227+ path,
228+ since_kind : deprecated_since_kind ( is_in_effect, depr. since . clone ( ) ) ,
229+ } ;
230+ lint_buffer. buffer_lint_with_diagnostic ( deprecation_lint ( is_in_effect) , node_id, span, diag) ;
205231}
206232
207233fn late_report_deprecation (
208234 tcx : TyCtxt < ' _ > ,
209- message : String ,
210- suggestion : Option < Symbol > ,
211- lint : & ' static Lint ,
235+ depr : & Deprecation ,
212236 span : Span ,
213237 method_span : Option < Span > ,
214238 hir_id : HirId ,
@@ -217,13 +241,26 @@ fn late_report_deprecation(
217241 if span. in_derive_expansion ( ) {
218242 return ;
219243 }
244+
245+ let def_path = with_no_trimmed_paths ! ( tcx. def_path_str( def_id) ) ;
246+ let def_kind = tcx. def_descr ( def_id) ;
247+ let is_in_effect = depr. is_in_effect ( ) ;
248+
220249 let method_span = method_span. unwrap_or ( span) ;
221- tcx. node_span_lint ( lint, hir_id, method_span, message, |diag| {
222- if let hir:: Node :: Expr ( _) = tcx. hir_node ( hir_id) {
223- let kind = tcx. def_descr ( def_id) ;
224- deprecation_suggestion ( diag, kind, suggestion, method_span) ;
225- }
226- } ) ;
250+ let suggestion =
251+ if let hir:: Node :: Expr ( _) = tcx. hir_node ( hir_id) { depr. suggestion } else { None } ;
252+ let diag = Deprecated {
253+ sub : suggestion. map ( |suggestion| DeprecationSuggestion {
254+ span : method_span,
255+ kind : def_kind. to_owned ( ) ,
256+ suggestion,
257+ } ) ,
258+ kind : def_kind. to_owned ( ) ,
259+ path : def_path,
260+ note : depr. note ,
261+ since_kind : deprecated_since_kind ( is_in_effect, depr. since ) ,
262+ } ;
263+ tcx. emit_node_span_lint ( deprecation_lint ( is_in_effect) , hir_id, method_span, diag) ;
227264}
228265
229266/// Result of `TyCtxt::eval_stability`.
@@ -352,28 +389,9 @@ impl<'tcx> TyCtxt<'tcx> {
352389 // Calculating message for lint involves calling `self.def_path_str`.
353390 // Which by default to calculate visible path will invoke expensive `visible_parent_map` query.
354391 // So we skip message calculation altogether, if lint is allowed.
355- let is_in_effect = depr_attr. is_in_effect ( ) ;
356- let lint = deprecation_lint ( is_in_effect) ;
392+ let lint = deprecation_lint ( depr_attr. is_in_effect ( ) ) ;
357393 if self . lint_level_at_node ( lint, id) . 0 != Level :: Allow {
358- let def_path = with_no_trimmed_paths ! ( self . def_path_str( def_id) ) ;
359- let def_kind = self . def_descr ( def_id) ;
360-
361- late_report_deprecation (
362- self ,
363- deprecation_message (
364- is_in_effect,
365- depr_attr. since ,
366- depr_attr. note ,
367- def_kind,
368- & def_path,
369- ) ,
370- depr_attr. suggestion ,
371- lint,
372- span,
373- method_span,
374- id,
375- def_id,
376- ) ;
394+ late_report_deprecation ( self , depr_attr, span, method_span, id, def_id) ;
377395 }
378396 }
379397 } ;
0 commit comments