1

Consider `#[must_use]` annotation on `async fn` as also affecting the `Future::O...

 2 years ago
source link: https://github.com/rust-lang/rust/pull/100633
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

Contributor

@tmandry tmandry left a comment

I think this is a very good approach that gets us a useful lint without boiling the ocean. It doesn't solve all problems (like going through join! or similar), but that's allowed ("Trivial no-op expressions containing the value will not violate the lint").

It might actually be possible to support more of those cases by examining any pattern match, not just from matches desugared awaits. But if that's not easy (or too slow) we should land this now and leave it as follow-up work.

@rustbot author

estebank reacted with thumbs up emojispastorino reacted with heart emoji All reactions

compiler/rustc_lint/src/unused.rs

Outdated Show resolved

1

}

#[must_use]

fn bar() -> impl std::future::Future<Output=i32> {

Contributor

@tmandry tmandry 23 days ago

edited

I actually think this might have bigger lang implications, like implying this should also work for functions returning Result as mentioned by #78149 (comment) or on associated types of other traits.

Do you think we should restrict to only async fn for now? (I don't really want to do that since it limits the usefulness of the PR, but we might want the lang team to weigh in otherwise.)

All reactions

Contributor

@guswynn guswynn 23 days ago

Yeah, I think we should limit this to just async fn's for now. Generalizing #[must_use] to look through types like Result and Future is going to require, I think, a pretty significant change (I think niko and I talked about basically needing auto-trait semantics?), and we should probably hold off on any half-measures that may make that more difficult (unless we decide its too difficult)

All reactions

Contributor

Author

@estebank estebank 22 days ago

edited

Stopping this from working would require changing the FnDecl representation of all functions with information about the asyncness. Right now that is only tracked up to the HIR. I could make the lint check the fn item to see if it's async or not, but that only works for functions of the local crate. The four options here are: what it does now, and always propagate must_use from any fn to the Future::Output it might return, make must_use on async fn only work for local crates, make must_use on fns always work for foreign crates but only for async fn in local crates, or modify ty::FnDecl to track more metadata. I'm leaning towards the first case, despite the incorrect mental model it might imply to users for Result and Option.

All reactions

Contributor

@guswynn guswynn 22 days ago

edited

Did not realize the complexity here! In that case, its probably fine to leave it! The plus side is that future work could make things like

#[must_use]
fn thing() -> BoxFuture<Thing> { ... }

can apply to Thing!

estebank reacted with thumbs up emoji All reactions

Contributor

@tmandry tmandry 22 days ago

I tend to agree, but I also don't know if I should be approving decisions about where a lint applies. I started a Zulip thread to get some t-lang feedback first.

All reactions

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK