@@ -718,6 +718,7 @@ struct MirUsedCollector<'a, 'tcx> {
718
718
tcx : TyCtxt < ' tcx > ,
719
719
body : & ' a mir:: Body < ' tcx > ,
720
720
used_items : & ' a mut MonoItems < ' tcx > ,
721
+ used_mentioned_items : & ' a mut FxHashSet < MentionedItem < ' tcx > > ,
721
722
instance : Instance < ' tcx > ,
722
723
/// Spans for move size lints already emitted. Helps avoid duplicate lints.
723
724
move_size_spans : Vec < Span > ,
@@ -988,6 +989,10 @@ impl<'a, 'tcx> MirVisitor<'tcx> for MirUsedCollector<'a, 'tcx> {
988
989
match terminator. kind {
989
990
mir:: TerminatorKind :: Call { ref func, ref args, ref fn_span, .. } => {
990
991
let callee_ty = func. ty ( self . body , tcx) ;
992
+ // *Before* monomorphizing, record that we already handled this mention.
993
+ if let ty:: FnDef ( def_id, args) = callee_ty. kind ( ) {
994
+ self . used_mentioned_items . insert ( MentionedItem :: Fn ( * def_id, args) ) ;
995
+ }
991
996
let callee_ty = self . monomorphize ( callee_ty) ;
992
997
self . check_fn_args_move_size ( callee_ty, args, * fn_span, location) ;
993
998
visit_fn_use ( self . tcx , callee_ty, true , source, & mut self . used_items )
@@ -1633,10 +1638,15 @@ fn collect_items_of_instance<'tcx>(
1633
1638
mode : CollectionMode ,
1634
1639
) {
1635
1640
let body = tcx. instance_mir ( instance. def ) ;
1641
+ // Collects all `MentionedItem` that were already added to `used_items`. Note that `used_items`
1642
+ // stores `MonoItem`; the point of this is to speed up the `body.mentioned_items` loop below by
1643
+ // not having to call `monomorphize` on `MentionedItem` that were already fully handled.
1644
+ let mut used_mentioned_items = FxHashSet :: < MentionedItem < ' tcx > > :: default ( ) ;
1636
1645
let mut collector = MirUsedCollector {
1637
1646
tcx,
1638
1647
body,
1639
1648
used_items,
1649
+ used_mentioned_items : & mut used_mentioned_items,
1640
1650
instance,
1641
1651
move_size_spans : vec ! [ ] ,
1642
1652
visiting_call_terminator : false ,
@@ -1656,10 +1666,13 @@ fn collect_items_of_instance<'tcx>(
1656
1666
}
1657
1667
}
1658
1668
1659
- // Always gather mentioned items.
1669
+ // Always gather mentioned items. We try to avoid processing items that we have already added to
1670
+ // `used_items` above.
1660
1671
for item in & body. mentioned_items {
1661
- let item_mono = collector. monomorphize ( item. node ) ;
1662
- visit_mentioned_item ( tcx, & item_mono, item. span , mentioned_items) ;
1672
+ if !collector. used_mentioned_items . contains ( & item. node ) {
1673
+ let item_mono = collector. monomorphize ( item. node ) ;
1674
+ visit_mentioned_item ( tcx, & item_mono, item. span , mentioned_items) ;
1675
+ }
1663
1676
}
1664
1677
}
1665
1678
0 commit comments