Skip to content

Commit 7b6ef64

Browse files
authored
Merge pull request #4487 from rust-lang/rustup-2025-07-22
Automatic Rustup
2 parents 9396463 + 6df0dae commit 7b6ef64

File tree

6 files changed

+59
-39
lines changed

6 files changed

+59
-39
lines changed

rust-version

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
460259d14de0274b97b8801e08cb2fe5f16fdac5
1+
9748d87dc70a9a6725c5dbd76ce29d04752b4f90

src/alloc_addresses/mod.rs

Lines changed: 34 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -116,21 +116,26 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> {
116116
let this = self.eval_context_ref();
117117
let info = this.get_alloc_info(alloc_id);
118118

119-
// Miri's address assignment leaks state across thread boundaries, which is incompatible
120-
// with GenMC execution. So we instead let GenMC assign addresses to allocations.
121-
if let Some(genmc_ctx) = this.machine.data_race.as_genmc_ref() {
122-
let addr = genmc_ctx.handle_alloc(&this.machine, info.size, info.align, memory_kind)?;
123-
return interp_ok(addr);
124-
}
125-
126-
let mut rng = this.machine.rng.borrow_mut();
127119
// This is either called immediately after allocation (and then cached), or when
128120
// adjusting `tcx` pointers (which never get freed). So assert that we are looking
129121
// at a live allocation. This also ensures that we never re-assign an address to an
130122
// allocation that previously had an address, but then was freed and the address
131123
// information was removed.
132124
assert!(!matches!(info.kind, AllocKind::Dead));
133125

126+
// TypeId allocations always have a "base address" of 0 (i.e., the relative offset is the
127+
// hash fragment and therefore equal to the actual integer value).
128+
if matches!(info.kind, AllocKind::TypeId) {
129+
return interp_ok(0);
130+
}
131+
132+
// Miri's address assignment leaks state across thread boundaries, which is incompatible
133+
// with GenMC execution. So we instead let GenMC assign addresses to allocations.
134+
if let Some(genmc_ctx) = this.machine.data_race.as_genmc_ref() {
135+
let addr = genmc_ctx.handle_alloc(&this.machine, info.size, info.align, memory_kind)?;
136+
return interp_ok(addr);
137+
}
138+
134139
// This allocation does not have a base address yet, pick or reuse one.
135140
if !this.machine.native_lib.is_empty() {
136141
// In native lib mode, we use the "real" address of the bytes for this allocation.
@@ -157,7 +162,7 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> {
157162
this.get_alloc_bytes_unchecked_raw(alloc_id)?
158163
}
159164
}
160-
AllocKind::Function | AllocKind::Virtual => {
165+
AllocKind::Function | AllocKind::VTable => {
161166
// Allocate some dummy memory to get a unique address for this function/vtable.
162167
let alloc_bytes = MiriAllocBytes::from_bytes(
163168
&[0u8; 1],
@@ -169,12 +174,13 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> {
169174
std::mem::forget(alloc_bytes);
170175
ptr
171176
}
172-
AllocKind::Dead => unreachable!(),
177+
AllocKind::TypeId | AllocKind::Dead => unreachable!(),
173178
};
174179
// We don't have to expose this pointer yet, we do that in `prepare_for_native_call`.
175180
return interp_ok(base_ptr.addr().to_u64());
176181
}
177182
// We are not in native lib mode, so we control the addresses ourselves.
183+
let mut rng = this.machine.rng.borrow_mut();
178184
if let Some((reuse_addr, clock)) = global_state.reuse.take_addr(
179185
&mut *rng,
180186
info.size,
@@ -295,21 +301,25 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
295301
// Store address in cache.
296302
global_state.base_addr.try_insert(alloc_id, base_addr).unwrap();
297303

298-
// Also maintain the opposite mapping in `int_to_ptr_map`, ensuring we keep it sorted.
299-
// We have a fast-path for the common case that this address is bigger than all previous ones.
300-
let pos = if global_state
301-
.int_to_ptr_map
302-
.last()
303-
.is_some_and(|(last_addr, _)| *last_addr < base_addr)
304-
{
305-
global_state.int_to_ptr_map.len()
306-
} else {
307-
global_state
304+
// Also maintain the opposite mapping in `int_to_ptr_map`, ensuring we keep it
305+
// sorted. We have a fast-path for the common case that this address is bigger than
306+
// all previous ones. We skip this for allocations at address 0; those can't be
307+
// real, they must be TypeId "fake allocations".
308+
if base_addr != 0 {
309+
let pos = if global_state
308310
.int_to_ptr_map
309-
.binary_search_by_key(&base_addr, |(addr, _)| *addr)
310-
.unwrap_err()
311-
};
312-
global_state.int_to_ptr_map.insert(pos, (base_addr, alloc_id));
311+
.last()
312+
.is_some_and(|(last_addr, _)| *last_addr < base_addr)
313+
{
314+
global_state.int_to_ptr_map.len()
315+
} else {
316+
global_state
317+
.int_to_ptr_map
318+
.binary_search_by_key(&base_addr, |(addr, _)| *addr)
319+
.unwrap_err()
320+
};
321+
global_state.int_to_ptr_map.insert(pos, (base_addr, alloc_id));
322+
}
313323

314324
interp_ok(base_addr)
315325
}

src/borrow_tracker/stacked_borrows/mod.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -650,7 +650,7 @@ trait EvalContextPrivExt<'tcx, 'ecx>: crate::MiriInterpCxExt<'tcx> {
650650
dcx.log_protector();
651651
}
652652
},
653-
AllocKind::Function | AllocKind::Virtual | AllocKind::Dead => {
653+
AllocKind::Function | AllocKind::VTable | AllocKind::TypeId | AllocKind::Dead => {
654654
// No stacked borrows on these allocations.
655655
}
656656
}
@@ -1021,7 +1021,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
10211021
trace!("Stacked Borrows tag {tag:?} exposed in {alloc_id:?}");
10221022
alloc_extra.borrow_tracker_sb().borrow_mut().exposed_tags.insert(tag);
10231023
}
1024-
AllocKind::Function | AllocKind::Virtual | AllocKind::Dead => {
1024+
AllocKind::Function | AllocKind::VTable | AllocKind::TypeId | AllocKind::Dead => {
10251025
// No stacked borrows on these allocations.
10261026
}
10271027
}

src/borrow_tracker/tree_borrows/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -673,7 +673,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
673673
trace!("Tree Borrows tag {tag:?} exposed in {alloc_id:?}");
674674
alloc_extra.borrow_tracker_tb().borrow_mut().expose_tag(tag);
675675
}
676-
AllocKind::Function | AllocKind::Virtual | AllocKind::Dead => {
676+
AllocKind::Function | AllocKind::VTable | AllocKind::TypeId | AllocKind::Dead => {
677677
// No tree borrows on these allocations.
678678
}
679679
}

tests/pass/fn_align.rs

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,19 @@
11
//@compile-flags: -Zmin-function-alignment=8
2+
3+
// FIXME(rust-lang/rust#82232, rust-lang/rust#143834): temporarily renamed to mitigate `#[align]`
4+
// nameres ambiguity
5+
#![feature(rustc_attrs)]
26
#![feature(fn_align)]
37

48
// When a function uses `align(N)`, the function address should be a multiple of `N`.
59

6-
#[align(256)]
10+
#[rustc_align(256)]
711
fn foo() {}
812

9-
#[align(16)]
13+
#[rustc_align(16)]
1014
fn bar() {}
1115

12-
#[align(4)]
16+
#[rustc_align(4)]
1317
fn baz() {}
1418

1519
fn main() {

tests/pass/intrinsics/portable-simd.rs

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -349,12 +349,15 @@ fn simd_mask() {
349349
// Non-power-of-2 multi-byte mask.
350350
#[repr(simd, packed)]
351351
#[allow(non_camel_case_types)]
352-
#[derive(Copy, Clone, Debug, PartialEq)]
352+
#[derive(Copy, Clone)]
353353
struct i32x10([i32; 10]);
354354
impl i32x10 {
355355
fn splat(x: i32) -> Self {
356356
Self([x; 10])
357357
}
358+
fn into_array(self) -> [i32; 10] {
359+
unsafe { std::mem::transmute(self) }
360+
}
358361
}
359362
unsafe {
360363
let mask = i32x10([!0, !0, 0, !0, 0, 0, !0, 0, !0, 0]);
@@ -377,19 +380,22 @@ fn simd_mask() {
377380
i32x10::splat(!0), // yes
378381
i32x10::splat(0), // no
379382
);
380-
assert_eq!(selected1, mask);
381-
assert_eq!(selected2, mask);
383+
assert_eq!(selected1.into_array(), mask.into_array());
384+
assert_eq!(selected2.into_array(), mask.into_array());
382385
}
383386

384387
// Test for a mask where the next multiple of 8 is not a power of two.
385388
#[repr(simd, packed)]
386389
#[allow(non_camel_case_types)]
387-
#[derive(Copy, Clone, Debug, PartialEq)]
390+
#[derive(Copy, Clone)]
388391
struct i32x20([i32; 20]);
389392
impl i32x20 {
390393
fn splat(x: i32) -> Self {
391394
Self([x; 20])
392395
}
396+
fn into_array(self) -> [i32; 20] {
397+
unsafe { std::mem::transmute(self) }
398+
}
393399
}
394400
unsafe {
395401
let mask = i32x20([!0, !0, 0, !0, 0, 0, !0, 0, !0, 0, 0, 0, 0, !0, !0, !0, !0, !0, !0, !0]);
@@ -419,8 +425,8 @@ fn simd_mask() {
419425
i32x20::splat(!0), // yes
420426
i32x20::splat(0), // no
421427
);
422-
assert_eq!(selected1, mask);
423-
assert_eq!(selected2, mask);
428+
assert_eq!(selected1.into_array(), mask.into_array());
429+
assert_eq!(selected2.into_array(), mask.into_array());
424430
}
425431
}
426432

@@ -708,12 +714,12 @@ fn simd_ops_non_pow2() {
708714
let x = SimdPacked([1u32; 3]);
709715
let y = SimdPacked([2u32; 3]);
710716
let z = unsafe { intrinsics::simd_add(x, y) };
711-
assert_eq!({ z.0 }, [3u32; 3]);
717+
assert_eq!(unsafe { *(&raw const z).cast::<[u32; 3]>() }, [3u32; 3]);
712718

713719
let x = SimdPadded([1u32; 3]);
714720
let y = SimdPadded([2u32; 3]);
715721
let z = unsafe { intrinsics::simd_add(x, y) };
716-
assert_eq!(z.0, [3u32; 3]);
722+
assert_eq!(unsafe { *(&raw const z).cast::<[u32; 3]>() }, [3u32; 3]);
717723
}
718724

719725
fn main() {

0 commit comments

Comments
 (0)