about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--compiler/rustc_error_messages/locales/en-US/lint.ftl3
-rw-r--r--compiler/rustc_lint/src/deref_into_dyn_supertrait.rs30
-rw-r--r--compiler/rustc_lint/src/lints.rs18
3 files changed, 33 insertions, 18 deletions
diff --git a/compiler/rustc_error_messages/locales/en-US/lint.ftl b/compiler/rustc_error_messages/locales/en-US/lint.ftl
index 3fa52ff0eb3..d63ff77d8e2 100644
--- a/compiler/rustc_error_messages/locales/en-US/lint.ftl
+++ b/compiler/rustc_error_messages/locales/en-US/lint.ftl
@@ -457,6 +457,9 @@ lint_builtin_special_module_name_used_lib = found module declaration for lib.rs
 lint_builtin_special_module_name_used_main = found module declaration for main.rs
     .note = a binary crate cannot be used as library
 
+lint_supertrait_as_deref_target = `{$t}` implements `Deref` with supertrait `{$target_principal}` as target
+    .label = target type is set here
+
 lint_overruled_attribute = {$lint_level}({$lint_source}) incompatible with previous forbid
     .label = overruled by previous forbid
 
diff --git a/compiler/rustc_lint/src/deref_into_dyn_supertrait.rs b/compiler/rustc_lint/src/deref_into_dyn_supertrait.rs
index 1d29a234a3c..dff5a645c17 100644
--- a/compiler/rustc_lint/src/deref_into_dyn_supertrait.rs
+++ b/compiler/rustc_lint/src/deref_into_dyn_supertrait.rs
@@ -1,6 +1,8 @@
-use crate::{LateContext, LateLintPass, LintContext};
+use crate::{
+    lints::{SupertraitAsDerefTarget, SupertraitAsDerefTargetLabel},
+    LateContext, LateLintPass, LintContext,
+};
 
-use rustc_errors::DelayDm;
 use rustc_hir as hir;
 use rustc_middle::{traits::util::supertraits, ty};
 use rustc_span::sym;
@@ -71,22 +73,14 @@ impl<'tcx> LateLintPass<'tcx> for DerefIntoDynSupertrait {
             && supertraits(cx.tcx, t_principal.with_self_ty(cx.tcx, cx.tcx.types.trait_object_dummy_self))
                 .any(|sup| sup.map_bound(|x| ty::ExistentialTraitRef::erase_self_ty(cx.tcx, x)) == target_principal)
         {
-            cx.struct_span_lint(
-                DEREF_INTO_DYN_SUPERTRAIT,
-                cx.tcx.def_span(item.owner_id.def_id),
-                DelayDm(|| {
-                    format!(
-                        "`{t}` implements `Deref` with supertrait `{target_principal}` as target"
-                    )
-                }),
-                |lint| {
-                    if let Some(target_span) = impl_.items.iter().find_map(|i| (i.ident.name == sym::Target).then_some(i.span)) {
-                        lint.span_label(target_span, "target type is set here");
-                    }
-
-                    lint
-                },
-            )
+            let label = impl_.items.iter().find_map(|i| (i.ident.name == sym::Target).then_some(i.span)).map(|label| SupertraitAsDerefTargetLabel {
+                label,
+            });
+            cx.emit_spanned_lint(DEREF_INTO_DYN_SUPERTRAIT, cx.tcx.def_span(item.owner_id.def_id), SupertraitAsDerefTarget {
+                t,
+                target_principal: target_principal.to_string(),
+                label,
+            });
         }
     }
 }
diff --git a/compiler/rustc_lint/src/lints.rs b/compiler/rustc_lint/src/lints.rs
index a98d5cec979..c3782a49689 100644
--- a/compiler/rustc_lint/src/lints.rs
+++ b/compiler/rustc_lint/src/lints.rs
@@ -551,6 +551,24 @@ pub struct BuiltinUnexpectedCliConfigValue {
     pub value: Symbol,
 }
 
+// deref_into_dyn_supertrait.rs
+#[derive(LintDiagnostic)]
+#[diag(lint_supertrait_as_deref_target)]
+pub struct SupertraitAsDerefTarget<'a> {
+    pub t: Ty<'a>,
+    pub target_principal: String,
+    // pub target_principal: Binder<'a, ExistentialTraitRef<'b>>,
+    #[subdiagnostic]
+    pub label: Option<SupertraitAsDerefTargetLabel>,
+}
+
+#[derive(Subdiagnostic)]
+#[label(label)]
+pub struct SupertraitAsDerefTargetLabel {
+    #[primary_span]
+    pub label: Span,
+}
+
 // enum_intrinsics_non_enums.rs
 #[derive(LintDiagnostic)]
 #[diag(lint_enum_intrinsics_mem_discriminant)]