Skip to content

Commit db8b83e

Browse files
committed
Rework the logic for PointerFinder::visit_place
This makes the implementation of our PointerFinder a bit more straightforward.
1 parent d3ef125 commit db8b83e

File tree

1 file changed

+17
-22
lines changed

1 file changed

+17
-22
lines changed

compiler/rustc_mir_transform/src/check_pointers.rs

+17-22
Original file line numberDiff line numberDiff line change
@@ -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+
&& let Some(PlaceElem::Field(_, ty)) = place.projection.last()
204+
{
205+
pointee_ty = *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

Comments
 (0)