Auto merge of #124084 - matthiaskrgr:rollup-h42psbx, r=matthiaskrgr
Rollup of 9 pull requests Successful merges: - #116957 (meta: notify #t-rustdoc Zulip stream on backport nominations) - #122201 (Document overrides of `clone_from()` in core/std) - #122723 (Use same file permissions for ar_archive_writer as the LLVM archive writer) - #124030 (interpret: pass MemoryKind to adjust_alloc_base_pointer) - #124037 (Don't ascend into parent bodies when collecting stmts for possible return suggestion) - #124049 (Stabilize `const_io_structs`) - #124062 (Add another expression to weird-exprs.rs) - #124066 (Don't error on subtyping of equal types) - #124073 (Remove libc from rust_get_test_int uses) r? `@ghost` `@rustbot` modify labels: rollup
This commit is contained in:
commit
c45dee5efd
48 changed files with 402 additions and 162 deletions
|
@ -13,7 +13,7 @@ use object::read::macho::FatArch;
|
|||
use tempfile::Builder as TempFileBuilder;
|
||||
|
||||
use std::error::Error;
|
||||
use std::fs::File;
|
||||
use std::fs::{self, File};
|
||||
use std::io::{self, Write};
|
||||
use std::path::{Path, PathBuf};
|
||||
|
||||
|
@ -280,12 +280,21 @@ impl<'a> ArArchiveBuilder<'a> {
|
|||
// This prevents programs (including rustc) from attempting to read a partial archive.
|
||||
// It also enables writing an archive with the same filename as a dependency on Windows as
|
||||
// required by a test.
|
||||
let mut archive_tmpfile = TempFileBuilder::new()
|
||||
// The tempfile crate currently uses 0o600 as mode for the temporary files and directories
|
||||
// it creates. We need it to be the default mode for back compat reasons however. (See
|
||||
// #107495) To handle this we are telling tempfile to create a temporary directory instead
|
||||
// and then inside this directory create a file using File::create.
|
||||
let archive_tmpdir = TempFileBuilder::new()
|
||||
.suffix(".temp-archive")
|
||||
.tempfile_in(output.parent().unwrap_or_else(|| Path::new("")))
|
||||
.map_err(|err| io_error_context("couldn't create a temp file", err))?;
|
||||
.tempdir_in(output.parent().unwrap_or_else(|| Path::new("")))
|
||||
.map_err(|err| {
|
||||
io_error_context("couldn't create a directory for the temp file", err)
|
||||
})?;
|
||||
let archive_tmpfile_path = archive_tmpdir.path().join("tmp.a");
|
||||
let mut archive_tmpfile = File::create_new(&archive_tmpfile_path)
|
||||
.map_err(|err| io_error_context("couldn't create the temp file", err))?;
|
||||
|
||||
write_archive_to_stream(archive_tmpfile.as_file_mut(), &entries, archive_kind, false)?;
|
||||
write_archive_to_stream(&mut archive_tmpfile, &entries, archive_kind, false)?;
|
||||
|
||||
let any_entries = !entries.is_empty();
|
||||
drop(entries);
|
||||
|
@ -293,9 +302,11 @@ impl<'a> ArArchiveBuilder<'a> {
|
|||
// output archive to the same location as an input archive on Windows.
|
||||
drop(self.src_archives);
|
||||
|
||||
archive_tmpfile
|
||||
.persist(output)
|
||||
.map_err(|err| io_error_context("failed to rename archive file", err.error))?;
|
||||
fs::rename(archive_tmpfile_path, output)
|
||||
.map_err(|err| io_error_context("failed to rename archive file", err))?;
|
||||
archive_tmpdir
|
||||
.close()
|
||||
.map_err(|err| io_error_context("failed to remove temporary directory", err))?;
|
||||
|
||||
Ok(any_entries)
|
||||
}
|
||||
|
|
|
@ -288,28 +288,19 @@ pub trait Machine<'mir, 'tcx: 'mir>: Sized {
|
|||
}
|
||||
|
||||
/// Return the `AllocId` for the given thread-local static in the current thread.
|
||||
fn thread_local_static_base_pointer(
|
||||
fn thread_local_static_pointer(
|
||||
_ecx: &mut InterpCx<'mir, 'tcx, Self>,
|
||||
def_id: DefId,
|
||||
) -> InterpResult<'tcx, Pointer<Self::Provenance>> {
|
||||
throw_unsup!(ThreadLocalStatic(def_id))
|
||||
}
|
||||
|
||||
/// Return the root pointer for the given `extern static`.
|
||||
fn extern_static_base_pointer(
|
||||
/// Return the `AllocId` for the given `extern static`.
|
||||
fn extern_static_pointer(
|
||||
ecx: &InterpCx<'mir, 'tcx, Self>,
|
||||
def_id: DefId,
|
||||
) -> InterpResult<'tcx, Pointer<Self::Provenance>>;
|
||||
|
||||
/// Return a "base" pointer for the given allocation: the one that is used for direct
|
||||
/// accesses to this static/const/fn allocation, or the one returned from the heap allocator.
|
||||
///
|
||||
/// Not called on `extern` or thread-local statics (those use the methods above).
|
||||
fn adjust_alloc_base_pointer(
|
||||
ecx: &InterpCx<'mir, 'tcx, Self>,
|
||||
ptr: Pointer,
|
||||
) -> InterpResult<'tcx, Pointer<Self::Provenance>>;
|
||||
|
||||
/// "Int-to-pointer cast"
|
||||
fn ptr_from_addr_cast(
|
||||
ecx: &InterpCx<'mir, 'tcx, Self>,
|
||||
|
@ -336,6 +327,8 @@ pub trait Machine<'mir, 'tcx: 'mir>: Sized {
|
|||
|
||||
/// Called to adjust allocations to the Provenance and AllocExtra of this machine.
|
||||
///
|
||||
/// If `alloc` contains pointers, then they are all pointing to globals.
|
||||
///
|
||||
/// The way we construct allocations is to always first construct it without extra and then add
|
||||
/// the extra. This keeps uniform code paths for handling both allocations created by CTFE for
|
||||
/// globals, and allocations created by Miri during evaluation.
|
||||
|
@ -354,6 +347,19 @@ pub trait Machine<'mir, 'tcx: 'mir>: Sized {
|
|||
kind: Option<MemoryKind<Self::MemoryKind>>,
|
||||
) -> InterpResult<'tcx, Cow<'b, Allocation<Self::Provenance, Self::AllocExtra, Self::Bytes>>>;
|
||||
|
||||
/// Return a "root" pointer for the given allocation: the one that is used for direct
|
||||
/// accesses to this static/const/fn allocation, or the one returned from the heap allocator.
|
||||
///
|
||||
/// Not called on `extern` or thread-local statics (those use the methods above).
|
||||
///
|
||||
/// `kind` is the kind of the allocation the pointer points to; it can be `None` when
|
||||
/// it's a global and `GLOBAL_KIND` is `None`.
|
||||
fn adjust_alloc_root_pointer(
|
||||
ecx: &InterpCx<'mir, 'tcx, Self>,
|
||||
ptr: Pointer,
|
||||
kind: Option<MemoryKind<Self::MemoryKind>>,
|
||||
) -> InterpResult<'tcx, Pointer<Self::Provenance>>;
|
||||
|
||||
/// Evaluate the inline assembly.
|
||||
///
|
||||
/// This should take care of jumping to the next block (one of `targets`) when asm goto
|
||||
|
@ -592,7 +598,7 @@ pub macro compile_time_machine(<$mir: lifetime, $tcx: lifetime>) {
|
|||
Ok(alloc)
|
||||
}
|
||||
|
||||
fn extern_static_base_pointer(
|
||||
fn extern_static_pointer(
|
||||
ecx: &InterpCx<$mir, $tcx, Self>,
|
||||
def_id: DefId,
|
||||
) -> InterpResult<$tcx, Pointer> {
|
||||
|
@ -601,9 +607,10 @@ pub macro compile_time_machine(<$mir: lifetime, $tcx: lifetime>) {
|
|||
}
|
||||
|
||||
#[inline(always)]
|
||||
fn adjust_alloc_base_pointer(
|
||||
fn adjust_alloc_root_pointer(
|
||||
_ecx: &InterpCx<$mir, $tcx, Self>,
|
||||
ptr: Pointer<CtfeProvenance>,
|
||||
_kind: Option<MemoryKind<Self::MemoryKind>>,
|
||||
) -> InterpResult<$tcx, Pointer<CtfeProvenance>> {
|
||||
Ok(ptr)
|
||||
}
|
||||
|
|
|
@ -165,7 +165,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
|
|||
///
|
||||
/// This function can fail only if `ptr` points to an `extern static`.
|
||||
#[inline]
|
||||
pub fn global_base_pointer(
|
||||
pub fn global_root_pointer(
|
||||
&self,
|
||||
ptr: Pointer<CtfeProvenance>,
|
||||
) -> InterpResult<'tcx, Pointer<M::Provenance>> {
|
||||
|
@ -178,12 +178,18 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
|
|||
bug!("global memory cannot point to thread-local static")
|
||||
}
|
||||
Some(GlobalAlloc::Static(def_id)) if self.tcx.is_foreign_item(def_id) => {
|
||||
return M::extern_static_base_pointer(self, def_id);
|
||||
return M::extern_static_pointer(self, def_id);
|
||||
}
|
||||
None => {
|
||||
assert!(
|
||||
self.memory.extra_fn_ptr_map.contains_key(&alloc_id),
|
||||
"{alloc_id:?} is neither global nor a function pointer"
|
||||
);
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
// And we need to get the provenance.
|
||||
M::adjust_alloc_base_pointer(self, ptr)
|
||||
M::adjust_alloc_root_pointer(self, ptr, M::GLOBAL_KIND.map(MemoryKind::Machine))
|
||||
}
|
||||
|
||||
pub fn fn_ptr(&mut self, fn_val: FnVal<'tcx, M::ExtraFnVal>) -> Pointer<M::Provenance> {
|
||||
|
@ -197,9 +203,9 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
|
|||
id
|
||||
}
|
||||
};
|
||||
// Functions are global allocations, so make sure we get the right base pointer.
|
||||
// Functions are global allocations, so make sure we get the right root pointer.
|
||||
// We know this is not an `extern static` so this cannot fail.
|
||||
self.global_base_pointer(Pointer::from(id)).unwrap()
|
||||
self.global_root_pointer(Pointer::from(id)).unwrap()
|
||||
}
|
||||
|
||||
pub fn allocate_ptr(
|
||||
|
@ -240,7 +246,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
|
|||
);
|
||||
let alloc = M::adjust_allocation(self, id, Cow::Owned(alloc), Some(kind))?;
|
||||
self.memory.alloc_map.insert(id, (kind, alloc.into_owned()));
|
||||
M::adjust_alloc_base_pointer(self, Pointer::from(id))
|
||||
M::adjust_alloc_root_pointer(self, Pointer::from(id), Some(kind))
|
||||
}
|
||||
|
||||
pub fn reallocate_ptr(
|
||||
|
|
|
@ -764,7 +764,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
|
|||
// Other cases need layout.
|
||||
let adjust_scalar = |scalar| -> InterpResult<'tcx, _> {
|
||||
Ok(match scalar {
|
||||
Scalar::Ptr(ptr, size) => Scalar::Ptr(self.global_base_pointer(ptr)?, size),
|
||||
Scalar::Ptr(ptr, size) => Scalar::Ptr(self.global_root_pointer(ptr)?, size),
|
||||
Scalar::Int(int) => Scalar::Int(int),
|
||||
})
|
||||
};
|
||||
|
@ -772,7 +772,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
|
|||
let imm = match val_val {
|
||||
mir::ConstValue::Indirect { alloc_id, offset } => {
|
||||
// This is const data, no mutation allowed.
|
||||
let ptr = self.global_base_pointer(Pointer::new(
|
||||
let ptr = self.global_root_pointer(Pointer::new(
|
||||
CtfeProvenance::from(alloc_id).as_immutable(),
|
||||
offset,
|
||||
))?;
|
||||
|
@ -784,7 +784,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
|
|||
// This is const data, no mutation allowed.
|
||||
let alloc_id = self.tcx.reserve_and_set_memory_alloc(data);
|
||||
let ptr = Pointer::new(CtfeProvenance::from(alloc_id).as_immutable(), Size::ZERO);
|
||||
Immediate::new_slice(self.global_base_pointer(ptr)?.into(), meta, self)
|
||||
Immediate::new_slice(self.global_root_pointer(ptr)?.into(), meta, self)
|
||||
}
|
||||
};
|
||||
Ok(OpTy { op: Operand::Immediate(imm), layout })
|
||||
|
|
|
@ -1010,7 +1010,7 @@ where
|
|||
) -> InterpResult<'tcx, MPlaceTy<'tcx, M::Provenance>> {
|
||||
// This must be an allocation in `tcx`
|
||||
let _ = self.tcx.global_alloc(raw.alloc_id);
|
||||
let ptr = self.global_base_pointer(Pointer::from(raw.alloc_id))?;
|
||||
let ptr = self.global_root_pointer(Pointer::from(raw.alloc_id))?;
|
||||
let layout = self.layout_of(raw.ty)?;
|
||||
Ok(self.ptr_to_mplace(ptr.into(), layout))
|
||||
}
|
||||
|
|
|
@ -144,7 +144,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
|
|||
use rustc_middle::mir::Rvalue::*;
|
||||
match *rvalue {
|
||||
ThreadLocalRef(did) => {
|
||||
let ptr = M::thread_local_static_base_pointer(self, did)?;
|
||||
let ptr = M::thread_local_static_pointer(self, did)?;
|
||||
self.write_pointer(ptr, &dest)?;
|
||||
}
|
||||
|
||||
|
|
|
@ -28,7 +28,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
|
|||
ensure_monomorphic_enough(*self.tcx, poly_trait_ref)?;
|
||||
|
||||
let vtable_symbolic_allocation = self.tcx.reserve_and_set_vtable_alloc(ty, poly_trait_ref);
|
||||
let vtable_ptr = self.global_base_pointer(Pointer::from(vtable_symbolic_allocation))?;
|
||||
let vtable_ptr = self.global_root_pointer(Pointer::from(vtable_symbolic_allocation))?;
|
||||
Ok(vtable_ptr.into())
|
||||
}
|
||||
|
||||
|
|
|
@ -2011,12 +2011,16 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||
for (span, code) in errors_causecode {
|
||||
self.dcx().try_steal_modify_and_emit_err(span, StashKey::MaybeForgetReturn, |err| {
|
||||
if let Some(fn_sig) = self.body_fn_sig()
|
||||
&& let ExprBindingObligation(_, _, hir_id, ..) = code
|
||||
&& let ExprBindingObligation(_, _, binding_hir_id, ..) = code
|
||||
&& !fn_sig.output().is_unit()
|
||||
{
|
||||
let mut block_num = 0;
|
||||
let mut found_semi = false;
|
||||
for (_, node) in self.tcx.hir().parent_iter(hir_id) {
|
||||
for (hir_id, node) in self.tcx.hir().parent_iter(binding_hir_id) {
|
||||
// Don't proceed into parent bodies
|
||||
if hir_id.owner != binding_hir_id.owner {
|
||||
break;
|
||||
}
|
||||
match node {
|
||||
hir::Node::Stmt(stmt) => {
|
||||
if let hir::StmtKind::Semi(expr) = stmt.kind {
|
||||
|
|
|
@ -952,7 +952,7 @@ impl<'tcx> InferCtxt<'tcx> {
|
|||
// a test for it.
|
||||
(_, ty::Infer(ty::TyVar(_))) => {}
|
||||
(ty::Infer(ty::TyVar(_)), _) => {}
|
||||
_ if (r_a, r_b).has_opaque_types() => {
|
||||
_ if r_a != r_b && (r_a, r_b).has_opaque_types() => {
|
||||
span_bug!(
|
||||
cause.span(),
|
||||
"opaque types got hidden types registered from within subtype predicate: {r_a:?} vs {r_b:?}"
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue