From a lifetime perspective, the borrow does not end until 'a ends, and 'a does not end until the function returns. (All generic parameters of a function always outlive the function call.) From a perspective of LLVM-backed code generation, the same is true because noalias is a property of the function's parameter that applies to the whole function call. From a Stacked Borrows perspective, I’m not well informed, but I believe a “protector” plays the same role.
What these all have in common is that they are claims upon (the kinds of access to) that memory which start when a reference is passed to a function, and end when that function call ends.
I see Ref uses NonNull<T> and adds T: ?Sized. It looks like I could maybe save the pointer as *const [T] instead of *const T, but I'm not sure how to do that. If I change ptr.cast::<T>() to ptr.cast::<[T]>() I get
error[E0277]: the size for values of type `[T]` cannot be known at compilation time
--> src/lib.rs:165:24
|
165 | ptr.cast::<[T]>()
| ---- ^^^ doesn't have a size known at compile-time
| |
| required by a bound introduced by this call
|
= help: the trait `Sized` is not implemented for `[T]`
note: required by an implicit `Sized` bound in `std::ptr::mut_ptr::<impl *mut T>::cast`
--> /home/andy/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/core/src/ptr/mut_ptr.rs:47:23
|
47 | pub const fn cast<U>(self) -> *mut U {
| ^ required by the implicit `Sized` requirement on this type parameter in `std::ptr::mut_ptr::<impl *mut T>::cast`