Skip to content

Symbol-mangling (v0) should show difference between async / closure / generator #104830

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
Swatinem opened this issue Nov 24, 2022 · 2 comments
Labels
A-closures Area: Closures (`|…| { … }`) A-linkage Area: linking into static, shared libraries and binaries T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.

Comments

@Swatinem
Copy link
Contributor

The following code:

pub async fn fn_with_nested_block() -> Backtrace {
    None.unwrap_or_else(|| async { Backtrace::force_capture() })
        .await
}

Generates the following demangled symbol with legacy demangling:

async_codegen::fn_with_nested_block::{{closure}}::{{closure}}::{{closure}}

(v0 mangling is similar, but with {closure#0} instead)

Whereas Windows mangling gives this fn name:

async_codegen::fn_with_nested_block::async_fn$0::closure$0::async_block$0

This makes it clear what is an async fn, closure or async block. v0 symbol mangling should make a similar distinction.

#104333 is a first attempt to thread the necessary information through to the place that does the symbol mangling, but actually extending the v0 symbol mangling format / spec is necessary as well to fully solve this.

@jyn514
Copy link
Member

jyn514 commented Apr 12, 2023

v0 is a public spec that is already been implemented by other tools (e.g. gdb). is this proposed change backwards compatible? If not, is it enough to extend the tools or does there need to be a new v1 format?

@jyn514 jyn514 added A-linkage Area: linking into static, shared libraries and binaries A-closures Area: Closures (`|…| { … }`) T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. labels Apr 12, 2023
@sharnoff
Copy link
Contributor

sharnoff commented Jun 15, 2025

I hit this issue recently — I was digging into compile times for a project and having {closure#0} in the v0 mangling of an async function led me to incorrectly believe that the compiler was spending a long time optimizing a small closure in the function, rather than the main body of the async function.

Reading through this issue and the v0 mangling format (link for reference), there's two options that come to mind:

  1. Embed generator information in an identifier attached to a shim/closure namespace — demangling might look like my_crate::my_fn::{shim:async_fn}::{closure#0}::{closure:async_block#0}
  2. Add new namespace tags, alongside "closure" and "shim". Demangling could look like my_crate::my_fn::{async_fn}::{closure#0}::{async_block#0}.
    • Perhaps we'd want to keep async fn as a "shim" but async { ... } as a unique namespace type. There's a few potential routes here

The v0 spec does say to account for new tags being added, but it seems like the second route would still require a new version.


Maybe a reasonable path forward would be to use option (1) with the v0 format, but also start work on a v1 that allows option (2) ?

I'm not sure what the long-term path should be w.r.t. representing new language features in symbols — it'd be unfortunate if a wide swathe of tools need to be updated before each language feature, but including the block types as full identifiers in the symbol (e.g. async_block?) is also a lot of extra characters.

Either way, I'm happy to try picking up #104333 following option (1), if that'd be worthwhile?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-closures Area: Closures (`|…| { … }`) A-linkage Area: linking into static, shared libraries and binaries T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.
Projects
None yet
Development

No branches or pull requests

3 participants