]> git.lizzy.rs Git - rust.git/commitdiff
rustc: Add a debug_assertions #[cfg] directive
authorAlex Crichton <alex@alexcrichton.com>
Mon, 2 Mar 2015 22:51:24 +0000 (14:51 -0800)
committerAlex Crichton <alex@alexcrichton.com>
Thu, 5 Mar 2015 22:51:38 +0000 (14:51 -0800)
This commit is an implementation of [RFC 563][rfc] which adds a new
`cfg(debug_assertions)` directive which is specially recognized and calculated
by the compiler. The flag is turned off at any optimization level greater than 1
and may also be explicitly controlled through the `-C debug-assertions`
flag.

[rfc]: https://github.com/rust-lang/rfcs/pull/563

The `debug_assert!` and `debug_assert_eq!` macros now respect this instead of
the `ndebug` variable and `ndebug` no longer holds any meaning to the standard
library.

Code which was previously relying on `not(ndebug)` to gate expensive code should
be updated to rely on `debug_assertions` instead.

Closes #22492
[breaking-change]

13 files changed:
mk/tests.mk
src/libcore/macros.rs
src/liblog/macros.rs
src/librustc/session/config.rs
src/librustc_trans/trans/base.rs
src/test/run-fail/overflowing-add.rs
src/test/run-fail/overflowing-mul.rs
src/test/run-fail/overflowing-sub.rs
src/test/run-make/debug-assertions/Makefile [new file with mode: 0644]
src/test/run-make/debug-assertions/debug.rs [new file with mode: 0644]
src/test/run-pass/conditional-debug-macro-off.rs
src/test/run-pass/logging-enabled-debug.rs
src/test/run-pass/logging-separate-lines.rs

index 838ed0dccfcbbf971971f640121e5ddef109203d..ef38abcab651877dfdd0a6a9c9358d4176cadce6 100644 (file)
@@ -590,7 +590,7 @@ TEST_SREQ$(1)_T_$(2)_H_$(3) = \
 
 # The tests select when to use debug configuration on their own;
 # remove directive, if present, from CFG_RUSTC_FLAGS (issue #7898).
-CTEST_RUSTC_FLAGS := $$(subst --cfg ndebug,,$$(CFG_RUSTC_FLAGS))
+CTEST_RUSTC_FLAGS := $$(subst -C debug-assertions,,$$(CFG_RUSTC_FLAGS))
 
 # The tests cannot be optimized while the rest of the compiler is optimized, so
 # filter out the optimization (if any) from rustc and then figure out if we need
index 94ca9ec37b49b515523e2e6ed713e1df3c6074cb..96c9beece1c021af4a4158c9e596aec1f42e1069 100644 (file)
@@ -100,10 +100,12 @@ macro_rules! assert_eq {
 /// This will invoke the `panic!` macro if the provided expression cannot be
 /// evaluated to `true` at runtime.
 ///
-/// Unlike `assert!`, `debug_assert!` statements can be disabled by passing
-/// `--cfg ndebug` to the compiler. This makes `debug_assert!` useful for
-/// checks that are too expensive to be present in a release build but may be
-/// helpful during development.
+/// Unlike `assert!`, `debug_assert!` statements are only enabled in non
+/// optimized builds by default. An optimized build will omit all
+/// `debug_assert!` statements unless `-C debug-assertions` is passed to the
+/// compiler. This makes `debug_assert!` useful for checks that are too
+/// expensive to be present in a release build but may be helpful during
+/// development.
 ///
 /// # Example
 ///
@@ -125,7 +127,7 @@ macro_rules! assert_eq {
 #[macro_export]
 #[stable(feature = "rust1", since = "1.0.0")]
 macro_rules! debug_assert {
-    ($($arg:tt)*) => (if cfg!(not(ndebug)) { assert!($($arg)*); })
+    ($($arg:tt)*) => (if cfg!(debug_assertions) { assert!($($arg)*); })
 }
 
 /// Asserts that two expressions are equal to each other, testing equality in
@@ -133,10 +135,12 @@ macro_rules! debug_assert {
 ///
 /// On panic, this macro will print the values of the expressions.
 ///
-/// Unlike `assert_eq!`, `debug_assert_eq!` statements can be disabled by
-/// passing `--cfg ndebug` to the compiler. This makes `debug_assert_eq!`
-/// useful for checks that are too expensive to be present in a release build
-/// but may be helpful during development.
+/// Unlike `assert_eq!`, `debug_assert_eq!` statements are only enabled in non
+/// optimized builds by default. An optimized build will omit all
+/// `debug_assert_eq!` statements unless `-C debug-assertions` is passed to the
+/// compiler. This makes `debug_assert_eq!` useful for checks that are too
+/// expensive to be present in a release build but may be helpful during
+/// development.
 ///
 /// # Example
 ///
@@ -147,7 +151,7 @@ macro_rules! debug_assert {
 /// ```
 #[macro_export]
 macro_rules! debug_assert_eq {
-    ($($arg:tt)*) => (if cfg!(not(ndebug)) { assert_eq!($($arg)*); })
+    ($($arg:tt)*) => (if cfg!(debug_assertions) { assert_eq!($($arg)*); })
 }
 
 /// Short circuiting evaluation on Err
index 4a9a9bd40600b73d736244b022a68a46cab331fb..f0f861a3831a126efe176495d163f55d486b6cb1 100644 (file)
@@ -157,7 +157,7 @@ macro_rules! info {
 /// ```
 #[macro_export]
 macro_rules! debug {
-    ($($arg:tt)*) => (if cfg!(not(ndebug)) { log!(::log::DEBUG, $($arg)*) })
+    ($($arg:tt)*) => (if cfg!(debug_assertions) { log!(::log::DEBUG, $($arg)*) })
 }
 
 /// A macro to test whether a log level is enabled for the current module.
@@ -192,7 +192,7 @@ macro_rules! debug {
 macro_rules! log_enabled {
     ($lvl:expr) => ({
         let lvl = $lvl;
-        (lvl != ::log::DEBUG || cfg!(not(ndebug))) &&
+        (lvl != ::log::DEBUG || cfg!(debug_assertions)) &&
         lvl <= ::log::log_level() &&
         ::log::mod_enabled(lvl, module_path!())
     })
index a4355803f4a4e3bd79fd3f6223be46b1a8a0f664..1b09be050203bd82b894d0e981b43f5417a0f524 100644 (file)
@@ -81,6 +81,7 @@ pub struct Options {
 
     pub gc: bool,
     pub optimize: OptLevel,
+    pub debug_assertions: bool,
     pub debuginfo: DebugInfoLevel,
     pub lint_opts: Vec<(String, lint::Level)>,
     pub describe_lints: bool,
@@ -238,7 +239,8 @@ pub fn basic_options() -> Options {
         crate_name: None,
         alt_std_name: None,
         libs: Vec::new(),
-        unstable_features: UnstableFeatures::Disallow
+        unstable_features: UnstableFeatures::Disallow,
+        debug_assertions: true,
     }
 }
 
@@ -528,6 +530,8 @@ fn parse_passes(slot: &mut Passes, v: Option<&str>) -> bool {
          2 = full debug info with variable and type information"),
     opt_level: Option<uint> = (None, parse_opt_uint,
         "Optimize with possible levels 0-3"),
+    debug_assertions: Option<bool> = (None, parse_opt_bool,
+        "explicitly enable the cfg(debug_assertions) directive"),
 }
 
 
@@ -621,7 +625,7 @@ pub fn default_configuration(sess: &Session) -> ast::CrateConfig {
     };
 
     let mk = attr::mk_name_value_item_str;
-    return vec!(// Target bindings.
+    let mut ret = vec![ // Target bindings.
          attr::mk_word_item(fam.clone()),
          mk(InternedString::new("target_os"), intern(os)),
          mk(InternedString::new("target_family"), fam),
@@ -629,7 +633,11 @@ pub fn default_configuration(sess: &Session) -> ast::CrateConfig {
          mk(InternedString::new("target_endian"), intern(end)),
          mk(InternedString::new("target_pointer_width"),
             intern(wordsz))
-    );
+    ];
+    if sess.opts.debug_assertions {
+        ret.push(attr::mk_word_item(InternedString::new("debug_assertions")));
+    }
+    return ret;
 }
 
 pub fn append_configuration(cfg: &mut ast::CrateConfig,
@@ -923,6 +931,7 @@ pub fn build_session_options(matches: &getopts::Matches) -> Options {
             }
         }
     };
+    let debug_assertions = cg.debug_assertions.unwrap_or(opt_level == No);
     let gc = debugging_opts.gc;
     let debuginfo = if matches.opt_present("g") {
         if cg.debuginfo.is_some() {
@@ -1064,6 +1073,7 @@ pub fn build_session_options(matches: &getopts::Matches) -> Options {
         alt_std_name: None,
         libs: libs,
         unstable_features: get_unstable_features_setting(),
+        debug_assertions: debug_assertions,
     }
 }
 
index 13f882bc36318c79d895c651c043158505afdb6b..cf4d0e543e3767d99263823be2b667d5012ae795 100644 (file)
@@ -3089,7 +3089,7 @@ pub fn trans_crate<'tcx>(analysis: ty::CrateAnalysis<'tcx>)
     let check_overflow = if let Some(v) = tcx.sess.opts.debugging_opts.force_overflow_checks {
         v
     } else {
-        !attr::contains_name(&krate.config, "ndebug")
+        tcx.sess.opts.debug_assertions
     };
 
     // Before we touch LLVM, make sure that multithreading is enabled.
index 34a03e5f0080dc258feb18dc780e1d21f552aefc..cd13b817c2b8c5fc6d7f2ac64257bff0b3b1db6d 100644 (file)
@@ -9,6 +9,7 @@
 // except according to those terms.
 
 // error-pattern:thread '<main>' panicked at 'arithmetic operation overflowed'
+// compile-flags: -C debug-assertions
 
 // (Work around constant-evaluation)
 fn value() -> u8 { 200 }
index b18d99cd232e85ed596e2e67ab827701c7b6b8b8..5d2f53962406c5427793320805a0b068ef75c40e 100644 (file)
@@ -9,6 +9,7 @@
 // except according to those terms.
 
 // error-pattern:thread '<main>' panicked at 'arithmetic operation overflowed'
+// compile-flags: -C debug-assertions
 
 // (Work around constant-evaluation)
 fn value() -> u8 { 200 }
index ee32291eca6b23062658ffc69fed609c08c9cddb..b089dccbaa52f0c54b18abcb4ec65377ccd0c383 100644 (file)
@@ -9,6 +9,7 @@
 // except according to those terms.
 
 // error-pattern:thread '<main>' panicked at 'arithmetic operation overflowed'
+// compile-flags: -C debug-assertions
 
 // (Work around constant-evaluation)
 fn value() -> u8 { 42 }
diff --git a/src/test/run-make/debug-assertions/Makefile b/src/test/run-make/debug-assertions/Makefile
new file mode 100644 (file)
index 0000000..7129756
--- /dev/null
@@ -0,0 +1,21 @@
+-include ../tools.mk
+
+all:
+       $(RUSTC) debug.rs -C debug-assertions=no
+       $(call RUN,debug) good
+       $(RUSTC) debug.rs -C opt-level=0
+       $(call RUN,debug) bad
+       $(RUSTC) debug.rs -C opt-level=1
+       $(call RUN,debug) good
+       $(RUSTC) debug.rs -C opt-level=2
+       $(call RUN,debug) good
+       $(RUSTC) debug.rs -C opt-level=3
+       $(call RUN,debug) good
+       $(RUSTC) debug.rs -O
+       $(call RUN,debug) good
+       $(RUSTC) debug.rs
+       $(call RUN,debug) bad
+       $(RUSTC) debug.rs -C debug-assertions=yes -O
+       $(call RUN,debug) bad
+       $(RUSTC) debug.rs -C debug-assertions=yes -C opt-level=1
+       $(call RUN,debug) bad
diff --git a/src/test/run-make/debug-assertions/debug.rs b/src/test/run-make/debug-assertions/debug.rs
new file mode 100644 (file)
index 0000000..a0ccc75
--- /dev/null
@@ -0,0 +1,42 @@
+// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+#![deny(warnings)]
+
+use std::env;
+use std::thread;
+
+fn main() {
+    let should_fail = env::args().nth(1) == Some("bad".to_string());
+
+    assert_eq!(thread::spawn(debug_assert_eq).join().is_err(), should_fail);
+    assert_eq!(thread::spawn(debug_assert).join().is_err(), should_fail);
+    assert_eq!(thread::spawn(overflow).join().is_err(), should_fail);
+}
+
+fn debug_assert_eq() {
+    let mut hit1 = false;
+    let mut hit2 = false;
+    debug_assert_eq!({ hit1 = true; 1 }, { hit2 = true; 2 });
+    assert!(!hit1);
+    assert!(!hit2);
+}
+
+fn debug_assert() {
+    let mut hit = false;
+    debug_assert!({ hit = true; false });
+    assert!(!hit);
+}
+
+fn overflow() {
+    fn add(a: u8, b: u8) -> u8 { a + b }
+
+    add(200u8, 200u8);
+}
index b5a5f57d07abda322171f642cf19c29b7a9eec5f..90142350772b82693c6b3b1da58c63513aa62358 100644 (file)
@@ -8,7 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-// compile-flags: --cfg ndebug
+// compile-flags: -C debug-assertions=no
 // exec-env:RUST_LOG=conditional-debug-macro-off=4
 
 #[macro_use]
index 262d9b21eb48bddd57815f6d246e26151037ef4a..dfc9272827066c517138209ab1851338af90e681 100644 (file)
@@ -8,7 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-// compile-flags:--cfg ndebug
+// compile-flags:-C debug-assertions=no
 // exec-env:RUST_LOG=logging-enabled-debug=debug
 
 #[macro_use]
index 8526dfe72da134a5c96e16fd7c1459d4db099c56..82a155b117301980bb74b123fa524a4cc74c37e7 100644 (file)
@@ -10,6 +10,7 @@
 
 // ignore-windows
 // exec-env:RUST_LOG=debug
+// compile-flags:-C debug-assertions=y
 
 #[macro_use]
 extern crate log;