Skip to content

Commit 6c04cb2

Browse files
committed
Port DeprecatedMacro to diag structs
1 parent 50b76d4 commit 6c04cb2

File tree

5 files changed

+139
-98
lines changed

5 files changed

+139
-98
lines changed

compiler/rustc_lint/src/context/diagnostics.rs

+20-6
Original file line numberDiff line numberDiff line change
@@ -19,9 +19,6 @@ mod check_cfg;
1919

2020
fn buffered_decorate(sess: &Session, diagnostic: BuiltinLintDiag, diag: &mut Diag<'_, ()>) {
2121
match diagnostic {
22-
BuiltinLintDiag::DeprecatedMacro { suggestion, span, .. } => {
23-
stability::deprecation_suggestion(diag, "macro", suggestion, span)
24-
}
2522
BuiltinLintDiag::UnusedDocComment(span) => {
2623
diag.span_label(span, "rustdoc does not generate documentation for macro invocations");
2724
diag.help("to document an item produced by a macro, \
@@ -259,6 +256,7 @@ fn buffered_decorate(sess: &Session, diagnostic: BuiltinLintDiag, diag: &mut Dia
259256
| BuiltinLintDiag::UnknownCrateTypes { .. }
260257
| BuiltinLintDiag::UnusedImports { .. }
261258
| BuiltinLintDiag::RedundantImport(_, _)
259+
| BuiltinLintDiag::DeprecatedMacro { .. }
262260
| BuiltinLintDiag::MacroUseDeprecated
263261
| BuiltinLintDiag::UnusedMacroUse
264262
| BuiltinLintDiag::PrivateExternCrateReexport(_)
@@ -290,7 +288,6 @@ fn buffered_decorate(sess: &Session, diagnostic: BuiltinLintDiag, diag: &mut Dia
290288

291289
fn buffered_message(diagnostic: &BuiltinLintDiag) -> DiagMessage {
292290
match diagnostic {
293-
BuiltinLintDiag::DeprecatedMacro { message, .. } => message.clone().into(),
294291
BuiltinLintDiag::MissingAbi(_, _) => fluent::lint_extern_without_abi,
295292
BuiltinLintDiag::UnusedDocComment(_) => fluent::lint_unused_doc_comment,
296293
BuiltinLintDiag::UnusedBuiltinAttribute { attr_name, .. } => {
@@ -364,6 +361,7 @@ fn buffered_message(diagnostic: &BuiltinLintDiag) -> DiagMessage {
364361
| BuiltinLintDiag::UnknownCrateTypes { .. }
365362
| BuiltinLintDiag::UnusedImports { .. }
366363
| BuiltinLintDiag::RedundantImport(_, _)
364+
| BuiltinLintDiag::DeprecatedMacro { .. }
367365
| BuiltinLintDiag::MacroUseDeprecated
368366
| BuiltinLintDiag::UnusedMacroUse
369367
| BuiltinLintDiag::PrivateExternCrateReexport(_)
@@ -400,8 +398,7 @@ pub(super) fn emit_buffered_lint<C: LintContext + ?Sized>(
400398
diagnostic: BuiltinLintDiag,
401399
) {
402400
match diagnostic {
403-
BuiltinLintDiag::DeprecatedMacro { .. }
404-
| BuiltinLintDiag::MissingAbi(_, _)
401+
BuiltinLintDiag::MissingAbi(_, _)
405402
| BuiltinLintDiag::UnusedDocComment(_)
406403
| BuiltinLintDiag::UnusedBuiltinAttribute { .. }
407404
| BuiltinLintDiag::PatternsInFnsWithoutBody { .. }
@@ -555,6 +552,23 @@ pub(super) fn emit_buffered_lint<C: LintContext + ?Sized>(
555552
.collect();
556553
ctx.emit_span_lint(lint, span, lints::RedundantImport { subs, ident });
557554
}
555+
BuiltinLintDiag::DeprecatedMacro {
556+
suggestion,
557+
suggestion_span,
558+
note,
559+
path,
560+
since_kind,
561+
} => {
562+
let sub = suggestion.map(|suggestion| stability::DeprecationSuggestion {
563+
span: suggestion_span,
564+
suggestion,
565+
});
566+
ctx.emit_span_lint(
567+
lint,
568+
span,
569+
stability::Deprecated { sub, kind: "macro".to_string(), path, note, since_kind },
570+
);
571+
}
558572
BuiltinLintDiag::MacroUseDeprecated => {
559573
ctx.emit_span_lint(lint, span, lints::MacroUseDeprecated)
560574
}

compiler/rustc_lint_defs/src/lib.rs

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

571+
#[derive(Debug, Clone)]
572+
pub enum DeprecatedSinceKind {
573+
InEffect,
574+
InFuture,
575+
InVersion(String),
576+
}
577+
571578
// This could be a closure, but then implementing derive trait
572579
// becomes hacky (and it gets allocated).
573580
#[derive(Debug)]
@@ -594,8 +601,10 @@ pub enum BuiltinLintDiag {
594601
RedundantImport(Vec<(Span, bool)>, Ident),
595602
DeprecatedMacro {
596603
suggestion: Option<Symbol>,
597-
span: Span,
598-
message: String,
604+
suggestion_span: Span,
605+
note: Option<Symbol>,
606+
path: String,
607+
since_kind: DeprecatedSinceKind,
599608
},
600609
MissingAbi(Span, Abi),
601610
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

+91-85
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,106 @@ 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-
);
140-
}
141-
}
142-
143127
fn deprecation_lint(is_in_effect: bool) -> &'static Lint {
144128
if is_in_effect { DEPRECATED } else { DEPRECATED_IN_FUTURE }
145129
}
146130

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}`")
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 suggestion: Symbol,
143+
}
144+
145+
pub struct Deprecated {
146+
pub sub: Option<DeprecationSuggestion>,
147+
148+
// FIXME: make this translatable
149+
pub kind: String,
150+
pub path: String,
151+
pub note: Option<Symbol>,
152+
pub since_kind: DeprecatedSinceKind,
153+
}
154+
155+
impl<'a, G: EmissionGuarantee> rustc_errors::LintDiagnostic<'a, G> for Deprecated {
156+
fn decorate_lint<'b>(self, diag: &'b mut Diag<'a, G>) {
157+
diag.arg("kind", self.kind);
158+
diag.arg("path", self.path);
159+
if let DeprecatedSinceKind::InVersion(version) = self.since_kind {
160+
diag.arg("version", version);
161+
}
162+
if let Some(note) = self.note {
163+
diag.arg("has_note", true);
164+
diag.arg("note", note);
165+
} else {
166+
diag.arg("has_note", false);
167+
}
168+
if let Some(sub) = self.sub {
169+
diag.subdiagnostic(diag.dcx, sub);
170+
}
171+
}
172+
173+
fn msg(&self) -> rustc_errors::DiagMessage {
174+
match self.since_kind {
175+
DeprecatedSinceKind::InEffect => crate::fluent_generated::middle_deprecated,
176+
DeprecatedSinceKind::InFuture => crate::fluent_generated::middle_deprecated_in_future,
177+
DeprecatedSinceKind::InVersion(_) => {
178+
crate::fluent_generated::middle_deprecated_in_version
179+
}
180+
}
181+
}
182+
}
183+
184+
fn deprecated_since_kind(is_in_effect: bool, since: DeprecatedSince) -> DeprecatedSinceKind {
185+
if is_in_effect {
186+
DeprecatedSinceKind::InEffect
156187
} else {
157188
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")
189+
DeprecatedSince::RustcVersion(version) => {
190+
DeprecatedSinceKind::InVersion(version.to_string())
163191
}
192+
DeprecatedSince::Future => DeprecatedSinceKind::InFuture,
164193
DeprecatedSince::NonStandard(_)
165194
| DeprecatedSince::Unspecified
166195
| DeprecatedSince::Err => {
167196
unreachable!("this deprecation is always in effect; {since:?}")
168197
}
169198
}
170-
};
171-
172-
match note {
173-
Some(reason) => format!("{message}: {reason}"),
174-
None => message,
175199
}
176200
}
177201

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(
202+
pub fn early_report_macro_deprecation(
191203
lint_buffer: &mut LintBuffer,
192-
message: String,
193-
suggestion: Option<Symbol>,
194-
lint: &'static Lint,
204+
depr: &Deprecation,
195205
span: Span,
196206
node_id: NodeId,
207+
path: String,
197208
) {
198209
if span.in_derive_expansion() {
199210
return;
200211
}
201212

202-
let diag = BuiltinLintDiag::DeprecatedMacro { suggestion, span, message };
203-
lint_buffer.buffer_lint_with_diagnostic(lint, node_id, span, diag);
213+
let is_in_effect = depr.is_in_effect();
214+
let diag = BuiltinLintDiag::DeprecatedMacro {
215+
suggestion: depr.suggestion,
216+
suggestion_span: span,
217+
note: depr.note,
218+
path,
219+
since_kind: deprecated_since_kind(is_in_effect, depr.since.clone()),
220+
};
221+
lint_buffer.buffer_lint_with_diagnostic(deprecation_lint(is_in_effect), node_id, span, diag);
204222
}
205223

206224
fn late_report_deprecation(
207225
tcx: TyCtxt<'_>,
208-
message: String,
209-
suggestion: Option<Symbol>,
210-
lint: &'static Lint,
226+
depr: &Deprecation,
211227
span: Span,
212228
method_span: Option<Span>,
213229
hir_id: HirId,
@@ -216,13 +232,22 @@ fn late_report_deprecation(
216232
if span.in_derive_expansion() {
217233
return;
218234
}
235+
236+
let def_path = with_no_trimmed_paths!(tcx.def_path_str(def_id));
237+
let def_kind = tcx.def_descr(def_id);
238+
let is_in_effect = depr.is_in_effect();
239+
219240
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-
});
241+
let suggestion =
242+
if let hir::Node::Expr(_) = tcx.hir_node(hir_id) { depr.suggestion } else { None };
243+
let diag = Deprecated {
244+
sub: suggestion.map(|suggestion| DeprecationSuggestion { span: method_span, suggestion }),
245+
kind: def_kind.to_owned(),
246+
path: def_path,
247+
note: depr.note,
248+
since_kind: deprecated_since_kind(is_in_effect, depr.since),
249+
};
250+
tcx.emit_node_span_lint(deprecation_lint(is_in_effect), hir_id, method_span, diag);
226251
}
227252

228253
/// Result of `TyCtxt::eval_stability`.
@@ -351,28 +376,9 @@ impl<'tcx> TyCtxt<'tcx> {
351376
// Calculating message for lint involves calling `self.def_path_str`.
352377
// Which by default to calculate visible path will invoke expensive `visible_parent_map` query.
353378
// 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);
379+
let lint = deprecation_lint(depr_attr.is_in_effect());
356380
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-
);
381+
late_report_deprecation(self, depr_attr, span, method_span, id, def_id);
376382
}
377383
}
378384
};

compiler/rustc_resolve/src/macros.rs

+3-5
Original file line numberDiff line numberDiff line change
@@ -862,14 +862,12 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
862862
}
863863
if let Some(depr) = &ext.deprecation {
864864
let path = pprust::path_to_string(path);
865-
let (message, lint) = stability::deprecation_message_and_lint(depr, "macro", &path);
866-
stability::early_report_deprecation(
865+
stability::early_report_macro_deprecation(
867866
&mut self.lint_buffer,
868-
message,
869-
depr.suggestion,
870-
lint,
867+
depr,
871868
span,
872869
node_id,
870+
path,
873871
);
874872
}
875873
}

0 commit comments

Comments
 (0)