@@ -17,7 +17,7 @@ use rustc_hir::{Node, PatKind, TyKind};
17
17
use rustc_middle:: middle:: codegen_fn_attrs:: CodegenFnAttrFlags ;
18
18
use rustc_middle:: middle:: privacy:: Level ;
19
19
use rustc_middle:: query:: Providers ;
20
- use rustc_middle:: ty:: { self , AssocItemContainer , TyCtxt } ;
20
+ use rustc_middle:: ty:: { self , TyCtxt } ;
21
21
use rustc_middle:: { bug, span_bug} ;
22
22
use rustc_session:: lint;
23
23
use rustc_session:: lint:: builtin:: DEAD_CODE ;
@@ -44,63 +44,16 @@ fn should_explore(tcx: TyCtxt<'_>, def_id: LocalDefId) -> bool {
44
44
)
45
45
}
46
46
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 {
83
48
if let TyKind :: Path ( hir:: QPath :: Resolved ( _, path) ) = ty. kind
84
49
&& let Res :: Def ( def_kind, def_id) = path. res
85
50
&& def_id. is_local ( )
51
+ && matches ! ( def_kind, DefKind :: Struct | DefKind :: Enum | DefKind :: Union )
86
52
{
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
101
56
}
102
-
103
- Publicness :: new ( true , true )
104
57
}
105
58
106
59
/// Determine if a work from the worklist is coming from a `#[allow]`
@@ -499,11 +452,9 @@ impl<'tcx> MarkSymbolVisitor<'tcx> {
499
452
{
500
453
if !matches ! ( trait_item. kind, hir:: TraitItemKind :: Type ( ..) )
501
454
&& !ty_ref_to_pub_struct ( self . tcx , impl_ref. self_ty )
502
- . ty_and_all_fields_are_public
503
455
{
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`
507
458
continue ;
508
459
}
509
460
@@ -584,21 +535,22 @@ impl<'tcx> MarkSymbolVisitor<'tcx> {
584
535
&& let Some ( local_def_id) = def_id. as_local ( )
585
536
&& matches ! ( def_kind, DefKind :: Struct | DefKind :: Enum | DefKind :: Union )
586
537
{
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
+
587
544
if let Some ( trait_item_id) = self . tcx . associated_item ( impl_item_id) . trait_item_def_id
588
545
&& let Some ( local_id) = trait_item_id. as_local ( )
589
546
{
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,
591
548
// 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) ;
598
551
}
599
- } else {
600
- false
601
552
}
553
+ false
602
554
}
603
555
}
604
556
@@ -820,9 +772,7 @@ fn check_item<'tcx>(
820
772
. iter ( )
821
773
. filter_map ( |def_id| def_id. as_local ( ) ) ;
822
774
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 ) ;
826
776
827
777
// And we access the Map here to get HirId from LocalDefId
828
778
for local_def_id in local_def_ids {
@@ -838,20 +788,18 @@ fn check_item<'tcx>(
838
788
// for trait impl blocks,
839
789
// mark the method live if the self_ty is public,
840
790
// 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) )
844
795
{
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
848
796
worklist. push ( ( local_def_id, ComesFromAllowExpect :: No ) ) ;
849
797
} else if let Some ( comes_from_allow) =
850
798
has_allow_dead_code_or_lang_attr ( tcx, local_def_id)
851
799
{
852
800
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
855
803
unsolved_impl_items. push ( ( id, local_def_id) ) ;
856
804
}
857
805
}
@@ -918,14 +866,6 @@ fn create_and_seed_worklist(
918
866
effective_vis
919
867
. is_public_at_level ( Level :: Reachable )
920
868
. 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
- } )
929
869
. map ( |id| ( id, ComesFromAllowExpect :: No ) )
930
870
} )
931
871
// Seed entry point
@@ -1250,15 +1190,10 @@ fn check_mod_deathness(tcx: TyCtxt<'_>, module: LocalModDefId) {
1250
1190
|| ( def_kind == DefKind :: Trait && live_symbols. contains ( & item. owner_id . def_id ) )
1251
1191
{
1252
1192
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
1254
1194
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
1262
1197
{
1263
1198
continue ;
1264
1199
}
0 commit comments