Skip to content

Commit 619cc4f

Browse files
Revert "Rollup merge of rust-lang#125572 - mu001999-contrib:dead/enhance, r=pnkfelix"
This reverts commit 13314df, reversing changes made to 6e534c7.
1 parent 4658b0a commit 619cc4f

32 files changed

+86
-270
lines changed

compiler/rustc_passes/src/dead.rs

+28-93
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ use rustc_hir::{Node, PatKind, TyKind};
1717
use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrFlags;
1818
use rustc_middle::middle::privacy::Level;
1919
use rustc_middle::query::Providers;
20-
use rustc_middle::ty::{self, AssocItemContainer, TyCtxt};
20+
use rustc_middle::ty::{self, TyCtxt};
2121
use rustc_middle::{bug, span_bug};
2222
use rustc_session::lint;
2323
use rustc_session::lint::builtin::DEAD_CODE;
@@ -44,63 +44,16 @@ fn should_explore(tcx: TyCtxt<'_>, def_id: LocalDefId) -> bool {
4444
)
4545
}
4646

47-
struct Publicness {
48-
ty_is_public: bool,
49-
ty_and_all_fields_are_public: bool,
50-
}
51-
52-
impl Publicness {
53-
fn new(ty_is_public: bool, ty_and_all_fields_are_public: bool) -> Self {
54-
Self { ty_is_public, ty_and_all_fields_are_public }
55-
}
56-
}
57-
58-
fn struct_all_fields_are_public(tcx: TyCtxt<'_>, id: DefId) -> bool {
59-
// treat PhantomData and positional ZST as public,
60-
// we don't want to lint types which only have them,
61-
// cause it's a common way to use such types to check things like well-formedness
62-
tcx.adt_def(id).all_fields().all(|field| {
63-
let field_type = tcx.type_of(field.did).instantiate_identity();
64-
if field_type.is_phantom_data() {
65-
return true;
66-
}
67-
let is_positional = field.name.as_str().starts_with(|c: char| c.is_ascii_digit());
68-
if is_positional
69-
&& tcx
70-
.layout_of(tcx.param_env(field.did).and(field_type))
71-
.map_or(true, |layout| layout.is_zst())
72-
{
73-
return true;
74-
}
75-
field.vis.is_public()
76-
})
77-
}
78-
79-
/// check struct and its fields are public or not,
80-
/// for enum and union, just check they are public,
81-
/// and doesn't solve types like &T for now, just skip them
82-
fn ty_ref_to_pub_struct(tcx: TyCtxt<'_>, ty: &hir::Ty<'_>) -> Publicness {
47+
fn ty_ref_to_pub_struct(tcx: TyCtxt<'_>, ty: &hir::Ty<'_>) -> bool {
8348
if let TyKind::Path(hir::QPath::Resolved(_, path)) = ty.kind
8449
&& let Res::Def(def_kind, def_id) = path.res
8550
&& def_id.is_local()
51+
&& matches!(def_kind, DefKind::Struct | DefKind::Enum | DefKind::Union)
8652
{
87-
return match def_kind {
88-
DefKind::Enum | DefKind::Union => {
89-
let ty_is_public = tcx.visibility(def_id).is_public();
90-
Publicness::new(ty_is_public, ty_is_public)
91-
}
92-
DefKind::Struct => {
93-
let ty_is_public = tcx.visibility(def_id).is_public();
94-
Publicness::new(
95-
ty_is_public,
96-
ty_is_public && struct_all_fields_are_public(tcx, def_id),
97-
)
98-
}
99-
_ => Publicness::new(true, true),
100-
};
53+
tcx.visibility(def_id).is_public()
54+
} else {
55+
true
10156
}
102-
103-
Publicness::new(true, true)
10457
}
10558

10659
/// Determine if a work from the worklist is coming from a `#[allow]`
@@ -499,11 +452,9 @@ impl<'tcx> MarkSymbolVisitor<'tcx> {
499452
{
500453
if !matches!(trait_item.kind, hir::TraitItemKind::Type(..))
501454
&& !ty_ref_to_pub_struct(self.tcx, impl_ref.self_ty)
502-
.ty_and_all_fields_are_public
503455
{
504-
// skip impl-items of non pure pub ty,
505-
// cause we don't know the ty is constructed or not,
506-
// check these later in `solve_rest_impl_items`
456+
// skip methods of private ty,
457+
// they would be solved in `solve_rest_impl_items`
507458
continue;
508459
}
509460

@@ -584,21 +535,22 @@ impl<'tcx> MarkSymbolVisitor<'tcx> {
584535
&& let Some(local_def_id) = def_id.as_local()
585536
&& matches!(def_kind, DefKind::Struct | DefKind::Enum | DefKind::Union)
586537
{
538+
if self.tcx.visibility(impl_item_id).is_public() {
539+
// for the public method, we don't know the trait item is used or not,
540+
// so we mark the method live if the self is used
541+
return self.live_symbols.contains(&local_def_id);
542+
}
543+
587544
if let Some(trait_item_id) = self.tcx.associated_item(impl_item_id).trait_item_def_id
588545
&& let Some(local_id) = trait_item_id.as_local()
589546
{
590-
// for the local impl item, we can know the trait item is used or not,
547+
// for the private method, we can know the trait item is used or not,
591548
// so we mark the method live if the self is used and the trait item is used
592-
self.live_symbols.contains(&local_id) && self.live_symbols.contains(&local_def_id)
593-
} else {
594-
// for the foreign method and inherent pub method,
595-
// we don't know the trait item or the method is used or not,
596-
// so we mark the method live if the self is used
597-
self.live_symbols.contains(&local_def_id)
549+
return self.live_symbols.contains(&local_id)
550+
&& self.live_symbols.contains(&local_def_id);
598551
}
599-
} else {
600-
false
601552
}
553+
false
602554
}
603555
}
604556

@@ -820,9 +772,7 @@ fn check_item<'tcx>(
820772
.iter()
821773
.filter_map(|def_id| def_id.as_local());
822774

823-
let self_ty = tcx.hir().item(id).expect_impl().self_ty;
824-
let Publicness { ty_is_public, ty_and_all_fields_are_public } =
825-
ty_ref_to_pub_struct(tcx, self_ty);
775+
let ty_is_pub = ty_ref_to_pub_struct(tcx, tcx.hir().item(id).expect_impl().self_ty);
826776

827777
// And we access the Map here to get HirId from LocalDefId
828778
for local_def_id in local_def_ids {
@@ -838,20 +788,18 @@ fn check_item<'tcx>(
838788
// for trait impl blocks,
839789
// mark the method live if the self_ty is public,
840790
// or the method is public and may construct self
841-
if of_trait && matches!(tcx.def_kind(local_def_id), DefKind::AssocTy)
842-
|| tcx.visibility(local_def_id).is_public()
843-
&& (ty_and_all_fields_are_public || may_construct_self)
791+
if of_trait
792+
&& (!matches!(tcx.def_kind(local_def_id), DefKind::AssocFn)
793+
|| tcx.visibility(local_def_id).is_public()
794+
&& (ty_is_pub || may_construct_self))
844795
{
845-
// if the impl item is public,
846-
// and the ty may be constructed or can be constructed in foreign crates,
847-
// mark the impl item live
848796
worklist.push((local_def_id, ComesFromAllowExpect::No));
849797
} else if let Some(comes_from_allow) =
850798
has_allow_dead_code_or_lang_attr(tcx, local_def_id)
851799
{
852800
worklist.push((local_def_id, comes_from_allow));
853-
} else if of_trait || tcx.visibility(local_def_id).is_public() && ty_is_public {
854-
// private impl items of traits || public impl items not constructs self
801+
} else if of_trait {
802+
// private method || public method not constructs self
855803
unsolved_impl_items.push((id, local_def_id));
856804
}
857805
}
@@ -918,14 +866,6 @@ fn create_and_seed_worklist(
918866
effective_vis
919867
.is_public_at_level(Level::Reachable)
920868
.then_some(id)
921-
.filter(|&id|
922-
// checks impls, impl-items and pub structs with all public fields later
923-
match tcx.def_kind(id) {
924-
DefKind::Impl { .. } => false,
925-
DefKind::AssocConst | DefKind::AssocFn => !matches!(tcx.associated_item(id).container, AssocItemContainer::ImplContainer),
926-
DefKind::Struct => struct_all_fields_are_public(tcx, id.to_def_id()),
927-
_ => true
928-
})
929869
.map(|id| (id, ComesFromAllowExpect::No))
930870
})
931871
// Seed entry point
@@ -1250,15 +1190,10 @@ fn check_mod_deathness(tcx: TyCtxt<'_>, module: LocalModDefId) {
12501190
|| (def_kind == DefKind::Trait && live_symbols.contains(&item.owner_id.def_id))
12511191
{
12521192
for &def_id in tcx.associated_item_def_ids(item.owner_id.def_id) {
1253-
// We have diagnosed unused assoc consts and fns in traits
1193+
// We have diagnosed unused methods in traits
12541194
if matches!(def_kind, DefKind::Impl { of_trait: true })
1255-
&& matches!(tcx.def_kind(def_id), DefKind::AssocConst | DefKind::AssocFn)
1256-
// skip unused public inherent methods,
1257-
// cause we have diagnosed unconstructed struct
1258-
|| matches!(def_kind, DefKind::Impl { of_trait: false })
1259-
&& tcx.visibility(def_id).is_public()
1260-
&& ty_ref_to_pub_struct(tcx, tcx.hir().item(item).expect_impl().self_ty).ty_is_public
1261-
|| def_kind == DefKind::Trait && tcx.def_kind(def_id) == DefKind::AssocTy
1195+
&& tcx.def_kind(def_id) == DefKind::AssocFn
1196+
|| def_kind == DefKind::Trait && tcx.def_kind(def_id) != DefKind::AssocFn
12621197
{
12631198
continue;
12641199
}

tests/codegen-units/item-collection/generic-impl.rs

+5-5
Original file line numberDiff line numberDiff line change
@@ -22,16 +22,16 @@ impl<T> Struct<T> {
2222
}
2323
}
2424

25-
pub struct _LifeTimeOnly<'a> {
25+
pub struct LifeTimeOnly<'a> {
2626
_a: &'a u32,
2727
}
2828

29-
impl<'a> _LifeTimeOnly<'a> {
30-
//~ MONO_ITEM fn _LifeTimeOnly::<'_>::foo
29+
impl<'a> LifeTimeOnly<'a> {
30+
//~ MONO_ITEM fn LifeTimeOnly::<'_>::foo
3131
pub fn foo(&self) {}
32-
//~ MONO_ITEM fn _LifeTimeOnly::<'_>::bar
32+
//~ MONO_ITEM fn LifeTimeOnly::<'_>::bar
3333
pub fn bar(&'a self) {}
34-
//~ MONO_ITEM fn _LifeTimeOnly::<'_>::baz
34+
//~ MONO_ITEM fn LifeTimeOnly::<'_>::baz
3535
pub fn baz<'b>(&'b self) {}
3636

3737
pub fn non_instantiated<T>(&self) {}

tests/codegen-units/item-collection/overloaded-operators.rs

+12-12
Original file line numberDiff line numberDiff line change
@@ -5,44 +5,44 @@
55

66
use std::ops::{Add, Deref, Index, IndexMut};
77

8-
pub struct _Indexable {
8+
pub struct Indexable {
99
data: [u8; 3],
1010
}
1111

12-
impl Index<usize> for _Indexable {
12+
impl Index<usize> for Indexable {
1313
type Output = u8;
1414

15-
//~ MONO_ITEM fn <_Indexable as std::ops::Index<usize>>::index
15+
//~ MONO_ITEM fn <Indexable as std::ops::Index<usize>>::index
1616
fn index(&self, index: usize) -> &Self::Output {
1717
if index >= 3 { &self.data[0] } else { &self.data[index] }
1818
}
1919
}
2020

21-
impl IndexMut<usize> for _Indexable {
22-
//~ MONO_ITEM fn <_Indexable as std::ops::IndexMut<usize>>::index_mut
21+
impl IndexMut<usize> for Indexable {
22+
//~ MONO_ITEM fn <Indexable as std::ops::IndexMut<usize>>::index_mut
2323
fn index_mut(&mut self, index: usize) -> &mut Self::Output {
2424
if index >= 3 { &mut self.data[0] } else { &mut self.data[index] }
2525
}
2626
}
2727

28-
//~ MONO_ITEM fn <_Equatable as std::cmp::PartialEq>::eq
29-
//~ MONO_ITEM fn <_Equatable as std::cmp::PartialEq>::ne
28+
//~ MONO_ITEM fn <Equatable as std::cmp::PartialEq>::eq
29+
//~ MONO_ITEM fn <Equatable as std::cmp::PartialEq>::ne
3030
#[derive(PartialEq)]
31-
pub struct _Equatable(u32);
31+
pub struct Equatable(u32);
3232

33-
impl Add<u32> for _Equatable {
33+
impl Add<u32> for Equatable {
3434
type Output = u32;
3535

36-
//~ MONO_ITEM fn <_Equatable as std::ops::Add<u32>>::add
36+
//~ MONO_ITEM fn <Equatable as std::ops::Add<u32>>::add
3737
fn add(self, rhs: u32) -> u32 {
3838
self.0 + rhs
3939
}
4040
}
4141

42-
impl Deref for _Equatable {
42+
impl Deref for Equatable {
4343
type Target = u32;
4444

45-
//~ MONO_ITEM fn <_Equatable as std::ops::Deref>::deref
45+
//~ MONO_ITEM fn <Equatable as std::ops::Deref>::deref
4646
fn deref(&self) -> &Self::Target {
4747
&self.0
4848
}

tests/ui/coherence/re-rebalance-coherence.rs

-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@
44
extern crate re_rebalance_coherence_lib as lib;
55
use lib::*;
66

7-
#[allow(dead_code)]
87
struct Oracle;
98
impl Backend for Oracle {}
109
impl<'a, T:'a, Tab> QueryFragment<Oracle> for BatchInsert<'a, T, Tab> {}

tests/ui/const-generics/defaults/repr-c-issue-82792.rs

-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22

33
//@ run-pass
44

5-
#[allow(dead_code)]
65
#[repr(C)]
76
pub struct Loaf<T: Sized, const N: usize = 1> {
87
head: [T; N],

tests/ui/const-generics/generic_const_exprs/associated-consts.rs

+1-2
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,7 @@ impl BlockCipher for BarCipher {
1616
const BLOCK_SIZE: usize = 32;
1717
}
1818

19-
#[allow(dead_code)]
20-
pub struct Block<C>(C);
19+
pub struct Block<C>(#[allow(dead_code)] C);
2120

2221
pub fn test<C: BlockCipher, const M: usize>()
2322
where

tests/ui/const-generics/transparent-maybeunit-array-wrapper.rs

-1
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@
66

77
use std::mem::MaybeUninit;
88

9-
#[allow(dead_code)]
109
#[repr(transparent)]
1110
pub struct MaybeUninitWrapper<const N: usize>(MaybeUninit<[u64; N]>);
1211

tests/ui/derives/clone-debug-dead-code-in-the-same-struct.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
#![forbid(dead_code)]
22

33
#[derive(Debug)]
4-
pub struct Whatever { //~ ERROR struct `Whatever` is never constructed
4+
pub struct Whatever {
55
pub field0: (),
6-
field1: (),
6+
field1: (), //~ ERROR fields `field1`, `field2`, `field3`, and `field4` are never read
77
field2: (),
88
field3: (),
99
field4: (),

tests/ui/derives/clone-debug-dead-code-in-the-same-struct.stderr

+13-3
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,19 @@
1-
error: struct `Whatever` is never constructed
2-
--> $DIR/clone-debug-dead-code-in-the-same-struct.rs:4:12
1+
error: fields `field1`, `field2`, `field3`, and `field4` are never read
2+
--> $DIR/clone-debug-dead-code-in-the-same-struct.rs:6:5
33
|
44
LL | pub struct Whatever {
5-
| ^^^^^^^^
5+
| -------- fields in this struct
6+
LL | pub field0: (),
7+
LL | field1: (),
8+
| ^^^^^^
9+
LL | field2: (),
10+
| ^^^^^^
11+
LL | field3: (),
12+
| ^^^^^^
13+
LL | field4: (),
14+
| ^^^^^^
615
|
16+
= note: `Whatever` has a derived impl for the trait `Debug`, but this is intentionally ignored during dead code analysis
717
note: the lint level is defined here
818
--> $DIR/clone-debug-dead-code-in-the-same-struct.rs:1:11
919
|

tests/ui/issues/issue-5708.rs

-1
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,6 @@ pub trait MyTrait<T> {
4444
fn dummy(&self, t: T) -> T { panic!() }
4545
}
4646

47-
#[allow(dead_code)]
4847
pub struct MyContainer<'a, T:'a> {
4948
foos: Vec<&'a (dyn MyTrait<T>+'a)> ,
5049
}

tests/ui/lint/dead-code/lint-dead-code-1.rs

+3-2
Original file line numberDiff line numberDiff line change
@@ -46,10 +46,11 @@ struct SemiUsedStruct;
4646
impl SemiUsedStruct {
4747
fn la_la_la() {}
4848
}
49-
struct StructUsedAsField; //~ ERROR struct `StructUsedAsField` is never constructed
49+
struct StructUsedAsField;
5050
pub struct StructUsedInEnum;
5151
struct StructUsedInGeneric;
52-
pub struct PubStruct2 { //~ ERROR struct `PubStruct2` is never constructed
52+
pub struct PubStruct2 {
53+
#[allow(dead_code)]
5354
struct_used_as_field: *const StructUsedAsField
5455
}
5556

0 commit comments

Comments
 (0)