@@ -92,7 +92,27 @@ impl<'tcx, T> Visitor<'tcx> for TransferFunction<'_, T>
92
92
where
93
93
T : GenKill < Local > ,
94
94
{
95
+ fn visit_place ( & mut self , place : & mir:: Place < ' tcx > , context : PlaceContext , location : Location ) {
96
+ let mir:: Place { projection, local } = * place;
97
+
98
+ // We purposefully do not call `super_place` here to avoid calling `visit_local` for this
99
+ // place with one of the `Projection` variants of `PlaceContext`.
100
+ self . visit_projection ( local, projection, context, location) ;
101
+
102
+ match DefUse :: for_place ( context) {
103
+ // Treat derefs as a use of the base local. `*p = 4` is not a def of `p` but a use.
104
+ Some ( _) if place. is_indirect ( ) => self . 0 . gen ( local) ,
105
+
106
+ Some ( DefUse :: Def ) if projection. is_empty ( ) => self . 0 . kill ( local) ,
107
+ Some ( DefUse :: Use ) => self . 0 . gen ( local) ,
108
+ _ => { }
109
+ }
110
+ }
111
+
95
112
fn visit_local ( & mut self , & local: & Local , context : PlaceContext , _: Location ) {
113
+ // Because we do not call `super_place` above, `visit_local` is only called for locals that
114
+ // do not appear as part of a `Place` in the MIR. This handles cases like the implicit use
115
+ // of the return place in a `Return` terminator or the index in an `Index` projection.
96
116
match DefUse :: for_place ( context) {
97
117
Some ( DefUse :: Def ) => self . 0 . kill ( local) ,
98
118
Some ( DefUse :: Use ) => self . 0 . gen ( local) ,
@@ -126,19 +146,22 @@ impl DefUse {
126
146
| MutatingUseContext :: AsmOutput
127
147
| MutatingUseContext :: Borrow
128
148
| MutatingUseContext :: Drop
129
- | MutatingUseContext :: Projection
130
149
| MutatingUseContext :: Retag ,
131
150
)
132
151
| PlaceContext :: NonMutatingUse (
133
152
NonMutatingUseContext :: AddressOf
134
153
| NonMutatingUseContext :: Copy
135
154
| NonMutatingUseContext :: Inspect
136
155
| NonMutatingUseContext :: Move
137
- | NonMutatingUseContext :: Projection
138
156
| NonMutatingUseContext :: ShallowBorrow
139
157
| NonMutatingUseContext :: SharedBorrow
140
158
| NonMutatingUseContext :: UniqueBorrow ,
141
159
) => Some ( DefUse :: Use ) ,
160
+
161
+ PlaceContext :: MutatingUse ( MutatingUseContext :: Projection )
162
+ | PlaceContext :: NonMutatingUse ( NonMutatingUseContext :: Projection ) => {
163
+ unreachable ! ( "A projection could be a def or a use and must be handled separately" )
164
+ }
142
165
}
143
166
}
144
167
}
0 commit comments