Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Rollup of 5 pull requests #114553

Merged
merged 10 commits into from
Aug 6, 2023
2 changes: 1 addition & 1 deletion compiler/rustc_codegen_ssa/src/mir/place.rs
Original file line number Diff line number Diff line change
Expand Up @@ -441,7 +441,7 @@ 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 place_ref.has_deref() {
if place_ref.is_indirect_first_projection() {
base = 1;
let cg_base = self.codegen_consume(
bx,
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_const_eval/src/interpret/step.rs
Original file line number Diff line number Diff line change
Expand Up @@ -247,7 +247,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {

AddressOf(_, place) => {
// Figure out whether this is an addr_of of an already raw place.
let place_base_raw = if place.has_deref() {
let place_base_raw = if place.is_indirect_first_projection() {
let ty = self.frame().body.local_decls[place.local].ty;
ty.is_unsafe_ptr()
} else {
Expand Down
28 changes: 17 additions & 11 deletions compiler/rustc_middle/src/mir/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1592,14 +1592,13 @@ 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 accidentally used in wrong mir phase
debug_assert!(
self.projection.is_empty() || !self.projection[1..].contains(&PlaceElem::Deref)
);
self.projection.first() == Some(&PlaceElem::Deref)
/// Returns `true` if this `Place`'s first projection is `Deref`.
///
/// This is useful because for MIR phases `AnalysisPhase::PostCleanup` and later,
/// `Deref` projections can only occur as the first projection. In that case this method
/// is equivalent to `is_indirect`, but faster.
pub fn is_indirect_first_projection(&self) -> bool {
self.as_ref().is_indirect_first_projection()
}

/// Finds the innermost `Local` from this `Place`, *if* it is either a local itself or
Expand Down Expand Up @@ -1672,9 +1671,16 @@ impl<'tcx> PlaceRef<'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 {
/// Returns `true` if this `Place`'s first projection is `Deref`.
///
/// This is useful because for MIR phases `AnalysisPhase::PostCleanup` and later,
/// `Deref` projections can only occur as the first projection. In that case this method
/// is equivalent to `is_indirect`, but faster.
pub fn is_indirect_first_projection(&self) -> bool {
// To make sure this is not accidentally used in wrong mir phase
debug_assert!(
self.projection.is_empty() || !self.projection[1..].contains(&PlaceElem::Deref)
);
self.projection.first() == Some(&PlaceElem::Deref)
}

Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_mir_dataflow/src/value_analysis.rs
Original file line number Diff line number Diff line change
Expand Up @@ -839,7 +839,7 @@ impl Map {
tail_elem: Option<TrackElem>,
f: &mut impl FnMut(ValueIndex),
) {
if place.has_deref() {
if place.is_indirect_first_projection() {
// We do not track indirect places.
return;
}
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_mir_transform/src/add_retag.rs
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ impl<'tcx> MirPass<'tcx> for AddRetag {
let basic_blocks = body.basic_blocks.as_mut();
let local_decls = &body.local_decls;
let needs_retag = |place: &Place<'tcx>| {
!place.has_deref() // we're not really interested in stores to "outside" locations, they are hard to keep track of anyway
!place.is_indirect_first_projection() // we're not really interested in stores to "outside" locations, they are hard to keep track of anyway
&& may_contain_reference(place.ty(&*local_decls, tcx).ty, /*depth*/ 3, tcx)
&& !local_decls[place.local].is_deref_temp()
};
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_mir_transform/src/copy_prop.rs
Original file line number Diff line number Diff line change
Expand Up @@ -154,7 +154,7 @@ impl<'tcx> MutVisitor<'tcx> for Replacer<'_, 'tcx> {
fn visit_operand(&mut self, operand: &mut Operand<'tcx>, loc: Location) {
if let Operand::Move(place) = *operand
// A move out of a projection of a copy is equivalent to a copy of the original projection.
&& !place.has_deref()
&& !place.is_indirect_first_projection()
&& !self.fully_moved.contains(place.local)
{
*operand = Operand::Copy(place);
Expand Down
31 changes: 31 additions & 0 deletions compiler/rustc_smir/src/rustc_smir/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1063,3 +1063,34 @@ impl<'tcx> Stable<'tcx> for rustc_middle::ty::BoundTy {
BoundTy { var: self.var.as_usize(), kind: self.kind.stable(tables) }
}
}

impl<'tcx> Stable<'tcx> for mir::interpret::Allocation {
type T = stable_mir::ty::Allocation;

fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T {
let size = self.size();
let mut bytes: Vec<Option<u8>> = self
.inspect_with_uninit_and_ptr_outside_interpreter(0..size.bytes_usize())
.iter()
.copied()
.map(Some)
.collect();
for (i, b) in bytes.iter_mut().enumerate() {
if !self.init_mask().get(rustc_target::abi::Size::from_bytes(i)) {
*b = None;
}
}
stable_mir::ty::Allocation {
bytes: bytes,
provenance: {
let mut ptrs = Vec::new();
for (size, prov) in self.provenance().ptrs().iter() {
ptrs.push((size.bytes_usize(), opaque(prov)));
}
stable_mir::ty::ProvenanceMap { ptrs }
},
align: self.align.bytes(),
mutability: self.mutability.stable(tables),
}
}
}
22 changes: 22 additions & 0 deletions compiler/rustc_smir/src/stable_mir/ty.rs
Original file line number Diff line number Diff line change
Expand Up @@ -242,3 +242,25 @@ pub struct BoundTy {
pub var: usize,
pub kind: BoundTyKind,
}

pub type Bytes = Vec<Option<u8>>;
pub type Size = usize;
pub type Prov = Opaque;
pub type Align = u64;
pub type InitMaskMaterialized = Vec<u64>;

/// Stores the provenance information of pointers stored in memory.
#[derive(Clone, Debug)]
pub struct ProvenanceMap {
/// Provenance in this map applies from the given offset for an entire pointer-size worth of
/// bytes. Two entries in this map are always at least a pointer size apart.
pub ptrs: Vec<(Size, Prov)>,
}

#[derive(Clone, Debug)]
pub struct Allocation {
pub bytes: Bytes,
pub provenance: ProvenanceMap,
pub align: Align,
pub mutability: Mutability,
}
1 change: 1 addition & 0 deletions library/std/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -298,6 +298,7 @@
#![feature(maybe_uninit_slice)]
#![feature(maybe_uninit_uninit_array)]
#![feature(maybe_uninit_write_slice)]
#![feature(offset_of)]
#![feature(panic_can_unwind)]
#![feature(panic_info_message)]
#![feature(panic_internals)]
Expand Down
27 changes: 2 additions & 25 deletions library/std/src/sys/unix/fs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,17 +7,6 @@ use crate::ffi::{CStr, OsStr, OsString};
use crate::fmt;
use crate::io::{self, BorrowedCursor, Error, IoSlice, IoSliceMut, SeekFrom};
use crate::mem;
#[cfg(any(
target_os = "android",
target_os = "linux",
target_os = "solaris",
target_os = "fuchsia",
target_os = "redox",
target_os = "illumos",
target_os = "nto",
target_os = "vita",
))]
use crate::mem::MaybeUninit;
use crate::os::unix::io::{AsFd, AsRawFd, BorrowedFd, FromRawFd, IntoRawFd};
use crate::path::{Path, PathBuf};
use crate::ptr;
Expand Down Expand Up @@ -712,22 +701,10 @@ impl Iterator for ReadDir {
// requires the full extent of *entry_ptr to be in bounds of the same
// allocation, which is not necessarily the case here.
//
// Absent any other way to obtain a pointer to `(*entry_ptr).d_name`
// legally in Rust analogously to how it would be done in C, we instead
// need to make our own non-libc allocation that conforms to the weird
// imaginary definition of dirent64, and use that for a field offset
// computation.
// Instead we must access fields individually through their offsets.
macro_rules! offset_ptr {
($entry_ptr:expr, $field:ident) => {{
const OFFSET: isize = {
let delusion = MaybeUninit::<dirent64>::uninit();
let entry_ptr = delusion.as_ptr();
unsafe {
ptr::addr_of!((*entry_ptr).$field)
.cast::<u8>()
.offset_from(entry_ptr.cast::<u8>())
}
};
const OFFSET: isize = mem::offset_of!(dirent64, $field) as isize;
if true {
// Cast to the same type determined by the else branch.
$entry_ptr.byte_offset(OFFSET).cast::<_>()
Expand Down
2 changes: 1 addition & 1 deletion src/tools/clippy/clippy_lints/src/dereference.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1170,7 +1170,7 @@ fn referent_used_exactly_once<'tcx>(
&& let [location] = *local_assignments(mir, local).as_slice()
&& let Some(statement) = mir.basic_blocks[location.block].statements.get(location.statement_index)
&& let StatementKind::Assign(box (_, Rvalue::Ref(_, _, place))) = statement.kind
&& !place.has_deref()
&& !place.is_indirect_first_projection()
// Ensure not in a loop (https://github.com/rust-lang/rust-clippy/issues/9710)
&& TriColorDepthFirstSearch::new(&mir.basic_blocks).run_from(location.block, &mut CycleDetector).is_none()
{
Expand Down
1 change: 0 additions & 1 deletion src/tools/linkchecker/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -368,7 +368,6 @@ impl Checker {
return;
}
// Search for intra-doc links that rustdoc didn't warn about
// FIXME(#77199, 77200) Rustdoc should just warn about these directly.
// NOTE: only looks at one line at a time; in practice this should find most links
for (i, line) in source.lines().enumerate() {
for broken_link in BROKEN_INTRA_DOC_LINK.captures_iter(line) {
Expand Down
6 changes: 3 additions & 3 deletions tests/rustdoc-gui/search-error.goml
Original file line number Diff line number Diff line change
Expand Up @@ -20,20 +20,20 @@ call-function: (
"check-colors",
{
"theme": "ayu",
"error_background": "rgb(79, 76, 76)",
"error_background": "#4f4c4c",
},
)
call-function: (
"check-colors",
{
"theme": "dark",
"error_background": "rgb(72, 72, 72)",
"error_background": "#484848",
},
)
call-function: (
"check-colors",
{
"theme": "light",
"error_background": "rgb(208, 204, 204)",
"error_background": "#d0cccc",
},
)