Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Fix assembling mutable slice from const reference
The pointer from which a mutable reference is created must have provenance for accessing the underlying elements of the struct and its fields (a single array here) mutably. A pointer acquired by slice::as_ptr does not have that provenance, it only allows shared read access. The `slice::as_ptr` method says: > The caller must also ensure that the memory the pointer (non-transitively) points to is never written to (except inside an UnsafeCell) using this pointer or any pointer derived from it. If you need to mutate the contents of the slice, use as_mut_ptr. This fails MIRI which checks for this assertion but I'm not aware of mis-compilation resulting from it. In fact, consider: pub fn as_ptr(slice: &mut [u8]) -> *const u8 { slice.as_ptr() } pub fn as_mut_ptr(slice: &mut [u8]) -> *mut u8 { slice.as_mut_ptr() } <https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=28d3c19800236ae520441a22a6f99b19> Then llvm-IR in optimization will show that the functions are collapsed to a single one, hinting there is no semantic difference at that level. The difference in codegen is a readonly attribute on the slice::as_ptr argument but this is scoped to the particular function and argument, not the pointer value itself: > On a function, this attribute indicates that the function does not write through any pointer arguments <https://llvm.org/docs/LangRef.html> Since the _outer_ function correctly takes a `&mut self` argument the restriction possibly no longer applies to our own method. Of course, a stricter codegen of Rust's memory model might not be as kind and exploit the MIR level UB here.
- Loading branch information