@@ -427,10 +427,11 @@ impl<'tcx> MarkSymbolVisitor<'tcx> {
427
427
&& let ItemKind :: Impl ( impl_ref) =
428
428
self . tcx . hir ( ) . expect_item ( local_impl_id) . kind
429
429
{
430
- if self . tcx . visibility ( trait_id) . is_public ( )
431
- && matches ! ( trait_item. kind, hir:: TraitItemKind :: Fn ( ..) )
430
+ if matches ! ( trait_item. kind, hir:: TraitItemKind :: Fn ( ..) )
432
431
&& !ty_ref_to_pub_struct ( self . tcx , impl_ref. self_ty )
433
432
{
433
+ // skip methods of private ty,
434
+ // they would be solved in `solve_rest_impl_items`
434
435
continue ;
435
436
}
436
437
@@ -487,32 +488,46 @@ impl<'tcx> MarkSymbolVisitor<'tcx> {
487
488
488
489
fn solve_rest_impl_items ( & mut self , mut unsolved_impl_items : Vec < ( hir:: ItemId , LocalDefId ) > ) {
489
490
let mut ready;
490
- ( ready, unsolved_impl_items) = unsolved_impl_items
491
- . into_iter ( )
492
- . partition ( |& ( impl_id, _) | self . impl_item_with_used_self ( impl_id) ) ;
491
+ ( ready, unsolved_impl_items) =
492
+ unsolved_impl_items. into_iter ( ) . partition ( |& ( impl_id, impl_item_id) | {
493
+ self . impl_item_with_used_self ( impl_id, impl_item_id)
494
+ } ) ;
493
495
494
496
while !ready. is_empty ( ) {
495
497
self . worklist =
496
498
ready. into_iter ( ) . map ( |( _, id) | ( id, ComesFromAllowExpect :: No ) ) . collect ( ) ;
497
499
self . mark_live_symbols ( ) ;
498
500
499
- ( ready, unsolved_impl_items) = unsolved_impl_items
500
- . into_iter ( )
501
- . partition ( |& ( impl_id, _) | self . impl_item_with_used_self ( impl_id) ) ;
501
+ ( ready, unsolved_impl_items) =
502
+ unsolved_impl_items. into_iter ( ) . partition ( |& ( impl_id, impl_item_id) | {
503
+ self . impl_item_with_used_self ( impl_id, impl_item_id)
504
+ } ) ;
502
505
}
503
506
}
504
507
505
- fn impl_item_with_used_self ( & mut self , impl_id : hir:: ItemId ) -> bool {
508
+ fn impl_item_with_used_self ( & mut self , impl_id : hir:: ItemId , impl_item_id : LocalDefId ) -> bool {
506
509
if let TyKind :: Path ( hir:: QPath :: Resolved ( _, path) ) =
507
510
self . tcx . hir ( ) . item ( impl_id) . expect_impl ( ) . self_ty . kind
508
511
&& let Res :: Def ( def_kind, def_id) = path. res
509
512
&& let Some ( local_def_id) = def_id. as_local ( )
510
513
&& matches ! ( def_kind, DefKind :: Struct | DefKind :: Enum | DefKind :: Union )
511
514
{
512
- self . live_symbols . contains ( & local_def_id)
513
- } else {
514
- false
515
+ if self . tcx . visibility ( impl_item_id) . is_public ( ) {
516
+ // for the public method, we don't know the trait item is used or not,
517
+ // so we mark the method live if the self is used
518
+ return self . live_symbols . contains ( & local_def_id) ;
519
+ }
520
+
521
+ if let Some ( trait_item_id) = self . tcx . associated_item ( impl_item_id) . trait_item_def_id
522
+ && let Some ( local_id) = trait_item_id. as_local ( )
523
+ {
524
+ // for the private method, we can know the trait item is used or not,
525
+ // so we mark the method live if the self is used and the trait item is used
526
+ return self . live_symbols . contains ( & local_id)
527
+ && self . live_symbols . contains ( & local_def_id) ;
528
+ }
515
529
}
530
+ false
516
531
}
517
532
}
518
533
@@ -746,20 +761,22 @@ fn check_item<'tcx>(
746
761
matches ! ( fn_sig. decl. implicit_self, hir:: ImplicitSelfKind :: None ) ;
747
762
}
748
763
749
- // for impl trait blocks, mark associate functions live if the trait is public
764
+ // for trait impl blocks,
765
+ // mark the method live if the self_ty is public,
766
+ // or the method is public and may construct self
750
767
if of_trait
751
768
&& ( !matches ! ( tcx. def_kind( local_def_id) , DefKind :: AssocFn )
752
769
|| tcx. visibility ( local_def_id) . is_public ( )
753
770
&& ( ty_is_pub || may_construct_self) )
754
771
{
755
772
worklist. push ( ( local_def_id, ComesFromAllowExpect :: No ) ) ;
756
- } else if of_trait && tcx. visibility ( local_def_id) . is_public ( ) {
757
- // pub method && private ty & methods not construct self
758
- unsolved_impl_items. push ( ( id, local_def_id) ) ;
759
773
} else if let Some ( comes_from_allow) =
760
774
has_allow_dead_code_or_lang_attr ( tcx, local_def_id)
761
775
{
762
776
worklist. push ( ( local_def_id, comes_from_allow) ) ;
777
+ } else if of_trait {
778
+ // private method || public method not constructs self
779
+ unsolved_impl_items. push ( ( id, local_def_id) ) ;
763
780
}
764
781
}
765
782
}
0 commit comments