Skip to content

Build-std: panic strategies - #17185

Open
Bryanskiy wants to merge 5 commits into
rust-lang:masterfrom
Bryanskiy:build-std-panic-strategy-2
Open

Build-std: panic strategies#17185
Bryanskiy wants to merge 5 commits into
rust-lang:masterfrom
Bryanskiy:build-std-panic-strategy-2

Conversation

@Bryanskiy

@Bryanskiy Bryanskiy commented Jul 6, 2026

Copy link
Copy Markdown

View all comments

What does this PR try to resolve?

Implementation for rust-lang/wg-cargo-std-aware#29

Tracking issue: rust-lang/rust#155363

fixes #7359 (Technically fixed by rust-lang/rust#160007)
fixes #17404

How to test and review this PR?

Commit 1: add panic_abort to mock std and make the panic configuration closer to real std.
Commit 2: add multiple tests.
Commit 3: add test for #17404

Commit 4: remove panic_unwind from roots. With rust-lang/rust#160007 panic runtimes can be loaded like regular transitive dependencies.

Commit 5: implementation for rules described in https://rust-lang.github.io/rfcs/3874-build-std-always.html#panic-strategies. In short, with this change panic_unwind is no longer built when the abort or immediate-abort profiles are used. (previously panic_unwind was always built).

Future steps:

panic-unwind is currently a default feature(it's not in mock-std):

https://github.com/rust-lang/rust/blob/36714a9983d6ba11203d8bb87a1b372247fbcf06/library/sysroot/Cargo.toml#L23

This should be removed to enable this change.

Additional information

Proposal says:

if panic is set to “unwind” then the panic_unwind feature of sysroot will be enabled and -Cpanic=unwind will be passed

but I found that in cargo -Cpanic=unwind is not passed with "unwind" profile:

if *panic != PanicStrategy::Unwind {
cmd.arg("-C").arg(format!("panic={}", panic));
}

Because rustc in that case uses default which is based on target:

https://github.com/rust-lang/rust/blob/36714a9983d6ba11203d8bb87a1b372247fbcf06/compiler/rustc_session/src/session.rs#L700-L704

Is this a mistake in the RFC, or did I misunderstand something? I have not changed this behavior at the moment for build-std.

cc @adamgemmell

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

rustbot commented Jul 6, 2026

Copy link
Copy Markdown
Collaborator

Thanks for the pull request, and welcome! The Rust Project is excited to review your changes, and you should hear from @ehuss (or someone else) some time within the next two weeks.

Please see the contribution instructions for more information. Namely, in order to ensure the minimum review times lag, PR authors and assigned reviewers should ensure that the review label (S-waiting-on-review and S-waiting-on-author) stays updated, invoking these commands when appropriate:

  • @rustbot author: the review is finished, PR author should check the comments and take action accordingly
  • @rustbot review: the author is ready for a review, this PR will be queued again in the reviewer's queue
Why was this reviewer chosen?

The reviewer was selected based on:

  • Owners of files modified in this PR: @ehuss, @epage, @weihanglo
  • @ehuss, @epage, @weihanglo expanded to ehuss, epage, weihanglo
  • Random selection from ehuss, epage, weihanglo

@Bryanskiy

Copy link
Copy Markdown
Author

@rustbot author (I have to fix CI)

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

rustbot commented Jul 7, 2026

Copy link
Copy Markdown
Collaborator

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

@rustbot rustbot added the S-waiting-on-author Status: The marked PR is awaiting some action (such as code changes) from the PR author. label Jul 7, 2026
@adamgemmell

Copy link
Copy Markdown
Contributor

Is this a mistake in the RFC, or did I misunderstand something? I have not changed this behavior at the moment for build-std.

I think it probably is... panic = unwind in the profile really just means "use the target default" which is why it uses the default behaviour for rustc as you found.

The RFC also describes what happens when panic isn't set in the profile, which I don't think is possible.

@Bryanskiy
Bryanskiy force-pushed the build-std-panic-strategy-2 branch from 4f5fb5a to 6020f3d Compare July 7, 2026 15:19
@rustbot

This comment has been minimized.

@Bryanskiy
Bryanskiy force-pushed the build-std-panic-strategy-2 branch from 6020f3d to 6204c2b Compare July 8, 2026 16:21

@adamgemmell adamgemmell 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.

This looks good, thanks. I appreciate the thorough tests

View changes since this review

Comment thread src/cargo/core/compiler/standard_lib.rs Outdated
crates.insert("alloc");
crates.insert("proc_macro");
crates.insert("panic_unwind");
crates.insert("panic_abort");

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 should be built by default. The reason the strategies are roots is that rustc won't pick them up unless they're passed in via --extern. We have a section in the build-std=always RFC for this, but it's not next to the other section on panic strategies (sorry!)

rustc loads panic runtimes in a different way to most dependencies, and without looking in the sysroot they will fail to load correctly unless passed in with --extern. rustc will need to be patched to be able to load panic runtimes from -L dependency= paths in line with other transitive dependencies.

This doesn't need to block this PR though as the change to this patch to support that will be quite small, and this function will change a lot in the future anyway when the UI changes.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

rust-lang/rust#160007 has landed, so this is now fixed

Comment thread src/cargo/core/compiler/standard_lib.rs Outdated
// overridden. See `validate_profile_override`.
let profile = profiles.base_profile();
if profile.panic == PanicStrategy::Unwind {
crates.insert("panic_unwind");

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.

Should be enabled via a feature on sysroot eventually once the rustc loading behaviour has been changed. Again, this doesn't need to block this PR.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

rust-lang/rust#160007 has landed, so this is now fixed

Comment thread src/cargo/core/compiler/standard_lib.rs Outdated
let (specs, build_panic_unwind) = {
// If there is anything looks like needing std, resolve with it.
// If not, we assume only `core` maye be needed, as `core the most fundamental crate.
// If not, we assume only `core` may be needed, as `core` the most fundamental crate.

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.

nit: "as core is the most fundamental crate"

@Bryanskiy
Bryanskiy force-pushed the build-std-panic-strategy-2 branch 2 times, most recently from c45cd72 to c603013 Compare July 8, 2026 17:33
@Bryanskiy

Copy link
Copy Markdown
Author

@rustbot ready (CI is green and Adam sees his concerns as non-blocking)

@rustbot rustbot added S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. and removed S-waiting-on-author Status: The marked PR is awaiting some action (such as code changes) from the PR author. labels Jul 8, 2026
@davidtwco davidtwco mentioned this pull request Jul 15, 2026
10 tasks
Comment thread src/cargo/core/compiler/standard_lib.rs Outdated
Comment on lines +47 to +50
let profile = profiles.base_profile();
if profile.panic == PanicStrategy::Unwind {
crates.insert("panic_unwind");
}

@ehuss ehuss Jul 16, 2026

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 doesn't seem to handle the situation for cargo test which forces the unwind strategy to be "unwind" even when the strategy is "abort". Thus, when running cargo test, it will end up with the same duplicate lang item problem since it tries to load the wrong unwind.

There's also some complexities when running host tests (proc-macro tests), which I think are also AlwaysUnwind.

I'm a little concerned that trying to deal with these complexities will make this optimization difficult to support. For abort-only targets, the unwind crate should be empty and essentially have no cost.

View changes since the review

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.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

it turned out that the test is incorrect due to:

panic_unwind = { path = "../panic_unwind" }

Today I plan to open a PR in rustc to address #17185 (comment) (load panic runtime with -L dependency) and then I'll come back to this concern.

Comment thread src/cargo/core/compiler/standard_lib.rs Outdated
// those included because we'll never use them anyway.
std_ws.set_require_optional_deps(false);
let specs = {
let profiles = Profiles::new(ws, build_config.requested_profile)?;

@ehuss ehuss Jul 16, 2026

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.

Just a minor nit, but I worry that this function has the possibility to be expensive to call. Would it be possible to pass it in?

View changes since the review

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Done, but this requires moving profile creation before std resolution. Not sure if this is desirable as it might slow down error paths.  If necessary I can undo the change.

@rustbot

This comment has been minimized.

@Bryanskiy

Copy link
Copy Markdown
Author

@rustbot author (need to fix #17185 (comment) and #17185 (comment) first)

@rustbot rustbot added S-waiting-on-author Status: The marked PR is awaiting some action (such as code changes) from the PR author. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels Jul 20, 2026
@weihanglo

Copy link
Copy Markdown
Member

Blocked on rust-lang/rust#160007.

@Bryanskiy
Bryanskiy force-pushed the build-std-panic-strategy-2 branch from c603013 to f4371d0 Compare September 2, 2026 17:40
@rustbot

rustbot commented Sep 2, 2026

Copy link
Copy Markdown
Collaborator

This PR was rebased onto a different master commit. Here's a range-diff highlighting what actually changed.

Rebasing is a normal part of keeping PRs up to date, so no action is needed—this note is just to help reviewers.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Command-fetch S-waiting-on-author Status: The marked PR is awaiting some action (such as code changes) from the PR author.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Windows -Zbuild-std with windows_raw_dylib broken after nightly-2026-08-27 [-Zbuild-std] Duplicate lang item with panic=abort

5 participants