Are passed values always valid in function scope?

If NULL does not exists in Rust, then one can always assume that an incoming variable to a function is always a "valid" (its not null).
Is this a valid assumption or am I way off?

Given:

fn set_location(p: &mut Point) {

I can assume p is always valid and I dont need to "check if its null".

Yes, there are no checks to do here. An &mut Point — or an &Point or a Box<Point> — not only is prohibited from being a null (zero valued) pointer, but also, will always point to a valid value of the Point type; it isn't allowed to be a non-null pointer to an unmapped or uninitialized location, either.

4 Likes

Here's more info in the book on nulls, describing how Rust uses Option instead of nullable pointers or nullable references.

Addendum: for &mut Point (not &Point), you can also assume you are the only one accessing the underlying Point too.

1 Like

There's an implication here that is important as you learn more about lifetimes. (If you haven't learned about lifetimes yet, perhaps skip this comment for now.)

This:

fn set_location(p: &mut Point) {

is short for this:

fn set_location<'p>(p: &'p mut Point) {

And because p must always be valid, 'p must also be valid. In fact, generic lifetimes on functions are always valid for longer than the function body.[1]

This means you can never borrow a local variable for as long as a generic lifetime parameter, because local variables always drop or move by the end of the function body.

Hence why this results in a borrow check error.

fn example<'s>(s: &'s str) {
    let local = 0;
    let borrow: &'s i32 = &local; // Error: does not live long enough
}

  1. Perhaps only just longer, but always longer. ↩ī¸Ž

1 Like

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.