@@ -182,35 +182,29 @@ impl<'a, 'tcx> Visitor<'tcx> for PointerFinder<'a, 'tcx> {
182
182
return ;
183
183
}
184
184
185
- // Since Deref projections must come first and only once, the pointer for an indirect place
186
- // is the Local that the Place is based on.
185
+ // Get the place and type we visit.
187
186
let pointer = Place :: from ( place. local ) ;
188
- let pointer_ty = self . local_decls [ place . local ] . ty ;
187
+ let pointer_ty = pointer . ty ( self . local_decls , self . tcx ) . ty ;
189
188
190
189
// We only want to check places based on raw pointers
191
- if ! pointer_ty. is_raw_ptr ( ) {
190
+ let & ty :: RawPtr ( mut pointee_ty , _ ) = pointer_ty. kind ( ) else {
192
191
trace ! ( "Indirect, but not based on an raw ptr, not checking {:?}" , place) ;
193
192
return ;
193
+ } ;
194
+
195
+ // If we see a borrow of a field projection, we want to pass the field type to the
196
+ // check and not the pointee type.
197
+ if matches ! ( self . field_projection_mode, BorrowedFieldProjectionMode :: FollowProjections )
198
+ && matches ! (
199
+ context,
200
+ PlaceContext :: NonMutatingUse ( NonMutatingUseContext :: SharedBorrow )
201
+ | PlaceContext :: MutatingUse ( MutatingUseContext :: Borrow )
202
+ )
203
+ && let Some ( PlaceElem :: Field ( _, ty) ) = place. projection . last ( )
204
+ {
205
+ pointee_ty = * ty;
194
206
}
195
207
196
- // If we see a borrow of a field projection, we want to pass the field Ty to the
197
- // check and not the pointee Ty.
198
- let pointee_ty = match self . field_projection_mode {
199
- BorrowedFieldProjectionMode :: FollowProjections
200
- if matches ! (
201
- context,
202
- PlaceContext :: NonMutatingUse ( NonMutatingUseContext :: SharedBorrow )
203
- | PlaceContext :: MutatingUse ( MutatingUseContext :: Borrow )
204
- ) =>
205
- {
206
- if let Some ( PlaceElem :: Field ( _, ty) ) = place. projection . last ( ) {
207
- * ty
208
- } else {
209
- pointer_ty. builtin_deref ( true ) . expect ( "no builtin_deref for an raw pointer" )
210
- }
211
- }
212
- _ => pointer_ty. builtin_deref ( true ) . expect ( "no builtin_deref for an raw pointer" ) ,
213
- } ;
214
208
// Ideally we'd support this in the future, but for now we are limited to sized types.
215
209
if !pointee_ty. is_sized ( self . tcx , self . typing_env ) {
216
210
trace ! ( "Raw pointer, but pointee is not known to be sized: {:?}" , pointer_ty) ;
@@ -222,6 +216,7 @@ impl<'a, 'tcx> Visitor<'tcx> for PointerFinder<'a, 'tcx> {
222
216
ty:: Array ( ty, _) => * ty,
223
217
_ => pointee_ty,
224
218
} ;
219
+ // Check if we excluded this pointee type from the check.
225
220
if self . excluded_pointees . contains ( & element_ty) {
226
221
trace ! ( "Skipping pointer for type: {:?}" , pointee_ty) ;
227
222
return ;
0 commit comments