Skip to content

Commit 1919dff

Browse files
committed
Auto merge of rust-lang#10989 - ericmarkmartin:use-placeref-abstraction, r=Manishearth
Use placeref abstraction rust-lang#80647 suggests refactoring certain patterns with MIR places to use higher-level abstractions provided by the [`Place`](https://doc.rust-lang.org/stable/nightly-rustc/rustc_middle/mir/struct.Place.html)/[`PlaceRef`](https://doc.rust-lang.org/stable/nightly-rustc/rustc_middle/mir/struct.PlaceRef.html). While working on that issue, I found a couple candidates for such refactoring in clippy. *Please write a short comment explaining your change (or "none" for internal only changes)* changelog: none
2 parents 89294e1 + 9bc6e11 commit 1919dff

File tree

3 files changed

+16
-15
lines changed

3 files changed

+16
-15
lines changed

clippy_lints/src/redundant_clone.rs

Lines changed: 5 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -320,8 +320,6 @@ fn base_local_and_movability<'tcx>(
320320
mir: &mir::Body<'tcx>,
321321
place: mir::Place<'tcx>,
322322
) -> (mir::Local, CannotMoveOut) {
323-
use rustc_middle::mir::PlaceRef;
324-
325323
// Dereference. You cannot move things out from a borrowed value.
326324
let mut deref = false;
327325
// Accessing a field of an ADT that has `Drop`. Moving the field out will cause E0509.
@@ -330,17 +328,14 @@ fn base_local_and_movability<'tcx>(
330328
// underlying type implements Copy
331329
let mut slice = false;
332330

333-
let PlaceRef { local, mut projection } = place.as_ref();
334-
while let [base @ .., elem] = projection {
335-
projection = base;
331+
for (base, elem) in place.as_ref().iter_projections() {
332+
let base_ty = base.ty(&mir.local_decls, cx.tcx).ty;
336333
deref |= matches!(elem, mir::ProjectionElem::Deref);
337-
field |= matches!(elem, mir::ProjectionElem::Field(..))
338-
&& has_drop(cx, mir::Place::ty_from(local, projection, &mir.local_decls, cx.tcx).ty);
339-
slice |= matches!(elem, mir::ProjectionElem::Index(..))
340-
&& !is_copy(cx, mir::Place::ty_from(local, projection, &mir.local_decls, cx.tcx).ty);
334+
field |= matches!(elem, mir::ProjectionElem::Field(..)) && has_drop(cx, base_ty);
335+
slice |= matches!(elem, mir::ProjectionElem::Index(..)) && !is_copy(cx, base_ty);
341336
}
342337

343-
(local, deref || field || slice)
338+
(place.local, deref || field || slice)
344339
}
345340

346341
#[derive(Default)]

clippy_utils/src/qualify_min_const_fn.rs

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -284,13 +284,10 @@ fn check_operand<'tcx>(tcx: TyCtxt<'tcx>, operand: &Operand<'tcx>, span: Span, b
284284
}
285285

286286
fn check_place<'tcx>(tcx: TyCtxt<'tcx>, place: Place<'tcx>, span: Span, body: &Body<'tcx>) -> McfResult {
287-
let mut cursor = place.projection.as_ref();
288-
289-
while let [ref proj_base @ .., elem] = *cursor {
290-
cursor = proj_base;
287+
for (base, elem) in place.as_ref().iter_projections() {
291288
match elem {
292289
ProjectionElem::Field(..) => {
293-
let base_ty = Place::ty_from(place.local, proj_base, body, tcx).ty;
290+
let base_ty = base.ty(body, tcx).ty;
294291
if let Some(def) = base_ty.ty_adt_def() {
295292
// No union field accesses in `const fn`
296293
if def.is_union() {

tests/ui/missing_const_for_fn/cant_be_const.rs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -157,3 +157,12 @@ impl Issue10617 {
157157
self.0
158158
}
159159
}
160+
161+
union U {
162+
f: u32,
163+
}
164+
165+
// Do not lint because accessing union fields from const functions is unstable
166+
fn h(u: U) -> u32 {
167+
unsafe { u.f }
168+
}

0 commit comments

Comments
 (0)