@@ -718,6 +718,7 @@ struct MirUsedCollector<'a, 'tcx> {
718718    tcx :  TyCtxt < ' tcx > , 
719719    body :  & ' a  mir:: Body < ' tcx > , 
720720    used_items :  & ' a  mut  MonoItems < ' tcx > , 
721+     used_mentioned_items :  & ' a  mut  FxHashSet < MentionedItem < ' tcx > > , 
721722    instance :  Instance < ' tcx > , 
722723    /// Spans for move size lints already emitted. Helps avoid duplicate lints. 
723724     move_size_spans :  Vec < Span > , 
@@ -988,6 +989,10 @@ impl<'a, 'tcx> MirVisitor<'tcx> for MirUsedCollector<'a, 'tcx> {
988989        match  terminator. kind  { 
989990            mir:: TerminatorKind :: Call  {  ref  func,  ref  args,  ref  fn_span,  .. }  => { 
990991                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+                 } 
991996                let  callee_ty = self . monomorphize ( callee_ty) ; 
992997                self . check_fn_args_move_size ( callee_ty,  args,  * fn_span,  location) ; 
993998                visit_fn_use ( self . tcx ,  callee_ty,  true ,  source,  & mut  self . used_items ) 
@@ -1633,10 +1638,15 @@ fn collect_items_of_instance<'tcx>(
16331638    mode :  CollectionMode , 
16341639)  { 
16351640    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 ( ) ; 
16361645    let  mut  collector = MirUsedCollector  { 
16371646        tcx, 
16381647        body, 
16391648        used_items, 
1649+         used_mentioned_items :  & mut  used_mentioned_items, 
16401650        instance, 
16411651        move_size_spans :  vec ! [ ] , 
16421652        visiting_call_terminator :  false , 
@@ -1656,10 +1666,13 @@ fn collect_items_of_instance<'tcx>(
16561666        } 
16571667    } 
16581668
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. 
16601671    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+         } 
16631676    } 
16641677} 
16651678
0 commit comments