I currently read some MIR about Vec.
From `Vec::clone`, `std::slice::from_raw_parts` is invoked to construct a slice pointer. The MIR for `std::slice::from_raw_parts` shows follow.
fn std::slice::from_raw_parts::<'_, i32>(_1: *const i32, _2: usize) -> &[i32] {
let mut _0: &[i32];
let mut _3: bool;
let _4: ();
let mut _5: *mut ();
let mut _6: usize;
let mut _7: usize;
let _8: *const [i32];
debug data => _1;
debug len => _2;
bb0: {
StorageLive(_3);
_3 = core::ub_checks::check_language_ub() -> [return: bb1, unwind unreachable];
}
bb1: {
switchInt(move _3) -> [0: bb6, otherwise: bb2];
}
bb2: {
StorageLive(_5);
_5 = _1 as *mut ();
StorageLive(_6);
_6 = std::mem::size_of::<i32>() -> [return: bb3, unwind unreachable];
}
bb3: {
StorageLive(_7);
_7 = std::mem::align_of::<i32>() -> [return: bb4, unwind unreachable];
}
bb4: {
_4 = std::slice::from_raw_parts::precondition_check(move _5, move _6, move _7, _2) -> [return: bb5, unwind unreachable];
}
bb5: {
StorageDead(_7);
StorageDead(_6);
StorageDead(_5);
goto -> bb6;
}
bb6: {
StorageDead(_3);
StorageLive(_8);
_8 = std::ptr::slice_from_raw_parts::<i32>(move _1, move _2) -> [return: bb7, unwind unreachable];
}
bb7: {
_0 = &(*_8);
StorageDead(_8);
return;
}
}
I am curious about the semantics for _0 = &(*_8) in bb7.
If the cloned Vec is not allocated, _1 is an invalid pointer. For example, the empty can be created by Vec::new(). And the pointer it holds is align_of::<i32>() as *const i32.
Thus, my question is, is the star operator *_8 illegal? Or, &* is special for a fat pointer.