Port DeprecatedMacro to diag structs
This commit is contained in:
parent
c227f35a9c
commit
41a20b4c56
5 changed files with 153 additions and 97 deletions
|
@ -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, .. } => {
|
||||
|
|
|
@ -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),
|
||||
|
|
|
@ -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}
|
||||
|
|
|
@ -9,15 +9,15 @@ use rustc_attr::{
|
|||
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 @@ impl<'tcx> TyCtxt<'tcx> {
|
|||
// 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);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
|
|
@ -852,14 +852,12 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
|
|||
}
|
||||
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,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue