Skip to content

Add coroutine info to v0 symbol mangling (via DefPath/DefPathData) #143259

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
wants to merge 2 commits into
base: master
Choose a base branch
from

Conversation

sharnoff
Copy link
Contributor

See #104830 (comment) for some context.

The high-level goal here is to change the v0 symbol mangling to include any relevant coroutine information for closures — i.e. if it's been desugared from async, gen, or #[coroutine] blocks/closures.

Example of the intended change

So the idea is to move from this:

// mcyrate::foo::{closure#0}
async fn foo() {}

fn bar() {
    // mycrate::bar::{closure#0}
    let _ = async {};

    // mycrate::bar::{closure#1}::{closure#0}
    let _ = async || {};
    // mycrate::bar::{closure#2}::{closure#0}
    let _ = || async {};

    // mycrate::bar::{closure#3}
    let _ = #[coroutine] || {};
}

to this:

// mcyrate::foo::{closure:async#0}
async fn foo() {}

fn bar() {
    // mycrate::bar::{closure:async#0}
    let _ = async {};

    // mycrate::bar::{closure#0}::{closure:async#0}
    let _ = async || {};
    // mycrate::bar::{closure#1}::{closure:async#0}
    let _ = || async {};

    // mycrate::bar::{closure:coroutine#0}
    let _ = #[coroutine] || {};
}

To do that, this PR:

  1. Adds coroutine information to rustc_hir::DefKind
  2. Passes that information through to rustc_hir::DefPathData
  3. Exposes the coroutine information via DefPathData::get_opt_name so that it shows up as {closure:<coroutine kind>} in symbol mangling
  4. Uses the new DefPathData coroutine info in DefPathDataName to have similar {closure:async} formatting in other places

Ideally it wouldn't have required threading this information everywhere, but AFAICT the only other way to do it would be via accessing HIR nodes during type printing, which IIUC won't work because we can only get HIR nodes for the local crate (?)

This PR affects a few different areas, so I'm not totally sure who to ping for review. Also more than happy to split it up into a few smaller PRs, if that'd be useful.

r? rust-lang/compiler

sharnoff added 2 commits June 30, 2025 20:41
... and, make that available via `get_opt_name()` so that it shows up in
symbol mangling.
@rustbot rustbot added PG-exploit-mitigations Project group: Exploit mitigations S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. T-rustdoc Relevant to the rustdoc team, which will review and decide on the PR/issue. labels Jun 30, 2025
@rustbot
Copy link
Collaborator

rustbot commented Jun 30, 2025

Some changes occurred in coverage tests.

cc @Zalathar

Some changes occurred in match checking

cc @Nadrieril

Some changes occurred in compiler/rustc_codegen_ssa

cc @WaffleLapkin

Some changes occurred in compiler/rustc_sanitizers

cc @rcvalle

Some changes occurred to the CTFE machinery

cc @RalfJung, @oli-obk, @lcnr

Some changes occurred to the CTFE / Miri interpreter

cc @rust-lang/miri

Some changes occurred in src/tools/clippy

cc @rust-lang/clippy

Some changes occurred to MIR optimizations

cc @rust-lang/wg-mir-opt

HIR ty lowering was modified

cc @fmease

@compiler-errors
Copy link
Member

compiler-errors commented Jun 30, 2025

I wonder if a simpler approach here would be to make a closure_kind query and encode it cross-crate like we do for coroutine_kind.

Then in the demangler, you could instead just intercept the tcx.coroutine_kind to decorate the closure with a better name than its anonymized name?

Not sure if that's possible.

@rust-log-analyzer
Copy link
Collaborator

The job aarch64-gnu-llvm-19-1 failed! Check out the build log: (web) (plain enhanced) (plain)

Click to see the possible cause of the failure (guessed by this bot)
--- stderr -------------------------------
warning: function `gbc` is never used
##[warning] --> coroutine_body.rs:2:18
  |
2 |         async fn gbc() -> i32 {
  |                  ^^^
  |
  = note: `#[warn(dead_code)]` on by default


thread 'rustc' panicked at /checkout/tests/ui-fulldeps/stable-mir/check_coroutine_body.rs:43:9:
Cannot find `gbc::{closure#0}`. All local items are: [
    CrateItem(
        DefId {
            id: 0,
            name: "gbc",
        },
    ),
    CrateItem(
        DefId {
            id: 1,
            name: "gbc::{closure:async#0}",
        },
    ),
    CrateItem(
        DefId {
            id: 2,
            name: "gbc::{closure:async#0}::{closure:async#0}",
        },
    ),
    CrateItem(
        DefId {
            id: 3,

@sharnoff
Copy link
Contributor Author

That would definitely be much better 😅

AFAICT the earliest point where coroutine info is available is when HIR nodes are constructed, but those can only be accessed by LocalDefId.

I thought it wouldn't work for that reason, but from what you said - do I understand correctly that if a query has separate_provide_extern, it'll be able to get that information, even if the DefId is from a different crate?
(I guess like what's done here?)

If so, we can probably just use the coroutine_kind in the symbol mangler already (and I can open a new, much simpler PR 😄)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
PG-exploit-mitigations Project group: Exploit mitigations S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. T-rustdoc Relevant to the rustdoc team, which will review and decide on the PR/issue.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants