@@ -182,35 +182,29 @@ impl<'a, 'tcx> Visitor<'tcx> for PointerFinder<'a, 'tcx> {
182182 return ;
183183 }
184184
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.
187186 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 ;
189188
190189 // 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 {
192191 trace ! ( "Indirect, but not based on an raw ptr, not checking {:?}" , place) ;
193192 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+ {
204+ // Naturally, the field type is type of the initial place we look at.
205+ pointee_ty = place. ty ( self . local_decls , self . tcx ) . ty ;
194206 }
195207
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- } ;
214208 // Ideally we'd support this in the future, but for now we are limited to sized types.
215209 if !pointee_ty. is_sized ( self . tcx , self . typing_env ) {
216210 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> {
222216 ty:: Array ( ty, _) => * ty,
223217 _ => pointee_ty,
224218 } ;
219+ // Check if we excluded this pointee type from the check.
225220 if self . excluded_pointees . contains ( & element_ty) {
226221 trace ! ( "Skipping pointer for type: {:?}" , pointee_ty) ;
227222 return ;
0 commit comments