about summary refs log tree commit diff
path: root/compiler
diff options
context:
space:
mode:
authorXiretza <xiretza@xiretza.xyz>2024-04-21 13:24:25 +0000
committerXiretza <xiretza@xiretza.xyz>2024-05-21 20:16:39 +0000
commit41a20b4c5659d93ef01051351f012c04fea1a38a (patch)
tree4b0fc808ed197d02ee9d15db97b106e1c13db36d /compiler
parentc227f35a9cd7ef894abfb623a16ad28abf8b6e3f (diff)
downloadrust-41a20b4c5659d93ef01051351f012c04fea1a38a.tar.gz
rust-41a20b4c5659d93ef01051351f012c04fea1a38a.zip
Port DeprecatedMacro to diag structs
Diffstat (limited to 'compiler')
-rw-r--r--compiler/rustc_lint/src/context/diagnostics.rs25
-rw-r--r--compiler/rustc_lint_defs/src/lib.rs13
-rw-r--r--compiler/rustc_middle/messages.ftl14
-rw-r--r--compiler/rustc_middle/src/middle/stability.rs188
-rw-r--r--compiler/rustc_resolve/src/macros.rs8
5 files changed, 152 insertions, 96 deletions
diff --git a/compiler/rustc_lint/src/context/diagnostics.rs b/compiler/rustc_lint/src/context/diagnostics.rs
index df012b2d10b..70aa14a565d 100644
--- a/compiler/rustc_lint/src/context/diagnostics.rs
+++ b/compiler/rustc_lint/src/context/diagnostics.rs
@@ -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, .. } => {
diff --git a/compiler/rustc_lint_defs/src/lib.rs b/compiler/rustc_lint_defs/src/lib.rs
index a0b24d02561..53238ed9629 100644
--- a/compiler/rustc_lint_defs/src/lib.rs
+++ b/compiler/rustc_lint_defs/src/lib.rs
@@ -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),
diff --git a/compiler/rustc_middle/messages.ftl b/compiler/rustc_middle/messages.ftl
index 27d555d7e26..f4d619329eb 100644
--- a/compiler/rustc_middle/messages.ftl
+++ b/compiler/rustc_middle/messages.ftl
@@ -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}
diff --git a/compiler/rustc_middle/src/middle/stability.rs b/compiler/rustc_middle/src/middle/stability.rs
index 75ed408e644..37d2c6a7078 100644
--- a/compiler/rustc_middle/src/middle/stability.rs
+++ b/compiler/rustc_middle/src/middle/stability.rs
@@ -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 }
+}
+
+#[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
+            }
+        }
     }
 }
 
-fn deprecation_lint(is_in_effect: bool) -> &'static Lint {
-    if is_in_effect { DEPRECATED } else { DEPRECATED_IN_FUTURE }
+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 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}`")
+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);
                     }
                 }
             };
diff --git a/compiler/rustc_resolve/src/macros.rs b/compiler/rustc_resolve/src/macros.rs
index 0e0e6ffc136..63461d5744b 100644
--- a/compiler/rustc_resolve/src/macros.rs
+++ b/compiler/rustc_resolve/src/macros.rs
@@ -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,
             );
         }
     }