@@ -612,8 +612,8 @@ impl<'a, 'tcx> MirUsedCollector<'a, 'tcx> {
612612 }
613613
614614 fn check_operand_move_size ( & mut self , operand : & mir:: Operand < ' tcx > , location : Location ) {
615- let limit = self . tcx . move_size_limit ( ) . 0 ;
616- if limit == 0 {
615+ let limit = self . tcx . move_size_limit ( ) ;
616+ if limit. 0 == 0 {
617617 return ;
618618 }
619619
@@ -625,48 +625,19 @@ impl<'a, 'tcx> MirUsedCollector<'a, 'tcx> {
625625 return ;
626626 }
627627
628- let limit = Size :: from_bytes ( limit) ;
629- let ty = operand. ty ( self . body , self . tcx ) ;
630- let ty = self . monomorphize ( ty) ;
631- let Ok ( layout) = self . tcx . layout_of ( ty:: ParamEnv :: reveal_all ( ) . and ( ty) ) else { return } ;
632- if layout. size <= limit {
633- return ;
634- }
635- debug ! ( ?layout) ;
636628 let source_info = self . body . source_info ( location) ;
637629 debug ! ( ?source_info) ;
638- for span in & self . move_size_spans {
639- if span. overlaps ( source_info. span ) {
640- return ;
641- }
642- }
643- let lint_root = source_info. scope . lint_root ( & self . body . source_scopes ) ;
644- debug ! ( ?lint_root) ;
645- let Some ( lint_root) = lint_root else {
646- // This happens when the issue is in a function from a foreign crate that
647- // we monomorphized in the current crate. We can't get a `HirId` for things
648- // in other crates.
649- // FIXME: Find out where to report the lint on. Maybe simply crate-level lint root
650- // but correct span? This would make the lint at least accept crate-level lint attributes.
651- return ;
630+
631+ if let Some ( too_large_size) = self . operand_size_if_too_large ( limit, operand) {
632+ self . lint_large_assignment ( limit. 0 , too_large_size, location, source_info. span ) ;
652633 } ;
653- self . tcx . emit_spanned_lint (
654- LARGE_ASSIGNMENTS ,
655- lint_root,
656- source_info. span ,
657- LargeAssignmentsLint {
658- span : source_info. span ,
659- size : layout. size . bytes ( ) ,
660- limit : limit. bytes ( ) ,
661- } ,
662- ) ;
663- self . move_size_spans . push ( source_info. span ) ;
664634 }
665635
666636 fn check_fn_args_move_size (
667637 & mut self ,
668638 callee_ty : Ty < ' tcx > ,
669639 args : & [ Spanned < mir:: Operand < ' tcx > > ] ,
640+ fn_span : Span ,
670641 location : Location ,
671642 ) {
672643 let limit = self . tcx . move_size_limit ( ) ;
@@ -690,10 +661,65 @@ impl<'a, 'tcx> MirUsedCollector<'a, 'tcx> {
690661 return ;
691662 }
692663
664+ debug ! ( ?def_id, ?fn_span) ;
665+
693666 for arg in args {
694- self . check_operand_move_size ( & arg. node , location) ;
667+ if let Some ( too_large_size) = self . operand_size_if_too_large ( limit, & arg. node ) {
668+ self . lint_large_assignment ( limit. 0 , too_large_size, location, arg. span ) ;
669+ } ;
670+ }
671+ }
672+
673+ fn operand_size_if_too_large (
674+ & mut self ,
675+ limit : Limit ,
676+ operand : & mir:: Operand < ' tcx > ,
677+ ) -> Option < Size > {
678+ let ty = operand. ty ( self . body , self . tcx ) ;
679+ let ty = self . monomorphize ( ty) ;
680+ let Ok ( layout) = self . tcx . layout_of ( ty:: ParamEnv :: reveal_all ( ) . and ( ty) ) else {
681+ return None ;
682+ } ;
683+ if layout. size . bytes_usize ( ) > limit. 0 {
684+ debug ! ( ?layout) ;
685+ Some ( layout. size )
686+ } else {
687+ None
695688 }
696689 }
690+
691+ fn lint_large_assignment (
692+ & mut self ,
693+ limit : usize ,
694+ too_large_size : Size ,
695+ location : Location ,
696+ span : Span ,
697+ ) {
698+ let source_info = self . body . source_info ( location) ;
699+ debug ! ( ?source_info) ;
700+ for reported_span in & self . move_size_spans {
701+ if reported_span. overlaps ( span) {
702+ return ;
703+ }
704+ }
705+ let lint_root = source_info. scope . lint_root ( & self . body . source_scopes ) ;
706+ debug ! ( ?lint_root) ;
707+ let Some ( lint_root) = lint_root else {
708+ // This happens when the issue is in a function from a foreign crate that
709+ // we monomorphized in the current crate. We can't get a `HirId` for things
710+ // in other crates.
711+ // FIXME: Find out where to report the lint on. Maybe simply crate-level lint root
712+ // but correct span? This would make the lint at least accept crate-level lint attributes.
713+ return ;
714+ } ;
715+ self . tcx . emit_spanned_lint (
716+ LARGE_ASSIGNMENTS ,
717+ lint_root,
718+ span,
719+ LargeAssignmentsLint { span, size : too_large_size. bytes ( ) , limit : limit as u64 } ,
720+ ) ;
721+ self . move_size_spans . push ( span) ;
722+ }
697723}
698724
699725impl < ' a , ' tcx > MirVisitor < ' tcx > for MirUsedCollector < ' a , ' tcx > {
@@ -811,10 +837,10 @@ impl<'a, 'tcx> MirVisitor<'tcx> for MirUsedCollector<'a, 'tcx> {
811837 } ;
812838
813839 match terminator. kind {
814- mir:: TerminatorKind :: Call { ref func, ref args, .. } => {
840+ mir:: TerminatorKind :: Call { ref func, ref args, ref fn_span , .. } => {
815841 let callee_ty = func. ty ( self . body , tcx) ;
816842 let callee_ty = self . monomorphize ( callee_ty) ;
817- self . check_fn_args_move_size ( callee_ty, args, location) ;
843+ self . check_fn_args_move_size ( callee_ty, args, * fn_span , location) ;
818844 visit_fn_use ( self . tcx , callee_ty, true , source, & mut self . output )
819845 }
820846 mir:: TerminatorKind :: Drop { ref place, .. } => {
0 commit comments