auto merge of #20776 : kmcallister/rust/macro-cleanup, r=alexcrichton
r? @alexcrichton. This passes tests for me.
This commit is contained in:
commit
c133b2110b
@ -440,14 +440,18 @@ to print "I am never printed" and to run forever.
|
||||
|
||||
# Scoping and macro import/export
|
||||
|
||||
Macros occupy a single global namespace. The interaction with Rust's system of
|
||||
modules and crates is somewhat complex.
|
||||
Macros are expanded at an early stage in compilation, before name resolution.
|
||||
One downside is that scoping works differently for macros, compared to other
|
||||
constructs in the language.
|
||||
|
||||
Definition and expansion of macros both happen in a single depth-first,
|
||||
lexical-order traversal of a crate's source. So a macro defined at module scope
|
||||
is visible to any subsequent code in the same module, which includes the body
|
||||
of any subsequent child `mod` items.
|
||||
|
||||
A macro defined within the body of a single `fn`, or anywhere else not at
|
||||
module scope, is visible only within that item.
|
||||
|
||||
If a module has the `macro_use` attribute, its macros are also visible in its
|
||||
parent module after the child's `mod` item. If the parent also has `macro_use`
|
||||
then the macros will be visible in the grandparent after the parent's `mod`
|
||||
|
@ -49,15 +49,16 @@ macro_rules! panic {
|
||||
/// assert!(a + b == 30, "a = {}, b = {}", a, b);
|
||||
/// ```
|
||||
#[macro_export]
|
||||
#[stable]
|
||||
macro_rules! assert {
|
||||
($cond:expr) => (
|
||||
if !$cond {
|
||||
panic!(concat!("assertion failed: ", stringify!($cond)))
|
||||
}
|
||||
);
|
||||
($cond:expr, $($arg:expr),+) => (
|
||||
($cond:expr, $($arg:tt)+) => (
|
||||
if !$cond {
|
||||
panic!($($arg),+)
|
||||
panic!($($arg)+)
|
||||
}
|
||||
);
|
||||
}
|
||||
@ -75,6 +76,7 @@ macro_rules! assert {
|
||||
/// assert_eq!(a, b);
|
||||
/// ```
|
||||
#[macro_export]
|
||||
#[stable]
|
||||
macro_rules! assert_eq {
|
||||
($left:expr , $right:expr) => ({
|
||||
match (&($left), &($right)) {
|
||||
@ -116,6 +118,7 @@ macro_rules! assert_eq {
|
||||
/// debug_assert!(a + b == 30, "a = {}, b = {}", a, b);
|
||||
/// ```
|
||||
#[macro_export]
|
||||
#[stable]
|
||||
macro_rules! debug_assert {
|
||||
($($arg:tt)*) => (if cfg!(not(ndebug)) { assert!($($arg)*); })
|
||||
}
|
||||
@ -227,6 +230,7 @@ macro_rules! writeln {
|
||||
/// }
|
||||
/// ```
|
||||
#[macro_export]
|
||||
#[unstable = "relationship with panic is unclear"]
|
||||
macro_rules! unreachable {
|
||||
() => ({
|
||||
panic!("internal error: entered unreachable code")
|
||||
@ -242,6 +246,7 @@ macro_rules! unreachable {
|
||||
/// A standardised placeholder for marking unfinished code. It panics with the
|
||||
/// message `"not yet implemented"` when executed.
|
||||
#[macro_export]
|
||||
#[unstable = "relationship with panic is unclear"]
|
||||
macro_rules! unimplemented {
|
||||
() => (panic!("not yet implemented"))
|
||||
}
|
||||
|
@ -122,7 +122,8 @@
|
||||
extern crate log;
|
||||
|
||||
#[macro_use]
|
||||
#[macro_reexport(write, writeln)]
|
||||
#[macro_reexport(assert, assert_eq, debug_assert, debug_assert_eq,
|
||||
unreachable, unimplemented, write, writeln)]
|
||||
extern crate core;
|
||||
|
||||
#[macro_use]
|
||||
|
@ -60,184 +60,6 @@ macro_rules! panic {
|
||||
});
|
||||
}
|
||||
|
||||
/// Ensure that a boolean expression is `true` at runtime.
|
||||
///
|
||||
/// This will invoke the `panic!` macro if the provided expression cannot be
|
||||
/// evaluated to `true` at runtime.
|
||||
///
|
||||
/// # Example
|
||||
///
|
||||
/// ```
|
||||
/// // the panic message for these assertions is the stringified value of the
|
||||
/// // expression given.
|
||||
/// assert!(true);
|
||||
/// # fn some_computation() -> bool { true }
|
||||
/// assert!(some_computation());
|
||||
///
|
||||
/// // assert with a custom message
|
||||
/// # let x = true;
|
||||
/// assert!(x, "x wasn't true!");
|
||||
/// # let a = 3i; let b = 27i;
|
||||
/// assert!(a + b == 30, "a = {}, b = {}", a, b);
|
||||
/// ```
|
||||
#[macro_export]
|
||||
#[stable]
|
||||
macro_rules! assert {
|
||||
($cond:expr) => (
|
||||
if !$cond {
|
||||
panic!(concat!("assertion failed: ", stringify!($cond)))
|
||||
}
|
||||
);
|
||||
($cond:expr, $($arg:tt)+) => (
|
||||
if !$cond {
|
||||
panic!($($arg)+)
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
/// Asserts that two expressions are equal to each other, testing equality in
|
||||
/// both directions.
|
||||
///
|
||||
/// On panic, this macro will print the values of the expressions.
|
||||
///
|
||||
/// # Example
|
||||
///
|
||||
/// ```
|
||||
/// let a = 3i;
|
||||
/// let b = 1i + 2i;
|
||||
/// assert_eq!(a, b);
|
||||
/// ```
|
||||
#[macro_export]
|
||||
#[stable]
|
||||
macro_rules! assert_eq {
|
||||
($left:expr , $right:expr) => ({
|
||||
match (&($left), &($right)) {
|
||||
(left_val, right_val) => {
|
||||
// check both directions of equality....
|
||||
if !((*left_val == *right_val) &&
|
||||
(*right_val == *left_val)) {
|
||||
panic!("assertion failed: `(left == right) && (right == left)` \
|
||||
(left: `{:?}`, right: `{:?}`)", *left_val, *right_val)
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
/// Ensure that a boolean expression is `true` at runtime.
|
||||
///
|
||||
/// 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.
|
||||
///
|
||||
/// # Example
|
||||
///
|
||||
/// ```
|
||||
/// // the panic message for these assertions is the stringified value of the
|
||||
/// // expression given.
|
||||
/// debug_assert!(true);
|
||||
/// # fn some_expensive_computation() -> bool { true }
|
||||
/// debug_assert!(some_expensive_computation());
|
||||
///
|
||||
/// // assert with a custom message
|
||||
/// # let x = true;
|
||||
/// debug_assert!(x, "x wasn't true!");
|
||||
/// # let a = 3i; let b = 27i;
|
||||
/// debug_assert!(a + b == 30, "a = {}, b = {}", a, b);
|
||||
/// ```
|
||||
#[macro_export]
|
||||
#[stable]
|
||||
macro_rules! debug_assert {
|
||||
($($arg:tt)*) => (if cfg!(not(ndebug)) { assert!($($arg)*); })
|
||||
}
|
||||
|
||||
/// Asserts that two expressions are equal to each other, testing equality in
|
||||
/// both directions.
|
||||
///
|
||||
/// 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.
|
||||
///
|
||||
/// # Example
|
||||
///
|
||||
/// ```
|
||||
/// let a = 3i;
|
||||
/// let b = 1i + 2i;
|
||||
/// debug_assert_eq!(a, b);
|
||||
/// ```
|
||||
#[macro_export]
|
||||
macro_rules! debug_assert_eq {
|
||||
($($arg:tt)*) => (if cfg!(not(ndebug)) { assert_eq!($($arg)*); })
|
||||
}
|
||||
|
||||
/// A utility macro for indicating unreachable code.
|
||||
///
|
||||
/// This is useful any time that the compiler can't determine that some code is unreachable. For
|
||||
/// example:
|
||||
///
|
||||
/// * Match arms with guard conditions.
|
||||
/// * Loops that dynamically terminate.
|
||||
/// * Iterators that dynamically terminate.
|
||||
///
|
||||
/// # Panics
|
||||
///
|
||||
/// This will always panic.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// Match arms:
|
||||
///
|
||||
/// ```rust
|
||||
/// fn foo(x: Option<int>) {
|
||||
/// match x {
|
||||
/// Some(n) if n >= 0 => println!("Some(Non-negative)"),
|
||||
/// Some(n) if n < 0 => println!("Some(Negative)"),
|
||||
/// Some(_) => unreachable!(), // compile error if commented out
|
||||
/// None => println!("None")
|
||||
/// }
|
||||
/// }
|
||||
/// ```
|
||||
///
|
||||
/// Iterators:
|
||||
///
|
||||
/// ```rust
|
||||
/// fn divide_by_three(x: u32) -> u32 { // one of the poorest implementations of x/3
|
||||
/// for i in std::iter::count(0_u32, 1) {
|
||||
/// if 3*i < i { panic!("u32 overflow"); }
|
||||
/// if x < 3*i { return i-1; }
|
||||
/// }
|
||||
/// unreachable!();
|
||||
/// }
|
||||
/// ```
|
||||
#[macro_export]
|
||||
#[unstable = "relationship with panic is unclear"]
|
||||
macro_rules! unreachable {
|
||||
() => ({
|
||||
panic!("internal error: entered unreachable code")
|
||||
});
|
||||
($msg:expr) => ({
|
||||
unreachable!("{}", $msg)
|
||||
});
|
||||
($fmt:expr, $($arg:tt)*) => ({
|
||||
panic!(concat!("internal error: entered unreachable code: ", $fmt), $($arg)*)
|
||||
});
|
||||
}
|
||||
|
||||
/// A standardised placeholder for marking unfinished code. It panics with the
|
||||
/// message `"not yet implemented"` when executed.
|
||||
#[macro_export]
|
||||
#[unstable = "relationship with panic is unclear"]
|
||||
macro_rules! unimplemented {
|
||||
() => (panic!("not yet implemented"))
|
||||
}
|
||||
|
||||
/// Use the syntax described in `std::fmt` to create a value of type `String`.
|
||||
/// See `std::fmt` for more information.
|
||||
///
|
||||
|
Loading…
Reference in New Issue
Block a user