Skip to content

Commit 41a20b4

Browse files
committed
Port DeprecatedMacro to diag structs
1 parent c227f35 commit 41a20b4

File tree

5 files changed

+152
-96
lines changed

5 files changed

+152
-96
lines changed

compiler/rustc_lint/src/context/diagnostics.rs

+21-4
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,9 @@
22
#![allow(rustc::untranslatable_diagnostic)]
33

44
use rustc_ast::util::unicode::TEXT_FLOW_CONTROL_CHARS;
5-
use rustc_errors::{elided_lifetime_in_path_suggestion, pluralize, Diag, DiagMessage};
5+
use rustc_errors::{
6+
elided_lifetime_in_path_suggestion, pluralize, Diag, DiagMessage, LintDiagnostic,
7+
};
68
use rustc_errors::{Applicability, SuggestionStyle};
79
use rustc_middle::middle::stability;
810
use rustc_session::lint::BuiltinLintDiag;
@@ -114,8 +116,21 @@ pub(super) fn builtin(sess: &Session, diagnostic: BuiltinLintDiag, diag: &mut Di
114116
);
115117
}
116118
}
117-
BuiltinLintDiag::DeprecatedMacro { suggestion, span, .. } => {
118-
stability::deprecation_suggestion(diag, "macro", suggestion, span)
119+
BuiltinLintDiag::DeprecatedMacro {
120+
suggestion,
121+
suggestion_span,
122+
note,
123+
path,
124+
since_kind,
125+
} => {
126+
let sub = suggestion.map(|suggestion| stability::DeprecationSuggestion {
127+
span: suggestion_span,
128+
kind: "macro".to_owned(),
129+
suggestion,
130+
});
131+
let deprecated =
132+
stability::Deprecated { sub, kind: "macro".to_owned(), path, note, since_kind };
133+
deprecated.decorate_lint(diag);
119134
}
120135
BuiltinLintDiag::UnusedDocComment(span) => {
121136
diag.span_label(span, "rustdoc does not generate documentation for macro invocations");
@@ -390,7 +405,9 @@ pub(super) fn builtin_message(diagnostic: &BuiltinLintDiag) -> DiagMessage {
390405
BuiltinLintDiag::RedundantImport(_, source) => {
391406
format!("the item `{source}` is imported redundantly").into()
392407
}
393-
BuiltinLintDiag::DeprecatedMacro { message, .. } => message.clone().into(),
408+
BuiltinLintDiag::DeprecatedMacro { since_kind, .. } => {
409+
stability::Deprecated::msg_for_since_kind(since_kind)
410+
}
394411
BuiltinLintDiag::MissingAbi(_, _) => crate::fluent_generated::lint_extern_without_abi,
395412
BuiltinLintDiag::UnusedDocComment(_) => "unused doc comment".into(),
396413
BuiltinLintDiag::UnusedBuiltinAttribute { attr_name, .. } => {

compiler/rustc_lint_defs/src/lib.rs

+11-2
Original file line numberDiff line numberDiff line change
@@ -566,6 +566,13 @@ pub struct AmbiguityErrorDiag {
566566
pub b2_help_msgs: Vec<String>,
567567
}
568568

569+
#[derive(Debug, Clone)]
570+
pub enum DeprecatedSinceKind {
571+
InEffect,
572+
InFuture,
573+
InVersion(String),
574+
}
575+
569576
// This could be a closure, but then implementing derive trait
570577
// becomes hacky (and it gets allocated).
571578
#[derive(Debug)]
@@ -589,8 +596,10 @@ pub enum BuiltinLintDiag {
589596
RedundantImport(Vec<(Span, bool)>, Ident),
590597
DeprecatedMacro {
591598
suggestion: Option<Symbol>,
592-
span: Span,
593-
message: String,
599+
suggestion_span: Span,
600+
note: Option<Symbol>,
601+
path: String,
602+
since_kind: DeprecatedSinceKind,
594603
},
595604
MissingAbi(Span, Abi),
596605
UnusedDocComment(Span),

compiler/rustc_middle/messages.ftl

+14
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,20 @@ middle_const_not_used_in_type_alias =
5050
middle_cycle =
5151
a cycle occurred during layout computation
5252
53+
middle_deprecated = use of deprecated {$kind} `{$path}`{$has_note ->
54+
[true] : {$note}
55+
*[other] {""}
56+
}
57+
middle_deprecated_in_future = use of {$kind} `{$path}` that will be deprecated in a future Rust version{$has_note ->
58+
[true] : {$note}
59+
*[other] {""}
60+
}
61+
middle_deprecated_in_version = use of {$kind} `{$path}` that will be deprecated in future version {$version}{$has_note ->
62+
[true] : {$note}
63+
*[other] {""}
64+
}
65+
middle_deprecated_suggestion = replace the use of the deprecated {$kind}
66+
5367
middle_drop_check_overflow =
5468
overflow while adding drop-check rules for {$ty}
5569
.note = overflowed on {$overflow_ty}

compiler/rustc_middle/src/middle/stability.rs

+103-85
Original file line numberDiff line numberDiff line change
@@ -9,15 +9,15 @@ use rustc_attr::{
99
self as attr, ConstStability, DefaultBodyStability, DeprecatedSince, Deprecation, Stability,
1010
};
1111
use rustc_data_structures::unord::UnordMap;
12-
use rustc_errors::{Applicability, Diag};
12+
use rustc_errors::{Applicability, Diag, EmissionGuarantee};
1313
use rustc_feature::GateIssue;
1414
use rustc_hir::def::DefKind;
1515
use rustc_hir::def_id::{DefId, LocalDefId, LocalDefIdMap};
1616
use rustc_hir::{self as hir, HirId};
17-
use rustc_macros::{Decodable, Encodable, HashStable};
17+
use rustc_macros::{Decodable, Encodable, HashStable, Subdiagnostic};
1818
use rustc_middle::ty::print::with_no_trimmed_paths;
1919
use 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};
2121
use rustc_session::parse::feature_err_issue;
2222
use rustc_session::Session;
2323
use 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

207233
fn 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
};

compiler/rustc_resolve/src/macros.rs

+3-5
Original file line numberDiff line numberDiff line change
@@ -852,14 +852,12 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
852852
}
853853
if let Some(depr) = &ext.deprecation {
854854
let path = pprust::path_to_string(path);
855-
let (message, lint) = stability::deprecation_message_and_lint(depr, "macro", &path);
856-
stability::early_report_deprecation(
855+
stability::early_report_macro_deprecation(
857856
&mut self.lint_buffer,
858-
message,
859-
depr.suggestion,
860-
lint,
857+
depr,
861858
span,
862859
node_id,
860+
path,
863861
);
864862
}
865863
}

0 commit comments

Comments
 (0)