Open Manishearth opened 1 year ago
An interesting one is the first one (and you see this failure in a bunch of places)
The problem is, here, we are trying to construct a pointer-to-DST (&FlexZeroSlice
) from an &[u8]
slice. The FlexZeroSlice
pointer has a metadata value of one less than the slice it is constructed from (since it starts with a u8
header field). The only stable way we have to construct such a slice is to cast the pointer: on nightly we can use std::ptr::from_raw_parts()
. However, to do so we end up going through an intermediary of an &[u8]
type with the correct pointer but one less length, which for empty FZSes will be an empty slice. Apparently Stacked Borrows doesn't allow retagging empty slices that way.
I'm going to stash my progress in https://github.com/unicode-org/icu4x/pull/3513
With https://github.com/unicode-org/icu4x/pull/3515 and the MSRV WIP in #3513, we're down to 32 failures (we started at around 70)
There's a bunch of weird ones in the VZV mutation code, there's also this one in the hashmap code
The hashmap one is in an external crate (t1ha
) that hasn't been updated since 2019. It fails miri on its own, worth investigating separately. There's another VZV failure due to bad databake data, I'm just deleting the test for now (https://github.com/unicode-org/icu4x/pull/2147/files#r1227541004). Someone ought to regen that data correctly, and perhaps add another test that ensure the databaked data has the appropriate contents.
An interesting one is the failure in stress_test
around VZV mutation. I believe this is because the from
and to
in the ptr::copy
are overlapping, which is allowed, but potentially not allowed in the stacked borrows model.
Most of what's left seems to be VZV DST stuff that I don't think can be handled until we have proper pointer metadata APIs.
There is one tricky one in VarULE::to_boxed()
:
The reason it's tricky is that fn from_byte_slice_unchecked(bytes: &[u8]) -> &Self
definitely does not produce a reference you can turn into a Box, but we're only really relying on it to do pointer arithmetic for us. We could replace it with from_byte_slice_unchecked(bytes: *const [u8]) -> *const Self
, though I'm not sure if it counts as a retag to turn that into a *mut
first. I'd rather not maintain parallel *const
and *mut
versions of the same API.
https://github.com/rust-lang/unsafe-code-guidelines/issues/256 is the upstream issue for a couple of the DST twiddling violations we have seen. Looks like it's fixed under Tree Borrows.
Current progress:
failures:
utils/zerovec/src/lib.rs - (line 92)
utils/zerovec/src/lib.rs - make_varule (line 448)
utils/zerovec/src/map/map.rs - map::map::ZeroMap<'a,K,V>::insert_var_v (line 333)
utils/zerovec/src/map/map.rs - map::map::ZeroMap<'a,K,V>::remove (line 228)
utils/zerovec/src/map2d/map.rs - map2d::map::ZeroMap2d<'a,K0,K1,V>::remove (line 323)
(minus the hashmap issues from t1ha)
Stacked borrows is an experimental safety model for Rust, and miri runs it. There are still some rough edges so it's okay to fail a Stacked Borrows run, but it's worth starting to look at them now because there may be upstream fixes required. The model may also be replaced by Tree Borrows though I suspect it'll have similar implications for us.
In zerovec we have a ton of violations in the miri run (
cargo +nightly miri test --all-features --no-fail-fast
to see all the failures)A bunch of them do not seem fixable (yet) and I plan to ask upstream. I'll document some of them here first.
cc @sffc