@@ -15,7 +15,7 @@ use rustc_hir::{Node, PatKind, TyKind};
1515use rustc_middle:: middle:: codegen_fn_attrs:: CodegenFnAttrFlags ;
1616use rustc_middle:: middle:: privacy:: Level ;
1717use rustc_middle:: query:: Providers ;
18- use rustc_middle:: ty:: { self , AssocItemContainer , TyCtxt } ;
18+ use rustc_middle:: ty:: { self , TyCtxt } ;
1919use rustc_middle:: { bug, span_bug} ;
2020use rustc_session:: lint;
2121use 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 the a `#[allow]`
@@ -474,11 +427,9 @@ impl<'tcx> MarkSymbolVisitor<'tcx> {
474427 {
475428 if matches ! ( trait_item. kind, hir:: TraitItemKind :: Fn ( ..) )
476429 && !ty_ref_to_pub_struct ( self . tcx , impl_ref. self_ty )
477- . ty_and_all_fields_are_public
478430 {
479- // skip impl-items of non pure pub ty,
480- // cause we don't know the ty is constructed or not,
481- // check these later in `solve_rest_impl_items`
431+ // skip methods of private ty,
432+ // they would be solved in `solve_rest_impl_items`
482433 continue ;
483434 }
484435
@@ -559,21 +510,22 @@ impl<'tcx> MarkSymbolVisitor<'tcx> {
559510 && let Some ( local_def_id) = def_id. as_local ( )
560511 && matches ! ( def_kind, DefKind :: Struct | DefKind :: Enum | DefKind :: Union )
561512 {
513+ if self . tcx . visibility ( impl_item_id) . is_public ( ) {
514+ // for the public method, we don't know the trait item is used or not,
515+ // so we mark the method live if the self is used
516+ return self . live_symbols . contains ( & local_def_id) ;
517+ }
518+
562519 if let Some ( trait_item_id) = self . tcx . associated_item ( impl_item_id) . trait_item_def_id
563520 && let Some ( local_id) = trait_item_id. as_local ( )
564521 {
565- // for the local impl item , we can know the trait item is used or not,
522+ // for the private method , we can know the trait item is used or not,
566523 // so we mark the method live if the self is used and the trait item is used
567- self . live_symbols . contains ( & local_id) && self . live_symbols . contains ( & local_def_id)
568- } else {
569- // for the foreign method and inherent pub method,
570- // we don't know the trait item or the method is used or not,
571- // so we mark the method live if the self is used
572- self . live_symbols . contains ( & local_def_id)
524+ return self . live_symbols . contains ( & local_id)
525+ && self . live_symbols . contains ( & local_def_id) ;
573526 }
574- } else {
575- false
576527 }
528+ false
577529 }
578530}
579531
@@ -795,9 +747,7 @@ fn check_item<'tcx>(
795747 . iter ( )
796748 . filter_map ( |def_id| def_id. as_local ( ) ) ;
797749
798- let self_ty = tcx. hir ( ) . item ( id) . expect_impl ( ) . self_ty ;
799- let Publicness { ty_is_public, ty_and_all_fields_are_public } =
800- ty_ref_to_pub_struct ( tcx, self_ty) ;
750+ let ty_is_pub = ty_ref_to_pub_struct ( tcx, tcx. hir ( ) . item ( id) . expect_impl ( ) . self_ty ) ;
801751
802752 // And we access the Map here to get HirId from LocalDefId
803753 for local_def_id in local_def_ids {
@@ -813,20 +763,18 @@ fn check_item<'tcx>(
813763 // for trait impl blocks,
814764 // mark the method live if the self_ty is public,
815765 // or the method is public and may construct self
816- if of_trait && matches ! ( tcx. def_kind( local_def_id) , DefKind :: AssocTy )
817- || tcx. visibility ( local_def_id) . is_public ( )
818- && ( ty_and_all_fields_are_public || may_construct_self)
766+ if of_trait
767+ && ( !matches ! ( tcx. def_kind( local_def_id) , DefKind :: AssocFn )
768+ || tcx. visibility ( local_def_id) . is_public ( )
769+ && ( ty_is_pub || may_construct_self) )
819770 {
820- // if the impl item is public,
821- // and the ty may be constructed or can be constructed in foreign crates,
822- // mark the impl item live
823771 worklist. push ( ( local_def_id, ComesFromAllowExpect :: No ) ) ;
824772 } else if let Some ( comes_from_allow) =
825773 has_allow_dead_code_or_lang_attr ( tcx, local_def_id)
826774 {
827775 worklist. push ( ( local_def_id, comes_from_allow) ) ;
828- } else if of_trait || tcx . visibility ( local_def_id ) . is_public ( ) && ty_is_public {
829- // private impl items of traits || public impl items not constructs self
776+ } else if of_trait {
777+ // private method || public method not constructs self
830778 unsolved_impl_items. push ( ( id, local_def_id) ) ;
831779 }
832780 }
@@ -893,14 +841,6 @@ fn create_and_seed_worklist(
893841 effective_vis
894842 . is_public_at_level ( Level :: Reachable )
895843 . then_some ( id)
896- . filter ( |& id|
897- // checks impls, impl-items and pub structs with all public fields later
898- match tcx. def_kind ( id) {
899- DefKind :: Impl { .. } => false ,
900- DefKind :: AssocConst | DefKind :: AssocFn => !matches ! ( tcx. associated_item( id) . container, AssocItemContainer :: ImplContainer ) ,
901- DefKind :: Struct => struct_all_fields_are_public ( tcx, id. to_def_id ( ) ) || has_allow_dead_code_or_lang_attr ( tcx, id) . is_some ( ) ,
902- _ => true
903- } )
904844 . map ( |id| ( id, ComesFromAllowExpect :: No ) )
905845 } )
906846 // Seed entry point
@@ -1173,15 +1113,10 @@ fn check_mod_deathness(tcx: TyCtxt<'_>, module: LocalModDefId) {
11731113 || ( def_kind == DefKind :: Trait && live_symbols. contains ( & item. owner_id . def_id ) )
11741114 {
11751115 for & def_id in tcx. associated_item_def_ids ( item. owner_id . def_id ) {
1176- // We have diagnosed unused assoc consts and fns in traits
1116+ // We have diagnosed unused methods in traits
11771117 if matches ! ( def_kind, DefKind :: Impl { of_trait: true } )
1178- && matches ! ( tcx. def_kind( def_id) , DefKind :: AssocConst | DefKind :: AssocFn )
1179- // skip unused public inherent methods,
1180- // cause we have diagnosed unconstructed struct
1181- || matches ! ( def_kind, DefKind :: Impl { of_trait: false } )
1182- && tcx. visibility ( def_id) . is_public ( )
1183- && ty_ref_to_pub_struct ( tcx, tcx. hir ( ) . item ( item) . expect_impl ( ) . self_ty ) . ty_is_public
1184- || def_kind == DefKind :: Trait && tcx. def_kind ( def_id) == DefKind :: AssocTy
1118+ && tcx. def_kind ( def_id) == DefKind :: AssocFn
1119+ || def_kind == DefKind :: Trait && tcx. def_kind ( def_id) != DefKind :: AssocFn
11851120 {
11861121 continue ;
11871122 }
0 commit comments