In this lesson, you will learn how to safely transition from Rust’s strictly checked references to raw pointers for low-level memory inspection.
Why Downgrade?
Rust’s references (&T and &mut T) are governed by the borrow checker, which enforces strict aliasing and lifetime rules to ensure memory safety. However, when building low-level systems—such as inspecting memory layouts, interacting with foreign function interfaces (FFI), or implementing custom data structures—you occasionally need to bypass these restrictions.
Constructing a raw pointer from a reference is a way to "downgrade" the reference. You are effectively telling the compiler: "I am temporarily shedding the safety guarantees of the borrow checker so I can look at this address directly."
The Mechanics of Coercion
You can convert a reference to a raw pointer using the as keyword. This process is safe because, while the creation of the pointer is benign, the use (dereferencing) of it remains unsafe.
Consider this example:
let my_val: i32 = 42;
// Downgrading a shared reference to a constant raw pointer
let ptr: *const i32 = &my_val as *const i32;
// Downgrading a mutable reference to a mutable raw pointer
let mut_val: &mut i32 = &mut 10;
let mut_ptr: *mut i32 = mut_val as *mut i32;
unsafe {
// Now we can perform raw pointer arithmetic or inspection
println!("Value at address: {}", *ptr);
}
Important Considerations
When you convert a reference to a raw pointer, the pointer inherently loses the lifetime information associated with the original reference. The compiler no longer tracks how long that memory remains valid. Therefore, you must manually ensure that the memory you are pointing to is not deallocated or mutated in a way that violates Rust's aliasing rules while you hold the pointer.
Creating a raw pointer does not require an unsafe block; it is the act of dereferencing that pointer to read or write the underlying memory that requires you to explicitly wrap your code in unsafe { ... }. By downgrading, you are preparing for that low-level access.
Key Takeaway: Constructing a raw pointer from a reference is a safe coercion that sheds lifetime tracking, placing the responsibility on you to ensure the pointer remains valid and sound before you eventually perform an unsafe dereference.