Auto merge of #114553 - matthiaskrgr:rollup-5yddunv, r=matthiaskrgr
Rollup of 5 pull requests Successful merges: - #114466 (Add Allocation to SMIR) - #114505 (Add documentation to has_deref) - #114519 (use offset_of! to calculate dirent64 field offsets) - #114537 (Migrate GUI colors test to original CSS color format) - #114539 (linkchecker: Remove unneeded FIXME about intra-doc links) Failed merges: - #114485 (Add trait decls to SMIR) r? `@ghost` `@rustbot` modify labels: rollup
This commit is contained in:
commit
85fbb57149
13 changed files with 82 additions and 46 deletions
|
@ -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,
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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
|
||||
|
@ -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)
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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()
|
||||
};
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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,
|
||||
}
|
||||
|
|
|
@ -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)]
|
||||
|
|
|
@ -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;
|
||||
|
@ -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::<_>()
|
||||
|
|
|
@ -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()
|
||||
{
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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",
|
||||
},
|
||||
)
|
||||
|
|
Loading…
Add table
Reference in a new issue