@@ -12,70 +12,21 @@ pub struct CloneUsage {
12
12
/// Whether the clone value is mutated.
13
13
pub clone_consumed_or_mutated : bool ,
14
14
}
15
+
15
16
pub fn visit_clone_usage (
16
17
cloned : mir:: Local ,
17
18
clone : mir:: Local ,
18
19
mir : & mir:: Body < ' _ > ,
19
20
bb : mir:: BasicBlock ,
20
21
) -> CloneUsage {
21
- struct V {
22
- cloned : mir:: Local ,
23
- clone : mir:: Local ,
24
- result : CloneUsage ,
25
- }
26
- impl < ' tcx > mir:: visit:: Visitor < ' tcx > for V {
27
- fn visit_basic_block_data ( & mut self , block : mir:: BasicBlock , data : & mir:: BasicBlockData < ' tcx > ) {
28
- let statements = & data. statements ;
29
- for ( statement_index, statement) in statements. iter ( ) . enumerate ( ) {
30
- self . visit_statement ( statement, mir:: Location { block, statement_index } ) ;
31
- }
32
-
33
- self . visit_terminator (
34
- data. terminator ( ) ,
35
- mir:: Location {
36
- block,
37
- statement_index : statements. len ( ) ,
38
- } ,
39
- ) ;
40
- }
41
-
42
- fn visit_place ( & mut self , place : & mir:: Place < ' tcx > , ctx : PlaceContext , loc : mir:: Location ) {
43
- let local = place. local ;
44
-
45
- if local == self . cloned
46
- && !matches ! (
47
- ctx,
48
- PlaceContext :: MutatingUse ( MutatingUseContext :: Drop ) | PlaceContext :: NonUse ( _)
49
- )
50
- {
51
- self . result . cloned_used = true ;
52
- self . result . cloned_consume_or_mutate_loc = self . result . cloned_consume_or_mutate_loc . or_else ( || {
53
- matches ! (
54
- ctx,
55
- PlaceContext :: NonMutatingUse ( NonMutatingUseContext :: Move )
56
- | PlaceContext :: MutatingUse ( MutatingUseContext :: Borrow )
57
- )
58
- . then ( || loc)
59
- } ) ;
60
- } else if local == self . clone {
61
- match ctx {
62
- PlaceContext :: NonMutatingUse ( NonMutatingUseContext :: Move )
63
- | PlaceContext :: MutatingUse ( MutatingUseContext :: Borrow ) => {
64
- self . result . clone_consumed_or_mutated = true ;
65
- } ,
66
- _ => { } ,
67
- }
68
- }
69
- }
70
- }
71
-
72
22
let init = CloneUsage {
73
23
cloned_used : false ,
74
24
cloned_consume_or_mutate_loc : None ,
75
25
// Consider non-temporary clones consumed.
76
26
// TODO: Actually check for mutation of non-temporaries.
77
27
clone_consumed_or_mutated : mir. local_kind ( clone) != mir:: LocalKind :: Temp ,
78
28
} ;
29
+
79
30
traversal:: ReversePostorder :: new ( mir, bb)
80
31
. skip ( 1 )
81
32
. fold ( init, |usage, ( tbb, tdata) | {
@@ -100,3 +51,55 @@ pub fn visit_clone_usage(
100
51
v. result
101
52
} )
102
53
}
54
+
55
+ struct V {
56
+ cloned : mir:: Local ,
57
+ clone : mir:: Local ,
58
+ result : CloneUsage ,
59
+ }
60
+
61
+ impl < ' tcx > mir:: visit:: Visitor < ' tcx > for V {
62
+ fn visit_basic_block_data ( & mut self , block : mir:: BasicBlock , data : & mir:: BasicBlockData < ' tcx > ) {
63
+ let statements = & data. statements ;
64
+ for ( statement_index, statement) in statements. iter ( ) . enumerate ( ) {
65
+ self . visit_statement ( statement, mir:: Location { block, statement_index } ) ;
66
+ }
67
+
68
+ self . visit_terminator (
69
+ data. terminator ( ) ,
70
+ mir:: Location {
71
+ block,
72
+ statement_index : statements. len ( ) ,
73
+ } ,
74
+ ) ;
75
+ }
76
+
77
+ fn visit_place ( & mut self , place : & mir:: Place < ' tcx > , ctx : PlaceContext , loc : mir:: Location ) {
78
+ let local = place. local ;
79
+
80
+ if local == self . cloned
81
+ && !matches ! (
82
+ ctx,
83
+ PlaceContext :: MutatingUse ( MutatingUseContext :: Drop ) | PlaceContext :: NonUse ( _)
84
+ )
85
+ {
86
+ self . result . cloned_used = true ;
87
+ self . result . cloned_consume_or_mutate_loc = self . result . cloned_consume_or_mutate_loc . or_else ( || {
88
+ matches ! (
89
+ ctx,
90
+ PlaceContext :: NonMutatingUse ( NonMutatingUseContext :: Move )
91
+ | PlaceContext :: MutatingUse ( MutatingUseContext :: Borrow )
92
+ )
93
+ . then ( || loc)
94
+ } ) ;
95
+ } else if local == self . clone {
96
+ match ctx {
97
+ PlaceContext :: NonMutatingUse ( NonMutatingUseContext :: Move )
98
+ | PlaceContext :: MutatingUse ( MutatingUseContext :: Borrow ) => {
99
+ self . result . clone_consumed_or_mutated = true ;
100
+ } ,
101
+ _ => { } ,
102
+ }
103
+ }
104
+ }
105
+ }
0 commit comments