Skip to content

Commit

Permalink
Detect unused associated constants in traits
Browse files Browse the repository at this point in the history
  • Loading branch information
mu001999 committed May 26, 2024
1 parent 5a08af0 commit 9bc0e5b
Show file tree
Hide file tree
Showing 3 changed files with 40 additions and 16 deletions.
23 changes: 7 additions & 16 deletions compiler/rustc_passes/src/dead.rs
Original file line number Diff line number Diff line change
Expand Up @@ -786,18 +786,9 @@ fn check_item<'tcx>(
// for trait impl blocks,
// mark the method live if the self_ty is public,
// or the method is public and may construct self
if of_trait
&& (!matches!(tcx.def_kind(local_def_id), DefKind::AssocFn)
|| tcx.visibility(local_def_id).is_public()
&& (ty_is_pure_pub || may_construct_self))
{
// if the impl item is public,
// and the ty may be constructed or can be constructed in foreign crates,
// mark the impl item live
worklist.push((local_def_id, ComesFromAllowExpect::No));
} else if !of_trait
&& tcx.visibility(local_def_id).is_public()
&& (ty_is_pure_pub || may_construct_self)
if of_trait && matches!(tcx.def_kind(local_def_id), DefKind::AssocTy)
|| tcx.visibility(local_def_id).is_public()
&& (ty_is_pure_pub || may_construct_self)
{
// if the impl item is public,
// and the ty may be constructed or can be constructed in foreign crates,
Expand Down Expand Up @@ -882,7 +873,7 @@ fn create_and_seed_worklist(
// checks impls, impl-items and pub structs with all public fields later
match tcx.def_kind(id) {
DefKind::Impl { .. } => false,
DefKind::AssocFn => !matches!(tcx.associated_item(id).container, AssocItemContainer::ImplContainer),
DefKind::AssocConst | DefKind::AssocFn => !matches!(tcx.associated_item(id).container, AssocItemContainer::ImplContainer),
DefKind::Struct => struct_all_fields_are_public(tcx, id.to_def_id()),
_ => true
})
Expand Down Expand Up @@ -1158,13 +1149,13 @@ fn check_mod_deathness(tcx: TyCtxt<'_>, module: LocalModDefId) {
|| (def_kind == DefKind::Trait && live_symbols.contains(&item.owner_id.def_id))
{
for &def_id in tcx.associated_item_def_ids(item.owner_id.def_id) {
// We have diagnosed unused methods in traits
// We have diagnosed unused assoc consts and fns in traits
if matches!(def_kind, DefKind::Impl { of_trait: true })
&& tcx.def_kind(def_id) == DefKind::AssocFn
&& matches!(tcx.def_kind(def_id), DefKind::AssocConst | DefKind::AssocFn)
// skip unused public inherent methods,
// cause we have diagnosed unconstructed struct
|| matches!(def_kind, DefKind::Impl { of_trait: false }) && tcx.visibility(def_id).is_public() && ty_ref_to_pub_struct(tcx, tcx.hir().item(item).expect_impl().self_ty)
|| def_kind == DefKind::Trait && tcx.def_kind(def_id) != DefKind::AssocFn
|| def_kind == DefKind::Trait && tcx.def_kind(def_id) == DefKind::AssocTy
{
continue;
}
Expand Down
17 changes: 17 additions & 0 deletions tests/ui/lint/dead-code/unused_assoc_const.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
#![deny(dead_code)]

trait Trait {
const I: i32; //~ ERROR associated constant `I` is never used

fn foo(&self) {}
}

pub struct T(());

impl Trait for T {
const I: i32 = 0;
}

fn main() {
T(()).foo();
}
16 changes: 16 additions & 0 deletions tests/ui/lint/dead-code/unused_assoc_const.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
error: associated constant `I` is never used
--> $DIR/unused_assoc_const.rs:4:11
|
LL | trait Trait {
| ----- associated constant in this trait
LL | const I: i32;
| ^
|
note: the lint level is defined here
--> $DIR/unused_assoc_const.rs:1:9
|
LL | #![deny(dead_code)]
| ^^^^^^^^^

error: aborting due to 1 previous error

0 comments on commit 9bc0e5b

Please sign in to comment.