From d630f5da7a24e225a9547301e6a7c634f67aad79 Mon Sep 17 00:00:00 2001 From: long-long-float Date: Sun, 28 Apr 2024 14:45:06 +0900 Subject: [PATCH] Show notice about "never used" for enum --- compiler/rustc_passes/src/dead.rs | 19 ++++++++++++++++ tests/ui/lint/dead-code/unused-variant.rs | 15 +++++++++++++ tests/ui/lint/dead-code/unused-variant.stderr | 22 ++++++++++++++++++- 3 files changed, 55 insertions(+), 1 deletion(-) diff --git a/compiler/rustc_passes/src/dead.rs b/compiler/rustc_passes/src/dead.rs index 6a74ddc5508a7..142cfc0559895 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, 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 82108fa9c13bf..7030681eb36d9 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 0ae15fde47b05..4bc8cf420da7b 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