Mixing heap and primitive variables in thread closure

I'm having some trouble with threads and would love some help.

My program starts by computing an immutable vector, which I plan to use as a reference in threads. I would really like to only compute this vector once.

The other variable that I want to use in the thread closure is a simple primitive type. For example:

    extern crate crossbeam;
    fn heap_and_primitive_types_in_thread(_heap_type: &Vec<bool>, _primitive_type: i32) {
        // do some work
    }

    fn run_threads() {
        let heap_type = vec![true, false, true];
        let list_of_primitives = vec![1, 2, 3];

        crossbeam::scope(|s| {
            for primitive in list_of_primitives  {
                s.spawn(|_| {
                    heap_and_primitive_types_in_thread(&heap_type, primitive);
                });
            }
        }).unwrap();
    }

But this is the error I get:
error[E0373]: closure may outlive the current function, but it borrows primitive, which is owned by the current function
--> src/chessmusic.rs:62:21
|
60 | crossbeam::scope(|s| {
| - has type &crossbeam::thread::Scope<'1>
61 | for primitive in list_of_primitives.iter().cloned() {
62 | s.spawn(|_| {
| ^^^ may outlive borrowed value primitive
63 | heap_and_primitive_types_in_thread(&heap_type, primitive);
| --------- primitive is borrowed here

I've tried iterating list_of_primitives with iter().cloned(), but I get the same error

You'll need to add the move keyword to your inner closure, so it captures primitive by value rather than by reference.

However, you do want it to capture heap_type by reference. You can force this by explicitly taking a reference to it, outside of the closure:

crossbeam::scope(|s| {
    for primitive in list_of_primitives  {
        let heap_type = &heap_type;
        s.spawn(move |_| {
            heap_and_primitive_types_in_thread(heap_type, primitive);
        });
    }
}).unwrap();

Thank you! Your answer works.
I'm a bit unclear as to why it works though

    let heap_type = &vec![true, false, true]; // Note this is a reference now
    let list_of_primitives = vec![1, 2, 3];
    crossbeam::scope(|s| {
        for primitive in list_of_primitives.iter().cloned()  {
            s.spawn( move |_| {
                heap_and_primitive_types_in_thread(&heap_type, primitive);
            });
        }
    }).unwrap();

From the docs: move converts any variables captured by reference or mutable reference to owned by value variables.

Wouldn't this mean that heap_type should be dropped by the first closure?

heap_type is a shared reference (&T), and shared references are Copy and dropping it is no-op.

That makes sense. Thank you!