'static reference does not live long enough

Apologies for the slightly convoluted example; it was reduced from a much longer program.

I'm building a 'static shared reference which can be used anywhere in an async program; using Box::leak should make that work, since the original value is just a struct which carries no lifetime parameters.
Here is what I do:

use std::future::Future;

struct Foo {
    baz: String,
}

fn blip(foo: &'static Foo) {
    println!("It's a {}", foo.baz);
}

fn yargh<F>(bzink: F) where F: Future + 'static {
    
}

#[tokio::main]
async fn main() {
    let baz = "bla".to_owned();
    let foo: &'static Foo = Box::leak(Box::new(Foo { baz }));
    let fut = async { blip(foo) };
    yargh(fut);
}

(Playground)

Yet I am getting unexpected compiler errors::

   Compiling playground v0.0.1 (/playground)
warning: unused variable: `bzink`
  --> src/lib.rs:11:13
   |
11 | fn yargh<F>(bzink: F) where F: Future + 'static {
   |             ^^^^^ help: consider prefixing with an underscore: `_bzink`
   |
   = note: `#[warn(unused_variables)]` on by default

error[E0597]: `foo` does not live long enough
  --> src/lib.rs:19:28
   |
19 |     let fut = async { blip(foo) };
   |               -------------^^^---
   |               |     |      |
   |               |     |      borrowed value does not live long enough
   |               |     value captured here by generator
   |               argument requires that `foo` is borrowed for `'static`
20 |     yargh(fut);
21 | }
   | - `foo` dropped here while still borrowed

error: aborting due to previous error

For more information about this error, try `rustc --explain E0597`.
error: could not compile `playground`.

To learn more, run the command again with --verbose.

Am I in the wrong, or is the compiler?
How else do I conjure convenient &'static refs?

You need to use a async move block to capture the environment by value instead of by reference.

#[tokio::main]
async fn main() {
    let baz = "bla".to_owned();
    let foo: &'static Foo = Box::leak(Box::new(Foo { baz }));
-   let fut = async { blip(foo) };
+   let fut = async move { blip(foo) };
    yargh(fut);
}

Thank you, that makes it work.
I do not understand why foo, a reference, would not be treated as Copy and captured safely by default.

Async blocks and closures never capture by value without the move keyword.

Just as a tidbit, capture by move is inferred per capture when the value is consumed. For example:

fn main() {
    let s = String::from("hello");
    let f = || drop(s);
    println!("{:?}", f());
}

(This example compiles, the string is consumed, and it outputs () which is the return value from drop.)

Also notice that nightly will give you this solution already.