Lack of warning when future is assigned to a variable but never polled

I'm sure my lack of knowledge on how the compiler handles(prioritizes) warnings is causing my confusion, but it seems to me that both fut and _fut2 should emit warnings that the future is never polled?

async fn do_nothing(){
    println!("should never appear in this example!"); 
}  

fn main(){
     do_nothing(); //warns that future is unused... great!
     let fut = do_nothing(); //warns that fut is unused var (nothing about unused future)... okay, but would prefer warning about unused future
     let _fut2 = do_nothing(); //no warnings... not great!
}

(Playground)

Output:

Errors:

   Compiling playground v0.0.1 (/playground)
warning: unused variable: `fut`
 --> src/main.rs:8:10
  |
8 |      let fut = do_nothing();
  |          ^^^ help: if this is intentional, prefix it with an underscore: `_fut`
  |
  = note: `#[warn(unused_variables)]` on by default

warning: unused implementer of `futures::Future` that must be used
 --> src/main.rs:7:6
  |
7 |      do_nothing();
  |      ^^^^^^^^^^^^^
  |
  = note: `#[warn(unused_must_use)]` on by default
  = note: futures do nothing unless you `.await` or poll them

warning: 2 warnings emitted

    Finished dev [unoptimized + debuginfo] target(s) in 1.14s
     Running `target/debug/playground`

It's not a priority. A leading _ disables the warning... which is why the help in the warning says

help: if this is intentional, prefix it with an underscore

(This is useful when doing things like

impl SomeTrait for MyType {
    fn method_where_i_dont_control_the_arguments(&self, _unused: bool) {
    }
}

without using annotations to disable the warning.)

1 Like

Fair enough, I guess using the _ is a blanket suppression. There still seems to be some priority though in that the unused variable warning gets reported over the unpolled future warning, is it just the last warning that occurs essentially?

Ah sorry, I see what you wish you got in that case now.

The warning that the future is unused is part of a more general warning mechanism. If you do this for example:

use std::io::Write;
let mut v: Vec<u8> = Vec::new();
write!(&mut v, "...");

You'll get a similar warning about not using a Result. Just assigning it is considered "using" it.

In other words, the lint currently isn't smart enough for what you want.

For what you want, it will have to see an assignment to a variable (that doesn't start with _) and then track that variable to make sure you eventually call .await or poll it.

I have no idea how feasible this is, maybe someone else will.

No worries, thanks for the response! I was more curious about this behavior than anything else

Related:

2 Likes

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.