Skip to content

Commit

Permalink
auto merge of rust-lang#20776 : kmcallister/rust/macro-cleanup, r=ale…
Browse files Browse the repository at this point in the history
…xcrichton

r? @alexcrichton. This passes tests for me.
  • Loading branch information
bors committed Jan 9, 2015
2 parents 73a25f5 + a96a8b2 commit c133b21
Show file tree
Hide file tree
Showing 4 changed files with 15 additions and 183 deletions.
8 changes: 6 additions & 2 deletions src/doc/trpl/macros.md
Original file line number Diff line number Diff line change
Expand Up @@ -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`
Expand Down
9 changes: 7 additions & 2 deletions src/libcore/macros.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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)+)
}
);
}
Expand All @@ -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)) {
Expand Down Expand Up @@ -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)*); })
}
Expand Down Expand Up @@ -227,6 +230,7 @@ macro_rules! writeln {
/// }
/// ```
#[macro_export]
#[unstable = "relationship with panic is unclear"]
macro_rules! unreachable {
() => ({
panic!("internal error: entered unreachable code")
Expand All @@ -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"))
}
3 changes: 2 additions & 1 deletion src/libstd/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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]
Expand Down
178 changes: 0 additions & 178 deletions src/libstd/macros.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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.
///
Expand Down

0 comments on commit c133b21

Please sign in to comment.