Rust: #[must_use] on traits, e.g. on Future

Created on 30 Oct 2018  Â·  19Comments  Â·  Source: rust-lang/rust

Putting #[must_use] on a trait is currently a no-op (it doesn't seem to do anything, but it is allowed). See example on playground.

One important use-case for this would be to have #[must_use] on std::Future. When returning impl Future<…> or Box<dyn Future<…>> from a function, it should lead to a warning if that future is not used, as that is almost certainly a bug.

A-lint E-easy E-mentor

Most helpful comment

This is now possible. It should be easy to make a pull request adding #[must_use] to Future (with a test).

We probably want to also consider what other traits would benefit from being #[must_use]. Iterator is a fairly obvious choice, for one.

All 19 comments

cc @varkor

This is now possible. It should be easy to make a pull request adding #[must_use] to Future (with a test).

We probably want to also consider what other traits would benefit from being #[must_use]. Iterator is a fairly obvious choice, for one.

Fn FnMut FnOnce are good candidates as well.

@F001 Can you elaborate? If Output = () then I probably don't want the warning...?

@Centril Well, I think this warning means this:

let c : impl Fn(i32) = ... ;
c(); // `c` must be used. If `c` is discarded, it probably indicates something wrong.

let r = c(); // I think this attribute does not care `r` is used or not

@F001 Yeah that makes sense.

Has this issue been taken?

@FrankSD: this appears to have been completed in https://github.com/rust-lang/rust/pull/56677. However, at least one of the traits could do with a more informative #[must_use] message as highlighted in https://github.com/rust-lang/rust/pull/56677/files#r241236020 (and perhaps the others could be improved too). So you're welcome to open a PR with that improvement!


I'm going to close this issue, though, as I think it's been completed satisfactorily.

The OP mentions both impl Future and Box<dyn Future>. It appears the former has been implemented, but the latter doesn't warn still.

#[must_use]
trait Foo {}

impl Foo for () {}

fn foo() -> impl Foo {
    ()
}

fn bar() -> Box<dyn Foo> {
    Box::new(())
}


fn main() {
    foo();
    bar();
}

only gives (playground)

   Compiling playground v0.0.1 (/playground)
warning: unused implementer of `Foo` that must be used
  --> src/main.rs:16:5
   |
16 |     foo();
   |     ^^^^^^
   |
   = note: #[warn(unused_must_use)] on by default

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

This was an oversight on my part; I'll open up a PR soon to fix this.

It does apply to let x: dyn Future.

As for Box<dyn Trait> and #[must_use] it doesn't seem trivial to me unless you make it a special case for Box. We should think of a general solution for type constructors.

This is related to (or is maybe just a subissue of) https://github.com/rust-lang/rust/issues/39524. It seems reasonable to special-case Box as a stop-gap and try to fix the whole issue at some point.

@varkor If you're going for a hack, an attribute based hack seems better, e.g.

pub struct Box<#[rustc_propagate_must_use] T: ?Sized>(Unique<T>);

@Centril: I'm not really going for a hack — Box is already a special-cased type and I'm simply going to add explicit handling for it into unused.rs. I think we'd want to special case it even if we had general support for unused components of structs, to give better error messages.

@varkor is this going to propagate #[must_use] for Pin<Box<Future>>? Or just Box<Future>?

@andll: I don't think this will propagate for Pin<Box<Future>>, but I imagine https://github.com/rust-lang/rust/pull/62262 would do.

I'd like to bring this back up a bit.

I've been doing some introductory async work, and I've been bitten by the lack of hints to use a boxed future (futures::future::BoxFuture<'a, T> / Pin<Box<dyn Future<Output = T> + 'a + Send>>) multiple times. This is exacerbated because we cannot use async fn in traits, so boxing is a common workaround — the compiler error messages even suggest using a crate that automatically performs this rewriting!

@shepmaster new issue for that appears to be https://github.com/rust-lang/rust/issues/67387

Was this page helpful?
0 / 5 - 0 ratings

Related issues

dnsl48 picture dnsl48  Â·  3Comments

drewcrawford picture drewcrawford  Â·  3Comments

dwrensha picture dwrensha  Â·  3Comments

SharplEr picture SharplEr  Â·  3Comments

dtolnay picture dtolnay  Â·  3Comments