@@ -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
+ {
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;
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