2014-05-01 10:47:18 -07:00
|
|
|
// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
|
|
|
|
// file at the top-level directory of this distribution and at
|
|
|
|
// http://rust-lang.org/COPYRIGHT.
|
|
|
|
//
|
|
|
|
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
|
|
|
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
|
|
|
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
|
|
|
// option. This file may not be copied, modified, or distributed
|
|
|
|
// except according to those terms.
|
|
|
|
|
2015-05-09 00:12:29 +09:00
|
|
|
/// Entry point of thread panic, for details, see std::macros
|
2014-12-27 23:57:43 +02:00
|
|
|
#[macro_export]
|
2015-06-09 11:18:03 -07:00
|
|
|
#[allow_internal_unstable]
|
2015-12-02 17:31:49 -08:00
|
|
|
#[stable(feature = "core", since = "1.6.0")]
|
2014-12-27 23:57:43 +02:00
|
|
|
macro_rules! panic {
|
|
|
|
() => (
|
|
|
|
panic!("explicit panic")
|
|
|
|
);
|
|
|
|
($msg:expr) => ({
|
2015-02-21 17:26:29 -05:00
|
|
|
static _MSG_FILE_LINE: (&'static str, &'static str, u32) = ($msg, file!(), line!());
|
2015-07-30 06:29:24 +10:00
|
|
|
$crate::panicking::panic(&_MSG_FILE_LINE)
|
2014-12-27 23:57:43 +02:00
|
|
|
});
|
|
|
|
($fmt:expr, $($arg:tt)*) => ({
|
|
|
|
// The leading _'s are to avoid dead code warnings if this is
|
|
|
|
// used inside a dead function. Just `#[allow(dead_code)]` is
|
|
|
|
// insufficient, since the user may have
|
|
|
|
// `#[forbid(dead_code)]` and which cannot be overridden.
|
2015-02-21 17:26:29 -05:00
|
|
|
static _FILE_LINE: (&'static str, u32) = (file!(), line!());
|
2015-07-30 06:29:24 +10:00
|
|
|
$crate::panicking::panic_fmt(format_args!($fmt, $($arg)*), &_FILE_LINE)
|
2014-12-27 23:57:43 +02:00
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2014-09-15 19:29:47 -07:00
|
|
|
/// Ensure that a boolean expression is `true` at runtime.
|
|
|
|
///
|
2016-07-27 15:03:23 -04:00
|
|
|
/// This will invoke the `panic!` macro if the provided expression cannot be
|
|
|
|
/// evaluated to `true` at runtime.
|
2016-07-27 13:12:35 -04:00
|
|
|
///
|
|
|
|
/// Assertions are always checked in both debug and release builds, and cannot
|
2016-07-27 15:16:11 -04:00
|
|
|
/// be disabled. See `debug_assert!` for assertions that are not enabled in
|
|
|
|
/// release builds by default.
|
2016-07-27 13:12:35 -04:00
|
|
|
///
|
|
|
|
/// Unsafe code relies on `assert!` to enforce run-time invariants that, if
|
|
|
|
/// violated could lead to unsafety.
|
|
|
|
///
|
2016-10-21 00:49:47 +01:00
|
|
|
/// Other use-cases of `assert!` include [testing] and enforcing run-time
|
|
|
|
/// invariants in safe code (whose violation cannot result in unsafety).
|
2014-09-15 19:29:47 -07:00
|
|
|
///
|
2015-10-28 00:56:27 +01:00
|
|
|
/// This macro has a second version, where a custom panic message can be provided.
|
|
|
|
///
|
2016-10-21 00:49:47 +01:00
|
|
|
/// [testing]: ../book/testing.html
|
|
|
|
///
|
2015-03-11 21:11:40 -04:00
|
|
|
/// # Examples
|
2014-09-15 19:29:47 -07:00
|
|
|
///
|
|
|
|
/// ```
|
|
|
|
/// // the panic message for these assertions is the stringified value of the
|
|
|
|
/// // expression given.
|
|
|
|
/// assert!(true);
|
2015-01-12 16:59:34 -05:00
|
|
|
///
|
|
|
|
/// fn some_computation() -> bool { true } // a very simple function
|
|
|
|
///
|
2014-09-15 19:29:47 -07:00
|
|
|
/// assert!(some_computation());
|
|
|
|
///
|
|
|
|
/// // assert with a custom message
|
2015-01-12 16:59:34 -05:00
|
|
|
/// let x = true;
|
2014-09-15 19:29:47 -07:00
|
|
|
/// assert!(x, "x wasn't true!");
|
2015-01-12 16:59:34 -05:00
|
|
|
///
|
2015-01-22 14:08:56 +00:00
|
|
|
/// let a = 3; let b = 27;
|
2014-09-15 19:29:47 -07:00
|
|
|
/// assert!(a + b == 30, "a = {}, b = {}", a, b);
|
|
|
|
/// ```
|
2014-05-01 10:47:18 -07:00
|
|
|
#[macro_export]
|
2015-01-23 21:48:20 -08:00
|
|
|
#[stable(feature = "rust1", since = "1.0.0")]
|
2014-11-14 09:18:10 -08:00
|
|
|
macro_rules! assert {
|
2014-05-01 10:47:18 -07:00
|
|
|
($cond:expr) => (
|
|
|
|
if !$cond {
|
2014-10-09 15:17:22 -04:00
|
|
|
panic!(concat!("assertion failed: ", stringify!($cond)))
|
2014-05-01 10:47:18 -07:00
|
|
|
}
|
|
|
|
);
|
2015-01-08 12:21:51 -08:00
|
|
|
($cond:expr, $($arg:tt)+) => (
|
2014-05-10 13:47:46 -07:00
|
|
|
if !$cond {
|
2015-01-08 12:21:51 -08:00
|
|
|
panic!($($arg)+)
|
2014-05-10 13:47:46 -07:00
|
|
|
}
|
|
|
|
);
|
2014-11-14 09:18:10 -08:00
|
|
|
}
|
2014-05-01 10:47:18 -07:00
|
|
|
|
2015-03-10 17:59:23 -07:00
|
|
|
/// Asserts that two expressions are equal to each other.
|
2014-09-15 19:29:47 -07:00
|
|
|
///
|
2015-03-10 17:59:23 -07:00
|
|
|
/// On panic, this macro will print the values of the expressions with their
|
|
|
|
/// debug representations.
|
2014-09-15 19:29:47 -07:00
|
|
|
///
|
2015-03-11 21:11:40 -04:00
|
|
|
/// # Examples
|
2014-09-15 19:29:47 -07:00
|
|
|
///
|
|
|
|
/// ```
|
2015-01-22 14:08:56 +00:00
|
|
|
/// let a = 3;
|
|
|
|
/// let b = 1 + 2;
|
2014-09-15 19:29:47 -07:00
|
|
|
/// assert_eq!(a, b);
|
|
|
|
/// ```
|
std: Recreate a `collections` module
As with the previous commit with `librand`, this commit shuffles around some
`collections` code. The new state of the world is similar to that of librand:
* The libcollections crate now only depends on libcore and liballoc.
* The standard library has a new module, `std::collections`. All functionality
of libcollections is reexported through this module.
I would like to stress that this change is purely cosmetic. There are very few
alterations to these primitives.
There are a number of notable points about the new organization:
* std::{str, slice, string, vec} all moved to libcollections. There is no reason
that these primitives shouldn't be necessarily usable in a freestanding
context that has allocation. These are all reexported in their usual places in
the standard library.
* The `hashmap`, and transitively the `lru_cache`, modules no longer reside in
`libcollections`, but rather in libstd. The reason for this is because the
`HashMap::new` contructor requires access to the OSRng for initially seeding
the hash map. Beyond this requirement, there is no reason that the hashmap
could not move to libcollections.
I do, however, have a plan to move the hash map to the collections module. The
`HashMap::new` function could be altered to require that the `H` hasher
parameter ascribe to the `Default` trait, allowing the entire `hashmap` module
to live in libcollections. The key idea would be that the default hasher would
be different in libstd. Something along the lines of:
// src/libstd/collections/mod.rs
pub type HashMap<K, V, H = RandomizedSipHasher> =
core_collections::HashMap<K, V, H>;
This is not possible today because you cannot invoke static methods through
type aliases. If we modified the compiler, however, to allow invocation of
static methods through type aliases, then this type definition would
essentially be switching the default hasher from `SipHasher` in libcollections
to a libstd-defined `RandomizedSipHasher` type. This type's `Default`
implementation would randomly seed the `SipHasher` instance, and otherwise
perform the same as `SipHasher`.
This future state doesn't seem incredibly far off, but until that time comes,
the hashmap module will live in libstd to not compromise on functionality.
* In preparation for the hashmap moving to libcollections, the `hash` module has
moved from libstd to libcollections. A previously snapshotted commit enables a
distinct `Writer` trait to live in the `hash` module which `Hash`
implementations are now parameterized over.
Due to using a custom trait, the `SipHasher` implementation has lost its
specialized methods for writing integers. These can be re-added
backwards-compatibly in the future via default methods if necessary, but the
FNV hashing should satisfy much of the need for speedier hashing.
A list of breaking changes:
* HashMap::{get, get_mut} no longer fails with the key formatted into the error
message with `{:?}`, instead, a generic message is printed. With backtraces,
it should still be not-too-hard to track down errors.
* The HashMap, HashSet, and LruCache types are now available through
std::collections instead of the collections crate.
* Manual implementations of hash should be parameterized over `hash::Writer`
instead of just `Writer`.
[breaking-change]
2014-05-29 18:50:12 -07:00
|
|
|
#[macro_export]
|
2015-01-23 21:48:20 -08:00
|
|
|
#[stable(feature = "rust1", since = "1.0.0")]
|
2014-11-14 09:18:10 -08:00
|
|
|
macro_rules! assert_eq {
|
2014-09-15 19:29:47 -07:00
|
|
|
($left:expr , $right:expr) => ({
|
2016-05-18 22:24:33 +09:00
|
|
|
match (&$left, &$right) {
|
2014-09-15 19:29:47 -07:00
|
|
|
(left_val, right_val) => {
|
2015-03-10 17:59:23 -07:00
|
|
|
if !(*left_val == *right_val) {
|
|
|
|
panic!("assertion failed: `(left == right)` \
|
2015-11-11 14:25:08 +00:00
|
|
|
(left: `{:?}`, right: `{:?}`)", left_val, right_val)
|
2014-09-15 19:29:47 -07:00
|
|
|
}
|
|
|
|
}
|
2014-05-11 11:14:14 -07:00
|
|
|
}
|
2016-05-31 01:53:14 +09:00
|
|
|
});
|
|
|
|
($left:expr , $right:expr, $($arg:tt)*) => ({
|
|
|
|
match (&($left), &($right)) {
|
|
|
|
(left_val, right_val) => {
|
|
|
|
if !(*left_val == *right_val) {
|
|
|
|
panic!("assertion failed: `(left == right)` \
|
|
|
|
(left: `{:?}`, right: `{:?}`): {}", left_val, right_val,
|
|
|
|
format_args!($($arg)*))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
});
|
2014-11-14 09:18:10 -08:00
|
|
|
}
|
2014-05-11 11:14:14 -07:00
|
|
|
|
2016-07-27 10:47:19 -07:00
|
|
|
/// Asserts that two expressions are not equal to each other.
|
|
|
|
///
|
|
|
|
/// On panic, this macro will print the values of the expressions with their
|
|
|
|
/// debug representations.
|
|
|
|
///
|
|
|
|
/// # Examples
|
|
|
|
///
|
|
|
|
/// ```
|
|
|
|
/// let a = 3;
|
|
|
|
/// let b = 2;
|
|
|
|
/// assert_ne!(a, b);
|
|
|
|
/// ```
|
|
|
|
#[macro_export]
|
|
|
|
#[stable(feature = "assert_ne", since = "1.12.0")]
|
|
|
|
macro_rules! assert_ne {
|
|
|
|
($left:expr , $right:expr) => ({
|
|
|
|
match (&$left, &$right) {
|
|
|
|
(left_val, right_val) => {
|
|
|
|
if *left_val == *right_val {
|
|
|
|
panic!("assertion failed: `(left != right)` \
|
|
|
|
(left: `{:?}`, right: `{:?}`)", left_val, right_val)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
});
|
|
|
|
($left:expr , $right:expr, $($arg:tt)*) => ({
|
|
|
|
match (&($left), &($right)) {
|
|
|
|
(left_val, right_val) => {
|
|
|
|
if *left_val == *right_val {
|
|
|
|
panic!("assertion failed: `(left != right)` \
|
|
|
|
(left: `{:?}`, right: `{:?}`): {}", left_val, right_val,
|
|
|
|
format_args!($($arg)*))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2014-09-15 19:29:47 -07:00
|
|
|
/// 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.
|
|
|
|
///
|
2015-10-28 00:56:27 +01:00
|
|
|
/// Like `assert!`, this macro also has a second version, where a custom panic
|
|
|
|
/// message can be provided.
|
|
|
|
///
|
2015-03-02 14:51:24 -08:00
|
|
|
/// Unlike `assert!`, `debug_assert!` statements are only enabled in non
|
|
|
|
/// optimized builds by default. An optimized build will omit all
|
|
|
|
/// `debug_assert!` statements unless `-C debug-assertions` is passed 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.
|
2014-09-15 19:29:47 -07:00
|
|
|
///
|
2016-07-27 13:12:35 -04:00
|
|
|
/// An unchecked assertion allows a program in an inconsistent state to keep
|
|
|
|
/// running, which might have unexpected consequences but does not introduce
|
|
|
|
/// unsafety as long as this only happens in safe code. The performance cost
|
|
|
|
/// of assertions, is however, not measurable in general. Replacing `assert!`
|
2016-07-27 15:01:43 -04:00
|
|
|
/// with `debug_assert!` is thus only encouraged after thorough profiling, and
|
2016-07-27 13:12:35 -04:00
|
|
|
/// more importantly, only in safe code!
|
|
|
|
///
|
2015-03-11 21:11:40 -04:00
|
|
|
/// # Examples
|
2014-09-15 19:29:47 -07:00
|
|
|
///
|
|
|
|
/// ```
|
|
|
|
/// // the panic message for these assertions is the stringified value of the
|
|
|
|
/// // expression given.
|
|
|
|
/// debug_assert!(true);
|
2015-01-12 16:59:34 -05:00
|
|
|
///
|
|
|
|
/// fn some_expensive_computation() -> bool { true } // a very simple function
|
2014-09-15 19:29:47 -07:00
|
|
|
/// debug_assert!(some_expensive_computation());
|
|
|
|
///
|
|
|
|
/// // assert with a custom message
|
2015-01-12 16:59:34 -05:00
|
|
|
/// let x = true;
|
2014-09-15 19:29:47 -07:00
|
|
|
/// debug_assert!(x, "x wasn't true!");
|
2015-01-12 16:59:34 -05:00
|
|
|
///
|
|
|
|
/// let a = 3; let b = 27;
|
2014-09-15 19:29:47 -07:00
|
|
|
/// debug_assert!(a + b == 30, "a = {}, b = {}", a, b);
|
|
|
|
/// ```
|
|
|
|
#[macro_export]
|
2015-01-23 21:48:20 -08:00
|
|
|
#[stable(feature = "rust1", since = "1.0.0")]
|
2014-09-15 19:29:47 -07:00
|
|
|
macro_rules! debug_assert {
|
2015-03-02 14:51:24 -08:00
|
|
|
($($arg:tt)*) => (if cfg!(debug_assertions) { assert!($($arg)*); })
|
2014-09-15 19:29:47 -07:00
|
|
|
}
|
|
|
|
|
2015-12-29 11:01:35 -05:00
|
|
|
/// Asserts that two expressions are equal to each other.
|
2014-09-15 19:29:47 -07:00
|
|
|
///
|
2015-12-29 11:01:35 -05:00
|
|
|
/// On panic, this macro will print the values of the expressions with their
|
|
|
|
/// debug representations.
|
2014-09-15 19:29:47 -07:00
|
|
|
///
|
2015-03-02 14:51:24 -08:00
|
|
|
/// Unlike `assert_eq!`, `debug_assert_eq!` statements are only enabled in non
|
|
|
|
/// optimized builds by default. An optimized build will omit all
|
|
|
|
/// `debug_assert_eq!` statements unless `-C debug-assertions` is passed 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.
|
2014-09-15 19:29:47 -07:00
|
|
|
///
|
2015-03-11 21:11:40 -04:00
|
|
|
/// # Examples
|
2014-09-15 19:29:47 -07:00
|
|
|
///
|
|
|
|
/// ```
|
2015-01-22 14:08:56 +00:00
|
|
|
/// let a = 3;
|
|
|
|
/// let b = 1 + 2;
|
2014-09-15 19:29:47 -07:00
|
|
|
/// debug_assert_eq!(a, b);
|
|
|
|
/// ```
|
std: Recreate a `collections` module
As with the previous commit with `librand`, this commit shuffles around some
`collections` code. The new state of the world is similar to that of librand:
* The libcollections crate now only depends on libcore and liballoc.
* The standard library has a new module, `std::collections`. All functionality
of libcollections is reexported through this module.
I would like to stress that this change is purely cosmetic. There are very few
alterations to these primitives.
There are a number of notable points about the new organization:
* std::{str, slice, string, vec} all moved to libcollections. There is no reason
that these primitives shouldn't be necessarily usable in a freestanding
context that has allocation. These are all reexported in their usual places in
the standard library.
* The `hashmap`, and transitively the `lru_cache`, modules no longer reside in
`libcollections`, but rather in libstd. The reason for this is because the
`HashMap::new` contructor requires access to the OSRng for initially seeding
the hash map. Beyond this requirement, there is no reason that the hashmap
could not move to libcollections.
I do, however, have a plan to move the hash map to the collections module. The
`HashMap::new` function could be altered to require that the `H` hasher
parameter ascribe to the `Default` trait, allowing the entire `hashmap` module
to live in libcollections. The key idea would be that the default hasher would
be different in libstd. Something along the lines of:
// src/libstd/collections/mod.rs
pub type HashMap<K, V, H = RandomizedSipHasher> =
core_collections::HashMap<K, V, H>;
This is not possible today because you cannot invoke static methods through
type aliases. If we modified the compiler, however, to allow invocation of
static methods through type aliases, then this type definition would
essentially be switching the default hasher from `SipHasher` in libcollections
to a libstd-defined `RandomizedSipHasher` type. This type's `Default`
implementation would randomly seed the `SipHasher` instance, and otherwise
perform the same as `SipHasher`.
This future state doesn't seem incredibly far off, but until that time comes,
the hashmap module will live in libstd to not compromise on functionality.
* In preparation for the hashmap moving to libcollections, the `hash` module has
moved from libstd to libcollections. A previously snapshotted commit enables a
distinct `Writer` trait to live in the `hash` module which `Hash`
implementations are now parameterized over.
Due to using a custom trait, the `SipHasher` implementation has lost its
specialized methods for writing integers. These can be re-added
backwards-compatibly in the future via default methods if necessary, but the
FNV hashing should satisfy much of the need for speedier hashing.
A list of breaking changes:
* HashMap::{get, get_mut} no longer fails with the key formatted into the error
message with `{:?}`, instead, a generic message is printed. With backtraces,
it should still be not-too-hard to track down errors.
* The HashMap, HashSet, and LruCache types are now available through
std::collections instead of the collections crate.
* Manual implementations of hash should be parameterized over `hash::Writer`
instead of just `Writer`.
[breaking-change]
2014-05-29 18:50:12 -07:00
|
|
|
#[macro_export]
|
2015-12-02 17:31:49 -08:00
|
|
|
#[stable(feature = "rust1", since = "1.0.0")]
|
2014-11-14 09:18:10 -08:00
|
|
|
macro_rules! debug_assert_eq {
|
2015-03-02 14:51:24 -08:00
|
|
|
($($arg:tt)*) => (if cfg!(debug_assertions) { assert_eq!($($arg)*); })
|
2014-11-14 09:18:10 -08:00
|
|
|
}
|
std: Recreate a `collections` module
As with the previous commit with `librand`, this commit shuffles around some
`collections` code. The new state of the world is similar to that of librand:
* The libcollections crate now only depends on libcore and liballoc.
* The standard library has a new module, `std::collections`. All functionality
of libcollections is reexported through this module.
I would like to stress that this change is purely cosmetic. There are very few
alterations to these primitives.
There are a number of notable points about the new organization:
* std::{str, slice, string, vec} all moved to libcollections. There is no reason
that these primitives shouldn't be necessarily usable in a freestanding
context that has allocation. These are all reexported in their usual places in
the standard library.
* The `hashmap`, and transitively the `lru_cache`, modules no longer reside in
`libcollections`, but rather in libstd. The reason for this is because the
`HashMap::new` contructor requires access to the OSRng for initially seeding
the hash map. Beyond this requirement, there is no reason that the hashmap
could not move to libcollections.
I do, however, have a plan to move the hash map to the collections module. The
`HashMap::new` function could be altered to require that the `H` hasher
parameter ascribe to the `Default` trait, allowing the entire `hashmap` module
to live in libcollections. The key idea would be that the default hasher would
be different in libstd. Something along the lines of:
// src/libstd/collections/mod.rs
pub type HashMap<K, V, H = RandomizedSipHasher> =
core_collections::HashMap<K, V, H>;
This is not possible today because you cannot invoke static methods through
type aliases. If we modified the compiler, however, to allow invocation of
static methods through type aliases, then this type definition would
essentially be switching the default hasher from `SipHasher` in libcollections
to a libstd-defined `RandomizedSipHasher` type. This type's `Default`
implementation would randomly seed the `SipHasher` instance, and otherwise
perform the same as `SipHasher`.
This future state doesn't seem incredibly far off, but until that time comes,
the hashmap module will live in libstd to not compromise on functionality.
* In preparation for the hashmap moving to libcollections, the `hash` module has
moved from libstd to libcollections. A previously snapshotted commit enables a
distinct `Writer` trait to live in the `hash` module which `Hash`
implementations are now parameterized over.
Due to using a custom trait, the `SipHasher` implementation has lost its
specialized methods for writing integers. These can be re-added
backwards-compatibly in the future via default methods if necessary, but the
FNV hashing should satisfy much of the need for speedier hashing.
A list of breaking changes:
* HashMap::{get, get_mut} no longer fails with the key formatted into the error
message with `{:?}`, instead, a generic message is printed. With backtraces,
it should still be not-too-hard to track down errors.
* The HashMap, HashSet, and LruCache types are now available through
std::collections instead of the collections crate.
* Manual implementations of hash should be parameterized over `hash::Writer`
instead of just `Writer`.
[breaking-change]
2014-05-29 18:50:12 -07:00
|
|
|
|
2016-07-27 10:47:19 -07:00
|
|
|
/// Asserts that two expressions are not equal to each other.
|
|
|
|
///
|
|
|
|
/// On panic, this macro will print the values of the expressions with their
|
|
|
|
/// debug representations.
|
|
|
|
///
|
|
|
|
/// Unlike `assert_ne!`, `debug_assert_ne!` statements are only enabled in non
|
|
|
|
/// optimized builds by default. An optimized build will omit all
|
|
|
|
/// `debug_assert_ne!` statements unless `-C debug-assertions` is passed to the
|
|
|
|
/// compiler. This makes `debug_assert_ne!` useful for checks that are too
|
|
|
|
/// expensive to be present in a release build but may be helpful during
|
|
|
|
/// development.
|
|
|
|
///
|
|
|
|
/// # Examples
|
|
|
|
///
|
|
|
|
/// ```
|
|
|
|
/// let a = 3;
|
|
|
|
/// let b = 2;
|
|
|
|
/// debug_assert_ne!(a, b);
|
|
|
|
/// ```
|
|
|
|
#[macro_export]
|
|
|
|
#[stable(feature = "assert_ne", since = "1.12.0")]
|
|
|
|
macro_rules! debug_assert_ne {
|
|
|
|
($($arg:tt)*) => (if cfg!(debug_assertions) { assert_ne!($($arg)*); })
|
|
|
|
}
|
|
|
|
|
2016-08-29 20:05:47 +02:00
|
|
|
/// Helper macro for reducing boilerplate code for matching `Result` together
|
|
|
|
/// with converting downstream errors.
|
|
|
|
///
|
2016-10-06 11:36:36 +13:00
|
|
|
/// Prefer using `?` syntax to `try!`. `?` is built in to the language and is
|
2016-10-07 08:18:17 +13:00
|
|
|
/// more succinct than `try!`. It is the standard method for error propagation.
|
2016-10-06 11:36:36 +13:00
|
|
|
///
|
2016-08-29 20:05:47 +02:00
|
|
|
/// `try!` matches the given `Result`. In case of the `Ok` variant, the
|
|
|
|
/// expression has the value of the wrapped value.
|
|
|
|
///
|
|
|
|
/// In case of the `Err` variant, it retrieves the inner error. `try!` then
|
|
|
|
/// performs conversion using `From`. This provides automatic conversion
|
|
|
|
/// between specialized errors and more general ones. The resulting
|
|
|
|
/// error is then immediately returned.
|
|
|
|
///
|
|
|
|
/// Because of the early return, `try!` can only be used in functions that
|
|
|
|
/// return `Result`.
|
2015-12-02 17:31:49 -08:00
|
|
|
///
|
|
|
|
/// # Examples
|
2014-09-15 19:29:47 -07:00
|
|
|
///
|
2015-12-02 17:31:49 -08:00
|
|
|
/// ```
|
|
|
|
/// use std::io;
|
|
|
|
/// use std::fs::File;
|
|
|
|
/// use std::io::prelude::*;
|
|
|
|
///
|
2016-08-29 20:05:47 +02:00
|
|
|
/// enum MyError {
|
|
|
|
/// FileWriteError
|
|
|
|
/// }
|
|
|
|
///
|
|
|
|
/// impl From<io::Error> for MyError {
|
|
|
|
/// fn from(e: io::Error) -> MyError {
|
|
|
|
/// MyError::FileWriteError
|
|
|
|
/// }
|
|
|
|
/// }
|
|
|
|
///
|
|
|
|
/// fn write_to_file_using_try() -> Result<(), MyError> {
|
2015-12-02 17:31:49 -08:00
|
|
|
/// let mut file = try!(File::create("my_best_friends.txt"));
|
|
|
|
/// try!(file.write_all(b"This is a list of my best friends."));
|
|
|
|
/// println!("I wrote to the file");
|
|
|
|
/// Ok(())
|
|
|
|
/// }
|
|
|
|
/// // This is equivalent to:
|
2016-08-29 20:05:47 +02:00
|
|
|
/// fn write_to_file_using_match() -> Result<(), MyError> {
|
2015-12-02 17:31:49 -08:00
|
|
|
/// let mut file = try!(File::create("my_best_friends.txt"));
|
|
|
|
/// match file.write_all(b"This is a list of my best friends.") {
|
2016-04-12 01:18:35 +02:00
|
|
|
/// Ok(v) => v,
|
2016-08-29 20:05:47 +02:00
|
|
|
/// Err(e) => return Err(From::from(e)),
|
2015-12-02 17:31:49 -08:00
|
|
|
/// }
|
|
|
|
/// println!("I wrote to the file");
|
|
|
|
/// Ok(())
|
|
|
|
/// }
|
|
|
|
/// ```
|
2014-05-10 13:48:26 -07:00
|
|
|
#[macro_export]
|
2015-12-02 17:31:49 -08:00
|
|
|
#[stable(feature = "rust1", since = "1.0.0")]
|
2014-11-14 09:18:10 -08:00
|
|
|
macro_rules! try {
|
2015-12-02 17:31:49 -08:00
|
|
|
($expr:expr) => (match $expr {
|
|
|
|
$crate::result::Result::Ok(val) => val,
|
|
|
|
$crate::result::Result::Err(err) => {
|
|
|
|
return $crate::result::Result::Err($crate::convert::From::from(err))
|
2014-09-15 19:29:47 -07:00
|
|
|
}
|
|
|
|
})
|
2014-11-14 09:18:10 -08:00
|
|
|
}
|
2014-05-11 11:14:14 -07:00
|
|
|
|
2016-08-04 04:33:50 +03:00
|
|
|
/// Write formatted data into a buffer
|
2015-08-27 14:24:53 -04:00
|
|
|
///
|
2016-10-29 15:44:43 -07:00
|
|
|
/// This macro accepts a 'writer' (any value with a `write_fmt` method), a format string, and a
|
|
|
|
/// list of arguments to format.
|
2016-08-04 03:11:50 +03:00
|
|
|
///
|
2016-10-29 15:44:43 -07:00
|
|
|
/// The `write_fmt` method usually comes from an implementation of [`std::fmt::Write`][fmt_write]
|
|
|
|
/// or [`std::io::Write`][io_write] traits. The term 'writer' refers to an implementation of one of
|
|
|
|
/// these two traits.
|
2016-08-04 03:11:50 +03:00
|
|
|
///
|
2016-08-04 04:33:50 +03:00
|
|
|
/// Passed arguments will be formatted according to the specified format string and the resulting
|
|
|
|
/// string will be passed to the writer.
|
2015-08-27 14:24:53 -04:00
|
|
|
///
|
|
|
|
/// See [`std::fmt`][fmt] for more information on format syntax.
|
|
|
|
///
|
2016-10-29 15:44:43 -07:00
|
|
|
/// `write!` returns whatever the 'write_fmt' method returns.
|
2016-08-04 04:33:50 +03:00
|
|
|
///
|
2016-10-29 15:44:43 -07:00
|
|
|
/// Common return values include: [`fmt::Result`][fmt_result], [`io::Result`][io_result]
|
2016-08-04 04:33:50 +03:00
|
|
|
///
|
2016-03-07 23:55:52 -08:00
|
|
|
/// [fmt]: ../std/fmt/index.html
|
2016-08-04 03:11:50 +03:00
|
|
|
/// [fmt_write]: ../std/fmt/trait.Write.html
|
|
|
|
/// [io_write]: ../std/io/trait.Write.html
|
2016-10-29 15:44:43 -07:00
|
|
|
/// [fmt_result]: ../std/fmt/type.Result.html
|
|
|
|
/// [io_result]: ../std/io/type.Result.html
|
2014-09-15 19:29:47 -07:00
|
|
|
///
|
2015-03-11 21:11:40 -04:00
|
|
|
/// # Examples
|
2014-09-15 19:29:47 -07:00
|
|
|
///
|
|
|
|
/// ```
|
2015-03-17 13:33:26 -07:00
|
|
|
/// use std::io::Write;
|
2014-09-15 19:29:47 -07:00
|
|
|
///
|
|
|
|
/// let mut w = Vec::new();
|
2015-06-06 18:58:35 -04:00
|
|
|
/// write!(&mut w, "test").unwrap();
|
|
|
|
/// write!(&mut w, "formatted {}", "arguments").unwrap();
|
2015-08-27 14:24:53 -04:00
|
|
|
///
|
|
|
|
/// assert_eq!(w, b"testformatted arguments");
|
2014-09-15 19:29:47 -07:00
|
|
|
/// ```
|
2016-10-29 15:23:49 -07:00
|
|
|
///
|
|
|
|
/// A module can import both `std::fmt::Write` and `std::io::Write` and call `write!` on objects
|
|
|
|
/// implementing either, as objects do not typically implement both. However, the module must
|
|
|
|
/// import the traits qualified so their names do not conflict:
|
|
|
|
///
|
|
|
|
/// ```
|
|
|
|
/// use std::fmt::Write as FmtWrite;
|
|
|
|
/// use std::io::Write as IoWrite;
|
|
|
|
///
|
|
|
|
/// let mut s = String::new();
|
|
|
|
/// let mut v = Vec::new();
|
|
|
|
/// write!(&mut s, "{} {}", "abc", 123).unwrap(); // uses fmt::Write::write_fmt
|
|
|
|
/// write!(&mut v, "s = {:?}", s).unwrap(); // uses io::Write::write_fmt
|
|
|
|
/// assert_eq!(v, b"s = \"abc 123\"");
|
|
|
|
/// ```
|
2014-12-27 23:57:43 +02:00
|
|
|
#[macro_export]
|
2015-12-02 17:31:49 -08:00
|
|
|
#[stable(feature = "core", since = "1.6.0")]
|
2014-12-27 23:57:43 +02:00
|
|
|
macro_rules! write {
|
2015-04-01 19:48:49 +13:00
|
|
|
($dst:expr, $($arg:tt)*) => ($dst.write_fmt(format_args!($($arg)*)))
|
2014-12-27 23:57:43 +02:00
|
|
|
}
|
|
|
|
|
2016-10-29 15:44:43 -07:00
|
|
|
/// Write formatted data into a buffer, with a newline appended.
|
2016-08-04 03:11:50 +03:00
|
|
|
///
|
2016-08-04 04:33:50 +03:00
|
|
|
/// On all platforms, the newline is the LINE FEED character (`\n`/`U+000A`) alone
|
|
|
|
/// (no additional CARRIAGE RETURN (`\r`/`U+000D`).
|
2015-08-27 14:24:53 -04:00
|
|
|
///
|
2016-10-29 15:44:43 -07:00
|
|
|
/// This macro accepts a 'writer' (any value with a `write_fmt` method), a format string, and a
|
|
|
|
/// list of arguments to format.
|
2016-08-04 03:11:50 +03:00
|
|
|
///
|
2016-10-29 15:44:43 -07:00
|
|
|
/// The `write_fmt` method usually comes from an implementation of [`std::fmt::Write`][fmt_write]
|
|
|
|
/// or [`std::io::Write`][io_write] traits. The term 'writer' refers to an implementation of one of
|
|
|
|
/// these two traits.
|
2016-08-04 03:11:50 +03:00
|
|
|
///
|
2016-08-04 04:33:50 +03:00
|
|
|
/// Passed arguments will be formatted according to the specified format string and the resulting
|
2016-10-29 15:44:43 -07:00
|
|
|
/// string will be passed to the writer, along with the appended newline.
|
2015-08-27 14:24:53 -04:00
|
|
|
///
|
|
|
|
/// See [`std::fmt`][fmt] for more information on format syntax.
|
|
|
|
///
|
2016-10-29 15:44:43 -07:00
|
|
|
/// `write!` returns whatever the 'write_fmt' method returns.
|
2016-08-04 04:33:50 +03:00
|
|
|
///
|
2016-10-29 15:44:43 -07:00
|
|
|
/// Common return values include: [`fmt::Result`][fmt_result], [`io::Result`][io_result]
|
2016-08-04 04:33:50 +03:00
|
|
|
///
|
2016-03-07 23:55:52 -08:00
|
|
|
/// [fmt]: ../std/fmt/index.html
|
2016-08-04 03:11:50 +03:00
|
|
|
/// [fmt_write]: ../std/fmt/trait.Write.html
|
|
|
|
/// [io_write]: ../std/io/trait.Write.html
|
2016-10-29 15:44:43 -07:00
|
|
|
/// [fmt_result]: ../std/fmt/type.Result.html
|
|
|
|
/// [io_result]: ../std/io/type.Result.html
|
2015-08-27 14:24:53 -04:00
|
|
|
///
|
|
|
|
/// # Examples
|
|
|
|
///
|
|
|
|
/// ```
|
|
|
|
/// use std::io::Write;
|
|
|
|
///
|
|
|
|
/// let mut w = Vec::new();
|
|
|
|
/// writeln!(&mut w, "test").unwrap();
|
|
|
|
/// writeln!(&mut w, "formatted {}", "arguments").unwrap();
|
|
|
|
///
|
|
|
|
/// assert_eq!(&w[..], "test\nformatted arguments\n".as_bytes());
|
|
|
|
/// ```
|
2016-10-29 15:23:49 -07:00
|
|
|
///
|
|
|
|
/// A module can import both `std::fmt::Write` and `std::io::Write` and call `write!` on objects
|
|
|
|
/// implementing either, as objects do not typically implement both. However, the module must
|
|
|
|
/// import the traits qualified so their names do not conflict:
|
|
|
|
///
|
|
|
|
/// ```
|
|
|
|
/// use std::fmt::Write as FmtWrite;
|
|
|
|
/// use std::io::Write as IoWrite;
|
|
|
|
///
|
|
|
|
/// let mut s = String::new();
|
|
|
|
/// let mut v = Vec::new();
|
|
|
|
/// writeln!(&mut s, "{} {}", "abc", 123).unwrap(); // uses fmt::Write::write_fmt
|
|
|
|
/// writeln!(&mut v, "s = {:?}", s).unwrap(); // uses io::Write::write_fmt
|
|
|
|
/// assert_eq!(v, b"s = \"abc 123\\n\"\n");
|
|
|
|
/// ```
|
std: Extract librustrt out of libstd
As part of the libstd facade efforts, this commit extracts the runtime interface
out of the standard library into a standalone crate, librustrt. This crate will
provide the following services:
* Definition of the rtio interface
* Definition of the Runtime interface
* Implementation of the Task structure
* Implementation of task-local-data
* Implementation of task failure via unwinding via libunwind
* Implementation of runtime initialization and shutdown
* Implementation of thread-local-storage for the local rust Task
Notably, this crate avoids the following services:
* Thread creation and destruction. The crate does not require the knowledge of
an OS threading system, and as a result it seemed best to leave out the
`rt::thread` module from librustrt. The librustrt module does depend on
mutexes, however.
* Implementation of backtraces. There is no inherent requirement for the runtime
to be able to generate backtraces. As will be discussed later, this
functionality continues to live in libstd rather than librustrt.
As usual, a number of architectural changes were required to make this crate
possible. Users of "stable" functionality will not be impacted by this change,
but users of the `std::rt` module will likely note the changes. A list of
architectural changes made is:
* The stdout/stderr handles no longer live directly inside of the `Task`
structure. This is a consequence of librustrt not knowing about `std::io`.
These two handles are now stored inside of task-local-data.
The handles were originally stored inside of the `Task` for perf reasons, and
TLD is not currently as fast as it could be. For comparison, 100k prints goes
from 59ms to 68ms (a 15% slowdown). This appeared to me to be an acceptable
perf loss for the successful extraction of a librustrt crate.
* The `rtio` module was forced to duplicate more functionality of `std::io`. As
the module no longer depends on `std::io`, `rtio` now defines structures such
as socket addresses, addrinfo fiddly bits, etc. The primary change made was
that `rtio` now defines its own `IoError` type. This type is distinct from
`std::io::IoError` in that it does not have an enum for what error occurred,
but rather a platform-specific error code.
The native and green libraries will be updated in later commits for this
change, and the bulk of this effort was put behind updating the two libraries
for this change (with `rtio`).
* Printing a message on task failure (along with the backtrace) continues to
live in libstd, not in librustrt. This is a consequence of the above decision
to move the stdout/stderr handles to TLD rather than inside the `Task` itself.
The unwinding API now supports registration of global callback functions which
will be invoked when a task fails, allowing for libstd to register a function
to print a message and a backtrace.
The API for registering a callback is experimental and unsafe, as the
ramifications of running code on unwinding is pretty hairy.
* The `std::unstable::mutex` module has moved to `std::rt::mutex`.
* The `std::unstable::sync` module has been moved to `std::rt::exclusive` and
the type has been rewritten to not internally have an Arc and to have an RAII
guard structure when locking. Old code should stop using `Exclusive` in favor
of the primitives in `libsync`, but if necessary, old code should port to
`Arc<Exclusive<T>>`.
* The local heap has been stripped down to have fewer debugging options. None of
these were tested, and none of these have been used in a very long time.
[breaking-change]
2014-06-03 19:11:49 -07:00
|
|
|
#[macro_export]
|
2015-01-23 21:48:20 -08:00
|
|
|
#[stable(feature = "rust1", since = "1.0.0")]
|
2014-11-14 09:18:10 -08:00
|
|
|
macro_rules! writeln {
|
2015-01-06 18:02:00 -05:00
|
|
|
($dst:expr, $fmt:expr) => (
|
|
|
|
write!($dst, concat!($fmt, "\n"))
|
2015-01-06 18:46:37 -05:00
|
|
|
);
|
2015-01-06 16:16:35 -08:00
|
|
|
($dst:expr, $fmt:expr, $($arg:tt)*) => (
|
|
|
|
write!($dst, concat!($fmt, "\n"), $($arg)*)
|
2015-01-06 18:46:37 -05:00
|
|
|
);
|
2014-11-14 09:18:10 -08:00
|
|
|
}
|
std: Extract librustrt out of libstd
As part of the libstd facade efforts, this commit extracts the runtime interface
out of the standard library into a standalone crate, librustrt. This crate will
provide the following services:
* Definition of the rtio interface
* Definition of the Runtime interface
* Implementation of the Task structure
* Implementation of task-local-data
* Implementation of task failure via unwinding via libunwind
* Implementation of runtime initialization and shutdown
* Implementation of thread-local-storage for the local rust Task
Notably, this crate avoids the following services:
* Thread creation and destruction. The crate does not require the knowledge of
an OS threading system, and as a result it seemed best to leave out the
`rt::thread` module from librustrt. The librustrt module does depend on
mutexes, however.
* Implementation of backtraces. There is no inherent requirement for the runtime
to be able to generate backtraces. As will be discussed later, this
functionality continues to live in libstd rather than librustrt.
As usual, a number of architectural changes were required to make this crate
possible. Users of "stable" functionality will not be impacted by this change,
but users of the `std::rt` module will likely note the changes. A list of
architectural changes made is:
* The stdout/stderr handles no longer live directly inside of the `Task`
structure. This is a consequence of librustrt not knowing about `std::io`.
These two handles are now stored inside of task-local-data.
The handles were originally stored inside of the `Task` for perf reasons, and
TLD is not currently as fast as it could be. For comparison, 100k prints goes
from 59ms to 68ms (a 15% slowdown). This appeared to me to be an acceptable
perf loss for the successful extraction of a librustrt crate.
* The `rtio` module was forced to duplicate more functionality of `std::io`. As
the module no longer depends on `std::io`, `rtio` now defines structures such
as socket addresses, addrinfo fiddly bits, etc. The primary change made was
that `rtio` now defines its own `IoError` type. This type is distinct from
`std::io::IoError` in that it does not have an enum for what error occurred,
but rather a platform-specific error code.
The native and green libraries will be updated in later commits for this
change, and the bulk of this effort was put behind updating the two libraries
for this change (with `rtio`).
* Printing a message on task failure (along with the backtrace) continues to
live in libstd, not in librustrt. This is a consequence of the above decision
to move the stdout/stderr handles to TLD rather than inside the `Task` itself.
The unwinding API now supports registration of global callback functions which
will be invoked when a task fails, allowing for libstd to register a function
to print a message and a backtrace.
The API for registering a callback is experimental and unsafe, as the
ramifications of running code on unwinding is pretty hairy.
* The `std::unstable::mutex` module has moved to `std::rt::mutex`.
* The `std::unstable::sync` module has been moved to `std::rt::exclusive` and
the type has been rewritten to not internally have an Arc and to have an RAII
guard structure when locking. Old code should stop using `Exclusive` in favor
of the primitives in `libsync`, but if necessary, old code should port to
`Arc<Exclusive<T>>`.
* The local heap has been stripped down to have fewer debugging options. None of
these were tested, and none of these have been used in a very long time.
[breaking-change]
2014-06-03 19:11:49 -07:00
|
|
|
|
2014-09-15 19:29:47 -07:00
|
|
|
/// 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:
|
|
|
|
///
|
2015-03-12 22:42:38 -04:00
|
|
|
/// ```
|
2015-11-03 15:27:03 +00:00
|
|
|
/// # #[allow(dead_code)]
|
2015-03-25 17:06:52 -07:00
|
|
|
/// fn foo(x: Option<i32>) {
|
2014-09-15 19:29:47 -07:00
|
|
|
/// 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:
|
|
|
|
///
|
2015-03-12 22:42:38 -04:00
|
|
|
/// ```
|
2015-11-03 15:27:03 +00:00
|
|
|
/// # #[allow(dead_code)]
|
2014-09-15 19:29:47 -07:00
|
|
|
/// fn divide_by_three(x: u32) -> u32 { // one of the poorest implementations of x/3
|
2015-03-30 11:00:05 -07:00
|
|
|
/// for i in 0.. {
|
2014-09-15 19:29:47 -07:00
|
|
|
/// if 3*i < i { panic!("u32 overflow"); }
|
|
|
|
/// if x < 3*i { return i-1; }
|
|
|
|
/// }
|
|
|
|
/// unreachable!();
|
|
|
|
/// }
|
|
|
|
/// ```
|
2014-06-07 11:13:26 -07:00
|
|
|
#[macro_export]
|
2015-12-02 17:31:49 -08:00
|
|
|
#[stable(feature = "core", since = "1.6.0")]
|
2014-09-15 19:29:47 -07:00
|
|
|
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)*)
|
|
|
|
});
|
|
|
|
}
|
2014-11-14 09:18:10 -08:00
|
|
|
|
2015-10-13 09:44:11 -04:00
|
|
|
/// A standardized placeholder for marking unfinished code. It panics with the
|
2014-09-15 19:29:47 -07:00
|
|
|
/// message `"not yet implemented"` when executed.
|
2015-08-27 14:14:03 -04:00
|
|
|
///
|
|
|
|
/// This can be useful if you are prototyping and are just looking to have your
|
|
|
|
/// code typecheck, or if you're implementing a trait that requires multiple
|
|
|
|
/// methods, and you're only planning on using one of them.
|
|
|
|
///
|
|
|
|
/// # Examples
|
|
|
|
///
|
|
|
|
/// Here's an example of some in-progress code. We have a trait `Foo`:
|
|
|
|
///
|
|
|
|
/// ```
|
|
|
|
/// trait Foo {
|
|
|
|
/// fn bar(&self);
|
|
|
|
/// fn baz(&self);
|
|
|
|
/// }
|
|
|
|
/// ```
|
|
|
|
///
|
|
|
|
/// We want to implement `Foo` on one of our types, but we also want to work on
|
|
|
|
/// just `bar()` first. In order for our code to compile, we need to implement
|
|
|
|
/// `baz()`, so we can use `unimplemented!`:
|
|
|
|
///
|
|
|
|
/// ```
|
|
|
|
/// # trait Foo {
|
|
|
|
/// # fn bar(&self);
|
2015-11-12 00:47:42 +09:00
|
|
|
/// # fn baz(&self);
|
2015-08-27 14:14:03 -04:00
|
|
|
/// # }
|
|
|
|
/// struct MyStruct;
|
|
|
|
///
|
|
|
|
/// impl Foo for MyStruct {
|
2015-11-12 00:47:42 +09:00
|
|
|
/// fn bar(&self) {
|
2015-08-27 14:14:03 -04:00
|
|
|
/// // implementation goes here
|
|
|
|
/// }
|
|
|
|
///
|
2015-11-12 00:47:42 +09:00
|
|
|
/// fn baz(&self) {
|
|
|
|
/// // let's not worry about implementing baz() for now
|
2015-08-27 14:14:03 -04:00
|
|
|
/// unimplemented!();
|
|
|
|
/// }
|
|
|
|
/// }
|
|
|
|
///
|
|
|
|
/// fn main() {
|
|
|
|
/// let s = MyStruct;
|
2015-11-12 00:47:42 +09:00
|
|
|
/// s.bar();
|
2015-08-27 14:14:03 -04:00
|
|
|
///
|
2015-11-12 00:47:42 +09:00
|
|
|
/// // we aren't even using baz() yet, so this is fine.
|
2015-08-27 14:14:03 -04:00
|
|
|
/// }
|
|
|
|
/// ```
|
2014-09-15 19:29:47 -07:00
|
|
|
#[macro_export]
|
2015-12-02 17:31:49 -08:00
|
|
|
#[stable(feature = "core", since = "1.6.0")]
|
2014-09-15 19:29:47 -07:00
|
|
|
macro_rules! unimplemented {
|
|
|
|
() => (panic!("not yet implemented"))
|
|
|
|
}
|
2016-10-21 17:23:50 +03:00
|
|
|
|
|
|
|
/// Built-in macros to the compiler itself.
|
|
|
|
///
|
|
|
|
/// These macros do not have any corresponding definition with a `macro_rules!`
|
|
|
|
/// macro, but are documented here. Their implementations can be found hardcoded
|
|
|
|
/// into libsyntax itself.
|
|
|
|
///
|
|
|
|
/// For more information, see documentation for `std`'s macros.
|
2016-11-12 00:30:53 +01:00
|
|
|
mod builtin {
|
2016-10-21 17:23:50 +03:00
|
|
|
/// The core macro for formatted string creation & output.
|
|
|
|
///
|
|
|
|
/// For more information, see the documentation for [`std::format_args!`].
|
|
|
|
///
|
|
|
|
/// [`std::format_args!`]: ../std/macro.format_args.html
|
|
|
|
#[stable(feature = "rust1", since = "1.0.0")]
|
|
|
|
#[macro_export]
|
2016-11-12 00:30:53 +01:00
|
|
|
#[cfg(dox)]
|
2016-10-21 17:23:50 +03:00
|
|
|
macro_rules! format_args { ($fmt:expr, $($args:tt)*) => ({
|
|
|
|
/* compiler built-in */
|
|
|
|
}) }
|
|
|
|
|
|
|
|
/// Inspect an environment variable at compile time.
|
|
|
|
///
|
|
|
|
/// For more information, see the documentation for [`std::env!`].
|
|
|
|
///
|
|
|
|
/// [`std::env!`]: ../std/macro.env.html
|
|
|
|
#[stable(feature = "rust1", since = "1.0.0")]
|
|
|
|
#[macro_export]
|
2016-11-12 00:30:53 +01:00
|
|
|
#[cfg(dox)]
|
2016-10-21 17:23:50 +03:00
|
|
|
macro_rules! env { ($name:expr) => ({ /* compiler built-in */ }) }
|
|
|
|
|
|
|
|
/// Optionally inspect an environment variable at compile time.
|
|
|
|
///
|
|
|
|
/// For more information, see the documentation for [`std::option_env!`].
|
|
|
|
///
|
|
|
|
/// [`std::option_env!`]: ../std/macro.option_env.html
|
|
|
|
#[stable(feature = "rust1", since = "1.0.0")]
|
|
|
|
#[macro_export]
|
2016-11-12 00:30:53 +01:00
|
|
|
#[cfg(dox)]
|
2016-10-21 17:23:50 +03:00
|
|
|
macro_rules! option_env { ($name:expr) => ({ /* compiler built-in */ }) }
|
|
|
|
|
|
|
|
/// Concatenate identifiers into one identifier.
|
|
|
|
///
|
|
|
|
/// For more information, see the documentation for [`std::concat_idents!`].
|
|
|
|
///
|
|
|
|
/// [`std::concat_idents!`]: ../std/macro.concat_idents.html
|
2016-10-14 18:14:29 -04:00
|
|
|
#[unstable(feature = "concat_idents_macro", issue = "29599")]
|
2016-10-21 17:23:50 +03:00
|
|
|
#[macro_export]
|
2016-11-12 00:30:53 +01:00
|
|
|
#[cfg(dox)]
|
2016-10-21 17:23:50 +03:00
|
|
|
macro_rules! concat_idents {
|
|
|
|
($($e:ident),*) => ({ /* compiler built-in */ })
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Concatenates literals into a static string slice.
|
|
|
|
///
|
|
|
|
/// For more information, see the documentation for [`std::concat!`].
|
|
|
|
///
|
|
|
|
/// [`std::concat!`]: ../std/macro.concat.html
|
|
|
|
#[stable(feature = "rust1", since = "1.0.0")]
|
|
|
|
#[macro_export]
|
2016-11-12 00:30:53 +01:00
|
|
|
#[cfg(dox)]
|
2016-10-21 17:23:50 +03:00
|
|
|
macro_rules! concat { ($($e:expr),*) => ({ /* compiler built-in */ }) }
|
|
|
|
|
|
|
|
/// A macro which expands to the line number on which it was invoked.
|
|
|
|
///
|
|
|
|
/// For more information, see the documentation for [`std::line!`].
|
|
|
|
///
|
|
|
|
/// [`std::line!`]: ../std/macro.line.html
|
|
|
|
#[stable(feature = "rust1", since = "1.0.0")]
|
|
|
|
#[macro_export]
|
2016-11-12 00:30:53 +01:00
|
|
|
#[cfg(dox)]
|
2016-10-21 17:23:50 +03:00
|
|
|
macro_rules! line { () => ({ /* compiler built-in */ }) }
|
|
|
|
|
|
|
|
/// A macro which expands to the column number on which it was invoked.
|
|
|
|
///
|
|
|
|
/// For more information, see the documentation for [`std::column!`].
|
|
|
|
///
|
|
|
|
/// [`std::column!`]: ../std/macro.column.html
|
|
|
|
#[stable(feature = "rust1", since = "1.0.0")]
|
|
|
|
#[macro_export]
|
2016-11-12 00:30:53 +01:00
|
|
|
#[cfg(dox)]
|
2016-10-21 17:23:50 +03:00
|
|
|
macro_rules! column { () => ({ /* compiler built-in */ }) }
|
|
|
|
|
|
|
|
/// A macro which expands to the file name from which it was invoked.
|
|
|
|
///
|
|
|
|
/// For more information, see the documentation for [`std::file!`].
|
|
|
|
///
|
|
|
|
/// [`std::file!`]: ../std/macro.file.html
|
|
|
|
#[stable(feature = "rust1", since = "1.0.0")]
|
|
|
|
#[macro_export]
|
2016-11-12 00:30:53 +01:00
|
|
|
#[cfg(dox)]
|
2016-10-21 17:23:50 +03:00
|
|
|
macro_rules! file { () => ({ /* compiler built-in */ }) }
|
|
|
|
|
|
|
|
/// A macro which stringifies its argument.
|
|
|
|
///
|
|
|
|
/// For more information, see the documentation for [`std::stringify!`].
|
|
|
|
///
|
|
|
|
/// [`std::stringify!`]: ../std/macro.stringify.html
|
|
|
|
#[stable(feature = "rust1", since = "1.0.0")]
|
|
|
|
#[macro_export]
|
2016-11-12 00:30:53 +01:00
|
|
|
#[cfg(dox)]
|
2016-10-21 17:23:50 +03:00
|
|
|
macro_rules! stringify { ($t:tt) => ({ /* compiler built-in */ }) }
|
|
|
|
|
|
|
|
/// Includes a utf8-encoded file as a string.
|
|
|
|
///
|
|
|
|
/// For more information, see the documentation for [`std::include_str!`].
|
|
|
|
///
|
|
|
|
/// [`std::include_str!`]: ../std/macro.include_str.html
|
|
|
|
#[stable(feature = "rust1", since = "1.0.0")]
|
|
|
|
#[macro_export]
|
2016-11-12 00:30:53 +01:00
|
|
|
#[cfg(dox)]
|
2016-10-21 17:23:50 +03:00
|
|
|
macro_rules! include_str { ($file:expr) => ({ /* compiler built-in */ }) }
|
|
|
|
|
|
|
|
/// Includes a file as a reference to a byte array.
|
|
|
|
///
|
|
|
|
/// For more information, see the documentation for [`std::include_bytes!`].
|
|
|
|
///
|
|
|
|
/// [`std::include_bytes!`]: ../std/macro.include_bytes.html
|
|
|
|
#[stable(feature = "rust1", since = "1.0.0")]
|
|
|
|
#[macro_export]
|
2016-11-12 00:30:53 +01:00
|
|
|
#[cfg(dox)]
|
2016-10-21 17:23:50 +03:00
|
|
|
macro_rules! include_bytes { ($file:expr) => ({ /* compiler built-in */ }) }
|
|
|
|
|
|
|
|
/// Expands to a string that represents the current module path.
|
|
|
|
///
|
|
|
|
/// For more information, see the documentation for [`std::module_path!`].
|
|
|
|
///
|
|
|
|
/// [`std::module_path!`]: ../std/macro.module_path.html
|
|
|
|
#[stable(feature = "rust1", since = "1.0.0")]
|
|
|
|
#[macro_export]
|
2016-11-12 00:30:53 +01:00
|
|
|
#[cfg(dox)]
|
2016-10-21 17:23:50 +03:00
|
|
|
macro_rules! module_path { () => ({ /* compiler built-in */ }) }
|
|
|
|
|
|
|
|
/// Boolean evaluation of configuration flags.
|
|
|
|
///
|
|
|
|
/// For more information, see the documentation for [`std::cfg!`].
|
|
|
|
///
|
|
|
|
/// [`std::cfg!`]: ../std/macro.cfg.html
|
|
|
|
#[stable(feature = "rust1", since = "1.0.0")]
|
|
|
|
#[macro_export]
|
2016-11-12 00:30:53 +01:00
|
|
|
#[cfg(dox)]
|
2016-10-21 17:23:50 +03:00
|
|
|
macro_rules! cfg { ($($cfg:tt)*) => ({ /* compiler built-in */ }) }
|
|
|
|
|
2016-10-21 17:44:19 +03:00
|
|
|
/// Parse a file as an expression or an item according to the context.
|
2016-10-21 17:23:50 +03:00
|
|
|
///
|
|
|
|
/// For more information, see the documentation for [`std::include!`].
|
|
|
|
///
|
|
|
|
/// [`std::include!`]: ../std/macro.include.html
|
|
|
|
#[stable(feature = "rust1", since = "1.0.0")]
|
|
|
|
#[macro_export]
|
2016-11-12 00:30:53 +01:00
|
|
|
#[cfg(dox)]
|
2016-10-21 17:23:50 +03:00
|
|
|
macro_rules! include { ($file:expr) => ({ /* compiler built-in */ }) }
|
|
|
|
}
|