@@ -590,6 +590,8 @@ struct MirUsedCollector<'a, 'tcx> {
590590 body : & ' a mir:: Body < ' tcx > ,
591591 output : & ' a mut MonoItems < ' tcx > ,
592592 instance : Instance < ' tcx > ,
593+ /// Spans for move size lints already emitted. Helps avoid duplicate lints.
594+ move_size_spans : Vec < Span > ,
593595}
594596
595597impl < ' a , ' tcx > MirUsedCollector < ' a , ' tcx > {
@@ -604,6 +606,45 @@ impl<'a, 'tcx> MirUsedCollector<'a, 'tcx> {
604606 ty:: EarlyBinder :: bind ( value) ,
605607 )
606608 }
609+
610+ fn check_move_size ( & mut self , limit : usize , operand : & mir:: Operand < ' tcx > , location : Location ) {
611+ let limit = Size :: from_bytes ( limit) ;
612+ let ty = operand. ty ( self . body , self . tcx ) ;
613+ let ty = self . monomorphize ( ty) ;
614+ let Ok ( layout) = self . tcx . layout_of ( ty:: ParamEnv :: reveal_all ( ) . and ( ty) ) else { return } ;
615+ if layout. size <= limit {
616+ return ;
617+ }
618+ debug ! ( ?layout) ;
619+ let source_info = self . body . source_info ( location) ;
620+ debug ! ( ?source_info) ;
621+ for span in & self . move_size_spans {
622+ if span. overlaps ( source_info. span ) {
623+ return ;
624+ }
625+ }
626+ let lint_root = source_info. scope . lint_root ( & self . body . source_scopes ) ;
627+ debug ! ( ?lint_root) ;
628+ let Some ( lint_root) = lint_root else {
629+ // This happens when the issue is in a function from a foreign crate that
630+ // we monomorphized in the current crate. We can't get a `HirId` for things
631+ // in other crates.
632+ // FIXME: Find out where to report the lint on. Maybe simply crate-level lint root
633+ // but correct span? This would make the lint at least accept crate-level lint attributes.
634+ return ;
635+ } ;
636+ self . tcx . emit_spanned_lint (
637+ LARGE_ASSIGNMENTS ,
638+ lint_root,
639+ source_info. span ,
640+ LargeAssignmentsLint {
641+ span : source_info. span ,
642+ size : layout. size . bytes ( ) ,
643+ limit : limit. bytes ( ) ,
644+ } ,
645+ ) ;
646+ self . move_size_spans . push ( source_info. span ) ;
647+ }
607648}
608649
609650impl < ' a , ' tcx > MirVisitor < ' tcx > for MirUsedCollector < ' a , ' tcx > {
@@ -803,40 +844,9 @@ impl<'a, 'tcx> MirVisitor<'tcx> for MirUsedCollector<'a, 'tcx> {
803844
804845 fn visit_operand ( & mut self , operand : & mir:: Operand < ' tcx > , location : Location ) {
805846 self . super_operand ( operand, location) ;
806- let limit = self . tcx . move_size_limit ( ) . 0 ;
807- if limit == 0 {
808- return ;
809- }
810- let limit = Size :: from_bytes ( limit) ;
811- let ty = operand. ty ( self . body , self . tcx ) ;
812- let ty = self . monomorphize ( ty) ;
813- let layout = self . tcx . layout_of ( ty:: ParamEnv :: reveal_all ( ) . and ( ty) ) ;
814- if let Ok ( layout) = layout {
815- if layout. size > limit {
816- debug ! ( ?layout) ;
817- let source_info = self . body . source_info ( location) ;
818- debug ! ( ?source_info) ;
819- let lint_root = source_info. scope . lint_root ( & self . body . source_scopes ) ;
820- debug ! ( ?lint_root) ;
821- let Some ( lint_root) = lint_root else {
822- // This happens when the issue is in a function from a foreign crate that
823- // we monomorphized in the current crate. We can't get a `HirId` for things
824- // in other crates.
825- // FIXME: Find out where to report the lint on. Maybe simply crate-level lint root
826- // but correct span? This would make the lint at least accept crate-level lint attributes.
827- return ;
828- } ;
829- self . tcx . emit_spanned_lint (
830- LARGE_ASSIGNMENTS ,
831- lint_root,
832- source_info. span ,
833- LargeAssignmentsLint {
834- span : source_info. span ,
835- size : layout. size . bytes ( ) ,
836- limit : limit. bytes ( ) ,
837- } ,
838- )
839- }
847+ let move_size_limit = self . tcx . move_size_limit ( ) . 0 ;
848+ if move_size_limit > 0 {
849+ self . check_move_size ( move_size_limit, operand, location) ;
840850 }
841851 }
842852
@@ -1363,7 +1373,8 @@ fn collect_used_items<'tcx>(
13631373 output : & mut MonoItems < ' tcx > ,
13641374) {
13651375 let body = tcx. instance_mir ( instance. def ) ;
1366- MirUsedCollector { tcx, body : & body, output, instance } . visit_body ( & body) ;
1376+ MirUsedCollector { tcx, body : & body, output, instance, move_size_spans : vec ! [ ] }
1377+ . visit_body ( & body) ;
13671378}
13681379
13691380#[ instrument( skip( tcx, output) , level = "debug" ) ]
0 commit comments