Description
i have a self referential Builder
.
something like this:
struct Builder {
data: Vec<u8>,
// points into `data`, only used internally.
some_slice: &'static [u8],
}
impl Builder {
fn new(data: &[u8]) -> Builder {
let data = Vec::from(data);
let some_slice = unsafe {
let the_slice = &data[0..4];
core::mem::transmute::<&[u8], &[u8]>(the_slice)
};
return Builder { data, some_slice };
}
fn build(self) {
drop(self.data);
}
}
fn main() {
Builder::new(b"1234hello").build();
}
(the real thing uses a bump allocator and some_slice
is a "leaked" allocation in that allocator)
the problem is, dropping self.data
in build
triggers undefined behavior:
error: Undefined Behavior: not granting access to tag <3378> because that would remove [SharedRead
Only for <3599>] which is strongly protected because it is an argument of call 865
--> /Users/leddoo/.rustup/toolchains/nightly-aarch64-apple-darwin/lib/rustlib/src/rust/library/
core/src/ptr/mod.rs:514:1
|
514 | pub unsafe fn drop_in_place<T: ?Sized>(to_drop: *mut T) {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not granting access to tag <3378> be
cause that would remove [SharedReadOnly for <3599>] which is strongly protected because it is an a
rgument of call 865
|
help: <3378> was created here, as the base tag for alloc1476
--> src/main.rs:9:20
|
9 | let data = Vec::from(data);
| ^^^^^^^^^^^^^^^
help: <3599> is this argument
--> src/main.rs:20:14
|
20 | fn build(this: Self) {
(in the real code, build returns a Result
, and on error, the bump allocator is dropped, while "some_slice
" protects the bump allocator's memory)
i've read stacked borrows section 4.1, so i know what's going on.
best thing i've come up with so far would be an UnprotectedRefs
wrapper type, that just tells miri to not create stack protectors for references contained in that wrapper (and tells the compiler to not rely on those references being valid for the duration of the call).
right now, the only workaround i've found is boxing that slice, which isn't ideal.
is there anything like UnprotectedRefs
or a different workaround on stable right now?