How and what compiler thinks about this code?

fn main() {

let mut x  =1234;
ok(&mut x);
println!("{}",x); 

}

pub fn ok<'s>(_z:& 'static mut i32){

}

ERROR: Why this code shows x cant borrow immutable because it also borrowed mutably.

MY QUESTION: after calling the ok function it releases the borrows right?. Then where x still be borrowed..

Pls explain it..

No, because ok requires the borrow to live forever.

1 Like

Can you pls expand the term.

why ok` requires the borrow to live forever

'static is a special lifetime, which can be treated as "arbitrarily large". For references, since the lifetime annotation is the lower bound, that means "&'static T must live arbitrarily long", i.e. "&'static T must live until the program termination".

1 Like

But after ok function dont anyone cant borrowing right but why it shows cant borrow immutable because it also borrowed mutable..

Who borrowed the x mutable

The borrow you passed to ok. Check this, for example:

fn main() {
    let mut x = 1234;
    ok(&mut x);
    println!("{}", x);
}

pub fn ok(z: &'static mut i32) {
    std::thread::spawn(move || {
        std::thread::sleep(std::time::Duration::from_secs(1));
        *z = 42;
    });
}

This is the valid implementation of ok, with the same signature as it is in your code. But in this case, borrow would be used by spawned thread, and the caller, i.e. main, can't know how long this thread will run and how long it will hold this borrow - so it must be 'static. In fact, this function, with the only change being lifetime annotation in signature, won't compile:

pub fn not_ok<'s>(z: &'s mut i32) {
    std::thread::spawn(move || {
        std::thread::sleep(std::time::Duration::from_secs(1));
        *z = 42;
    });
}

Now, since Rust doesn't look at function body when verifying its caller, it can't possibly know whether ok is empty (as in your case) or really uses borrow as 'static (as here). And the signature clearly tells it that this is the latter.

4 Likes

It's like I said in the other thread:

The lifetimes say otherwise. The compiler will follow the lifetimes as written, even if they impose more strict requirements than you need.

In this case, the 'static lifetime requires x to be valid forever. (including until after main has returned)

2 Likes

Lifetime errors are sometimes a bit hard to understand. Even without understanding the errors fully, you should try to remember some antipatterns, in particular&'a mut Type where Type itself contains the same lifetime 'a syntactically is (almost) never something you’ll want to have, like the &'s mut &'s str you had here. Quite related, &'static mut Type is (almost) never something you’ll want.

Note that both cases talk about &'a mut reference, so mutable references. With immutable/shared references you might indeed sometimes encounter &'a Type where Type itself contains the same lifetime 'a, or &'static Type.

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.