Closed
Description
Violating code
While this code might look unnecessarily funky, it is so because I stripped it down to the (hopefully) bare minimum for a repro. Here's the code:
use std::{mem::ManuallyDrop, slice};
#[test]
fn extend_fail() {
let data = Data::allocate(b"hello");
assert_eq!(data.read(), b"hello");
let mut buffer = Vec::<u8>::with_capacity(1024);
buffer.extend(data.read());
assert_eq!(buffer.len(), 5);
}
#[test]
fn extend_pass() {
let data = Data::allocate(b"hello");
assert_eq!(data.read(), b"hello");
let mut buffer = Vec::<u8>::with_capacity(1024);
for byte in data.read() {
buffer.push(*byte);
}
assert_eq!(buffer.len(), 5);
}
pub struct Data {
data: DataUnion,
}
impl Data {
pub fn allocate(data: &[u8]) -> Self {
let mut data = ManuallyDrop::new(data.to_owned().into_boxed_slice());
Self {
data: DataUnion {
x: ManuallyDrop::new(FatPointer::new(
data.as_mut_ptr() as usize,
data.len() as u64,
)),
},
}
}
pub fn read(&self) -> &[u8] {
unsafe {
// SAFETY: fine since we r/w it directly!
slice::from_raw_parts(self.data.x.ptr as *mut u8, self.data.x.len as usize)
}
}
}
impl Drop for Data {
fn drop(&mut self) {
unsafe {
Vec::from_raw_parts(
self.data.x.ptr as *mut u8,
self.data.x.len as usize,
self.data.x.len as usize,
);
}
}
}
struct FatPointer {
len: u64,
ptr: usize,
}
impl FatPointer {
fn new(ptr: usize, len: u64) -> Self {
Self { len, ptr }
}
}
union DataUnion {
x: ManuallyDrop<FatPointer>,
}
What seemed interesting to me is that neither stacked borrows nor tree borrows reports an error with the extend_pass
test when run with either of:
MIRIFLAGS="-Zmiri-permissive-provenance -Zmiri-tree-borrows" cargo miri test extend_pass
MIRIFLAGS="-Zmiri-permissive-provenance" cargo miri test extend_pass
But when you try it for extend_fail
with tree-borrows, it fails.
Violation
--> /home/sayan/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/core/src/slice/iter.rs:136:1
|
136 | / iterator! {struct Iter -> *const T, &'a...
137 | | fn is_sorted_by<F>(self, mut compar...
138 | | where
139 | | Self: Sized,
... |
143 | | }
144 | | }}
| |__^ `ptr_offset_from_unsigned` called on pointers into different allocations
Meta
Tried with:
miri 0.1.0 (8bfcae7 2024-07-23)
miri 0.1.0 (7120fda 2024-07-25)
Metadata
Metadata
Assignees
Labels
No labels