@@ -425,10 +425,11 @@ impl<'tcx> MarkSymbolVisitor<'tcx> {
425425 && let ItemKind :: Impl ( impl_ref) =
426426 self . tcx . hir ( ) . expect_item ( local_impl_id) . kind
427427 {
428- if self . tcx . visibility ( trait_id) . is_public ( )
429- && matches ! ( trait_item. kind, hir:: TraitItemKind :: Fn ( ..) )
428+ if matches ! ( trait_item. kind, hir:: TraitItemKind :: Fn ( ..) )
430429 && !ty_ref_to_pub_struct ( self . tcx , impl_ref. self_ty )
431430 {
431+ // skip methods of private ty,
432+ // they would be solved in `solve_rest_impl_items`
432433 continue ;
433434 }
434435
@@ -485,32 +486,46 @@ impl<'tcx> MarkSymbolVisitor<'tcx> {
485486
486487 fn solve_rest_impl_items ( & mut self , mut unsolved_impl_items : Vec < ( hir:: ItemId , LocalDefId ) > ) {
487488 let mut ready;
488- ( ready, unsolved_impl_items) = unsolved_impl_items
489- . into_iter ( )
490- . partition ( |& ( impl_id, _) | self . impl_item_with_used_self ( impl_id) ) ;
489+ ( ready, unsolved_impl_items) =
490+ unsolved_impl_items. into_iter ( ) . partition ( |& ( impl_id, impl_item_id) | {
491+ self . impl_item_with_used_self ( impl_id, impl_item_id)
492+ } ) ;
491493
492494 while !ready. is_empty ( ) {
493495 self . worklist =
494496 ready. into_iter ( ) . map ( |( _, id) | ( id, ComesFromAllowExpect :: No ) ) . collect ( ) ;
495497 self . mark_live_symbols ( ) ;
496498
497- ( ready, unsolved_impl_items) = unsolved_impl_items
498- . into_iter ( )
499- . partition ( |& ( impl_id, _) | self . impl_item_with_used_self ( impl_id) ) ;
499+ ( ready, unsolved_impl_items) =
500+ unsolved_impl_items. into_iter ( ) . partition ( |& ( impl_id, impl_item_id) | {
501+ self . impl_item_with_used_self ( impl_id, impl_item_id)
502+ } ) ;
500503 }
501504 }
502505
503- fn impl_item_with_used_self ( & mut self , impl_id : hir:: ItemId ) -> bool {
506+ fn impl_item_with_used_self ( & mut self , impl_id : hir:: ItemId , impl_item_id : LocalDefId ) -> bool {
504507 if let TyKind :: Path ( hir:: QPath :: Resolved ( _, path) ) =
505508 self . tcx . hir ( ) . item ( impl_id) . expect_impl ( ) . self_ty . kind
506509 && let Res :: Def ( def_kind, def_id) = path. res
507510 && let Some ( local_def_id) = def_id. as_local ( )
508511 && matches ! ( def_kind, DefKind :: Struct | DefKind :: Enum | DefKind :: Union )
509512 {
510- self . live_symbols . contains ( & local_def_id)
511- } else {
512- false
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+
519+ if let Some ( trait_item_id) = self . tcx . associated_item ( impl_item_id) . trait_item_def_id
520+ && let Some ( local_id) = trait_item_id. as_local ( )
521+ {
522+ // for the private method, we can know the trait item is used or not,
523+ // so we mark the method live if the self is used and the trait item is used
524+ return self . live_symbols . contains ( & local_id)
525+ && self . live_symbols . contains ( & local_def_id) ;
526+ }
513527 }
528+ false
514529 }
515530}
516531
@@ -745,20 +760,22 @@ fn check_item<'tcx>(
745760 matches ! ( fn_sig. decl. implicit_self, hir:: ImplicitSelfKind :: None ) ;
746761 }
747762
748- // for impl trait blocks, mark associate functions live if the trait is public
763+ // for trait impl blocks,
764+ // mark the method live if the self_ty is public,
765+ // or the method is public and may construct self
749766 if of_trait
750767 && ( !matches ! ( tcx. def_kind( local_def_id) , DefKind :: AssocFn )
751768 || tcx. visibility ( local_def_id) . is_public ( )
752769 && ( ty_is_pub || may_construct_self) )
753770 {
754771 worklist. push ( ( local_def_id, ComesFromAllowExpect :: No ) ) ;
755- } else if of_trait && tcx. visibility ( local_def_id) . is_public ( ) {
756- // pub method && private ty & methods not construct self
757- unsolved_impl_items. push ( ( id, local_def_id) ) ;
758772 } else if let Some ( comes_from_allow) =
759773 has_allow_dead_code_or_lang_attr ( tcx, local_def_id)
760774 {
761775 worklist. push ( ( local_def_id, comes_from_allow) ) ;
776+ } else if of_trait {
777+ // private method || public method not constructs self
778+ unsolved_impl_items. push ( ( id, local_def_id) ) ;
762779 }
763780 }
764781 }
0 commit comments