Rollup merge of #74754 - davidhewitt:cfg-panic, r=ecstatic-morse

Add `#[cfg(panic = '...')]`

This PR adds conditional compilation according to the panic strategy.

I've come across a need for a flag like this a couple of times while writing tests: #74301 , https://github.com/rust-lang/rust/pull/73670#issuecomment-653629031

I'm not sure if I need to add a feature gate for this flag?
This commit is contained in:
Dylan DPC 2020-11-09 19:06:37 +01:00 committed by GitHub
commit 46bce9f8ef
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
15 changed files with 136 additions and 10 deletions

View File

@ -613,6 +613,9 @@ pub fn set(&self, features: &mut Features, span: Span) {
/// Allows the use of destructuring assignments.
(active, destructuring_assignment, "1.49.0", Some(71126), None),
/// Enables `#[cfg(panic = "...")]` config key.
(active, cfg_panic, "1.49.0", Some(77443), None),
// -------------------------------------------------------------------------
// feature-group-end: actual feature gates
// -------------------------------------------------------------------------

View File

@ -33,6 +33,7 @@ macro_rules! cfg_fn {
),
(sym::sanitize, sym::cfg_sanitize, cfg_fn!(cfg_sanitize)),
(sym::version, sym::cfg_version, cfg_fn!(cfg_version)),
(sym::panic, sym::cfg_panic, cfg_fn!(cfg_panic)),
];
/// Find a gated cfg determined by the `pred`icate which is given the cfg's name.

View File

@ -793,6 +793,9 @@ pub fn default_configuration(sess: &Session) -> CrateConfig {
}
}
let panic_strategy = sess.panic_strategy();
ret.insert((sym::panic, Some(panic_strategy.desc_symbol())));
for s in sess.opts.debugging_opts.sanitizer {
let symbol = Symbol::intern(&s.to_string());
ret.insert((sym::sanitize, Some(symbol)));

View File

@ -326,6 +326,7 @@
cfg_attr,
cfg_attr_multi,
cfg_doctest,
cfg_panic,
cfg_sanitize,
cfg_target_feature,
cfg_target_has_atomic,

View File

@ -37,6 +37,7 @@
use crate::spec::abi::{lookup as lookup_abi, Abi};
use crate::spec::crt_objects::{CrtObjects, CrtObjectsFallback};
use rustc_serialize::json::{Json, ToJson};
use rustc_span::symbol::{sym, Symbol};
use std::collections::BTreeMap;
use std::ops::Deref;
use std::path::{Path, PathBuf};
@ -176,6 +177,13 @@ pub fn desc(&self) -> &str {
PanicStrategy::Abort => "abort",
}
}
pub fn desc_symbol(&self) -> Symbol {
match *self {
PanicStrategy::Unwind => sym::unwind,
PanicStrategy::Abort => sym::abort,
}
}
}
impl ToJson for PanicStrategy {

View File

@ -0,0 +1,38 @@
# `cfg_panic`
The tracking issue for this feature is: [#77443]
[#77443]: https://github.com/rust-lang/rust/issues/77443
------------------------
The `cfg_panic` feature makes it possible to execute different code
depending on the panic strategy.
Possible values at the moment are `"unwind"` or `"abort"`, although
it is possible that new panic strategies may be added to Rust in the
future.
## Examples
```rust
#![feature(cfg_panic)]
#[cfg(panic = "unwind")]
fn a() {
// ...
}
#[cfg(not(panic = "unwind"))]
fn a() {
// ...
}
fn b() {
if cfg!(panic = "abort") {
// ...
} else {
// ...
}
}
```

View File

@ -0,0 +1,16 @@
// build-pass
// compile-flags: -C panic=abort
// no-prefer-dynamic
#![feature(cfg_panic)]
#[cfg(panic = "unwind")]
pub fn bad() -> i32 { }
#[cfg(not(panic = "abort"))]
pub fn bad() -> i32 { }
#[cfg(panic = "some_imaginary_future_panic_handler")]
pub fn bad() -> i32 { }
#[cfg(panic = "abort")]
pub fn main() { }

View File

@ -0,0 +1,18 @@
// build-pass
// compile-flags: -C panic=unwind
// ignore-emscripten no panic_unwind implementation
// ignore-wasm32 no panic_unwind implementation
// ignore-wasm64 no panic_unwind implementation
#![feature(cfg_panic)]
#[cfg(panic = "abort")]
pub fn bad() -> i32 { }
#[cfg(not(panic = "unwind"))]
pub fn bad() -> i32 { }
#[cfg(panic = "some_imaginary_future_panic_handler")]
pub fn bad() -> i32 { }
#[cfg(panic = "unwind")]
pub fn main() { }

View File

@ -1,14 +1,14 @@
// Test that `assert` works when `const_panic` is enabled.
// revisions: stock panic
// revisions: stock const_panic
#![cfg_attr(panic, feature(const_panic))]
#![cfg_attr(const_panic, feature(const_panic))]
const _: () = assert!(true);
//[stock]~^ ERROR panicking in constants is unstable
const _: () = assert!(false);
//[stock]~^ ERROR panicking in constants is unstable
//[panic]~^^ ERROR any use of this value will cause an error
//[const_panic]~^^ ERROR any use of this value will cause an error
fn main() {}

View File

@ -0,0 +1,11 @@
#[cfg(panic = "unwind")]
//~^ ERROR `cfg(panic)` is experimental and subject to change
fn foo() -> bool { true }
#[cfg(not(panic = "unwind"))]
//~^ ERROR `cfg(panic)` is experimental and subject to change
fn foo() -> bool { false }
fn main() {
assert!(foo());
}

View File

@ -0,0 +1,21 @@
error[E0658]: `cfg(panic)` is experimental and subject to change
--> $DIR/feature-gate-cfg-panic.rs:1:7
|
LL | #[cfg(panic = "unwind")]
| ^^^^^^^^^^^^^^^^
|
= note: see issue #77443 <https://github.com/rust-lang/rust/issues/77443> for more information
= help: add `#![feature(cfg_panic)]` to the crate attributes to enable
error[E0658]: `cfg(panic)` is experimental and subject to change
--> $DIR/feature-gate-cfg-panic.rs:4:11
|
LL | #[cfg(not(panic = "unwind"))]
| ^^^^^^^^^^^^^^^^
|
= note: see issue #77443 <https://github.com/rust-lang/rust/issues/77443> for more information
= help: add `#![feature(cfg_panic)]` to the crate attributes to enable
error: aborting due to 2 previous errors
For more information about this error, try `rustc --explain E0658`.

View File

@ -1,13 +1,16 @@
// run-pass
// ignore-wasm32
// ignore-wasm64
#![feature(format_args_capture)]
#![feature(cfg_panic)]
fn main() {
named_argument_takes_precedence_to_captured();
panic_with_single_argument_does_not_get_formatted();
panic_with_multiple_arguments_is_formatted();
formatting_parameters_can_be_captured();
#[cfg(panic = "unwind")]
{
panic_with_single_argument_does_not_get_formatted();
panic_with_multiple_arguments_is_formatted();
}
}
fn named_argument_takes_precedence_to_captured() {
@ -22,6 +25,7 @@ fn named_argument_takes_precedence_to_captured() {
assert_eq!(&s, "positional-named-captured");
}
#[cfg(panic = "unwind")]
fn panic_with_single_argument_does_not_get_formatted() {
// panic! with a single argument does not perform string formatting.
// RFC #2795 suggests that this may need to change so that captured arguments are formatted.
@ -34,6 +38,7 @@ fn panic_with_single_argument_does_not_get_formatted() {
assert_eq!(msg.downcast_ref::<&str>(), Some(&"{foo}"))
}
#[cfg(panic = "unwind")]
fn panic_with_multiple_arguments_is_formatted() {
let foo = "captured";

View File

@ -4,8 +4,7 @@
// entering the catch_unwind.
//
// run-pass
// ignore-wasm no panic support
// ignore-emscripten no panic support
#![feature(cfg_panic)]
use std::panic::catch_unwind;
@ -19,6 +18,7 @@ fn drop(&mut self) {
}
fn main() {
#[cfg(panic = "unwind")]
let _ = catch_unwind(|| {
let _guard = Guard::default();
panic!();

View File

@ -1,11 +1,12 @@
// run-pass
// ignore-wasm32-bare compiled with panic=abort by default
// compile-flags: --test
#![feature(allow_fail)]
#![feature(cfg_panic)]
#[test]
#[allow_fail]
fn test1() {
#[cfg(not(panic = "abort"))]
panic!();
}