Skip to content

Fix unused_async_trait_impl suggestions with return statements#17181

Merged
dswij merged 1 commit into
rust-lang:masterfrom
Wassasin:fix/unused_async_trait_impl_return
Jun 7, 2026
Merged

Fix unused_async_trait_impl suggestions with return statements#17181
dswij merged 1 commit into
rust-lang:masterfrom
Wassasin:fix/unused_async_trait_impl_return

Conversation

@Wassasin

@Wassasin Wassasin commented Jun 7, 2026

Copy link
Copy Markdown
Contributor

changelog: [unused_async_trait_impl]: fix suggestions for statements containing return

Fixes #17179.

@rustbot rustbot added the S-waiting-on-review Status: Awaiting review from the assignee but also interested parties label Jun 7, 2026
@rustbot

rustbot commented Jun 7, 2026

Copy link
Copy Markdown
Collaborator

r? @dswij

rustbot has assigned @dswij.
They will have a look at your PR within the next two weeks and either review your PR or reassign to another reviewer.

Use r? to explicitly pick a reviewer

Why was this reviewer chosen?

The reviewer was selected based on:

  • Owners of files modified in this PR: 8 candidates
  • 8 candidates expanded to 8 candidates
  • Random selection from Jarcho, dswij, llogiq, samueltardieu

@dswij dswij left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great test coverage. Thanks!

View changes since this review

@dswij dswij added this pull request to the merge queue Jun 7, 2026

@ada4a ada4a left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd say feel free to assign fixes to this lint to me? I can generally go through them pretty quickly

r? @ada4a

View changes since this review

Comment on lines +169 to +170
// Unlikely, but someone could potentially hide another return statement in this expression.
walk_expr(self, expr);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

wanna have a test case for this as well? Something like:

async fn foo() -> u32 {
    if a {
        return {
            if b {
                return 1;
            }

            2
        };
    }

    3
}

Comment on lines +317 to +327
let mut visitor = ReturnValueVisitor { exprs: vec![] };
visitor.visit_block(block);

sugg.extend(visitor.exprs.into_iter().filter_map(|expr| {
walk_span_to_context(expr.span, ctxt).map(|expr_span| {
let expr_snippet =
snippet_with_applicability(cx, expr_span, "_", &mut app).to_string();

(expr_span, format!("{builtin_crate}::future::ready({expr_snippet})"))
})
}));

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this would be great to put a comment on, something like:

// Additionally, find all early-returns in the function body, and wrap those in `ready` as well

| |_________^
|
= note: `std::future::ready` creates a `Future` which returns the value immediately when `poll`ed
help: consider removing the `async` from this function and returning `impl Future<Output = u32>` instead

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

since we're changing more things here, it imo becomes less clear what's actually happening -- maybe we should add , using `{std_or_core}::future::ready` to the suggestion message?

Comment on lines +118 to +132
// Test that local functions are not touched by the suggestion.
fn local_func() -> u32 {
if 5 == 2 {
return 1;
}
2
}

// Test that we do not change the tail expr or return in a (unrelated) closure.
let f = || {
if 5 == 2 {
return 1;
}
2
};

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

huh, I wouldn't even have thought of this! well done:)

visitor.visit_block(block);

sugg.extend(visitor.exprs.into_iter().filter_map(|expr| {
walk_span_to_context(expr.span, ctxt).map(|expr_span| {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

hm, wouldn't be great to just ignore expressions where span walking doesn't work.. maybe do something like this?

for expr in visitor.exprs {
    if let Some(expr_span) = walk_span_to_context(expr.span, ctxt) {
        /* add snippet, as before */
    } else {
        app = app.min(Applicability::Unspecified);
    }
}

@rustbot rustbot assigned ada4a and unassigned dswij Jun 7, 2026
@rustbot rustbot added S-waiting-on-author Status: This is awaiting some action from the author. (Use `@rustbot ready` to update this status) and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties labels Jun 7, 2026
@rustbot

rustbot commented Jun 7, 2026

Copy link
Copy Markdown
Collaborator

Reminder, once the PR becomes ready for a review, use @rustbot ready.

@ada4a

ada4a commented Jun 7, 2026

Copy link
Copy Markdown
Contributor

oh no, I was too late...

Merged via the queue into rust-lang:master with commit 0db591d Jun 7, 2026
11 of 13 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

S-waiting-on-author Status: This is awaiting some action from the author. (Use `@rustbot ready` to update this status)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

unused_async_trait_impl generates incorrect suggestion for statements containing return

4 participants