Skip to content

Commit

Permalink
Add #[cfg(panic = "...")]
Browse files Browse the repository at this point in the history
  • Loading branch information
davidhewitt committed Nov 9, 2020
1 parent 25f6938 commit 8d43b3c
Show file tree
Hide file tree
Showing 15 changed files with 136 additions and 10 deletions.
3 changes: 3 additions & 0 deletions compiler/rustc_feature/src/active.rs
Expand Up @@ -613,6 +613,9 @@ declare_features! (
/// 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
// -------------------------------------------------------------------------
Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_feature/src/builtin_attrs.rs
Expand Up @@ -33,6 +33,7 @@ const GATED_CFGS: &[GatedCfg] = &[
),
(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.
Expand Down
3 changes: 3 additions & 0 deletions compiler/rustc_session/src/config.rs
Expand Up @@ -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)));
Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_span/src/symbol.rs
Expand Up @@ -326,6 +326,7 @@ symbols! {
cfg_attr,
cfg_attr_multi,
cfg_doctest,
cfg_panic,
cfg_sanitize,
cfg_target_feature,
cfg_target_has_atomic,
Expand Down
8 changes: 8 additions & 0 deletions compiler/rustc_target/src/spec/mod.rs
Expand Up @@ -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};
Expand Down Expand Up @@ -176,6 +177,13 @@ impl PanicStrategy {
PanicStrategy::Abort => "abort",
}
}

pub fn desc_symbol(&self) -> Symbol {
match *self {
PanicStrategy::Unwind => sym::unwind,
PanicStrategy::Abort => sym::abort,
}
}
}

impl ToJson for PanicStrategy {
Expand Down
38 changes: 38 additions & 0 deletions src/doc/unstable-book/src/language-features/cfg-panic.md
@@ -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 {
// ...
}
}
```
16 changes: 16 additions & 0 deletions src/test/ui/cfg/cfg-panic-abort.rs
@@ -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() { }
18 changes: 18 additions & 0 deletions src/test/ui/cfg/cfg-panic.rs
@@ -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() { }
6 changes: 3 additions & 3 deletions src/test/ui/consts/control-flow/assert.rs
@@ -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() {}
11 changes: 11 additions & 0 deletions src/test/ui/feature-gates/feature-gate-cfg-panic.rs
@@ -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());
}
21 changes: 21 additions & 0 deletions src/test/ui/feature-gates/feature-gate-cfg-panic.stderr
@@ -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`.
13 changes: 9 additions & 4 deletions src/test/ui/fmt/format-args-capture.rs
@@ -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() {
Expand All @@ -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.
Expand All @@ -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";

Expand Down
4 changes: 2 additions & 2 deletions src/test/ui/issues/issue-68696-catch-during-unwind.rs
Expand Up @@ -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;

Expand All @@ -19,6 +18,7 @@ impl Drop for Guard {
}

fn main() {
#[cfg(panic = "unwind")]
let _ = catch_unwind(|| {
let _guard = Guard::default();
panic!();
Expand Down
3 changes: 2 additions & 1 deletion src/test/ui/test-attrs/test-allow-fail-attr.rs
@@ -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!();
}

Expand Down

0 comments on commit 8d43b3c

Please sign in to comment.