Skip to content

Commit

Permalink
Auto merge of rust-lang#99735 - JohnTitor:rollup-d93jyr2, r=JohnTitor
Browse files Browse the repository at this point in the history
Rollup of 9 pull requests

Successful merges:

 - rust-lang#92390 (Constify a few `(Partial)Ord` impls)
 - rust-lang#97077 (Simplify some code that depend on Deref)
 - rust-lang#98710 (correct the output of a `capacity` method example)
 - rust-lang#99084 (clarify how write_bytes can lead to UB due to invalid values)
 - rust-lang#99178 (Lighten up const_prop_lint, reusing const_prop)
 - rust-lang#99673 (don't ICE on invalid dyn calls)
 - rust-lang#99703 (Expose size_hint() for TokenStream's iterator)
 - rust-lang#99709 (`Inherited` always has `TypeckResults` available)
 - rust-lang#99713 (Fix sidebar background)

Failed merges:

r? `@ghost`
`@rustbot` modify labels: rollup
  • Loading branch information
bors committed Jul 25, 2022
2 parents 6dbae3a + e58bfac commit a867059
Show file tree
Hide file tree
Showing 15 changed files with 157 additions and 471 deletions.
12 changes: 3 additions & 9 deletions compiler/rustc_codegen_ssa/src/mir/place.rs
Original file line number Diff line number Diff line change
Expand Up @@ -435,18 +435,12 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
LocalRef::Place(place) => place,
LocalRef::UnsizedPlace(place) => bx.load_operand(place).deref(cx),
LocalRef::Operand(..) => {
if let Some(elem) = place_ref
.projection
.iter()
.enumerate()
.find(|elem| matches!(elem.1, mir::ProjectionElem::Deref))
{
base = elem.0 + 1;
if place_ref.has_deref() {
base = 1;
let cg_base = self.codegen_consume(
bx,
mir::PlaceRef { projection: &place_ref.projection[..elem.0], ..place_ref },
mir::PlaceRef { projection: &place_ref.projection[..0], ..place_ref },
);

cg_base.deref(bx.cx())
} else {
bug!("using operand local {:?} as place", place_ref);
Expand Down
4 changes: 2 additions & 2 deletions compiler/rustc_const_eval/src/interpret/terminator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -571,8 +571,8 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {

// Now determine the actual method to call. We can do that in two different ways and
// compare them to ensure everything fits.
let ty::VtblEntry::Method(fn_inst) = self.get_vtable_entries(vptr)?[idx] else {
span_bug!(self.cur_span(), "dyn call index points at something that is not a method")
let Some(ty::VtblEntry::Method(fn_inst)) = self.get_vtable_entries(vptr)?.get(idx).copied() else {
throw_ub_format!("`dyn` call trying to call something that is not a method")
};
if cfg!(debug_assertions) {
let tcx = *self.tcx;
Expand Down
14 changes: 14 additions & 0 deletions compiler/rustc_middle/src/mir/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1461,6 +1461,14 @@ impl<'tcx> Place<'tcx> {
self.projection.iter().any(|elem| elem.is_indirect())
}

/// If MirPhase >= Derefered and if projection contains Deref,
/// It's guaranteed to be in the first place
pub fn has_deref(&self) -> bool {
// To make sure this is not accidently used in wrong mir phase
debug_assert!(!self.projection[1..].contains(&PlaceElem::Deref));
self.projection.first() == Some(&PlaceElem::Deref)
}

/// Finds the innermost `Local` from this `Place`, *if* it is either a local itself or
/// a single deref of a local.
#[inline(always)]
Expand Down Expand Up @@ -1533,6 +1541,12 @@ impl<'tcx> PlaceRef<'tcx> {
}
}

/// If MirPhase >= Derefered and if projection contains Deref,
/// It's guaranteed to be in the first place
pub fn has_deref(&self) -> bool {
self.projection.first() == Some(&PlaceElem::Deref)
}

/// If this place represents a local variable like `_X` with no
/// projections, return `Some(_X)`.
#[inline]
Expand Down
26 changes: 5 additions & 21 deletions compiler/rustc_mir_transform/src/add_retag.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,22 +15,9 @@ pub struct AddRetag;
/// (Concurrent accesses by other threads are no problem as these are anyway non-atomic
/// copies. Data races are UB.)
fn is_stable(place: PlaceRef<'_>) -> bool {
place.projection.iter().all(|elem| {
match elem {
// Which place this evaluates to can change with any memory write,
// so cannot assume this to be stable.
ProjectionElem::Deref => false,
// Array indices are interesting, but MIR building generates a *fresh*
// temporary for every array access, so the index cannot be changed as
// a side-effect.
ProjectionElem::Index { .. } |
// The rest is completely boring, they just offset by a constant.
ProjectionElem::Field { .. } |
ProjectionElem::ConstantIndex { .. } |
ProjectionElem::Subslice { .. } |
ProjectionElem::Downcast { .. } => true,
}
})
// Which place this evaluates to can change with any memory write,
// so cannot assume deref to be stable.
!place.has_deref()
}

/// Determine whether this type may contain a reference (or box), and thus needs retagging.
Expand Down Expand Up @@ -91,11 +78,8 @@ impl<'tcx> MirPass<'tcx> for AddRetag {
};
let place_base_raw = |place: &Place<'tcx>| {
// If this is a `Deref`, get the type of what we are deref'ing.
let deref_base =
place.projection.iter().rposition(|p| matches!(p, ProjectionElem::Deref));
if let Some(deref_base) = deref_base {
let base_proj = &place.projection[..deref_base];
let ty = Place::ty_from(place.local, base_proj, &*local_decls, tcx).ty;
if place.has_deref() {
let ty = &local_decls[place.local].ty;
ty.is_unsafe_ptr()
} else {
// Not a deref, and thus not raw.
Expand Down
16 changes: 8 additions & 8 deletions compiler/rustc_mir_transform/src/const_prop.rs
Original file line number Diff line number Diff line change
Expand Up @@ -155,18 +155,18 @@ impl<'tcx> MirPass<'tcx> for ConstProp {
}
}

struct ConstPropMachine<'mir, 'tcx> {
pub struct ConstPropMachine<'mir, 'tcx> {
/// The virtual call stack.
stack: Vec<Frame<'mir, 'tcx>>,
/// `OnlyInsideOwnBlock` locals that were written in the current block get erased at the end.
written_only_inside_own_block_locals: FxHashSet<Local>,
pub written_only_inside_own_block_locals: FxHashSet<Local>,
/// Locals that need to be cleared after every block terminates.
only_propagate_inside_block_locals: BitSet<Local>,
can_const_prop: IndexVec<Local, ConstPropMode>,
pub only_propagate_inside_block_locals: BitSet<Local>,
pub can_const_prop: IndexVec<Local, ConstPropMode>,
}

impl ConstPropMachine<'_, '_> {
fn new(
pub fn new(
only_propagate_inside_block_locals: BitSet<Local>,
can_const_prop: IndexVec<Local, ConstPropMode>,
) -> Self {
Expand Down Expand Up @@ -816,7 +816,7 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> {

/// The mode that `ConstProp` is allowed to run in for a given `Local`.
#[derive(Clone, Copy, Debug, PartialEq)]
enum ConstPropMode {
pub enum ConstPropMode {
/// The `Local` can be propagated into and reads of this `Local` can also be propagated.
FullConstProp,
/// The `Local` can only be propagated into and from its own block.
Expand All @@ -828,7 +828,7 @@ enum ConstPropMode {
NoPropagation,
}

struct CanConstProp {
pub struct CanConstProp {
can_const_prop: IndexVec<Local, ConstPropMode>,
// False at the beginning. Once set, no more assignments are allowed to that local.
found_assignment: BitSet<Local>,
Expand All @@ -838,7 +838,7 @@ struct CanConstProp {

impl CanConstProp {
/// Returns true if `local` can be propagated
fn check<'tcx>(
pub fn check<'tcx>(
tcx: TyCtxt<'tcx>,
param_env: ParamEnv<'tcx>,
body: &Body<'tcx>,
Expand Down
Loading

0 comments on commit a867059

Please sign in to comment.