Skip to content

Commit e97d4e6

Browse files
committed
auto merge of #13789 : sfackler/rust/debug-assert, r=pcwalton
I switched the `assert!` calls in `RefCell` over to `debug_assert!`. There are probably other instances that should be converted as well, but I couldn't think of any off the top of my head. RFC: 0015-assert
2 parents adcbf53 + ca84d79 commit e97d4e6

File tree

4 files changed

+65
-28
lines changed

4 files changed

+65
-28
lines changed

src/libcollections/hashmap.rs

+6-12
Original file line numberDiff line numberDiff line change
@@ -278,8 +278,7 @@ mod table {
278278
/// the appropriate types to pass on to most of the other functions in
279279
/// this module.
280280
pub fn peek(&self, index: uint) -> BucketState {
281-
// FIXME #12049
282-
if cfg!(test) { assert!(index < self.capacity) }
281+
debug_assert!(index < self.capacity);
283282

284283
let idx = index as int;
285284
let hash = unsafe { *self.hashes.offset(idx) };
@@ -306,8 +305,7 @@ mod table {
306305
let idx = index.idx;
307306

308307
unsafe {
309-
// FIXME #12049
310-
if cfg!(test) { assert!(*self.hashes.offset(idx) != EMPTY_BUCKET) }
308+
debug_assert!(*self.hashes.offset(idx) != EMPTY_BUCKET);
311309
(&'a *self.keys.offset(idx),
312310
&'a *self.vals.offset(idx))
313311
}
@@ -319,8 +317,7 @@ mod table {
319317
let idx = index.idx;
320318

321319
unsafe {
322-
// FIXME #12049
323-
if cfg!(test) { assert!(*self.hashes.offset(idx) != EMPTY_BUCKET) }
320+
debug_assert!(*self.hashes.offset(idx) != EMPTY_BUCKET);
324321
(&'a *self.keys.offset(idx),
325322
&'a mut *self.vals.offset(idx))
326323
}
@@ -332,8 +329,7 @@ mod table {
332329
let idx = index.idx;
333330

334331
unsafe {
335-
// FIXME #12049
336-
if cfg!(test) { assert!(*self.hashes.offset(idx) != EMPTY_BUCKET) }
332+
debug_assert!(*self.hashes.offset(idx) != EMPTY_BUCKET);
337333
(transmute(self.hashes.offset(idx)),
338334
&'a mut *self.keys.offset(idx),
339335
&'a mut *self.vals.offset(idx))
@@ -351,8 +347,7 @@ mod table {
351347
let idx = index.idx;
352348

353349
unsafe {
354-
// FIXME #12049
355-
if cfg!(test) { assert_eq!(*self.hashes.offset(idx), EMPTY_BUCKET) }
350+
debug_assert_eq!(*self.hashes.offset(idx), EMPTY_BUCKET);
356351
*self.hashes.offset(idx) = hash.inspect();
357352
move_val_init(&mut *self.keys.offset(idx), k);
358353
move_val_init(&mut *self.vals.offset(idx), v);
@@ -371,8 +366,7 @@ mod table {
371366
let idx = index.idx;
372367

373368
unsafe {
374-
// FIXME #12049
375-
if cfg!(test) { assert!(*self.hashes.offset(idx) != EMPTY_BUCKET) }
369+
debug_assert!(*self.hashes.offset(idx) != EMPTY_BUCKET);
376370

377371
*self.hashes.offset(idx) = EMPTY_BUCKET;
378372

src/libstd/cell.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,7 @@ impl<T> RefCell<T> {
9393

9494
/// Consumes the `RefCell`, returning the wrapped value.
9595
pub fn unwrap(self) -> T {
96-
assert!(self.borrow.get() == UNUSED);
96+
debug_assert!(self.borrow.get() == UNUSED);
9797
unsafe{self.value.unwrap()}
9898
}
9999

@@ -181,7 +181,7 @@ pub struct Ref<'b, T> {
181181
impl<'b, T> Drop for Ref<'b, T> {
182182
fn drop(&mut self) {
183183
let borrow = self.parent.borrow.get();
184-
assert!(borrow != WRITING && borrow != UNUSED);
184+
debug_assert!(borrow != WRITING && borrow != UNUSED);
185185
self.parent.borrow.set(borrow - 1);
186186
}
187187
}
@@ -202,7 +202,7 @@ pub struct RefMut<'b, T> {
202202
impl<'b, T> Drop for RefMut<'b, T> {
203203
fn drop(&mut self) {
204204
let borrow = self.parent.borrow.get();
205-
assert!(borrow == WRITING);
205+
debug_assert!(borrow == WRITING);
206206
self.parent.borrow.set(UNUSED);
207207
}
208208
}

src/libstd/macros.rs

+52-5
Original file line numberDiff line numberDiff line change
@@ -90,11 +90,6 @@ macro_rules! assert(
9090
fail!("assertion failed: {:s}", stringify!($cond))
9191
}
9292
);
93-
($cond:expr, $msg:expr) => (
94-
if !$cond {
95-
fail!($msg)
96-
}
97-
);
9893
($cond:expr, $($arg:expr),+) => (
9994
if !$cond {
10095
fail!($($arg),+)
@@ -130,6 +125,58 @@ macro_rules! assert_eq(
130125
})
131126
)
132127

128+
/// Ensure that a boolean expression is `true` at runtime.
129+
///
130+
/// This will invoke the `fail!` macro if the provided expression cannot be
131+
/// evaluated to `true` at runtime.
132+
///
133+
/// Unlike `assert!`, `debug_assert!` statements can be disabled by passing
134+
/// `--cfg ndebug` to the compiler. This makes `debug_assert!` useful for
135+
/// checks that are too expensive to be present in a release build but may be
136+
/// helpful during development.
137+
///
138+
/// # Example
139+
///
140+
/// ```
141+
/// // the failure message for these assertions is the stringified value of the
142+
/// // expression given.
143+
/// debug_assert!(true);
144+
/// # fn some_expensive_computation() -> bool { true }
145+
/// debug_assert!(some_expensive_computation());
146+
///
147+
/// // assert with a custom message
148+
/// # let x = true;
149+
/// debug_assert!(x, "x wasn't true!");
150+
/// # let a = 3; let b = 27;
151+
/// debug_assert!(a + b == 30, "a = {}, b = {}", a, b);
152+
/// ```
153+
#[macro_export]
154+
macro_rules! debug_assert(
155+
($($arg:tt)*) => (if cfg!(not(ndebug)) { assert!($($arg)*); })
156+
)
157+
158+
/// Asserts that two expressions are equal to each other, testing equality in
159+
/// both directions.
160+
///
161+
/// On failure, this macro will print the values of the expressions.
162+
///
163+
/// Unlike `assert_eq!`, `debug_assert_eq!` statements can be disabled by
164+
/// passing `--cfg ndebug` to the compiler. This makes `debug_assert_eq!`
165+
/// useful for checks that are too expensive to be present in a release build
166+
/// but may be helpful during development.
167+
///
168+
/// # Example
169+
///
170+
/// ```
171+
/// let a = 3;
172+
/// let b = 1 + 2;
173+
/// debug_assert_eq!(a, b);
174+
/// ```
175+
#[macro_export]
176+
macro_rules! debug_assert_eq(
177+
($($arg:tt)*) => (if cfg!(not(ndebug)) { assert_eq!($($arg)*); })
178+
)
179+
133180
/// A utility macro for indicating unreachable code. It will fail if
134181
/// executed. This is occasionally useful to put after loops that never
135182
/// terminate normally, but instead directly return from a function.

src/libstd/sync/arc.rs

+4-8
Original file line numberDiff line numberDiff line change
@@ -86,8 +86,7 @@ impl<T: Send> UnsafeArc<T> {
8686
#[inline]
8787
pub fn get(&self) -> *mut T {
8888
unsafe {
89-
// FIXME(#12049): this needs some sort of debug assertion
90-
if cfg!(test) { assert!((*self.data).count.load(Relaxed) > 0); }
89+
debug_assert!((*self.data).count.load(Relaxed) > 0);
9190
return (*self.data).data.get();
9291
}
9392
}
@@ -97,8 +96,7 @@ impl<T: Send> UnsafeArc<T> {
9796
#[inline]
9897
pub fn get_immut(&self) -> *T {
9998
unsafe {
100-
// FIXME(#12049): this needs some sort of debug assertion
101-
if cfg!(test) { assert!((*self.data).count.load(Relaxed) > 0); }
99+
debug_assert!((*self.data).count.load(Relaxed) > 0);
102100
return (*self.data).data.get() as *T;
103101
}
104102
}
@@ -125,8 +123,7 @@ impl<T: Send> Clone for UnsafeArc<T> {
125123
// synchronization.
126124
// [1]: (www.boost.org/doc/libs/1_55_0/doc/html/atomic/usage_examples.html)
127125
let old_count = (*self.data).count.fetch_add(1, Relaxed);
128-
// FIXME(#12049): this needs some sort of debug assertion
129-
if cfg!(test) { assert!(old_count >= 1); }
126+
debug_assert!(old_count >= 1);
130127
return UnsafeArc { data: self.data };
131128
}
132129
}
@@ -144,8 +141,7 @@ impl<T> Drop for UnsafeArc<T>{
144141
// Because `fetch_sub` is already atomic, we do not need to synchronize with other
145142
// threads unless we are going to delete the object.
146143
let old_count = (*self.data).count.fetch_sub(1, Release);
147-
// FIXME(#12049): this needs some sort of debug assertion
148-
if cfg!(test) { assert!(old_count >= 1); }
144+
debug_assert!(old_count >= 1);
149145
if old_count == 1 {
150146
// This fence is needed to prevent reordering of use of the data and deletion of
151147
// the data. Because it is marked `Release`, the decreasing of the reference count

0 commit comments

Comments
 (0)