1
1
use rustc_abi:: Size ;
2
2
use rustc_data_structures:: fx:: FxIndexSet ;
3
3
use 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 } ;
7
6
use rustc_session:: Limit ;
8
7
use rustc_session:: lint:: builtin:: LARGE_ASSIGNMENTS ;
9
8
use rustc_span:: Span ;
10
9
use rustc_span:: source_map:: Spanned ;
11
10
use rustc_span:: symbol:: { Ident , sym} ;
12
- use tracing:: { debug, trace } ;
11
+ use tracing:: debug;
13
12
13
+ use super :: MonoCheckVisitor ;
14
14
use crate :: errors:: LargeAssignmentsLint ;
15
15
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 {
20
18
/// Spans for move size lints already emitted. Helps avoid duplicate lints.
21
19
move_size_spans : Vec < Span > ,
22
20
}
23
21
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
+ ) {
70
28
let limit = self . tcx . move_size_limit ( ) ;
71
29
if limit. 0 == 0 {
72
30
return ;
73
31
}
74
32
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
+
75
41
let source_info = self . body . source_info ( location) ;
76
42
debug ! ( ?source_info) ;
77
43
@@ -147,7 +113,7 @@ impl<'tcx> MoveCheckVisitor<'tcx> {
147
113
span : Span ,
148
114
) {
149
115
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 {
151
117
if reported_span. overlaps ( span) {
152
118
return ;
153
119
}
@@ -166,7 +132,7 @@ impl<'tcx> MoveCheckVisitor<'tcx> {
166
132
size : too_large_size. bytes ( ) ,
167
133
limit : limit as u64 ,
168
134
} ) ;
169
- self . move_size_spans . push ( span) ;
135
+ self . move_check . move_size_spans . push ( span) ;
170
136
}
171
137
}
172
138
0 commit comments