Skip to content

Commit c0e4230

Browse files
committed
simplify some code that depend on Deref
1 parent 41419e7 commit c0e4230

File tree

3 files changed

+32
-28
lines changed

3 files changed

+32
-28
lines changed

compiler/rustc_codegen_ssa/src/mir/place.rs

+3-8
Original file line numberDiff line numberDiff line change
@@ -435,16 +435,11 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
435435
LocalRef::Place(place) => place,
436436
LocalRef::UnsizedPlace(place) => bx.load_operand(place).deref(cx),
437437
LocalRef::Operand(..) => {
438-
if let Some(elem) = place_ref
439-
.projection
440-
.iter()
441-
.enumerate()
442-
.find(|elem| matches!(elem.1, mir::ProjectionElem::Deref))
443-
{
444-
base = elem.0 + 1;
438+
if place_ref.ret_deref().is_some() {
439+
base = 1;
445440
let cg_base = self.codegen_consume(
446441
bx,
447-
mir::PlaceRef { projection: &place_ref.projection[..elem.0], ..place_ref },
442+
mir::PlaceRef { projection: &place_ref.projection[..0], ..place_ref },
448443
);
449444

450445
cg_base.deref(bx.cx())

compiler/rustc_middle/src/mir/mod.rs

+20
Original file line numberDiff line numberDiff line change
@@ -1461,6 +1461,16 @@ impl<'tcx> Place<'tcx> {
14611461
self.projection.iter().any(|elem| elem.is_indirect())
14621462
}
14631463

1464+
/// If MirPhase >= Derefered and if projection contains Deref,
1465+
/// It's guaranteed to be in the first place
1466+
pub fn ret_deref(&self) -> Option<PlaceElem<'tcx>> {
1467+
if !self.projection.is_empty() && self.projection[0] == PlaceElem::Deref {
1468+
return Some(self.projection[0]);
1469+
} else {
1470+
None
1471+
}
1472+
}
1473+
14641474
/// Finds the innermost `Local` from this `Place`, *if* it is either a local itself or
14651475
/// a single deref of a local.
14661476
#[inline(always)]
@@ -1533,6 +1543,16 @@ impl<'tcx> PlaceRef<'tcx> {
15331543
}
15341544
}
15351545

1546+
/// If MirPhase >= Derefered and if projection contains Deref,
1547+
/// It's guaranteed to be in the first place
1548+
pub fn ret_deref(&self) -> Option<PlaceElem<'tcx>> {
1549+
if !self.projection.is_empty() && self.projection[0] == PlaceElem::Deref {
1550+
return Some(self.projection[0]);
1551+
} else {
1552+
None
1553+
}
1554+
}
1555+
15361556
/// If this place represents a local variable like `_X` with no
15371557
/// projections, return `Some(_X)`.
15381558
#[inline]

compiler/rustc_mir_transform/src/add_retag.rs

+9-20
Original file line numberDiff line numberDiff line change
@@ -15,22 +15,13 @@ pub struct AddRetag;
1515
/// (Concurrent accesses by other threads are no problem as these are anyway non-atomic
1616
/// copies. Data races are UB.)
1717
fn is_stable(place: PlaceRef<'_>) -> bool {
18-
place.projection.iter().all(|elem| {
19-
match elem {
20-
// Which place this evaluates to can change with any memory write,
21-
// so cannot assume this to be stable.
22-
ProjectionElem::Deref => false,
23-
// Array indices are interesting, but MIR building generates a *fresh*
24-
// temporary for every array access, so the index cannot be changed as
25-
// a side-effect.
26-
ProjectionElem::Index { .. } |
27-
// The rest is completely boring, they just offset by a constant.
28-
ProjectionElem::Field { .. } |
29-
ProjectionElem::ConstantIndex { .. } |
30-
ProjectionElem::Subslice { .. } |
31-
ProjectionElem::Downcast { .. } => true,
32-
}
33-
})
18+
if place.ret_deref().is_some() {
19+
// Which place this evaluates to can change with any memory write,
20+
// so cannot assume deref to be stable.
21+
return false;
22+
} else {
23+
return true;
24+
}
3425
}
3526

3627
/// Determine whether this type may contain a reference (or box), and thus needs retagging.
@@ -91,10 +82,8 @@ impl<'tcx> MirPass<'tcx> for AddRetag {
9182
};
9283
let place_base_raw = |place: &Place<'tcx>| {
9384
// If this is a `Deref`, get the type of what we are deref'ing.
94-
let deref_base =
95-
place.projection.iter().rposition(|p| matches!(p, ProjectionElem::Deref));
96-
if let Some(deref_base) = deref_base {
97-
let base_proj = &place.projection[..deref_base];
85+
if place.ret_deref().is_some() {
86+
let base_proj = &place.projection[..0];
9887
let ty = Place::ty_from(place.local, base_proj, &*local_decls, tcx).ty;
9988
ty.is_unsafe_ptr()
10089
} else {

0 commit comments

Comments
 (0)