@@ -425,10 +425,11 @@ impl<'tcx> MarkSymbolVisitor<'tcx> {
425
425
&& let ItemKind :: Impl ( impl_ref) =
426
426
self . tcx . hir ( ) . expect_item ( local_impl_id) . kind
427
427
{
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 ( ..) )
430
429
&& !ty_ref_to_pub_struct ( self . tcx , impl_ref. self_ty )
431
430
{
431
+ // skip methods of private ty,
432
+ // they would be solved in `solve_rest_impl_items`
432
433
continue ;
433
434
}
434
435
@@ -485,32 +486,46 @@ impl<'tcx> MarkSymbolVisitor<'tcx> {
485
486
486
487
fn solve_rest_impl_items ( & mut self , mut unsolved_impl_items : Vec < ( hir:: ItemId , LocalDefId ) > ) {
487
488
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
+ } ) ;
491
493
492
494
while !ready. is_empty ( ) {
493
495
self . worklist =
494
496
ready. into_iter ( ) . map ( |( _, id) | ( id, ComesFromAllowExpect :: No ) ) . collect ( ) ;
495
497
self . mark_live_symbols ( ) ;
496
498
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
+ } ) ;
500
503
}
501
504
}
502
505
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 {
504
507
if let TyKind :: Path ( hir:: QPath :: Resolved ( _, path) ) =
505
508
self . tcx . hir ( ) . item ( impl_id) . expect_impl ( ) . self_ty . kind
506
509
&& let Res :: Def ( def_kind, def_id) = path. res
507
510
&& let Some ( local_def_id) = def_id. as_local ( )
508
511
&& matches ! ( def_kind, DefKind :: Struct | DefKind :: Enum | DefKind :: Union )
509
512
{
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
+ }
513
527
}
528
+ false
514
529
}
515
530
}
516
531
@@ -745,20 +760,22 @@ fn check_item<'tcx>(
745
760
matches ! ( fn_sig. decl. implicit_self, hir:: ImplicitSelfKind :: None ) ;
746
761
}
747
762
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
749
766
if of_trait
750
767
&& ( !matches ! ( tcx. def_kind( local_def_id) , DefKind :: AssocFn )
751
768
|| tcx. visibility ( local_def_id) . is_public ( )
752
769
&& ( ty_is_pub || may_construct_self) )
753
770
{
754
771
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) ) ;
758
772
} else if let Some ( comes_from_allow) =
759
773
has_allow_dead_code_or_lang_attr ( tcx, local_def_id)
760
774
{
761
775
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) ) ;
762
779
}
763
780
}
764
781
}
0 commit comments