Skip to content

Commit 315dbab

Browse files
committed
Port DeprecatedMacro to diag structs
1 parent db2f44d commit 315dbab

File tree

5 files changed

+151
-95
lines changed

5 files changed

+151
-95
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");
@@ -382,7 +397,9 @@ pub(super) fn builtin_message(diagnostic: &BuiltinLintDiag) -> DiagMessage {
382397
BuiltinLintDiag::RedundantImport(_, source) => {
383398
format!("the item `{source}` is imported redundantly").into()
384399
}
385-
BuiltinLintDiag::DeprecatedMacro { message, .. } => message.clone().into(),
400+
BuiltinLintDiag::DeprecatedMacro { since_kind, .. } => {
401+
stability::Deprecated::msg_for_since_kind(since_kind)
402+
}
386403
BuiltinLintDiag::MissingAbi(_, _) => crate::fluent_generated::lint_extern_without_abi,
387404
BuiltinLintDiag::UnusedDocComment(_) => "unused doc comment".into(),
388405
BuiltinLintDiag::UnusedBuiltinAttribute { attr_name, .. } => {

compiler/rustc_lint_defs/src/lib.rs

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

570+
#[derive(Debug, Clone)]
571+
pub enum DeprecatedSinceKind {
572+
InEffect,
573+
InFuture,
574+
InVersion(String),
575+
}
576+
570577
// This could be a closure, but then implementing derive trait
571578
// becomes hacky (and it gets allocated).
572579
#[derive(Debug)]
@@ -590,8 +597,10 @@ pub enum BuiltinLintDiag {
590597
RedundantImport(Vec<(Span, bool)>, Ident),
591598
DeprecatedMacro {
592599
suggestion: Option<Symbol>,
593-
span: Span,
594-
message: String,
600+
suggestion_span: Span,
601+
note: Option<Symbol>,
602+
path: String,
603+
since_kind: DeprecatedSinceKind,
595604
},
596605
MissingAbi(Span, Abi),
597606
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+
*[others] {""}
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+
*[others] {""}
60+
}
61+
middle_deprecated_in_version = use of {$kind} `{$path}` that will be deprecated in future version {$version}{$has_note ->
62+
[true] : {$note}
63+
*[others] {""}
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

+102-84
Original file line numberDiff line numberDiff line change
@@ -9,14 +9,14 @@ 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};
1717
use rustc_middle::ty::print::with_no_trimmed_paths;
1818
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};
2020
use rustc_session::parse::feature_err_issue;
2121
use rustc_session::Session;
2222
use 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

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

compiler/rustc_resolve/src/macros.rs

+3-5
Original file line numberDiff line numberDiff line change
@@ -846,14 +846,12 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
846846
}
847847
if let Some(depr) = &ext.deprecation {
848848
let path = pprust::path_to_string(path);
849-
let (message, lint) = stability::deprecation_message_and_lint(depr, "macro", &path);
850-
stability::early_report_deprecation(
849+
stability::early_report_macro_deprecation(
851850
&mut self.lint_buffer,
852-
message,
853-
depr.suggestion,
854-
lint,
851+
depr,
855852
span,
856853
node_id,
854+
path,
857855
);
858856
}
859857
}

0 commit comments

Comments
 (0)