Skip to content

#[inline(never)] does not work for async functions #129347

Closed

Description

@michaelwoerister

I would expect the following code produced a Future::poll() impl with the noinline attribute.

#![feature(noop_waker)]

use std::task::{Context, Waker, Poll};
use std::future::Future;

#[inline(never)]
pub async fn foo() -> u32 {
    std::hint::black_box(1)
}

pub fn bar() -> Poll<u32> {
    let f = std::pin::pin!(foo());
    f.poll(&mut Context::from_waker(Waker::noop()))
}

Instead, the poll method has inlinehint applied to it and gets inlined accordingly:

; This is the function creating the async fn obj:
; Function Attrs: noinline nonlazybind uwtable
define i8 @_RNvCs8Nh0J9OTdDr_15async_fn_inline3foo() unnamed_addr #2 {
  %1 = alloca [1 x i8], align 1
  store i8 0, ptr %1, align 1
  %2 = load i8, ptr %1, align 1
  ret i8 %2
}

; This the poll method:
; Function Attrs: inlinehint nonlazybind uwtable <== this should arguably be noinline too
define internal { i32, i32 } @_RNCNvCs8Nh0J9OTdDr_15async_fn_inline3foo0B3_(...)

Meta

rustc --version --verbose:

rustc 1.82.0-nightly (636d7ff91 2024-08-19)
binary: rustc
commit-hash: 636d7ff91b9847d6d43c7bbe023568828f6e3246
commit-date: 2024-08-19
host: x86_64-unknown-linux-gnu
release: 1.82.0-nightly
LLVM version: 19.1.0

Activity

  1. added
    needs-triageThis issue may need triage. Remove when done. See docs forge.rust-lang.org/release/issue-triaging
    on Aug 21, 2024
  2. added
    A-LLVMArea: Code generation parts specific to LLVM. Both correctness bugs and optimization-related issues.
    A-codegenArea: Code generation
    T-compilerRelevant to the compiler team, which will review and decide on the PR/issue.
    S-has-mcveStatus: A Minimal Complete and Verifiable Example has been found for this issue
    on Aug 21, 2024
  3. removed
    needs-triageThis issue may need triage. Remove when done. See docs forge.rust-lang.org/release/issue-triaging
    on Aug 21, 2024
  4. compiler-errors commented on Aug 21, 2024

    @compiler-errors
    Contributor

    I feel like it's actually up for debate whether #[inline] on an async fn should apply to the function item itself (that produces the future) or the poll function of the coroutine that the item returns. This distinction matters, and it's a subtlety that's not really possible to clearly distinguish with the current inline syntax.

  5. michaelwoerister commented on Aug 21, 2024

    @michaelwoerister
    MemberAuthor

    I agree that that's not clear. It would be great, however, if there was some way to control the inlining behavior of the poll function.

  6. compiler-errors commented on Aug 21, 2024

    @compiler-errors
    Contributor

    I can agree about that!

  7. added
    AsyncAwait-TriagedAsync-await issues that have been triaged during a working group meeting.
    on Oct 3, 2024
  8. traviscross commented on Oct 3, 2024

    @traviscross
    Contributor

    @rustbot labels +T-lang +I-lang-nominated

    We discussed this during WG-async triage. On the one hand, this is an optimization, so it seems like a compiler issue. But there's also a lang issue hiding in here:

    To what does the attribute apply?

    That's probably a lang question. So let's lang nominate it and discuss.

    Our feeling on the WG-async call was that the attribute should probably apply semantically to both the function that constructs the future and to the constructed poll function. We felt in particular that the current behavior of it not applying to the poll function is surprising and less useful.

    And we felt that if people needed more control than that, the suggestion would be that they desugar the async fn into #[inline(..)] fn .. -> impl Future<..> { #[inline(..)] async { .. }}.

    What does the team think?

  9. added
    I-lang-nominatedNominated for discussion during a lang team meeting.
    T-langRelevant to the language team
    on Oct 3, 2024
  10. 29 remaining items

  11. added 2 commits that reference this issue on Nov 3, 2026
    ddc818e
    45d60e4
  12. added a commit that references this issue on Nov 3, 2026
    93a716b
  13. added a commit that references this issue on Nov 3, 2026
    f129f50
  14. added a commit that references this issue on Nov 3, 2026
    a28b383
  15. added a commit that references this issue on Nov 3, 2026
    a8308b5
  16. added a commit that references this issue on Nov 3, 2026
    5413e35
  17. added 3 commits that reference this issue on Nov 3, 2026
    b91648c
    483af01
    7bbe838
  18. added a commit that references this issue on Nov 3, 2026
    5900293
  19. added a commit that references this issue on Nov 3, 2026
    77f64e5
  20. added a commit that references this issue on Nov 4, 2026
    8fc1145
  21. added a commit that references this issue on Nov 4, 2026
    77bae25
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-LLVMArea: Code generation parts specific to LLVM. Both correctness bugs and optimization-related issues.A-async-awaitArea: Async & AwaitA-codegenArea: Code generationAsyncAwait-TriagedAsync-await issues that have been triaged during a working group meeting.C-bugCategory: This is a bug.S-has-mcveStatus: A Minimal Complete and Verifiable Example has been found for this issueT-langRelevant to the language teamdisposition-mergeThis issue / PR is in PFCP or FCP with a disposition to merge it.finished-final-comment-periodThe final comment period is finished for this PR / Issue.

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions