rust-lang / rust-lang/rust-clippy

[lint] Suggest more permissive async bounds

Open
#16,445 2 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

A-lint
Dominant language
Rust
Stars
13.5k
Forks
2.2k
Avg merge
2d 10h
Merged PRs (30d)
32

Description

What it does

Warn on T: Future bounds, suggest T: IntoFuture instead.

Advantage
  • T: IntoFuture is a strictly more permissive bound than T: Future because Rust has a blanket impl<T: Future> IntoFuture for T.
  • From a semver perspective it's not breaking to change T: Future to T: IntoFuture.
  • This will make it substantially nicer to actually implement and use T: IntoFuture in the ecosystem.
  • This sets Rust up to eventually start desugaring async {} to return IntoFuture rather than Future, allowing us to solve a number of auto-trait issues.
  • We're considering making gen {} return IntoIterator rather than Iterator for this same reason as well.
Drawbacks
  • Like with any new lint, this may result in new warnings and cause people to update their code. However that is the intended effect.
  • Implementations will need to call .into_future() internally to access the future. But this is balanced out by saving callers from having to call .into_future() themselves.
  • IntoFuture is more characters than Future. Ideally we would have had the more general trait have a shorter name, but unfortunately that didn't work out that way. Though luckily both traits are part of the prelude since the 2024 edition, so it's not harder in terms of imports.
Example

When someone writes a T: Future bound:

fn foo<T: Future>(x: T) { .. }

Suggest they write T: IntoFuture instead:

fn foo<T: IntoFuture>(x: T) { .. }
Comparison with existing lints

I did not find any relevant existing lints; this lint appears to be new.

Additional Context

A similar lint could probably be implemented for T: Iterator and T: IntoIterator as well. With the eye on gen {} potentially returning IntoIterator that might be worthwhile implementing as well.

If we do ever decide that we should change the desugaring of async {} from Future to IntoFuture, we'd probably want to have this lint on-by-default in the compiler. I'm filing this issue on clippy first so we can iterate on the lint before suggesting we add it to the compiler.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start by searching rust-clippy for existing trait-bound lints and their UI tests, then trace how a lint is registered and how suggestions are emitted. Implement the warning for T: Future and its suggested T: IntoFuture replacement, and add coverage for the issue's example while checking that unrelated bounds are not diagnosed.

Written by the indexing model from the issue text.

Assessment

Tech stack
rust
Domain
tooling
Issue type
Feature
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
38/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.