Issues with adding lifetimes to non-references

Hey,

I was trying to improve my project by trying to constrain JobHandleScoped to the life time of the JobScope type.

However, when I write the following piece of code:

        let mut jobs = Vec::<_>::with_capacity(200);
        {
            let job_sys = JobSystem::new(2, 128).unwrap();
            let js = JobScope::new_from_system(&job_sys);
            let mut v: u32 = 0;
            for _ in 0..100 {
                let handle = js.create) || {}).unwrap();
                js.run(&handle).unwrap();
                jobs.push(handle);
            }
        }
    }

I doesn't complain that the jobs Vec contains handles that will outlive the scope of the JobScope instance.

The handle is defined as:

pub struct ScopedJobHandle<'scope, T> {
    h: usize,
    p: PhantomData<T>
    s: PhantomData<&'scope mut ()>,
}

and the function signature for create is

 pub fn create<T>(&self, job: T) -> Result<ScopedJobHandle<T>, Error>
    where
        T: Sized + FnOnce() + Send

Am I missing something here? Are my lifetime annotations not sufficient?

What happens if you try actually using e.g. jobs[0] after the block? Lifetimes are not the same as scopes. The compiler tries to be smart and shrink borrows and lifetimes as much as possible, so that more valid code is accepted (which would be otherwise rejected due to spuriously overlapping lifetimes). So maybe if you are not actually reading any element of the vector, it is not considered to have an excessively long lifetime and there's no error.

Note that scopes used to coincide with lifetimes in older versions of Rust. The borrow checker has since been updated at least twice, one such enhancement is called NLL, and the next iteration (still not stable) is called Polonius. In these versions of the borrow checker, lifetimes and borrows are not necessarily the same as block (or other) scopes, they can be (and usually are) strictly shorter.

1 Like

Then it get the expected error.

Ah I see. I was under the impression that rust still had it's life times restricted by the scope as well. That explains it then :).

Well, they are still restricted (bounded from above) by scopes, they are just not identical. :slight_smile: