murphy
murphy

Reputation: 544

Why 'static lifetime needed for owned variable by cloning

I struggle a little with rust lifetimes: why is 'static lifetime needed for run_trait_test?.

I want it to behave like run_concrete_test

I read the documentation, searched stackoverflow and the rust-book but I'm obviously missing something.

use std::thread;

#[derive(Debug, Clone)]
struct Test {
    test_string: String,
}

trait Example {
    fn tst(&self) -> ();
}

impl Example for Test {
    fn tst(&self) {
        println!("{:?}", self);
    }
}

// compiles, no 'static here
fn run_concrete_test(tester: &Test) {
    let t = tester.clone();
    thread::spawn(move || {
        t.tst();
    });
}

// compiles with 'static
// but F shouldn't be only static
fn run_trait_test<F>(tester: &'static F)
where
    F: Example + Sync + Send + 'static,
{
    let t = tester.clone();
    let store_t = thread::spawn(move || {
        t.tst();
    });
}

fn main() {
    //does run, no static
    let x = Test {
        test_string: "test string".to_string(),
    };
    run_concrete_test(&x);

    // doe sn't compile because of static
    // run_trait_test(&x);
    println!("{:?}", x);
}

Upvotes: 3

Views: 1734

Answers (1)

&#214;mer Erden
&#214;mer Erden

Reputation: 8793

From reference :

The following traits are implemented for all &T, regardless of the type of its referent:

  • ...
  • Clone (Note that this will not defer to T's Clone implementation if it exists!)
  • ...

Since F has 'static lifetime boundary, &F is a type of shared variable:

  • Without Clone boundary compiler will use clone from borrowed version of F (Simply it would just clone the reference)
  • With Clone boundary, compiler will use the implementation of F's Clone

With all of these the code below will work as same with run_concrete_test :

trait Example {
    fn test(&self);
}

fn _run_trait_test<F>(tester: &F)
where
    F: Example + Sync + Send + Clone + 'static,
{
    let t = tester.clone();

    ::std::thread::spawn(move || {
        t.test();
    });
}

Note: Without 'static lifetime boundary it is possible that F could be considered as some T's borrowed type like F = &T

Playground

Upvotes: 4

Related Questions