]> git.lizzy.rs Git - rust.git/blob - src/libcore/macros.rs
Auto merge of #23678 - richo:check-flightcheck, 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 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, u32) = ($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, u32) = (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 /// # Examples
37 ///
38 /// ```
39 /// // the panic message for these assertions is the stringified value of the
40 /// // expression given.
41 /// assert!(true);
42 ///
43 /// fn some_computation() -> bool { true } // a very simple function
44 ///
45 /// assert!(some_computation());
46 ///
47 /// // assert with a custom message
48 /// let x = true;
49 /// assert!(x, "x wasn't true!");
50 ///
51 /// let a = 3; let b = 27;
52 /// assert!(a + b == 30, "a = {}, b = {}", a, b);
53 /// ```
54 #[macro_export]
55 #[stable(feature = "rust1", since = "1.0.0")]
56 macro_rules! assert {
57     ($cond:expr) => (
58         if !$cond {
59             panic!(concat!("assertion failed: ", stringify!($cond)))
60         }
61     );
62     ($cond:expr, $($arg:tt)+) => (
63         if !$cond {
64             panic!($($arg)+)
65         }
66     );
67 }
68
69 /// Asserts that two expressions are equal to each other, testing equality in
70 /// both directions.
71 ///
72 /// On panic, this macro will print the values of the expressions.
73 ///
74 /// # Examples
75 ///
76 /// ```
77 /// let a = 3;
78 /// let b = 1 + 2;
79 /// assert_eq!(a, b);
80 /// ```
81 #[macro_export]
82 #[stable(feature = "rust1", since = "1.0.0")]
83 macro_rules! assert_eq {
84     ($left:expr , $right:expr) => ({
85         match (&($left), &($right)) {
86             (left_val, right_val) => {
87                 // check both directions of equality....
88                 if !((*left_val == *right_val) &&
89                      (*right_val == *left_val)) {
90                     panic!("assertion failed: `(left == right) && (right == left)` \
91                            (left: `{:?}`, right: `{:?}`)", *left_val, *right_val)
92                 }
93             }
94         }
95     })
96 }
97
98 /// Ensure that a boolean expression is `true` at runtime.
99 ///
100 /// This will invoke the `panic!` macro if the provided expression cannot be
101 /// evaluated to `true` at runtime.
102 ///
103 /// Unlike `assert!`, `debug_assert!` statements are only enabled in non
104 /// optimized builds by default. An optimized build will omit all
105 /// `debug_assert!` statements unless `-C debug-assertions` is passed to the
106 /// compiler. This makes `debug_assert!` useful for checks that are too
107 /// expensive to be present in a release build but may be helpful during
108 /// development.
109 ///
110 /// # Examples
111 ///
112 /// ```
113 /// // the panic message for these assertions is the stringified value of the
114 /// // expression given.
115 /// debug_assert!(true);
116 ///
117 /// fn some_expensive_computation() -> bool { true } // a very simple function
118 /// debug_assert!(some_expensive_computation());
119 ///
120 /// // assert with a custom message
121 /// let x = true;
122 /// debug_assert!(x, "x wasn't true!");
123 ///
124 /// let a = 3; let b = 27;
125 /// debug_assert!(a + b == 30, "a = {}, b = {}", a, b);
126 /// ```
127 #[macro_export]
128 #[stable(feature = "rust1", since = "1.0.0")]
129 macro_rules! debug_assert {
130     ($($arg:tt)*) => (if cfg!(debug_assertions) { assert!($($arg)*); })
131 }
132
133 /// Asserts that two expressions are equal to each other, testing equality in
134 /// both directions.
135 ///
136 /// On panic, this macro will print the values of the expressions.
137 ///
138 /// Unlike `assert_eq!`, `debug_assert_eq!` statements are only enabled in non
139 /// optimized builds by default. An optimized build will omit all
140 /// `debug_assert_eq!` statements unless `-C debug-assertions` is passed to the
141 /// compiler. This makes `debug_assert_eq!` useful for checks that are too
142 /// expensive to be present in a release build but may be helpful during
143 /// development.
144 ///
145 /// # Examples
146 ///
147 /// ```
148 /// let a = 3;
149 /// let b = 1 + 2;
150 /// debug_assert_eq!(a, b);
151 /// ```
152 #[macro_export]
153 macro_rules! debug_assert_eq {
154     ($($arg:tt)*) => (if cfg!(debug_assertions) { assert_eq!($($arg)*); })
155 }
156
157 /// Short circuiting evaluation on Err
158 ///
159 /// `libstd` contains a more general `try!` macro that uses `FromError`.
160 #[macro_export]
161 macro_rules! try {
162     ($e:expr) => ({
163         use $crate::result::Result::{Ok, Err};
164
165         match $e {
166             Ok(e) => e,
167             Err(e) => return Err(e),
168         }
169     })
170 }
171
172 /// Use the `format!` syntax to write data into a buffer of type `&mut Writer`.
173 /// See `std::fmt` for more information.
174 ///
175 /// # Examples
176 ///
177 /// ```
178 /// # #![allow(unused_must_use)]
179 /// use std::io::Write;
180 ///
181 /// let mut w = Vec::new();
182 /// write!(&mut w, "test");
183 /// write!(&mut w, "formatted {}", "arguments");
184 /// ```
185 #[macro_export]
186 macro_rules! write {
187     ($dst:expr, $($arg:tt)*) => ((&mut *$dst).write_fmt(format_args!($($arg)*)))
188 }
189
190 /// Equivalent to the `write!` macro, except that a newline is appended after
191 /// the message is written.
192 #[macro_export]
193 #[stable(feature = "rust1", since = "1.0.0")]
194 macro_rules! writeln {
195     ($dst:expr, $fmt:expr) => (
196         write!($dst, concat!($fmt, "\n"))
197     );
198     ($dst:expr, $fmt:expr, $($arg:tt)*) => (
199         write!($dst, concat!($fmt, "\n"), $($arg)*)
200     );
201 }
202
203 /// A utility macro for indicating unreachable code.
204 ///
205 /// This is useful any time that the compiler can't determine that some code is unreachable. For
206 /// example:
207 ///
208 /// * Match arms with guard conditions.
209 /// * Loops that dynamically terminate.
210 /// * Iterators that dynamically terminate.
211 ///
212 /// # Panics
213 ///
214 /// This will always panic.
215 ///
216 /// # Examples
217 ///
218 /// Match arms:
219 ///
220 /// ```
221 /// fn foo(x: Option<i32>) {
222 ///     match x {
223 ///         Some(n) if n >= 0 => println!("Some(Non-negative)"),
224 ///         Some(n) if n <  0 => println!("Some(Negative)"),
225 ///         Some(_)           => unreachable!(), // compile error if commented out
226 ///         None              => println!("None")
227 ///     }
228 /// }
229 /// ```
230 ///
231 /// Iterators:
232 ///
233 /// ```
234 /// # #![feature(core)]
235 /// fn divide_by_three(x: u32) -> u32 { // one of the poorest implementations of x/3
236 ///     for i in std::iter::count(0, 1) {
237 ///         if 3*i < i { panic!("u32 overflow"); }
238 ///         if x < 3*i { return i-1; }
239 ///     }
240 ///     unreachable!();
241 /// }
242 /// ```
243 #[macro_export]
244 #[unstable(feature = "core",
245            reason = "relationship with panic is unclear")]
246 macro_rules! unreachable {
247     () => ({
248         panic!("internal error: entered unreachable code")
249     });
250     ($msg:expr) => ({
251         unreachable!("{}", $msg)
252     });
253     ($fmt:expr, $($arg:tt)*) => ({
254         panic!(concat!("internal error: entered unreachable code: ", $fmt), $($arg)*)
255     });
256 }
257
258 /// A standardised placeholder for marking unfinished code. It panics with the
259 /// message `"not yet implemented"` when executed.
260 #[macro_export]
261 #[unstable(feature = "core",
262            reason = "relationship with panic is unclear")]
263 macro_rules! unimplemented {
264     () => (panic!("not yet implemented"))
265 }