From 8d43b3cbb91b7327b42b0da721525e7ae2911f0b Mon Sep 17 00:00:00 2001 From: David Hewitt <1939362+davidhewitt@users.noreply.github.com> Date: Sat, 25 Jul 2020 19:02:49 +0100 Subject: [PATCH] Add `#[cfg(panic = "...")]` --- compiler/rustc_feature/src/active.rs | 3 ++ compiler/rustc_feature/src/builtin_attrs.rs | 1 + compiler/rustc_session/src/config.rs | 3 ++ compiler/rustc_span/src/symbol.rs | 1 + compiler/rustc_target/src/spec/mod.rs | 8 ++++ .../src/language-features/cfg-panic.md | 38 +++++++++++++++++++ src/test/ui/cfg/cfg-panic-abort.rs | 16 ++++++++ src/test/ui/cfg/cfg-panic.rs | 18 +++++++++ ...panic.stderr => assert.const_panic.stderr} | 0 src/test/ui/consts/control-flow/assert.rs | 6 +-- .../feature-gates/feature-gate-cfg-panic.rs | 11 ++++++ .../feature-gate-cfg-panic.stderr | 21 ++++++++++ src/test/ui/fmt/format-args-capture.rs | 13 +++++-- .../issues/issue-68696-catch-during-unwind.rs | 4 +- .../ui/test-attrs/test-allow-fail-attr.rs | 3 +- 15 files changed, 136 insertions(+), 10 deletions(-) create mode 100644 src/doc/unstable-book/src/language-features/cfg-panic.md create mode 100644 src/test/ui/cfg/cfg-panic-abort.rs create mode 100644 src/test/ui/cfg/cfg-panic.rs rename src/test/ui/consts/control-flow/{assert.panic.stderr => assert.const_panic.stderr} (100%) create mode 100644 src/test/ui/feature-gates/feature-gate-cfg-panic.rs create mode 100644 src/test/ui/feature-gates/feature-gate-cfg-panic.stderr diff --git a/compiler/rustc_feature/src/active.rs b/compiler/rustc_feature/src/active.rs index 84114fc773533..0df67b63eba58 100644 --- a/compiler/rustc_feature/src/active.rs +++ b/compiler/rustc_feature/src/active.rs @@ -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 // ------------------------------------------------------------------------- diff --git a/compiler/rustc_feature/src/builtin_attrs.rs b/compiler/rustc_feature/src/builtin_attrs.rs index 57ae534590ddf..5c5cf609ac33c 100644 --- a/compiler/rustc_feature/src/builtin_attrs.rs +++ b/compiler/rustc_feature/src/builtin_attrs.rs @@ -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. diff --git a/compiler/rustc_session/src/config.rs b/compiler/rustc_session/src/config.rs index b632bfbed301c..ab694ad4c5afd 100644 --- a/compiler/rustc_session/src/config.rs +++ b/compiler/rustc_session/src/config.rs @@ -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))); diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs index 2324dba80f543..ad58f89d87da7 100644 --- a/compiler/rustc_span/src/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs @@ -326,6 +326,7 @@ symbols! { cfg_attr, cfg_attr_multi, cfg_doctest, + cfg_panic, cfg_sanitize, cfg_target_feature, cfg_target_has_atomic, diff --git a/compiler/rustc_target/src/spec/mod.rs b/compiler/rustc_target/src/spec/mod.rs index 895114b026e31..55d27fd8698a7 100644 --- a/compiler/rustc_target/src/spec/mod.rs +++ b/compiler/rustc_target/src/spec/mod.rs @@ -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 @@ 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 { diff --git a/src/doc/unstable-book/src/language-features/cfg-panic.md b/src/doc/unstable-book/src/language-features/cfg-panic.md new file mode 100644 index 0000000000000..f5b73128ad6c2 --- /dev/null +++ b/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 { + // ... + } +} +``` diff --git a/src/test/ui/cfg/cfg-panic-abort.rs b/src/test/ui/cfg/cfg-panic-abort.rs new file mode 100644 index 0000000000000..9b88eff12ed38 --- /dev/null +++ b/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() { } diff --git a/src/test/ui/cfg/cfg-panic.rs b/src/test/ui/cfg/cfg-panic.rs new file mode 100644 index 0000000000000..dbb5932a9bb85 --- /dev/null +++ b/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() { } diff --git a/src/test/ui/consts/control-flow/assert.panic.stderr b/src/test/ui/consts/control-flow/assert.const_panic.stderr similarity index 100% rename from src/test/ui/consts/control-flow/assert.panic.stderr rename to src/test/ui/consts/control-flow/assert.const_panic.stderr diff --git a/src/test/ui/consts/control-flow/assert.rs b/src/test/ui/consts/control-flow/assert.rs index 30cd31ee8a734..90017fee19337 100644 --- a/src/test/ui/consts/control-flow/assert.rs +++ b/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() {} diff --git a/src/test/ui/feature-gates/feature-gate-cfg-panic.rs b/src/test/ui/feature-gates/feature-gate-cfg-panic.rs new file mode 100644 index 0000000000000..1508374d94266 --- /dev/null +++ b/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()); +} diff --git a/src/test/ui/feature-gates/feature-gate-cfg-panic.stderr b/src/test/ui/feature-gates/feature-gate-cfg-panic.stderr new file mode 100644 index 0000000000000..ea5cd54fa90f0 --- /dev/null +++ b/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 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 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`. diff --git a/src/test/ui/fmt/format-args-capture.rs b/src/test/ui/fmt/format-args-capture.rs index 7490632110c85..9348bb46dfe34 100644 --- a/src/test/ui/fmt/format-args-capture.rs +++ b/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() { @@ -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"; diff --git a/src/test/ui/issues/issue-68696-catch-during-unwind.rs b/src/test/ui/issues/issue-68696-catch-during-unwind.rs index d042bed225d17..f25a78f59cd20 100644 --- a/src/test/ui/issues/issue-68696-catch-during-unwind.rs +++ b/src/test/ui/issues/issue-68696-catch-during-unwind.rs @@ -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 @@ impl Drop for Guard { } fn main() { + #[cfg(panic = "unwind")] let _ = catch_unwind(|| { let _guard = Guard::default(); panic!(); diff --git a/src/test/ui/test-attrs/test-allow-fail-attr.rs b/src/test/ui/test-attrs/test-allow-fail-attr.rs index 1a478460efc6c..29ce9f7c2e94f 100644 --- a/src/test/ui/test-attrs/test-allow-fail-attr.rs +++ b/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!(); }