Skip to content

Commit c45dee5

Browse files
committed
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
2 parents 00ed4ed + abbe0d0 commit c45dee5

File tree

48 files changed

+402
-162
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

48 files changed

+402
-162
lines changed

compiler/rustc_codegen_ssa/src/back/archive.rs

+19-8
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ use object::read::macho::FatArch;
1313
use tempfile::Builder as TempFileBuilder;
1414

1515
use std::error::Error;
16-
use std::fs::File;
16+
use std::fs::{self, File};
1717
use std::io::{self, Write};
1818
use std::path::{Path, PathBuf};
1919

@@ -280,22 +280,33 @@ impl<'a> ArArchiveBuilder<'a> {
280280
// This prevents programs (including rustc) from attempting to read a partial archive.
281281
// It also enables writing an archive with the same filename as a dependency on Windows as
282282
// required by a test.
283-
let mut archive_tmpfile = TempFileBuilder::new()
283+
// The tempfile crate currently uses 0o600 as mode for the temporary files and directories
284+
// it creates. We need it to be the default mode for back compat reasons however. (See
285+
// #107495) To handle this we are telling tempfile to create a temporary directory instead
286+
// and then inside this directory create a file using File::create.
287+
let archive_tmpdir = TempFileBuilder::new()
284288
.suffix(".temp-archive")
285-
.tempfile_in(output.parent().unwrap_or_else(|| Path::new("")))
286-
.map_err(|err| io_error_context("couldn't create a temp file", err))?;
289+
.tempdir_in(output.parent().unwrap_or_else(|| Path::new("")))
290+
.map_err(|err| {
291+
io_error_context("couldn't create a directory for the temp file", err)
292+
})?;
293+
let archive_tmpfile_path = archive_tmpdir.path().join("tmp.a");
294+
let mut archive_tmpfile = File::create_new(&archive_tmpfile_path)
295+
.map_err(|err| io_error_context("couldn't create the temp file", err))?;
287296

288-
write_archive_to_stream(archive_tmpfile.as_file_mut(), &entries, archive_kind, false)?;
297+
write_archive_to_stream(&mut archive_tmpfile, &entries, archive_kind, false)?;
289298

290299
let any_entries = !entries.is_empty();
291300
drop(entries);
292301
// Drop src_archives to unmap all input archives, which is necessary if we want to write the
293302
// output archive to the same location as an input archive on Windows.
294303
drop(self.src_archives);
295304

296-
archive_tmpfile
297-
.persist(output)
298-
.map_err(|err| io_error_context("failed to rename archive file", err.error))?;
305+
fs::rename(archive_tmpfile_path, output)
306+
.map_err(|err| io_error_context("failed to rename archive file", err))?;
307+
archive_tmpdir
308+
.close()
309+
.map_err(|err| io_error_context("failed to remove temporary directory", err))?;
299310

300311
Ok(any_entries)
301312
}

compiler/rustc_const_eval/src/interpret/machine.rs

+21-14
Original file line numberDiff line numberDiff line change
@@ -288,28 +288,19 @@ pub trait Machine<'mir, 'tcx: 'mir>: Sized {
288288
}
289289

290290
/// Return the `AllocId` for the given thread-local static in the current thread.
291-
fn thread_local_static_base_pointer(
291+
fn thread_local_static_pointer(
292292
_ecx: &mut InterpCx<'mir, 'tcx, Self>,
293293
def_id: DefId,
294294
) -> InterpResult<'tcx, Pointer<Self::Provenance>> {
295295
throw_unsup!(ThreadLocalStatic(def_id))
296296
}
297297

298-
/// Return the root pointer for the given `extern static`.
299-
fn extern_static_base_pointer(
298+
/// Return the `AllocId` for the given `extern static`.
299+
fn extern_static_pointer(
300300
ecx: &InterpCx<'mir, 'tcx, Self>,
301301
def_id: DefId,
302302
) -> InterpResult<'tcx, Pointer<Self::Provenance>>;
303303

304-
/// Return a "base" pointer for the given allocation: the one that is used for direct
305-
/// accesses to this static/const/fn allocation, or the one returned from the heap allocator.
306-
///
307-
/// Not called on `extern` or thread-local statics (those use the methods above).
308-
fn adjust_alloc_base_pointer(
309-
ecx: &InterpCx<'mir, 'tcx, Self>,
310-
ptr: Pointer,
311-
) -> InterpResult<'tcx, Pointer<Self::Provenance>>;
312-
313304
/// "Int-to-pointer cast"
314305
fn ptr_from_addr_cast(
315306
ecx: &InterpCx<'mir, 'tcx, Self>,
@@ -336,6 +327,8 @@ pub trait Machine<'mir, 'tcx: 'mir>: Sized {
336327

337328
/// Called to adjust allocations to the Provenance and AllocExtra of this machine.
338329
///
330+
/// If `alloc` contains pointers, then they are all pointing to globals.
331+
///
339332
/// The way we construct allocations is to always first construct it without extra and then add
340333
/// the extra. This keeps uniform code paths for handling both allocations created by CTFE for
341334
/// globals, and allocations created by Miri during evaluation.
@@ -354,6 +347,19 @@ pub trait Machine<'mir, 'tcx: 'mir>: Sized {
354347
kind: Option<MemoryKind<Self::MemoryKind>>,
355348
) -> InterpResult<'tcx, Cow<'b, Allocation<Self::Provenance, Self::AllocExtra, Self::Bytes>>>;
356349

350+
/// Return a "root" pointer for the given allocation: the one that is used for direct
351+
/// accesses to this static/const/fn allocation, or the one returned from the heap allocator.
352+
///
353+
/// Not called on `extern` or thread-local statics (those use the methods above).
354+
///
355+
/// `kind` is the kind of the allocation the pointer points to; it can be `None` when
356+
/// it's a global and `GLOBAL_KIND` is `None`.
357+
fn adjust_alloc_root_pointer(
358+
ecx: &InterpCx<'mir, 'tcx, Self>,
359+
ptr: Pointer,
360+
kind: Option<MemoryKind<Self::MemoryKind>>,
361+
) -> InterpResult<'tcx, Pointer<Self::Provenance>>;
362+
357363
/// Evaluate the inline assembly.
358364
///
359365
/// 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>) {
592598
Ok(alloc)
593599
}
594600

595-
fn extern_static_base_pointer(
601+
fn extern_static_pointer(
596602
ecx: &InterpCx<$mir, $tcx, Self>,
597603
def_id: DefId,
598604
) -> InterpResult<$tcx, Pointer> {
@@ -601,9 +607,10 @@ pub macro compile_time_machine(<$mir: lifetime, $tcx: lifetime>) {
601607
}
602608

603609
#[inline(always)]
604-
fn adjust_alloc_base_pointer(
610+
fn adjust_alloc_root_pointer(
605611
_ecx: &InterpCx<$mir, $tcx, Self>,
606612
ptr: Pointer<CtfeProvenance>,
613+
_kind: Option<MemoryKind<Self::MemoryKind>>,
607614
) -> InterpResult<$tcx, Pointer<CtfeProvenance>> {
608615
Ok(ptr)
609616
}

compiler/rustc_const_eval/src/interpret/memory.rs

+12-6
Original file line numberDiff line numberDiff line change
@@ -165,7 +165,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
165165
///
166166
/// This function can fail only if `ptr` points to an `extern static`.
167167
#[inline]
168-
pub fn global_base_pointer(
168+
pub fn global_root_pointer(
169169
&self,
170170
ptr: Pointer<CtfeProvenance>,
171171
) -> InterpResult<'tcx, Pointer<M::Provenance>> {
@@ -178,12 +178,18 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
178178
bug!("global memory cannot point to thread-local static")
179179
}
180180
Some(GlobalAlloc::Static(def_id)) if self.tcx.is_foreign_item(def_id) => {
181-
return M::extern_static_base_pointer(self, def_id);
181+
return M::extern_static_pointer(self, def_id);
182+
}
183+
None => {
184+
assert!(
185+
self.memory.extra_fn_ptr_map.contains_key(&alloc_id),
186+
"{alloc_id:?} is neither global nor a function pointer"
187+
);
182188
}
183189
_ => {}
184190
}
185191
// And we need to get the provenance.
186-
M::adjust_alloc_base_pointer(self, ptr)
192+
M::adjust_alloc_root_pointer(self, ptr, M::GLOBAL_KIND.map(MemoryKind::Machine))
187193
}
188194

189195
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> {
197203
id
198204
}
199205
};
200-
// Functions are global allocations, so make sure we get the right base pointer.
206+
// Functions are global allocations, so make sure we get the right root pointer.
201207
// We know this is not an `extern static` so this cannot fail.
202-
self.global_base_pointer(Pointer::from(id)).unwrap()
208+
self.global_root_pointer(Pointer::from(id)).unwrap()
203209
}
204210

205211
pub fn allocate_ptr(
@@ -240,7 +246,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
240246
);
241247
let alloc = M::adjust_allocation(self, id, Cow::Owned(alloc), Some(kind))?;
242248
self.memory.alloc_map.insert(id, (kind, alloc.into_owned()));
243-
M::adjust_alloc_base_pointer(self, Pointer::from(id))
249+
M::adjust_alloc_root_pointer(self, Pointer::from(id), Some(kind))
244250
}
245251

246252
pub fn reallocate_ptr(

compiler/rustc_const_eval/src/interpret/operand.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -764,15 +764,15 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
764764
// Other cases need layout.
765765
let adjust_scalar = |scalar| -> InterpResult<'tcx, _> {
766766
Ok(match scalar {
767-
Scalar::Ptr(ptr, size) => Scalar::Ptr(self.global_base_pointer(ptr)?, size),
767+
Scalar::Ptr(ptr, size) => Scalar::Ptr(self.global_root_pointer(ptr)?, size),
768768
Scalar::Int(int) => Scalar::Int(int),
769769
})
770770
};
771771
let layout = from_known_layout(self.tcx, self.param_env, layout, || self.layout_of(ty))?;
772772
let imm = match val_val {
773773
mir::ConstValue::Indirect { alloc_id, offset } => {
774774
// This is const data, no mutation allowed.
775-
let ptr = self.global_base_pointer(Pointer::new(
775+
let ptr = self.global_root_pointer(Pointer::new(
776776
CtfeProvenance::from(alloc_id).as_immutable(),
777777
offset,
778778
))?;
@@ -784,7 +784,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
784784
// This is const data, no mutation allowed.
785785
let alloc_id = self.tcx.reserve_and_set_memory_alloc(data);
786786
let ptr = Pointer::new(CtfeProvenance::from(alloc_id).as_immutable(), Size::ZERO);
787-
Immediate::new_slice(self.global_base_pointer(ptr)?.into(), meta, self)
787+
Immediate::new_slice(self.global_root_pointer(ptr)?.into(), meta, self)
788788
}
789789
};
790790
Ok(OpTy { op: Operand::Immediate(imm), layout })

compiler/rustc_const_eval/src/interpret/place.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1010,7 +1010,7 @@ where
10101010
) -> InterpResult<'tcx, MPlaceTy<'tcx, M::Provenance>> {
10111011
// This must be an allocation in `tcx`
10121012
let _ = self.tcx.global_alloc(raw.alloc_id);
1013-
let ptr = self.global_base_pointer(Pointer::from(raw.alloc_id))?;
1013+
let ptr = self.global_root_pointer(Pointer::from(raw.alloc_id))?;
10141014
let layout = self.layout_of(raw.ty)?;
10151015
Ok(self.ptr_to_mplace(ptr.into(), layout))
10161016
}

compiler/rustc_const_eval/src/interpret/step.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -144,7 +144,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
144144
use rustc_middle::mir::Rvalue::*;
145145
match *rvalue {
146146
ThreadLocalRef(did) => {
147-
let ptr = M::thread_local_static_base_pointer(self, did)?;
147+
let ptr = M::thread_local_static_pointer(self, did)?;
148148
self.write_pointer(ptr, &dest)?;
149149
}
150150

compiler/rustc_const_eval/src/interpret/traits.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
2828
ensure_monomorphic_enough(*self.tcx, poly_trait_ref)?;
2929

3030
let vtable_symbolic_allocation = self.tcx.reserve_and_set_vtable_alloc(ty, poly_trait_ref);
31-
let vtable_ptr = self.global_base_pointer(Pointer::from(vtable_symbolic_allocation))?;
31+
let vtable_ptr = self.global_root_pointer(Pointer::from(vtable_symbolic_allocation))?;
3232
Ok(vtable_ptr.into())
3333
}
3434

compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs

+6-2
Original file line numberDiff line numberDiff line change
@@ -2011,12 +2011,16 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
20112011
for (span, code) in errors_causecode {
20122012
self.dcx().try_steal_modify_and_emit_err(span, StashKey::MaybeForgetReturn, |err| {
20132013
if let Some(fn_sig) = self.body_fn_sig()
2014-
&& let ExprBindingObligation(_, _, hir_id, ..) = code
2014+
&& let ExprBindingObligation(_, _, binding_hir_id, ..) = code
20152015
&& !fn_sig.output().is_unit()
20162016
{
20172017
let mut block_num = 0;
20182018
let mut found_semi = false;
2019-
for (_, node) in self.tcx.hir().parent_iter(hir_id) {
2019+
for (hir_id, node) in self.tcx.hir().parent_iter(binding_hir_id) {
2020+
// Don't proceed into parent bodies
2021+
if hir_id.owner != binding_hir_id.owner {
2022+
break;
2023+
}
20202024
match node {
20212025
hir::Node::Stmt(stmt) => {
20222026
if let hir::StmtKind::Semi(expr) = stmt.kind {

compiler/rustc_infer/src/infer/mod.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -952,7 +952,7 @@ impl<'tcx> InferCtxt<'tcx> {
952952
// a test for it.
953953
(_, ty::Infer(ty::TyVar(_))) => {}
954954
(ty::Infer(ty::TyVar(_)), _) => {}
955-
_ if (r_a, r_b).has_opaque_types() => {
955+
_ if r_a != r_b && (r_a, r_b).has_opaque_types() => {
956956
span_bug!(
957957
cause.span(),
958958
"opaque types got hidden types registered from within subtype predicate: {r_a:?} vs {r_b:?}"

library/alloc/src/boxed.rs

+22-4
Original file line numberDiff line numberDiff line change
@@ -2088,11 +2088,29 @@ impl<T: Clone, A: Allocator + Clone> Clone for Box<[T], A> {
20882088
self.to_vec_in(alloc).into_boxed_slice()
20892089
}
20902090

2091-
fn clone_from(&mut self, other: &Self) {
2092-
if self.len() == other.len() {
2093-
self.clone_from_slice(&other);
2091+
/// Copies `source`'s contents into `self` without creating a new allocation,
2092+
/// so long as the two are of the same length.
2093+
///
2094+
/// # Examples
2095+
///
2096+
/// ```
2097+
/// let x = Box::new([5, 6, 7]);
2098+
/// let mut y = Box::new([8, 9, 10]);
2099+
/// let yp: *const [i32] = &*y;
2100+
///
2101+
/// y.clone_from(&x);
2102+
///
2103+
/// // The value is the same
2104+
/// assert_eq!(x, y);
2105+
///
2106+
/// // And no allocation occurred
2107+
/// assert_eq!(yp, &*y);
2108+
/// ```
2109+
fn clone_from(&mut self, source: &Self) {
2110+
if self.len() == source.len() {
2111+
self.clone_from_slice(&source);
20942112
} else {
2095-
*self = other.clone();
2113+
*self = source.clone();
20962114
}
20972115
}
20982116
}

library/alloc/src/collections/binary_heap/mod.rs

+6
Original file line numberDiff line numberDiff line change
@@ -385,6 +385,12 @@ impl<T: Clone, A: Allocator + Clone> Clone for BinaryHeap<T, A> {
385385
BinaryHeap { data: self.data.clone() }
386386
}
387387

388+
/// Overwrites the contents of `self` with a clone of the contents of `source`.
389+
///
390+
/// This method is preferred over simply assigning `source.clone()` to `self`,
391+
/// as it avoids reallocation if possible.
392+
///
393+
/// See [`Vec::clone_from()`] for more details.
388394
fn clone_from(&mut self, source: &Self) {
389395
self.data.clone_from(&source.data);
390396
}

library/alloc/src/collections/btree/set.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -116,8 +116,8 @@ impl<T: Clone, A: Allocator + Clone> Clone for BTreeSet<T, A> {
116116
BTreeSet { map: self.map.clone() }
117117
}
118118

119-
fn clone_from(&mut self, other: &Self) {
120-
self.map.clone_from(&other.map);
119+
fn clone_from(&mut self, source: &Self) {
120+
self.map.clone_from(&source.map);
121121
}
122122
}
123123

library/alloc/src/collections/linked_list.rs

+14-8
Original file line numberDiff line numberDiff line change
@@ -2126,16 +2126,22 @@ impl<T: Clone, A: Allocator + Clone> Clone for LinkedList<T, A> {
21262126
list
21272127
}
21282128

2129-
fn clone_from(&mut self, other: &Self) {
2130-
let mut iter_other = other.iter();
2131-
if self.len() > other.len() {
2132-
self.split_off(other.len());
2129+
/// Overwrites the contents of `self` with a clone of the contents of `source`.
2130+
///
2131+
/// This method is preferred over simply assigning `source.clone()` to `self`,
2132+
/// as it avoids reallocation of the nodes of the linked list. Additionally,
2133+
/// if the element type `T` overrides `clone_from()`, this will reuse the
2134+
/// resources of `self`'s elements as well.
2135+
fn clone_from(&mut self, source: &Self) {
2136+
let mut source_iter = source.iter();
2137+
if self.len() > source.len() {
2138+
self.split_off(source.len());
21332139
}
2134-
for (elem, elem_other) in self.iter_mut().zip(&mut iter_other) {
2135-
elem.clone_from(elem_other);
2140+
for (elem, source_elem) in self.iter_mut().zip(&mut source_iter) {
2141+
elem.clone_from(source_elem);
21362142
}
2137-
if !iter_other.is_empty() {
2138-
self.extend(iter_other.cloned());
2143+
if !source_iter.is_empty() {
2144+
self.extend(source_iter.cloned());
21392145
}
21402146
}
21412147
}

library/alloc/src/collections/vec_deque/mod.rs

+6-2
Original file line numberDiff line numberDiff line change
@@ -113,9 +113,13 @@ impl<T: Clone, A: Allocator + Clone> Clone for VecDeque<T, A> {
113113
deq
114114
}
115115

116-
fn clone_from(&mut self, other: &Self) {
116+
/// Overwrites the contents of `self` with a clone of the contents of `source`.
117+
///
118+
/// This method is preferred over simply assigning `source.clone()` to `self`,
119+
/// as it avoids reallocation if possible.
120+
fn clone_from(&mut self, source: &Self) {
117121
self.clear();
118-
self.extend(other.iter().cloned());
122+
self.extend(source.iter().cloned());
119123
}
120124
}
121125

library/alloc/src/string.rs

+4
Original file line numberDiff line numberDiff line change
@@ -2097,6 +2097,10 @@ impl Clone for String {
20972097
String { vec: self.vec.clone() }
20982098
}
20992099

2100+
/// Clones the contents of `source` into `self`.
2101+
///
2102+
/// This method is preferred over simply assigning `source.clone()` to `self`,
2103+
/// as it avoids reallocation if possible.
21002104
fn clone_from(&mut self, source: &Self) {
21012105
self.vec.clone_from(&source.vec);
21022106
}

0 commit comments

Comments
 (0)