11use rustc_abi:: Size ;
22use rustc_data_structures:: fx:: FxIndexSet ;
33use rustc_hir:: def_id:: DefId ;
4- use rustc_middle:: mir:: visit:: Visitor as MirVisitor ;
5- use rustc_middle:: mir:: { self , Location , traversal} ;
6- use rustc_middle:: ty:: { self , AssocKind , Instance , Ty , TyCtxt , TypeFoldable } ;
4+ use rustc_middle:: mir:: { self , Location } ;
5+ use rustc_middle:: ty:: { self , AssocKind , Ty , TyCtxt } ;
76use rustc_session:: Limit ;
87use rustc_session:: lint:: builtin:: LARGE_ASSIGNMENTS ;
98use rustc_span:: Span ;
109use rustc_span:: source_map:: Spanned ;
1110use rustc_span:: symbol:: { Ident , sym} ;
12- use tracing:: { debug, trace } ;
11+ use tracing:: debug;
1312
13+ use super :: MonoCheckVisitor ;
1414use crate :: errors:: LargeAssignmentsLint ;
1515
16- struct MoveCheckVisitor < ' tcx > {
17- tcx : TyCtxt < ' tcx > ,
18- instance : Instance < ' tcx > ,
19- body : & ' tcx mir:: Body < ' tcx > ,
16+ #[ derive( Default ) ]
17+ pub ( super ) struct State {
2018 /// Spans for move size lints already emitted. Helps avoid duplicate lints.
2119 move_size_spans : Vec < Span > ,
2220}
2321
24- pub ( crate ) fn check_moves < ' tcx > (
25- tcx : TyCtxt < ' tcx > ,
26- instance : Instance < ' tcx > ,
27- body : & ' tcx mir:: Body < ' tcx > ,
28- ) {
29- let mut visitor = MoveCheckVisitor { tcx, instance, body, move_size_spans : vec ! [ ] } ;
30- for ( bb, data) in traversal:: mono_reachable ( body, tcx, instance) {
31- visitor. visit_basic_block_data ( bb, data)
32- }
33- }
34-
35- impl < ' tcx > MirVisitor < ' tcx > for MoveCheckVisitor < ' tcx > {
36- fn visit_terminator ( & mut self , terminator : & mir:: Terminator < ' tcx > , location : Location ) {
37- match terminator. kind {
38- mir:: TerminatorKind :: Call { ref func, ref args, ref fn_span, .. }
39- | mir:: TerminatorKind :: TailCall { ref func, ref args, ref fn_span } => {
40- let callee_ty = func. ty ( self . body , self . tcx ) ;
41- let callee_ty = self . monomorphize ( callee_ty) ;
42- self . check_fn_args_move_size ( callee_ty, args, * fn_span, location) ;
43- }
44- _ => { }
45- }
46-
47- // We deliberately do *not* visit the nested operands here, to avoid
48- // hitting `visit_operand` for function arguments.
49- }
50-
51- fn visit_operand ( & mut self , operand : & mir:: Operand < ' tcx > , location : Location ) {
52- self . check_operand_move_size ( operand, location) ;
53- }
54- }
55-
56- impl < ' tcx > MoveCheckVisitor < ' tcx > {
57- fn monomorphize < T > ( & self , value : T ) -> T
58- where
59- T : TypeFoldable < TyCtxt < ' tcx > > ,
60- {
61- trace ! ( "monomorphize: self.instance={:?}" , self . instance) ;
62- self . instance . instantiate_mir_and_normalize_erasing_regions (
63- self . tcx ,
64- ty:: ParamEnv :: reveal_all ( ) ,
65- ty:: EarlyBinder :: bind ( value) ,
66- )
67- }
68-
69- fn check_operand_move_size ( & mut self , operand : & mir:: Operand < ' tcx > , location : Location ) {
22+ impl < ' tcx > MonoCheckVisitor < ' tcx > {
23+ pub ( super ) fn check_operand_move_size (
24+ & mut self ,
25+ operand : & mir:: Operand < ' tcx > ,
26+ location : Location ,
27+ ) {
7028 let limit = self . tcx . move_size_limit ( ) ;
7129 if limit. 0 == 0 {
7230 return ;
7331 }
7432
33+ // This function is called by visit_operand() which visits _all_
34+ // operands, including TerminatorKind::Call operands. But if
35+ // check_fn_args_move_size() has been called, the operands have already
36+ // been visited. Do not visit them again.
37+ if self . visiting_call_terminator {
38+ return ;
39+ }
40+
7541 let source_info = self . body . source_info ( location) ;
7642 debug ! ( ?source_info) ;
7743
@@ -147,7 +113,7 @@ impl<'tcx> MoveCheckVisitor<'tcx> {
147113 span : Span ,
148114 ) {
149115 let source_info = self . body . source_info ( location) ;
150- for reported_span in & self . move_size_spans {
116+ for reported_span in & self . move_check . move_size_spans {
151117 if reported_span. overlaps ( span) {
152118 return ;
153119 }
@@ -166,7 +132,7 @@ impl<'tcx> MoveCheckVisitor<'tcx> {
166132 size : too_large_size. bytes ( ) ,
167133 limit : limit as u64 ,
168134 } ) ;
169- self . move_size_spans . push ( span) ;
135+ self . move_check . move_size_spans . push ( span) ;
170136 }
171137}
172138
0 commit comments