@@ -614,8 +614,8 @@ impl<'a, 'tcx> MirUsedCollector<'a, 'tcx> {
614
614
}
615
615
616
616
fn check_operand_move_size ( & mut self , operand : & mir:: Operand < ' tcx > , location : Location ) {
617
- let limit = self . tcx . move_size_limit ( ) . 0 ;
618
- if limit == 0 {
617
+ let limit = self . tcx . move_size_limit ( ) ;
618
+ if limit. 0 == 0 {
619
619
return ;
620
620
}
621
621
@@ -627,48 +627,19 @@ impl<'a, 'tcx> MirUsedCollector<'a, 'tcx> {
627
627
return ;
628
628
}
629
629
630
- let limit = Size :: from_bytes ( limit) ;
631
- let ty = operand. ty ( self . body , self . tcx ) ;
632
- let ty = self . monomorphize ( ty) ;
633
- let Ok ( layout) = self . tcx . layout_of ( ty:: ParamEnv :: reveal_all ( ) . and ( ty) ) else { return } ;
634
- if layout. size <= limit {
635
- return ;
636
- }
637
- debug ! ( ?layout) ;
638
630
let source_info = self . body . source_info ( location) ;
639
631
debug ! ( ?source_info) ;
640
- for span in & self . move_size_spans {
641
- if span. overlaps ( source_info. span ) {
642
- return ;
643
- }
644
- }
645
- let lint_root = source_info. scope . lint_root ( & self . body . source_scopes ) ;
646
- debug ! ( ?lint_root) ;
647
- let Some ( lint_root) = lint_root else {
648
- // This happens when the issue is in a function from a foreign crate that
649
- // we monomorphized in the current crate. We can't get a `HirId` for things
650
- // in other crates.
651
- // FIXME: Find out where to report the lint on. Maybe simply crate-level lint root
652
- // but correct span? This would make the lint at least accept crate-level lint attributes.
653
- return ;
632
+
633
+ if let Some ( too_large_size) = self . operand_size_if_too_large ( limit, operand) {
634
+ self . lint_large_assignment ( limit. 0 , too_large_size, location, source_info. span ) ;
654
635
} ;
655
- self . tcx . emit_spanned_lint (
656
- LARGE_ASSIGNMENTS ,
657
- lint_root,
658
- source_info. span ,
659
- LargeAssignmentsLint {
660
- span : source_info. span ,
661
- size : layout. size . bytes ( ) ,
662
- limit : limit. bytes ( ) ,
663
- } ,
664
- ) ;
665
- self . move_size_spans . push ( source_info. span ) ;
666
636
}
667
637
668
638
fn check_fn_args_move_size (
669
639
& mut self ,
670
640
callee_ty : Ty < ' tcx > ,
671
641
args : & [ Spanned < mir:: Operand < ' tcx > > ] ,
642
+ fn_span : Span ,
672
643
location : Location ,
673
644
) {
674
645
let limit = self . tcx . move_size_limit ( ) ;
@@ -692,10 +663,65 @@ impl<'a, 'tcx> MirUsedCollector<'a, 'tcx> {
692
663
return ;
693
664
}
694
665
666
+ debug ! ( ?def_id, ?fn_span) ;
667
+
695
668
for arg in args {
696
- self . check_operand_move_size ( & arg. node , location) ;
669
+ if let Some ( too_large_size) = self . operand_size_if_too_large ( limit, & arg. node ) {
670
+ self . lint_large_assignment ( limit. 0 , too_large_size, location, arg. span ) ;
671
+ } ;
672
+ }
673
+ }
674
+
675
+ fn operand_size_if_too_large (
676
+ & mut self ,
677
+ limit : Limit ,
678
+ operand : & mir:: Operand < ' tcx > ,
679
+ ) -> Option < Size > {
680
+ let ty = operand. ty ( self . body , self . tcx ) ;
681
+ let ty = self . monomorphize ( ty) ;
682
+ let Ok ( layout) = self . tcx . layout_of ( ty:: ParamEnv :: reveal_all ( ) . and ( ty) ) else {
683
+ return None ;
684
+ } ;
685
+ if layout. size . bytes_usize ( ) > limit. 0 {
686
+ debug ! ( ?layout) ;
687
+ Some ( layout. size )
688
+ } else {
689
+ None
697
690
}
698
691
}
692
+
693
+ fn lint_large_assignment (
694
+ & mut self ,
695
+ limit : usize ,
696
+ too_large_size : Size ,
697
+ location : Location ,
698
+ span : Span ,
699
+ ) {
700
+ let source_info = self . body . source_info ( location) ;
701
+ debug ! ( ?source_info) ;
702
+ for reported_span in & self . move_size_spans {
703
+ if reported_span. overlaps ( span) {
704
+ return ;
705
+ }
706
+ }
707
+ let lint_root = source_info. scope . lint_root ( & self . body . source_scopes ) ;
708
+ debug ! ( ?lint_root) ;
709
+ let Some ( lint_root) = lint_root else {
710
+ // This happens when the issue is in a function from a foreign crate that
711
+ // we monomorphized in the current crate. We can't get a `HirId` for things
712
+ // in other crates.
713
+ // FIXME: Find out where to report the lint on. Maybe simply crate-level lint root
714
+ // but correct span? This would make the lint at least accept crate-level lint attributes.
715
+ return ;
716
+ } ;
717
+ self . tcx . emit_spanned_lint (
718
+ LARGE_ASSIGNMENTS ,
719
+ lint_root,
720
+ span,
721
+ LargeAssignmentsLint { span, size : too_large_size. bytes ( ) , limit : limit as u64 } ,
722
+ ) ;
723
+ self . move_size_spans . push ( span) ;
724
+ }
699
725
}
700
726
701
727
impl < ' a , ' tcx > MirVisitor < ' tcx > for MirUsedCollector < ' a , ' tcx > {
@@ -813,11 +839,11 @@ impl<'a, 'tcx> MirVisitor<'tcx> for MirUsedCollector<'a, 'tcx> {
813
839
} ;
814
840
815
841
match terminator. kind {
816
- mir:: TerminatorKind :: Call { ref func, ref args, .. } => {
842
+ mir:: TerminatorKind :: Call { ref func, ref args, ref fn_span , .. } => {
817
843
let callee_ty = func. ty ( self . body , tcx) ;
818
844
let callee_ty = self . monomorphize ( callee_ty) ;
819
- self . check_fn_args_move_size ( callee_ty, args, location) ;
820
- visit_fn_use ( self . tcx , callee_ty, true , source, self . output )
845
+ self . check_fn_args_move_size ( callee_ty, args, * fn_span , location) ;
846
+ visit_fn_use ( self . tcx , callee_ty, true , source, & mut self . output )
821
847
}
822
848
mir:: TerminatorKind :: Drop { ref place, .. } => {
823
849
let ty = place. ty ( self . body , self . tcx ) . ty ;
0 commit comments