# 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
/// 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
///
#[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
///
/// 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
///
/// ```
#[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
/// ```
#[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.
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!())
})
pub gc: bool,
pub optimize: OptLevel,
+ pub debug_assertions: bool,
pub debuginfo: DebugInfoLevel,
pub lint_opts: Vec<(String, lint::Level)>,
pub describe_lints: bool,
crate_name: None,
alt_std_name: None,
libs: Vec::new(),
- unstable_features: UnstableFeatures::Disallow
+ unstable_features: UnstableFeatures::Disallow,
+ debug_assertions: true,
}
}
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"),
}
};
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),
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,
}
}
};
+ 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() {
alt_std_name: None,
libs: libs,
unstable_features: get_unstable_features_setting(),
+ debug_assertions: debug_assertions,
}
}
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.
// 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 }
// 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 }
// 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 }
--- /dev/null
+-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
--- /dev/null
+// 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);
+}
// 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]
// 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]
// ignore-windows
// exec-env:RUST_LOG=debug
+// compile-flags:-C debug-assertions=y
#[macro_use]
extern crate log;