]> git.lizzy.rs Git - rust.git/blob - src/libcore/macros.rs
Auto merge of #29513 - apasel422:issue-23217, r=alexcrichton
[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 thread panic, for details, see std::macros
12 #[macro_export]
13 #[allow_internal_unstable]
14 macro_rules! panic {
15     () => (
16         panic!("explicit panic")
17     );
18     ($msg:expr) => ({
19         static _MSG_FILE_LINE: (&'static str, &'static str, u32) = ($msg, file!(), line!());
20         $crate::panicking::panic(&_MSG_FILE_LINE)
21     });
22     ($fmt:expr, $($arg:tt)*) => ({
23         // The leading _'s are to avoid dead code warnings if this is
24         // used inside a dead function. Just `#[allow(dead_code)]` is
25         // insufficient, since the user may have
26         // `#[forbid(dead_code)]` and which cannot be overridden.
27         static _FILE_LINE: (&'static str, u32) = (file!(), line!());
28         $crate::panicking::panic_fmt(format_args!($fmt, $($arg)*), &_FILE_LINE)
29     });
30 }
31
32 /// Ensure that a boolean expression is `true` at runtime.
33 ///
34 /// This will invoke the `panic!` macro if the provided expression cannot be
35 /// evaluated to `true` at runtime.
36 ///
37 /// This macro has a second version, where a custom panic message can be provided.
38 ///
39 /// # Examples
40 ///
41 /// ```
42 /// // the panic message for these assertions is the stringified value of the
43 /// // expression given.
44 /// assert!(true);
45 ///
46 /// fn some_computation() -> bool { true } // a very simple function
47 ///
48 /// assert!(some_computation());
49 ///
50 /// // assert with a custom message
51 /// let x = true;
52 /// assert!(x, "x wasn't true!");
53 ///
54 /// let a = 3; let b = 27;
55 /// assert!(a + b == 30, "a = {}, b = {}", a, b);
56 /// ```
57 #[macro_export]
58 #[stable(feature = "rust1", since = "1.0.0")]
59 macro_rules! assert {
60     ($cond:expr) => (
61         if !$cond {
62             panic!(concat!("assertion failed: ", stringify!($cond)))
63         }
64     );
65     ($cond:expr, $($arg:tt)+) => (
66         if !$cond {
67             panic!($($arg)+)
68         }
69     );
70 }
71
72 /// Asserts that two expressions are equal to each other.
73 ///
74 /// On panic, this macro will print the values of the expressions with their
75 /// debug representations.
76 ///
77 /// # Examples
78 ///
79 /// ```
80 /// let a = 3;
81 /// let b = 1 + 2;
82 /// assert_eq!(a, b);
83 /// ```
84 #[macro_export]
85 #[stable(feature = "rust1", since = "1.0.0")]
86 macro_rules! assert_eq {
87     ($left:expr , $right:expr) => ({
88         match (&($left), &($right)) {
89             (left_val, right_val) => {
90                 if !(*left_val == *right_val) {
91                     panic!("assertion failed: `(left == right)` \
92                            (left: `{:?}`, right: `{:?}`)", *left_val, *right_val)
93                 }
94             }
95         }
96     })
97 }
98
99 /// Ensure that a boolean expression is `true` at runtime.
100 ///
101 /// This will invoke the `panic!` macro if the provided expression cannot be
102 /// evaluated to `true` at runtime.
103 ///
104 /// Like `assert!`, this macro also has a second version, where a custom panic
105 /// message can be provided.
106 ///
107 /// Unlike `assert!`, `debug_assert!` statements are only enabled in non
108 /// optimized builds by default. An optimized build will omit all
109 /// `debug_assert!` statements unless `-C debug-assertions` is passed to the
110 /// compiler. This makes `debug_assert!` useful for checks that are too
111 /// expensive to be present in a release build but may be helpful during
112 /// development.
113 ///
114 /// # Examples
115 ///
116 /// ```
117 /// // the panic message for these assertions is the stringified value of the
118 /// // expression given.
119 /// debug_assert!(true);
120 ///
121 /// fn some_expensive_computation() -> bool { true } // a very simple function
122 /// debug_assert!(some_expensive_computation());
123 ///
124 /// // assert with a custom message
125 /// let x = true;
126 /// debug_assert!(x, "x wasn't true!");
127 ///
128 /// let a = 3; let b = 27;
129 /// debug_assert!(a + b == 30, "a = {}, b = {}", a, b);
130 /// ```
131 #[macro_export]
132 #[stable(feature = "rust1", since = "1.0.0")]
133 macro_rules! debug_assert {
134     ($($arg:tt)*) => (if cfg!(debug_assertions) { assert!($($arg)*); })
135 }
136
137 /// Asserts that two expressions are equal to each other, testing equality in
138 /// both directions.
139 ///
140 /// On panic, this macro will print the values of the expressions.
141 ///
142 /// Unlike `assert_eq!`, `debug_assert_eq!` statements are only enabled in non
143 /// optimized builds by default. An optimized build will omit all
144 /// `debug_assert_eq!` statements unless `-C debug-assertions` is passed to the
145 /// compiler. This makes `debug_assert_eq!` useful for checks that are too
146 /// expensive to be present in a release build but may be helpful during
147 /// development.
148 ///
149 /// # Examples
150 ///
151 /// ```
152 /// let a = 3;
153 /// let b = 1 + 2;
154 /// debug_assert_eq!(a, b);
155 /// ```
156 #[macro_export]
157 macro_rules! debug_assert_eq {
158     ($($arg:tt)*) => (if cfg!(debug_assertions) { assert_eq!($($arg)*); })
159 }
160
161 /// Short circuiting evaluation on Err
162 ///
163 /// `libstd` contains a more general `try!` macro that uses `From<E>`.
164 #[macro_export]
165 macro_rules! try {
166     ($e:expr) => ({
167         use $crate::result::Result::{Ok, Err};
168
169         match $e {
170             Ok(e) => e,
171             Err(e) => return Err(e),
172         }
173     })
174 }
175
176 /// Use the `format!` syntax to write data into a buffer.
177 ///
178 /// This macro is typically used with a buffer of `&mut `[`Write`][write].
179 ///
180 /// See [`std::fmt`][fmt] for more information on format syntax.
181 ///
182 /// [fmt]: fmt/index.html
183 /// [write]: io/trait.Write.html
184 ///
185 /// # Examples
186 ///
187 /// ```
188 /// use std::io::Write;
189 ///
190 /// let mut w = Vec::new();
191 /// write!(&mut w, "test").unwrap();
192 /// write!(&mut w, "formatted {}", "arguments").unwrap();
193 ///
194 /// assert_eq!(w, b"testformatted arguments");
195 /// ```
196 #[macro_export]
197 macro_rules! write {
198     ($dst:expr, $($arg:tt)*) => ($dst.write_fmt(format_args!($($arg)*)))
199 }
200
201 /// Use the `format!` syntax to write data into a buffer, appending a newline.
202 ///
203 /// This macro is typically used with a buffer of `&mut `[`Write`][write].
204 ///
205 /// See [`std::fmt`][fmt] for more information on format syntax.
206 ///
207 /// [fmt]: fmt/index.html
208 /// [write]: io/trait.Write.html
209 ///
210 /// # Examples
211 ///
212 /// ```
213 /// use std::io::Write;
214 ///
215 /// let mut w = Vec::new();
216 /// writeln!(&mut w, "test").unwrap();
217 /// writeln!(&mut w, "formatted {}", "arguments").unwrap();
218 ///
219 /// assert_eq!(&w[..], "test\nformatted arguments\n".as_bytes());
220 /// ```
221 #[macro_export]
222 #[stable(feature = "rust1", since = "1.0.0")]
223 macro_rules! writeln {
224     ($dst:expr, $fmt:expr) => (
225         write!($dst, concat!($fmt, "\n"))
226     );
227     ($dst:expr, $fmt:expr, $($arg:tt)*) => (
228         write!($dst, concat!($fmt, "\n"), $($arg)*)
229     );
230 }
231
232 /// A utility macro for indicating unreachable code.
233 ///
234 /// This is useful any time that the compiler can't determine that some code is unreachable. For
235 /// example:
236 ///
237 /// * Match arms with guard conditions.
238 /// * Loops that dynamically terminate.
239 /// * Iterators that dynamically terminate.
240 ///
241 /// # Panics
242 ///
243 /// This will always panic.
244 ///
245 /// # Examples
246 ///
247 /// Match arms:
248 ///
249 /// ```
250 /// fn foo(x: Option<i32>) {
251 ///     match x {
252 ///         Some(n) if n >= 0 => println!("Some(Non-negative)"),
253 ///         Some(n) if n <  0 => println!("Some(Negative)"),
254 ///         Some(_)           => unreachable!(), // compile error if commented out
255 ///         None              => println!("None")
256 ///     }
257 /// }
258 /// ```
259 ///
260 /// Iterators:
261 ///
262 /// ```
263 /// fn divide_by_three(x: u32) -> u32 { // one of the poorest implementations of x/3
264 ///     for i in 0.. {
265 ///         if 3*i < i { panic!("u32 overflow"); }
266 ///         if x < 3*i { return i-1; }
267 ///     }
268 ///     unreachable!();
269 /// }
270 /// ```
271 #[macro_export]
272 #[unstable(feature = "core",
273            reason = "relationship with panic is unclear",
274            issue = "27701")]
275 macro_rules! unreachable {
276     () => ({
277         panic!("internal error: entered unreachable code")
278     });
279     ($msg:expr) => ({
280         unreachable!("{}", $msg)
281     });
282     ($fmt:expr, $($arg:tt)*) => ({
283         panic!(concat!("internal error: entered unreachable code: ", $fmt), $($arg)*)
284     });
285 }
286
287 /// A standardized placeholder for marking unfinished code. It panics with the
288 /// message `"not yet implemented"` when executed.
289 ///
290 /// This can be useful if you are prototyping and are just looking to have your
291 /// code typecheck, or if you're implementing a trait that requires multiple
292 /// methods, and you're only planning on using one of them.
293 ///
294 /// # Examples
295 ///
296 /// Here's an example of some in-progress code. We have a trait `Foo`:
297 ///
298 /// ```
299 /// trait Foo {
300 ///     fn bar(&self);
301 ///     fn baz(&self);
302 /// }
303 /// ```
304 ///
305 /// We want to implement `Foo` on one of our types, but we also want to work on
306 /// just `bar()` first. In order for our code to compile, we need to implement
307 /// `baz()`, so we can use `unimplemented!`:
308 ///
309 /// ```
310 /// # trait Foo {
311 /// #     fn foo(&self);
312 /// #     fn bar(&self);
313 /// # }
314 /// struct MyStruct;
315 ///
316 /// impl Foo for MyStruct {
317 ///     fn foo(&self) {
318 ///         // implementation goes here
319 ///     }
320 ///
321 ///     fn bar(&self) {
322 ///         // let's not worry about implementing bar() for now
323 ///         unimplemented!();
324 ///     }
325 /// }
326 ///
327 /// fn main() {
328 ///     let s = MyStruct;
329 ///     s.foo();
330 ///
331 ///     // we aren't even using bar() yet, so this is fine.
332 /// }
333 /// ```
334 #[macro_export]
335 #[unstable(feature = "core",
336            reason = "relationship with panic is unclear",
337            issue = "27701")]
338 macro_rules! unimplemented {
339     () => (panic!("not yet implemented"))
340 }