-
Notifications
You must be signed in to change notification settings - Fork 349
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Tree-borrows false positive with iter::Extend
?
#3764
Comments
Update Looks like the 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 {
len: usize,
ptr: usize,
}
impl Data {
pub fn allocate(data: &[u8]) -> Self {
let mut data = ManuallyDrop::new(data.to_owned().into_boxed_slice());
Self {
len: data.len(),
ptr: data.as_mut_ptr() as usize,
}
}
pub fn read(&self) -> &[u8] {
unsafe {
// SAFETY: fine since we r/w it directly!
slice::from_raw_parts(self.ptr as *mut u8, self.len)
}
}
}
impl Drop for Data {
fn drop(&mut self) {
unsafe {
Vec::from_raw_parts(self.ptr as *mut u8, self.len, self.len);
}
}
} Edit; Further simplified |
The error seems to originate from this: https://github.com/rust-lang/rust/blob/72d73cec61aa8f85901358cd5d386d5dd066fe52/library/core/src/slice/iter.rs#L136 Also, maybe it's got to do with this: https://github.com/rust-lang/rust/blob/72d73cec61aa8f85901358cd5d386d5dd066fe52/library/core/src/slice/iter/macros.rs#L49? That's the only place where |
iter::Extend
?
Can you please show the error you are getting? And what makes you think it is a false positive? |
Running this in Miri, I see |
better diagnostics for Tree Borrows + int2ptr casts - Entirely reject `-Zmiri-permissive-provenance -Zmiri-tree-borrows` since that combination just doesn't work - In the int2ptr cast warning, when Tree Borrows is enabled, do not recommend `-Zmiri-permissive-provenance`, instead note that Tree Borrows does not support int2ptr casts Fixes #3764
FWIW if you remove the int2ptr casts and just preserve the pointer, it works in Tree Borrows just fine: use std::{mem::ManuallyDrop, slice};
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);
}
fn main() {
extend_fail();
}
pub struct Data {
len: usize,
ptr: *mut u8,
}
impl Data {
pub fn allocate(data: &[u8]) -> Self {
let mut data = ManuallyDrop::new(data.to_owned().into_boxed_slice());
Self {
len: data.len(),
ptr: data.as_mut_ptr(),
}
}
pub fn read(&self) -> &[u8] {
unsafe {
// SAFETY: fine since we r/w it directly!
slice::from_raw_parts(self.ptr, self.len)
}
}
}
impl Drop for Data {
fn drop(&mut self) {
unsafe {
Vec::from_raw_parts(self.ptr, self.len, self.len);
}
}
} That said, the error you are getting is quite strange. |
better diagnostics for Tree Borrows + int2ptr casts - Entirely reject `-Zmiri-permissive-provenance -Zmiri-tree-borrows` since that combination just doesn't work - In the int2ptr cast warning, when Tree Borrows is enabled, do not recommend `-Zmiri-permissive-provenance`, instead note that Tree Borrows does not support int2ptr casts Fixes rust-lang/miri#3764
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:
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:But when you try it for
extend_fail
with tree-borrows, it fails.Violation
Meta
Tried with:
miri 0.1.0 (8bfcae7 2024-07-23)
miri 0.1.0 (7120fda 2024-07-25)
The text was updated successfully, but these errors were encountered: