diff options
| author | Bastian Kersting <bkersting@google.com> | 2025-03-17 15:37:17 +0000 |
|---|---|---|
| committer | Bastian Kersting <bkersting@google.com> | 2025-04-28 12:36:47 +0000 |
| commit | 7082fa27a792e34a9474db396ccf3958143211af (patch) | |
| tree | bc0c24aaceefeafee228c5fb45669e695b6582fd | |
| parent | a3e7c699bc430e29e3035d36e4b3f9682c86c56e (diff) | |
| download | rust-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.rs | 39 |
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; |
