Skip to content

Commit 9cfdf4d

Browse files
committed
Inherit panic settings in test/bench profiles
We've always ignored the `panic` settings configured in test/bench profiles, so this just continues to ignore them but in a slightly different way.
1 parent f37f3ae commit 9cfdf4d

File tree

2 files changed

+70
-36
lines changed

2 files changed

+70
-36
lines changed

src/cargo/core/profiles.rs

Lines changed: 67 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -314,7 +314,7 @@ impl Profiles {
314314
mode: CompileMode,
315315
profile_kind: ProfileKind,
316316
) -> Profile {
317-
let profile_name = if !self.named_profiles_enabled {
317+
let (profile_name, inherits) = if !self.named_profiles_enabled {
318318
// With the feature disabled, we degrade `--profile` back to the
319319
// `--release` and `--debug` predicates, and convert back from
320320
// ProfileKind::Custom instantiation.
@@ -328,9 +328,9 @@ impl Profiles {
328328
match mode {
329329
CompileMode::Test | CompileMode::Bench => {
330330
if release {
331-
"bench"
331+
("bench", Some("release"))
332332
} else {
333-
"test"
333+
("test", Some("dev"))
334334
}
335335
}
336336
CompileMode::Build
@@ -342,26 +342,33 @@ impl Profiles {
342342
// ancestor's profile. However, `cargo clean -p` can hit this
343343
// path.
344344
if release {
345-
"release"
345+
("release", None)
346346
} else {
347-
"dev"
347+
("dev", None)
348348
}
349349
}
350-
CompileMode::Doc { .. } => "doc",
350+
CompileMode::Doc { .. } => ("doc", None),
351351
}
352352
} else {
353-
profile_kind.name()
353+
(profile_kind.name(), None)
354354
};
355355
let maker = match self.by_name.get(profile_name) {
356356
None => panic!("Profile {} undefined", profile_name),
357357
Some(r) => r,
358358
};
359359
let mut profile = maker.get_profile(Some(pkg_id), is_member, unit_for);
360-
// `panic` may not be set for tests/benches, or any of their
361-
// dependencies, so handle that here if that's what `UnitFor` tells us
362-
// to do.
363-
if !unit_for.is_panic_abort_ok() {
364-
profile.panic = PanicStrategy::Unwind;
360+
361+
// Dealing with `panic=abort` and `panic=unwind` requires some special
362+
// treatment. Be sure to process all the various options here.
363+
match unit_for.panic_setting() {
364+
PanicSetting::AlwaysUnwind => profile.panic = PanicStrategy::Unwind,
365+
PanicSetting::ReadProfile => {}
366+
PanicSetting::Inherit => {
367+
if let Some(inherits) = inherits {
368+
let maker = self.by_name.get(inherits).unwrap();
369+
profile.panic = maker.get_profile(Some(pkg_id), is_member, unit_for).panic;
370+
}
371+
}
365372
}
366373

367374
// Incremental can be globally overridden.
@@ -881,11 +888,25 @@ pub struct UnitFor {
881888
/// any of its dependencies. This enables `build-override` profiles for
882889
/// these targets.
883890
build: bool,
884-
/// This is true if it is *allowed* to set the `panic=abort` flag. Currently
885-
/// this is false for test/bench targets and all their dependencies, and
886-
/// "for_host" units such as proc macro and custom build scripts and their
887-
/// dependencies.
888-
panic_abort_ok: bool,
891+
/// How Cargo processes the `panic` setting or profiles. This is done to
892+
/// handle test/benches inheriting from dev/release, as well as forcing
893+
/// `for_host` units to always unwind.
894+
panic_setting: PanicSetting,
895+
}
896+
897+
#[derive(Copy, Clone, Debug, Eq, PartialEq, Hash, Ord, PartialOrd)]
898+
enum PanicSetting {
899+
/// Used to force a unit to always be compiled with the `panic=unwind`
900+
/// strategy, notably for build scripts, proc macros, etc.
901+
AlwaysUnwind,
902+
903+
/// Indicates that this unit will read its `profile` setting and use
904+
/// whatever is configured there.
905+
ReadProfile,
906+
907+
/// This unit will ignore its `panic` setting in its profile and will
908+
/// instead inherit it from the `dev` or `release` profile, as appropriate.
909+
Inherit,
889910
}
890911

891912
impl UnitFor {
@@ -894,7 +915,7 @@ impl UnitFor {
894915
pub fn new_normal() -> UnitFor {
895916
UnitFor {
896917
build: false,
897-
panic_abort_ok: true,
918+
panic_setting: PanicSetting::ReadProfile,
898919
}
899920
}
900921

@@ -904,7 +925,7 @@ impl UnitFor {
904925
build: true,
905926
// Force build scripts to always use `panic=unwind` for now to
906927
// maximally share dependencies with procedural macros.
907-
panic_abort_ok: false,
928+
panic_setting: PanicSetting::AlwaysUnwind,
908929
}
909930
}
910931

@@ -915,7 +936,7 @@ impl UnitFor {
915936
// Force plugins to use `panic=abort` so panics in the compiler do
916937
// not abort the process but instead end with a reasonable error
917938
// message that involves catching the panic in the compiler.
918-
panic_abort_ok: false,
939+
panic_setting: PanicSetting::AlwaysUnwind,
919940
}
920941
}
921942

@@ -928,7 +949,15 @@ impl UnitFor {
928949
pub fn new_test(config: &Config) -> UnitFor {
929950
UnitFor {
930951
build: false,
931-
panic_abort_ok: config.cli_unstable().panic_abort_tests,
952+
// We're testing out an unstable feature (`-Zpanic-abort-tests`)
953+
// which inherits the panic setting from the dev/release profile
954+
// (basically avoid recompiles) but historical defaults required
955+
// that we always unwound.
956+
panic_setting: if config.cli_unstable().panic_abort_tests {
957+
PanicSetting::Inherit
958+
} else {
959+
PanicSetting::AlwaysUnwind
960+
},
932961
}
933962
}
934963

@@ -942,7 +971,11 @@ impl UnitFor {
942971
pub fn with_for_host(self, for_host: bool) -> UnitFor {
943972
UnitFor {
944973
build: self.build || for_host,
945-
panic_abort_ok: self.panic_abort_ok && !for_host,
974+
panic_setting: if for_host {
975+
PanicSetting::AlwaysUnwind
976+
} else {
977+
self.panic_setting
978+
},
946979
}
947980
}
948981

@@ -952,29 +985,32 @@ impl UnitFor {
952985
self.build
953986
}
954987

955-
/// Returns `true` if this unit is allowed to set the `panic=abort`
956-
/// compiler flag.
957-
pub fn is_panic_abort_ok(self) -> bool {
958-
self.panic_abort_ok
988+
/// Returns how `panic` settings should be handled for this profile
989+
fn panic_setting(self) -> PanicSetting {
990+
self.panic_setting
959991
}
960992

961993
/// All possible values, used by `clean`.
962994
pub fn all_values() -> &'static [UnitFor] {
963-
static ALL: [UnitFor; 3] = [
995+
static ALL: &[UnitFor] = &[
964996
UnitFor {
965997
build: false,
966-
panic_abort_ok: true,
998+
panic_setting: PanicSetting::ReadProfile,
967999
},
9681000
UnitFor {
9691001
build: true,
970-
panic_abort_ok: false,
1002+
panic_setting: PanicSetting::AlwaysUnwind,
1003+
},
1004+
UnitFor {
1005+
build: false,
1006+
panic_setting: PanicSetting::AlwaysUnwind,
9711007
},
9721008
UnitFor {
9731009
build: false,
974-
panic_abort_ok: false,
1010+
panic_setting: PanicSetting::Inherit,
9751011
},
9761012
];
977-
&ALL
1013+
ALL
9781014
}
9791015
}
9801016

tests/testsuite/test.rs

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3954,14 +3954,13 @@ fn panic_abort_only_test() {
39543954
.build();
39553955

39563956
p.cargo("test -Z panic-abort-tests -v")
3957-
.with_stderr_does_not_contain("[..]--crate-name a [..]-C panic=abort[..]")
3958-
.with_stderr_contains("[..]--crate-name foo [..]-C panic=abort[..]--test[..]")
3957+
.with_stderr_contains("warning: `panic` setting is ignored for `test` profile")
39593958
.masquerade_as_nightly_cargo()
39603959
.run();
39613960
}
39623961

39633962
#[cargo_test]
3964-
fn panic_abort_invalid() {
3963+
fn panic_abort_test_profile_inherits() {
39653964
if !is_nightly() {
39663965
// -Zpanic-abort-tests in rustc is unstable
39673966
return;
@@ -3997,7 +3996,6 @@ fn panic_abort_invalid() {
39973996

39983997
p.cargo("test -Z panic-abort-tests -v")
39993998
.masquerade_as_nightly_cargo()
4000-
.with_status(101)
4001-
.with_stderr_contains("[..]incompatible with this crate's strategy[..]")
3999+
.with_status(0)
40024000
.run();
40034001
}

0 commit comments

Comments
 (0)