Closure might outlive current function even though it is joined
The compiler does not know it is joined. It does not apply any special analysis to see if threads are joined.
However, if you join your threads, you can use scoped threads to access variables:
fn main() {
    let foo = 5;

    std::thread::scope(|s| {
        s.spawn(|| {
            println!("{}", foo);
        });
        // Thread implicitly joined here.
    });
}


fn main() {
    let foo = 5;

    std::thread::spawn(|| { // closure may outlive the current function, but it borrows `foo`, which is owned by the current function
        println!("{}", foo);
    })
    .join()
    .unwrap();
}

Moving the value is not an option since it have to make multiple threads
The situation in my code is a bit more complicated, but I still need threads and I ended up moving and Arc into it instead of just a reference
Here is a link to the line in the project, but you don't have to read it: https://github.com/Antosser/web-crawler/blob/5d23ffa7ed64c772080c7be08a26bda575028c7c/src/main.rs#L291
