auto merge of #16895 : alexcrichton/rust/rollup, r=alexcrichton

Let's try this again!
This commit is contained in:
bors 2014-08-31 08:26:30 +00:00
commit db47aa5bdf
22 changed files with 385 additions and 228 deletions

View File

@ -729,6 +729,31 @@ This part is coming soon.
This part is coming soon.
# Patterns and `ref`
When you're trying to match something that's stored in a pointer, there may be
a situation where matching directly isn't the best option available. Let's see
how to properly handle this:
```{rust,ignore}
fn possibly_print(x: &Option<String>) {
match *x {
// BAD: cannot move out of a `&`
Some(s) => println!("{}", s)
// GOOD: instead take a reference into the memory of the `Option`
Some(ref s) => println!("{}", *s),
None => {}
}
}
```
The `ref s` here means that `s` will be of type `&String`, rather than type
`String`.
This is important when the type you're trying to get access to has a destructor
and you don't want to move it, you just want a reference to it.
# Cheat Sheet
Here's a quick rundown of Rust's pointer types:

View File

@ -297,7 +297,7 @@ $ mv hello_world.rs src/hello_world.rs
```
Cargo expects your source files to live inside a `src` directory. That leaves
the top level for other things, like READMEs, licence information, and anything
the top level for other things, like READMEs, license information, and anything
not related to your code. Cargo helps us keep our projects nice and tidy. A
place for everything, and everything in its place.
@ -315,7 +315,7 @@ Put this inside:
[package]
name = "hello_world"
version = "0.1.0"
version = "0.0.1"
authors = [ "Your name <you@example.com>" ]
[[bin]]
@ -630,7 +630,7 @@ In Rust, however, using `let` to introduce a binding is _not_ an expression. The
following will produce a compile-time error:
```{ignore}
let x = (let y = 5i); // found `let` in ident position
let x = (let y = 5i); // expected identifier, found keyword `let`
```
The compiler is telling us here that it was expecting to see the beginning of
@ -1743,7 +1743,7 @@ fn main() {
}
```
Sometimes, this makes things more readable. Sometimes, less. Use your judgement
Sometimes, this makes things more readable. Sometimes, less. Use your judgment
here.
That's all you need to get basic input from the standard input! It's not too
@ -1813,7 +1813,7 @@ Try it out:
```{notrust,ignore}
$ cargo run
Compiling guessing_game v0.1.0 (file:///home/you/projects/guessing_game)
Compiling guessing_game v0.0.1 (file:///home/you/projects/guessing_game)
Running `target/guessing_game`
Hello, world!
```
@ -1959,7 +1959,7 @@ Try running our new program a few times:
```{notrust,ignore}
$ cargo run
Compiling guessing_game v0.1.0 (file:///home/you/projects/guessing_game)
Compiling guessing_game v0.0.1 (file:///home/you/projects/guessing_game)
Running `target/guessing_game`
Guess the number!
The secret number is: 7
@ -2012,7 +2012,7 @@ And trying it out:
```{notrust,ignore}
$ cargo run
Compiling guessing_game v0.1.0 (file:///home/you/projects/guessing_game)
Compiling guessing_game v0.0.1 (file:///home/you/projects/guessing_game)
Running `target/guessing_game`
Guess the number!
The secret number is: 57
@ -2283,7 +2283,7 @@ print an error message and return. Let's give this a shot:
```{notrust,ignore}
$ cargo run
Compiling guessing_game v0.1.0 (file:///home/you/projects/guessing_game)
Compiling guessing_game v0.0.1 (file:///home/you/projects/guessing_game)
Running `target/guessing_game`
Guess the number!
The secret number is: 17
@ -2348,7 +2348,7 @@ Let's try it!
```{notrust,ignore}
$ cargo run
Compiling guessing_game v0.1.0 (file:///home/you/projects/guessing_game)
Compiling guessing_game v0.0.1 (file:///home/you/projects/guessing_game)
Running `target/guessing_game`
Guess the number!
The secret number is: 58
@ -2425,7 +2425,7 @@ that `return`? If we give a non-number answer, we'll `return` and quit. Observe:
```{notrust,ignore}
$ cargo run
Compiling guessing_game v0.1.0 (file:///home/you/projects/guessing_game)
Compiling guessing_game v0.0.1 (file:///home/you/projects/guessing_game)
Running `target/guessing_game`
Guess the number!
The secret number is: 59
@ -2557,7 +2557,7 @@ Now we should be good! Let's try:
```{notrust,ignore}
$ cargo run
Compiling guessing_game v0.1.0 (file:///home/you/projects/guessing_game)
Compiling guessing_game v0.0.1 (file:///home/you/projects/guessing_game)
Running `target/guessing_game`
Guess the number!
The secret number is: 61
@ -2659,7 +2659,7 @@ modules, which can contain other modules, as deeply as you'd like.
Note that we haven't mentioned anything about files yet. Rust does not impose a
particular relationship between your filesystem structure and your module
structure. That said, there is a conventional approach to how Rust looks for
modules on the file system, but it's also overrideable.
modules on the file system, but it's also overridable.
Enough talk, let's build something! Let's make a new project called `modules`.
@ -2670,10 +2670,10 @@ $ cargo new modules --bin
Let's double check our work by compiling:
```{bash,ignore}
$ cargo build
```{bash,notrust}
$ cargo run
Compiling modules v0.0.1 (file:///home/you/projects/modules)
$ ./target/modules
Running `target/modules`
Hello, world!
```
@ -3011,7 +3011,7 @@ markers.
Rust provides six attributes to indicate the stability level of various
parts of your library. The six levels are:
* deprecated: this item should no longer be used. No guarantee of backwards
* deprecated: This item should no longer be used. No guarantee of backwards
compatibility.
* experimental: This item was only recently introduced or is otherwise in a
state of flux. It may change significantly, or even be removed. No guarantee
@ -3300,7 +3300,7 @@ To learn more, run the command again with --verbose.
Rust can't find this function. That makes sense, as we didn't write it yet!
In order to share this codes with our tests, we'll need to make a library crate.
In order to share this code with our tests, we'll need to make a library crate.
This is also just good software design: as we mentioned before, it's a good idea
to put most of your functionality into a library crate, and have your executable
crate use that library. This allows for code re-use.
@ -3511,7 +3511,7 @@ exporting the name again, somewhere else.
We've now covered the basics of testing. Rust's tools are primitive, but they
work well in the simple cases. There are some Rustaceans working on building
more complicated frameworks on top of all of this, but thery're just starting
more complicated frameworks on top of all of this, but they're just starting
out.
# Pointers
@ -3668,15 +3668,20 @@ because it's easy. And if you need precise control over when something is
deallocated, leaving it up to your runtime can make this difficult.
Rust chooses a different path, and that path is called **ownership**. Any
binding that creates a resource is the **owner** of that resource. Being an
owner gives you three privileges, with two restrictions:
binding that creates a resource is the **owner** of that resource.
Being an owner affords you some privileges:
1. You control when that resource is deallocated.
2. You may lend that resource, immutably, to as many borrowers as you'd like.
3. You may lend that resource, mutably, to a single borrower. **BUT**
4. Once you've done so, you may not also lend it out otherwise, mutably or
immutably.
5. You may not lend it out mutably if you're currently lending it to someone.
3. You may lend that resource, mutably, to a single borrower.
But it also comes with some restrictions:
1. If someone is borrowing your resource (either mutably or immutably), you may
not mutate the resource or mutably lend it to someone.
2. If someone is mutably borrowing your resource, you may not lend it out at
all (mutably or immutably) or access it in any way.
What's up with all this 'lending' and 'borrowing'? When you allocate memory,
you get a pointer to that memory. This pointer allows you to manipulate said
@ -4063,7 +4068,7 @@ match x {
}
```
If you have a struct, you can desugar it inside of a pattern:
If you have a struct, you can destructure it inside of a pattern:
```{rust}
struct Point {
@ -4223,7 +4228,7 @@ don't need to declare one. This is different from named functions, which
default to returning unit (`()`).
There's one big difference between a closure and named functions, and it's in
the name: a function "closes over its environment." What's that mean? It means
the name: a closure "closes over its environment." What's that mean? It means
this:
```{rust}
@ -5494,7 +5499,7 @@ fn main() {
Whew! This isn't too terrible. You can see that we still `let x = 5i`,
but then things get a little bit hairy. Three more bindings get set: a
static format string, an argument vector, and the aruments. We then
static format string, an argument vector, and the arguments. We then
invoke the `println_args` function with the generated arguments.
This is the code (well, the full version) that Rust actually compiles. You can
@ -5510,7 +5515,7 @@ Guide can help you if you want to write your own.
# Unsafe
Finally, there's one more concept that you should be aware in Rust: `unsafe`.
Finally, there's one more Rust concept that you should be aware of: `unsafe`.
There are two circumstances where Rust's safety provisions don't work well.
The first is when interfacing with C code, and the second is when building
certain kinds of abstractions.

View File

@ -2215,14 +2215,14 @@ These types help drive the compiler's analysis
* `begin_unwind`
: ___Needs filling in___
* `managed_bound`
: This type implements "managed"
* `no_copy_bound`
: This type does not implement "copy", even if eligible
* `no_send_bound`
: This type does not implement "send", even if eligible
* `no_sync_bound`
: This type does not implement "sync", even if eligible
* `managed_bound`
: This type implements "managed"
* `no_share_bound`
: This type does not implement "share", even if eligible
* `eh_personality`
: ___Needs filling in___
* `exchange_free`

View File

@ -12,7 +12,7 @@
//!
//! This is the lowest level library through which allocation in Rust can be
//! performed where the allocation is assumed to succeed. This library will
//! trigger a task failure when allocation fails.
//! abort the process when allocation fails.
//!
//! This library, like libcore, is not intended for general usage, but rather as
//! a building block of other libraries. The types and interfaces in this

View File

@ -160,6 +160,8 @@ pub trait Signed: Num + Neg<Self> {
/// Computes the absolute value.
///
/// For `f32` and `f64`, `NaN` will be returned if the number is `NaN`.
///
/// For signed integers, `::MIN` will be returned if the number is `::MIN`.
fn abs(&self) -> Self;
/// The positive difference of two numbers.
@ -176,7 +178,7 @@ pub trait Signed: Num + Neg<Self> {
/// * `-1.0` if the number is negative, `-0.0` or `NEG_INFINITY`
/// * `NaN` if the number is `NaN`
///
/// For `int`:
/// For signed integers:
///
/// * `0` if the number is zero
/// * `1` if the number is positive
@ -272,6 +274,8 @@ signed_float_impl!(f64, f64::NAN, f64::INFINITY, f64::NEG_INFINITY,
/// Computes the absolute value.
///
/// For `f32` and `f64`, `NaN` will be returned if the number is `NaN`
///
/// For signed integers, `::MIN` will be returned if the number is `::MIN`.
#[inline(always)]
pub fn abs<T: Signed>(value: T) -> T {
value.abs()
@ -294,7 +298,7 @@ pub fn abs_sub<T: Signed>(x: T, y: T) -> T {
/// * `-1.0` if the number is negative, `-0.0` or `NEG_INFINITY`
/// * `NaN` if the number is `NaN`
///
/// For int:
/// For signed integers:
///
/// * `0` if the number is zero
/// * `1` if the number is positive

View File

@ -57,31 +57,31 @@ use raw::Slice as RawSlice;
// Extension traits
//
/// Extension methods for vectors
/// Extension methods for immutable slices.
#[unstable = "may merge with other traits; region parameter may disappear"]
pub trait ImmutableSlice<'a, T> {
/**
* Returns a slice of self spanning the interval [`start`, `end`).
*
* Fails when the slice (or part of it) is outside the bounds of self,
* or when `start` > `end`.
*/
/// Returns a subslice spanning the interval [`start`, `end`).
///
/// Fails when the end of the new slice lies beyond the end of the
/// original slice (i.e. when `end > self.len()`) or when `start > end`.
///
/// Slicing with `start` equal to `end` yields an empty slice.
#[unstable]
fn slice(&self, start: uint, end: uint) -> &'a [T];
/**
* Returns a slice of self from `start` to the end of the vec.
*
* Fails when `start` points outside the bounds of self.
*/
/// Returns a subslice from `start` to the end of the slice.
///
/// Fails when `start` is strictly greater than the length of the original slice.
///
/// Slicing from `self.len()` yields an empty slice.
#[unstable]
fn slice_from(&self, start: uint) -> &'a [T];
/**
* Returns a slice of self from the start of the vec to `end`.
*
* Fails when `end` points outside the bounds of self.
*/
/// Returns a subslice from the start of the slice to `end`.
///
/// Fails when `end` is strictly greater than the length of the original slice.
///
/// Slicing to `0` yields an empty slice.
#[unstable]
fn slice_to(&self, end: uint) -> &'a [T];
@ -486,21 +486,26 @@ pub trait MutableSlice<'a, T> {
/// Primarily intended for getting a &mut [T] from a [T, ..N].
fn as_mut_slice(self) -> &'a mut [T];
/// Return a slice that points into another slice.
/// Returns a mutable subslice spanning the interval [`start`, `end`).
///
/// Fails when the end of the new slice lies beyond the end of the
/// original slice (i.e. when `end > self.len()`) or when `start > end`.
///
/// Slicing with `start` equal to `end` yields an empty slice.
fn mut_slice(self, start: uint, end: uint) -> &'a mut [T];
/**
* Returns a slice of self from `start` to the end of the vec.
*
* Fails when `start` points outside the bounds of self.
*/
/// Returns a mutable subslice from `start` to the end of the slice.
///
/// Fails when `start` is strictly greater than the length of the original slice.
///
/// Slicing from `self.len()` yields an empty slice.
fn mut_slice_from(self, start: uint) -> &'a mut [T];
/**
* Returns a slice of self from the start of the vec to `end`.
*
* Fails when `end` points outside the bounds of self.
*/
/// Returns a mutable subslice from the start of the slice to `end`.
///
/// Fails when `end` is strictly greater than the length of the original slice.
///
/// Slicing to `0` yields an empty slice.
fn mut_slice_to(self, end: uint) -> &'a mut [T];
/// Returns an iterator that allows modifying each value
@ -515,14 +520,14 @@ pub trait MutableSlice<'a, T> {
fn mut_split(self, pred: |&T|: 'a -> bool) -> MutSplits<'a, T>;
/**
* Returns an iterator over `size` elements of the vector at a time.
* The chunks are mutable and do not overlap. If `size` does not divide the
* length of the vector, then the last chunk will not have length
* `size`.
* Returns an iterator over `chunk_size` elements of the vector at a time.
* The chunks are mutable and do not overlap. If `chunk_size` does
* not divide the length of the vector, then the last chunk will not
* have length `chunk_size`.
*
* # Failure
*
* Fails if `size` is 0.
* Fails if `chunk_size` is 0.
*/
fn mut_chunks(self, chunk_size: uint) -> MutChunks<'a, T>;

View File

@ -8,120 +8,154 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
/*!
Utilities for program-wide and customizable logging
## Example
```
#![feature(phase)]
#[phase(plugin, link)] extern crate log;
fn main() {
debug!("this is a debug {}", "message");
error!("this is printed by default");
if log_enabled!(log::INFO) {
let x = 3i * 4i; // expensive computation
info!("the answer was: {}", x);
}
}
```
## Logging Macros
There are five macros that the logging subsystem uses:
* `log!(level, ...)` - the generic logging macro, takes a level as a u32 and any
related `format!` arguments
* `debug!(...)` - a macro hard-wired to the log level of `DEBUG`
* `info!(...)` - a macro hard-wired to the log level of `INFO`
* `warn!(...)` - a macro hard-wired to the log level of `WARN`
* `error!(...)` - a macro hard-wired to the log level of `ERROR`
All of these macros use the same style of syntax as the `format!` syntax
extension. Details about the syntax can be found in the documentation of
`std::fmt` along with the Rust tutorial/manual.
If you want to check at runtime if a given logging level is enabled (e.g. if the
information you would want to log is expensive to produce), you can use the
following macro:
* `log_enabled!(level)` - returns true if logging of the given level is enabled
## Enabling logging
Log levels are controlled on a per-module basis, and by default all logging is
disabled except for `error!` (a log level of 1). Logging is controlled via the
`RUST_LOG` environment variable. The value of this environment variable is a
comma-separated list of logging directives. A logging directive is of the form:
```text
path::to::module=log_level
```
The path to the module is rooted in the name of the crate it was compiled for,
so if your program is contained in a file `hello.rs`, for example, to turn on
logging for this file you would use a value of `RUST_LOG=hello`.
Furthermore, this path is a prefix-search, so all modules nested in the
specified module will also have logging enabled.
The actual `log_level` is optional to specify. If omitted, all logging will be
enabled. If specified, the it must be either a numeric in the range of 1-255, or
it must be one of the strings `debug`, `error`, `info`, or `warn`. If a numeric
is specified, then all logging less than or equal to that numeral is enabled.
For example, if logging level 3 is active, error, warn, and info logs will be
printed, but debug will be omitted.
As the log level for a module is optional, the module to enable logging for is
also optional. If only a `log_level` is provided, then the global log level for
all modules is set to this value.
Some examples of valid values of `RUST_LOG` are:
* `hello` turns on all logging for the 'hello' module
* `info` turns on all info logging
* `hello=debug` turns on debug logging for 'hello'
* `hello=3` turns on info logging for 'hello'
* `hello,std::option` turns on hello, and std's option logging
* `error,hello=warn` turn on global error logging and also warn for hello
## Filtering results
A RUST_LOG directive may include a regex filter. The syntax is to append `/`
followed by a regex. Each message is checked against the regex, and is only
logged if it matches. Note that the matching is done after formatting the log
string but before adding any logging meta-data. There is a single filter for all
modules.
Some examples:
* `hello/foo` turns on all logging for the 'hello' module where the log message
includes 'foo'.
* `info/f.o` turns on all info logging where the log message includes 'foo',
'f1o', 'fao', etc.
* `hello=debug/foo*foo` turns on debug logging for 'hello' where the the log
message includes 'foofoo' or 'fofoo' or 'fooooooofoo', etc.
* `error,hello=warn/[0-9] scopes` turn on global error logging and also warn for
hello. In both cases the log message must include a single digit number
followed by 'scopes'
## Performance and Side Effects
Each of these macros will expand to code similar to:
```rust,ignore
if log_level <= my_module_log_level() {
::log::log(log_level, format!(...));
}
```
What this means is that each of these macros are very cheap at runtime if
they're turned off (just a load and an integer comparison). This also means that
if logging is disabled, none of the components of the log will be executed.
*/
//! Utilities for program-wide and customizable logging
//!
//! ## Example
//!
//! ```
//! #![feature(phase)]
//! #[phase(plugin, link)] extern crate log;
//!
//! fn main() {
//! debug!("this is a debug {}", "message");
//! error!("this is printed by default");
//!
//! if log_enabled!(log::INFO) {
//! let x = 3i * 4i; // expensive computation
//! info!("the answer was: {}", x);
//! }
//! }
//! ```
//!
//! Assumes the binary is `main`:
//!
//! ```{.bash}
//! $ RUST_LOG=error ./main
//! ERROR:main: this is printed by default
//! ```
//!
//! ```{.bash}
//! $ RUST_LOG=info ./main
//! ERROR:main: this is printed by default
//! INFO:main: the answer was: 12
//! ```
//!
//! ```{.bash}
//! $ RUST_LOG=debug ./main
//! DEBUG:main: this is a debug message
//! ERROR:main: this is printed by default
//! INFO:main: the answer was: 12
//! ```
//!
//! You can also set the log level on a per module basis:
//!
//! ```{.bash}
//! $ RUST_LOG=main=info ./main
//! ERROR:main: this is printed by default
//! INFO:main: the answer was: 12
//! ```
//!
//! And enable all logging:
//!
//! ```{.bash}
//! $ RUST_LOG=main ./main
//! DEBUG:main: this is a debug message
//! ERROR:main: this is printed by default
//! INFO:main: the answer was: 12
//! ```
//!
//!
//! ## Logging Macros
//!
//! There are five macros that the logging subsystem uses:
//!
//! * `log!(level, ...)` - the generic logging macro, takes a level as a u32 and any
//! related `format!` arguments
//! * `debug!(...)` - a macro hard-wired to the log level of `DEBUG`
//! * `info!(...)` - a macro hard-wired to the log level of `INFO`
//! * `warn!(...)` - a macro hard-wired to the log level of `WARN`
//! * `error!(...)` - a macro hard-wired to the log level of `ERROR`
//!
//! All of these macros use the same style of syntax as the `format!` syntax
//! extension. Details about the syntax can be found in the documentation of
//! `std::fmt` along with the Rust tutorial/manual.
//!
//! If you want to check at runtime if a given logging level is enabled (e.g. if the
//! information you would want to log is expensive to produce), you can use the
//! following macro:
//!
//! * `log_enabled!(level)` - returns true if logging of the given level is enabled
//!
//! ## Enabling logging
//!
//! Log levels are controlled on a per-module basis, and by default all logging is
//! disabled except for `error!` (a log level of 1). Logging is controlled via the
//! `RUST_LOG` environment variable. The value of this environment variable is a
//! comma-separated list of logging directives. A logging directive is of the form:
//!
//! ```text
//! path::to::module=log_level
//! ```
//!
//! The path to the module is rooted in the name of the crate it was compiled for,
//! so if your program is contained in a file `hello.rs`, for example, to turn on
//! logging for this file you would use a value of `RUST_LOG=hello`.
//! Furthermore, this path is a prefix-search, so all modules nested in the
//! specified module will also have logging enabled.
//!
//! The actual `log_level` is optional to specify. If omitted, all logging will be
//! enabled. If specified, the it must be either a numeric in the range of 1-255, or
//! it must be one of the strings `debug`, `error`, `info`, or `warn`. If a numeric
//! is specified, then all logging less than or equal to that numeral is enabled.
//! For example, if logging level 3 is active, error, warn, and info logs will be
//! printed, but debug will be omitted.
//!
//! As the log level for a module is optional, the module to enable logging for is
//! also optional. If only a `log_level` is provided, then the global log level for
//! all modules is set to this value.
//!
//! Some examples of valid values of `RUST_LOG` are:
//!
//! * `hello` turns on all logging for the 'hello' module
//! * `info` turns on all info logging
//! * `hello=debug` turns on debug logging for 'hello'
//! * `hello=3` turns on info logging for 'hello'
//! * `hello,std::option` turns on hello, and std's option logging
//! * `error,hello=warn` turn on global error logging and also warn for hello
//!
//! ## Filtering results
//!
//! A RUST_LOG directive may include a regex filter. The syntax is to append `/`
//! followed by a regex. Each message is checked against the regex, and is only
//! logged if it matches. Note that the matching is done after formatting the log
//! string but before adding any logging meta-data. There is a single filter for all
//! modules.
//!
//! Some examples:
//!
//! * `hello/foo` turns on all logging for the 'hello' module where the log message
//! includes 'foo'.
//! * `info/f.o` turns on all info logging where the log message includes 'foo',
//! 'f1o', 'fao', etc.
//! * `hello=debug/foo*foo` turns on debug logging for 'hello' where the the log
//! message includes 'foofoo' or 'fofoo' or 'fooooooofoo', etc.
//! * `error,hello=warn/[0-9] scopes` turn on global error logging and also warn for
//! hello. In both cases the log message must include a single digit number
//! followed by 'scopes'
//!
//! ## Performance and Side Effects
//!
//! Each of these macros will expand to code similar to:
//!
//! ```rust,ignore
//! if log_level <= my_module_log_level() {
//! ::log::log(log_level, format!(...));
//! }
//! ```
//!
//! What this means is that each of these macros are very cheap at runtime if
//! they're turned off (just a load and an integer comparison). This also means that
//! if logging is disabled, none of the components of the log will be executed.
#![crate_name = "log"]
#![experimental]

View File

@ -24,11 +24,31 @@
/// #![feature(phase)]
/// #[phase(plugin, link)] extern crate log;
///
/// # fn main() {
/// log!(log::DEBUG, "this is a debug message");
/// log!(log::WARN, "this is a warning {}", "message");
/// log!(6, "this is a custom logging level: {level}", level=6u);
/// # }
/// fn main() {
/// log!(log::WARN, "this is a warning {}", "message");
/// log!(log::DEBUG, "this is a debug message");
/// log!(6, "this is a custom logging level: {level}", level=6u);
/// }
/// ```
///
/// Assumes the binary is `main`:
///
/// ```{.bash}
/// $ RUST_LOG=warn ./main
/// WARN:main: this is a warning message
/// ```
///
/// ```{.bash}
/// $ RUST_LOG=debug ./main
/// DEBUG:main: this is a debug message
/// WARN:main: this is a warning message
/// ```
///
/// ```{.bash}
/// $ RUST_LOG=6 ./main
/// DEBUG:main: this is a debug message
/// WARN:main: this is a warning message
/// 6:main: this is a custom logging level: 6
/// ```
#[macro_export]
macro_rules! log(
@ -53,11 +73,19 @@ macro_rules! log(
/// #![feature(phase)]
/// #[phase(plugin, link)] extern crate log;
///
/// # fn main() {
/// # let error = 3u;
/// error!("the build has failed with error code: {}", error);
/// # }
/// fn main() {
/// let error = 3u;
/// error!("the build has failed with error code: {}", error);
/// }
/// ```
///
/// Assumes the binary is `main`:
///
/// ```{.bash}
/// $ RUST_LOG=error ./main
/// ERROR:main: the build has failed with error code: 3
/// ```
///
#[macro_export]
macro_rules! error(
($($arg:tt)*) => (log!(::log::ERROR, $($arg)*))
@ -71,10 +99,17 @@ macro_rules! error(
/// #![feature(phase)]
/// #[phase(plugin, link)] extern crate log;
///
/// # fn main() {
/// # let code = 3u;
/// warn!("you may like to know that a process exited with: {}", code);
/// # }
/// fn main() {
/// let code = 3u;
/// warn!("you may like to know that a process exited with: {}", code);
/// }
/// ```
///
/// Assumes the binary is `main`:
///
/// ```{.bash}
/// $ RUST_LOG=warn ./main
/// WARN:main: you may like to know that a process exited with: 3
/// ```
#[macro_export]
macro_rules! warn(
@ -89,10 +124,17 @@ macro_rules! warn(
/// #![feature(phase)]
/// #[phase(plugin, link)] extern crate log;
///
/// # fn main() {
/// # let ret = 3i;
/// info!("this function is about to return: {}", ret);
/// # }
/// fn main() {
/// let ret = 3i;
/// info!("this function is about to return: {}", ret);
/// }
/// ```
///
/// Assumes the binary is `main`:
///
/// ```{.bash}
/// $ RUST_LOG=info ./main
/// INFO:main: this function is about to return: 3
/// ```
#[macro_export]
macro_rules! info(
@ -109,9 +151,16 @@ macro_rules! info(
/// #![feature(phase)]
/// #[phase(plugin, link)] extern crate log;
///
/// # fn main() {
/// debug!("x = {x}, y = {y}", x=10i, y=20i);
/// # }
/// fn main() {
/// debug!("x = {x}, y = {y}", x=10i, y=20i);
/// }
/// ```
///
/// Assumes the binary is `main`:
///
/// ```{.bash}
/// $ RUST_LOG=debug ./main
/// DEBUG:main: x = 10, y = 20
/// ```
#[macro_export]
macro_rules! debug(
@ -126,14 +175,26 @@ macro_rules! debug(
/// #![feature(phase)]
/// #[phase(plugin, link)] extern crate log;
///
/// # fn main() {
/// # struct Point { x: int, y: int }
/// # fn some_expensive_computation() -> Point { Point { x: 1, y: 2 } }
/// if log_enabled!(log::DEBUG) {
/// let x = some_expensive_computation();
/// debug!("x.x = {}, x.y = {}", x.x, x.y);
/// struct Point { x: int, y: int }
/// fn some_expensive_computation() -> Point { Point { x: 1, y: 2 } }
///
/// fn main() {
/// if log_enabled!(log::DEBUG) {
/// let x = some_expensive_computation();
/// debug!("x.x = {}, x.y = {}", x.x, x.y);
/// }
/// }
/// # }
/// ```
///
/// Assumes the binary is `main`:
///
/// ```{.bash}
/// $ RUST_LOG=error ./main
/// ```
///
/// ```{.bash}
/// $ RUST_LOG=debug ./main
/// DEBUG:main: x.x = 1, x.y = 2
/// ```
#[macro_export]
macro_rules! log_enabled(

View File

@ -137,15 +137,14 @@ impl<T: Clone + Integer + PartialOrd>
}
/// Rounds to the nearest integer. Rounds half-way cases away from zero.
///
/// Note: This function is currently broken and always rounds away from zero.
#[inline]
pub fn round(&self) -> Ratio<T> {
// FIXME(#15826)
if *self < Zero::zero() {
Ratio::from_integer((self.numer - self.denom + One::one()) / self.denom)
// a/b - 1/2 = (2*a - b)/(2*b)
Ratio::from_integer((self.numer + self.numer - self.denom) / (self.denom + self.denom))
} else {
Ratio::from_integer((self.numer + self.denom - One::one()) / self.denom)
// a/b + 1/2 = (2*a + b)/(2*b)
Ratio::from_integer((self.numer + self.numer + self.denom) / (self.denom + self.denom))
}
}
@ -388,7 +387,11 @@ mod test {
pub static _2: Rational = Ratio { numer: 2, denom: 1};
pub static _1_2: Rational = Ratio { numer: 1, denom: 2};
pub static _3_2: Rational = Ratio { numer: 3, denom: 2};
pub static _neg1_2: Rational = Ratio { numer: -1, denom: 2};
pub static _neg1_2: Rational = Ratio { numer: -1, denom: 2};
pub static _1_3: Rational = Ratio { numer: 1, denom: 3};
pub static _neg1_3: Rational = Ratio { numer: -1, denom: 3};
pub static _2_3: Rational = Ratio { numer: 2, denom: 3};
pub static _neg2_3: Rational = Ratio { numer: -2, denom: 3};
pub fn to_big(n: Rational) -> BigRational {
Ratio::new(
@ -578,6 +581,26 @@ mod test {
#[test]
fn test_round() {
assert_eq!(_1_3.ceil(), _1);
assert_eq!(_1_3.floor(), _0);
assert_eq!(_1_3.round(), _0);
assert_eq!(_1_3.trunc(), _0);
assert_eq!(_neg1_3.ceil(), _0);
assert_eq!(_neg1_3.floor(), -_1);
assert_eq!(_neg1_3.round(), _0);
assert_eq!(_neg1_3.trunc(), _0);
assert_eq!(_2_3.ceil(), _1);
assert_eq!(_2_3.floor(), _0);
assert_eq!(_2_3.round(), _1);
assert_eq!(_2_3.trunc(), _0);
assert_eq!(_neg2_3.ceil(), _0);
assert_eq!(_neg2_3.floor(), -_1);
assert_eq!(_neg2_3.round(), -_1);
assert_eq!(_neg2_3.trunc(), _0);
assert_eq!(_1_2.ceil(), _1);
assert_eq!(_1_2.floor(), _0);
assert_eq!(_1_2.round(), _1);

View File

@ -417,7 +417,7 @@ pub fn check_crate(sess: &Session, krate: &ast::Crate) {
sess.span_err(mi.span, "feature has been removed");
}
Some(&(_, Accepted)) => {
sess.span_warn(mi.span, "feature has added to rust, \
sess.span_warn(mi.span, "feature has been added to Rust, \
directive not necessary");
}
None => {

View File

@ -599,7 +599,7 @@ impl<'a> Parser<'a> {
let token_str = self.this_token_to_string();
let span = self.span;
self.span_err(span,
format!("found `{}` in ident position",
format!("expected identifier, found keyword `{}`",
token_str).as_slice());
}
}

View File

@ -8,5 +8,5 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
fn false() { } //~ ERROR found `false` in ident position
fn false() { } //~ ERROR expected identifier, found keyword `false`
fn main() { }

View File

@ -8,5 +8,5 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
fn true() { } //~ ERROR found `true` in ident position
fn true() { } //~ ERROR expected identifier, found keyword `true`
fn main() { }

View File

@ -20,4 +20,4 @@
#![feature = "foo"] //~ ERROR: malformed feature
#![feature(test_removed_feature)] //~ ERROR: feature has been removed
#![feature(test_accepted_feature)] //~ WARNING: feature has added
#![feature(test_accepted_feature)] //~ WARNING: feature has been added

View File

@ -9,5 +9,5 @@
// except according to those terms.
fn main() {
let super: int; //~ ERROR found `super` in ident position
let super: int; //~ ERROR expected identifier, found keyword `super`
}

View File

@ -9,5 +9,5 @@
// except according to those terms.
pub mod break {
//~^ ERROR found `break` in ident position
//~^ ERROR expected identifier, found keyword `break`
}

View File

@ -10,6 +10,6 @@
struct s {
let foo: (),
//~^ ERROR found `let` in ident position
//~^ ERROR expected identifier, found keyword `let`
//~^^ ERROR expected `:`, found `foo`
}

View File

@ -10,6 +10,6 @@
fn f() {
let v = [mut 1, 2, 3, 4];
//~^ ERROR found `mut` in ident position
//~^ ERROR expected identifier, found keyword `mut`
//~^^ ERROR expected `]`, found `1`
}

View File

@ -9,5 +9,5 @@
// except according to those terms.
type v = [mut int];
//~^ ERROR found `mut` in ident position
//~^ ERROR expected identifier, found keyword `mut`
//~^^ ERROR expected `]`, found `int`

View File

@ -10,6 +10,6 @@
fn f() {
let a_box = box mut 42;
//~^ ERROR found `mut` in ident position
//~^ ERROR expected identifier, found keyword `mut`
//~^^ ERROR expected `;`, found `42`
}

View File

@ -9,5 +9,5 @@
// except according to those terms.
type mut_box = Box<mut int>;
//~^ ERROR found `mut` in ident position
//~^ ERROR expected identifier, found keyword `mut`
//~^^ ERROR expected `,`, found `int`

View File

@ -13,5 +13,5 @@
fn f<X>() {}
pub fn main() {
f<type>(); //~ ERROR found `type` in ident position
f<type>(); //~ ERROR expected identifier, found keyword `type`
}