3 ms·
There's one other oddity, where `let x: &mut T` allows mutating the target, while `let x: Box<T>` or `T` doesn't. fn box_immut(x: Box<i32>) { // illega
by nyanpasu64 5y ago
There's one other oddity, where `let x: &mut T` allows mutating the target, while `let x: Box<T>` or `T` doesn't.
fn box_immut(x: Box<i32>) {
// illegal
*x += 1;
}
fn ref_immut(x: &mut i32) {
// legal
*x += 1;
}
IIRC under the current current Rust-to-LLVM compilation rules, &mut T is noalias (because it's exclusive), and &T is noalias or readonly or something (because all other &T are immutable) unless T contains an UnsafeCell. It actually took many years to get &mut T to be noalias without exposing LLVM bugs resulting in miscompiled Rust (which went undiscovered because Rust is the first LLVM language to use noalias so heavily).
And noalias and pointer aliasing is a huge mess, with crates like owning_ref and Tokio's intrusive linked lists and Pin<Box<T>> being unsound under the proposed Stacked Borrows rules. And I just found a LLVM codegen soundness issue: https://github.com/rust-lang/rust/issues/63787 https://github.com/rust-lang/rust/issues/63787.