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::Place(place) => place,
|
||||||
LocalRef::UnsizedPlace(place) => bx.load_operand(place).deref(cx),
|
LocalRef::UnsizedPlace(place) => bx.load_operand(place).deref(cx),
|
||||||
LocalRef::Operand(..) => {
|
LocalRef::Operand(..) => {
|
||||||
if place_ref.has_deref() {
|
if place_ref.is_indirect_first_projection() {
|
||||||
base = 1;
|
base = 1;
|
||||||
let cg_base = self.codegen_consume(
|
let cg_base = self.codegen_consume(
|
||||||
bx,
|
bx,
|
||||||
|
|
|
@ -247,7 +247,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
|
||||||
|
|
||||||
AddressOf(_, place) => {
|
AddressOf(_, place) => {
|
||||||
// Figure out whether this is an addr_of of an already raw 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;
|
let ty = self.frame().body.local_decls[place.local].ty;
|
||||||
ty.is_unsafe_ptr()
|
ty.is_unsafe_ptr()
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -1592,14 +1592,13 @@ impl<'tcx> Place<'tcx> {
|
||||||
self.projection.iter().any(|elem| elem.is_indirect())
|
self.projection.iter().any(|elem| elem.is_indirect())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// If MirPhase >= Derefered and if projection contains Deref,
|
/// Returns `true` if this `Place`'s first projection is `Deref`.
|
||||||
/// It's guaranteed to be in the first place
|
///
|
||||||
pub fn has_deref(&self) -> bool {
|
/// This is useful because for MIR phases `AnalysisPhase::PostCleanup` and later,
|
||||||
// To make sure this is not accidentally used in wrong mir phase
|
/// `Deref` projections can only occur as the first projection. In that case this method
|
||||||
debug_assert!(
|
/// is equivalent to `is_indirect`, but faster.
|
||||||
self.projection.is_empty() || !self.projection[1..].contains(&PlaceElem::Deref)
|
pub fn is_indirect_first_projection(&self) -> bool {
|
||||||
);
|
self.as_ref().is_indirect_first_projection()
|
||||||
self.projection.first() == Some(&PlaceElem::Deref)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Finds the innermost `Local` from this `Place`, *if* it is either a local itself or
|
/// 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())
|
self.projection.iter().any(|elem| elem.is_indirect())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// If MirPhase >= Derefered and if projection contains Deref,
|
/// Returns `true` if this `Place`'s first projection is `Deref`.
|
||||||
/// It's guaranteed to be in the first place
|
///
|
||||||
pub fn has_deref(&self) -> bool {
|
/// 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)
|
self.projection.first() == Some(&PlaceElem::Deref)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -839,7 +839,7 @@ impl Map {
|
||||||
tail_elem: Option<TrackElem>,
|
tail_elem: Option<TrackElem>,
|
||||||
f: &mut impl FnMut(ValueIndex),
|
f: &mut impl FnMut(ValueIndex),
|
||||||
) {
|
) {
|
||||||
if place.has_deref() {
|
if place.is_indirect_first_projection() {
|
||||||
// We do not track indirect places.
|
// We do not track indirect places.
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
@ -60,7 +60,7 @@ impl<'tcx> MirPass<'tcx> for AddRetag {
|
||||||
let basic_blocks = body.basic_blocks.as_mut();
|
let basic_blocks = body.basic_blocks.as_mut();
|
||||||
let local_decls = &body.local_decls;
|
let local_decls = &body.local_decls;
|
||||||
let needs_retag = |place: &Place<'tcx>| {
|
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)
|
&& may_contain_reference(place.ty(&*local_decls, tcx).ty, /*depth*/ 3, tcx)
|
||||||
&& !local_decls[place.local].is_deref_temp()
|
&& !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) {
|
fn visit_operand(&mut self, operand: &mut Operand<'tcx>, loc: Location) {
|
||||||
if let Operand::Move(place) = *operand
|
if let Operand::Move(place) = *operand
|
||||||
// A move out of a projection of a copy is equivalent to a copy of the original projection.
|
// 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)
|
&& !self.fully_moved.contains(place.local)
|
||||||
{
|
{
|
||||||
*operand = Operand::Copy(place);
|
*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) }
|
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 var: usize,
|
||||||
pub kind: BoundTyKind,
|
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_slice)]
|
||||||
#![feature(maybe_uninit_uninit_array)]
|
#![feature(maybe_uninit_uninit_array)]
|
||||||
#![feature(maybe_uninit_write_slice)]
|
#![feature(maybe_uninit_write_slice)]
|
||||||
|
#![feature(offset_of)]
|
||||||
#![feature(panic_can_unwind)]
|
#![feature(panic_can_unwind)]
|
||||||
#![feature(panic_info_message)]
|
#![feature(panic_info_message)]
|
||||||
#![feature(panic_internals)]
|
#![feature(panic_internals)]
|
||||||
|
|
|
@ -7,17 +7,6 @@ use crate::ffi::{CStr, OsStr, OsString};
|
||||||
use crate::fmt;
|
use crate::fmt;
|
||||||
use crate::io::{self, BorrowedCursor, Error, IoSlice, IoSliceMut, SeekFrom};
|
use crate::io::{self, BorrowedCursor, Error, IoSlice, IoSliceMut, SeekFrom};
|
||||||
use crate::mem;
|
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::os::unix::io::{AsFd, AsRawFd, BorrowedFd, FromRawFd, IntoRawFd};
|
||||||
use crate::path::{Path, PathBuf};
|
use crate::path::{Path, PathBuf};
|
||||||
use crate::ptr;
|
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
|
// requires the full extent of *entry_ptr to be in bounds of the same
|
||||||
// allocation, which is not necessarily the case here.
|
// allocation, which is not necessarily the case here.
|
||||||
//
|
//
|
||||||
// Absent any other way to obtain a pointer to `(*entry_ptr).d_name`
|
// Instead we must access fields individually through their offsets.
|
||||||
// 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.
|
|
||||||
macro_rules! offset_ptr {
|
macro_rules! offset_ptr {
|
||||||
($entry_ptr:expr, $field:ident) => {{
|
($entry_ptr:expr, $field:ident) => {{
|
||||||
const OFFSET: isize = {
|
const OFFSET: isize = mem::offset_of!(dirent64, $field) as 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>())
|
|
||||||
}
|
|
||||||
};
|
|
||||||
if true {
|
if true {
|
||||||
// Cast to the same type determined by the else branch.
|
// Cast to the same type determined by the else branch.
|
||||||
$entry_ptr.byte_offset(OFFSET).cast::<_>()
|
$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 [location] = *local_assignments(mir, local).as_slice()
|
||||||
&& let Some(statement) = mir.basic_blocks[location.block].statements.get(location.statement_index)
|
&& let Some(statement) = mir.basic_blocks[location.block].statements.get(location.statement_index)
|
||||||
&& let StatementKind::Assign(box (_, Rvalue::Ref(_, _, place))) = statement.kind
|
&& 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)
|
// 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()
|
&& TriColorDepthFirstSearch::new(&mir.basic_blocks).run_from(location.block, &mut CycleDetector).is_none()
|
||||||
{
|
{
|
||||||
|
|
|
@ -368,7 +368,6 @@ impl Checker {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// Search for intra-doc links that rustdoc didn't warn about
|
// 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
|
// NOTE: only looks at one line at a time; in practice this should find most links
|
||||||
for (i, line) in source.lines().enumerate() {
|
for (i, line) in source.lines().enumerate() {
|
||||||
for broken_link in BROKEN_INTRA_DOC_LINK.captures_iter(line) {
|
for broken_link in BROKEN_INTRA_DOC_LINK.captures_iter(line) {
|
||||||
|
|
|
@ -20,20 +20,20 @@ call-function: (
|
||||||
"check-colors",
|
"check-colors",
|
||||||
{
|
{
|
||||||
"theme": "ayu",
|
"theme": "ayu",
|
||||||
"error_background": "rgb(79, 76, 76)",
|
"error_background": "#4f4c4c",
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
call-function: (
|
call-function: (
|
||||||
"check-colors",
|
"check-colors",
|
||||||
{
|
{
|
||||||
"theme": "dark",
|
"theme": "dark",
|
||||||
"error_background": "rgb(72, 72, 72)",
|
"error_background": "#484848",
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
call-function: (
|
call-function: (
|
||||||
"check-colors",
|
"check-colors",
|
||||||
{
|
{
|
||||||
"theme": "light",
|
"theme": "light",
|
||||||
"error_background": "rgb(208, 204, 204)",
|
"error_background": "#d0cccc",
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue