about summary refs log tree commit diff
path: root/src/libcore
diff options
context:
space:
mode:
authorAlex Crichton <alex@alexcrichton.com>2015-01-05 19:01:17 -0800
committerAlex Crichton <alex@alexcrichton.com>2015-01-05 19:01:17 -0800
commit7975fd9cee750f26f9f6ef85b92a20b24ee24120 (patch)
tree0c36840cd8bf89ad1f662ed81d8e71c93e22c41e /src/libcore
parent563f6d8218cf15bf2590507c38ce4cbb734d6bba (diff)
parent78e841d8b10e05b5bbad4b02a9d5f0e9611100c7 (diff)
rollup merge of #20482: kmcallister/macro-reform
Conflicts:
	src/libflate/lib.rs
	src/libstd/lib.rs
	src/libstd/macros.rs
	src/libsyntax/feature_gate.rs
	src/libsyntax/parse/parser.rs
	src/libsyntax/show_span.rs
	src/test/auxiliary/macro_crate_test.rs
	src/test/compile-fail/lint-stability.rs
	src/test/run-pass/intrinsics-math.rs
	src/test/run-pass/tcp-connect-timeouts.rs
Diffstat (limited to 'src/libcore')
-rw-r--r--src/libcore/fmt/mod.rs5
-rw-r--r--src/libcore/lib.rs20
-rw-r--r--src/libcore/macros.rs201
-rw-r--r--src/libcore/num/float_macros.rs1
-rw-r--r--src/libcore/num/int_macros.rs1
-rw-r--r--src/libcore/num/uint_macros.rs1
-rw-r--r--src/libcore/result.rs4
-rw-r--r--src/libcore/str/mod.rs9
8 files changed, 205 insertions, 37 deletions
diff --git a/src/libcore/fmt/mod.rs b/src/libcore/fmt/mod.rs
index 7d92b707f98..951f5c29f00 100644
--- a/src/libcore/fmt/mod.rs
+++ b/src/libcore/fmt/mod.rs
@@ -20,12 +20,15 @@ use mem;
 use option::Option;
 use option::Option::{Some, None};
 use ops::{Deref, FnOnce};
-use result::Result::{Ok, Err};
+use result::Result::Ok;
 use result;
 use slice::SliceExt;
 use slice;
 use str::{self, StrExt, Utf8Error};
 
+// NOTE: for old macros; remove after the next snapshot
+#[cfg(stage0)] use result::Result::Err;
+
 pub use self::num::radix;
 pub use self::num::Radix;
 pub use self::num::RadixFmt;
diff --git a/src/libcore/lib.rs b/src/libcore/lib.rs
index d646245510d..aff0065c527 100644
--- a/src/libcore/lib.rs
+++ b/src/libcore/lib.rs
@@ -62,11 +62,24 @@
 #![feature(default_type_params, unboxed_closures, associated_types)]
 #![deny(missing_docs)]
 
+#[cfg_attr(stage0, macro_escape)]
+#[cfg_attr(not(stage0), macro_use)]
 mod macros;
 
-#[path = "num/float_macros.rs"] mod float_macros;
-#[path = "num/int_macros.rs"]   mod int_macros;
-#[path = "num/uint_macros.rs"]  mod uint_macros;
+#[path = "num/float_macros.rs"]
+#[cfg_attr(stage0, macro_escape)]
+#[cfg_attr(not(stage0), macro_use)]
+mod float_macros;
+
+#[path = "num/int_macros.rs"]
+#[cfg_attr(stage0, macro_escape)]
+#[cfg_attr(not(stage0), macro_use)]
+mod int_macros;
+
+#[path = "num/uint_macros.rs"]
+#[cfg_attr(stage0, macro_escape)]
+#[cfg_attr(not(stage0), macro_use)]
+mod uint_macros;
 
 #[path = "num/int.rs"]  pub mod int;
 #[path = "num/i8.rs"]   pub mod i8;
@@ -130,6 +143,7 @@ mod array;
 #[doc(hidden)]
 mod core {
     pub use panicking;
+    pub use fmt;
 }
 
 #[doc(hidden)]
diff --git a/src/libcore/macros.rs b/src/libcore/macros.rs
index e8fbd9d930f..a579f9db416 100644
--- a/src/libcore/macros.rs
+++ b/src/libcore/macros.rs
@@ -8,8 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![macro_escape]
-
 /// Entry point of task panic, for details, see std::macros
 #[macro_export]
 macro_rules! panic {
@@ -30,7 +28,26 @@ macro_rules! panic {
     });
 }
 
-/// Runtime assertion, for details see std::macros
+/// 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]
 macro_rules! assert {
     ($cond:expr) => (
@@ -38,61 +55,197 @@ macro_rules! assert {
             panic!(concat!("assertion failed: ", stringify!($cond)))
         }
     );
-    ($cond:expr, $($arg:tt)*) => (
+    ($cond:expr, $($arg:expr),+) => (
         if !$cond {
-            panic!($($arg)*)
+            panic!($($arg),+)
         }
     );
 }
 
-/// Runtime assertion for equality, for details see std::macros
+/// 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]
 macro_rules! assert_eq {
-    ($cond1:expr, $cond2:expr) => ({
-        let c1 = $cond1;
-        let c2 = $cond2;
-        if c1 != c2 || c2 != c1 {
-            panic!("expressions not equal, left: {}, right: {}", c1, c2);
+    ($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)
+                }
+            }
         }
     })
 }
 
-/// Runtime assertion for equality, only without `--cfg ndebug`
+/// 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]
+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 {
-    ($($a:tt)*) => ({
-        if cfg!(not(ndebug)) {
-            assert_eq!($($a)*);
-        }
-    })
+    ($($arg:tt)*) => (if cfg!(not(ndebug)) { assert_eq!($($arg)*); })
 }
 
-/// Runtime assertion, disableable at compile time with `--cfg ndebug`
+#[cfg(stage0)]
 #[macro_export]
-macro_rules! debug_assert {
-    ($($arg:tt)*) => (if cfg!(not(ndebug)) { assert!($($arg)*); })
+macro_rules! try {
+    ($e:expr) => (match $e { Ok(e) => e, Err(e) => return Err(e) })
 }
 
 /// Short circuiting evaluation on Err
+///
+/// `libstd` contains a more general `try!` macro that uses `FromError`.
+#[cfg(not(stage0))]
 #[macro_export]
 macro_rules! try {
-    ($e:expr) => (match $e { Ok(e) => e, Err(e) => return Err(e) })
+    ($e:expr) => ({
+        use $crate::result::Result::{Ok, Err};
+
+        match $e {
+            Ok(e) => e,
+            Err(e) => return Err(e),
+        }
+    })
 }
 
-/// Writing a formatted string into a writer
+/// Use the `format!` syntax to write data into a buffer of type `&mut Writer`.
+/// See `std::fmt` for more information.
+///
+/// # Example
+///
+/// ```
+/// # #![allow(unused_must_use)]
+///
+/// let mut w = Vec::new();
+/// write!(&mut w, "test");
+/// write!(&mut w, "formatted {}", "arguments");
+/// ```
 #[macro_export]
 macro_rules! write {
     ($dst:expr, $($arg:tt)*) => ((&mut *$dst).write_fmt(format_args!($($arg)*)))
 }
 
-/// Writing a formatted string plus a newline into a writer
+/// Equivalent to the `write!` macro, except that a newline is appended after
+/// the message is written.
 #[macro_export]
+#[stable]
 macro_rules! writeln {
     ($dst:expr, $fmt:expr $($arg:tt)*) => (
         write!($dst, concat!($fmt, "\n") $($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]
-macro_rules! unreachable { () => (panic!("unreachable code")) }
+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]
+macro_rules! unimplemented {
+    () => (panic!("not yet implemented"))
+}
diff --git a/src/libcore/num/float_macros.rs b/src/libcore/num/float_macros.rs
index 97de61d7e27..20300d29fa0 100644
--- a/src/libcore/num/float_macros.rs
+++ b/src/libcore/num/float_macros.rs
@@ -8,7 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![macro_escape]
 #![doc(hidden)]
 
 macro_rules! assert_approx_eq {
diff --git a/src/libcore/num/int_macros.rs b/src/libcore/num/int_macros.rs
index 522eab9180c..61cd8cbf7c1 100644
--- a/src/libcore/num/int_macros.rs
+++ b/src/libcore/num/int_macros.rs
@@ -8,7 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![macro_escape]
 #![doc(hidden)]
 
 macro_rules! int_module { ($T:ty, $bits:expr) => (
diff --git a/src/libcore/num/uint_macros.rs b/src/libcore/num/uint_macros.rs
index 82eca0d4659..535765840a0 100644
--- a/src/libcore/num/uint_macros.rs
+++ b/src/libcore/num/uint_macros.rs
@@ -8,7 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![macro_escape]
 #![doc(hidden)]
 
 macro_rules! uint_module { ($T:ty, $T_SIGNED:ty, $bits:expr) => (
diff --git a/src/libcore/result.rs b/src/libcore/result.rs
index 7293ed6455b..8e9bf5487e3 100644
--- a/src/libcore/result.rs
+++ b/src/libcore/result.rs
@@ -220,9 +220,9 @@
 //!
 //! ```
 //! # #![feature(macro_rules)]
-//! macro_rules! try(
+//! macro_rules! try {
 //!     ($e:expr) => (match $e { Ok(e) => e, Err(e) => return Err(e) })
-//! );
+//! }
 //! # fn main() { }
 //! ```
 //!
diff --git a/src/libcore/str/mod.rs b/src/libcore/str/mod.rs
index d9749899b22..a39787b8207 100644
--- a/src/libcore/str/mod.rs
+++ b/src/libcore/str/mod.rs
@@ -964,17 +964,18 @@ fn run_utf8_validation_iterator(iter: &mut slice::Iter<u8>)
         let old = *iter;
 
         // restore the iterator we had at the start of this codepoint.
-        macro_rules! err (() => { {
+        macro_rules! err { () => {{
             *iter = old;
             return Err(Utf8Error::InvalidByte(whole.len() - iter.as_slice().len()))
-        } });
-        macro_rules! next ( () => {
+        }}}
+
+        macro_rules! next { () => {
             match iter.next() {
                 Some(a) => *a,
                 // we needed data, but there was none: error!
                 None => return Err(Utf8Error::TooShort),
             }
-        });
+        }}
 
         let first = match iter.next() {
             Some(&b) => b,