Port DeprecatedMacro to diag structs

This commit is contained in:
Xiretza 2024-04-21 13:24:25 +00:00
parent c227f35a9c
commit 41a20b4c56
5 changed files with 153 additions and 97 deletions

View file

@ -2,7 +2,9 @@
#![allow(rustc::untranslatable_diagnostic)]
use rustc_ast::util::unicode::TEXT_FLOW_CONTROL_CHARS;
use rustc_errors::{elided_lifetime_in_path_suggestion, pluralize, Diag, DiagMessage};
use rustc_errors::{
elided_lifetime_in_path_suggestion, pluralize, Diag, DiagMessage, LintDiagnostic,
};
use rustc_errors::{Applicability, SuggestionStyle};
use rustc_middle::middle::stability;
use rustc_session::lint::BuiltinLintDiag;
@ -114,8 +116,21 @@ pub(super) fn builtin(sess: &Session, diagnostic: BuiltinLintDiag, diag: &mut Di
);
}
}
BuiltinLintDiag::DeprecatedMacro { suggestion, span, .. } => {
stability::deprecation_suggestion(diag, "macro", suggestion, span)
BuiltinLintDiag::DeprecatedMacro {
suggestion,
suggestion_span,
note,
path,
since_kind,
} => {
let sub = suggestion.map(|suggestion| stability::DeprecationSuggestion {
span: suggestion_span,
kind: "macro".to_owned(),
suggestion,
});
let deprecated =
stability::Deprecated { sub, kind: "macro".to_owned(), path, note, since_kind };
deprecated.decorate_lint(diag);
}
BuiltinLintDiag::UnusedDocComment(span) => {
diag.span_label(span, "rustdoc does not generate documentation for macro invocations");
@ -390,7 +405,9 @@ pub(super) fn builtin_message(diagnostic: &BuiltinLintDiag) -> DiagMessage {
BuiltinLintDiag::RedundantImport(_, source) => {
format!("the item `{source}` is imported redundantly").into()
}
BuiltinLintDiag::DeprecatedMacro { message, .. } => message.clone().into(),
BuiltinLintDiag::DeprecatedMacro { since_kind, .. } => {
stability::Deprecated::msg_for_since_kind(since_kind)
}
BuiltinLintDiag::MissingAbi(_, _) => crate::fluent_generated::lint_extern_without_abi,
BuiltinLintDiag::UnusedDocComment(_) => "unused doc comment".into(),
BuiltinLintDiag::UnusedBuiltinAttribute { attr_name, .. } => {

View file

@ -566,6 +566,13 @@ pub struct AmbiguityErrorDiag {
pub b2_help_msgs: Vec<String>,
}
#[derive(Debug, Clone)]
pub enum DeprecatedSinceKind {
InEffect,
InFuture,
InVersion(String),
}
// This could be a closure, but then implementing derive trait
// becomes hacky (and it gets allocated).
#[derive(Debug)]
@ -589,8 +596,10 @@ pub enum BuiltinLintDiag {
RedundantImport(Vec<(Span, bool)>, Ident),
DeprecatedMacro {
suggestion: Option<Symbol>,
span: Span,
message: String,
suggestion_span: Span,
note: Option<Symbol>,
path: String,
since_kind: DeprecatedSinceKind,
},
MissingAbi(Span, Abi),
UnusedDocComment(Span),

View file

@ -50,6 +50,20 @@ middle_const_not_used_in_type_alias =
middle_cycle =
a cycle occurred during layout computation
middle_deprecated = use of deprecated {$kind} `{$path}`{$has_note ->
[true] : {$note}
*[other] {""}
}
middle_deprecated_in_future = use of {$kind} `{$path}` that will be deprecated in a future Rust version{$has_note ->
[true] : {$note}
*[other] {""}
}
middle_deprecated_in_version = use of {$kind} `{$path}` that will be deprecated in future version {$version}{$has_note ->
[true] : {$note}
*[other] {""}
}
middle_deprecated_suggestion = replace the use of the deprecated {$kind}
middle_drop_check_overflow =
overflow while adding drop-check rules for {$ty}
.note = overflowed on {$overflow_ty}

View file

@ -9,15 +9,15 @@
self as attr, ConstStability, DefaultBodyStability, DeprecatedSince, Deprecation, Stability,
};
use rustc_data_structures::unord::UnordMap;
use rustc_errors::{Applicability, Diag};
use rustc_errors::{Applicability, Diag, EmissionGuarantee};
use rustc_feature::GateIssue;
use rustc_hir::def::DefKind;
use rustc_hir::def_id::{DefId, LocalDefId, LocalDefIdMap};
use rustc_hir::{self as hir, HirId};
use rustc_macros::{Decodable, Encodable, HashStable};
use rustc_macros::{Decodable, Encodable, HashStable, Subdiagnostic};
use rustc_middle::ty::print::with_no_trimmed_paths;
use rustc_session::lint::builtin::{DEPRECATED, DEPRECATED_IN_FUTURE, SOFT_UNSTABLE};
use rustc_session::lint::{BuiltinLintDiag, Level, Lint, LintBuffer};
use rustc_session::lint::{BuiltinLintDiag, DeprecatedSinceKind, Level, Lint, LintBuffer};
use rustc_session::parse::feature_err_issue;
use rustc_session::Session;
use rustc_span::symbol::{sym, Symbol};
@ -125,90 +125,114 @@ pub fn report_unstable(
}
}
pub fn deprecation_suggestion(
diag: &mut Diag<'_, ()>,
kind: &str,
suggestion: Option<Symbol>,
span: Span,
) {
if let Some(suggestion) = suggestion {
diag.span_suggestion_verbose(
span,
format!("replace the use of the deprecated {kind}"),
suggestion,
Applicability::MachineApplicable,
);
}
}
fn deprecation_lint(is_in_effect: bool) -> &'static Lint {
if is_in_effect { DEPRECATED } else { DEPRECATED_IN_FUTURE }
}
fn deprecation_message(
is_in_effect: bool,
since: DeprecatedSince,
note: Option<Symbol>,
kind: &str,
path: &str,
) -> String {
let message = if is_in_effect {
format!("use of deprecated {kind} `{path}`")
#[derive(Subdiagnostic)]
#[suggestion(
middle_deprecated_suggestion,
code = "{suggestion}",
style = "verbose",
applicability = "machine-applicable"
)]
pub struct DeprecationSuggestion {
#[primary_span]
pub span: Span,
pub kind: String,
pub suggestion: Symbol,
}
pub struct Deprecated {
pub sub: Option<DeprecationSuggestion>,
// FIXME: make this translatable
pub kind: String,
pub path: String,
pub note: Option<Symbol>,
pub since_kind: DeprecatedSinceKind,
}
impl Deprecated {
// FIXME: remove
pub fn msg_for_since_kind(since_kind: &DeprecatedSinceKind) -> rustc_errors::DiagMessage {
match since_kind {
DeprecatedSinceKind::InEffect => crate::fluent_generated::middle_deprecated,
DeprecatedSinceKind::InFuture => crate::fluent_generated::middle_deprecated_in_future,
DeprecatedSinceKind::InVersion(_) => {
crate::fluent_generated::middle_deprecated_in_version
}
}
}
}
impl<'a, G: EmissionGuarantee> rustc_errors::LintDiagnostic<'a, G> for Deprecated {
fn decorate_lint<'b>(self, diag: &'b mut Diag<'a, G>) {
diag.arg("kind", self.kind);
diag.arg("path", self.path);
if let DeprecatedSinceKind::InVersion(version) = self.since_kind {
diag.arg("version", version);
}
if let Some(note) = self.note {
diag.arg("has_note", true);
diag.arg("note", note);
} else {
diag.arg("has_note", false);
}
if let Some(sub) = self.sub {
diag.subdiagnostic(diag.dcx, sub);
}
}
fn msg(&self) -> rustc_errors::DiagMessage {
Self::msg_for_since_kind(&self.since_kind)
}
}
fn deprecated_since_kind(is_in_effect: bool, since: DeprecatedSince) -> DeprecatedSinceKind {
if is_in_effect {
DeprecatedSinceKind::InEffect
} else {
match since {
DeprecatedSince::RustcVersion(version) => format!(
"use of {kind} `{path}` that will be deprecated in future version {version}"
),
DeprecatedSince::Future => {
format!("use of {kind} `{path}` that will be deprecated in a future Rust version")
DeprecatedSince::RustcVersion(version) => {
DeprecatedSinceKind::InVersion(version.to_string())
}
DeprecatedSince::Future => DeprecatedSinceKind::InFuture,
DeprecatedSince::NonStandard(_)
| DeprecatedSince::Unspecified
| DeprecatedSince::Err => {
unreachable!("this deprecation is always in effect; {since:?}")
}
}
};
match note {
Some(reason) => format!("{message}: {reason}"),
None => message,
}
}
pub fn deprecation_message_and_lint(
depr: &Deprecation,
kind: &str,
path: &str,
) -> (String, &'static Lint) {
let is_in_effect = depr.is_in_effect();
(
deprecation_message(is_in_effect, depr.since, depr.note, kind, path),
deprecation_lint(is_in_effect),
)
}
pub fn early_report_deprecation(
pub fn early_report_macro_deprecation(
lint_buffer: &mut LintBuffer,
message: String,
suggestion: Option<Symbol>,
lint: &'static Lint,
depr: &Deprecation,
span: Span,
node_id: NodeId,
path: String,
) {
if span.in_derive_expansion() {
return;
}
let diag = BuiltinLintDiag::DeprecatedMacro { suggestion, span, message };
lint_buffer.buffer_lint_with_diagnostic(lint, node_id, span, diag);
let is_in_effect = depr.is_in_effect();
let diag = BuiltinLintDiag::DeprecatedMacro {
suggestion: depr.suggestion,
suggestion_span: span,
note: depr.note,
path,
since_kind: deprecated_since_kind(is_in_effect, depr.since.clone()),
};
lint_buffer.buffer_lint_with_diagnostic(deprecation_lint(is_in_effect), node_id, span, diag);
}
fn late_report_deprecation(
tcx: TyCtxt<'_>,
message: String,
suggestion: Option<Symbol>,
lint: &'static Lint,
depr: &Deprecation,
span: Span,
method_span: Option<Span>,
hir_id: HirId,
@ -217,13 +241,26 @@ fn late_report_deprecation(
if span.in_derive_expansion() {
return;
}
let def_path = with_no_trimmed_paths!(tcx.def_path_str(def_id));
let def_kind = tcx.def_descr(def_id);
let is_in_effect = depr.is_in_effect();
let method_span = method_span.unwrap_or(span);
tcx.node_span_lint(lint, hir_id, method_span, message, |diag| {
if let hir::Node::Expr(_) = tcx.hir_node(hir_id) {
let kind = tcx.def_descr(def_id);
deprecation_suggestion(diag, kind, suggestion, method_span);
}
});
let suggestion =
if let hir::Node::Expr(_) = tcx.hir_node(hir_id) { depr.suggestion } else { None };
let diag = Deprecated {
sub: suggestion.map(|suggestion| DeprecationSuggestion {
span: method_span,
kind: def_kind.to_owned(),
suggestion,
}),
kind: def_kind.to_owned(),
path: def_path,
note: depr.note,
since_kind: deprecated_since_kind(is_in_effect, depr.since),
};
tcx.emit_node_span_lint(deprecation_lint(is_in_effect), hir_id, method_span, diag);
}
/// Result of `TyCtxt::eval_stability`.
@ -352,28 +389,9 @@ pub fn eval_stability_allow_unstable(
// Calculating message for lint involves calling `self.def_path_str`.
// Which by default to calculate visible path will invoke expensive `visible_parent_map` query.
// So we skip message calculation altogether, if lint is allowed.
let is_in_effect = depr_attr.is_in_effect();
let lint = deprecation_lint(is_in_effect);
let lint = deprecation_lint(depr_attr.is_in_effect());
if self.lint_level_at_node(lint, id).0 != Level::Allow {
let def_path = with_no_trimmed_paths!(self.def_path_str(def_id));
let def_kind = self.def_descr(def_id);
late_report_deprecation(
self,
deprecation_message(
is_in_effect,
depr_attr.since,
depr_attr.note,
def_kind,
&def_path,
),
depr_attr.suggestion,
lint,
span,
method_span,
id,
def_id,
);
late_report_deprecation(self, depr_attr, span, method_span, id, def_id);
}
}
};

View file

@ -852,14 +852,12 @@ fn check_stability_and_deprecation(
}
if let Some(depr) = &ext.deprecation {
let path = pprust::path_to_string(path);
let (message, lint) = stability::deprecation_message_and_lint(depr, "macro", &path);
stability::early_report_deprecation(
stability::early_report_macro_deprecation(
&mut self.lint_buffer,
message,
depr.suggestion,
lint,
depr,
span,
node_id,
path,
);
}
}