(index<- )        ./libstd/macros.rs

    git branch:    * master           5200215 auto merge of #14035 : alexcrichton/rust/experimental, r=huonw
    modified:    Fri May  9 13:02:28 2014
   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  //! Standard library macros
  12  //!
  13  //! This modules contains a set of macros which are exported from the standard
  14  //! library. Each macro is available for use when linking against the standard
  15  //! library.
  16  
  17  #![macro_escape]
  18  
  19  /// The entry point for failure of rust tasks.
  20  ///
  21  /// This macro is used to inject failure into a rust task, causing the task to
  22  /// unwind and fail entirely. Each task's failure can be reaped as the
  23  /// `Box<Any>` type, and the single-argument form of the `fail!` macro will be
  24  /// the value which is transmitted.
  25  ///
  26  /// The multi-argument form of this macro fails with a string and has the
  27  /// `format!` syntax for building a string.
  28  ///
  29  /// # Example
  30  ///
  31  /// ```should_fail
  32  /// # #![allow(unreachable_code)]
  33  /// fail!();
  34  /// fail!("this is a terrible mistake!");
  35  /// fail!(4); // fail with the value of 4 to be collected elsewhere
  36  /// fail!("this is a {} {message}", "fancy", message = "message");
  37  /// ```
  38  #[macro_export]
  39  macro_rules! fail(
  40      () => (
  41          fail!("explicit failure")
  42      );
  43      ($msg:expr) => (
  44          ::std::rt::begin_unwind($msg, file!(), line!())
  45      );
  46      ($fmt:expr, $($arg:tt)*) => ({
  47          // a closure can't have return type !, so we need a full
  48          // function to pass to format_args!, *and* we need the
  49          // file and line numbers right here; so an inner bare fn
  50          // is our only choice.
  51          //
  52          // LLVM doesn't tend to inline this, presumably because begin_unwind_fmt
  53          // is #[cold] and #[inline(never)] and because this is flagged as cold
  54          // as returning !. We really do want this to be inlined, however,
  55          // because it's just a tiny wrapper. Small wins (156K to 149K in size)
  56          // were seen when forcing this to be inlined, and that number just goes
  57          // up with the number of calls to fail!()
  58          #[inline(always)]
  59          fn run_fmt(fmt&::std::fmt::Arguments) -> ! {
  60              ::std::rt::begin_unwind_fmt(fmt, file!(), line!())
  61          }
  62          format_args!(run_fmt, $fmt, $($arg)*)
  63      });
  64  )
  65  
  66  /// Ensure that a boolean expression is `true` at runtime.
  67  ///
  68  /// This will invoke the `fail!` macro if the provided expression cannot be
  69  /// evaluated to `true` at runtime.
  70  ///
  71  /// # Example
  72  ///
  73  /// ```
  74  /// // the failure message for these assertions is the stringified value of the
  75  /// // expression given.
  76  /// assert!(true);
  77  /// # fn some_computation() -> bool { true }
  78  /// assert!(some_computation());
  79  ///
  80  /// // assert with a custom message
  81  /// # let x = true;
  82  /// assert!(x, "x wasn't true!");
  83  /// # let a = 3; let b = 27;
  84  /// assert!(a + b == 30, "a = {}, b = {}", a, b);
  85  /// ```
  86  #[macro_export]
  87  macro_rules! assert(
  88      ($cond:expr) => (
  89          if !$cond {
  90              fail!("assertion failed: {:s}", stringify!($cond))
  91          }
  92      );
  93      ($cond:expr, $($arg:expr),+) => (
  94          if !$cond {
  95              fail!($($arg),+)
  96          }
  97      );
  98  )
  99  
 100  /// Asserts that two expressions are equal to each other, testing equality in
 101  /// both directions.
 102  ///
 103  /// On failure, this macro will print the values of the expressions.
 104  ///
 105  /// # Example
 106  ///
 107  /// ```
 108  /// let a = 3;
 109  /// let b = 1 + 2;
 110  /// assert_eq!(a, b);
 111  /// ```
 112  #[macro_export]
 113  macro_rules! assert_eq(
 114      ($given:expr , $expected:expr) => ({
 115          match (&($given), &($expected)) {
 116              (given_val, expected_val) => {
 117                  // check both directions of equality....
 118                  if !((*given_val == *expected_val) &&
 119                       (*expected_val == *given_val)) {
 120                      fail!("assertion failed: `(left == right) && (right == left)` \
 121                             (left: `{}`, right: `{}`)", *given_val, *expected_val)
 122                  }
 123              }
 124          }
 125      })
 126  )
 127  
 128  /// Ensure that a boolean expression is `true` at runtime.
 129  ///
 130  /// This will invoke the `fail!` macro if the provided expression cannot be
 131  /// evaluated to `true` at runtime.
 132  ///
 133  /// Unlike `assert!`, `debug_assert!` statements can be disabled by passing
 134  /// `--cfg ndebug` to the compiler. This makes `debug_assert!` useful for
 135  /// checks that are too expensive to be present in a release build but may be
 136  /// helpful during development.
 137  ///
 138  /// # Example
 139  ///
 140  /// ```
 141  /// // the failure message for these assertions is the stringified value of the
 142  /// // expression given.
 143  /// debug_assert!(true);
 144  /// # fn some_expensive_computation() -> bool { true }
 145  /// debug_assert!(some_expensive_computation());
 146  ///
 147  /// // assert with a custom message
 148  /// # let x = true;
 149  /// debug_assert!(x, "x wasn't true!");
 150  /// # let a = 3; let b = 27;
 151  /// debug_assert!(a + b == 30, "a = {}, b = {}", a, b);
 152  /// ```
 153  #[macro_export]
 154  macro_rules! debug_assert(
 155      ($($arg:tt)*) => (if cfg!(not(ndebug)) { assert!($($arg)*); })
 156  )
 157  
 158  /// Asserts that two expressions are equal to each other, testing equality in
 159  /// both directions.
 160  ///
 161  /// On failure, this macro will print the values of the expressions.
 162  ///
 163  /// Unlike `assert_eq!`, `debug_assert_eq!` statements can be disabled by
 164  /// passing `--cfg ndebug` to the compiler. This makes `debug_assert_eq!`
 165  /// useful for checks that are too expensive to be present in a release build
 166  /// but may be helpful during development.
 167  ///
 168  /// # Example
 169  ///
 170  /// ```
 171  /// let a = 3;
 172  /// let b = 1 + 2;
 173  /// debug_assert_eq!(a, b);
 174  /// ```
 175  #[macro_export]
 176  macro_rules! debug_assert_eq(
 177      ($($arg:tt)*) => (if cfg!(not(ndebug)) { assert_eq!($($arg)*); })
 178  )
 179  
 180  /// A utility macro for indicating unreachable code. It will fail if
 181  /// executed. This is occasionally useful to put after loops that never
 182  /// terminate normally, but instead directly return from a function.
 183  ///
 184  /// # Example
 185  ///
 186  /// ~~~rust
 187  /// struct Item { weight: uint }
 188  ///
 189  /// fn choose_weighted_item(v: &[Item]) -> Item {
 190  ///     assert!(!v.is_empty());
 191  ///     let mut so_far = 0u;
 192  ///     for item in v.iter() {
 193  ///         so_far += item.weight;
 194  ///         if so_far > 100 {
 195  ///             return *item;
 196  ///         }
 197  ///     }
 198  ///     // The above loop always returns, so we must hint to the
 199  ///     // type checker that it isn't possible to get down here
 200  ///     unreachable!();
 201  /// }
 202  /// ~~~
 203  #[macro_export]
 204  macro_rules! unreachable(
 205      () => (fail!("internal error: entered unreachable code"))
 206  )
 207  
 208  /// A standardised placeholder for marking unfinished code. It fails with the
 209  /// message `"not yet implemented"` when executed.
 210  #[macro_export]
 211  macro_rules! unimplemented(
 212      () => (fail!("not yet implemented"))
 213  )
 214  
 215  /// Use the syntax described in `std::fmt` to create a value of type `~str`.
 216  /// See `std::fmt` for more information.
 217  ///
 218  /// # Example
 219  ///
 220  /// ```
 221  /// format!("test");
 222  /// format!("hello {}", "world!");
 223  /// format!("x = {}, y = {y}", 10, y = 30);
 224  /// ```
 225  #[macro_export]
 226  macro_rules! format(
 227      ($($arg:tt)*) => (
 228          format_args!(::std::fmt::format, $($arg)*)
 229      )
 230  )
 231  
 232  /// Use the `format!` syntax to write data into a buffer of type `&mut Writer`.
 233  /// See `std::fmt` for more information.
 234  ///
 235  /// # Example
 236  ///
 237  /// ```
 238  /// # #![allow(unused_must_use)]
 239  /// use std::io::MemWriter;
 240  ///
 241  /// let mut w = MemWriter::new();
 242  /// write!(&mut w, "test");
 243  /// write!(&mut w, "formatted {}", "arguments");
 244  /// ```
 245  #[macro_export]
 246  macro_rules! write(
 247      ($dst:expr, $($arg:tt)*) => ({
 248          let dst&mut ::std::io::Writer = $dst;
 249          format_args!(|args| { ::std::fmt::write(dst, args) }, $($arg)*)
 250      })
 251  )
 252  
 253  /// Equivalent to the `write!` macro, except that a newline is appended after
 254  /// the message is written.
 255  #[macro_export]
 256  macro_rules! writeln(
 257      ($dst:expr, $($arg:tt)*) => ({
 258          let dst&mut ::std::io::Writer = $dst;
 259          format_args!(|args| { ::std::fmt::writeln(dst, args) }, $($arg)*)
 260      })
 261  )
 262  
 263  /// Equivalent to the `println!` macro except that a newline is not printed at
 264  /// the end of the message.
 265  #[macro_export]
 266  macro_rules! print(
 267      ($($arg:tt)*) => (format_args!(::std::io::stdio::print_args, $($arg)*))
 268  )
 269  
 270  /// Macro for printing to a task's stdout handle.
 271  ///
 272  /// Each task can override its stdout handle via `std::io::stdio::set_stdout`.
 273  /// The syntax of this macro is the same as that used for `format!`. For more
 274  /// information, see `std::fmt` and `std::io::stdio`.
 275  ///
 276  /// # Example
 277  ///
 278  /// ```
 279  /// println!("hello there!");
 280  /// println!("format {} arguments", "some");
 281  /// ```
 282  #[macro_export]
 283  macro_rules! println(
 284      ($($arg:tt)*) => (format_args!(::std::io::stdio::println_args, $($arg)*))
 285  )
 286  
 287  /// Declare a task-local key with a specific type.
 288  ///
 289  /// # Example
 290  ///
 291  /// ```
 292  /// local_data_key!(my_integer: int)
 293  ///
 294  /// my_integer.replace(Some(2));
 295  /// println!("{}", my_integer.get().map(|a| *a));
 296  /// ```
 297  #[macro_export]
 298  macro_rules! local_data_key(
 299      ($name:ident: $ty:ty) => (
 300          static $name: ::std::local_data::Key<$ty> = &::std::local_data::Key;
 301      );
 302      (pub $name:ident: $ty:ty) => (
 303          pub static $name: ::std::local_data::Key<$ty> = &::std::local_data::Key;
 304      );
 305  )
 306  
 307  /// Helper macro for unwrapping `Result` values while returning early with an
 308  /// error if the value of the expression is `Err`. For more information, see
 309  /// `std::io`.
 310  #[macro_export]
 311  macro_rules! try(
 312      ($e:expr) => (match $e { Ok(e) => e, Err(e) => return Err(e) })
 313  )
 314  
 315  /// Create a `std::vec::Vec` containing the arguments.
 316  #[macro_export]
 317  macro_rules! vec(
 318      ($($e:expr),*) => ({
 319          // leading _ to allow empty construction without a warning.
 320          let mut _temp = ::std::vec::Vec::new();
 321          $(_temp.push($e);)*
 322          _temp
 323      });
 324      ($($e:expr),+,) => (vec!($($e),+))
 325  )
 326  
 327  
 328  /// A macro to select an event from a number of ports.
 329  ///
 330  /// This macro is used to wait for the first event to occur on a number of
 331  /// ports. It places no restrictions on the types of ports given to this macro,
 332  /// this can be viewed as a heterogeneous select.
 333  ///
 334  /// # Example
 335  ///
 336  /// ```
 337  /// let (tx1, rx1) = channel();
 338  /// let (tx2, rx2) = channel();
 339  /// # fn long_running_task() {}
 340  /// # fn calculate_the_answer() -> int { 42 }
 341  ///
 342  /// spawn(proc() { long_running_task(); tx1.send(()) });
 343  /// spawn(proc() { tx2.send(calculate_the_answer()) });
 344  ///
 345  /// select! (
 346  ///     () = rx1.recv() => println!("the long running task finished first"),
 347  ///     answer = rx2.recv() => {
 348  ///         println!("the answer was: {}", answer);
 349  ///     }
 350  /// )
 351  /// ```
 352  ///
 353  /// For more information about select, see the `std::comm::Select` structure.
 354  #[macro_export]
 355  #[experimental]
 356  macro_rules! select {
 357      (
 358          $($name:pat = $rx:ident.$meth:ident() => $code:expr),+
 359      ) => ({
 360          use std::comm::Select;
 361          let sel = Select::new();
 362          $( let mut $rx = sel.handle(&$rx); )+
 363          unsafe {
 364              $( $rx.add(); )+
 365          }
 366          let ret = sel.wait();
 367          $( if ret == $rx.id() { let $name = $rx.$meth(); $code } else )+
 368          { unreachable!() }
 369      })
 370  }
 371  
 372  // When testing the standard library, we link to the liblog crate to get the
 373  // logging macros. In doing so, the liblog crate was linked against the real
 374  // version of libstd, and uses a different std::fmt module than the test crate
 375  // uses. To get around this difference, we redefine the log!() macro here to be
 376  // just a dumb version of what it should be.
 377  #[cfg(test)]
 378  macro_rules! log (
 379      ($lvl:expr, $($args:tt)*) => (
 380          if log_enabled!($lvl) { println!($($args)*) }
 381      )
 382  )
 383  
 384  /// Built-in macros to the compiler itself.
 385  ///
 386  /// These macros do not have any corresponding definition with a `macro_rules!`
 387  /// macro, but are documented here. Their implementations can be found hardcoded
 388  /// into libsyntax itself.
 389  #[cfg(dox)]
 390  pub mod builtin {
 391      /// The core macro for formatted string creation & output.
 392      ///
 393      /// This macro takes as its first argument a callable expression which will
 394      /// receive as its first argument a value of type `&fmt::Arguments`. This
 395      /// value can be passed to the functions in `std::fmt` for performing useful
 396      /// functions. All other formatting macros (`format!`, `write!`,
 397      /// `println!`, etc) are proxied through this one.
 398      ///
 399      /// For more information, see the documentation in `std::fmt`.
 400      ///
 401      /// # Example
 402      ///
 403      /// ```rust
 404      /// use std::fmt;
 405      ///
 406      /// let s = format_args!(fmt::format, "hello {}", "world");
 407      /// assert_eq!(s, format!("hello {}", "world"));
 408      ///
 409      /// format_args!(|args| {
 410      ///     // pass `args` to another function, etc.
 411      /// }, "hello {}", "world");
 412      /// ```
 413      #[macro_export]
 414      macro_rules! format_args( ($closure:expr, $fmt:expr $($args:tt)*) => ({
 415          /* compiler built-in */
 416      }) )
 417  
 418      /// Inspect an environment variable at compile time.
 419      ///
 420      /// This macro will expand to the value of the named environment variable at
 421      /// compile time, yielding an expression of type `&'static str`.
 422      ///
 423      /// If the environment variable is not defined, then a compilation error
 424      /// will be emitted.  To not emit a compile error, use the `option_env!`
 425      /// macro instead.
 426      ///
 427      /// # Example
 428      ///
 429      /// ```rust
 430      /// let user: &'static str = env!("USER");
 431      /// println!("the user who compiled this code is: {}", user);
 432      /// ```
 433      #[macro_export]
 434      macro_rules! env( ($name:expr) => ({ /* compiler built-in */ }) )
 435  
 436      /// Optionally inspect an environment variable at compile time.
 437      ///
 438      /// If the named environment variable is present at compile time, this will
 439      /// expand into an expression of type `Option<&'static str>` whose value is
 440      /// `Some` of the value of the environment variable. If the environment
 441      /// variable is not present, then this will expand to `None`.
 442      ///
 443      /// A compile time error is never emitted when using this macro regardless
 444      /// of whether the environment variable is present or not.
 445      ///
 446      /// # Example
 447      ///
 448      /// ```rust
 449      /// let key: Option<&'static str> = option_env!("SECRET_KEY");
 450      /// println!("the secret key might be: {}", key);
 451      /// ```
 452      #[macro_export]
 453      macro_rules! option_env( ($name:expr) => ({ /* compiler built-in */ }) )
 454  
 455      /// Concatenate literals into a static byte slice.
 456      ///
 457      /// This macro takes any number of comma-separated literal expressions,
 458      /// yielding an expression of type `&'static [u8]` which is the
 459      /// concatenation (left to right) of all the literals in their byte format.
 460      ///
 461      /// This extension currently only supports string literals, character
 462      /// literals, and integers less than 256. The byte slice returned is the
 463      /// utf8-encoding of strings and characters.
 464      ///
 465      /// # Example
 466      ///
 467      /// ```
 468      /// let rust = bytes!("r", 'u', "st");
 469      /// assert_eq!(rust[1], 'u' as u8);
 470      /// ```
 471      #[macro_export]
 472      macro_rules! bytes( ($($e:expr),*) => ({ /* compiler built-in */ }) )
 473  
 474      /// Concatenate identifiers into one identifier.
 475      ///
 476      /// This macro takes any number of comma-separated identifiers, and
 477      /// concatenates them all into one, yielding an expression which is a new
 478      /// identifier. Note that hygiene makes it such that this macro cannot
 479      /// capture local variables, and macros are only allowed in item,
 480      /// statement or expression position, meaning this macro may be difficult to
 481      /// use in some situations.
 482      ///
 483      /// # Example
 484      ///
 485      /// ```
 486      /// fn foobar() -> int { 23 }
 487      ///
 488      /// let f = concat_idents!(foo, bar);
 489      /// println!("{}", f());
 490      /// ```
 491      #[macro_export]
 492      macro_rules! concat_idents( ($($e:ident),*) => ({ /* compiler built-in */ }) )
 493  
 494      /// Concatenates literals into a static string slice.
 495      ///
 496      /// This macro takes any number of comma-separated literals, yielding an
 497      /// expression of type `&'static str` which represents all of the literals
 498      /// concatenated left-to-right.
 499      ///
 500      /// Integer and floating point literals are stringified in order to be
 501      /// concatenated.
 502      ///
 503      /// # Example
 504      ///
 505      /// ```
 506      /// let s = concat!("test", 10, 'b', true);
 507      /// assert_eq!(s, "test10btrue");
 508      /// ```
 509      #[macro_export]
 510      macro_rules! concat( ($($e:expr),*) => ({ /* compiler built-in */ }) )
 511  
 512      /// A macro which expands to the line number on which it was invoked.
 513      ///
 514      /// The expanded expression has type `uint`, and the returned line is not
 515      /// the invocation of the `line!()` macro itself, but rather the first macro
 516      /// invocation leading up to the invocation of the `line!()` macro.
 517      ///
 518      /// # Example
 519      ///
 520      /// ```
 521      /// let current_line = line!();
 522      /// println!("defined on line: {}", current_line);
 523      /// ```
 524      #[macro_export]
 525      macro_rules! line( () => ({ /* compiler built-in */ }) )
 526  
 527      /// A macro which expands to the column number on which it was invoked.
 528      ///
 529      /// The expanded expression has type `uint`, and the returned column is not
 530      /// the invocation of the `col!()` macro itself, but rather the first macro
 531      /// invocation leading up to the invocation of the `col!()` macro.
 532      ///
 533      /// # Example
 534      ///
 535      /// ```
 536      /// let current_col = col!();
 537      /// println!("defined on column: {}", current_col);
 538      /// ```
 539      #[macro_export]
 540      macro_rules! col( () => ({ /* compiler built-in */ }) )
 541  
 542      /// A macro which expands to the file name from which it was invoked.
 543      ///
 544      /// The expanded expression has type `&'static str`, and the returned file
 545      /// is not the invocation of the `file!()` macro itself, but rather the
 546      /// first macro invocation leading up to the invocation of the `file!()`
 547      /// macro.
 548      ///
 549      /// # Example
 550      ///
 551      /// ```
 552      /// let this_file = file!();
 553      /// println!("defined in file: {}", this_file);
 554      /// ```
 555      #[macro_export]
 556      macro_rules! file( () => ({ /* compiler built-in */ }) )
 557  
 558      /// A macro which stringifies its argument.
 559      ///
 560      /// This macro will yield an expression of type `&'static str` which is the
 561      /// stringification of all the tokens passed to the macro. No restrictions
 562      /// are placed on the syntax of the macro invocation itself.
 563      ///
 564      /// # Example
 565      ///
 566      /// ```
 567      /// let one_plus_one = stringify!(1 + 1);
 568      /// assert_eq!(one_plus_one, "1 + 1");
 569      /// ```
 570      #[macro_export]
 571      macro_rules! stringify( ($t:tt) => ({ /* compiler built-in */ }) )
 572  
 573      /// Includes a utf8-encoded file as a string.
 574      ///
 575      /// This macro will yield an expression of type `&'static str` which is the
 576      /// contents of the filename specified. The file is located relative to the
 577      /// current file (similarly to how modules are found),
 578      ///
 579      /// # Example
 580      ///
 581      /// ```rust,ignore
 582      /// let secret_key = include_str!("secret-key.ascii");
 583      /// ```
 584      #[macro_export]
 585      macro_rules! include_str( ($file:expr) => ({ /* compiler built-in */ }) )
 586  
 587      /// Includes a file as a byte slice.
 588      ///
 589      /// This macro will yield an expression of type `&'static [u8]` which is
 590      /// the contents of the filename specified. The file is located relative to
 591      /// the current file (similarly to how modules are found),
 592      ///
 593      /// # Example
 594      ///
 595      /// ```rust,ignore
 596      /// let secret_key = include_bin!("secret-key.bin");
 597      /// ```
 598      #[macro_export]
 599      macro_rules! include_bin( ($file:expr) => ({ /* compiler built-in */ }) )
 600  
 601      /// Expands to a string that represents the current module path.
 602      ///
 603      /// The current module path can be thought of as the hierarchy of modules
 604      /// leading back up to the crate root. The first component of the path
 605      /// returned is the name of the crate currently being compiled.
 606      ///
 607      /// # Example
 608      ///
 609      /// ```rust
 610      /// mod test {
 611      ///     pub fn foo() {
 612      ///         assert!(module_path!().ends_with("test"));
 613      ///     }
 614      /// }
 615      ///
 616      /// test::foo();
 617      /// ```
 618      #[macro_export]
 619      macro_rules! module_path( () => ({ /* compiler built-in */ }) )
 620  
 621      /// Boolean evaluation of configuration flags.
 622      ///
 623      /// In addition to the `#[cfg]` attribute, this macro is provided to allow
 624      /// boolean expression evaluation of configuration flags. This frequently
 625      /// leads to less duplicated code.
 626      ///
 627      /// The syntax given to this macro is the same syntax as the `cfg`
 628      /// attribute.
 629      ///
 630      /// # Example
 631      ///
 632      /// ```rust
 633      /// let my_directory = if cfg!(windows) {
 634      ///     "windows-specific-directory"
 635      /// } else {
 636      ///     "unix-directory"
 637      /// };
 638      /// ```
 639      #[macro_export]
 640      macro_rules! cfg( ($cfg:tt) => ({ /* compiler built-in */ }) )
 641  }