This is safe:
fn foo<T, U>(x: &T) -> *mut U {
x as *const T as *mut U
}
Unfortunately this (among other safe-raw-pointers things) prevents making e.g. Atomic* take *const instead of &. Which sucks, as raw pointers have the property of not enforcing the properties of references at the LLVM IR level and whatnot, and this would be nice sometimes, even in safe APIs. What's the rationale for transmuting raw pointers being safe and whatnot? To us it seems like this feature (raw pointers) is best described as an oversight or a mistake since safe code should never be interacting with raw pointers in the first place. But maybe it exists this way to actively prevent safe abstractions from using raw pointers? We can't find anything about it tho. Otherwise the implicit conversion between & and *const would've been nice to abuse in some APIs.
What about making it so raw pointers are entirely unsafe in 2021 edition? Specifically:
- Reading a raw pointer is unsafe.
- Writing a raw pointer is safe.
- Transmuting raw pointers, casting raw pointers, etc, is unsafe.
This would allow one to pass &Foo
straight to *const Foo
, it'd also be sound because altho you can store *const Foo
like in let x: *const Foo = &Foo
, you can't actually read it without unsafe
, so something like:
let x = Foo;
let y: *const Foo = &x;
drop(x);
bar(y); // error: reading raw pointers is unsafe
just doesn't compile. Returned raw pointers also count as reading so bar(ptr::null())
would be automatically disallowed in safe code without even changing the definition of ptr::null()
. So what else would change is that for pre-2021 edition code, the post-2021 edition safe functions (except those marked with some internal rustc attribute, for backwards compatibility) that take raw pointers would seem as if they take references-only instead.