-
Notifications
You must be signed in to change notification settings - Fork 13.6k
Description
Location
String::from_raw_parts example
Summary
The example is technically correct, however adding s.reserve(1)
makes Miri complain about an invalid deallocation. From the documentation there is no obvious reason why that is.
problematic code
use std::mem;
unsafe {
let mut s = String::from("hello");
s.reserve(1); // <= not in std example
// Prevent automatically dropping the String's data
let mut s = mem::ManuallyDrop::new(s);
let ptr = s.as_mut_ptr();
let len = s.len();
let capacity = s.capacity();
let s = String::from_raw_parts(ptr, len, capacity);
assert_eq!(String::from("hello"), s);
}
I opened an issue on rust-lang/miri#2751, where @bjorn3 clarified that there is indeed an issue:
This seems to be an issue in the documentation, albeit a tricky one. The
as_mut_ptr
method comes fromstr
, notString
. The deref fromString
tostr
shrinks the region to which thestr
and thusas_mut_ptr
result is valid for to fit exactly the size and not the capacity of the string. I think the only way to do this currently ares.into_bytes().as_mut_ptr()
(which usesVec::as_mut_ptr
, which does cover the whole capacity) ors.into_raw_parts()
, which is unstable.
They also added:
One way to fix this would be to add an as_mut_ptr method directly to String.
I tagged this A-docs but the solution may be to actually create a String::as_mut_ptr
and not update the documentation. An other solution is to describe the issue I experienced and change the ManuallyDrop
line to be
let mut s = mem::ManuallyDrop::new(s.into_bytes());
Activity
saethlin commentedon Jan 8, 2023
I think you are asking for #97483
trinity-1686a commentedon Jan 8, 2023
I'm not sure exactly what I'm asking for, 97483 is indeed one of the possibilities
RalfJung commentedon Apr 26, 2023
FWIW with Tree Borrows, this code will be accepted by Miri.
as_ptr
andas_mut_ptr
inherent method toString
#97483