Reputation: 3017
I have a type that stores a slice, for example:
struct S<'a> {
slice: &'a [u8],
}
I am trying to write code that will merge two of these structs. Now obviously this should only succeed if the two slices are subslices of the original data. I believe this can be checked with pointers: make sure that the ranges "in pointer space" (i.e. [pointer, pointer+length]) of each slices overlap. If this is the case, then both slices are views into the same original memory location.
After having done this check, I use let new_slice = unsafe { core::slice::from_raw_parts(lower_ptr, new_length_elements) };
to reconstruct the slice. This sounds fine, including the unit tests making sure this works as expected, but Miri complains:
error: Undefined Behavior: trying to retag from <718383> for SharedReadOnly permission at alloc
486[0x14], but that tag does not exist in the borrow stack for this location
--> ~/.rustup/toolchains/nightly-aarch64-apple-darwin/lib/rustlib/src/rust/library/core/src/slice/raw.rs:138:9 |
138 | &*ptr::slice_from_raw_parts(data, len)
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
| |
| trying to retag from <718383> for SharedReadOnly permission at alloc486[0x14], but that tag does not exist in the borrow stack for this location
| this error occurs as part of retag at alloc486[0x8..0x18]
|
= help: this indicates a potential bug in the program: it performed an invalid operation, but the Stacked Borrows rules it violated are still experimental
= help: see https://github.com/rust-lang/unsafe-code-guidelines/blob/master/wip/stacked-borrows.md for further information
help: <718383> was created by a SharedReadOnly retag at offsets [0x8..0x14]
--> example/src/lib.rs:229:24
|
229 | let lower_ptr = self.slice.as_ptr();
| ^^^^^^^^^^^^^^^^^^^
= note: BACKTRACE (of the first span) on thread `tests::merge`:
= note: inside `std::slice::from_raw_parts::<'_, u32>` at ~/.rustup/toolchains/nightly-aarch64-apple-darwin/lib/rustlib/src/rust/library/core/src/slice/raw.rs:138:9: 138:47
I'm not sure I fully understand the error.
Should it be possible to rebuild a slice from two subslices that we taken from a single memory location? How should it be done so that Miri doesn't complain?
Upvotes: 0
Views: 40