Skip to content

Commit

Permalink
Auto merge of rust-lang#128742 - RalfJung:miri-vtable-uniqueness, r=s…
Browse files Browse the repository at this point in the history
…aethlin

miri: make vtable addresses not globally unique

Miri currently gives vtables a unique global address. That's not actually matching reality though. So this PR enables Miri to generate different addresses for the same type-trait pair.

To avoid generating an unbounded number of `AllocId` (and consuming unbounded amounts of memory), we use the "salt" technique that we also already use for giving constants non-unique addresses: the cache is keyed on a "salt" value n top of the actually relevant key, and Miri picks a random salt (currently in the range `0..16`) each time it needs to choose an `AllocId` for one of these globals -- that means we'll get up to 16 different addresses for each vtable. The salt scheme is integrated into the global allocation deduplication logic in `tcx`, and also used for functions and string literals. (So this also fixes the problem that casting the same function to a fn ptr over and over will consume unbounded memory.)

r? `@saethlin`
Fixes rust-lang/miri#3737
  • Loading branch information
bors committed Aug 13, 2024
2 parents e3da824 + 048efd0 commit c5e8189
Show file tree
Hide file tree
Showing 2 changed files with 8 additions and 5 deletions.
4 changes: 2 additions & 2 deletions alloc/tests/task.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ use alloc::task::{LocalWake, Wake};
use core::task::{LocalWaker, Waker};

#[test]
#[cfg_attr(miri, should_panic)] // `will_wake` doesn't guarantee that this test will work, and indeed on Miri it fails
#[cfg_attr(miri, ignore)] // `will_wake` doesn't guarantee that this test will work, and indeed on Miri it can fail
fn test_waker_will_wake_clone() {
struct NoopWaker;

Expand All @@ -20,7 +20,7 @@ fn test_waker_will_wake_clone() {
}

#[test]
#[cfg_attr(miri, should_panic)] // `will_wake` doesn't guarantee that this test will work, and indeed on Miri it fails
#[cfg_attr(miri, ignore)] // `will_wake` doesn't guarantee that this test will work, and indeed on Miri it can fail
fn test_local_waker_will_wake_clone() {
struct NoopWaker;

Expand Down
9 changes: 6 additions & 3 deletions core/tests/ptr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -810,9 +810,12 @@ fn ptr_metadata() {
assert_ne!(address_1, address_2);
// Different erased type => different vtable pointer
assert_ne!(address_2, address_3);
// Same erased type and same trait => same vtable pointer
assert_eq!(address_3, address_4);
assert_eq!(address_3, address_5);
// Same erased type and same trait => same vtable pointer.
// This is *not guaranteed*, so we skip it in Miri.
if !cfg!(miri) {
assert_eq!(address_3, address_4);
assert_eq!(address_3, address_5);
}
}
}

Expand Down

0 comments on commit c5e8189

Please sign in to comment.