Explicit future construction, implicit await

Yes, I believe that is exactly what @parasyte meant.

block_on is synchronous. It actually blocks the calling thread until the future has completed. await its "async equivalent" because it does not block the calling thread, but instead suspends the calling task.

You are correct that do_work does not start until the call to select. But your example does does not do what you want. You would need to do something like this instead:

fn start_do_work() -> impl Future {
    signal_thread_b_to_start_working();
    async { .. }
}

async fn do_work_with_timeout() {
    let work = start_do_work();

    my_sync_function();

    let when = Instant::now() + Duration::from_millis(100);
    let timeout = Delay::new(when);

    futures::select(work, timeout);
}

The latter- some_async_fn(a, b, c) has no meaning in a sync context, and results in a compiler error. This is what gives this proposal the name "implicit await."

Why does this not also apply to explicit await in Rust? This also accurately describes the main RFC, and this is precisely why the Dart designers reached out to warn us! (Yes, the main RFC does provide the -> impl Future { .. async { .. } } trick, but this is also available to Dart 1.)

The problem is not lazy futures on their own. It is lazy futures combined with the mistaken expectation that the expression some_async_fn() will do something more than construct the future. Dart 2 addresses the first aspect by making futures eager; implicit await addresses the second aspect by making that expectation correct.

Again, please think through the point you're trying to make, because you're re-treading ground that has already been covered here, on GitHub, and on Reddit.