about summary refs log tree commit diff
diff options
context:
space:
mode:
authorBastian Kersting <bkersting@google.com>2025-03-17 15:37:17 +0000
committerBastian Kersting <bkersting@google.com>2025-04-28 12:36:47 +0000
commit7082fa27a792e34a9474db396ccf3958143211af (patch)
treebc0c24aaceefeafee228c5fb45669e695b6582fd
parenta3e7c699bc430e29e3035d36e4b3f9682c86c56e (diff)
downloadrust-7082fa27a792e34a9474db396ccf3958143211af.tar.gz
rust-7082fa27a792e34a9474db396ccf3958143211af.zip
Rework the logic for PointerFinder::visit_place
This makes the implementation of our PointerFinder a bit more
straightforward.
-rw-r--r--compiler/rustc_mir_transform/src/check_pointers.rs39
1 files changed, 17 insertions, 22 deletions
diff --git a/compiler/rustc_mir_transform/src/check_pointers.rs b/compiler/rustc_mir_transform/src/check_pointers.rs
index 7e2d0e4b894..bf94f1aad24 100644
--- a/compiler/rustc_mir_transform/src/check_pointers.rs
+++ b/compiler/rustc_mir_transform/src/check_pointers.rs
@@ -182,35 +182,29 @@ impl<'a, 'tcx> Visitor<'tcx> for PointerFinder<'a, 'tcx> {
             return;
         }
 
-        // Since Deref projections must come first and only once, the pointer for an indirect place
-        // is the Local that the Place is based on.
+        // Get the place and type we visit.
         let pointer = Place::from(place.local);
-        let pointer_ty = self.local_decls[place.local].ty;
+        let pointer_ty = pointer.ty(self.local_decls, self.tcx).ty;
 
         // We only want to check places based on raw pointers
-        if !pointer_ty.is_raw_ptr() {
+        let &ty::RawPtr(mut pointee_ty, _) = pointer_ty.kind() else {
             trace!("Indirect, but not based on an raw ptr, not checking {:?}", place);
             return;
+        };
+
+        // If we see a borrow of a field projection, we want to pass the field type to the
+        // check and not the pointee type.
+        if matches!(self.field_projection_mode, BorrowedFieldProjectionMode::FollowProjections)
+            && matches!(
+                context,
+                PlaceContext::NonMutatingUse(NonMutatingUseContext::SharedBorrow)
+                    | PlaceContext::MutatingUse(MutatingUseContext::Borrow)
+            )
+        {
+            // Naturally, the field type is type of the initial place we look at.
+            pointee_ty = place.ty(self.local_decls, self.tcx).ty;
         }
 
-        // If we see a borrow of a field projection, we want to pass the field Ty to the
-        // check and not the pointee Ty.
-        let pointee_ty = match self.field_projection_mode {
-            BorrowedFieldProjectionMode::FollowProjections
-                if matches!(
-                    context,
-                    PlaceContext::NonMutatingUse(NonMutatingUseContext::SharedBorrow)
-                        | PlaceContext::MutatingUse(MutatingUseContext::Borrow)
-                ) =>
-            {
-                if let Some(PlaceElem::Field(_, ty)) = place.projection.last() {
-                    *ty
-                } else {
-                    pointer_ty.builtin_deref(true).expect("no builtin_deref for an raw pointer")
-                }
-            }
-            _ => pointer_ty.builtin_deref(true).expect("no builtin_deref for an raw pointer"),
-        };
         // Ideally we'd support this in the future, but for now we are limited to sized types.
         if !pointee_ty.is_sized(self.tcx, self.typing_env) {
             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> {
             ty::Array(ty, _) => *ty,
             _ => pointee_ty,
         };
+        // Check if we excluded this pointee type from the check.
         if self.excluded_pointees.contains(&element_ty) {
             trace!("Skipping pointer for type: {:?}", pointee_ty);
             return;