]> git.lizzy.rs Git - rust.git/blob - src/libcore/macros.rs
rollup merge of #20482: kmcallister/macro-reform
[rust.git] / src / libcore / macros.rs
1 // Copyright 2014 The Rust Project Developers. See the COPYRIGHT
2 // file at the top-level directory of this distribution and at
3 // http://rust-lang.org/COPYRIGHT.
4 //
5 // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6 // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8 // option. This file may not be copied, modified, or distributed
9 // except according to those terms.
10
11 /// Entry point of task panic, for details, see std::macros
12 #[macro_export]
13 macro_rules! panic {
14     () => (
15         panic!("explicit panic")
16     );
17     ($msg:expr) => ({
18         static _MSG_FILE_LINE: (&'static str, &'static str, uint) = ($msg, file!(), line!());
19         ::core::panicking::panic(&_MSG_FILE_LINE)
20     });
21     ($fmt:expr, $($arg:tt)*) => ({
22         // The leading _'s are to avoid dead code warnings if this is
23         // used inside a dead function. Just `#[allow(dead_code)]` is
24         // insufficient, since the user may have
25         // `#[forbid(dead_code)]` and which cannot be overridden.
26         static _FILE_LINE: (&'static str, uint) = (file!(), line!());
27         ::core::panicking::panic_fmt(format_args!($fmt, $($arg)*), &_FILE_LINE)
28     });
29 }
30
31 /// Ensure that a boolean expression is `true` at runtime.
32 ///
33 /// This will invoke the `panic!` macro if the provided expression cannot be
34 /// evaluated to `true` at runtime.
35 ///
36 /// # Example
37 ///
38 /// ```
39 /// // the panic message for these assertions is the stringified value of the
40 /// // expression given.
41 /// assert!(true);
42 /// # fn some_computation() -> bool { true }
43 /// assert!(some_computation());
44 ///
45 /// // assert with a custom message
46 /// # let x = true;
47 /// assert!(x, "x wasn't true!");
48 /// # let a = 3i; let b = 27i;
49 /// assert!(a + b == 30, "a = {}, b = {}", a, b);
50 /// ```
51 #[macro_export]
52 macro_rules! assert {
53     ($cond:expr) => (
54         if !$cond {
55             panic!(concat!("assertion failed: ", stringify!($cond)))
56         }
57     );
58     ($cond:expr, $($arg:expr),+) => (
59         if !$cond {
60             panic!($($arg),+)
61         }
62     );
63 }
64
65 /// Asserts that two expressions are equal to each other, testing equality in
66 /// both directions.
67 ///
68 /// On panic, this macro will print the values of the expressions.
69 ///
70 /// # Example
71 ///
72 /// ```
73 /// let a = 3i;
74 /// let b = 1i + 2i;
75 /// assert_eq!(a, b);
76 /// ```
77 #[macro_export]
78 macro_rules! assert_eq {
79     ($left:expr , $right:expr) => ({
80         match (&($left), &($right)) {
81             (left_val, right_val) => {
82                 // check both directions of equality....
83                 if !((*left_val == *right_val) &&
84                      (*right_val == *left_val)) {
85                     panic!("assertion failed: `(left == right) && (right == left)` \
86                            (left: `{}`, right: `{}`)", *left_val, *right_val)
87                 }
88             }
89         }
90     })
91 }
92
93 /// Ensure that a boolean expression is `true` at runtime.
94 ///
95 /// This will invoke the `panic!` macro if the provided expression cannot be
96 /// evaluated to `true` at runtime.
97 ///
98 /// Unlike `assert!`, `debug_assert!` statements can be disabled by passing
99 /// `--cfg ndebug` to the compiler. This makes `debug_assert!` useful for
100 /// checks that are too expensive to be present in a release build but may be
101 /// helpful during development.
102 ///
103 /// # Example
104 ///
105 /// ```
106 /// // the panic message for these assertions is the stringified value of the
107 /// // expression given.
108 /// debug_assert!(true);
109 /// # fn some_expensive_computation() -> bool { true }
110 /// debug_assert!(some_expensive_computation());
111 ///
112 /// // assert with a custom message
113 /// # let x = true;
114 /// debug_assert!(x, "x wasn't true!");
115 /// # let a = 3i; let b = 27i;
116 /// debug_assert!(a + b == 30, "a = {}, b = {}", a, b);
117 /// ```
118 #[macro_export]
119 macro_rules! debug_assert {
120     ($($arg:tt)*) => (if cfg!(not(ndebug)) { assert!($($arg)*); })
121 }
122
123 /// Asserts that two expressions are equal to each other, testing equality in
124 /// both directions.
125 ///
126 /// On panic, this macro will print the values of the expressions.
127 ///
128 /// Unlike `assert_eq!`, `debug_assert_eq!` statements can be disabled by
129 /// passing `--cfg ndebug` to the compiler. This makes `debug_assert_eq!`
130 /// useful for checks that are too expensive to be present in a release build
131 /// but may be helpful during development.
132 ///
133 /// # Example
134 ///
135 /// ```
136 /// let a = 3i;
137 /// let b = 1i + 2i;
138 /// debug_assert_eq!(a, b);
139 /// ```
140 #[macro_export]
141 macro_rules! debug_assert_eq {
142     ($($arg:tt)*) => (if cfg!(not(ndebug)) { assert_eq!($($arg)*); })
143 }
144
145 #[cfg(stage0)]
146 #[macro_export]
147 macro_rules! try {
148     ($e:expr) => (match $e { Ok(e) => e, Err(e) => return Err(e) })
149 }
150
151 /// Short circuiting evaluation on Err
152 ///
153 /// `libstd` contains a more general `try!` macro that uses `FromError`.
154 #[cfg(not(stage0))]
155 #[macro_export]
156 macro_rules! try {
157     ($e:expr) => ({
158         use $crate::result::Result::{Ok, Err};
159
160         match $e {
161             Ok(e) => e,
162             Err(e) => return Err(e),
163         }
164     })
165 }
166
167 /// Use the `format!` syntax to write data into a buffer of type `&mut Writer`.
168 /// See `std::fmt` for more information.
169 ///
170 /// # Example
171 ///
172 /// ```
173 /// # #![allow(unused_must_use)]
174 ///
175 /// let mut w = Vec::new();
176 /// write!(&mut w, "test");
177 /// write!(&mut w, "formatted {}", "arguments");
178 /// ```
179 #[macro_export]
180 macro_rules! write {
181     ($dst:expr, $($arg:tt)*) => ((&mut *$dst).write_fmt(format_args!($($arg)*)))
182 }
183
184 /// Equivalent to the `write!` macro, except that a newline is appended after
185 /// the message is written.
186 #[macro_export]
187 #[stable]
188 macro_rules! writeln {
189     ($dst:expr, $fmt:expr $($arg:tt)*) => (
190         write!($dst, concat!($fmt, "\n") $($arg)*)
191     )
192 }
193
194 /// A utility macro for indicating unreachable code.
195 ///
196 /// This is useful any time that the compiler can't determine that some code is unreachable. For
197 /// example:
198 ///
199 /// * Match arms with guard conditions.
200 /// * Loops that dynamically terminate.
201 /// * Iterators that dynamically terminate.
202 ///
203 /// # Panics
204 ///
205 /// This will always panic.
206 ///
207 /// # Examples
208 ///
209 /// Match arms:
210 ///
211 /// ```rust
212 /// fn foo(x: Option<int>) {
213 ///     match x {
214 ///         Some(n) if n >= 0 => println!("Some(Non-negative)"),
215 ///         Some(n) if n <  0 => println!("Some(Negative)"),
216 ///         Some(_)           => unreachable!(), // compile error if commented out
217 ///         None              => println!("None")
218 ///     }
219 /// }
220 /// ```
221 ///
222 /// Iterators:
223 ///
224 /// ```rust
225 /// fn divide_by_three(x: u32) -> u32 { // one of the poorest implementations of x/3
226 ///     for i in std::iter::count(0_u32, 1) {
227 ///         if 3*i < i { panic!("u32 overflow"); }
228 ///         if x < 3*i { return i-1; }
229 ///     }
230 ///     unreachable!();
231 /// }
232 /// ```
233 #[macro_export]
234 macro_rules! unreachable {
235     () => ({
236         panic!("internal error: entered unreachable code")
237     });
238     ($msg:expr) => ({
239         unreachable!("{}", $msg)
240     });
241     ($fmt:expr, $($arg:tt)*) => ({
242         panic!(concat!("internal error: entered unreachable code: ", $fmt), $($arg)*)
243     });
244 }
245
246 /// A standardised placeholder for marking unfinished code. It panics with the
247 /// message `"not yet implemented"` when executed.
248 #[macro_export]
249 macro_rules! unimplemented {
250     () => (panic!("not yet implemented"))
251 }