@@ -612,8 +612,8 @@ impl<'a, 'tcx> MirUsedCollector<'a, 'tcx> {
612
612
}
613
613
614
614
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 {
617
617
return ;
618
618
}
619
619
@@ -625,48 +625,19 @@ impl<'a, 'tcx> MirUsedCollector<'a, 'tcx> {
625
625
return ;
626
626
}
627
627
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) ;
636
628
let source_info = self . body . source_info ( location) ;
637
629
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 ) ;
652
633
} ;
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 ) ;
664
634
}
665
635
666
636
fn check_fn_args_move_size (
667
637
& mut self ,
668
638
callee_ty : Ty < ' tcx > ,
669
639
args : & [ Spanned < mir:: Operand < ' tcx > > ] ,
640
+ fn_span : Span ,
670
641
location : Location ,
671
642
) {
672
643
let limit = self . tcx . move_size_limit ( ) ;
@@ -690,10 +661,65 @@ impl<'a, 'tcx> MirUsedCollector<'a, 'tcx> {
690
661
return ;
691
662
}
692
663
664
+ debug ! ( ?def_id, ?fn_span) ;
665
+
693
666
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
695
688
}
696
689
}
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
+ }
697
723
}
698
724
699
725
impl < ' a , ' tcx > MirVisitor < ' tcx > for MirUsedCollector < ' a , ' tcx > {
@@ -811,10 +837,10 @@ impl<'a, 'tcx> MirVisitor<'tcx> for MirUsedCollector<'a, 'tcx> {
811
837
} ;
812
838
813
839
match terminator. kind {
814
- mir:: TerminatorKind :: Call { ref func, ref args, .. } => {
840
+ mir:: TerminatorKind :: Call { ref func, ref args, ref fn_span , .. } => {
815
841
let callee_ty = func. ty ( self . body , tcx) ;
816
842
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) ;
818
844
visit_fn_use ( self . tcx , callee_ty, true , source, & mut self . output )
819
845
}
820
846
mir:: TerminatorKind :: Drop { ref place, .. } => {
0 commit comments