@@ -590,6 +590,8 @@ struct MirUsedCollector<'a, 'tcx> {
590
590
body : & ' a mir:: Body < ' tcx > ,
591
591
output : & ' a mut MonoItems < ' tcx > ,
592
592
instance : Instance < ' tcx > ,
593
+ /// Spans for move size lints already emitted. Helps avoid duplicate lints.
594
+ move_size_spans : Vec < Span > ,
593
595
}
594
596
595
597
impl < ' a , ' tcx > MirUsedCollector < ' a , ' tcx > {
@@ -604,6 +606,45 @@ impl<'a, 'tcx> MirUsedCollector<'a, 'tcx> {
604
606
ty:: EarlyBinder :: bind ( value) ,
605
607
)
606
608
}
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
+ }
607
648
}
608
649
609
650
impl < ' a , ' tcx > MirVisitor < ' tcx > for MirUsedCollector < ' a , ' tcx > {
@@ -803,40 +844,9 @@ impl<'a, 'tcx> MirVisitor<'tcx> for MirUsedCollector<'a, 'tcx> {
803
844
804
845
fn visit_operand ( & mut self , operand : & mir:: Operand < ' tcx > , location : Location ) {
805
846
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) ;
840
850
}
841
851
}
842
852
@@ -1363,7 +1373,8 @@ fn collect_used_items<'tcx>(
1363
1373
output : & mut MonoItems < ' tcx > ,
1364
1374
) {
1365
1375
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) ;
1367
1378
}
1368
1379
1369
1380
#[ instrument( skip( tcx, output) , level = "debug" ) ]
0 commit comments