Skip to content

Commit 029de48

Browse files
authored
Add panic=immediate-abort support to Cargo (#16041)
I recently turned `-Zbuild-std-features=panic_immediate_abort` into `-Cpanic=immediate-abort` in rust-lang/rust#146317. There was some discussion of the feature on Zulip here: [#t-compiler/major changes > Unstably add -Cpanic=immediate-abort compiler-team#909](https://rust-lang.zulipchat.com/#narrow/channel/233931-t-compiler.2Fmajor-changes/topic/Unstably.20add.20-Cpanic.3Dimmediate-abort.20compiler-team.23909/with/542845480) One of the outcomes of this shipping in nightly is that a few use patterns were broken, see rust-lang/rust#146974 and rust-lang/rust#146317 for examples. I think most of the users commenting on these issues are having trouble with how `RUSTFLAGS` is propagated through Cargo, and most likely they would have just gotten what they wanted if they could have set a profile option instead. So I'm trying to implement that.
2 parents ed8b696 + 4cb6fe4 commit 029de48

File tree

8 files changed

+188
-25
lines changed

8 files changed

+188
-25
lines changed

src/cargo/core/compiler/mod.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1234,6 +1234,9 @@ fn build_base_args(
12341234
if *panic != PanicStrategy::Unwind {
12351235
cmd.arg("-C").arg(format!("panic={}", panic));
12361236
}
1237+
if *panic == PanicStrategy::ImmediateAbort {
1238+
cmd.arg("-Z").arg("unstable-options");
1239+
}
12371240

12381241
cmd.args(&lto_args(build_runner, unit));
12391242

@@ -1305,7 +1308,7 @@ fn build_base_args(
13051308
// flag to pass to rustc, so register that here. Eventually this flag
13061309
// will simply not be needed when the behavior is stabilized in the Rust
13071310
// compiler itself.
1308-
if *panic == PanicStrategy::Abort {
1311+
if *panic == PanicStrategy::Abort || *panic == PanicStrategy::ImmediateAbort {
13091312
cmd.arg("-Z").arg("panic-abort-tests");
13101313
}
13111314
} else if test {

src/cargo/core/features.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -579,6 +579,9 @@ features! {
579579

580580
/// Allows use of multiple build scripts.
581581
(unstable, multiple_build_scripts, "", "reference/unstable.html#multiple-build-scripts"),
582+
583+
/// Allows use of panic="immediate-abort".
584+
(unstable, panic_immediate_abort, "", "reference/unstable.html#panic-immediate-abort"),
582585
}
583586

584587
/// Status and metadata for a single unstable feature.
@@ -872,6 +875,7 @@ unstable_cli_options!(
872875
no_embed_metadata: bool = ("Avoid embedding metadata in library artifacts"),
873876
no_index_update: bool = ("Do not update the registry index even if the cache is outdated"),
874877
panic_abort_tests: bool = ("Enable support to run tests with -Cpanic=abort"),
878+
panic_immediate_abort: bool = ("Enable setting `panic = \"immediate-abort\"` in profiles"),
875879
profile_hint_mostly_unused: bool = ("Enable the `hint-mostly-unused` setting in profiles to mark a crate as mostly unused."),
876880
profile_rustflags: bool = ("Enable the `rustflags` option in profiles in .cargo/config.toml file"),
877881
public_dependency: bool = ("Respect a dependency's `public` field in Cargo.toml to control public/private dependencies"),
@@ -1417,6 +1421,7 @@ impl CliUnstable {
14171421
"skip-rustdoc-fingerprint" => self.skip_rustdoc_fingerprint = parse_empty(k, v)?,
14181422
"script" => self.script = parse_empty(k, v)?,
14191423
"target-applies-to-host" => self.target_applies_to_host = parse_empty(k, v)?,
1424+
"panic-immediate-abort" => self.panic_immediate_abort = parse_empty(k, v)?,
14201425
"unstable-options" => self.unstable_options = parse_empty(k, v)?,
14211426
"warnings" => self.warnings = parse_empty(k, v)?,
14221427
_ => bail!(

src/cargo/core/profiles.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -561,6 +561,7 @@ fn merge_profile(profile: &mut Profile, toml: &TomlProfile) {
561561
profile.panic = match panic.as_str() {
562562
"unwind" => PanicStrategy::Unwind,
563563
"abort" => PanicStrategy::Abort,
564+
"immediate-abort" => PanicStrategy::ImmediateAbort,
564565
// This should be validated in TomlProfile::validate
565566
_ => panic!("Unexpected panic setting `{}`", panic),
566567
};
@@ -872,17 +873,19 @@ impl serde::ser::Serialize for Lto {
872873

873874
/// The `panic` setting.
874875
#[derive(Clone, Copy, PartialEq, Eq, Debug, Hash, PartialOrd, Ord, serde::Serialize)]
875-
#[serde(rename_all = "lowercase")]
876+
#[serde(rename_all = "kebab-case")]
876877
pub enum PanicStrategy {
877878
Unwind,
878879
Abort,
880+
ImmediateAbort,
879881
}
880882

881883
impl fmt::Display for PanicStrategy {
882884
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
883885
match *self {
884886
PanicStrategy::Unwind => "unwind",
885887
PanicStrategy::Abort => "abort",
888+
PanicStrategy::ImmediateAbort => "immediate-abort",
886889
}
887890
.fmt(f)
888891
}

src/cargo/util/toml/mod.rs

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2570,10 +2570,10 @@ pub fn validate_profile(
25702570
}
25712571

25722572
if let Some(panic) = &root.panic {
2573-
if panic != "unwind" && panic != "abort" {
2573+
if panic != "unwind" && panic != "abort" && panic != "immediate-abort" {
25742574
bail!(
25752575
"`panic` setting of `{}` is not a valid setting, \
2576-
must be `unwind` or `abort`",
2576+
must be `unwind`, `abort`, or `immediate-abort`.",
25772577
panic
25782578
);
25792579
}
@@ -2627,6 +2627,15 @@ fn validate_profile_layer(
26272627
_ => {}
26282628
}
26292629
}
2630+
if profile.panic.as_deref() == Some("immediate-abort") {
2631+
match (
2632+
features.require(Feature::panic_immediate_abort()),
2633+
cli_unstable.panic_immediate_abort,
2634+
) {
2635+
(Err(e), false) => return Err(e),
2636+
_ => {}
2637+
}
2638+
}
26302639
Ok(())
26312640
}
26322641

src/doc/src/reference/unstable.md

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,7 @@ Each new feature described below should explain how to use it.
9595
* [target-applies-to-host](#target-applies-to-host) --- Alters whether certain flags will be passed to host build targets.
9696
* [gc](#gc) --- Global cache garbage collection.
9797
* [open-namespaces](#open-namespaces) --- Allow multiple packages to participate in the same API namespace
98+
* [panic-immediate-abort](#panic-immediate-abort) --- Passes `-Cpanic=immediate-abort` to the compiler.
9899
* rustdoc
99100
* [rustdoc-map](#rustdoc-map) --- Provides mappings for documentation to link to external sites like [docs.rs](https://docs.rs/).
100101
* [scrape-examples](#scrape-examples) --- Shows examples within documentation.
@@ -1674,6 +1675,24 @@ cargo-features = ["open-namespaces"]
16741675
# ...
16751676
```
16761677

1678+
## panic-immediate-abort
1679+
1680+
* Tracking Issue: [#16042](https://github.com/rust-lang/cargo/issues/16042)
1681+
* Upstream Tracking Issue: [rust-lang/rust#147286](https://github.com/rust-lang/rust/issues/147286)
1682+
1683+
Allow use of [`-Cpanic=immediate-abort`](../../rustc/codegen-options/index.html#panic) through a Cargo profile
1684+
1685+
This can be enabled like so:
1686+
```toml
1687+
cargo-features = ["immediate-abort"]
1688+
1689+
[package]
1690+
# ...
1691+
1692+
[profile.release]
1693+
panic = "immediate-abort"
1694+
```
1695+
16771696
## `[lints.cargo]`
16781697

16791698
* Tracking Issue: [#12235](https://github.com/rust-lang/cargo/issues/12235)

tests/testsuite/cargo/z_help/stdout.term.svg

Lines changed: 23 additions & 21 deletions
Loading

tests/testsuite/main.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -150,6 +150,7 @@ mod proc_macro;
150150
mod profile_config;
151151
mod profile_custom;
152152
mod profile_overrides;
153+
mod profile_panic_immediate_abort;
153154
mod profile_targets;
154155
mod profile_trim_paths;
155156
mod profiles;
Lines changed: 121 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,121 @@
1+
//! Tests for `panic = "immediate-abort"`.
2+
3+
use crate::prelude::*;
4+
use cargo_test_support::project;
5+
use cargo_test_support::str;
6+
7+
#[cargo_test]
8+
fn gated_manifest() {
9+
let p = project()
10+
.file(
11+
"Cargo.toml",
12+
r#"
13+
[package]
14+
name = "foo"
15+
version = "0.0.1"
16+
edition = "2015"
17+
18+
[profile.dev]
19+
panic = "immediate-abort"
20+
"#,
21+
)
22+
.file("src/lib.rs", "")
23+
.build();
24+
25+
p.cargo("check")
26+
.masquerade_as_nightly_cargo(&["panic-immediate-abort"])
27+
.with_status(101)
28+
.with_stderr_data(str![[r#"
29+
[ERROR] failed to parse manifest at `[ROOT]/foo/Cargo.toml`
30+
31+
Caused by:
32+
feature `panic-immediate-abort` is required
33+
...
34+
"#]])
35+
.run();
36+
}
37+
38+
#[cargo_test]
39+
fn gated_config_toml() {
40+
let p = project()
41+
.file(
42+
".cargo/config.toml",
43+
r#"
44+
[profile.dev]
45+
panic = "immediate-abort"
46+
"#,
47+
)
48+
.file("src/lib.rs", "")
49+
.build();
50+
51+
p.cargo("check")
52+
.masquerade_as_nightly_cargo(&["panic-immediate-abort"])
53+
.with_status(101)
54+
.with_stderr_data(str![[r#"
55+
[ERROR] config profile `dev` is not valid (defined in `[ROOT]/foo/.cargo/config.toml`)
56+
57+
Caused by:
58+
feature `panic-immediate-abort` is required
59+
...
60+
"#]])
61+
.run();
62+
}
63+
64+
#[cargo_test(nightly, reason = "-Cpanic=immediate-abort is unstable")]
65+
fn manifest_gate_works() {
66+
let p = project()
67+
.file(
68+
"Cargo.toml",
69+
r#"
70+
cargo-features = ["panic-immediate-abort"]
71+
[package]
72+
name = "foo"
73+
version = "0.0.1"
74+
edition = "2015"
75+
76+
[profile.dev]
77+
panic = "immediate-abort"
78+
"#,
79+
)
80+
.file("src/lib.rs", "")
81+
.build();
82+
83+
p.cargo("build --verbose")
84+
.masquerade_as_nightly_cargo(&["panic-immediate-abort"])
85+
.with_stderr_data(str![[r#"
86+
[COMPILING] foo v0.0.1 ([ROOT]/foo)
87+
[RUNNING] `rustc [..]-C panic=immediate-abort -Z unstable-options[..]`
88+
[FINISHED] `dev` profile [unoptimized + debuginfo] target(s) in [ELAPSED]s
89+
90+
"#]])
91+
.run();
92+
}
93+
94+
#[cargo_test(nightly, reason = "-Cpanic=immediate-abort is unstable")]
95+
fn cli_gate_works() {
96+
let p = project()
97+
.file(
98+
"Cargo.toml",
99+
r#"
100+
[package]
101+
name = "foo"
102+
version = "0.0.1"
103+
edition = "2015"
104+
105+
[profile.dev]
106+
panic = "immediate-abort"
107+
"#,
108+
)
109+
.file("src/lib.rs", "")
110+
.build();
111+
112+
p.cargo("build --verbose -Z panic-immediate-abort")
113+
.masquerade_as_nightly_cargo(&["panic-immediate-abort"])
114+
.with_stderr_data(str![[r#"
115+
[COMPILING] foo v0.0.1 ([ROOT]/foo)
116+
[RUNNING] `rustc [..]-C panic=immediate-abort -Z unstable-options[..]`
117+
[FINISHED] `dev` profile [unoptimized + debuginfo] target(s) in [ELAPSED]s
118+
119+
"#]])
120+
.run();
121+
}

0 commit comments

Comments
 (0)