{Rc,Arc}::{new_uninit_slice,from_iter} create too large references (original) (raw)

See #95252, #95295 and the discussion on Zulip for details. I just figured we should also have an issue to track this.

The following code:

#![feature(new_uninit)] use std::rc::Rc;

fn main() { let p = Rc::<[u8]>::new_uninit_slice(isize::MAX as usize + 1); p.last(); }

fails in Miri (on a 32bit target) with

error: Undefined Behavior: invalid metadata in wide pointer: slice is bigger than largest supported object
    --> /home/r/.rustup/toolchains/miri/lib/rustlib/src/rust/library/alloc/src/rc.rs:1326:24
     |
1326 |             ptr::write(&mut (*inner).strong, Cell::new(1));
     |                        ^^^^^^^^^^^^^^^^^^^^ invalid metadata in wide pointer: slice is bigger than largest supported object
     |
     = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior
     = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information
             
     = note: inside `std::rc::Rc::<[std::mem::MaybeUninit<u8>]>::try_allocate_for_layout::<[closure@std::rc::Rc<[std::mem::MaybeUninit<u8>]>::allocate_for_slice::{closure#0}], [closure@std::rc::Rc<[std::mem::MaybeUninit<u8>]>::allocate_for_slice::{closure#1}]>` at /home/r/.rustup/toolchains/miri/lib/rustlib/src/rust/library/alloc/src/rc.rs:1326:24
     = note: inside `std::rc::Rc::<[std::mem::MaybeUninit<u8>]>::allocate_for_layout::<[closure@std::rc::Rc<[std::mem::MaybeUninit<u8>]>::allocate_for_slice::{closure#0}], [closure@std::rc::Rc<[std::mem::MaybeUninit<u8>]>::allocate_for_slice::{closure#1}]>` at /home/r/.rustup/toolchains/miri/lib/rustlib/src/rust/library/alloc/src/rc.rs:1295:13
     = note: inside `std::rc::Rc::<[std::mem::MaybeUninit<u8>]>::allocate_for_slice` at /home/r/.rustup/toolchains/miri/lib/rustlib/src/rust/library/alloc/src/rc.rs:1375:13
     = note: inside `std::rc::Rc::<[u8]>::new_uninit_slice` at /home/r/.rustup/toolchains/miri/lib/rustlib/src/rust/library/alloc/src/rc.rs:691:31
note: inside `main` at rc.rs:5:13
    --> rc.rs:5:13
     |
5    |     let p = Rc::<[u8]>::new_uninit_slice(isize::MAX as usize + 1);
     |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

In fact it fails even without the +1 since the RcBox is still too big.

On a 64bit target it would fail the same way if creating that huge allocation would not already lead Miri to abort earlier. ;)