about summary refs log tree commit diff
diff options
context:
space:
mode:
authorlong-long-float <niinikazuki@yahoo.co.jp>2024-04-28 14:45:06 +0900
committerlong-long-float <niinikazuki@yahoo.co.jp>2024-06-16 18:33:51 +0900
commitd630f5da7a24e225a9547301e6a7c634f67aad79 (patch)
treeb22badb6de21ca1138abb1765ebe52bd230cf3b6
parent5639c21fb38d26a72420fe627be25d4f6dfc1f3b (diff)
downloadrust-d630f5da7a24e225a9547301e6a7c634f67aad79.tar.gz
rust-d630f5da7a24e225a9547301e6a7c634f67aad79.zip
Show notice about "never used" for enum
-rw-r--r--compiler/rustc_passes/src/dead.rs19
-rw-r--r--tests/ui/lint/dead-code/unused-variant.rs15
-rw-r--r--tests/ui/lint/dead-code/unused-variant.stderr22
3 files changed, 55 insertions, 1 deletions
diff --git a/compiler/rustc_passes/src/dead.rs b/compiler/rustc_passes/src/dead.rs
index 6a74ddc5508..142cfc05598 100644
--- a/compiler/rustc_passes/src/dead.rs
+++ b/compiler/rustc_passes/src/dead.rs
@@ -1011,6 +1011,22 @@ impl<'tcx> DeadVisitor<'tcx> {
         parent_item: Option<LocalDefId>,
         report_on: ReportOn,
     ) {
+        fn get_parent_if_enum_variant<'tcx>(
+            tcx: TyCtxt<'tcx>,
+            may_variant: LocalDefId,
+        ) -> LocalDefId {
+            if let Node::Variant(_) = tcx.hir_node_by_def_id(may_variant)
+                && let Some(enum_did) = tcx.opt_parent(may_variant.to_def_id())
+                && let Some(enum_local_id) = enum_did.as_local()
+                && let Node::Item(item) = tcx.hir_node_by_def_id(enum_local_id)
+                && let ItemKind::Enum(_, _) = item.kind
+            {
+                enum_local_id
+            } else {
+                may_variant
+            }
+        }
+
         let Some(&first_item) = dead_codes.first() else {
             return;
         };
@@ -1054,6 +1070,9 @@ impl<'tcx> DeadVisitor<'tcx> {
         };
 
         let encl_def_id = parent_item.unwrap_or(first_item.def_id);
+        // If parent of encl_def_id is an enum, use the parent ID intead.
+        let encl_def_id = get_parent_if_enum_variant(tcx, encl_def_id);
+
         let ignored_derived_impls =
             if let Some(ign_traits) = self.ignored_derived_traits.get(&encl_def_id) {
                 let trait_list = ign_traits
diff --git a/tests/ui/lint/dead-code/unused-variant.rs b/tests/ui/lint/dead-code/unused-variant.rs
index 82108fa9c13..7030681eb36 100644
--- a/tests/ui/lint/dead-code/unused-variant.rs
+++ b/tests/ui/lint/dead-code/unused-variant.rs
@@ -6,7 +6,22 @@ enum Enum {
     Variant2,
 }
 
+#[derive(Debug)]
+enum TupleVariant {
+    Variant1(i32), //~ ERROR: variant `Variant1` is never constructed
+    Variant2,
+}
+
+#[derive(Debug)]
+enum StructVariant {
+    Variant1 { id: i32 }, //~ ERROR: variant `Variant1` is never constructed
+    Variant2,
+}
+
 fn main() {
     let e = Enum::Variant2;
     e.clone();
+
+    let _ = TupleVariant::Variant2;
+    let _ = StructVariant::Variant2;
 }
diff --git a/tests/ui/lint/dead-code/unused-variant.stderr b/tests/ui/lint/dead-code/unused-variant.stderr
index 0ae15fde47b..4bc8cf420da 100644
--- a/tests/ui/lint/dead-code/unused-variant.stderr
+++ b/tests/ui/lint/dead-code/unused-variant.stderr
@@ -13,5 +13,25 @@ note: the lint level is defined here
 LL | #![deny(dead_code)]
    |         ^^^^^^^^^
 
-error: aborting due to 1 previous error
+error: variant `Variant1` is never constructed
+  --> $DIR/unused-variant.rs:11:5
+   |
+LL | enum TupleVariant {
+   |      ------------ variant in this enum
+LL |     Variant1(i32),
+   |     ^^^^^^^^
+   |
+   = note: `TupleVariant` has a derived impl for the trait `Debug`, but this is intentionally ignored during dead code analysis
+
+error: variant `Variant1` is never constructed
+  --> $DIR/unused-variant.rs:17:5
+   |
+LL | enum StructVariant {
+   |      ------------- variant in this enum
+LL |     Variant1 { id: i32 },
+   |     ^^^^^^^^
+   |
+   = note: `StructVariant` has a derived impl for the trait `Debug`, but this is intentionally ignored during dead code analysis
+
+error: aborting due to 3 previous errors