@@ -179,15 +179,16 @@ use rustc_middle::query::TyCtxtAt;
179179use  rustc_middle:: ty:: adjustment:: { CustomCoerceUnsized ,  PointerCoercion } ; 
180180use  rustc_middle:: ty:: print:: with_no_trimmed_paths; 
181181use  rustc_middle:: ty:: { 
182-     self ,  GenericParamDefKind ,  Instance ,  InstanceDef ,  Ty ,  TyCtxt ,  TypeFoldable ,   TypeVisitableExt , 
183-     VtblEntry , 
182+     self ,  AssocKind ,   GenericParamDefKind ,  Instance ,  InstanceDef ,  Ty ,  TyCtxt ,  TypeFoldable , 
183+     TypeVisitableExt ,   VtblEntry , 
184184} ; 
185185use  rustc_middle:: ty:: { GenericArgKind ,  GenericArgs } ; 
186186use  rustc_middle:: { middle:: codegen_fn_attrs:: CodegenFnAttrFlags ,  mir:: visit:: TyContext } ; 
187187use  rustc_session:: config:: EntryFnType ; 
188188use  rustc_session:: lint:: builtin:: LARGE_ASSIGNMENTS ; 
189189use  rustc_session:: Limit ; 
190190use  rustc_span:: source_map:: { dummy_spanned,  respan,  Span ,  Spanned ,  DUMMY_SP } ; 
191+ use  rustc_span:: symbol:: { sym,  Ident } ; 
191192use  rustc_target:: abi:: Size ; 
192193use  std:: path:: PathBuf ; 
193194
@@ -432,7 +433,7 @@ fn collect_items_rec<'tcx>(
432433                        hir:: InlineAsmOperand :: SymFn  {  anon_const }  => { 
433434                            let  fn_ty =
434435                                tcx. typeck_body ( anon_const. body ) . node_type ( anon_const. hir_id ) ; 
435-                             visit_fn_use ( tcx,  fn_ty,  false ,  * op_sp,  & mut  used_items) ; 
436+                             visit_fn_use ( tcx,  fn_ty,  false ,  * op_sp,  & mut  used_items,   & [ ] ) ; 
436437                        } 
437438                        hir:: InlineAsmOperand :: SymStatic  {  path :  _,  def_id }  => { 
438439                            let  instance = Instance :: mono ( tcx,  * def_id) ; 
@@ -593,6 +594,11 @@ struct MirUsedCollector<'a, 'tcx> {
593594    instance :  Instance < ' tcx > , 
594595    /// Spans for move size lints already emitted. Helps avoid duplicate lints. 
595596     move_size_spans :  Vec < Span > , 
597+     /// If true, we should temporarily skip move size checks, because we are 
598+      /// processing an operand to a `skip_move_check_fns` function call. 
599+      skip_move_size_check :  bool , 
600+     /// Set of functions for which it is OK to move large data into. 
601+      skip_move_check_fns :  Vec < DefId > , 
596602} 
597603
598604impl < ' a ,  ' tcx >  MirUsedCollector < ' a ,  ' tcx >  { 
@@ -691,7 +697,14 @@ impl<'a, 'tcx> MirVisitor<'tcx> for MirUsedCollector<'a, 'tcx> {
691697            )  => { 
692698                let  fn_ty = operand. ty ( self . body ,  self . tcx ) ; 
693699                let  fn_ty = self . monomorphize ( fn_ty) ; 
694-                 visit_fn_use ( self . tcx ,  fn_ty,  false ,  span,  & mut  self . output ) ; 
700+                 visit_fn_use ( 
701+                     self . tcx , 
702+                     fn_ty, 
703+                     false , 
704+                     span, 
705+                     & mut  self . output , 
706+                     & self . skip_move_check_fns , 
707+                 ) ; 
695708            } 
696709            mir:: Rvalue :: Cast ( 
697710                mir:: CastKind :: PointerCoercion ( PointerCoercion :: ClosureFnPointer ( _) ) , 
@@ -790,7 +803,14 @@ impl<'a, 'tcx> MirVisitor<'tcx> for MirUsedCollector<'a, 'tcx> {
790803            mir:: TerminatorKind :: Call  {  ref  func,  .. }  => { 
791804                let  callee_ty = func. ty ( self . body ,  tcx) ; 
792805                let  callee_ty = self . monomorphize ( callee_ty) ; 
793-                 visit_fn_use ( self . tcx ,  callee_ty,  true ,  source,  & mut  self . output ) 
806+                 self . skip_move_size_check  = visit_fn_use ( 
807+                     self . tcx , 
808+                     callee_ty, 
809+                     true , 
810+                     source, 
811+                     & mut  self . output , 
812+                     & self . skip_move_check_fns , 
813+                 ) 
794814            } 
795815            mir:: TerminatorKind :: Drop  {  ref  place,  .. }  => { 
796816                let  ty = place. ty ( self . body ,  self . tcx ) . ty ; 
@@ -802,7 +822,7 @@ impl<'a, 'tcx> MirVisitor<'tcx> for MirUsedCollector<'a, 'tcx> {
802822                    match  * op { 
803823                        mir:: InlineAsmOperand :: SymFn  {  ref  value }  => { 
804824                            let  fn_ty = self . monomorphize ( value. literal . ty ( ) ) ; 
805-                             visit_fn_use ( self . tcx ,  fn_ty,  false ,  source,  & mut  self . output ) ; 
825+                             visit_fn_use ( self . tcx ,  fn_ty,  false ,  source,  & mut  self . output ,   & [ ] ) ; 
806826                        } 
807827                        mir:: InlineAsmOperand :: SymStatic  {  def_id }  => { 
808828                            let  instance = Instance :: mono ( self . tcx ,  def_id) ; 
@@ -841,12 +861,13 @@ impl<'a, 'tcx> MirVisitor<'tcx> for MirUsedCollector<'a, 'tcx> {
841861        } 
842862
843863        self . super_terminator ( terminator,  location) ; 
864+         self . skip_move_size_check  = false ; 
844865    } 
845866
846867    fn  visit_operand ( & mut  self ,  operand :  & mir:: Operand < ' tcx > ,  location :  Location )  { 
847868        self . super_operand ( operand,  location) ; 
848869        let  move_size_limit = self . tcx . move_size_limit ( ) . 0 ; 
849-         if  move_size_limit > 0  { 
870+         if  move_size_limit > 0  && ! self . skip_move_size_check   { 
850871            self . check_move_size ( move_size_limit,  operand,  location) ; 
851872        } 
852873    } 
@@ -877,8 +898,11 @@ fn visit_fn_use<'tcx>(
877898    is_direct_call :  bool , 
878899    source :  Span , 
879900    output :  & mut  MonoItems < ' tcx > , 
880- )  { 
901+     skip_move_check_fns :  & [ DefId ] , 
902+ )  -> bool  { 
903+     let  mut  skip_move_size_check = false ; 
881904    if  let  ty:: FnDef ( def_id,  args)  = * ty. kind ( )  { 
905+         skip_move_size_check = skip_move_check_fns. contains ( & def_id) ; 
882906        let  instance = if  is_direct_call { 
883907            ty:: Instance :: expect_resolve ( tcx,  ty:: ParamEnv :: reveal_all ( ) ,  def_id,  args) 
884908        }  else  { 
@@ -889,6 +913,7 @@ fn visit_fn_use<'tcx>(
889913        } ; 
890914        visit_instance_use ( tcx,  instance,  is_direct_call,  source,  output) ; 
891915    } 
916+     skip_move_size_check
892917} 
893918
894919fn  visit_instance_use < ' tcx > ( 
@@ -1369,6 +1394,31 @@ fn collect_alloc<'tcx>(tcx: TyCtxt<'tcx>, alloc_id: AllocId, output: &mut MonoIt
13691394    } 
13701395} 
13711396
1397+ fn  add_assoc_fn < ' tcx > ( 
1398+     tcx :  TyCtxt < ' tcx > , 
1399+     def_id :  Option < DefId > , 
1400+     fn_ident :  Ident , 
1401+     skip_move_check_fns :  & mut  Vec < DefId > , 
1402+ )  { 
1403+     if  let  Some ( def_id)  = def_id. and_then ( |def_id| assoc_fn_of_type ( tcx,  def_id,  fn_ident) )  { 
1404+         skip_move_check_fns. push ( def_id) ; 
1405+     } 
1406+ } 
1407+ 
1408+ fn  assoc_fn_of_type < ' tcx > ( tcx :  TyCtxt < ' tcx > ,  def_id :  DefId ,  fn_ident :  Ident )  -> Option < DefId >  { 
1409+     for  impl_def_id in  tcx. inherent_impls ( def_id)  { 
1410+         if  let  Some ( new)  = tcx. associated_items ( impl_def_id) . find_by_name_and_kind ( 
1411+             tcx, 
1412+             fn_ident, 
1413+             AssocKind :: Fn , 
1414+             def_id, 
1415+         )  { 
1416+             return  Some ( new. def_id ) ; 
1417+         } 
1418+     } 
1419+     return  None ; 
1420+ } 
1421+ 
13721422/// Scans the MIR in order to find function calls, closures, and drop-glue. 
13731423#[ instrument( skip( tcx,  output) ,  level = "debug" ) ]  
13741424fn  collect_used_items < ' tcx > ( 
@@ -1377,8 +1427,39 @@ fn collect_used_items<'tcx>(
13771427    output :  & mut  MonoItems < ' tcx > , 
13781428)  { 
13791429    let  body = tcx. instance_mir ( instance. def ) ; 
1380-     MirUsedCollector  {  tcx,  body :  & body,  output,  instance,  move_size_spans :  vec ! [ ]  } 
1381-         . visit_body ( & body) ; 
1430+ 
1431+     let  mut  skip_move_check_fns = vec ! [ ] ; 
1432+     if  tcx. move_size_limit ( ) . 0  > 0  { 
1433+         add_assoc_fn ( 
1434+             tcx, 
1435+             tcx. lang_items ( ) . owned_box ( ) , 
1436+             Ident :: from_str ( "new" ) , 
1437+             & mut  skip_move_check_fns, 
1438+         ) ; 
1439+         add_assoc_fn ( 
1440+             tcx, 
1441+             tcx. get_diagnostic_item ( sym:: Arc ) , 
1442+             Ident :: from_str ( "new" ) , 
1443+             & mut  skip_move_check_fns, 
1444+         ) ; 
1445+         add_assoc_fn ( 
1446+             tcx, 
1447+             tcx. get_diagnostic_item ( sym:: Rc ) , 
1448+             Ident :: from_str ( "new" ) , 
1449+             & mut  skip_move_check_fns, 
1450+         ) ; 
1451+     } 
1452+ 
1453+     MirUsedCollector  { 
1454+         tcx, 
1455+         body :  & body, 
1456+         output, 
1457+         instance, 
1458+         move_size_spans :  vec ! [ ] , 
1459+         skip_move_size_check :  false , 
1460+         skip_move_check_fns, 
1461+     } 
1462+     . visit_body ( & body) ; 
13821463} 
13831464
13841465#[ instrument( skip( tcx,  output) ,  level = "debug" ) ]  
0 commit comments