Auto merge of #24433 - alexcrichton:rollup, r=alexcrichton

This commit is contained in:
bors 2015-04-15 01:05:03 +00:00
commit 16e1fcead1
273 changed files with 1570 additions and 25830 deletions

View File

@ -12,16 +12,16 @@
#![feature(box_syntax)] #![feature(box_syntax)]
#![feature(collections)] #![feature(collections)]
#![feature(old_io)]
#![feature(rustc_private)] #![feature(rustc_private)]
#![feature(unboxed_closures)]
#![feature(std_misc)] #![feature(std_misc)]
#![feature(test)] #![feature(test)]
#![feature(path_ext)] #![feature(path_ext)]
#![feature(str_char)] #![feature(str_char)]
#![feature(libc)]
#![deny(warnings)] #![deny(warnings)]
extern crate libc;
extern crate test; extern crate test;
extern crate getopts; extern crate getopts;
@ -42,6 +42,7 @@ pub mod header;
pub mod runtest; pub mod runtest;
pub mod common; pub mod common;
pub mod errors; pub mod errors;
mod raise_fd_limit;
pub fn main() { pub fn main() {
let config = parse_config(env::args().collect()); let config = parse_config(env::args().collect());
@ -245,11 +246,7 @@ pub fn run_tests(config: &Config) {
// sadly osx needs some file descriptor limits raised for running tests in // sadly osx needs some file descriptor limits raised for running tests in
// parallel (especially when we have lots and lots of child processes). // parallel (especially when we have lots and lots of child processes).
// For context, see #8904 // For context, see #8904
#[allow(deprecated)] unsafe { raise_fd_limit::raise_fd_limit(); }
fn raise_fd_limit() {
std::old_io::test::raise_fd_limit();
}
raise_fd_limit();
// Prevent issue #21352 UAC blocking .exe containing 'patch' etc. on Windows // Prevent issue #21352 UAC blocking .exe containing 'patch' etc. on Windows
// If #11207 is resolved (adding manifest to .exe) this becomes unnecessary // If #11207 is resolved (adding manifest to .exe) this becomes unnecessary
env::set_var("__COMPAT_LAYER", "RunAsInvoker"); env::set_var("__COMPAT_LAYER", "RunAsInvoker");

View File

@ -0,0 +1,79 @@
// Copyright 2015 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.
/// darwin_fd_limit exists to work around an issue where launchctl on Mac OS X
/// defaults the rlimit maxfiles to 256/unlimited. The default soft limit of 256
/// ends up being far too low for our multithreaded scheduler testing, depending
/// on the number of cores available.
///
/// This fixes issue #7772.
#[cfg(any(target_os = "macos", target_os = "ios"))]
#[allow(non_camel_case_types)]
pub unsafe fn raise_fd_limit() {
use libc;
use std::cmp;
use std::io;
use std::mem::size_of_val;
use std::ptr::null_mut;
type rlim_t = libc::uint64_t;
#[repr(C)]
struct rlimit {
rlim_cur: rlim_t,
rlim_max: rlim_t
}
extern {
// name probably doesn't need to be mut, but the C function doesn't
// specify const
fn sysctl(name: *mut libc::c_int, namelen: libc::c_uint,
oldp: *mut libc::c_void, oldlenp: *mut libc::size_t,
newp: *mut libc::c_void, newlen: libc::size_t) -> libc::c_int;
fn getrlimit(resource: libc::c_int, rlp: *mut rlimit) -> libc::c_int;
fn setrlimit(resource: libc::c_int, rlp: *const rlimit) -> libc::c_int;
}
static CTL_KERN: libc::c_int = 1;
static KERN_MAXFILESPERPROC: libc::c_int = 29;
static RLIMIT_NOFILE: libc::c_int = 8;
// The strategy here is to fetch the current resource limits, read the
// kern.maxfilesperproc sysctl value, and bump the soft resource limit for
// maxfiles up to the sysctl value.
// Fetch the kern.maxfilesperproc value
let mut mib: [libc::c_int; 2] = [CTL_KERN, KERN_MAXFILESPERPROC];
let mut maxfiles: libc::c_int = 0;
let mut size: libc::size_t = size_of_val(&maxfiles) as libc::size_t;
if sysctl(&mut mib[0], 2, &mut maxfiles as *mut _ as *mut _, &mut size,
null_mut(), 0) != 0 {
let err = io::Error::last_os_error();
panic!("raise_fd_limit: error calling sysctl: {}", err);
}
// Fetch the current resource limits
let mut rlim = rlimit{rlim_cur: 0, rlim_max: 0};
if getrlimit(RLIMIT_NOFILE, &mut rlim) != 0 {
let err = io::Error::last_os_error();
panic!("raise_fd_limit: error calling getrlimit: {}", err);
}
// Bump the soft limit to the smaller of kern.maxfilesperproc and the hard
// limit
rlim.rlim_cur = cmp::min(maxfiles as rlim_t, rlim.rlim_max);
// Set our newly-increased resource limit
if setrlimit(RLIMIT_NOFILE, &rlim) != 0 {
let err = io::Error::last_os_error();
panic!("raise_fd_limit: error calling setrlimit: {}", err);
}
}
#[cfg(not(any(target_os = "macos", target_os = "ios")))]
pub unsafe fn raise_fd_limit() {}

View File

@ -29,7 +29,6 @@ use std::net::TcpStream;
use std::path::{Path, PathBuf}; use std::path::{Path, PathBuf};
use std::process::{Command, Output, ExitStatus}; use std::process::{Command, Output, ExitStatus};
use std::str; use std::str;
use std::time::Duration;
use test::MetricMap; use test::MetricMap;
pub fn run(config: Config, testfile: &Path) { pub fn run(config: Config, testfile: &Path) {
@ -452,11 +451,7 @@ fn run_debuginfo_gdb_test(config: &Config, props: &TestProps, testfile: &Path) {
.expect(&format!("failed to exec `{:?}`", config.adb_path)); .expect(&format!("failed to exec `{:?}`", config.adb_path));
loop { loop {
//waiting 1 second for gdbserver start //waiting 1 second for gdbserver start
#[allow(deprecated)] ::std::thread::sleep_ms(1000);
fn sleep() {
::std::old_io::timer::sleep(Duration::milliseconds(1000));
}
sleep();
if TcpStream::connect("127.0.0.1:5039").is_ok() { if TcpStream::connect("127.0.0.1:5039").is_ok() {
break break
} }

View File

@ -15,6 +15,12 @@ Rust, its syntax, and its concepts. Upon completing the book, you'll be an
intermediate Rust developer, and will have a good grasp of the fundamental intermediate Rust developer, and will have a good grasp of the fundamental
ideas behind Rust. ideas behind Rust.
[Rust By Example][rbe] was originally a community resource, but was then
donated to the Rust project. As the name implies, it teaches you Rust through a
series of small examples.
[rbe]: rustbyexample.com
# Community & Getting Help # Community & Getting Help
If you need help with something, or just want to talk about Rust with others, If you need help with something, or just want to talk about Rust with others,
@ -76,17 +82,3 @@ We have [API documentation for the entire standard
library](std/index.html). There's a list of crates on the left with more library](std/index.html). There's a list of crates on the left with more
specific sections, or you can use the search bar at the top to search for specific sections, or you can use the search bar at the top to search for
something if you know its name. something if you know its name.
# External documentation
*Note: While these are great resources for learning Rust, they may track a
particular version of Rust that is likely not exactly the same as that for
which this documentation was generated.*
* [Rust by Example] - Short examples of common tasks in Rust (tracks the master
branch).
* [Rust for Rubyists] - The first community tutorial for Rust. Tracks the last
stable release. Not just for Ruby programmers.
[Rust by Example]: http://rustbyexample.com/
[Rust for Rubyists]: http://www.rustforrubyists.com/

View File

@ -389,6 +389,7 @@ safe concurrent programs.
Here's an example of a concurrent Rust program: Here's an example of a concurrent Rust program:
```{rust} ```{rust}
# #![feature(scoped)]
use std::thread; use std::thread;
fn main() { fn main() {
@ -421,6 +422,7 @@ problem.
Let's see an example. This Rust code will not compile: Let's see an example. This Rust code will not compile:
```{rust,ignore} ```{rust,ignore}
# #![feature(scoped)]
use std::thread; use std::thread;
fn main() { fn main() {
@ -467,6 +469,7 @@ that our mutation doesn't cause a data race.
Here's what using a Mutex looks like: Here's what using a Mutex looks like:
```{rust} ```{rust}
# #![feature(scoped)]
use std::thread; use std::thread;
use std::sync::Mutex; use std::sync::Mutex;
@ -527,6 +530,7 @@ As an example, Rust's ownership system is _entirely_ at compile time. The
safety check that makes this an error about moved values: safety check that makes this an error about moved values:
```{rust,ignore} ```{rust,ignore}
# #![feature(scoped)]
use std::thread; use std::thread;
fn main() { fn main() {

View File

@ -1,47 +1,45 @@
% Comments % Comments
Now that we have some functions, it's a good idea to learn about comments. Now that we have some functions, its a good idea to learn about comments.
Comments are notes that you leave to other programmers to help explain things Comments are notes that you leave to other programmers to help explain things
about your code. The compiler mostly ignores them. about your code. The compiler mostly ignores them.
Rust has two kinds of comments that you should care about: *line comments* Rust has two kinds of comments that you should care about: *line comments*
and *doc comments*. and *doc comments*.
```{rust} ```rust
// Line comments are anything after '//' and extend to the end of the line. // Line comments are anything after // and extend to the end of the line.
let x = 5; // this is also a line comment. let x = 5; // this is also a line comment.
// If you have a long explanation for something, you can put line comments next // If you have a long explanation for something, you can put line comments next
// to each other. Put a space between the // and your comment so that it's // to each other. Put a space between the // and your comment so that its
// more readable. // more readable.
``` ```
The other kind of comment is a doc comment. Doc comments use `///` instead of The other kind of comment is a doc comment. Doc comments use `///` instead of
`//`, and support Markdown notation inside: `//`, and support Markdown notation inside:
```{rust} ```rust
/// `hello` is a function that prints a greeting that is personalized based on /// Adds one to the number given.
/// the name given.
///
/// # Arguments
///
/// * `name` - The name of the person you'd like to greet.
/// ///
/// # Examples /// # Examples
/// ///
/// ```rust
/// let name = "Steve";
/// hello(name); // prints "Hello, Steve!"
/// ``` /// ```
fn hello(name: &str) { /// let five = 5;
println!("Hello, {}!", name); ///
/// assert_eq!(6, add_one(5));
/// ```
fn add_one(x: i32) -> i32 {
x + 1
} }
``` ```
When writing doc comments, adding sections for any arguments, return values, When writing doc comments, providing some examples of usage is very, very
and providing some examples of usage is very, very helpful. Don't worry about helpful. Youll notice weve used a new macro here: `assert_eq!`. This compares
the `&str`, we'll get to it soon. two values, and `panic!`s if theyre not equal to each other. Its very helpful
in documentation. Theres another macro, `assert!`, which `panic!`s if the
value passed to it is `false`.
You can use the [`rustdoc`](documentation.html) tool to generate HTML documentation You can use the [`rustdoc`](documentation.html) tool to generate HTML documentation
from these doc comments. from these doc comments, and also to run the code examples as tests!

View File

@ -56,67 +56,34 @@ place!
## Threads ## Threads
Rust's standard library provides a library for 'threads', which allow you to Rust's standard library provides a library for threads, which allow you to
run Rust code in parallel. Here's a basic example of using `std::thread`: run Rust code in parallel. Here's a basic example of using `std::thread`:
``` ```
use std::thread; use std::thread;
fn main() {
thread::scoped(|| {
println!("Hello from a thread!");
});
}
```
The `thread::scoped()` method accepts a closure, which is executed in a new
thread. It's called `scoped` because this thread returns a join guard:
```
use std::thread;
fn main() {
let guard = thread::scoped(|| {
println!("Hello from a thread!");
});
// guard goes out of scope here
}
```
When `guard` goes out of scope, it will block execution until the thread is
finished. If we didn't want this behaviour, we could use `thread::spawn()`:
```
use std::thread;
fn main() { fn main() {
thread::spawn(|| { thread::spawn(|| {
println!("Hello from a thread!"); println!("Hello from a thread!");
}); });
thread::sleep_ms(50);
} }
``` ```
We need to `sleep` here because when `main()` ends, it kills all of the The `thread::spawn()` method accepts a closure, which is executed in a
running threads. new thread. It returns a handle to the thread, that can be used to
wait for the child thread to finish and extract its result:
[`scoped`](std/thread/struct.Builder.html#method.scoped) has an interesting
type signature:
```text
fn scoped<'a, T, F>(self, f: F) -> JoinGuard<'a, T>
where T: Send + 'a,
F: FnOnce() -> T,
F: Send + 'a
``` ```
use std::thread;
Specifically, `F`, the closure that we pass to execute in the new thread. It fn main() {
has two restrictions: It must be a `FnOnce` from `()` to `T`. Using `FnOnce` let handle = thread::spawn(|| {
allows the closure to take ownership of any data it mentions from the parent "Hello from a thread!"
thread. The other restriction is that `F` must be `Send`. We aren't allowed to });
transfer this ownership unless the type thinks that's okay.
println!("{}", handle.join().unwrap());
}
```
Many languages have the ability to execute threads, but it's wildly unsafe. Many languages have the ability to execute threads, but it's wildly unsafe.
There are entire books about how to prevent errors that occur from shared There are entire books about how to prevent errors that occur from shared

View File

@ -143,7 +143,5 @@ matching, a tool that will let us deconstruct sum types (the type theory term
for enums) like `Ordering` in a very elegant way that avoids all these messy for enums) like `Ordering` in a very elegant way that avoids all these messy
and brittle `if`/`else`s. and brittle `if`/`else`s.
[arity]: ./glossary.html#arity
[match]: ./match.html [match]: ./match.html
[generics]: ./generics.html [generics]: ./generics.html

View File

@ -297,5 +297,5 @@ It's worth noting that you can only use `try!` from a function that returns a
`Result`, which means that you cannot use `try!` inside of `main()`, because `Result`, which means that you cannot use `try!` inside of `main()`, because
`main()` doesn't return anything. `main()` doesn't return anything.
`try!` makes use of [`FromError`](../std/error/#the-fromerror-trait) to determine `try!` makes use of [`From<Error>`](../std/convert/trait.From.hml) to determine
what to return in the error case. what to return in the error case.

View File

@ -1,6 +1,6 @@
% Functions % Functions
You've already seen one function so far, the `main` function: Every Rust program has at least one function, the `main` function:
```rust ```rust
fn main() { fn main() {
@ -8,16 +8,16 @@ fn main() {
``` ```
This is the simplest possible function declaration. As we mentioned before, This is the simplest possible function declaration. As we mentioned before,
`fn` says "this is a function," followed by the name, some parentheses because `fn` says this is a function, followed by the name, some parentheses because
this function takes no arguments, and then some curly braces to indicate the this function takes no arguments, and then some curly braces to indicate the
body. Here's a function named `foo`: body. Heres a function named `foo`:
```rust ```rust
fn foo() { fn foo() {
} }
``` ```
So, what about taking arguments? Here's a function that prints a number: So, what about taking arguments? Heres a function that prints a number:
```rust ```rust
fn print_number(x: i32) { fn print_number(x: i32) {
@ -25,7 +25,7 @@ fn print_number(x: i32) {
} }
``` ```
Here's a complete program that uses `print_number`: Heres a complete program that uses `print_number`:
```rust ```rust
fn main() { fn main() {
@ -40,7 +40,7 @@ fn print_number(x: i32) {
As you can see, function arguments work very similar to `let` declarations: As you can see, function arguments work very similar to `let` declarations:
you add a type to the argument name, after a colon. you add a type to the argument name, after a colon.
Here's a complete program that adds two numbers together and prints them: Heres a complete program that adds two numbers together and prints them:
```rust ```rust
fn main() { fn main() {
@ -58,7 +58,7 @@ as when you declare it.
Unlike `let`, you _must_ declare the types of function arguments. This does Unlike `let`, you _must_ declare the types of function arguments. This does
not work: not work:
```{rust,ignore} ```rust,ignore
fn print_sum(x, y) { fn print_sum(x, y) {
println!("sum is: {}", x + y); println!("sum is: {}", x + y);
} }
@ -67,8 +67,8 @@ fn print_sum(x, y) {
You get this error: You get this error:
```text ```text
hello.rs:5:18: 5:19 expected one of `!`, `:`, or `@`, found `)` expected one of `!`, `:`, or `@`, found `)`
hello.rs:5 fn print_number(x, y) { fn print_number(x, y) {
``` ```
This is a deliberate design decision. While full-program inference is possible, This is a deliberate design decision. While full-program inference is possible,
@ -77,7 +77,7 @@ types explicitly is a best-practice. We agree that forcing functions to declare
types while allowing for inference inside of function bodies is a wonderful types while allowing for inference inside of function bodies is a wonderful
sweet spot between full inference and no inference. sweet spot between full inference and no inference.
What about returning a value? Here's a function that adds one to an integer: What about returning a value? Heres a function that adds one to an integer:
```rust ```rust
fn add_one(x: i32) -> i32 { fn add_one(x: i32) -> i32 {
@ -86,11 +86,11 @@ fn add_one(x: i32) -> i32 {
``` ```
Rust functions return exactly one value, and you declare the type after an Rust functions return exactly one value, and you declare the type after an
"arrow," which is a dash (`-`) followed by a greater-than sign (`>`). arrow, which is a dash (`-`) followed by a greater-than sign (`>`). The last
line of a function determines what it returns. Youll note the lack of a
semicolon here. If we added it in:
You'll note the lack of a semicolon here. If we added it in: ```rust,ignore
```{rust,ignore}
fn add_one(x: i32) -> i32 { fn add_one(x: i32) -> i32 {
x + 1; x + 1;
} }
@ -109,24 +109,79 @@ help: consider removing this semicolon:
^ ^
``` ```
Remember our earlier discussions about semicolons and `()`? Our function claims This reveals two interesting things about Rust: it is an expression-based
to return an `i32`, but with a semicolon, it would return `()` instead. Rust language, and semicolons are different from semicolons in other curly brace
realizes this probably isn't what we want, and suggests removing the semicolon. and semicolon-based languages. These two things are related.
This is very much like our `if` statement before: the result of the block ## Expressions vs. Statements
(`{}`) is the value of the expression. Other expression-oriented languages,
such as Ruby, work like this, but it's a bit unusual in the systems programming Rust is primarily an expression-based language. There are only two kinds of
world. When people first learn about this, they usually assume that it statements, and everything else is an expression.
introduces bugs. But because Rust's type system is so strong, and because unit
is its own unique type, we have never seen an issue where adding or removing a So what's the difference? Expressions return a value, and statements do not.
semicolon in a return position would cause a bug. Thats why we end up with not all control paths return a value here: the
statement `x + 1;` doesnt return a value. There are two kinds of statements in
Rust: declaration statements and expression statements. Everything else is
an expression. Lets talk about declaration statements first.
In some languages, variable bindings can be written as expressions, not just
statements. Like Ruby:
```ruby
x = y = 5
```
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 = 5); // expected identifier, found keyword `let`
```
The compiler is telling us here that it was expecting to see the beginning of
an expression, and a `let` can only begin a statement, not an expression.
Note that assigning to an already-bound variable (e.g. `y = 5`) is still an
expression, although its value is not particularly useful. Unlike other
languages where an assignment evaluates to the assigned value (e.g. `5` in the
previous example), in Rust the value of an assignment is an empty tuple `()`:
```
let mut y = 5;
let x = (y = 6); // x has the value `()`, not `6`
```
The second kind of statement in Rust is the *expression statement*. Its
purpose is to turn any expression into a statement. In practical terms, Rust's
grammar expects statements to follow other statements. This means that you use
semicolons to separate expressions from each other. This means that Rust
looks a lot like most other languages that require you to use semicolons
at the end of every line, and you will see semicolons at the end of almost
every line of Rust code you see.
What is this exception that makes us say "almost"? You saw it already, in this
code:
```rust
fn add_one(x: i32) -> i32 {
x + 1
}
```
Our function claims to return an `i32`, but with a semicolon, it would return
`()` instead. Rust realizes this probably isnt what we want, and suggests
removing the semicolon in the error we saw before.
## Early returns
But what about early returns? Rust does have a keyword for that, `return`: But what about early returns? Rust does have a keyword for that, `return`:
```rust ```rust
fn foo(x: i32) -> i32 { fn foo(x: i32) -> i32 {
if x < 5 { return x; } return x;
// we never run this code!
x + 1 x + 1
} }
``` ```
@ -136,33 +191,17 @@ style:
```rust ```rust
fn foo(x: i32) -> i32 { fn foo(x: i32) -> i32 {
if x < 5 { return x; }
return x + 1; return x + 1;
} }
``` ```
The previous definition without `return` may look a bit strange if you haven't The previous definition without `return` may look a bit strange if you havent
worked in an expression-based language before, but it becomes intuitive over worked in an expression-based language before, but it becomes intuitive over
time. If this were production code, we wouldn't write it in that way anyway, time.
we'd write this:
```rust
fn foo(x: i32) -> i32 {
if x < 5 {
x
} else {
x + 1
}
}
```
Because `if` is an expression, and it's the only expression in this function,
the value will be the result of the `if`.
## Diverging functions ## Diverging functions
Rust has some special syntax for 'diverging functions', which are functions that Rust has some special syntax for diverging functions, which are functions that
do not return: do not return:
``` ```
@ -171,23 +210,18 @@ fn diverges() -> ! {
} }
``` ```
`panic!` is a macro, similar to `println!()` that we've already seen. Unlike `panic!` is a macro, similar to `println!()` that weve already seen. Unlike
`println!()`, `panic!()` causes the current thread of execution to crash with `println!()`, `panic!()` causes the current thread of execution to crash with
the given message. the given message.
Because this function will cause a crash, it will never return, and so it has Because this function will cause a crash, it will never return, and so it has
the type '`!`', which is read "diverges." A diverging function can be used the type `!`, which is read diverges. A diverging function can be used
as any type: as any type:
```should_panic ```should_panic
# fn diverges() -> ! { # fn diverges() -> ! {
# panic!("This function never returns!"); # panic!("This function never returns!");
# } # }
let x: i32 = diverges(); let x: i32 = diverges();
let x: String = diverges(); let x: String = diverges();
``` ```
We don't have a good use for diverging functions yet, because they're used in
conjunction with other Rust features. But when you see `-> !` later, you'll
know what it's called.

View File

@ -18,7 +18,7 @@ use a two-step version of the installation and examine our installation script:
```bash ```bash
$ curl -f -L https://static.rust-lang.org/rustup.sh -O $ curl -f -L https://static.rust-lang.org/rustup.sh -O
$ sudo sh rustup.sh $ sudo sh rustup.sh --channel=nightly
``` ```
[insecurity]: http://curlpipesh.tumblr.com [insecurity]: http://curlpipesh.tumblr.com

View File

@ -1,8 +1,15 @@
% Structs % Structs
A struct is another form of a *record type*, just like a tuple. There's a Structs are a way of creating more complex datatypes. For example, if we were
difference: structs give each element that they contain a name, called a doing calculations involving coordinates in 2D space, we would need both an `x`
*field* or a *member*. Check it out: and a `y` value:
```rust
let origin_x = 0;
let origin_y = 0;
```
A struct lets us combine these two into a single, unified datatype:
```rust ```rust
struct Point { struct Point {
@ -17,7 +24,7 @@ fn main() {
} }
``` ```
There's a lot going on here, so let's break it down. We declare a struct with Theres a lot going on here, so lets break it down. We declare a struct with
the `struct` keyword, and then with a name. By convention, structs begin with a the `struct` keyword, and then with a name. By convention, structs begin with a
capital letter and are also camel cased: `PointInSpace`, not `Point_In_Space`. capital letter and are also camel cased: `PointInSpace`, not `Point_In_Space`.
@ -31,7 +38,7 @@ notation: `origin.x`.
The values in structs are immutable by default, like other bindings in Rust. The values in structs are immutable by default, like other bindings in Rust.
Use `mut` to make them mutable: Use `mut` to make them mutable:
```{rust} ```rust
struct Point { struct Point {
x: i32, x: i32,
y: i32, y: i32,
@ -47,3 +54,36 @@ fn main() {
``` ```
This will print `The point is at (5, 0)`. This will print `The point is at (5, 0)`.
Rust does not support field mutability at the language level, so you cannot
write something like this:
```rust,ignore
struct Point {
mut x: i32,
y: i32,
}
```
Mutability is a property of the binding, not of the structure itself. If youre
used to field-level mutability, this may seem strange at first, but it
significantly simplifies things. It even lets you make things mutable for a short
time only:
```rust,ignore
struct Point {
x: i32,
y: i32,
}
fn main() {
let mut point = Point { x: 0, y: 0 };
point.x = 5;
let point = point; // this new binding cant change now
point.y = 6; // this causes an error
}
```

View File

@ -1,8 +1,7 @@
% Vectors % Vectors
A *vector* is a dynamic or "growable" array, implemented as the standard A *vector* is a dynamic or "growable" array, implemented as the standard
library type [`Vec<T>`](../std/vec/) (we'll talk about what the `<T>` means library type [`Vec<T>`](../std/vec/) (Where `<T>` is a [Generic](./generics.md) statement). Vectors always allocate their data on the heap. Vectors are to slices
later). Vectors always allocate their data on the heap. Vectors are to slices
what `String` is to `&str`. You can create them with the `vec!` macro: what `String` is to `&str`. You can create them with the `vec!` macro:
```{rust} ```{rust}

View File

@ -923,7 +923,7 @@ impl BitVec {
self.set(insert_pos, elem); self.set(insert_pos, elem);
} }
/// Return the total number of bits in this vector /// Returns the total number of bits in this vector
#[inline] #[inline]
#[stable(feature = "rust1", since = "1.0.0")] #[stable(feature = "rust1", since = "1.0.0")]
pub fn len(&self) -> usize { self.nbits } pub fn len(&self) -> usize { self.nbits }
@ -1695,7 +1695,7 @@ impl BitSet {
self.other_op(other, |w1, w2| w1 ^ w2); self.other_op(other, |w1, w2| w1 ^ w2);
} }
/// Return the number of set bits in this set. /// Returns the number of set bits in this set.
#[inline] #[inline]
#[stable(feature = "rust1", since = "1.0.0")] #[stable(feature = "rust1", since = "1.0.0")]
pub fn len(&self) -> usize { pub fn len(&self) -> usize {

View File

@ -1339,7 +1339,7 @@ impl<K, V> BTreeMap<K, V> {
Values { inner: self.iter().map(second) } Values { inner: self.iter().map(second) }
} }
/// Return the number of elements in the map. /// Returns the number of elements in the map.
/// ///
/// # Examples /// # Examples
/// ///
@ -1354,7 +1354,7 @@ impl<K, V> BTreeMap<K, V> {
#[stable(feature = "rust1", since = "1.0.0")] #[stable(feature = "rust1", since = "1.0.0")]
pub fn len(&self) -> usize { self.length } pub fn len(&self) -> usize { self.length }
/// Return true if the map contains no elements. /// Returns true if the map contains no elements.
/// ///
/// # Examples /// # Examples
/// ///

View File

@ -284,7 +284,7 @@ impl<T: Ord> BTreeSet<T> {
Union{a: self.iter().peekable(), b: other.iter().peekable()} Union{a: self.iter().peekable(), b: other.iter().peekable()}
} }
/// Return the number of elements in the set /// Returns the number of elements in the set.
/// ///
/// # Examples /// # Examples
/// ///
@ -299,7 +299,7 @@ impl<T: Ord> BTreeSet<T> {
#[stable(feature = "rust1", since = "1.0.0")] #[stable(feature = "rust1", since = "1.0.0")]
pub fn len(&self) -> usize { self.map.len() } pub fn len(&self) -> usize { self.map.len() }
/// Returns true if the set contains no elements /// Returns true if the set contains no elements.
/// ///
/// # Examples /// # Examples
/// ///

View File

@ -40,6 +40,7 @@
#![feature(str_char)] #![feature(str_char)]
#![feature(slice_patterns)] #![feature(slice_patterns)]
#![feature(debug_builders)] #![feature(debug_builders)]
#![feature(utf8_error)]
#![cfg_attr(test, feature(rand, rustc_private, test, hash, collections))] #![cfg_attr(test, feature(rand, rustc_private, test, hash, collections))]
#![cfg_attr(test, allow(deprecated))] // rand #![cfg_attr(test, allow(deprecated))] // rand

View File

@ -943,7 +943,7 @@ mod test {
use std::clone::Clone; use std::clone::Clone;
use std::iter::Iterator; use std::iter::Iterator;
use std::option::Option::{Some, None, self}; use std::option::Option::{Some, None, self};
use std::rand; use std::__rand::{thread_rng, Rng};
use std::thread; use std::thread;
use std::vec::Vec; use std::vec::Vec;
@ -1095,7 +1095,7 @@ mod test {
let mut v = vec![]; let mut v = vec![];
for i in 0..sz { for i in 0..sz {
check_links(&m); check_links(&m);
let r: u8 = rand::random(); let r: u8 = thread_rng().next_u32() as u8;
match r % 6 { match r % 6 {
0 => { 0 => {
m.pop_back(); m.pop_back();

View File

@ -549,7 +549,7 @@ impl<T> [T] {
core_slice::SliceExt::binary_search_by(self, f) core_slice::SliceExt::binary_search_by(self, f)
} }
/// Return the number of elements in the slice /// Returns the number of elements in the slice.
/// ///
/// # Example /// # Example
/// ///
@ -757,7 +757,7 @@ impl<T> [T] {
core_slice::SliceExt::get_unchecked_mut(self, index) core_slice::SliceExt::get_unchecked_mut(self, index)
} }
/// Return an unsafe mutable pointer to the slice's buffer. /// Returns an unsafe mutable pointer to the slice's buffer.
/// ///
/// The caller must ensure that the slice outlives the pointer this /// The caller must ensure that the slice outlives the pointer this
/// function returns, or else it will end up pointing to garbage. /// function returns, or else it will end up pointing to garbage.
@ -984,7 +984,7 @@ impl<T> [T] {
core_slice::SliceExt::ends_with(self, needle) core_slice::SliceExt::ends_with(self, needle)
} }
/// Convert `self` into a vector without clones or allocation. /// Converts `self` into a vector without clones or allocation.
#[stable(feature = "rust1", since = "1.0.0")] #[stable(feature = "rust1", since = "1.0.0")]
#[inline] #[inline]
pub fn into_vec(self: Box<Self>) -> Vec<T> { pub fn into_vec(self: Box<Self>) -> Vec<T> {

View File

@ -1248,7 +1248,7 @@ impl str {
core_str::StrExt::trim_right_matches(&self[..], pat) core_str::StrExt::trim_right_matches(&self[..], pat)
} }
/// Check that `index`-th byte lies at the start and/or end of a /// Checks that `index`-th byte lies at the start and/or end of a
/// UTF-8 code point sequence. /// UTF-8 code point sequence.
/// ///
/// The start and end of the string (when `index == self.len()`) are /// The start and end of the string (when `index == self.len()`) are
@ -1435,7 +1435,7 @@ impl str {
core_str::StrExt::char_at_reverse(&self[..], i) core_str::StrExt::char_at_reverse(&self[..], i)
} }
/// Convert `self` to a byte slice. /// Converts `self` to a byte slice.
/// ///
/// # Examples /// # Examples
/// ///
@ -1591,7 +1591,7 @@ impl str {
core_str::StrExt::subslice_offset(&self[..], inner) core_str::StrExt::subslice_offset(&self[..], inner)
} }
/// Return an unsafe pointer to the `&str`'s buffer. /// Returns an unsafe pointer to the `&str`'s buffer.
/// ///
/// The caller must ensure that the string outlives this pointer, and /// The caller must ensure that the string outlives this pointer, and
/// that it is not /// that it is not
@ -1609,7 +1609,7 @@ impl str {
core_str::StrExt::as_ptr(&self[..]) core_str::StrExt::as_ptr(&self[..])
} }
/// Return an iterator of `u16` over the string encoded as UTF-16. /// Returns an iterator of `u16` over the string encoded as UTF-16.
#[unstable(feature = "collections", #[unstable(feature = "collections",
reason = "this functionality may only be provided by libunicode")] reason = "this functionality may only be provided by libunicode")]
pub fn utf16_units(&self) -> Utf16Units { pub fn utf16_units(&self) -> Utf16Units {

View File

@ -132,7 +132,7 @@ impl String {
/// ///
/// let invalid_vec = vec![240, 144, 128]; /// let invalid_vec = vec![240, 144, 128];
/// let s = String::from_utf8(invalid_vec).err().unwrap(); /// let s = String::from_utf8(invalid_vec).err().unwrap();
/// assert_eq!(s.utf8_error(), Utf8Error::TooShort); /// let err = s.utf8_error();
/// assert_eq!(s.into_bytes(), [240, 144, 128]); /// assert_eq!(s.into_bytes(), [240, 144, 128]);
/// ``` /// ```
#[inline] #[inline]
@ -156,14 +156,10 @@ impl String {
/// ``` /// ```
#[stable(feature = "rust1", since = "1.0.0")] #[stable(feature = "rust1", since = "1.0.0")]
pub fn from_utf8_lossy<'a>(v: &'a [u8]) -> Cow<'a, str> { pub fn from_utf8_lossy<'a>(v: &'a [u8]) -> Cow<'a, str> {
let mut i = 0; let mut i;
match str::from_utf8(v) { match str::from_utf8(v) {
Ok(s) => return Cow::Borrowed(s), Ok(s) => return Cow::Borrowed(s),
Err(e) => { Err(e) => i = e.valid_up_to(),
if let Utf8Error::InvalidByte(firstbad) = e {
i = firstbad;
}
}
} }
const TAG_CONT_U8: u8 = 128; const TAG_CONT_U8: u8 = 128;
@ -188,9 +184,9 @@ impl String {
}; };
} }
// subseqidx is the index of the first byte of the subsequence we're looking at. // subseqidx is the index of the first byte of the subsequence we're
// It's used to copy a bunch of contiguous good codepoints at once instead of copying // looking at. It's used to copy a bunch of contiguous good codepoints
// them one by one. // at once instead of copying them one by one.
let mut subseqidx = i; let mut subseqidx = i;
while i < total { while i < total {
@ -347,7 +343,7 @@ impl String {
String { vec: bytes } String { vec: bytes }
} }
/// Return the underlying byte buffer, encoded as UTF-8. /// Returns the underlying byte buffer, encoded as UTF-8.
/// ///
/// # Examples /// # Examples
/// ///
@ -363,7 +359,7 @@ impl String {
self.vec self.vec
} }
/// Extract a string slice containing the entire string. /// Extracts a string slice containing the entire string.
#[inline] #[inline]
#[unstable(feature = "convert", #[unstable(feature = "convert",
reason = "waiting on RFC revision")] reason = "waiting on RFC revision")]
@ -607,7 +603,7 @@ impl String {
ch ch
} }
/// Insert a character into the string buffer at byte position `idx`. /// Inserts a character into the string buffer at byte position `idx`.
/// ///
/// # Warning /// # Warning
/// ///
@ -662,7 +658,7 @@ impl String {
&mut self.vec &mut self.vec
} }
/// Return the number of bytes in this string. /// Returns the number of bytes in this string.
/// ///
/// # Examples /// # Examples
/// ///
@ -705,12 +701,12 @@ impl String {
} }
impl FromUtf8Error { impl FromUtf8Error {
/// Consume this error, returning the bytes that were attempted to make a /// Consumes this error, returning the bytes that were attempted to make a
/// `String` with. /// `String` with.
#[stable(feature = "rust1", since = "1.0.0")] #[stable(feature = "rust1", since = "1.0.0")]
pub fn into_bytes(self) -> Vec<u8> { self.bytes } pub fn into_bytes(self) -> Vec<u8> { self.bytes }
/// Access the underlying UTF8-error that was the cause of this error. /// Accesss the underlying UTF8-error that was the cause of this error.
#[stable(feature = "rust1", since = "1.0.0")] #[stable(feature = "rust1", since = "1.0.0")]
pub fn utf8_error(&self) -> Utf8Error { self.error } pub fn utf8_error(&self) -> Utf8Error { self.error }
} }
@ -959,7 +955,7 @@ impl<'a> Deref for DerefString<'a> {
} }
} }
/// Convert a string slice to a wrapper type providing a `&String` reference. /// Converts a string slice to a wrapper type providing a `&String` reference.
/// ///
/// # Examples /// # Examples
/// ///

View File

@ -393,7 +393,7 @@ impl<T> Vec<T> {
} }
} }
/// Convert the vector into Box<[T]>. /// Converts the vector into Box<[T]>.
/// ///
/// Note that this will drop any excess capacity. Calling this and /// Note that this will drop any excess capacity. Calling this and
/// converting back to a vector with `into_vec()` is equivalent to calling /// converting back to a vector with `into_vec()` is equivalent to calling
@ -434,7 +434,7 @@ impl<T> Vec<T> {
} }
} }
/// Extract a slice containing the entire vector. /// Extracts a slice containing the entire vector.
#[inline] #[inline]
#[unstable(feature = "convert", #[unstable(feature = "convert",
reason = "waiting on RFC revision")] reason = "waiting on RFC revision")]
@ -1936,7 +1936,7 @@ impl<'a, T> Drop for DerefVec<'a, T> {
} }
} }
/// Convert a slice to a wrapper type providing a `&Vec<T>` reference. /// Converts a slice to a wrapper type providing a `&Vec<T>` reference.
#[unstable(feature = "collections")] #[unstable(feature = "collections")]
pub fn as_vec<'a, T>(x: &'a [T]) -> DerefVec<'a, T> { pub fn as_vec<'a, T>(x: &'a [T]) -> DerefVec<'a, T> {
unsafe { unsafe {

View File

@ -481,7 +481,7 @@ impl<T> VecDeque<T> {
} }
} }
/// Shorten a ringbuf, dropping excess elements from the back. /// Shortens a ringbuf, dropping excess elements from the back.
/// ///
/// If `len` is greater than the ringbuf's current length, this has no /// If `len` is greater than the ringbuf's current length, this has no
/// effect. /// effect.

View File

@ -452,7 +452,7 @@ impl<V> VecMap<V> {
Drain { iter: self.v.drain().enumerate().filter_map(filter) } Drain { iter: self.v.drain().enumerate().filter_map(filter) }
} }
/// Return the number of elements in the map. /// Returns the number of elements in the map.
/// ///
/// # Examples /// # Examples
/// ///
@ -470,7 +470,7 @@ impl<V> VecMap<V> {
self.v.iter().filter(|elt| elt.is_some()).count() self.v.iter().filter(|elt| elt.is_some()).count()
} }
/// Return true if the map contains no elements. /// Returns true if the map contains no elements.
/// ///
/// # Examples /// # Examples
/// ///

View File

@ -12,14 +12,13 @@ macro_rules! map_insert_rand_bench {
($name: ident, $n: expr, $map: ident) => ( ($name: ident, $n: expr, $map: ident) => (
#[bench] #[bench]
pub fn $name(b: &mut ::test::Bencher) { pub fn $name(b: &mut ::test::Bencher) {
use std::rand; use std::__rand::{thread_rng, Rng};
use std::rand::Rng;
use test::black_box; use test::black_box;
let n: usize = $n; let n: usize = $n;
let mut map = $map::new(); let mut map = $map::new();
// setup // setup
let mut rng = rand::weak_rng(); let mut rng = thread_rng();
for _ in 0..n { for _ in 0..n {
let i = rng.gen::<usize>() % n; let i = rng.gen::<usize>() % n;
@ -67,8 +66,7 @@ macro_rules! map_find_rand_bench {
#[bench] #[bench]
pub fn $name(b: &mut ::test::Bencher) { pub fn $name(b: &mut ::test::Bencher) {
use std::iter::Iterator; use std::iter::Iterator;
use std::rand::Rng; use std::__rand::{thread_rng, Rng};
use std::rand;
use std::vec::Vec; use std::vec::Vec;
use test::black_box; use test::black_box;
@ -76,7 +74,7 @@ macro_rules! map_find_rand_bench {
let n: usize = $n; let n: usize = $n;
// setup // setup
let mut rng = rand::weak_rng(); let mut rng = thread_rng();
let mut keys: Vec<_> = (0..n).map(|_| rng.gen::<usize>() % n).collect(); let mut keys: Vec<_> = (0..n).map(|_| rng.gen::<usize>() % n).collect();
for &k in &keys { for &k in &keys {

View File

@ -389,16 +389,15 @@ fn test_bit_vec_clone() {
mod bench { mod bench {
use std::collections::{BitSet, BitVec}; use std::collections::{BitSet, BitVec};
use std::rand::{Rng, self}; use std::__rand::{Rng, thread_rng, ThreadRng};
use std::u32; use std::u32;
use test::{Bencher, black_box}; use test::{Bencher, black_box};
const BENCH_BITS : usize = 1 << 14; const BENCH_BITS : usize = 1 << 14;
fn rng() -> rand::IsaacRng { fn rng() -> ThreadRng {
let seed: &[_] = &[1, 2, 3, 4, 5, 6, 7, 8, 9, 0]; thread_rng()
rand::SeedableRng::from_seed(seed)
} }
#[bench] #[bench]

View File

@ -633,15 +633,14 @@ fn test_bit_vec_extend() {
mod bench { mod bench {
use std::collections::BitVec; use std::collections::BitVec;
use std::u32; use std::u32;
use std::rand::{Rng, self}; use std::__rand::{Rng, thread_rng, ThreadRng};
use test::{Bencher, black_box}; use test::{Bencher, black_box};
const BENCH_BITS : usize = 1 << 14; const BENCH_BITS : usize = 1 << 14;
fn rng() -> rand::IsaacRng { fn rng() -> ThreadRng {
let seed: &[_] = &[1, 2, 3, 4, 5, 6, 7, 8, 9, 0]; thread_rng()
rand::SeedableRng::from_seed(seed)
} }
#[bench] #[bench]

View File

@ -251,7 +251,7 @@ fn test_entry(){
mod bench { mod bench {
use std::collections::BTreeMap; use std::collections::BTreeMap;
use std::rand::{Rng, weak_rng}; use std::__rand::{Rng, thread_rng};
use test::{Bencher, black_box}; use test::{Bencher, black_box};
@ -269,7 +269,7 @@ mod bench {
fn bench_iter(b: &mut Bencher, size: i32) { fn bench_iter(b: &mut Bencher, size: i32) {
let mut map = BTreeMap::<i32, i32>::new(); let mut map = BTreeMap::<i32, i32>::new();
let mut rng = weak_rng(); let mut rng = thread_rng();
for _ in 0..size { for _ in 0..size {
map.insert(rng.gen(), rng.gen()); map.insert(rng.gen(), rng.gen());

View File

@ -12,7 +12,7 @@ use std::cmp::Ordering::{Equal, Greater, Less};
use std::default::Default; use std::default::Default;
use std::iter::RandomAccessIterator; use std::iter::RandomAccessIterator;
use std::mem; use std::mem;
use std::rand::{Rng, thread_rng}; use std::__rand::{Rng, thread_rng};
use std::rc::Rc; use std::rc::Rc;
use std::slice::ElementSwaps; use std::slice::ElementSwaps;
@ -1296,7 +1296,7 @@ fn test_to_vec() {
mod bench { mod bench {
use std::iter::repeat; use std::iter::repeat;
use std::{mem, ptr}; use std::{mem, ptr};
use std::rand::{Rng, weak_rng}; use std::__rand::{Rng, thread_rng};
use test::{Bencher, black_box}; use test::{Bencher, black_box};
@ -1465,7 +1465,7 @@ mod bench {
#[bench] #[bench]
fn random_inserts(b: &mut Bencher) { fn random_inserts(b: &mut Bencher) {
let mut rng = weak_rng(); let mut rng = thread_rng();
b.iter(|| { b.iter(|| {
let mut v: Vec<_> = repeat((0, 0)).take(30).collect(); let mut v: Vec<_> = repeat((0, 0)).take(30).collect();
for _ in 0..100 { for _ in 0..100 {
@ -1477,7 +1477,7 @@ mod bench {
} }
#[bench] #[bench]
fn random_removes(b: &mut Bencher) { fn random_removes(b: &mut Bencher) {
let mut rng = weak_rng(); let mut rng = thread_rng();
b.iter(|| { b.iter(|| {
let mut v: Vec<_> = repeat((0, 0)).take(130).collect(); let mut v: Vec<_> = repeat((0, 0)).take(130).collect();
for _ in 0..100 { for _ in 0..100 {
@ -1489,7 +1489,7 @@ mod bench {
#[bench] #[bench]
fn sort_random_small(b: &mut Bencher) { fn sort_random_small(b: &mut Bencher) {
let mut rng = weak_rng(); let mut rng = thread_rng();
b.iter(|| { b.iter(|| {
let mut v: Vec<_> = rng.gen_iter::<u64>().take(5).collect(); let mut v: Vec<_> = rng.gen_iter::<u64>().take(5).collect();
v.sort(); v.sort();
@ -1499,7 +1499,7 @@ mod bench {
#[bench] #[bench]
fn sort_random_medium(b: &mut Bencher) { fn sort_random_medium(b: &mut Bencher) {
let mut rng = weak_rng(); let mut rng = thread_rng();
b.iter(|| { b.iter(|| {
let mut v: Vec<_> = rng.gen_iter::<u64>().take(100).collect(); let mut v: Vec<_> = rng.gen_iter::<u64>().take(100).collect();
v.sort(); v.sort();
@ -1509,7 +1509,7 @@ mod bench {
#[bench] #[bench]
fn sort_random_large(b: &mut Bencher) { fn sort_random_large(b: &mut Bencher) {
let mut rng = weak_rng(); let mut rng = thread_rng();
b.iter(|| { b.iter(|| {
let mut v: Vec<_> = rng.gen_iter::<u64>().take(10000).collect(); let mut v: Vec<_> = rng.gen_iter::<u64>().take(10000).collect();
v.sort(); v.sort();
@ -1530,7 +1530,7 @@ mod bench {
#[bench] #[bench]
fn sort_big_random_small(b: &mut Bencher) { fn sort_big_random_small(b: &mut Bencher) {
let mut rng = weak_rng(); let mut rng = thread_rng();
b.iter(|| { b.iter(|| {
let mut v = rng.gen_iter::<BigSortable>().take(5) let mut v = rng.gen_iter::<BigSortable>().take(5)
.collect::<Vec<BigSortable>>(); .collect::<Vec<BigSortable>>();
@ -1541,7 +1541,7 @@ mod bench {
#[bench] #[bench]
fn sort_big_random_medium(b: &mut Bencher) { fn sort_big_random_medium(b: &mut Bencher) {
let mut rng = weak_rng(); let mut rng = thread_rng();
b.iter(|| { b.iter(|| {
let mut v = rng.gen_iter::<BigSortable>().take(100) let mut v = rng.gen_iter::<BigSortable>().take(100)
.collect::<Vec<BigSortable>>(); .collect::<Vec<BigSortable>>();
@ -1552,7 +1552,7 @@ mod bench {
#[bench] #[bench]
fn sort_big_random_large(b: &mut Bencher) { fn sort_big_random_large(b: &mut Bencher) {
let mut rng = weak_rng(); let mut rng = thread_rng();
b.iter(|| { b.iter(|| {
let mut v = rng.gen_iter::<BigSortable>().take(10000) let mut v = rng.gen_iter::<BigSortable>().take(10000)
.collect::<Vec<BigSortable>>(); .collect::<Vec<BigSortable>>();

View File

@ -1502,7 +1502,7 @@ fn test_str_from_utf8() {
assert_eq!(from_utf8(xs), Ok("ศไทย中华Việt Nam")); assert_eq!(from_utf8(xs), Ok("ศไทย中华Việt Nam"));
let xs = b"hello\xFF"; let xs = b"hello\xFF";
assert_eq!(from_utf8(xs), Err(Utf8Error::TooShort)); assert!(from_utf8(xs).is_err());
} }
#[test] #[test]

View File

@ -45,7 +45,6 @@ fn test_from_utf8() {
let xs = b"hello\xFF".to_vec(); let xs = b"hello\xFF".to_vec();
let err = String::from_utf8(xs).err().unwrap(); let err = String::from_utf8(xs).err().unwrap();
assert_eq!(err.utf8_error(), Utf8Error::TooShort);
assert_eq!(err.into_bytes(), b"hello\xff".to_vec()); assert_eq!(err.into_bytes(), b"hello\xff".to_vec());
} }

View File

@ -91,7 +91,7 @@ use marker::{Reflect, Sized};
/// [mod]: index.html /// [mod]: index.html
#[stable(feature = "rust1", since = "1.0.0")] #[stable(feature = "rust1", since = "1.0.0")]
pub trait Any: Reflect + 'static { pub trait Any: Reflect + 'static {
/// Get the `TypeId` of `self` /// Gets the `TypeId` of `self`.
#[unstable(feature = "core", #[unstable(feature = "core",
reason = "this method will likely be replaced by an associated static")] reason = "this method will likely be replaced by an associated static")]
fn get_type_id(&self) -> TypeId; fn get_type_id(&self) -> TypeId;

View File

@ -78,12 +78,20 @@ use intrinsics;
use cell::UnsafeCell; use cell::UnsafeCell;
use marker::PhantomData; use marker::PhantomData;
use default::Default;
/// A boolean type which can be safely shared between threads. /// A boolean type which can be safely shared between threads.
#[stable(feature = "rust1", since = "1.0.0")] #[stable(feature = "rust1", since = "1.0.0")]
pub struct AtomicBool { pub struct AtomicBool {
v: UnsafeCell<usize>, v: UnsafeCell<usize>,
} }
impl Default for AtomicBool {
fn default() -> AtomicBool {
ATOMIC_BOOL_INIT
}
}
unsafe impl Sync for AtomicBool {} unsafe impl Sync for AtomicBool {}
/// A signed integer type which can be safely shared between threads. /// A signed integer type which can be safely shared between threads.
@ -92,6 +100,12 @@ pub struct AtomicIsize {
v: UnsafeCell<isize>, v: UnsafeCell<isize>,
} }
impl Default for AtomicIsize {
fn default() -> AtomicIsize {
ATOMIC_ISIZE_INIT
}
}
unsafe impl Sync for AtomicIsize {} unsafe impl Sync for AtomicIsize {}
/// An unsigned integer type which can be safely shared between threads. /// An unsigned integer type which can be safely shared between threads.
@ -100,6 +114,12 @@ pub struct AtomicUsize {
v: UnsafeCell<usize>, v: UnsafeCell<usize>,
} }
impl Default for AtomicUsize {
fn default() -> AtomicUsize {
ATOMIC_USIZE_INIT
}
}
unsafe impl Sync for AtomicUsize {} unsafe impl Sync for AtomicUsize {}
/// A raw pointer type which can be safely shared between threads. /// A raw pointer type which can be safely shared between threads.

View File

@ -211,7 +211,7 @@ impl<T:Copy> Cell<T> {
} }
} }
/// Get a reference to the underlying `UnsafeCell`. /// Gets a reference to the underlying `UnsafeCell`.
/// ///
/// # Unsafety /// # Unsafety
/// ///
@ -436,7 +436,7 @@ impl<T> RefCell<T> {
} }
} }
/// Get a reference to the underlying `UnsafeCell`. /// Gets a reference to the underlying `UnsafeCell`.
/// ///
/// This can be used to circumvent `RefCell`'s safety checks. /// This can be used to circumvent `RefCell`'s safety checks.
/// ///
@ -537,7 +537,7 @@ impl<'b, T> Deref for Ref<'b, T> {
} }
} }
/// Copy a `Ref`. /// Copies a `Ref`.
/// ///
/// The `RefCell` is already immutably borrowed, so this cannot fail. /// The `RefCell` is already immutably borrowed, so this cannot fail.
/// ///
@ -647,7 +647,7 @@ pub struct UnsafeCell<T> {
impl<T> !Sync for UnsafeCell<T> {} impl<T> !Sync for UnsafeCell<T> {}
impl<T> UnsafeCell<T> { impl<T> UnsafeCell<T> {
/// Construct a new instance of `UnsafeCell` which will wrap the specified /// Constructs a new instance of `UnsafeCell` which will wrap the specified
/// value. /// value.
/// ///
/// All access to the inner value through methods is `unsafe`, and it is highly discouraged to /// All access to the inner value through methods is `unsafe`, and it is highly discouraged to
@ -685,7 +685,7 @@ impl<T> UnsafeCell<T> {
&self.value as *const T as *mut T &self.value as *const T as *mut T
} }
/// Unwraps the value /// Unwraps the value.
/// ///
/// # Unsafety /// # Unsafety
/// ///

View File

@ -38,7 +38,7 @@ pub trait Clone : Sized {
#[stable(feature = "rust1", since = "1.0.0")] #[stable(feature = "rust1", since = "1.0.0")]
fn clone(&self) -> Self; fn clone(&self) -> Self;
/// Perform copy-assignment from `source`. /// Performs copy-assignment from `source`.
/// ///
/// `a.clone_from(&b)` is equivalent to `a = b.clone()` in functionality, /// `a.clone_from(&b)` is equivalent to `a = b.clone()` in functionality,
/// but can be overridden to reuse the resources of `a` to avoid unnecessary /// but can be overridden to reuse the resources of `a` to avoid unnecessary
@ -52,7 +52,7 @@ pub trait Clone : Sized {
#[stable(feature = "rust1", since = "1.0.0")] #[stable(feature = "rust1", since = "1.0.0")]
impl<'a, T: ?Sized> Clone for &'a T { impl<'a, T: ?Sized> Clone for &'a T {
/// Return a shallow copy of the reference. /// Returns a shallow copy of the reference.
#[inline] #[inline]
fn clone(&self) -> &'a T { *self } fn clone(&self) -> &'a T { *self }
} }
@ -61,7 +61,7 @@ macro_rules! clone_impl {
($t:ty) => { ($t:ty) => {
#[stable(feature = "rust1", since = "1.0.0")] #[stable(feature = "rust1", since = "1.0.0")]
impl Clone for $t { impl Clone for $t {
/// Return a deep copy of the value. /// Returns a deep copy of the value.
#[inline] #[inline]
fn clone(&self) -> $t { *self } fn clone(&self) -> $t { *self }
} }
@ -92,28 +92,28 @@ macro_rules! extern_fn_clone {
#[unstable(feature = "core", #[unstable(feature = "core",
reason = "this may not be sufficient for fns with region parameters")] reason = "this may not be sufficient for fns with region parameters")]
impl<$($A,)* ReturnType> Clone for extern "Rust" fn($($A),*) -> ReturnType { impl<$($A,)* ReturnType> Clone for extern "Rust" fn($($A),*) -> ReturnType {
/// Return a copy of a function pointer /// Returns a copy of a function pointer.
#[inline] #[inline]
fn clone(&self) -> extern "Rust" fn($($A),*) -> ReturnType { *self } fn clone(&self) -> extern "Rust" fn($($A),*) -> ReturnType { *self }
} }
#[unstable(feature = "core", reason = "brand new")] #[unstable(feature = "core", reason = "brand new")]
impl<$($A,)* ReturnType> Clone for extern "C" fn($($A),*) -> ReturnType { impl<$($A,)* ReturnType> Clone for extern "C" fn($($A),*) -> ReturnType {
/// Return a copy of a function pointer /// Returns a copy of a function pointer.
#[inline] #[inline]
fn clone(&self) -> extern "C" fn($($A),*) -> ReturnType { *self } fn clone(&self) -> extern "C" fn($($A),*) -> ReturnType { *self }
} }
#[unstable(feature = "core", reason = "brand new")] #[unstable(feature = "core", reason = "brand new")]
impl<$($A,)* ReturnType> Clone for unsafe extern "Rust" fn($($A),*) -> ReturnType { impl<$($A,)* ReturnType> Clone for unsafe extern "Rust" fn($($A),*) -> ReturnType {
/// Return a copy of a function pointer /// Returns a copy of a function pointer.
#[inline] #[inline]
fn clone(&self) -> unsafe extern "Rust" fn($($A),*) -> ReturnType { *self } fn clone(&self) -> unsafe extern "Rust" fn($($A),*) -> ReturnType { *self }
} }
#[unstable(feature = "core", reason = "brand new")] #[unstable(feature = "core", reason = "brand new")]
impl<$($A,)* ReturnType> Clone for unsafe extern "C" fn($($A),*) -> ReturnType { impl<$($A,)* ReturnType> Clone for unsafe extern "C" fn($($A),*) -> ReturnType {
/// Return a copy of a function pointer /// Returns a copy of a function pointer.
#[inline] #[inline]
fn clone(&self) -> unsafe extern "C" fn($($A),*) -> ReturnType { *self } fn clone(&self) -> unsafe extern "C" fn($($A),*) -> ReturnType { *self }
} }

View File

@ -1,4 +1,4 @@
// Copyright 2013-2014 The Rust Project Developers. See the COPYRIGHT // Copyright 2013-2015 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at // file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT. // http://rust-lang.org/COPYRIGHT.
// //
@ -8,14 +8,10 @@
// option. This file may not be copied, modified, or distributed // option. This file may not be copied, modified, or distributed
// except according to those terms. // except according to those terms.
#![allow(missing_docs)]
pub use self::ExponentFormat::*; pub use self::ExponentFormat::*;
pub use self::SignificantDigits::*; pub use self::SignificantDigits::*;
pub use self::SignFormat::*;
use char; use char::{self, CharExt};
use char::CharExt;
use fmt; use fmt;
use iter::Iterator; use iter::Iterator;
use num::{cast, Float, ToPrimitive}; use num::{cast, Float, ToPrimitive};
@ -46,50 +42,29 @@ pub enum SignificantDigits {
DigExact(usize) DigExact(usize)
} }
/// How to emit the sign of a number. /// Converts a float number to its string representation.
pub enum SignFormat { /// This is meant to be a common base implementation for various formatting styles.
/// `-` will be printed for negative values, but no sign will be emitted /// The number is assumed to be non-negative, callers use `Formatter::pad_integral`
/// for positive numbers. /// to add the right sign, if any.
SignNeg
}
const DIGIT_E_RADIX: u32 = ('e' as u32) - ('a' as u32) + 11;
/// Converts a number to its string representation as a byte vector.
/// This is meant to be a common base implementation for all numeric string
/// conversion functions like `to_string()` or `to_str_radix()`.
/// ///
/// # Arguments /// # Arguments
/// ///
/// - `num` - The number to convert. Accepts any number that /// - `num` - The number to convert (non-negative). Accepts any number that
/// implements the numeric traits. /// implements the numeric traits.
/// - `radix` - Base to use. Accepts only the values 2-36. If the exponential notation
/// is used, then this base is only used for the significand. The exponent
/// itself always printed using a base of 10.
/// - `negative_zero` - Whether to treat the special value `-0` as
/// `-0` or as `+0`.
/// - `sign` - How to emit the sign. See `SignFormat`.
/// - `digits` - The amount of digits to use for emitting the fractional /// - `digits` - The amount of digits to use for emitting the fractional
/// part, if any. See `SignificantDigits`. /// part, if any. See `SignificantDigits`.
/// - `exp_format` - Whether or not to use the exponential (scientific) notation. /// - `exp_format` - Whether or not to use the exponential (scientific) notation.
/// See `ExponentFormat`. /// See `ExponentFormat`.
/// - `exp_capital` - Whether or not to use a capital letter for the exponent sign, if /// - `exp_capital` - Whether or not to use a capital letter for the exponent sign, if
/// exponential notation is desired. /// exponential notation is desired.
/// - `f` - A closure to invoke with the bytes representing the /// - `f` - A closure to invoke with the string representing the
/// float. /// float.
/// ///
/// # Panics /// # Panics
/// ///
/// - Panics if `radix` < 2 or `radix` > 36. /// - Panics if `num` is negative.
/// - Panics if `radix` > 14 and `exp_format` is `ExpDec` due to conflict
/// between digit and exponent sign `'e'`.
/// - Panics if `radix` > 25 and `exp_format` is `ExpBin` due to conflict
/// between digit and exponent sign `'p'`.
pub fn float_to_str_bytes_common<T: Float, U, F>( pub fn float_to_str_bytes_common<T: Float, U, F>(
num: T, num: T,
radix: u32,
negative_zero: bool,
sign: SignFormat,
digits: SignificantDigits, digits: SignificantDigits,
exp_format: ExponentFormat, exp_format: ExponentFormat,
exp_upper: bool, exp_upper: bool,
@ -97,16 +72,12 @@ pub fn float_to_str_bytes_common<T: Float, U, F>(
) -> U where ) -> U where
F: FnOnce(&str) -> U, F: FnOnce(&str) -> U,
{ {
assert!(2 <= radix && radix <= 36);
match exp_format {
ExpDec if radix >= DIGIT_E_RADIX // decimal exponent 'e'
=> panic!("float_to_str_bytes_common: radix {} incompatible with \
use of 'e' as decimal exponent", radix),
_ => ()
}
let _0: T = Float::zero(); let _0: T = Float::zero();
let _1: T = Float::one(); let _1: T = Float::one();
let radix: u32 = 10;
let radix_f: T = cast(radix).unwrap();
assert!(num.is_nan() || num >= _0, "float_to_str_bytes_common: number is negative");
match num.classify() { match num.classify() {
Fp::Nan => return f("NaN"), Fp::Nan => return f("NaN"),
@ -119,41 +90,28 @@ pub fn float_to_str_bytes_common<T: Float, U, F>(
_ => {} _ => {}
} }
let neg = num < _0 || (negative_zero && _1 / num == Float::neg_infinity()); // For an f64 the (decimal) exponent is roughly in the range of [-307, 308], so
// For an f64 the exponent is in the range of [-1022, 1023] for base 2, so // we may have up to that many digits. We err on the side of caution and
// we may have up to that many digits. Give ourselves some extra wiggle room // add 50% extra wiggle room.
// otherwise as well. let mut buf = [0; 462];
let mut buf = [0; 1536];
let mut end = 0; let mut end = 0;
let radix_gen: T = cast(radix as isize).unwrap();
let (num, exp) = match exp_format { let (num, exp) = match exp_format {
ExpNone => (num, 0), ExpDec if num != _0 => {
ExpDec if num == _0 => (num, 0), let exp = num.log10().floor();
ExpDec => { (num / radix_f.powf(exp), cast::<T, i32>(exp).unwrap())
let (exp, exp_base) = match exp_format {
ExpDec => (num.abs().log10().floor(), cast::<f64, T>(10.0f64).unwrap()),
ExpNone => panic!("unreachable"),
};
(num / exp_base.powf(exp), cast::<T, i32>(exp).unwrap())
} }
_ => (num, 0)
}; };
// First emit the non-fractional part, looping at least once to make // First emit the non-fractional part, looping at least once to make
// sure at least a `0` gets emitted. // sure at least a `0` gets emitted.
let mut deccum = num.trunc(); let mut deccum = num.trunc();
loop { loop {
// Calculate the absolute value of each digit instead of only let current_digit = deccum % radix_f;
// doing it once for the whole number because a
// representable negative number doesn't necessary have an
// representable additive inverse of the same type
// (See twos complement). But we assume that for the
// numbers [-35 .. 0] we always have [0 .. 35].
let current_digit = (deccum % radix_gen).abs();
// Decrease the deccumulator one digit at a time // Decrease the deccumulator one digit at a time
deccum = deccum / radix_gen; deccum = deccum / radix_f;
deccum = deccum.trunc(); deccum = deccum.trunc();
let c = char::from_digit(current_digit.to_isize().unwrap() as u32, radix); let c = char::from_digit(current_digit.to_isize().unwrap() as u32, radix);
@ -170,15 +128,6 @@ pub fn float_to_str_bytes_common<T: Float, U, F>(
DigExact(count) => (true, count + 1, true) DigExact(count) => (true, count + 1, true)
}; };
// Decide what sign to put in front
match sign {
SignNeg if neg => {
buf[end] = b'-';
end += 1;
}
_ => ()
}
buf[..end].reverse(); buf[..end].reverse();
// Remember start of the fractional digits. // Remember start of the fractional digits.
@ -205,14 +154,11 @@ pub fn float_to_str_bytes_common<T: Float, U, F>(
) )
) { ) {
// Shift first fractional digit into the integer part // Shift first fractional digit into the integer part
deccum = deccum * radix_gen; deccum = deccum * radix_f;
// Calculate the absolute value of each digit. let current_digit = deccum.trunc();
// See note in first loop.
let current_digit = deccum.trunc().abs();
let c = char::from_digit(current_digit.to_isize().unwrap() as u32, let c = char::from_digit(current_digit.to_isize().unwrap() as u32, radix);
radix);
buf[end] = c.unwrap() as u8; buf[end] = c.unwrap() as u8;
end += 1; end += 1;
@ -301,12 +247,8 @@ pub fn float_to_str_bytes_common<T: Float, U, F>(
match exp_format { match exp_format {
ExpNone => {}, ExpNone => {},
_ => { ExpDec => {
buf[end] = match exp_format { buf[end] = if exp_upper { b'E' } else { b'e' };
ExpDec if exp_upper => 'E',
ExpDec if !exp_upper => 'e',
_ => panic!("unreachable"),
} as u8;
end += 1; end += 1;
struct Filler<'a> { struct Filler<'a> {
@ -324,11 +266,7 @@ pub fn float_to_str_bytes_common<T: Float, U, F>(
} }
let mut filler = Filler { buf: &mut buf, end: &mut end }; let mut filler = Filler { buf: &mut buf, end: &mut end };
match sign { let _ = fmt::write(&mut filler, format_args!("{:-}", exp));
SignNeg => {
let _ = fmt::write(&mut filler, format_args!("{:-}", exp));
}
}
} }
} }

View File

@ -1,4 +1,4 @@
// Copyright 2013-2014 The Rust Project Developers. See the COPYRIGHT // Copyright 2013-2015 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at // file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT. // http://rust-lang.org/COPYRIGHT.
// //
@ -18,6 +18,7 @@ use clone::Clone;
use iter::Iterator; use iter::Iterator;
use marker::{Copy, PhantomData, Sized}; use marker::{Copy, PhantomData, Sized};
use mem; use mem;
use num::Float;
use option::Option; use option::Option;
use option::Option::{Some, None}; use option::Option::{Some, None};
use result::Result::Ok; use result::Result::Ok;
@ -910,33 +911,38 @@ impl<'a, T> Pointer for &'a mut T {
} }
} }
// Common code of floating point Debug and Display.
fn float_to_str_common<T: Float, F>(num: &T, precision: Option<usize>, post: F) -> Result
where F : FnOnce(&str) -> Result {
let digits = match precision {
Some(i) => float::DigExact(i),
None => float::DigMax(6),
};
float::float_to_str_bytes_common(num.abs(),
digits,
float::ExpNone,
false,
post)
}
macro_rules! floating { ($ty:ident) => { macro_rules! floating { ($ty:ident) => {
#[stable(feature = "rust1", since = "1.0.0")] #[stable(feature = "rust1", since = "1.0.0")]
impl Debug for $ty { impl Debug for $ty {
fn fmt(&self, fmt: &mut Formatter) -> Result { fn fmt(&self, fmt: &mut Formatter) -> Result {
Display::fmt(self, fmt) float_to_str_common(self, fmt.precision, |absolute| {
// is_positive() counts -0.0 as negative
fmt.pad_integral(self.is_nan() || self.is_positive(), "", absolute)
})
} }
} }
#[stable(feature = "rust1", since = "1.0.0")] #[stable(feature = "rust1", since = "1.0.0")]
impl Display for $ty { impl Display for $ty {
fn fmt(&self, fmt: &mut Formatter) -> Result { fn fmt(&self, fmt: &mut Formatter) -> Result {
use num::Float; float_to_str_common(self, fmt.precision, |absolute| {
// simple comparison counts -0.0 as positive
let digits = match fmt.precision { fmt.pad_integral(self.is_nan() || *self >= 0.0, "", absolute)
Some(i) => float::DigExact(i),
None => float::DigMax(6),
};
float::float_to_str_bytes_common(self.abs(),
10,
true,
float::SignNeg,
digits,
float::ExpNone,
false,
|bytes| {
fmt.pad_integral(self.is_nan() || *self >= 0.0, "", bytes)
}) })
} }
} }
@ -951,9 +957,6 @@ macro_rules! floating { ($ty:ident) => {
None => float::DigMax(6), None => float::DigMax(6),
}; };
float::float_to_str_bytes_common(self.abs(), float::float_to_str_bytes_common(self.abs(),
10,
true,
float::SignNeg,
digits, digits,
float::ExpDec, float::ExpDec,
false, false,
@ -973,9 +976,6 @@ macro_rules! floating { ($ty:ident) => {
None => float::DigMax(6), None => float::DigMax(6),
}; };
float::float_to_str_bytes_common(self.abs(), float::float_to_str_bytes_common(self.abs(),
10,
true,
float::SignNeg,
digits, digits,
float::ExpDec, float::ExpDec,
true, true,

View File

@ -139,16 +139,16 @@ extern "rust-intrinsic" {
pub fn atomic_fence_rel(); pub fn atomic_fence_rel();
pub fn atomic_fence_acqrel(); pub fn atomic_fence_acqrel();
/// Abort the execution of the process. /// Aborts the execution of the process.
pub fn abort() -> !; pub fn abort() -> !;
/// Tell LLVM that this point in the code is not reachable, /// Tells LLVM that this point in the code is not reachable,
/// enabling further optimizations. /// enabling further optimizations.
/// ///
/// NB: This is very different from the `unreachable!()` macro! /// NB: This is very different from the `unreachable!()` macro!
pub fn unreachable() -> !; pub fn unreachable() -> !;
/// Inform the optimizer that a condition is always true. /// Informs the optimizer that a condition is always true.
/// If the condition is false, the behavior is undefined. /// If the condition is false, the behavior is undefined.
/// ///
/// No code is generated for this intrinsic, but the optimizer will try /// No code is generated for this intrinsic, but the optimizer will try
@ -158,7 +158,7 @@ extern "rust-intrinsic" {
/// own, or if it does not enable any significant optimizations. /// own, or if it does not enable any significant optimizations.
pub fn assume(b: bool); pub fn assume(b: bool);
/// Execute a breakpoint trap, for inspection by a debugger. /// Executes a breakpoint trap, for inspection by a debugger.
pub fn breakpoint(); pub fn breakpoint();
/// The size of a type in bytes. /// The size of a type in bytes.
@ -170,7 +170,7 @@ extern "rust-intrinsic" {
/// elements. /// elements.
pub fn size_of<T>() -> usize; pub fn size_of<T>() -> usize;
/// Move a value to an uninitialized memory location. /// Moves a value to an uninitialized memory location.
/// ///
/// Drop glue is not run on the destination. /// Drop glue is not run on the destination.
pub fn move_val_init<T>(dst: &mut T, src: T); pub fn move_val_init<T>(dst: &mut T, src: T);
@ -186,7 +186,7 @@ extern "rust-intrinsic" {
/// crate it is invoked in. /// crate it is invoked in.
pub fn type_id<T: ?Sized + 'static>() -> u64; pub fn type_id<T: ?Sized + 'static>() -> u64;
/// Create a value initialized to so that its drop flag, /// Creates a value initialized to so that its drop flag,
/// if any, says that it has been dropped. /// if any, says that it has been dropped.
/// ///
/// `init_dropped` is unsafe because it returns a datum with all /// `init_dropped` is unsafe because it returns a datum with all
@ -199,7 +199,7 @@ extern "rust-intrinsic" {
/// intrinsic). /// intrinsic).
pub fn init_dropped<T>() -> T; pub fn init_dropped<T>() -> T;
/// Create a value initialized to zero. /// Creates a value initialized to zero.
/// ///
/// `init` is unsafe because it returns a zeroed-out datum, /// `init` is unsafe because it returns a zeroed-out datum,
/// which is unsafe unless T is `Copy`. Also, even if T is /// which is unsafe unless T is `Copy`. Also, even if T is
@ -207,7 +207,7 @@ extern "rust-intrinsic" {
/// state for the type in question. /// state for the type in question.
pub fn init<T>() -> T; pub fn init<T>() -> T;
/// Create an uninitialized value. /// Creates an uninitialized value.
/// ///
/// `uninit` is unsafe because there is no guarantee of what its /// `uninit` is unsafe because there is no guarantee of what its
/// contents are. In particular its drop-flag may be set to any /// contents are. In particular its drop-flag may be set to any
@ -216,7 +216,7 @@ extern "rust-intrinsic" {
/// initialize memory previous set to the result of `uninit`. /// initialize memory previous set to the result of `uninit`.
pub fn uninit<T>() -> T; pub fn uninit<T>() -> T;
/// Move a value out of scope without running drop glue. /// Moves a value out of scope without running drop glue.
/// ///
/// `forget` is unsafe because the caller is responsible for /// `forget` is unsafe because the caller is responsible for
/// ensuring the argument is deallocated already. /// ensuring the argument is deallocated already.

View File

@ -91,7 +91,7 @@ pub trait Iterator {
#[stable(feature = "rust1", since = "1.0.0")] #[stable(feature = "rust1", since = "1.0.0")]
type Item; type Item;
/// Advance the iterator and return the next value. Return `None` when the /// Advances the iterator and returns the next value. Returns `None` when the
/// end is reached. /// end is reached.
#[stable(feature = "rust1", since = "1.0.0")] #[stable(feature = "rust1", since = "1.0.0")]
fn next(&mut self) -> Option<Self::Item>; fn next(&mut self) -> Option<Self::Item>;
@ -670,7 +670,7 @@ pub trait Iterator {
None None
} }
/// Return the index of the first element satisfying the specified predicate /// Returns the index of the first element satisfying the specified predicate
/// ///
/// Does not consume the iterator past the first found element. /// Does not consume the iterator past the first found element.
/// ///
@ -698,7 +698,7 @@ pub trait Iterator {
None None
} }
/// Return the index of the last element satisfying the specified predicate /// Returns the index of the last element satisfying the specified predicate
/// ///
/// If no element matches, None is returned. /// If no element matches, None is returned.
/// ///
@ -853,7 +853,7 @@ pub trait Iterator {
MinMax(min, max) MinMax(min, max)
} }
/// Return the element that gives the maximum value from the /// Returns the element that gives the maximum value from the
/// specified function. /// specified function.
/// ///
/// Returns the rightmost element if the comparison determines two elements /// Returns the rightmost element if the comparison determines two elements
@ -882,7 +882,7 @@ pub trait Iterator {
.map(|(_, x)| x) .map(|(_, x)| x)
} }
/// Return the element that gives the minimum value from the /// Returns the element that gives the minimum value from the
/// specified function. /// specified function.
/// ///
/// Returns the leftmost element if the comparison determines two elements /// Returns the leftmost element if the comparison determines two elements
@ -1099,7 +1099,7 @@ impl<'a, I: Iterator + ?Sized> Iterator for &'a mut I {
#[rustc_on_unimplemented="a collection of type `{Self}` cannot be \ #[rustc_on_unimplemented="a collection of type `{Self}` cannot be \
built from an iterator over elements of type `{A}`"] built from an iterator over elements of type `{A}`"]
pub trait FromIterator<A> { pub trait FromIterator<A> {
/// Build a container with elements from something iterable. /// Builds a container with elements from something iterable.
/// ///
/// # Examples /// # Examples
/// ///
@ -1158,7 +1158,7 @@ impl<I: Iterator> IntoIterator for I {
/// A type growable from an `Iterator` implementation /// A type growable from an `Iterator` implementation
#[stable(feature = "rust1", since = "1.0.0")] #[stable(feature = "rust1", since = "1.0.0")]
pub trait Extend<A> { pub trait Extend<A> {
/// Extend a container with the elements yielded by an arbitrary iterator /// Extends a container with the elements yielded by an arbitrary iterator
#[stable(feature = "rust1", since = "1.0.0")] #[stable(feature = "rust1", since = "1.0.0")]
fn extend<T: IntoIterator<Item=A>>(&mut self, iterable: T); fn extend<T: IntoIterator<Item=A>>(&mut self, iterable: T);
} }
@ -1170,7 +1170,7 @@ pub trait Extend<A> {
/// independently of each other. /// independently of each other.
#[stable(feature = "rust1", since = "1.0.0")] #[stable(feature = "rust1", since = "1.0.0")]
pub trait DoubleEndedIterator: Iterator { pub trait DoubleEndedIterator: Iterator {
/// Yield an element from the end of the range, returning `None` if the /// Yields an element from the end of the range, returning `None` if the
/// range is empty. /// range is empty.
#[stable(feature = "rust1", since = "1.0.0")] #[stable(feature = "rust1", since = "1.0.0")]
fn next_back(&mut self) -> Option<Self::Item>; fn next_back(&mut self) -> Option<Self::Item>;
@ -1191,11 +1191,11 @@ impl<'a, I: DoubleEndedIterator + ?Sized> DoubleEndedIterator for &'a mut I {
reason = "not widely used, may be better decomposed into Index \ reason = "not widely used, may be better decomposed into Index \
and ExactSizeIterator")] and ExactSizeIterator")]
pub trait RandomAccessIterator: Iterator { pub trait RandomAccessIterator: Iterator {
/// Return the number of indexable elements. At most `std::usize::MAX` /// Returns the number of indexable elements. At most `std::usize::MAX`
/// elements are indexable, even if the iterator represents a longer range. /// elements are indexable, even if the iterator represents a longer range.
fn indexable(&self) -> usize; fn indexable(&self) -> usize;
/// Return an element at an index, or `None` if the index is out of bounds /// Returns an element at an index, or `None` if the index is out of bounds
fn idx(&mut self, index: usize) -> Option<Self::Item>; fn idx(&mut self, index: usize) -> Option<Self::Item>;
} }
@ -1210,7 +1210,7 @@ pub trait RandomAccessIterator: Iterator {
pub trait ExactSizeIterator: Iterator { pub trait ExactSizeIterator: Iterator {
#[inline] #[inline]
#[stable(feature = "rust1", since = "1.0.0")] #[stable(feature = "rust1", since = "1.0.0")]
/// Return the exact length of the iterator. /// Returns the exact length of the iterator.
fn len(&self) -> usize { fn len(&self) -> usize {
let (lower, upper) = self.size_hint(); let (lower, upper) = self.size_hint();
// Note: This assertion is overly defensive, but it checks the invariant // Note: This assertion is overly defensive, but it checks the invariant
@ -1856,7 +1856,7 @@ impl<I: ExactSizeIterator> ExactSizeIterator for Peekable<I> {}
#[stable(feature = "rust1", since = "1.0.0")] #[stable(feature = "rust1", since = "1.0.0")]
impl<I: Iterator> Peekable<I> { impl<I: Iterator> Peekable<I> {
/// Return a reference to the next element of the iterator with out /// Returns a reference to the next element of the iterator with out
/// advancing it, or None if the iterator is exhausted. /// advancing it, or None if the iterator is exhausted.
#[inline] #[inline]
#[stable(feature = "rust1", since = "1.0.0")] #[stable(feature = "rust1", since = "1.0.0")]
@ -1870,7 +1870,7 @@ impl<I: Iterator> Peekable<I> {
} }
} }
/// Check whether peekable iterator is empty or not. /// Checks whether peekable iterator is empty or not.
#[inline] #[inline]
pub fn is_empty(&mut self) -> bool { pub fn is_empty(&mut self) -> bool {
self.peek().is_none() self.peek().is_none()
@ -2401,12 +2401,12 @@ pub trait Step: PartialOrd {
/// Steps `self` if possible. /// Steps `self` if possible.
fn step(&self, by: &Self) -> Option<Self>; fn step(&self, by: &Self) -> Option<Self>;
/// The number of steps between two step objects. /// Returns the number of steps between two step objects.
/// ///
/// `start` should always be less than `end`, so the result should never /// `start` should always be less than `end`, so the result should never
/// be negative. /// be negative.
/// ///
/// Return `None` if it is not possible to calculate steps_between /// Returns `None` if it is not possible to calculate steps_between
/// without overflow. /// without overflow.
fn steps_between(start: &Self, end: &Self, by: &Self) -> Option<usize>; fn steps_between(start: &Self, end: &Self, by: &Self) -> Option<usize>;
} }
@ -2549,7 +2549,7 @@ pub struct RangeInclusive<A> {
done: bool, done: bool,
} }
/// Return an iterator over the range [start, stop] /// Returns an iterator over the range [start, stop].
#[inline] #[inline]
#[unstable(feature = "core", #[unstable(feature = "core",
reason = "likely to be replaced by range notation and adapters")] reason = "likely to be replaced by range notation and adapters")]
@ -2657,7 +2657,7 @@ pub struct RangeStepInclusive<A> {
done: bool, done: bool,
} }
/// Return an iterator over the range [start, stop] by `step`. /// Returns an iterator over the range [start, stop] by `step`.
/// ///
/// It handles overflow by stopping. /// It handles overflow by stopping.
/// ///
@ -2827,7 +2827,7 @@ type IterateState<T, F> = (F, Option<T>, bool);
#[unstable(feature = "core")] #[unstable(feature = "core")]
pub type Iterate<T, F> = Unfold<IterateState<T, F>, fn(&mut IterateState<T, F>) -> Option<T>>; pub type Iterate<T, F> = Unfold<IterateState<T, F>, fn(&mut IterateState<T, F>) -> Option<T>>;
/// Create a new iterator that produces an infinite sequence of /// Creates a new iterator that produces an infinite sequence of
/// repeated applications of the given function `f`. /// repeated applications of the given function `f`.
#[unstable(feature = "core")] #[unstable(feature = "core")]
pub fn iterate<T, F>(seed: T, f: F) -> Iterate<T, F> where pub fn iterate<T, F>(seed: T, f: F) -> Iterate<T, F> where
@ -2853,7 +2853,7 @@ pub fn iterate<T, F>(seed: T, f: F) -> Iterate<T, F> where
Unfold::new((f, Some(seed), true), next) Unfold::new((f, Some(seed), true), next)
} }
/// Create a new iterator that endlessly repeats the element `elt`. /// Creates a new iterator that endlessly repeats the element `elt`.
#[inline] #[inline]
#[stable(feature = "rust1", since = "1.0.0")] #[stable(feature = "rust1", since = "1.0.0")]
pub fn repeat<T: Clone>(elt: T) -> Repeat<T> { pub fn repeat<T: Clone>(elt: T) -> Repeat<T> {
@ -2940,7 +2940,7 @@ pub mod order {
} }
} }
/// Compare `a` and `b` for nonequality (Using partial equality, `PartialEq`) /// Compares `a` and `b` for nonequality (Using partial equality, `PartialEq`)
pub fn ne<L: Iterator, R: Iterator>(mut a: L, mut b: R) -> bool where pub fn ne<L: Iterator, R: Iterator>(mut a: L, mut b: R) -> bool where
L::Item: PartialEq<R::Item>, L::Item: PartialEq<R::Item>,
{ {
@ -2953,7 +2953,7 @@ pub mod order {
} }
} }
/// Return `a` < `b` lexicographically (Using partial order, `PartialOrd`) /// Returns `a` < `b` lexicographically (Using partial order, `PartialOrd`)
pub fn lt<R: Iterator, L: Iterator>(mut a: L, mut b: R) -> bool where pub fn lt<R: Iterator, L: Iterator>(mut a: L, mut b: R) -> bool where
L::Item: PartialOrd<R::Item>, L::Item: PartialOrd<R::Item>,
{ {
@ -2967,7 +2967,7 @@ pub mod order {
} }
} }
/// Return `a` <= `b` lexicographically (Using partial order, `PartialOrd`) /// Returns `a` <= `b` lexicographically (Using partial order, `PartialOrd`)
pub fn le<L: Iterator, R: Iterator>(mut a: L, mut b: R) -> bool where pub fn le<L: Iterator, R: Iterator>(mut a: L, mut b: R) -> bool where
L::Item: PartialOrd<R::Item>, L::Item: PartialOrd<R::Item>,
{ {
@ -2981,7 +2981,7 @@ pub mod order {
} }
} }
/// Return `a` > `b` lexicographically (Using partial order, `PartialOrd`) /// Returns `a` > `b` lexicographically (Using partial order, `PartialOrd`)
pub fn gt<L: Iterator, R: Iterator>(mut a: L, mut b: R) -> bool where pub fn gt<L: Iterator, R: Iterator>(mut a: L, mut b: R) -> bool where
L::Item: PartialOrd<R::Item>, L::Item: PartialOrd<R::Item>,
{ {
@ -2995,7 +2995,7 @@ pub mod order {
} }
} }
/// Return `a` >= `b` lexicographically (Using partial order, `PartialOrd`) /// Returns `a` >= `b` lexicographically (Using partial order, `PartialOrd`)
pub fn ge<L: Iterator, R: Iterator>(mut a: L, mut b: R) -> bool where pub fn ge<L: Iterator, R: Iterator>(mut a: L, mut b: R) -> bool where
L::Item: PartialOrd<R::Item>, L::Item: PartialOrd<R::Item>,
{ {

View File

@ -134,7 +134,7 @@ pub fn align_of_val<T>(_val: &T) -> usize {
align_of::<T>() align_of::<T>()
} }
/// Create a value initialized to zero. /// Creates a value initialized to zero.
/// ///
/// This function is similar to allocating space for a local variable and zeroing it out (an unsafe /// This function is similar to allocating space for a local variable and zeroing it out (an unsafe
/// operation). /// operation).
@ -158,7 +158,7 @@ pub unsafe fn zeroed<T>() -> T {
intrinsics::init() intrinsics::init()
} }
/// Create a value initialized to an unspecified series of bytes. /// Creates a value initialized to an unspecified series of bytes.
/// ///
/// The byte sequence usually indicates that the value at the memory /// The byte sequence usually indicates that the value at the memory
/// in question has been dropped. Thus, *if* T carries a drop flag, /// in question has been dropped. Thus, *if* T carries a drop flag,
@ -179,7 +179,7 @@ pub unsafe fn dropped<T>() -> T {
dropped_impl() dropped_impl()
} }
/// Create an uninitialized value. /// Creates an uninitialized value.
/// ///
/// Care must be taken when using this function, if the type `T` has a destructor and the value /// Care must be taken when using this function, if the type `T` has a destructor and the value
/// falls out of scope (due to unwinding or returning) before being initialized, then the /// falls out of scope (due to unwinding or returning) before being initialized, then the
@ -234,7 +234,7 @@ pub fn swap<T>(x: &mut T, y: &mut T) {
} }
} }
/// Replace the value at a mutable location with a new one, returning the old value, without /// Replaces the value at a mutable location with a new one, returning the old value, without
/// deinitialising or copying either one. /// deinitialising or copying either one.
/// ///
/// This is primarily used for transferring and swapping ownership of a value in a mutable /// This is primarily used for transferring and swapping ownership of a value in a mutable

View File

@ -38,7 +38,7 @@ unsafe impl Zeroable for u64 {}
pub struct NonZero<T: Zeroable>(T); pub struct NonZero<T: Zeroable>(T);
impl<T: Zeroable> NonZero<T> { impl<T: Zeroable> NonZero<T> {
/// Create an instance of NonZero with the provided value. /// Creates an instance of NonZero with the provided value.
/// You must indeed ensure that the value is actually "non-zero". /// You must indeed ensure that the value is actually "non-zero".
#[inline(always)] #[inline(always)]
pub unsafe fn new(inner: T) -> NonZero<T> { pub unsafe fn new(inner: T) -> NonZero<T> {

View File

@ -268,7 +268,7 @@ pub trait Int
#[stable(feature = "rust1", since = "1.0.0")] #[stable(feature = "rust1", since = "1.0.0")]
fn swap_bytes(self) -> Self; fn swap_bytes(self) -> Self;
/// Convert an integer from big endian to the target's endianness. /// Converts an integer from big endian to the target's endianness.
/// ///
/// On big endian this is a no-op. On little endian the bytes are swapped. /// On big endian this is a no-op. On little endian the bytes are swapped.
/// ///
@ -291,7 +291,7 @@ pub trait Int
if cfg!(target_endian = "big") { x } else { x.swap_bytes() } if cfg!(target_endian = "big") { x } else { x.swap_bytes() }
} }
/// Convert an integer from little endian to the target's endianness. /// Converts an integer from little endian to the target's endianness.
/// ///
/// On little endian this is a no-op. On big endian the bytes are swapped. /// On little endian this is a no-op. On big endian the bytes are swapped.
/// ///
@ -314,7 +314,7 @@ pub trait Int
if cfg!(target_endian = "little") { x } else { x.swap_bytes() } if cfg!(target_endian = "little") { x } else { x.swap_bytes() }
} }
/// Convert `self` to big endian from the target's endianness. /// Converts `self` to big endian from the target's endianness.
/// ///
/// On big endian this is a no-op. On little endian the bytes are swapped. /// On big endian this is a no-op. On little endian the bytes are swapped.
/// ///
@ -337,7 +337,7 @@ pub trait Int
if cfg!(target_endian = "big") { self } else { self.swap_bytes() } if cfg!(target_endian = "big") { self } else { self.swap_bytes() }
} }
/// Convert `self` to little endian from the target's endianness. /// Converts `self` to little endian from the target's endianness.
/// ///
/// On little endian this is a no-op. On big endian the bytes are swapped. /// On little endian this is a no-op. On big endian the bytes are swapped.
/// ///
@ -845,7 +845,7 @@ macro_rules! int_impl {
let min: $T = Int::min_value(); !min let min: $T = Int::min_value(); !min
} }
/// Convert a string slice in a given base to an integer. /// Converts a string slice in a given base to an integer.
/// ///
/// Leading and trailing whitespace represent an error. /// Leading and trailing whitespace represent an error.
/// ///
@ -995,7 +995,7 @@ macro_rules! int_impl {
(self as $UnsignedT).swap_bytes() as $T (self as $UnsignedT).swap_bytes() as $T
} }
/// Convert an integer from big endian to the target's endianness. /// Converts an integer from big endian to the target's endianness.
/// ///
/// On big endian this is a no-op. On little endian the bytes are /// On big endian this is a no-op. On little endian the bytes are
/// swapped. /// swapped.
@ -1019,7 +1019,7 @@ macro_rules! int_impl {
if cfg!(target_endian = "big") { x } else { x.swap_bytes() } if cfg!(target_endian = "big") { x } else { x.swap_bytes() }
} }
/// Convert an integer from little endian to the target's endianness. /// Converts an integer from little endian to the target's endianness.
/// ///
/// On little endian this is a no-op. On big endian the bytes are /// On little endian this is a no-op. On big endian the bytes are
/// swapped. /// swapped.
@ -1043,7 +1043,7 @@ macro_rules! int_impl {
if cfg!(target_endian = "little") { x } else { x.swap_bytes() } if cfg!(target_endian = "little") { x } else { x.swap_bytes() }
} }
/// Convert `self` to big endian from the target's endianness. /// Converts `self` to big endian from the target's endianness.
/// ///
/// On big endian this is a no-op. On little endian the bytes are /// On big endian this is a no-op. On little endian the bytes are
/// swapped. /// swapped.
@ -1067,7 +1067,7 @@ macro_rules! int_impl {
if cfg!(target_endian = "big") { self } else { self.swap_bytes() } if cfg!(target_endian = "big") { self } else { self.swap_bytes() }
} }
/// Convert `self` to little endian from the target's endianness. /// Converts `self` to little endian from the target's endianness.
/// ///
/// On little endian this is a no-op. On big endian the bytes are /// On little endian this is a no-op. On big endian the bytes are
/// swapped. /// swapped.
@ -1361,7 +1361,7 @@ macro_rules! uint_impl {
#[stable(feature = "rust1", since = "1.0.0")] #[stable(feature = "rust1", since = "1.0.0")]
pub fn max_value() -> $T { !0 } pub fn max_value() -> $T { !0 }
/// Convert a string slice in a given base to an integer. /// Converts a string slice in a given base to an integer.
/// ///
/// Leading and trailing whitespace represent an error. /// Leading and trailing whitespace represent an error.
/// ///
@ -1517,7 +1517,7 @@ macro_rules! uint_impl {
unsafe { $bswap(self as $ActualT) as $T } unsafe { $bswap(self as $ActualT) as $T }
} }
/// Convert an integer from big endian to the target's endianness. /// Converts an integer from big endian to the target's endianness.
/// ///
/// On big endian this is a no-op. On little endian the bytes are /// On big endian this is a no-op. On little endian the bytes are
/// swapped. /// swapped.
@ -1541,7 +1541,7 @@ macro_rules! uint_impl {
if cfg!(target_endian = "big") { x } else { x.swap_bytes() } if cfg!(target_endian = "big") { x } else { x.swap_bytes() }
} }
/// Convert an integer from little endian to the target's endianness. /// Converts an integer from little endian to the target's endianness.
/// ///
/// On little endian this is a no-op. On big endian the bytes are /// On little endian this is a no-op. On big endian the bytes are
/// swapped. /// swapped.
@ -1565,7 +1565,7 @@ macro_rules! uint_impl {
if cfg!(target_endian = "little") { x } else { x.swap_bytes() } if cfg!(target_endian = "little") { x } else { x.swap_bytes() }
} }
/// Convert `self` to big endian from the target's endianness. /// Converts `self` to big endian from the target's endianness.
/// ///
/// On big endian this is a no-op. On little endian the bytes are /// On big endian this is a no-op. On little endian the bytes are
/// swapped. /// swapped.
@ -1589,7 +1589,7 @@ macro_rules! uint_impl {
if cfg!(target_endian = "big") { self } else { self.swap_bytes() } if cfg!(target_endian = "big") { self } else { self.swap_bytes() }
} }
/// Convert `self` to little endian from the target's endianness. /// Converts `self` to little endian from the target's endianness.
/// ///
/// On little endian this is a no-op. On big endian the bytes are /// On little endian this is a no-op. On big endian the bytes are
/// swapped. /// swapped.
@ -2183,7 +2183,7 @@ impl_to_primitive_float! { f64 }
/// A generic trait for converting a number to a value. /// A generic trait for converting a number to a value.
#[unstable(feature = "core", reason = "trait is likely to be removed")] #[unstable(feature = "core", reason = "trait is likely to be removed")]
pub trait FromPrimitive : ::marker::Sized { pub trait FromPrimitive : ::marker::Sized {
/// Convert an `isize` to return an optional value of this type. If the /// Converts an `isize` to return an optional value of this type. If the
/// value cannot be represented by this value, the `None` is returned. /// value cannot be represented by this value, the `None` is returned.
#[inline] #[inline]
#[unstable(feature = "core")] #[unstable(feature = "core")]
@ -2192,39 +2192,39 @@ pub trait FromPrimitive : ::marker::Sized {
FromPrimitive::from_i64(n as i64) FromPrimitive::from_i64(n as i64)
} }
/// Convert an `isize` to return an optional value of this type. If the /// Converts an `isize` to return an optional value of this type. If the
/// value cannot be represented by this value, the `None` is returned. /// value cannot be represented by this value, the `None` is returned.
#[inline] #[inline]
fn from_isize(n: isize) -> Option<Self> { fn from_isize(n: isize) -> Option<Self> {
FromPrimitive::from_i64(n as i64) FromPrimitive::from_i64(n as i64)
} }
/// Convert an `i8` to return an optional value of this type. If the /// Converts an `i8` to return an optional value of this type. If the
/// type cannot be represented by this value, the `None` is returned. /// type cannot be represented by this value, the `None` is returned.
#[inline] #[inline]
fn from_i8(n: i8) -> Option<Self> { fn from_i8(n: i8) -> Option<Self> {
FromPrimitive::from_i64(n as i64) FromPrimitive::from_i64(n as i64)
} }
/// Convert an `i16` to return an optional value of this type. If the /// Converts an `i16` to return an optional value of this type. If the
/// type cannot be represented by this value, the `None` is returned. /// type cannot be represented by this value, the `None` is returned.
#[inline] #[inline]
fn from_i16(n: i16) -> Option<Self> { fn from_i16(n: i16) -> Option<Self> {
FromPrimitive::from_i64(n as i64) FromPrimitive::from_i64(n as i64)
} }
/// Convert an `i32` to return an optional value of this type. If the /// Converts an `i32` to return an optional value of this type. If the
/// type cannot be represented by this value, the `None` is returned. /// type cannot be represented by this value, the `None` is returned.
#[inline] #[inline]
fn from_i32(n: i32) -> Option<Self> { fn from_i32(n: i32) -> Option<Self> {
FromPrimitive::from_i64(n as i64) FromPrimitive::from_i64(n as i64)
} }
/// Convert an `i64` to return an optional value of this type. If the /// Converts an `i64` to return an optional value of this type. If the
/// type cannot be represented by this value, the `None` is returned. /// type cannot be represented by this value, the `None` is returned.
fn from_i64(n: i64) -> Option<Self>; fn from_i64(n: i64) -> Option<Self>;
/// Convert an `usize` to return an optional value of this type. If the /// Converts an `usize` to return an optional value of this type. If the
/// type cannot be represented by this value, the `None` is returned. /// type cannot be represented by this value, the `None` is returned.
#[inline] #[inline]
#[unstable(feature = "core")] #[unstable(feature = "core")]
@ -2233,46 +2233,46 @@ pub trait FromPrimitive : ::marker::Sized {
FromPrimitive::from_u64(n as u64) FromPrimitive::from_u64(n as u64)
} }
/// Convert a `usize` to return an optional value of this type. If the /// Converts a `usize` to return an optional value of this type. If the
/// type cannot be represented by this value, the `None` is returned. /// type cannot be represented by this value, the `None` is returned.
#[inline] #[inline]
fn from_usize(n: usize) -> Option<Self> { fn from_usize(n: usize) -> Option<Self> {
FromPrimitive::from_u64(n as u64) FromPrimitive::from_u64(n as u64)
} }
/// Convert an `u8` to return an optional value of this type. If the /// Converts an `u8` to return an optional value of this type. If the
/// type cannot be represented by this value, the `None` is returned. /// type cannot be represented by this value, the `None` is returned.
#[inline] #[inline]
fn from_u8(n: u8) -> Option<Self> { fn from_u8(n: u8) -> Option<Self> {
FromPrimitive::from_u64(n as u64) FromPrimitive::from_u64(n as u64)
} }
/// Convert an `u16` to return an optional value of this type. If the /// Converts an `u16` to return an optional value of this type. If the
/// type cannot be represented by this value, the `None` is returned. /// type cannot be represented by this value, the `None` is returned.
#[inline] #[inline]
fn from_u16(n: u16) -> Option<Self> { fn from_u16(n: u16) -> Option<Self> {
FromPrimitive::from_u64(n as u64) FromPrimitive::from_u64(n as u64)
} }
/// Convert an `u32` to return an optional value of this type. If the /// Converts an `u32` to return an optional value of this type. If the
/// type cannot be represented by this value, the `None` is returned. /// type cannot be represented by this value, the `None` is returned.
#[inline] #[inline]
fn from_u32(n: u32) -> Option<Self> { fn from_u32(n: u32) -> Option<Self> {
FromPrimitive::from_u64(n as u64) FromPrimitive::from_u64(n as u64)
} }
/// Convert an `u64` to return an optional value of this type. If the /// Converts an `u64` to return an optional value of this type. If the
/// type cannot be represented by this value, the `None` is returned. /// type cannot be represented by this value, the `None` is returned.
fn from_u64(n: u64) -> Option<Self>; fn from_u64(n: u64) -> Option<Self>;
/// Convert a `f32` to return an optional value of this type. If the /// Converts a `f32` to return an optional value of this type. If the
/// type cannot be represented by this value, the `None` is returned. /// type cannot be represented by this value, the `None` is returned.
#[inline] #[inline]
fn from_f32(n: f32) -> Option<Self> { fn from_f32(n: f32) -> Option<Self> {
FromPrimitive::from_f64(n as f64) FromPrimitive::from_f64(n as f64)
} }
/// Convert a `f64` to return an optional value of this type. If the /// Converts a `f64` to return an optional value of this type. If the
/// type cannot be represented by this value, the `None` is returned. /// type cannot be represented by this value, the `None` is returned.
#[inline] #[inline]
fn from_f64(n: f64) -> Option<Self> { fn from_f64(n: f64) -> Option<Self> {
@ -2401,7 +2401,7 @@ impl_from_primitive! { u64, to_u64 }
impl_from_primitive! { f32, to_f32 } impl_from_primitive! { f32, to_f32 }
impl_from_primitive! { f64, to_f64 } impl_from_primitive! { f64, to_f64 }
/// Cast from one machine scalar to another. /// Casts from one machine scalar to another.
/// ///
/// # Examples /// # Examples
/// ///
@ -2583,16 +2583,16 @@ pub trait Float
/// Returns the mantissa, exponent and sign as integers, respectively. /// Returns the mantissa, exponent and sign as integers, respectively.
fn integer_decode(self) -> (u64, i16, i8); fn integer_decode(self) -> (u64, i16, i8);
/// Return the largest integer less than or equal to a number. /// Returns the largest integer less than or equal to a number.
fn floor(self) -> Self; fn floor(self) -> Self;
/// Return the smallest integer greater than or equal to a number. /// Returns the smallest integer greater than or equal to a number.
fn ceil(self) -> Self; fn ceil(self) -> Self;
/// Return the nearest integer to a number. Round half-way cases away from /// Returns the nearest integer to a number. Round half-way cases away from
/// `0.0`. /// `0.0`.
fn round(self) -> Self; fn round(self) -> Self;
/// Return the integer part of a number. /// Returns the integer part of a number.
fn trunc(self) -> Self; fn trunc(self) -> Self;
/// Return the fractional part of a number. /// Returns the fractional part of a number.
fn fract(self) -> Self; fn fract(self) -> Self;
/// Computes the absolute value of `self`. Returns `Float::nan()` if the /// Computes the absolute value of `self`. Returns `Float::nan()` if the
@ -2615,21 +2615,21 @@ pub trait Float
/// error. This produces a more accurate result with better performance than /// error. This produces a more accurate result with better performance than
/// a separate multiplication operation followed by an add. /// a separate multiplication operation followed by an add.
fn mul_add(self, a: Self, b: Self) -> Self; fn mul_add(self, a: Self, b: Self) -> Self;
/// Take the reciprocal (inverse) of a number, `1/x`. /// Takes the reciprocal (inverse) of a number, `1/x`.
fn recip(self) -> Self; fn recip(self) -> Self;
/// Raise a number to an integer power. /// Raises a number to an integer power.
/// ///
/// Using this function is generally faster than using `powf` /// Using this function is generally faster than using `powf`
fn powi(self, n: i32) -> Self; fn powi(self, n: i32) -> Self;
/// Raise a number to a floating point power. /// Raises a number to a floating point power.
fn powf(self, n: Self) -> Self; fn powf(self, n: Self) -> Self;
/// Take the square root of a number. /// Takes the square root of a number.
/// ///
/// Returns NaN if `self` is a negative number. /// Returns NaN if `self` is a negative number.
fn sqrt(self) -> Self; fn sqrt(self) -> Self;
/// Take the reciprocal (inverse) square root of a number, `1/sqrt(x)`. /// Takes the reciprocal (inverse) square root of a number, `1/sqrt(x)`.
fn rsqrt(self) -> Self; fn rsqrt(self) -> Self;
/// Returns `e^(self)`, (the exponential function). /// Returns `e^(self)`, (the exponential function).
@ -2645,9 +2645,9 @@ pub trait Float
/// Returns the base 10 logarithm of the number. /// Returns the base 10 logarithm of the number.
fn log10(self) -> Self; fn log10(self) -> Self;
/// Convert radians to degrees. /// Converts radians to degrees.
fn to_degrees(self) -> Self; fn to_degrees(self) -> Self;
/// Convert degrees to radians. /// Converts degrees to radians.
fn to_radians(self) -> Self; fn to_radians(self) -> Self;
} }
@ -2682,7 +2682,7 @@ macro_rules! from_str_radix_float_impl {
impl FromStr for $T { impl FromStr for $T {
type Err = ParseFloatError; type Err = ParseFloatError;
/// Convert a string in base 10 to a float. /// Converts a string in base 10 to a float.
/// Accepts an optional decimal exponent. /// Accepts an optional decimal exponent.
/// ///
/// This function accepts strings such as /// This function accepts strings such as
@ -2719,7 +2719,7 @@ macro_rules! from_str_radix_float_impl {
impl FromStrRadix for $T { impl FromStrRadix for $T {
type Err = ParseFloatError; type Err = ParseFloatError;
/// Convert a string in a given base to a float. /// Converts a string in a given base to a float.
/// ///
/// Due to possible conflicts, this function does **not** accept /// Due to possible conflicts, this function does **not** accept
/// the special values `inf`, `-inf`, `+inf` and `NaN`, **nor** /// the special values `inf`, `-inf`, `+inf` and `NaN`, **nor**

View File

@ -223,7 +223,7 @@ impl<T> Option<T> {
// Adapter for working with references // Adapter for working with references
///////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////
/// Convert from `Option<T>` to `Option<&T>` /// Converts from `Option<T>` to `Option<&T>`
/// ///
/// # Examples /// # Examples
/// ///
@ -248,7 +248,7 @@ impl<T> Option<T> {
} }
} }
/// Convert from `Option<T>` to `Option<&mut T>` /// Converts from `Option<T>` to `Option<&mut T>`
/// ///
/// # Examples /// # Examples
/// ///
@ -269,7 +269,7 @@ impl<T> Option<T> {
} }
} }
/// Convert from `Option<T>` to `&mut [T]` (without copying) /// Converts from `Option<T>` to `&mut [T]` (without copying)
/// ///
/// # Examples /// # Examples
/// ///
@ -704,7 +704,7 @@ impl<T> Option<T> {
mem::replace(self, None) mem::replace(self, None)
} }
/// Convert from `Option<T>` to `&[T]` (without copying) /// Converts from `Option<T>` to `&[T]` (without copying)
#[inline] #[inline]
#[unstable(feature = "as_slice", since = "unsure of the utility here")] #[unstable(feature = "as_slice", since = "unsure of the utility here")]
pub fn as_slice<'a>(&'a self) -> &'a [T] { pub fn as_slice<'a>(&'a self) -> &'a [T] {

View File

@ -544,19 +544,19 @@ unsafe impl<T: Send + ?Sized> Send for Unique<T> { }
unsafe impl<T: Sync + ?Sized> Sync for Unique<T> { } unsafe impl<T: Sync + ?Sized> Sync for Unique<T> { }
impl<T: ?Sized> Unique<T> { impl<T: ?Sized> Unique<T> {
/// Create a new `Unique`. /// Creates a new `Unique`.
#[unstable(feature = "unique")] #[unstable(feature = "unique")]
pub unsafe fn new(ptr: *mut T) -> Unique<T> { pub unsafe fn new(ptr: *mut T) -> Unique<T> {
Unique { pointer: NonZero::new(ptr), _marker: PhantomData } Unique { pointer: NonZero::new(ptr), _marker: PhantomData }
} }
/// Dereference the content. /// Dereferences the content.
#[unstable(feature = "unique")] #[unstable(feature = "unique")]
pub unsafe fn get(&self) -> &T { pub unsafe fn get(&self) -> &T {
&**self.pointer &**self.pointer
} }
/// Mutably dereference the content. /// Mutably dereferences the content.
#[unstable(feature = "unique")] #[unstable(feature = "unique")]
pub unsafe fn get_mut(&mut self) -> &mut T { pub unsafe fn get_mut(&mut self) -> &mut T {
&mut ***self &mut ***self

View File

@ -69,7 +69,7 @@
//! let good_result: Result<bool, i32> = good_result.and_then(|i| Ok(i == 11)); //! let good_result: Result<bool, i32> = good_result.and_then(|i| Ok(i == 11));
//! //!
//! // Use `or_else` to handle the error. //! // Use `or_else` to handle the error.
//! let bad_result: Result<i32, i32> = bad_result.or_else(|i| Ok(11)); //! let bad_result: Result<i32, i32> = bad_result.or_else(|i| Ok(i + 20));
//! //!
//! // Consume the result and return the contents with `unwrap`. //! // Consume the result and return the contents with `unwrap`.
//! let final_awesome_result = good_result.unwrap(); //! let final_awesome_result = good_result.unwrap();
@ -85,35 +85,32 @@
//! functions that may encounter errors but don't otherwise return a //! functions that may encounter errors but don't otherwise return a
//! useful value. //! useful value.
//! //!
//! Consider the `write_line` method defined for I/O types //! Consider the `write_all` method defined for I/O types
//! by the [`Writer`](../old_io/trait.Writer.html) trait: //! by the [`Write`](../io/trait.Write.html) trait:
//! //!
//! ``` //! ```
//! # #![feature(old_io)] //! use std::io;
//! use std::old_io::IoError;
//! //!
//! trait Writer { //! trait Writer {
//! fn write_line(&mut self, s: &str) -> Result<(), IoError>; //! fn write_all(&mut self, bytes: &[u8]) -> Result<(), io::Error>;
//! } //! }
//! ``` //! ```
//! //!
//! *Note: The actual definition of `Writer` uses `IoResult`, which //! *Note: The actual definition of `Write` uses `io::Result`, which
//! is just a synonym for `Result<T, IoError>`.* //! is just a synonym for `Result<T, io::Error>`.*
//! //!
//! This method doesn't produce a value, but the write may //! This method doesn't produce a value, but the write may
//! fail. It's crucial to handle the error case, and *not* write //! fail. It's crucial to handle the error case, and *not* write
//! something like this: //! something like this:
//! //!
//! ```{.ignore} //! ```no_run
//! # #![feature(old_io)] //! use std::fs::File;
//! use std::old_io::*; //! use std::io::prelude::*;
//! use std::old_path::Path;
//! //!
//! let mut file = File::open_mode(&Path::new("valuable_data.txt"), Open, Write); //! let mut file = File::create("valuable_data.txt").unwrap();
//! // If `write_line` errors, then we'll never know, because the return //! // If `write_all` errors, then we'll never know, because the return
//! // value is ignored. //! // value is ignored.
//! file.write_line("important message"); //! file.write_all(b"important message");
//! drop(file);
//! ``` //! ```
//! //!
//! If you *do* write that in Rust, the compiler will give you a //! If you *do* write that in Rust, the compiler will give you a
@ -125,37 +122,31 @@
//! a marginally useful message indicating why: //! a marginally useful message indicating why:
//! //!
//! ```{.no_run} //! ```{.no_run}
//! # #![feature(old_io, old_path)] //! use std::fs::File;
//! use std::old_io::*; //! use std::io::prelude::*;
//! use std::old_path::Path;
//! //!
//! let mut file = File::open_mode(&Path::new("valuable_data.txt"), Open, Write); //! let mut file = File::create("valuable_data.txt").unwrap();
//! file.write_line("important message").ok().expect("failed to write message"); //! file.write_all(b"important message").ok().expect("failed to write message");
//! drop(file);
//! ``` //! ```
//! //!
//! You might also simply assert success: //! You might also simply assert success:
//! //!
//! ```{.no_run} //! ```{.no_run}
//! # #![feature(old_io, old_path)] //! # use std::fs::File;
//! # use std::old_io::*; //! # use std::io::prelude::*;
//! # use std::old_path::Path; //! # let mut file = File::create("valuable_data.txt").unwrap();
//! //! assert!(file.write_all(b"important message").is_ok());
//! # let mut file = File::open_mode(&Path::new("valuable_data.txt"), Open, Write);
//! assert!(file.write_line("important message").is_ok());
//! # drop(file);
//! ``` //! ```
//! //!
//! Or propagate the error up the call stack with `try!`: //! Or propagate the error up the call stack with `try!`:
//! //!
//! ``` //! ```
//! # #![feature(old_io, old_path)] //! # use std::fs::File;
//! # use std::old_io::*; //! # use std::io::prelude::*;
//! # use std::old_path::Path; //! # use std::io;
//! fn write_message() -> Result<(), IoError> { //! fn write_message() -> io::Result<()> {
//! let mut file = File::open_mode(&Path::new("valuable_data.txt"), Open, Write); //! let mut file = try!(File::create("valuable_data.txt"));
//! try!(file.write_line("important message")); //! try!(file.write_all(b"important message"));
//! drop(file);
//! Ok(()) //! Ok(())
//! } //! }
//! ``` //! ```
@ -170,9 +161,9 @@
//! It replaces this: //! It replaces this:
//! //!
//! ``` //! ```
//! # #![feature(old_io, old_path)] //! use std::fs::File;
//! use std::old_io::*; //! use std::io::prelude::*;
//! use std::old_path::Path; //! use std::io;
//! //!
//! struct Info { //! struct Info {
//! name: String, //! name: String,
@ -180,25 +171,28 @@
//! rating: i32, //! rating: i32,
//! } //! }
//! //!
//! fn write_info(info: &Info) -> Result<(), IoError> { //! fn write_info(info: &Info) -> io::Result<()> {
//! let mut file = File::open_mode(&Path::new("my_best_friends.txt"), Open, Write); //! let mut file = try!(File::create("my_best_friends.txt"));
//! // Early return on error //! // Early return on error
//! if let Err(e) = file.write_line(&format!("name: {}", info.name)) { //! if let Err(e) = file.write_all(format!("name: {}\n", info.name).as_bytes()) {
//! return Err(e) //! return Err(e)
//! } //! }
//! if let Err(e) = file.write_line(&format!("age: {}", info.age)) { //! if let Err(e) = file.write_all(format!("age: {}\n", info.age).as_bytes()) {
//! return Err(e) //! return Err(e)
//! } //! }
//! file.write_line(&format!("rating: {}", info.rating)) //! if let Err(e) = file.write_all(format!("rating: {}\n", info.rating).as_bytes()) {
//! return Err(e)
//! }
//! Ok(())
//! } //! }
//! ``` //! ```
//! //!
//! With this: //! With this:
//! //!
//! ``` //! ```
//! # #![feature(old_io, old_path)] //! use std::fs::File;
//! use std::old_io::*; //! use std::io::prelude::*;
//! use std::old_path::Path; //! use std::io;
//! //!
//! struct Info { //! struct Info {
//! name: String, //! name: String,
@ -206,12 +200,12 @@
//! rating: i32, //! rating: i32,
//! } //! }
//! //!
//! fn write_info(info: &Info) -> Result<(), IoError> { //! fn write_info(info: &Info) -> io::Result<()> {
//! let mut file = File::open_mode(&Path::new("my_best_friends.txt"), Open, Write); //! let mut file = try!(File::create("my_best_friends.txt"));
//! // Early return on error //! // Early return on error
//! try!(file.write_line(&format!("name: {}", info.name))); //! try!(file.write_all(format!("name: {}\n", info.name).as_bytes()));
//! try!(file.write_line(&format!("age: {}", info.age))); //! try!(file.write_all(format!("age: {}\n", info.age).as_bytes()));
//! try!(file.write_line(&format!("rating: {}", info.rating))); //! try!(file.write_all(format!("rating: {}\n", info.rating).as_bytes()));
//! Ok(()) //! Ok(())
//! } //! }
//! ``` //! ```
@ -311,7 +305,7 @@ impl<T, E> Result<T, E> {
// Adapter for each variant // Adapter for each variant
///////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////
/// Convert from `Result<T, E>` to `Option<T>` /// Converts from `Result<T, E>` to `Option<T>`
/// ///
/// Converts `self` into an `Option<T>`, consuming `self`, /// Converts `self` into an `Option<T>`, consuming `self`,
/// and discarding the error, if any. /// and discarding the error, if any.
@ -334,7 +328,7 @@ impl<T, E> Result<T, E> {
} }
} }
/// Convert from `Result<T, E>` to `Option<E>` /// Converts from `Result<T, E>` to `Option<E>`
/// ///
/// Converts `self` into an `Option<E>`, consuming `self`, /// Converts `self` into an `Option<E>`, consuming `self`,
/// and discarding the success value, if any. /// and discarding the success value, if any.
@ -361,7 +355,7 @@ impl<T, E> Result<T, E> {
// Adapter for working with references // Adapter for working with references
///////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////
/// Convert from `Result<T, E>` to `Result<&T, &E>` /// Converts from `Result<T, E>` to `Result<&T, &E>`
/// ///
/// Produces a new `Result`, containing a reference /// Produces a new `Result`, containing a reference
/// into the original, leaving the original in place. /// into the original, leaving the original in place.
@ -382,7 +376,7 @@ impl<T, E> Result<T, E> {
} }
} }
/// Convert from `Result<T, E>` to `Result<&mut T, &mut E>` /// Converts from `Result<T, E>` to `Result<&mut T, &mut E>`
/// ///
/// ``` /// ```
/// fn mutate(r: &mut Result<i32, i32>) { /// fn mutate(r: &mut Result<i32, i32>) {
@ -409,7 +403,7 @@ impl<T, E> Result<T, E> {
} }
} }
/// Convert from `Result<T, E>` to `&[T]` (without copying) /// Converts from `Result<T, E>` to `&[T]` (without copying)
#[inline] #[inline]
#[unstable(feature = "as_slice", since = "unsure of the utility here")] #[unstable(feature = "as_slice", since = "unsure of the utility here")]
pub fn as_slice(&self) -> &[T] { pub fn as_slice(&self) -> &[T] {
@ -423,7 +417,7 @@ impl<T, E> Result<T, E> {
} }
} }
/// Convert from `Result<T, E>` to `&mut [T]` (without copying) /// Converts from `Result<T, E>` to `&mut [T]` (without copying)
/// ///
/// ``` /// ```
/// # #![feature(core)] /// # #![feature(core)]
@ -464,29 +458,17 @@ impl<T, E> Result<T, E> {
/// ///
/// # Examples /// # Examples
/// ///
/// Sum the lines of a buffer by mapping strings to numbers, /// Print the numbers on each line of a string multiplied by two.
/// ignoring I/O and parse errors:
/// ///
/// ``` /// ```
/// # #![feature(old_io)] /// let line = "1\n2\n3\n4\n";
/// use std::old_io::*;
/// ///
/// let mut buffer: &[u8] = b"1\n2\n3\n4\n"; /// for num in line.lines() {
/// let mut buffer = &mut buffer; /// match num.parse::<i32>().map(|i| i * 2) {
/// /// Ok(n) => println!("{}", n),
/// let mut sum = 0; /// Err(..) => {}
/// /// }
/// while !buffer.is_empty() {
/// let line: IoResult<String> = buffer.read_line();
/// // Convert the string line to a number using `map` and `from_str`
/// let val: IoResult<i32> = line.map(|line| {
/// line.trim_right().parse::<i32>().unwrap_or(0)
/// });
/// // Add the value if there were no errors, otherwise add 0
/// sum += val.unwrap_or(0);
/// } /// }
///
/// assert!(sum == 10);
/// ``` /// ```
#[inline] #[inline]
#[stable(feature = "rust1", since = "1.0.0")] #[stable(feature = "rust1", since = "1.0.0")]
@ -811,7 +793,7 @@ impl<T: fmt::Debug, E> Result<T, E> {
reason = "use inherent method instead")] reason = "use inherent method instead")]
#[allow(deprecated)] #[allow(deprecated)]
impl<T, E> AsSlice<T> for Result<T, E> { impl<T, E> AsSlice<T> for Result<T, E> {
/// Convert from `Result<T, E>` to `&[T]` (without copying) /// Converts from `Result<T, E>` to `&[T]` (without copying)
#[inline] #[inline]
fn as_slice<'a>(&'a self) -> &'a [T] { fn as_slice<'a>(&'a self) -> &'a [T] {
match *self { match *self {
@ -974,7 +956,7 @@ impl<A, E, V: FromIterator<A>> FromIterator<Result<A, E>> for Result<V, E> {
// FromIterator // FromIterator
///////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////
/// Perform a fold operation over the result values from an iterator. /// Performs a fold operation over the result values from an iterator.
/// ///
/// If an `Err` is encountered, it is immediately returned. /// If an `Err` is encountered, it is immediately returned.
/// Otherwise, the folded value is returned. /// Otherwise, the folded value is returned.

View File

@ -106,19 +106,19 @@ Section: Creating a string
/// Errors which can occur when attempting to interpret a byte slice as a `str`. /// Errors which can occur when attempting to interpret a byte slice as a `str`.
#[derive(Copy, Eq, PartialEq, Clone, Debug)] #[derive(Copy, Eq, PartialEq, Clone, Debug)]
#[unstable(feature = "core", #[stable(feature = "rust1", since = "1.0.0")]
reason = "error enumeration recently added and definitions may be refined")] pub struct Utf8Error {
pub enum Utf8Error { valid_up_to: usize,
/// An invalid byte was detected at the byte offset given. }
///
/// The offset is guaranteed to be in bounds of the slice in question, and
/// the byte at the specified offset was the first invalid byte in the
/// sequence detected.
InvalidByte(usize),
/// The byte slice was invalid because more bytes were needed but no more impl Utf8Error {
/// bytes were available. /// Returns the index in the given string up to which valid UTF-8 was
TooShort, /// verified.
///
/// Starting at the index provided, but not necessarily at it precisely, an
/// invalid UTF-8 encoding sequence was found.
#[unstable(feature = "utf8_error", reason = "method just added")]
pub fn valid_up_to(&self) -> usize { self.valid_up_to }
} }
/// Converts a slice of bytes to a string slice without performing any /// Converts a slice of bytes to a string slice without performing any
@ -147,14 +147,7 @@ pub unsafe fn from_utf8_unchecked<'a>(v: &'a [u8]) -> &'a str {
#[stable(feature = "rust1", since = "1.0.0")] #[stable(feature = "rust1", since = "1.0.0")]
impl fmt::Display for Utf8Error { impl fmt::Display for Utf8Error {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match *self { write!(f, "invalid utf-8: invalid byte near index {}", self.valid_up_to)
Utf8Error::InvalidByte(n) => {
write!(f, "invalid utf-8: invalid byte at index {}", n)
}
Utf8Error::TooShort => {
write!(f, "invalid utf-8: byte slice too short")
}
}
} }
} }
@ -1218,14 +1211,16 @@ fn run_utf8_validation_iterator(iter: &mut slice::Iter<u8>)
// restore the iterator we had at the start of this codepoint. // restore the iterator we had at the start of this codepoint.
macro_rules! err { () => {{ macro_rules! err { () => {{
*iter = old.clone(); *iter = old.clone();
return Err(Utf8Error::InvalidByte(whole.len() - iter.as_slice().len())) return Err(Utf8Error {
valid_up_to: whole.len() - iter.as_slice().len()
})
}}} }}}
macro_rules! next { () => { macro_rules! next { () => {
match iter.next() { match iter.next() {
Some(a) => *a, Some(a) => *a,
// we needed data, but there was none: error! // we needed data, but there was none: error!
None => return Err(Utf8Error::TooShort), None => err!(),
} }
}} }}

View File

@ -32,17 +32,17 @@ pub trait Pattern<'a>: Sized {
/// Associated searcher for this pattern /// Associated searcher for this pattern
type Searcher: Searcher<'a>; type Searcher: Searcher<'a>;
/// Construct the associated searcher from /// Constructs the associated searcher from
/// `self` and the `haystack` to search in. /// `self` and the `haystack` to search in.
fn into_searcher(self, haystack: &'a str) -> Self::Searcher; fn into_searcher(self, haystack: &'a str) -> Self::Searcher;
/// Check whether the pattern matches anywhere in the haystack /// Checks whether the pattern matches anywhere in the haystack
#[inline] #[inline]
fn is_contained_in(self, haystack: &'a str) -> bool { fn is_contained_in(self, haystack: &'a str) -> bool {
self.into_searcher(haystack).next_match().is_some() self.into_searcher(haystack).next_match().is_some()
} }
/// Check whether the pattern matches at the front of the haystack /// Checks whether the pattern matches at the front of the haystack
#[inline] #[inline]
fn is_prefix_of(self, haystack: &'a str) -> bool { fn is_prefix_of(self, haystack: &'a str) -> bool {
match self.into_searcher(haystack).next() { match self.into_searcher(haystack).next() {
@ -51,7 +51,7 @@ pub trait Pattern<'a>: Sized {
} }
} }
/// Check whether the pattern matches at the back of the haystack /// Checks whether the pattern matches at the back of the haystack
#[inline] #[inline]
fn is_suffix_of(self, haystack: &'a str) -> bool fn is_suffix_of(self, haystack: &'a str) -> bool
where Self::Searcher: ReverseSearcher<'a> where Self::Searcher: ReverseSearcher<'a>

View File

@ -169,42 +169,42 @@ fn test_radix_base_too_large() {
mod u32 { mod u32 {
use test::Bencher; use test::Bencher;
use core::fmt::radix; use core::fmt::radix;
use std::rand::{weak_rng, Rng}; use std::__rand::{thread_rng, Rng};
use std::io::{Write, sink}; use std::io::{Write, sink};
#[bench] #[bench]
fn format_bin(b: &mut Bencher) { fn format_bin(b: &mut Bencher) {
let mut rng = weak_rng(); let mut rng = thread_rng();
b.iter(|| { write!(&mut sink(), "{:b}", rng.gen::<u32>()) }) b.iter(|| { write!(&mut sink(), "{:b}", rng.gen::<u32>()) })
} }
#[bench] #[bench]
fn format_oct(b: &mut Bencher) { fn format_oct(b: &mut Bencher) {
let mut rng = weak_rng(); let mut rng = thread_rng();
b.iter(|| { write!(&mut sink(), "{:o}", rng.gen::<u32>()) }) b.iter(|| { write!(&mut sink(), "{:o}", rng.gen::<u32>()) })
} }
#[bench] #[bench]
fn format_dec(b: &mut Bencher) { fn format_dec(b: &mut Bencher) {
let mut rng = weak_rng(); let mut rng = thread_rng();
b.iter(|| { write!(&mut sink(), "{}", rng.gen::<u32>()) }) b.iter(|| { write!(&mut sink(), "{}", rng.gen::<u32>()) })
} }
#[bench] #[bench]
fn format_hex(b: &mut Bencher) { fn format_hex(b: &mut Bencher) {
let mut rng = weak_rng(); let mut rng = thread_rng();
b.iter(|| { write!(&mut sink(), "{:x}", rng.gen::<u32>()) }) b.iter(|| { write!(&mut sink(), "{:x}", rng.gen::<u32>()) })
} }
#[bench] #[bench]
fn format_show(b: &mut Bencher) { fn format_show(b: &mut Bencher) {
let mut rng = weak_rng(); let mut rng = thread_rng();
b.iter(|| { write!(&mut sink(), "{:?}", rng.gen::<u32>()) }) b.iter(|| { write!(&mut sink(), "{:?}", rng.gen::<u32>()) })
} }
#[bench] #[bench]
fn format_base_36(b: &mut Bencher) { fn format_base_36(b: &mut Bencher) {
let mut rng = weak_rng(); let mut rng = thread_rng();
b.iter(|| { write!(&mut sink(), "{}", radix(rng.gen::<u32>(), 36)) }) b.iter(|| { write!(&mut sink(), "{}", radix(rng.gen::<u32>(), 36)) })
} }
} }
@ -212,42 +212,42 @@ mod u32 {
mod i32 { mod i32 {
use test::Bencher; use test::Bencher;
use core::fmt::radix; use core::fmt::radix;
use std::rand::{weak_rng, Rng}; use std::__rand::{thread_rng, Rng};
use std::io::{Write, sink}; use std::io::{Write, sink};
#[bench] #[bench]
fn format_bin(b: &mut Bencher) { fn format_bin(b: &mut Bencher) {
let mut rng = weak_rng(); let mut rng = thread_rng();
b.iter(|| { write!(&mut sink(), "{:b}", rng.gen::<i32>()) }) b.iter(|| { write!(&mut sink(), "{:b}", rng.gen::<i32>()) })
} }
#[bench] #[bench]
fn format_oct(b: &mut Bencher) { fn format_oct(b: &mut Bencher) {
let mut rng = weak_rng(); let mut rng = thread_rng();
b.iter(|| { write!(&mut sink(), "{:o}", rng.gen::<i32>()) }) b.iter(|| { write!(&mut sink(), "{:o}", rng.gen::<i32>()) })
} }
#[bench] #[bench]
fn format_dec(b: &mut Bencher) { fn format_dec(b: &mut Bencher) {
let mut rng = weak_rng(); let mut rng = thread_rng();
b.iter(|| { write!(&mut sink(), "{}", rng.gen::<i32>()) }) b.iter(|| { write!(&mut sink(), "{}", rng.gen::<i32>()) })
} }
#[bench] #[bench]
fn format_hex(b: &mut Bencher) { fn format_hex(b: &mut Bencher) {
let mut rng = weak_rng(); let mut rng = thread_rng();
b.iter(|| { write!(&mut sink(), "{:x}", rng.gen::<i32>()) }) b.iter(|| { write!(&mut sink(), "{:x}", rng.gen::<i32>()) })
} }
#[bench] #[bench]
fn format_show(b: &mut Bencher) { fn format_show(b: &mut Bencher) {
let mut rng = weak_rng(); let mut rng = thread_rng();
b.iter(|| { write!(&mut sink(), "{:?}", rng.gen::<i32>()) }) b.iter(|| { write!(&mut sink(), "{:?}", rng.gen::<i32>()) })
} }
#[bench] #[bench]
fn format_base_36(b: &mut Bencher) { fn format_base_36(b: &mut Bencher) {
let mut rng = weak_rng(); let mut rng = thread_rng();
b.iter(|| { write!(&mut sink(), "{}", radix(rng.gen::<i32>(), 36)) }) b.iter(|| { write!(&mut sink(), "{}", radix(rng.gen::<i32>(), 36)) })
} }
} }

View File

@ -155,12 +155,11 @@ pub fn inflate_bytes_zlib(bytes: &[u8]) -> Result<Bytes,Error> {
mod tests { mod tests {
#![allow(deprecated)] #![allow(deprecated)]
use super::{inflate_bytes, deflate_bytes}; use super::{inflate_bytes, deflate_bytes};
use std::rand; use std::__rand::{thread_rng, Rng};
use std::rand::Rng;
#[test] #[test]
fn test_flate_round_trip() { fn test_flate_round_trip() {
let mut r = rand::thread_rng(); let mut r = thread_rng();
let mut words = vec![]; let mut words = vec![];
for _ in 0..20 { for _ in 0..20 {
let range = r.gen_range(1, 10); let range = r.gen_range(1, 10);

View File

@ -3344,6 +3344,8 @@ pub mod consts {
pub const _SC_XOPEN_REALTIME : c_int = 130; pub const _SC_XOPEN_REALTIME : c_int = 130;
pub const _SC_XOPEN_REALTIME_THREADS : c_int = 131; pub const _SC_XOPEN_REALTIME_THREADS : c_int = 131;
pub const PTHREAD_CREATE_JOINABLE: c_int = 0; pub const PTHREAD_CREATE_JOINABLE: c_int = 0;
pub const PTHREAD_CREATE_DETACHED: c_int = 1; pub const PTHREAD_CREATE_DETACHED: c_int = 1;
@ -3727,12 +3729,14 @@ pub mod consts {
pub const _SC_2_FORT_RUN : c_int = 50; pub const _SC_2_FORT_RUN : c_int = 50;
pub const _SC_2_SW_DEV : c_int = 51; pub const _SC_2_SW_DEV : c_int = 51;
pub const _SC_2_LOCALEDEF : c_int = 52; pub const _SC_2_LOCALEDEF : c_int = 52;
pub const _SC_NPROCESSORS_ONLN : c_int = 84;
pub const _SC_2_CHAR_TERM : c_int = 95; pub const _SC_2_CHAR_TERM : c_int = 95;
pub const _SC_2_C_VERSION : c_int = 96; pub const _SC_2_C_VERSION : c_int = 96;
pub const _SC_2_UPE : c_int = 97; pub const _SC_2_UPE : c_int = 97;
pub const _SC_XBS5_ILP32_OFF32 : c_int = 125; pub const _SC_XBS5_ILP32_OFF32 : c_int = 125;
pub const _SC_XBS5_ILP32_OFFBIG : c_int = 126; pub const _SC_XBS5_ILP32_OFFBIG : c_int = 126;
pub const _SC_XBS5_LPBIG_OFFBIG : c_int = 128; pub const _SC_XBS5_LPBIG_OFFBIG : c_int = 128;
} }
#[cfg(target_os = "nacl")] #[cfg(target_os = "nacl")]
pub mod sysconf { pub mod sysconf {
@ -3742,6 +3746,13 @@ pub mod consts {
pub static _SC_NPROCESSORS_ONLN : c_int = 1; pub static _SC_NPROCESSORS_ONLN : c_int = 1;
pub static _SC_PAGESIZE : c_int = 2; pub static _SC_PAGESIZE : c_int = 2;
} }
#[cfg(target_os = "macos")]
pub mod sysconf {
use types::os::arch::c95::c_int;
pub static _SC_NPROCESSORS_ONLN : c_int = 58;
}
#[cfg(target_os = "android")] #[cfg(target_os = "android")]
pub mod sysconf { pub mod sysconf {
use types::os::arch::c95::c_int; use types::os::arch::c95::c_int;

View File

@ -56,18 +56,6 @@ impl Rand for Exp1 {
/// ///
/// This distribution has density function: `f(x) = lambda * /// This distribution has density function: `f(x) = lambda *
/// exp(-lambda * x)` for `x > 0`. /// exp(-lambda * x)` for `x > 0`.
///
/// # Examples
///
/// ```
/// # #![feature(rand)]
/// use std::rand;
/// use std::rand::distributions::{Exp, IndependentSample};
///
/// let exp = Exp::new(2.0);
/// let v = exp.ind_sample(&mut rand::thread_rng());
/// println!("{} is from a Exp(2) distribution", v);
/// ```
#[derive(Copy, Clone)] #[derive(Copy, Clone)]
pub struct Exp { pub struct Exp {
/// `lambda` stored as `1/lambda`, since this is what we scale by. /// `lambda` stored as `1/lambda`, since this is what we scale by.

View File

@ -37,18 +37,6 @@ use super::{IndependentSample, Sample, Exp};
/// == 1`, and using the boosting technique described in [1] for /// == 1`, and using the boosting technique described in [1] for
/// `shape < 1`. /// `shape < 1`.
/// ///
/// # Examples
///
/// ```
/// # #![feature(rand)]
/// use std::rand;
/// use std::rand::distributions::{IndependentSample, Gamma};
///
/// let gamma = Gamma::new(2.0, 5.0);
/// let v = gamma.ind_sample(&mut rand::thread_rng());
/// println!("{} is from a Gamma(2, 5) distribution", v);
/// ```
///
/// [1]: George Marsaglia and Wai Wan Tsang. 2000. "A Simple Method /// [1]: George Marsaglia and Wai Wan Tsang. 2000. "A Simple Method
/// for Generating Gamma Variables" *ACM Trans. Math. Softw.* 26, 3 /// for Generating Gamma Variables" *ACM Trans. Math. Softw.* 26, 3
/// (September 2000), /// (September 2000),
@ -184,18 +172,6 @@ impl IndependentSample<f64> for GammaLargeShape {
/// of `k` independent standard normal random variables. For other /// of `k` independent standard normal random variables. For other
/// `k`, this uses the equivalent characterisation `χ²(k) = Gamma(k/2, /// `k`, this uses the equivalent characterisation `χ²(k) = Gamma(k/2,
/// 2)`. /// 2)`.
///
/// # Examples
///
/// ```
/// # #![feature(rand)]
/// use std::rand;
/// use std::rand::distributions::{ChiSquared, IndependentSample};
///
/// let chi = ChiSquared::new(11.0);
/// let v = chi.ind_sample(&mut rand::thread_rng());
/// println!("{} is from a χ²(11) distribution", v)
/// ```
pub struct ChiSquared { pub struct ChiSquared {
repr: ChiSquaredRepr, repr: ChiSquaredRepr,
} }
@ -242,18 +218,6 @@ impl IndependentSample<f64> for ChiSquared {
/// This distribution is equivalent to the ratio of two normalised /// This distribution is equivalent to the ratio of two normalised
/// chi-squared distributions, that is, `F(m,n) = (χ²(m)/m) / /// chi-squared distributions, that is, `F(m,n) = (χ²(m)/m) /
/// (χ²(n)/n)`. /// (χ²(n)/n)`.
///
/// # Examples
///
/// ```
/// # #![feature(rand)]
/// use std::rand;
/// use std::rand::distributions::{FisherF, IndependentSample};
///
/// let f = FisherF::new(2.0, 32.0);
/// let v = f.ind_sample(&mut rand::thread_rng());
/// println!("{} is from an F(2, 32) distribution", v)
/// ```
pub struct FisherF { pub struct FisherF {
numer: ChiSquared, numer: ChiSquared,
denom: ChiSquared, denom: ChiSquared,
@ -287,18 +251,6 @@ impl IndependentSample<f64> for FisherF {
/// The Student t distribution, `t(nu)`, where `nu` is the degrees of /// The Student t distribution, `t(nu)`, where `nu` is the degrees of
/// freedom. /// freedom.
///
/// # Examples
///
/// ```
/// # #![feature(rand)]
/// use std::rand;
/// use std::rand::distributions::{StudentT, IndependentSample};
///
/// let t = StudentT::new(11.0);
/// let v = t.ind_sample(&mut rand::thread_rng());
/// println!("{} is from a t(11) distribution", v)
/// ```
pub struct StudentT { pub struct StudentT {
chi: ChiSquared, chi: ChiSquared,
dof: f64 dof: f64

View File

@ -90,24 +90,6 @@ pub struct Weighted<T> {
/// `IndependentSample` traits. Note that `&T` is (cheaply) `Clone` for /// `IndependentSample` traits. Note that `&T` is (cheaply) `Clone` for
/// all `T`, as is `usize`, so one can store references or indices into /// all `T`, as is `usize`, so one can store references or indices into
/// another vector. /// another vector.
///
/// # Examples
///
/// ```
/// # #![feature(rand)]
/// use std::rand;
/// use std::rand::distributions::{Weighted, WeightedChoice, IndependentSample};
///
/// let mut items = vec!(Weighted { weight: 2, item: 'a' },
/// Weighted { weight: 4, item: 'b' },
/// Weighted { weight: 1, item: 'c' });
/// let wc = WeightedChoice::new(&mut items[..]);
/// let mut rng = rand::thread_rng();
/// for _ in 0..16 {
/// // on average prints 'a' 4 times, 'b' 8 and 'c' twice.
/// println!("{}", wc.ind_sample(&mut rng));
/// }
/// ```
pub struct WeightedChoice<'a, T:'a> { pub struct WeightedChoice<'a, T:'a> {
items: &'a mut [Weighted<T>], items: &'a mut [Weighted<T>],
weight_range: Range<usize> weight_range: Range<usize>

View File

@ -72,19 +72,6 @@ impl Rand for StandardNormal {
/// ///
/// This uses the ZIGNOR variant of the Ziggurat method, see /// This uses the ZIGNOR variant of the Ziggurat method, see
/// `StandardNormal` for more details. /// `StandardNormal` for more details.
///
/// # Examples
///
/// ```
/// # #![feature(rand)]
/// use std::rand;
/// use std::rand::distributions::{Normal, IndependentSample};
///
/// // mean 2, standard deviation 3
/// let normal = Normal::new(2.0, 3.0);
/// let v = normal.ind_sample(&mut rand::thread_rng());
/// println!("{} is from a N(2, 9) distribution", v)
/// ```
#[derive(Copy, Clone)] #[derive(Copy, Clone)]
pub struct Normal { pub struct Normal {
mean: f64, mean: f64,
@ -121,19 +108,6 @@ impl IndependentSample<f64> for Normal {
/// ///
/// If `X` is log-normal distributed, then `ln(X)` is `N(mean, /// If `X` is log-normal distributed, then `ln(X)` is `N(mean,
/// std_dev**2)` distributed. /// std_dev**2)` distributed.
///
/// # Examples
///
/// ```
/// # #![feature(rand)]
/// use std::rand;
/// use std::rand::distributions::{LogNormal, IndependentSample};
///
/// // mean 2, standard deviation 3
/// let log_normal = LogNormal::new(2.0, 3.0);
/// let v = log_normal.ind_sample(&mut rand::thread_rng());
/// println!("{} is from an ln N(2, 9) distribution", v)
/// ```
#[derive(Copy, Clone)] #[derive(Copy, Clone)]
pub struct LogNormal { pub struct LogNormal {
norm: Normal norm: Normal

View File

@ -32,23 +32,6 @@ use distributions::{Sample, IndependentSample};
/// including `high`, but this may be very difficult. All the /// including `high`, but this may be very difficult. All the
/// primitive integer types satisfy this property, and the float types /// primitive integer types satisfy this property, and the float types
/// normally satisfy it, but rounding may mean `high` can occur. /// normally satisfy it, but rounding may mean `high` can occur.
///
/// # Examples
///
/// ```
/// # #![feature(rand)]
/// use std::rand::distributions::{IndependentSample, Range};
///
/// fn main() {
/// let between = Range::new(10, 10000);
/// let mut rng = std::rand::thread_rng();
/// let mut sum = 0;
/// for _ in 0..1000 {
/// sum += between.ind_sample(&mut rng);
/// }
/// println!("{}", sum);
/// }
/// ```
pub struct Range<X> { pub struct Range<X> {
low: X, low: X,
range: X, range: X,

View File

@ -24,15 +24,13 @@
html_favicon_url = "http://www.rust-lang.org/favicon.ico", html_favicon_url = "http://www.rust-lang.org/favicon.ico",
html_root_url = "http://doc.rust-lang.org/nightly/", html_root_url = "http://doc.rust-lang.org/nightly/",
html_playground_url = "http://play.rust-lang.org/")] html_playground_url = "http://play.rust-lang.org/")]
#![feature(no_std)]
#![no_std] #![no_std]
#![unstable(feature = "rand")]
#![feature(staged_api)]
#![staged_api] #![staged_api]
#![unstable(feature = "rand")]
#![feature(core)] #![feature(core)]
#![feature(no_std)]
#![feature(staged_api)]
#![feature(step_by)] #![feature(step_by)]
#![deprecated(reason = "use the crates.io `rand` library instead",
since = "1.0.0-alpha")]
#![cfg_attr(test, feature(test, rand, rustc_private))] #![cfg_attr(test, feature(test, rand, rustc_private))]
@ -145,17 +143,6 @@ pub trait Rng : Sized {
/// with new data, and may panic if this is impossible /// with new data, and may panic if this is impossible
/// (e.g. reading past the end of a file that is being used as the /// (e.g. reading past the end of a file that is being used as the
/// source of randomness). /// source of randomness).
///
/// # Examples
///
/// ```
/// # #![feature(rand, core)]
/// use std::rand::{thread_rng, Rng};
///
/// let mut v = [0; 13579];
/// thread_rng().fill_bytes(&mut v);
/// println!("{:?}", &v[..]);
/// ```
fn fill_bytes(&mut self, dest: &mut [u8]) { fn fill_bytes(&mut self, dest: &mut [u8]) {
// this could, in theory, be done by transmuting dest to a // this could, in theory, be done by transmuting dest to a
// [u64], but this is (1) likely to be undefined behaviour for // [u64], but this is (1) likely to be undefined behaviour for
@ -181,18 +168,6 @@ pub trait Rng : Sized {
} }
/// Return a random value of a `Rand` type. /// Return a random value of a `Rand` type.
///
/// # Examples
///
/// ```
/// # #![feature(rand)]
/// use std::rand::{thread_rng, Rng};
///
/// let mut rng = thread_rng();
/// let x: usize = rng.gen();
/// println!("{}", x);
/// println!("{:?}", rng.gen::<(f64, bool)>());
/// ```
#[inline(always)] #[inline(always)]
fn gen<T: Rand>(&mut self) -> T { fn gen<T: Rand>(&mut self) -> T {
Rand::rand(self) Rand::rand(self)
@ -200,19 +175,6 @@ pub trait Rng : Sized {
/// Return an iterator that will yield an infinite number of randomly /// Return an iterator that will yield an infinite number of randomly
/// generated items. /// generated items.
///
/// # Examples
///
/// ```
/// # #![feature(rand)]
/// use std::rand::{thread_rng, Rng};
///
/// let mut rng = thread_rng();
/// let x = rng.gen_iter::<usize>().take(10).collect::<Vec<usize>>();
/// println!("{:?}", x);
/// println!("{:?}", rng.gen_iter::<(f64, bool)>().take(5)
/// .collect::<Vec<(f64, bool)>>());
/// ```
fn gen_iter<'a, T: Rand>(&'a mut self) -> Generator<'a, T, Self> { fn gen_iter<'a, T: Rand>(&'a mut self) -> Generator<'a, T, Self> {
Generator { rng: self, _marker: PhantomData } Generator { rng: self, _marker: PhantomData }
} }
@ -228,50 +190,17 @@ pub trait Rng : Sized {
/// # Panics /// # Panics
/// ///
/// Panics if `low >= high`. /// Panics if `low >= high`.
///
/// # Examples
///
/// ```
/// # #![feature(rand)]
/// use std::rand::{thread_rng, Rng};
///
/// let mut rng = thread_rng();
/// let n: usize = rng.gen_range(0, 10);
/// println!("{}", n);
/// let m: f64 = rng.gen_range(-40.0f64, 1.3e5f64);
/// println!("{}", m);
/// ```
fn gen_range<T: PartialOrd + SampleRange>(&mut self, low: T, high: T) -> T { fn gen_range<T: PartialOrd + SampleRange>(&mut self, low: T, high: T) -> T {
assert!(low < high, "Rng.gen_range called with low >= high"); assert!(low < high, "Rng.gen_range called with low >= high");
Range::new(low, high).ind_sample(self) Range::new(low, high).ind_sample(self)
} }
/// Return a bool with a 1 in n chance of true /// Return a bool with a 1 in n chance of true
///
/// # Examples
///
/// ```
/// # #![feature(rand)]
/// use std::rand::{thread_rng, Rng};
///
/// let mut rng = thread_rng();
/// println!("{}", rng.gen_weighted_bool(3));
/// ```
fn gen_weighted_bool(&mut self, n: usize) -> bool { fn gen_weighted_bool(&mut self, n: usize) -> bool {
n <= 1 || self.gen_range(0, n) == 0 n <= 1 || self.gen_range(0, n) == 0
} }
/// Return an iterator of random characters from the set A-Z,a-z,0-9. /// Return an iterator of random characters from the set A-Z,a-z,0-9.
///
/// # Examples
///
/// ```
/// # #![feature(rand)]
/// use std::rand::{thread_rng, Rng};
///
/// let s: String = thread_rng().gen_ascii_chars().take(10).collect();
/// println!("{}", s);
/// ```
fn gen_ascii_chars<'a>(&'a mut self) -> AsciiGenerator<'a, Self> { fn gen_ascii_chars<'a>(&'a mut self) -> AsciiGenerator<'a, Self> {
AsciiGenerator { rng: self } AsciiGenerator { rng: self }
} }
@ -279,18 +208,6 @@ pub trait Rng : Sized {
/// Return a random element from `values`. /// Return a random element from `values`.
/// ///
/// Return `None` if `values` is empty. /// Return `None` if `values` is empty.
///
/// # Examples
///
/// ```
/// # #![feature(rand)]
/// use std::rand::{thread_rng, Rng};
///
/// let choices = [1, 2, 4, 8, 16, 32];
/// let mut rng = thread_rng();
/// println!("{:?}", rng.choose(&choices));
/// assert_eq!(rng.choose(&choices[..0]), None);
/// ```
fn choose<'a, T>(&mut self, values: &'a [T]) -> Option<&'a T> { fn choose<'a, T>(&mut self, values: &'a [T]) -> Option<&'a T> {
if values.is_empty() { if values.is_empty() {
None None
@ -300,20 +217,6 @@ pub trait Rng : Sized {
} }
/// Shuffle a mutable slice in place. /// Shuffle a mutable slice in place.
///
/// # Examples
///
/// ```
/// # #![feature(rand, core)]
/// use std::rand::{thread_rng, Rng};
///
/// let mut rng = thread_rng();
/// let mut y = [1, 2, 3];
/// rng.shuffle(&mut y);
/// println!("{:?}", y);
/// rng.shuffle(&mut y);
/// println!("{:?}", y);
/// ```
fn shuffle<T>(&mut self, values: &mut [T]) { fn shuffle<T>(&mut self, values: &mut [T]) {
let mut i = values.len(); let mut i = values.len();
while i >= 2 { while i >= 2 {
@ -364,33 +267,9 @@ impl<'a, R: Rng> Iterator for AsciiGenerator<'a, R> {
/// the same stream of randomness multiple times. /// the same stream of randomness multiple times.
pub trait SeedableRng<Seed>: Rng { pub trait SeedableRng<Seed>: Rng {
/// Reseed an RNG with the given seed. /// Reseed an RNG with the given seed.
///
/// # Examples
///
/// ```
/// # #![feature(rand)]
/// use std::rand::{Rng, SeedableRng, StdRng};
///
/// let seed: &[_] = &[1, 2, 3, 4];
/// let mut rng: StdRng = SeedableRng::from_seed(seed);
/// println!("{}", rng.gen::<f64>());
/// rng.reseed(&[5, 6, 7, 8]);
/// println!("{}", rng.gen::<f64>());
/// ```
fn reseed(&mut self, Seed); fn reseed(&mut self, Seed);
/// Create a new RNG with the given seed. /// Create a new RNG with the given seed.
///
/// # Examples
///
/// ```
/// # #![feature(rand)]
/// use std::rand::{Rng, SeedableRng, StdRng};
///
/// let seed: &[_] = &[1, 2, 3, 4];
/// let mut rng: StdRng = SeedableRng::from_seed(seed);
/// println!("{}", rng.gen::<f64>());
/// ```
fn from_seed(seed: Seed) -> Self; fn from_seed(seed: Seed) -> Self;
} }
@ -486,16 +365,6 @@ impl Rand for XorShiftRng {
/// Use `Closed01` for the closed interval `[0,1]`, and the default /// Use `Closed01` for the closed interval `[0,1]`, and the default
/// `Rand` implementation for `f32` and `f64` for the half-open /// `Rand` implementation for `f32` and `f64` for the half-open
/// `[0,1)`. /// `[0,1)`.
///
/// # Examples
///
/// ```
/// # #![feature(rand)]
/// use std::rand::{random, Open01};
///
/// let Open01(val) = random::<Open01<f32>>();
/// println!("f32 from (0,1): {}", val);
/// ```
pub struct Open01<F>(pub F); pub struct Open01<F>(pub F);
/// A wrapper for generating floating point numbers uniformly in the /// A wrapper for generating floating point numbers uniformly in the
@ -504,31 +373,17 @@ pub struct Open01<F>(pub F);
/// Use `Open01` for the closed interval `(0,1)`, and the default /// Use `Open01` for the closed interval `(0,1)`, and the default
/// `Rand` implementation of `f32` and `f64` for the half-open /// `Rand` implementation of `f32` and `f64` for the half-open
/// `[0,1)`. /// `[0,1)`.
///
/// # Examples
///
/// ```
/// # #![feature(rand)]
/// use std::rand::{random, Closed01};
///
/// let Closed01(val) = random::<Closed01<f32>>();
/// println!("f32 from [0,1]: {}", val);
/// ```
pub struct Closed01<F>(pub F); pub struct Closed01<F>(pub F);
#[cfg(test)] #[cfg(test)]
mod test { mod test {
use std::rand; use std::__rand as rand;
pub struct MyRng<R> { inner: R } pub struct MyRng<R> { inner: R }
impl<R: rand::Rng> ::Rng for MyRng<R> { impl<R: rand::Rng> ::Rng for MyRng<R> {
fn next_u32(&mut self) -> u32 { fn next_u32(&mut self) -> u32 {
fn next<T: rand::Rng>(t: &mut T) -> u32 { rand::Rng::next_u32(&mut self.inner)
use std::rand::Rng;
t.next_u32()
}
next(&mut self.inner)
} }
} }
@ -536,7 +391,7 @@ mod test {
MyRng { inner: rand::thread_rng() } MyRng { inner: rand::thread_rng() }
} }
pub fn weak_rng() -> MyRng<rand::XorShiftRng> { pub fn weak_rng() -> MyRng<rand::ThreadRng> {
MyRng { inner: rand::weak_rng() } MyRng { inner: rand::thread_rng() }
} }
} }

View File

@ -211,55 +211,3 @@ impl<T:Rand> Rand for Option<T> {
} }
} }
} }
#[cfg(test)]
mod tests {
use std::rand::{Rng, thread_rng, Open01, Closed01};
struct ConstantRng(u64);
impl Rng for ConstantRng {
fn next_u32(&mut self) -> u32 {
let ConstantRng(v) = *self;
v as u32
}
fn next_u64(&mut self) -> u64 {
let ConstantRng(v) = *self;
v
}
}
#[test]
fn floating_point_edge_cases() {
// the test for exact equality is correct here.
assert!(ConstantRng(0xffff_ffff).gen::<f32>() != 1.0);
assert!(ConstantRng(0xffff_ffff_ffff_ffff).gen::<f64>() != 1.0);
}
#[test]
fn rand_open() {
// this is unlikely to catch an incorrect implementation that
// generates exactly 0 or 1, but it keeps it sane.
let mut rng = thread_rng();
for _ in 0..1_000 {
// strict inequalities
let Open01(f) = rng.gen::<Open01<f64>>();
assert!(0.0 < f && f < 1.0);
let Open01(f) = rng.gen::<Open01<f32>>();
assert!(0.0 < f && f < 1.0);
}
}
#[test]
fn rand_closed() {
let mut rng = thread_rng();
for _ in 0..1_000 {
// strict inequalities
let Closed01(f) = rng.gen::<Closed01<f64>>();
assert!(0.0 <= f && f <= 1.0);
let Closed01(f) = rng.gen::<Closed01<f32>>();
assert!(0.0 <= f && f <= 1.0);
}
}
}

View File

@ -99,34 +99,6 @@ impl<S, R: SeedableRng<S>, Rsdr: Reseeder<R> + Default>
} }
/// Something that can be used to reseed an RNG via `ReseedingRng`. /// Something that can be used to reseed an RNG via `ReseedingRng`.
///
/// # Examples
///
/// ```
/// # #![feature(rand)]
/// use std::rand::{Rng, SeedableRng, StdRng};
/// use std::rand::reseeding::{Reseeder, ReseedingRng};
///
/// struct TickTockReseeder { tick: bool }
/// impl Reseeder<StdRng> for TickTockReseeder {
/// fn reseed(&mut self, rng: &mut StdRng) {
/// let val = if self.tick {0} else {1};
/// rng.reseed(&[val]);
/// self.tick = !self.tick;
/// }
/// }
/// fn main() {
/// let rsdr = TickTockReseeder { tick: true };
///
/// let inner = StdRng::new().unwrap();
/// let mut rng = ReseedingRng::new(inner, 10, rsdr);
///
/// // this will repeat, because it gets reseeded very regularly.
/// let s: String = rng.gen_ascii_chars().take(100).collect();
/// println!("{}", s);
/// }
///
/// ```
pub trait Reseeder<R> { pub trait Reseeder<R> {
/// Reseed the given RNG. /// Reseed the given RNG.
fn reseed(&mut self, rng: &mut R); fn reseed(&mut self, rng: &mut R);

View File

@ -562,7 +562,7 @@ impl<'a, 'tcx, 'v> Visitor<'v> for DeadVisitor<'a, 'tcx> {
span: codemap::Span, id: ast::NodeId) { span: codemap::Span, id: ast::NodeId) {
// Have to warn method here because methods are not ast::Item // Have to warn method here because methods are not ast::Item
match fk { match fk {
visit::FkMethod(name, _) => { visit::FkMethod(name, _, _) => {
if !self.symbol_is_live(id, None) { if !self.symbol_is_live(id, None) {
self.warn_dead_code(id, span, name.name, "method"); self.warn_dead_code(id, span, name.name, "method");
} }

View File

@ -87,9 +87,9 @@ impl<'a, 'tcx, 'v> Visitor<'v> for EffectCheckVisitor<'a, 'tcx> {
block: &'v ast::Block, span: Span, _: ast::NodeId) { block: &'v ast::Block, span: Span, _: ast::NodeId) {
let (is_item_fn, is_unsafe_fn) = match fn_kind { let (is_item_fn, is_unsafe_fn) = match fn_kind {
visit::FkItemFn(_, _, fn_style, _) => visit::FkItemFn(_, _, fn_style, _, _) =>
(true, fn_style == ast::Unsafety::Unsafe), (true, fn_style == ast::Unsafety::Unsafe),
visit::FkMethod(_, sig) => visit::FkMethod(_, sig, _) =>
(true, sig.unsafety == ast::Unsafety::Unsafe), (true, sig.unsafety == ast::Unsafety::Unsafe),
_ => (false, false), _ => (false, false),
}; };

View File

@ -142,12 +142,12 @@ impl<'a, 'v> Visitor<'v> for LifetimeContext<'a> {
fn visit_fn(&mut self, fk: visit::FnKind<'v>, fd: &'v ast::FnDecl, fn visit_fn(&mut self, fk: visit::FnKind<'v>, fd: &'v ast::FnDecl,
b: &'v ast::Block, s: Span, _: ast::NodeId) { b: &'v ast::Block, s: Span, _: ast::NodeId) {
match fk { match fk {
visit::FkItemFn(_, generics, _, _) => { visit::FkItemFn(_, generics, _, _, _) => {
self.visit_early_late(subst::FnSpace, generics, |this| { self.visit_early_late(subst::FnSpace, generics, |this| {
visit::walk_fn(this, fk, fd, b, s) visit::walk_fn(this, fk, fd, b, s)
}) })
} }
visit::FkMethod(_, sig) => { visit::FkMethod(_, sig, _) => {
self.visit_early_late(subst::FnSpace, &sig.generics, |this| { self.visit_early_late(subst::FnSpace, &sig.generics, |this| {
visit::walk_fn(this, fk, fd, b, s) visit::walk_fn(this, fk, fd, b, s)
}) })

View File

@ -96,8 +96,8 @@ impl<'a> Annotator<'a> {
if tag == "unstable" || tag == "stable" || tag == "deprecated" { if tag == "unstable" || tag == "stable" || tag == "deprecated" {
attr::mark_used(attr); attr::mark_used(attr);
self.sess.span_warn(attr.span(), self.sess.span_warn(attr.span(),
"stability attributes are deprecated and \ "stability attributes are deprecated \
will soon become errors"); and will soon become errors");
} }
} }
f(self); f(self);

View File

@ -9,69 +9,42 @@
// except according to those terms. // except according to those terms.
use std::io; use std::io;
use std::env;
#[allow(deprecated)] use std::old_path::{self, GenericPath};
#[allow(deprecated)] use std::old_io;
use std::path::{Path, PathBuf}; use std::path::{Path, PathBuf};
/// Returns an absolute path in the filesystem that `path` points to. The #[cfg(windows)]
/// returned path does not contain any symlinks in its hierarchy.
#[allow(deprecated)] // readlink is deprecated
pub fn realpath(original: &Path) -> io::Result<PathBuf> { pub fn realpath(original: &Path) -> io::Result<PathBuf> {
let old = old_path::Path::new(original.to_str().unwrap()); Ok(original.to_path_buf())
match old_realpath(&old) {
Ok(p) => Ok(PathBuf::from(p.as_str().unwrap())),
Err(e) => Err(io::Error::new(io::ErrorKind::Other, e))
}
} }
#[allow(deprecated)] #[cfg(unix)]
fn old_realpath(original: &old_path::Path) -> old_io::IoResult<old_path::Path> { pub fn realpath(original: &Path) -> io::Result<PathBuf> {
use std::old_io::fs; use libc;
const MAX_LINKS_FOLLOWED: usize = 256; use std::ffi::{OsString, CString};
let original = old_path::Path::new(env::current_dir().unwrap() use std::os::unix::prelude::*;
.to_str().unwrap()).join(original);
// Right now lstat on windows doesn't work quite well extern {
if cfg!(windows) { fn realpath(pathname: *const libc::c_char, resolved: *mut libc::c_char)
return Ok(original) -> *mut libc::c_char;
} }
let result = original.root_path(); let path = try!(CString::new(original.as_os_str().as_bytes()));
let mut result = result.expect("make_absolute has no root_path"); let mut buf = vec![0u8; 16 * 1024];
let mut followed = 0; unsafe {
let r = realpath(path.as_ptr(), buf.as_mut_ptr() as *mut _);
for part in original.components() { if r.is_null() {
result.push(part); return Err(io::Error::last_os_error())
loop {
if followed == MAX_LINKS_FOLLOWED {
return Err(old_io::standard_error(old_io::InvalidInput))
}
match fs::lstat(&result) {
Err(..) => break,
Ok(ref stat) if stat.kind != old_io::FileType::Symlink => break,
Ok(..) => {
followed += 1;
let path = try!(fs::readlink(&result));
result.pop();
result.push(path);
}
}
} }
} }
let p = buf.iter().position(|i| *i == 0).unwrap();
return Ok(result); buf.truncate(p);
Ok(PathBuf::from(OsString::from_vec(buf)))
} }
#[cfg(all(not(windows), test))] #[cfg(all(not(windows), test))]
mod test { mod test {
use std::old_io; use tempdir::TempDir;
use std::old_io::fs::{File, symlink, mkdir, mkdir_recursive}; use std::fs::{self, File};
use super::old_realpath as realpath; use super::realpath;
use std::old_io::TempDir;
use std::old_path::{Path, GenericPath};
#[test] #[test]
fn realpath_works() { fn realpath_works() {
@ -83,15 +56,15 @@ mod test {
let linkdir = tmpdir.join("test3"); let linkdir = tmpdir.join("test3");
File::create(&file).unwrap(); File::create(&file).unwrap();
mkdir(&dir, old_io::USER_RWX).unwrap(); fs::create_dir(&dir).unwrap();
symlink(&file, &link).unwrap(); fs::soft_link(&file, &link).unwrap();
symlink(&dir, &linkdir).unwrap(); fs::soft_link(&dir, &linkdir).unwrap();
assert!(realpath(&tmpdir).unwrap() == tmpdir); assert_eq!(realpath(&tmpdir).unwrap(), tmpdir);
assert!(realpath(&file).unwrap() == file); assert_eq!(realpath(&file).unwrap(), file);
assert!(realpath(&link).unwrap() == file); assert_eq!(realpath(&link).unwrap(), file);
assert!(realpath(&linkdir).unwrap() == dir); assert_eq!(realpath(&linkdir).unwrap(), dir);
assert!(realpath(&linkdir.join("link")).unwrap() == file); assert_eq!(realpath(&linkdir.join("link")).unwrap(), file);
} }
#[test] #[test]
@ -106,13 +79,13 @@ mod test {
let e = d.join("e"); let e = d.join("e");
let f = a.join("f"); let f = a.join("f");
mkdir_recursive(&b, old_io::USER_RWX).unwrap(); fs::create_dir_all(&b).unwrap();
mkdir_recursive(&d, old_io::USER_RWX).unwrap(); fs::create_dir_all(&d).unwrap();
File::create(&f).unwrap(); File::create(&f).unwrap();
symlink(&Path::new("../d/e"), &c).unwrap(); fs::soft_link("../d/e", &c).unwrap();
symlink(&Path::new("../f"), &e).unwrap(); fs::soft_link("../f", &e).unwrap();
assert!(realpath(&c).unwrap() == f); assert_eq!(realpath(&c).unwrap(), f);
assert!(realpath(&e).unwrap() == f); assert_eq!(realpath(&e).unwrap(), f);
} }
} }

View File

@ -35,17 +35,16 @@
#![feature(box_syntax)] #![feature(box_syntax)]
#![feature(collections)] #![feature(collections)]
#![feature(core)] #![feature(core)]
#![feature(old_fs)]
#![feature(old_io)]
#![feature(old_path)]
#![feature(rustc_private)] #![feature(rustc_private)]
#![feature(staged_api)] #![feature(staged_api)]
#![feature(rand)] #![feature(rand)]
#![feature(path_ext)] #![feature(path_ext)]
#![feature(step_by)] #![feature(step_by)]
#![feature(libc)]
#![cfg_attr(test, feature(test, rand))] #![cfg_attr(test, feature(test, rand))]
extern crate syntax; extern crate syntax;
extern crate libc;
extern crate serialize; extern crate serialize;
#[macro_use] extern crate log; #[macro_use] extern crate log;

View File

@ -97,8 +97,9 @@ fn get_rpath_relative_to_output(config: &mut RPathConfig, lib: &Path) -> String
let cwd = env::current_dir().unwrap(); let cwd = env::current_dir().unwrap();
let mut lib = (config.realpath)(&cwd.join(lib)).unwrap(); let mut lib = (config.realpath)(&cwd.join(lib)).unwrap();
lib.pop(); lib.pop();
let mut output = (config.realpath)(&cwd.join(&config.out_filename)).unwrap(); let mut output = cwd.join(&config.out_filename);
output.pop(); output.pop();
let output = (config.realpath)(&output).unwrap();
let relative = path_relative_from(&lib, &output) let relative = path_relative_from(&lib, &output)
.expect(&format!("couldn't create relative path from {:?} to {:?}", output, lib)); .expect(&format!("couldn't create relative path from {:?} to {:?}", output, lib));
// FIXME (#9639): This needs to handle non-utf8 paths // FIXME (#9639): This needs to handle non-utf8 paths

View File

@ -12,7 +12,7 @@ use std::env;
use std::io::{self, Error, ErrorKind}; use std::io::{self, Error, ErrorKind};
use std::fs; use std::fs;
use std::path::{self, PathBuf, Path}; use std::path::{self, PathBuf, Path};
use std::rand::{thread_rng, Rng}; use std::__rand::{thread_rng, Rng};
/// A wrapper for a path to temporary directory implementing automatic /// A wrapper for a path to temporary directory implementing automatic
/// scope-based deletion. /// scope-based deletion.

View File

@ -957,7 +957,7 @@ impl LintPass for NonSnakeCase {
fk: visit::FnKind, _: &ast::FnDecl, fk: visit::FnKind, _: &ast::FnDecl,
_: &ast::Block, span: Span, id: ast::NodeId) { _: &ast::Block, span: Span, id: ast::NodeId) {
match fk { match fk {
visit::FkMethod(ident, _) => match method_context(cx, id, span) { visit::FkMethod(ident, _, _) => match method_context(cx, id, span) {
MethodContext::PlainImpl => { MethodContext::PlainImpl => {
self.check_snake_case(cx, "method", ident, span) self.check_snake_case(cx, "method", ident, span)
}, },
@ -966,7 +966,7 @@ impl LintPass for NonSnakeCase {
}, },
_ => (), _ => (),
}, },
visit::FkItemFn(ident, _, _, _) => { visit::FkItemFn(ident, _, _, _, _) => {
self.check_snake_case(cx, "function", ident, span) self.check_snake_case(cx, "function", ident, span)
}, },
_ => (), _ => (),
@ -1290,10 +1290,10 @@ impl LintPass for UnsafeCode {
fn check_fn(&mut self, cx: &Context, fk: visit::FnKind, _: &ast::FnDecl, fn check_fn(&mut self, cx: &Context, fk: visit::FnKind, _: &ast::FnDecl,
_: &ast::Block, span: Span, _: ast::NodeId) { _: &ast::Block, span: Span, _: ast::NodeId) {
match fk { match fk {
visit::FkItemFn(_, _, ast::Unsafety::Unsafe, _) => visit::FkItemFn(_, _, ast::Unsafety::Unsafe, _, _) =>
cx.span_lint(UNSAFE_CODE, span, "declaration of an `unsafe` function"), cx.span_lint(UNSAFE_CODE, span, "declaration of an `unsafe` function"),
visit::FkMethod(_, sig) => { visit::FkMethod(_, sig, _) => {
if sig.unsafety == ast::Unsafety::Unsafe { if sig.unsafety == ast::Unsafety::Unsafe {
cx.span_lint(UNSAFE_CODE, span, "implementation of an `unsafe` method") cx.span_lint(UNSAFE_CODE, span, "implementation of an `unsafe` method")
} }
@ -1818,8 +1818,8 @@ impl LintPass for UnconditionalRecursion {
ast::NodeId, ast::NodeId, ast::Ident, ast::NodeId) -> bool; ast::NodeId, ast::NodeId, ast::Ident, ast::NodeId) -> bool;
let (name, checker) = match fn_kind { let (name, checker) = match fn_kind {
visit::FkItemFn(name, _, _, _) => (name, id_refers_to_this_fn as F), visit::FkItemFn(name, _, _, _, _) => (name, id_refers_to_this_fn as F),
visit::FkMethod(name, _) => (name, id_refers_to_this_method as F), visit::FkMethod(name, _, _) => (name, id_refers_to_this_method as F),
// closures can't recur, so they don't matter. // closures can't recur, so they don't matter.
visit::FkFnBlock => return visit::FkFnBlock => return
}; };

View File

@ -242,11 +242,11 @@ impl<'a, 'v, 'tcx> Visitor<'v> for Resolver<'a, 'tcx> {
_: Span, _: Span,
node_id: NodeId) { node_id: NodeId) {
let rib_kind = match function_kind { let rib_kind = match function_kind {
visit::FkItemFn(_, generics, _, _) => { visit::FkItemFn(_, generics, _, _, _) => {
self.visit_generics(generics); self.visit_generics(generics);
ItemRibKind ItemRibKind
} }
visit::FkMethod(_, sig) => { visit::FkMethod(_, sig, _) => {
self.visit_generics(&sig.generics); self.visit_generics(&sig.generics);
self.visit_explicit_self(&sig.explicit_self); self.visit_explicit_self(&sig.explicit_self);
MethodRibKind MethodRibKind

View File

@ -131,7 +131,9 @@ pub fn trans_block<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
match b.expr { match b.expr {
Some(ref e) => { Some(ref e) => {
bcx = expr::trans_into(bcx, &**e, dest); if !bcx.unreachable.get() {
bcx = expr::trans_into(bcx, &**e, dest);
}
} }
None => { None => {
assert!(dest == expr::Ignore || bcx.unreachable.get()); assert!(dest == expr::Ignore || bcx.unreachable.get());

View File

@ -2616,8 +2616,8 @@ fn check_expr_with_unifier<'a, 'tcx, F>(fcx: &FnCtxt<'a, 'tcx>,
actual) actual)
}, },
expr_t, None); expr_t, None);
if let Some(t) = ty::ty_to_def_id(expr_t) { if let ty::ty_struct(did, _) = expr_t.sty {
suggest_field_names(t, field, tcx, vec![]); suggest_field_names(did, field, tcx, vec![]);
} }
} }

View File

@ -78,9 +78,11 @@
return; return;
} }
if (e.which === 191 && $('#help').hasClass('hidden')) { // question mark if (e.which === 191) { // question mark
e.preventDefault(); if (e.shiftKey && $('#help').hasClass('hidden')) {
$('#help').removeClass('hidden'); e.preventDefault();
$('#help').removeClass('hidden');
}
} else if (e.which === 27) { // esc } else if (e.which === 27) { // esc
if (!$('#help').hasClass('hidden')) { if (!$('#help').hasClass('hidden')) {
e.preventDefault(); e.preventDefault();

View File

@ -130,10 +130,10 @@ struct Output {
pub fn main() { pub fn main() {
const STACK_SIZE: usize = 32000000; // 32MB const STACK_SIZE: usize = 32000000; // 32MB
let res = std::thread::Builder::new().stack_size(STACK_SIZE).scoped(move || { let res = std::thread::Builder::new().stack_size(STACK_SIZE).spawn(move || {
let s = env::args().collect::<Vec<_>>(); let s = env::args().collect::<Vec<_>>();
main_args(&s) main_args(&s)
}).unwrap().join(); }).unwrap().join().unwrap();
env::set_exit_status(res as i32); env::set_exit_status(res as i32);
} }

View File

@ -2627,9 +2627,9 @@ mod tests {
use super::{Json, from_str, DecodeResult, DecoderError, JsonEvent, Parser, use super::{Json, from_str, DecodeResult, DecoderError, JsonEvent, Parser,
StackElement, Stack, Decoder, Encoder, EncoderError}; StackElement, Stack, Decoder, Encoder, EncoderError};
use std::{i64, u64, f32, f64}; use std::{i64, u64, f32, f64};
use std::io::prelude::*;
use std::collections::BTreeMap; use std::collections::BTreeMap;
use std::string; use std::string;
use std::old_io::Writer;
#[derive(RustcDecodable, Eq, PartialEq, Debug)] #[derive(RustcDecodable, Eq, PartialEq, Debug)]
struct OptionData { struct OptionData {
@ -3464,7 +3464,6 @@ mod tests {
#[test] #[test]
fn test_encode_hashmap_with_numeric_key() { fn test_encode_hashmap_with_numeric_key() {
use std::str::from_utf8; use std::str::from_utf8;
use std::old_io::Writer;
use std::collections::HashMap; use std::collections::HashMap;
let mut hm: HashMap<usize, bool> = HashMap::new(); let mut hm: HashMap<usize, bool> = HashMap::new();
hm.insert(1, true); hm.insert(1, true);
@ -3480,7 +3479,6 @@ mod tests {
#[test] #[test]
fn test_prettyencode_hashmap_with_numeric_key() { fn test_prettyencode_hashmap_with_numeric_key() {
use std::str::from_utf8; use std::str::from_utf8;
use std::old_io::Writer;
use std::collections::HashMap; use std::collections::HashMap;
let mut hm: HashMap<usize, bool> = HashMap::new(); let mut hm: HashMap<usize, bool> = HashMap::new();
hm.insert(1, true); hm.insert(1, true);

View File

@ -30,13 +30,12 @@ Core encoding and decoding interfaces.
#![feature(box_syntax)] #![feature(box_syntax)]
#![feature(collections)] #![feature(collections)]
#![feature(core)] #![feature(core)]
#![feature(old_path)]
#![feature(rustc_private)] #![feature(rustc_private)]
#![feature(staged_api)] #![feature(staged_api)]
#![feature(std_misc)] #![feature(std_misc)]
#![feature(unicode)] #![feature(unicode)]
#![feature(str_char)] #![feature(str_char)]
#![cfg_attr(test, feature(test, old_io))] #![cfg_attr(test, feature(test))]
// test harness access // test harness access
#[cfg(test)] extern crate test; #[cfg(test)] extern crate test;

View File

@ -14,8 +14,6 @@
Core encoding and decoding interfaces. Core encoding and decoding interfaces.
*/ */
#[allow(deprecated)]
use std::old_path::{self, GenericPath};
use std::path; use std::path;
use std::rc::Rc; use std::rc::Rc;
use std::cell::{Cell, RefCell}; use std::cell::{Cell, RefCell};
@ -540,36 +538,6 @@ macro_rules! tuple {
tuple! { T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, } tuple! { T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, }
#[allow(deprecated)]
impl Encodable for old_path::posix::Path {
fn encode<S: Encoder>(&self, e: &mut S) -> Result<(), S::Error> {
self.as_vec().encode(e)
}
}
#[allow(deprecated)]
impl Decodable for old_path::posix::Path {
fn decode<D: Decoder>(d: &mut D) -> Result<old_path::posix::Path, D::Error> {
let bytes: Vec<u8> = try!(Decodable::decode(d));
Ok(old_path::posix::Path::new(bytes))
}
}
#[allow(deprecated)]
impl Encodable for old_path::windows::Path {
fn encode<S: Encoder>(&self, e: &mut S) -> Result<(), S::Error> {
self.as_vec().encode(e)
}
}
#[allow(deprecated)]
impl Decodable for old_path::windows::Path {
fn decode<D: Decoder>(d: &mut D) -> Result<old_path::windows::Path, D::Error> {
let bytes: Vec<u8> = try!(Decodable::decode(d));
Ok(old_path::windows::Path::new(bytes))
}
}
impl Encodable for path::PathBuf { impl Encodable for path::PathBuf {
fn encode<S: Encoder>(&self, e: &mut S) -> Result<(), S::Error> { fn encode<S: Encoder>(&self, e: &mut S) -> Result<(), S::Error> {
self.to_str().unwrap().encode(e) self.to_str().unwrap().encode(e)

View File

@ -23,12 +23,12 @@ use mem;
#[unstable(feature = "std_misc", #[unstable(feature = "std_misc",
reason = "would prefer to do this in a more general way")] reason = "would prefer to do this in a more general way")]
pub trait OwnedAsciiExt { pub trait OwnedAsciiExt {
/// Convert the string to ASCII upper case: /// Converts the string to ASCII upper case:
/// ASCII letters 'a' to 'z' are mapped to 'A' to 'Z', /// ASCII letters 'a' to 'z' are mapped to 'A' to 'Z',
/// but non-ASCII letters are unchanged. /// but non-ASCII letters are unchanged.
fn into_ascii_uppercase(self) -> Self; fn into_ascii_uppercase(self) -> Self;
/// Convert the string to ASCII lower case: /// Converts the string to ASCII lower case:
/// ASCII letters 'A' to 'Z' are mapped to 'a' to 'z', /// ASCII letters 'A' to 'Z' are mapped to 'a' to 'z',
/// but non-ASCII letters are unchanged. /// but non-ASCII letters are unchanged.
fn into_ascii_lowercase(self) -> Self; fn into_ascii_lowercase(self) -> Self;
@ -41,7 +41,7 @@ pub trait AsciiExt {
#[stable(feature = "rust1", since = "1.0.0")] #[stable(feature = "rust1", since = "1.0.0")]
type Owned; type Owned;
/// Check if within the ASCII range. /// Checks if within the ASCII range.
/// ///
/// # Examples /// # Examples
/// ///
@ -95,7 +95,7 @@ pub trait AsciiExt {
#[stable(feature = "rust1", since = "1.0.0")] #[stable(feature = "rust1", since = "1.0.0")]
fn to_ascii_lowercase(&self) -> Self::Owned; fn to_ascii_lowercase(&self) -> Self::Owned;
/// Check that two strings are an ASCII case-insensitive match. /// Checks that two strings are an ASCII case-insensitive match.
/// ///
/// Same as `to_ascii_lowercase(a) == to_ascii_lowercase(b)`, /// Same as `to_ascii_lowercase(a) == to_ascii_lowercase(b)`,
/// but without allocating and copying temporary strings. /// but without allocating and copying temporary strings.
@ -117,7 +117,7 @@ pub trait AsciiExt {
#[stable(feature = "rust1", since = "1.0.0")] #[stable(feature = "rust1", since = "1.0.0")]
fn eq_ignore_ascii_case(&self, other: &Self) -> bool; fn eq_ignore_ascii_case(&self, other: &Self) -> bool;
/// Convert this type to its ASCII upper case equivalent in-place. /// Converts this type to its ASCII upper case equivalent in-place.
/// ///
/// See `to_ascii_uppercase` for more information. /// See `to_ascii_uppercase` for more information.
/// ///
@ -136,7 +136,7 @@ pub trait AsciiExt {
#[unstable(feature = "ascii")] #[unstable(feature = "ascii")]
fn make_ascii_uppercase(&mut self); fn make_ascii_uppercase(&mut self);
/// Convert this type to its ASCII lower case equivalent in-place. /// Converts this type to its ASCII lower case equivalent in-place.
/// ///
/// See `to_ascii_lowercase` for more information. /// See `to_ascii_lowercase` for more information.
/// ///

View File

@ -506,7 +506,7 @@ impl<K, V, S> HashMap<K, V, S>
} }
impl<K: Hash + Eq, V> HashMap<K, V, RandomState> { impl<K: Hash + Eq, V> HashMap<K, V, RandomState> {
/// Create an empty HashMap. /// Creates an empty HashMap.
/// ///
/// # Examples /// # Examples
/// ///
@ -563,7 +563,7 @@ impl<K, V, S> HashMap<K, V, S>
} }
} }
/// Create an empty HashMap with space for at least `capacity` /// Creates an empty HashMap with space for at least `capacity`
/// elements, using `hasher` to hash the keys. /// elements, using `hasher` to hash the keys.
/// ///
/// Warning: `hasher` is normally randomly generated, and /// Warning: `hasher` is normally randomly generated, and
@ -1596,7 +1596,7 @@ pub struct RandomState {
#[unstable(feature = "std_misc", #[unstable(feature = "std_misc",
reason = "hashing an hash maps may be altered")] reason = "hashing an hash maps may be altered")]
impl RandomState { impl RandomState {
/// Construct a new `RandomState` that is initialized with random keys. /// Constructs a new `RandomState` that is initialized with random keys.
#[inline] #[inline]
#[allow(deprecated)] #[allow(deprecated)]
pub fn new() -> RandomState { pub fn new() -> RandomState {
@ -1631,7 +1631,7 @@ mod test_map {
use super::Entry::{Occupied, Vacant}; use super::Entry::{Occupied, Vacant};
use iter::{range_inclusive, range_step_inclusive, repeat}; use iter::{range_inclusive, range_step_inclusive, repeat};
use cell::RefCell; use cell::RefCell;
use rand::{weak_rng, Rng}; use rand::{thread_rng, Rng};
#[test] #[test]
fn test_create_capacity_zero() { fn test_create_capacity_zero() {
@ -2290,7 +2290,7 @@ mod test_map {
} }
let mut m = HashMap::new(); let mut m = HashMap::new();
let mut rng = weak_rng(); let mut rng = thread_rng();
// Populate the map with some items. // Populate the map with some items.
for _ in 0..50 { for _ in 0..50 {

View File

@ -111,7 +111,7 @@ pub struct HashSet<T, S = RandomState> {
} }
impl<T: Hash + Eq> HashSet<T, RandomState> { impl<T: Hash + Eq> HashSet<T, RandomState> {
/// Create an empty HashSet. /// Creates an empty HashSet.
/// ///
/// # Examples /// # Examples
/// ///
@ -125,7 +125,7 @@ impl<T: Hash + Eq> HashSet<T, RandomState> {
HashSet::with_capacity(INITIAL_CAPACITY) HashSet::with_capacity(INITIAL_CAPACITY)
} }
/// Create an empty HashSet with space for at least `n` elements in /// Creates an empty HashSet with space for at least `n` elements in
/// the hash table. /// the hash table.
/// ///
/// # Examples /// # Examples
@ -166,7 +166,7 @@ impl<T, S> HashSet<T, S>
HashSet::with_capacity_and_hash_state(INITIAL_CAPACITY, hash_state) HashSet::with_capacity_and_hash_state(INITIAL_CAPACITY, hash_state)
} }
/// Create an empty HashSet with space for at least `capacity` /// Creates an empty HashSet with space for at least `capacity`
/// elements in the hash table, using `hasher` to hash the keys. /// elements in the hash table, using `hasher` to hash the keys.
/// ///
/// Warning: `hasher` is normally randomly generated, and /// Warning: `hasher` is normally randomly generated, and
@ -402,7 +402,7 @@ impl<T, S> HashSet<T, S>
Union { iter: self.iter().chain(other.difference(self)) } Union { iter: self.iter().chain(other.difference(self)) }
} }
/// Return the number of elements in the set /// Returns the number of elements in the set.
/// ///
/// # Examples /// # Examples
/// ///
@ -417,7 +417,7 @@ impl<T, S> HashSet<T, S>
#[stable(feature = "rust1", since = "1.0.0")] #[stable(feature = "rust1", since = "1.0.0")]
pub fn len(&self) -> usize { self.map.len() } pub fn len(&self) -> usize { self.map.len() }
/// Returns true if the set contains no elements /// Returns true if the set contains no elements.
/// ///
/// # Examples /// # Examples
/// ///

View File

@ -105,7 +105,7 @@ impl DynamicLibrary {
} }
} }
/// Access the value at the symbol of the dynamic library /// Accesses the value at the symbol of the dynamic library.
pub unsafe fn symbol<T>(&self, symbol: &str) -> Result<*mut T, String> { pub unsafe fn symbol<T>(&self, symbol: &str) -> Result<*mut T, String> {
// This function should have a lifetime constraint of 'a on // This function should have a lifetime constraint of 'a on
// T but that feature is still unimplemented // T but that feature is still unimplemented

View File

@ -261,7 +261,7 @@ pub fn set_var<K: ?Sized, V: ?Sized>(k: &K, v: &V)
os_imp::setenv(k.as_ref(), v.as_ref()) os_imp::setenv(k.as_ref(), v.as_ref())
} }
/// Remove an environment variable from the environment of the currently running process. /// Removes an environment variable from the environment of the currently running process.
/// ///
/// # Examples /// # Examples
/// ///

View File

@ -122,10 +122,7 @@ impl Error for str::ParseBoolError {
#[stable(feature = "rust1", since = "1.0.0")] #[stable(feature = "rust1", since = "1.0.0")]
impl Error for str::Utf8Error { impl Error for str::Utf8Error {
fn description(&self) -> &str { fn description(&self) -> &str {
match *self { "invalid utf-8: corrupt contents"
str::Utf8Error::TooShort => "invalid utf-8: not enough bytes",
str::Utf8Error::InvalidByte(..) => "invalid utf-8: corrupt contents",
}
} }
} }

View File

@ -18,8 +18,6 @@ use io;
use iter::Iterator; use iter::Iterator;
use libc; use libc;
use mem; use mem;
#[allow(deprecated)]
use old_io;
use ops::Deref; use ops::Deref;
use option::Option::{self, Some, None}; use option::Option::{self, Some, None};
use result::Result::{self, Ok, Err}; use result::Result::{self, Ok, Err};
@ -133,7 +131,7 @@ pub struct CStr {
pub struct NulError(usize, Vec<u8>); pub struct NulError(usize, Vec<u8>);
impl CString { impl CString {
/// Create a new C-compatible string from a container of bytes. /// Creates a new C-compatible string from a container of bytes.
/// ///
/// This method will consume the provided data and use the underlying bytes /// This method will consume the provided data and use the underlying bytes
/// to construct a new string, ensuring that there is a trailing 0 byte. /// to construct a new string, ensuring that there is a trailing 0 byte.
@ -169,11 +167,12 @@ impl CString {
} }
} }
/// Create a C-compatible string from a byte vector without checking for /// Creates a C-compatible string from a byte vector without checking for
/// interior 0 bytes. /// interior 0 bytes.
/// ///
/// This method is equivalent to `from_vec` except that no runtime assertion /// This method is equivalent to `new` except that no runtime assertion
/// is made that `v` contains no 0 bytes. /// is made that `v` contains no 0 bytes, and it requires an actual
/// byte vector, not anyhting that can be converted to one with Into.
#[stable(feature = "rust1", since = "1.0.0")] #[stable(feature = "rust1", since = "1.0.0")]
pub unsafe fn from_vec_unchecked(mut v: Vec<u8>) -> CString { pub unsafe fn from_vec_unchecked(mut v: Vec<u8>) -> CString {
v.push(0); v.push(0);
@ -215,7 +214,7 @@ impl fmt::Debug for CString {
impl NulError { impl NulError {
/// Returns the position of the nul byte in the slice that was provided to /// Returns the position of the nul byte in the slice that was provided to
/// `CString::from_vec`. /// `CString::new`.
#[stable(feature = "rust1", since = "1.0.0")] #[stable(feature = "rust1", since = "1.0.0")]
pub fn nul_position(&self) -> usize { self.0 } pub fn nul_position(&self) -> usize { self.0 }
@ -245,20 +244,8 @@ impl From<NulError> for io::Error {
} }
} }
#[stable(feature = "rust1", since = "1.0.0")]
#[allow(deprecated)]
impl From<NulError> for old_io::IoError {
fn from(_: NulError) -> old_io::IoError {
old_io::IoError {
kind: old_io::IoErrorKind::InvalidInput,
desc: "data provided contains a nul byte",
detail: None
}
}
}
impl CStr { impl CStr {
/// Cast a raw C string to a safe C string wrapper. /// Casts a raw C string to a safe C string wrapper.
/// ///
/// This function will cast the provided `ptr` to the `CStr` wrapper which /// This function will cast the provided `ptr` to the `CStr` wrapper which
/// allows inspection and interoperation of non-owned C strings. This method /// allows inspection and interoperation of non-owned C strings. This method
@ -301,7 +288,7 @@ impl CStr {
mem::transmute(slice::from_raw_parts(ptr, len as usize + 1)) mem::transmute(slice::from_raw_parts(ptr, len as usize + 1))
} }
/// Return the inner pointer to this C string. /// Returns the inner pointer to this C string.
/// ///
/// The returned pointer will be valid for as long as `self` is and points /// The returned pointer will be valid for as long as `self` is and points
/// to a contiguous region of memory terminated with a 0 byte to represent /// to a contiguous region of memory terminated with a 0 byte to represent
@ -311,7 +298,7 @@ impl CStr {
self.inner.as_ptr() self.inner.as_ptr()
} }
/// Convert this C string to a byte slice. /// Converts this C string to a byte slice.
/// ///
/// This function will calculate the length of this string (which normally /// This function will calculate the length of this string (which normally
/// requires a linear amount of work to be done) and then return the /// requires a linear amount of work to be done) and then return the
@ -329,7 +316,7 @@ impl CStr {
&bytes[..bytes.len() - 1] &bytes[..bytes.len() - 1]
} }
/// Convert this C string to a byte slice containing the trailing 0 byte. /// Converts this C string to a byte slice containing the trailing 0 byte.
/// ///
/// This function is the equivalent of `to_bytes` except that it will retain /// This function is the equivalent of `to_bytes` except that it will retain
/// the trailing nul instead of chopping it off. /// the trailing nul instead of chopping it off.

View File

@ -25,6 +25,6 @@ mod os_str;
/// Freely convertible to an `&OsStr` slice. /// Freely convertible to an `&OsStr` slice.
#[unstable(feature = "std_misc")] #[unstable(feature = "std_misc")]
pub trait AsOsStr { pub trait AsOsStr {
/// Convert to an `&OsStr` slice. /// Converts to an `&OsStr` slice.
fn as_os_str(&self) -> &OsStr; fn as_os_str(&self) -> &OsStr;
} }

View File

@ -42,7 +42,6 @@ use string::String;
use ops; use ops;
use cmp; use cmp;
use hash::{Hash, Hasher}; use hash::{Hash, Hasher};
use old_path::{Path, GenericPath};
use vec::Vec; use vec::Vec;
use sys::os_str::{Buf, Slice}; use sys::os_str::{Buf, Slice};
@ -69,7 +68,7 @@ impl OsString {
OsString { inner: Buf::from_string(String::new()) } OsString { inner: Buf::from_string(String::new()) }
} }
/// Construct an `OsString` from a byte sequence. /// Constructs an `OsString` from a byte sequence.
/// ///
/// # Platform behavior /// # Platform behavior
/// ///
@ -94,13 +93,13 @@ impl OsString {
from_bytes_inner(bytes.into()) from_bytes_inner(bytes.into())
} }
/// Convert to an `OsStr` slice. /// Converts to an `OsStr` slice.
#[stable(feature = "rust1", since = "1.0.0")] #[stable(feature = "rust1", since = "1.0.0")]
pub fn as_os_str(&self) -> &OsStr { pub fn as_os_str(&self) -> &OsStr {
self self
} }
/// Convert the `OsString` into a `String` if it contains valid Unicode data. /// Converts the `OsString` into a `String` if it contains valid Unicode data.
/// ///
/// On failure, ownership of the original `OsString` is returned. /// On failure, ownership of the original `OsString` is returned.
#[stable(feature = "rust1", since = "1.0.0")] #[stable(feature = "rust1", since = "1.0.0")]
@ -108,7 +107,7 @@ impl OsString {
self.inner.into_string().map_err(|buf| OsString { inner: buf} ) self.inner.into_string().map_err(|buf| OsString { inner: buf} )
} }
/// Extend the string with the given `&OsStr` slice. /// Extends the string with the given `&OsStr` slice.
#[stable(feature = "rust1", since = "1.0.0")] #[stable(feature = "rust1", since = "1.0.0")]
pub fn push<T: AsRef<OsStr>>(&mut self, s: T) { pub fn push<T: AsRef<OsStr>>(&mut self, s: T) {
self.inner.push_slice(&s.as_ref().inner) self.inner.push_slice(&s.as_ref().inner)
@ -221,13 +220,13 @@ impl Hash for OsString {
} }
impl OsStr { impl OsStr {
/// Coerce into an `OsStr` slice. /// Coerces into an `OsStr` slice.
#[stable(feature = "rust1", since = "1.0.0")] #[stable(feature = "rust1", since = "1.0.0")]
pub fn new<S: AsRef<OsStr> + ?Sized>(s: &S) -> &OsStr { pub fn new<S: AsRef<OsStr> + ?Sized>(s: &S) -> &OsStr {
s.as_ref() s.as_ref()
} }
/// Coerce directly from a `&str` slice to a `&OsStr` slice. /// Coerces directly from a `&str` slice to a `&OsStr` slice.
#[stable(feature = "rust1", since = "1.0.0")] #[stable(feature = "rust1", since = "1.0.0")]
#[deprecated(since = "1.0.0", #[deprecated(since = "1.0.0",
reason = "use `OsStr::new` instead")] reason = "use `OsStr::new` instead")]
@ -235,7 +234,7 @@ impl OsStr {
unsafe { mem::transmute(Slice::from_str(s)) } unsafe { mem::transmute(Slice::from_str(s)) }
} }
/// Yield a `&str` slice if the `OsStr` is valid unicode. /// Yields a `&str` slice if the `OsStr` is valid unicode.
/// ///
/// This conversion may entail doing a check for UTF-8 validity. /// This conversion may entail doing a check for UTF-8 validity.
#[stable(feature = "rust1", since = "1.0.0")] #[stable(feature = "rust1", since = "1.0.0")]
@ -243,7 +242,7 @@ impl OsStr {
self.inner.to_str() self.inner.to_str()
} }
/// Convert an `OsStr` to a `Cow<str>`. /// Converts an `OsStr` to a `Cow<str>`.
/// ///
/// Any non-Unicode sequences are replaced with U+FFFD REPLACEMENT CHARACTER. /// Any non-Unicode sequences are replaced with U+FFFD REPLACEMENT CHARACTER.
#[stable(feature = "rust1", since = "1.0.0")] #[stable(feature = "rust1", since = "1.0.0")]
@ -251,13 +250,13 @@ impl OsStr {
self.inner.to_string_lossy() self.inner.to_string_lossy()
} }
/// Copy the slice into an owned `OsString`. /// Copies the slice into an owned `OsString`.
#[stable(feature = "rust1", since = "1.0.0")] #[stable(feature = "rust1", since = "1.0.0")]
pub fn to_os_string(&self) -> OsString { pub fn to_os_string(&self) -> OsString {
OsString { inner: self.inner.to_owned() } OsString { inner: self.inner.to_owned() }
} }
/// Yield this `OsStr` as a byte slice. /// Yields this `OsStr` as a byte slice.
/// ///
/// # Platform behavior /// # Platform behavior
/// ///
@ -275,7 +274,7 @@ impl OsStr {
} }
} }
/// Create a `CString` containing this `OsStr` data. /// Creates a `CString` containing this `OsStr` data.
/// ///
/// Fails if the `OsStr` contains interior nulls. /// Fails if the `OsStr` contains interior nulls.
/// ///
@ -287,7 +286,7 @@ impl OsStr {
self.to_bytes().and_then(|b| CString::new(b).ok()) self.to_bytes().and_then(|b| CString::new(b).ok())
} }
/// Get the underlying byte representation. /// Gets the underlying byte representation.
/// ///
/// Note: it is *crucial* that this API is private, to avoid /// Note: it is *crucial* that this API is private, to avoid
/// revealing the internal, platform-specific encodings. /// revealing the internal, platform-specific encodings.
@ -447,21 +446,6 @@ impl AsRef<OsStr> for String {
} }
} }
#[allow(deprecated)]
#[stable(feature = "rust1", since = "1.0.0")]
#[deprecated(since = "1.0.0", reason = "trait is deprecated")]
impl AsOsStr for Path {
#[cfg(unix)]
fn as_os_str(&self) -> &OsStr {
unsafe { mem::transmute(self.as_vec()) }
}
#[cfg(windows)]
fn as_os_str(&self) -> &OsStr {
// currently .as_str() is actually infallible on windows
OsStr::from_str(self.as_str().unwrap())
}
}
impl FromInner<Buf> for OsString { impl FromInner<Buf> for OsString {
fn from_inner(buf: Buf) -> OsString { fn from_inner(buf: Buf) -> OsString {
OsString { inner: buf } OsString { inner: buf }

View File

@ -123,7 +123,7 @@ pub struct WalkDir {
/// Opening a file for both reading and writing, as well as creating it if it /// Opening a file for both reading and writing, as well as creating it if it
/// doesn't exist: /// doesn't exist:
/// ///
/// ``` /// ```no_run
/// use std::fs::OpenOptions; /// use std::fs::OpenOptions;
/// ///
/// let file = OpenOptions::new() /// let file = OpenOptions::new()
@ -171,7 +171,7 @@ impl File {
OpenOptions::new().read(true).open(path) OpenOptions::new().read(true).open(path)
} }
/// Open a file in write-only mode. /// Opens a file in write-only mode.
/// ///
/// This function will create a file if it does not exist, /// This function will create a file if it does not exist,
/// and will truncate it if it does. /// and will truncate it if it does.
@ -201,7 +201,7 @@ impl File {
self.path.as_ref().map(|p| &**p) self.path.as_ref().map(|p| &**p)
} }
/// Attempt to sync all OS-internal metadata to disk. /// Attempts to sync all OS-internal metadata to disk.
/// ///
/// This function will attempt to ensure that all in-core data reaches the /// This function will attempt to ensure that all in-core data reaches the
/// filesystem before returning. /// filesystem before returning.
@ -362,7 +362,7 @@ impl OpenOptions {
OpenOptions(fs_imp::OpenOptions::new()) OpenOptions(fs_imp::OpenOptions::new())
} }
/// Set the option for read access. /// Sets the option for read access.
/// ///
/// This option, when true, will indicate that the file should be /// This option, when true, will indicate that the file should be
/// `read`-able if opened. /// `read`-able if opened.
@ -379,7 +379,7 @@ impl OpenOptions {
self.0.read(read); self self.0.read(read); self
} }
/// Set the option for write access. /// Sets the option for write access.
/// ///
/// This option, when true, will indicate that the file should be /// This option, when true, will indicate that the file should be
/// `write`-able if opened. /// `write`-able if opened.
@ -396,7 +396,7 @@ impl OpenOptions {
self.0.write(write); self self.0.write(write); self
} }
/// Set the option for the append mode. /// Sets the option for the append mode.
/// ///
/// This option, when true, means that writes will append to a file instead /// This option, when true, means that writes will append to a file instead
/// of overwriting previous contents. /// of overwriting previous contents.
@ -413,7 +413,7 @@ impl OpenOptions {
self.0.append(append); self self.0.append(append); self
} }
/// Set the option for truncating a previous file. /// Sets the option for truncating a previous file.
/// ///
/// If a file is successfully opened with this option set it will truncate /// If a file is successfully opened with this option set it will truncate
/// the file to 0 length if it already exists. /// the file to 0 length if it already exists.
@ -430,7 +430,7 @@ impl OpenOptions {
self.0.truncate(truncate); self self.0.truncate(truncate); self
} }
/// Set the option for creating a new file. /// Sets the option for creating a new file.
/// ///
/// This option indicates whether a new file will be created if the file /// This option indicates whether a new file will be created if the file
/// does not yet already exist. /// does not yet already exist.
@ -447,7 +447,7 @@ impl OpenOptions {
self.0.create(create); self self.0.create(create); self
} }
/// Open a file at `path` with the options specified by `self`. /// Opens a file at `path` with the options specified by `self`.
/// ///
/// # Errors /// # Errors
/// ///
@ -587,7 +587,7 @@ impl Permissions {
#[stable(feature = "rust1", since = "1.0.0")] #[stable(feature = "rust1", since = "1.0.0")]
pub fn readonly(&self) -> bool { self.0.readonly() } pub fn readonly(&self) -> bool { self.0.readonly() }
/// Modify the readonly flag for this set of permissions. /// Modifies the readonly flag for this set of permissions.
/// ///
/// This operation does **not** modify the filesystem. To modify the /// This operation does **not** modify the filesystem. To modify the
/// filesystem use the `fs::set_permissions` function. /// filesystem use the `fs::set_permissions` function.
@ -670,7 +670,7 @@ impl DirEntry {
pub fn path(&self) -> PathBuf { self.0.path() } pub fn path(&self) -> PathBuf { self.0.path() }
} }
/// Remove a file from the underlying filesystem. /// Removes a file from the underlying filesystem.
/// ///
/// Note that, just because an unlink call was successful, it is not /// Note that, just because an unlink call was successful, it is not
/// guaranteed that a file is immediately deleted (e.g. depending on /// guaranteed that a file is immediately deleted (e.g. depending on
@ -856,7 +856,7 @@ pub fn read_link<P: AsRef<Path>>(path: P) -> io::Result<PathBuf> {
fs_imp::readlink(path.as_ref()) fs_imp::readlink(path.as_ref())
} }
/// Create a new, empty directory at the provided path /// Creates a new, empty directory at the provided path
/// ///
/// # Errors /// # Errors
/// ///
@ -906,7 +906,7 @@ pub fn create_dir_all<P: AsRef<Path>>(path: P) -> io::Result<()> {
create_dir(path) create_dir(path)
} }
/// Remove an existing, empty directory /// Removes an existing, empty directory.
/// ///
/// # Errors /// # Errors
/// ///
@ -1058,7 +1058,7 @@ impl Iterator for WalkDir {
reason = "the precise set of methods exposed on this trait may \ reason = "the precise set of methods exposed on this trait may \
change and some methods may be removed")] change and some methods may be removed")]
pub trait PathExt { pub trait PathExt {
/// Get information on the file, directory, etc at this path. /// Gets information on the file, directory, etc at this path.
/// ///
/// Consult the `fs::stat` documentation for more info. /// Consult the `fs::stat` documentation for more info.
/// ///
@ -1195,7 +1195,8 @@ mod tests {
pub fn tmpdir() -> TempDir { pub fn tmpdir() -> TempDir {
let p = env::temp_dir(); let p = env::temp_dir();
let ret = p.join(&format!("rust-{}", rand::random::<u32>())); let mut r = rand::thread_rng();
let ret = p.join(&format!("rust-{}", r.next_u32()));
check!(fs::create_dir(&ret)); check!(fs::create_dir(&ret));
TempDir(ret) TempDir(ret)
} }

View File

@ -34,21 +34,21 @@ pub struct Cursor<T> {
} }
impl<T> Cursor<T> { impl<T> Cursor<T> {
/// Create a new cursor wrapping the provided underlying I/O object. /// Creates a new cursor wrapping the provided underlying I/O object.
#[stable(feature = "rust1", since = "1.0.0")] #[stable(feature = "rust1", since = "1.0.0")]
pub fn new(inner: T) -> Cursor<T> { pub fn new(inner: T) -> Cursor<T> {
Cursor { pos: 0, inner: inner } Cursor { pos: 0, inner: inner }
} }
/// Consume this cursor, returning the underlying value. /// Consumes this cursor, returning the underlying value.
#[stable(feature = "rust1", since = "1.0.0")] #[stable(feature = "rust1", since = "1.0.0")]
pub fn into_inner(self) -> T { self.inner } pub fn into_inner(self) -> T { self.inner }
/// Get a reference to the underlying value in this cursor. /// Gets a reference to the underlying value in this cursor.
#[stable(feature = "rust1", since = "1.0.0")] #[stable(feature = "rust1", since = "1.0.0")]
pub fn get_ref(&self) -> &T { &self.inner } pub fn get_ref(&self) -> &T { &self.inner }
/// Get a mutable reference to the underlying value in this cursor. /// Gets a mutable reference to the underlying value in this cursor.
/// ///
/// Care should be taken to avoid modifying the internal I/O state of the /// Care should be taken to avoid modifying the internal I/O state of the
/// underlying value as it may corrupt this cursor's position. /// underlying value as it may corrupt this cursor's position.

View File

@ -191,7 +191,7 @@ impl Error {
} }
} }
/// Return the corresponding `ErrorKind` for this error. /// Returns the corresponding `ErrorKind` for this error.
#[stable(feature = "rust1", since = "1.0.0")] #[stable(feature = "rust1", since = "1.0.0")]
pub fn kind(&self) -> ErrorKind { pub fn kind(&self) -> ErrorKind {
match self.repr { match self.repr {

View File

@ -172,14 +172,11 @@ pub trait Read {
/// Read all bytes until EOF in this source, placing them into `buf`. /// Read all bytes until EOF in this source, placing them into `buf`.
/// ///
/// All bytes read from this source will be appended to the specified buffer /// All bytes read from this source will be appended to the specified buffer
/// `buf`. This function will return a call to `read` either: /// `buf`. This function will continuously call `read` to append more data to
/// `buf` until `read` returns either `Ok(0)` or an error of
/// non-`ErrorKind::Interrupted` kind.
/// ///
/// 1. Returns `Ok(0)`. /// If successful, this function will return the total number of bytes read.
/// 2. Returns an error which is not of the kind `ErrorKind::Interrupted`.
///
/// Until one of these conditions is met the function will continuously
/// invoke `read` to append more data to `buf`. If successful, this function
/// will return the total number of bytes read.
/// ///
/// # Errors /// # Errors
/// ///
@ -220,14 +217,14 @@ pub trait Read {
append_to_string(buf, |b| read_to_end(self, b)) append_to_string(buf, |b| read_to_end(self, b))
} }
/// Create a "by reference" adaptor for this instance of `Read`. /// Creates a "by reference" adaptor for this instance of `Read`.
/// ///
/// The returned adaptor also implements `Read` and will simply borrow this /// The returned adaptor also implements `Read` and will simply borrow this
/// current reader. /// current reader.
#[stable(feature = "rust1", since = "1.0.0")] #[stable(feature = "rust1", since = "1.0.0")]
fn by_ref(&mut self) -> &mut Self where Self: Sized { self } fn by_ref(&mut self) -> &mut Self where Self: Sized { self }
/// Transform this `Read` instance to an `Iterator` over its bytes. /// Transforms this `Read` instance to an `Iterator` over its bytes.
/// ///
/// The returned type implements `Iterator` where the `Item` is `Result<u8, /// The returned type implements `Iterator` where the `Item` is `Result<u8,
/// R::Err>`. The yielded item is `Ok` if a byte was successfully read and /// R::Err>`. The yielded item is `Ok` if a byte was successfully read and
@ -238,7 +235,7 @@ pub trait Read {
Bytes { inner: self } Bytes { inner: self }
} }
/// Transform this `Read` instance to an `Iterator` over `char`s. /// Transforms this `Read` instance to an `Iterator` over `char`s.
/// ///
/// This adaptor will attempt to interpret this reader as an UTF-8 encoded /// This adaptor will attempt to interpret this reader as an UTF-8 encoded
/// sequence of characters. The returned iterator will return `None` once /// sequence of characters. The returned iterator will return `None` once
@ -255,7 +252,7 @@ pub trait Read {
Chars { inner: self } Chars { inner: self }
} }
/// Create an adaptor which will chain this stream with another. /// Creates an adaptor which will chain this stream with another.
/// ///
/// The returned `Read` instance will first read all bytes from this object /// The returned `Read` instance will first read all bytes from this object
/// until EOF is encountered. Afterwards the output is equivalent to the /// until EOF is encountered. Afterwards the output is equivalent to the
@ -265,7 +262,7 @@ pub trait Read {
Chain { first: self, second: next, done_first: false } Chain { first: self, second: next, done_first: false }
} }
/// Create an adaptor which will read at most `limit` bytes from it. /// Creates an adaptor which will read at most `limit` bytes from it.
/// ///
/// This function returns a new instance of `Read` which will read at most /// This function returns a new instance of `Read` which will read at most
/// `limit` bytes, after which it will always return EOF (`Ok(0)`). Any /// `limit` bytes, after which it will always return EOF (`Ok(0)`). Any
@ -406,7 +403,7 @@ pub trait Write {
} }
} }
/// Create a "by reference" adaptor for this instance of `Write`. /// Creates a "by reference" adaptor for this instance of `Write`.
/// ///
/// The returned adaptor also implements `Write` and will simply borrow this /// The returned adaptor also implements `Write` and will simply borrow this
/// current writer. /// current writer.

View File

@ -45,7 +45,7 @@ struct StdoutRaw(stdio::Stdout);
/// the `std::io::stdio::stderr_raw` function. /// the `std::io::stdio::stderr_raw` function.
struct StderrRaw(stdio::Stderr); struct StderrRaw(stdio::Stderr);
/// Construct a new raw handle to the standard input of this process. /// Constructs a new raw handle to the standard input of this process.
/// ///
/// The returned handle does not interact with any other handles created nor /// The returned handle does not interact with any other handles created nor
/// handles returned by `std::io::stdin`. Data buffered by the `std::io::stdin` /// handles returned by `std::io::stdin`. Data buffered by the `std::io::stdin`
@ -54,7 +54,7 @@ struct StderrRaw(stdio::Stderr);
/// The returned handle has no external synchronization or buffering. /// The returned handle has no external synchronization or buffering.
fn stdin_raw() -> StdinRaw { StdinRaw(stdio::Stdin::new()) } fn stdin_raw() -> StdinRaw { StdinRaw(stdio::Stdin::new()) }
/// Construct a new raw handle to the standard input stream of this process. /// Constructs a new raw handle to the standard input stream of this process.
/// ///
/// The returned handle does not interact with any other handles created nor /// The returned handle does not interact with any other handles created nor
/// handles returned by `std::io::stdout`. Note that data is buffered by the /// handles returned by `std::io::stdout`. Note that data is buffered by the
@ -65,7 +65,7 @@ fn stdin_raw() -> StdinRaw { StdinRaw(stdio::Stdin::new()) }
/// top. /// top.
fn stdout_raw() -> StdoutRaw { StdoutRaw(stdio::Stdout::new()) } fn stdout_raw() -> StdoutRaw { StdoutRaw(stdio::Stdout::new()) }
/// Construct a new raw handle to the standard input stream of this process. /// Constructs a new raw handle to the standard input stream of this process.
/// ///
/// The returned handle does not interact with any other handles created nor /// The returned handle does not interact with any other handles created nor
/// handles returned by `std::io::stdout`. /// handles returned by `std::io::stdout`.
@ -109,7 +109,7 @@ pub struct StdinLock<'a> {
inner: MutexGuard<'a, BufReader<StdinRaw>>, inner: MutexGuard<'a, BufReader<StdinRaw>>,
} }
/// Create a new handle to the global standard input stream of this process. /// Creates a new handle to the global standard input stream of this process.
/// ///
/// The handle returned refers to a globally shared buffer between all threads. /// The handle returned refers to a globally shared buffer between all threads.
/// Access is synchronized and can be explicitly controlled with the `lock()` /// Access is synchronized and can be explicitly controlled with the `lock()`
@ -139,7 +139,7 @@ pub fn stdin() -> Stdin {
} }
impl Stdin { impl Stdin {
/// Lock this handle to the standard input stream, returning a readable /// Locks this handle to the standard input stream, returning a readable
/// guard. /// guard.
/// ///
/// The lock is released when the returned lock goes out of scope. The /// The lock is released when the returned lock goes out of scope. The
@ -243,7 +243,7 @@ pub fn stdout() -> Stdout {
} }
impl Stdout { impl Stdout {
/// Lock this handle to the standard output stream, returning a writable /// Locks this handle to the standard output stream, returning a writable
/// guard. /// guard.
/// ///
/// The lock is released when the returned lock goes out of scope. The /// The lock is released when the returned lock goes out of scope. The
@ -315,7 +315,7 @@ pub fn stderr() -> Stderr {
} }
impl Stderr { impl Stderr {
/// Lock this handle to the standard error stream, returning a writable /// Locks this handle to the standard error stream, returning a writable
/// guard. /// guard.
/// ///
/// The lock is released when the returned lock goes out of scope. The /// The lock is released when the returned lock goes out of scope. The

View File

@ -262,12 +262,9 @@ pub mod ffi;
pub mod fs; pub mod fs;
pub mod io; pub mod io;
pub mod net; pub mod net;
pub mod old_io;
pub mod old_path;
pub mod os; pub mod os;
pub mod path; pub mod path;
pub mod process; pub mod process;
pub mod rand;
pub mod sync; pub mod sync;
pub mod time; pub mod time;
@ -281,6 +278,18 @@ pub mod time;
pub mod rt; pub mod rt;
mod panicking; mod panicking;
mod rand;
// Some external utilities of the standard library rely on randomness (aka
// rustc_back::TempDir and tests) and need a way to get at the OS rng we've got
// here. This module is not at all intended for stabilization as-is, however,
// but it may be stabilized long-term. As a result we're exposing a hidden,
// unstable module so we can get our build working.
#[doc(hidden)]
#[unstable(feature = "rand")]
pub mod __rand {
pub use rand::{thread_rng, ThreadRng, Rng};
}
// Modules that exist purely to document + host impl docs for primitive types // Modules that exist purely to document + host impl docs for primitive types
@ -297,8 +306,6 @@ mod std {
pub use sync; // used for select!() pub use sync; // used for select!()
pub use error; // used for try!() pub use error; // used for try!()
pub use fmt; // used for any formatting strings pub use fmt; // used for any formatting strings
#[allow(deprecated)]
pub use old_io; // used for println!()
pub use option; // used for bitflags!{} pub use option; // used for bitflags!{}
pub use rt; // used for panic!() pub use rt; // used for panic!()
pub use vec; // used for vec![] pub use vec; // used for vec![]

View File

@ -615,7 +615,7 @@ mod tests {
fn ipv4_properties() { fn ipv4_properties() {
fn check(octets: &[u8; 4], unspec: bool, loopback: bool, fn check(octets: &[u8; 4], unspec: bool, loopback: bool,
private: bool, link_local: bool, global: bool, private: bool, link_local: bool, global: bool,
multicast: bool) { multicast: bool, broadcast: bool, documentation: bool) {
let ip = Ipv4Addr::new(octets[0], octets[1], octets[2], octets[3]); let ip = Ipv4Addr::new(octets[0], octets[1], octets[2], octets[3]);
assert_eq!(octets, &ip.octets()); assert_eq!(octets, &ip.octets());
@ -625,20 +625,23 @@ mod tests {
assert_eq!(ip.is_link_local(), link_local); assert_eq!(ip.is_link_local(), link_local);
assert_eq!(ip.is_global(), global); assert_eq!(ip.is_global(), global);
assert_eq!(ip.is_multicast(), multicast); assert_eq!(ip.is_multicast(), multicast);
assert_eq!(ip.is_broadcast(), broadcast);
assert_eq!(ip.is_documentation(), documentation);
} }
// address unspec loopbk privt linloc global multicast // address unspec loopbk privt linloc global multicast brdcast doc
check(&[0, 0, 0, 0], true, false, false, false, true, false); check(&[0, 0, 0, 0], true, false, false, false, true, false, false, false);
check(&[0, 0, 0, 1], false, false, false, false, true, false); check(&[0, 0, 0, 1], false, false, false, false, true, false, false, false);
check(&[1, 0, 0, 0], false, false, false, false, true, false); check(&[1, 0, 0, 0], false, false, false, false, true, false, false, false);
check(&[10, 9, 8, 7], false, false, true, false, false, false); check(&[10, 9, 8, 7], false, false, true, false, false, false, false, false);
check(&[127, 1, 2, 3], false, true, false, false, false, false); check(&[127, 1, 2, 3], false, true, false, false, false, false, false, false);
check(&[172, 31, 254, 253], false, false, true, false, false, false); check(&[172, 31, 254, 253], false, false, true, false, false, false, false, false);
check(&[169, 254, 253, 242], false, false, false, true, false, false); check(&[169, 254, 253, 242], false, false, false, true, false, false, false, false);
check(&[192, 168, 254, 253], false, false, true, false, false, false); check(&[192, 168, 254, 253], false, false, true, false, false, false, false, false);
check(&[224, 0, 0, 0], false, false, false, false, true, true); check(&[224, 0, 0, 0], false, false, false, false, true, true, false, false);
check(&[239, 255, 255, 255], false, false, false, false, true, true); check(&[239, 255, 255, 255], false, false, false, false, true, true, false, false);
check(&[255, 255, 255, 255], false, false, false, false, true, false); check(&[255, 255, 255, 255], false, false, false, false, false, false, true, false);
check(&[198, 51, 100, 0], false, false, false, false, false, false, false, true);
} }
#[test] #[test]

View File

@ -58,7 +58,7 @@ pub enum Ipv6MulticastScope {
} }
impl Ipv4Addr { impl Ipv4Addr {
/// Create a new IPv4 address from four eight-bit octets. /// Creates a new IPv4 address from four eight-bit octets.
/// ///
/// The result will represent the IP address a.b.c.d /// The result will represent the IP address a.b.c.d
#[stable(feature = "rust1", since = "1.0.0")] #[stable(feature = "rust1", since = "1.0.0")]
@ -115,9 +115,11 @@ impl Ipv4Addr {
/// ///
/// Non-globally-routable networks include the private networks (10.0.0.0/8, /// Non-globally-routable networks include the private networks (10.0.0.0/8,
/// 172.16.0.0/12 and 192.168.0.0/16), the loopback network (127.0.0.0/8), /// 172.16.0.0/12 and 192.168.0.0/16), the loopback network (127.0.0.0/8),
/// and the link-local network (169.254.0.0/16). /// the link-local network (169.254.0.0/16), the broadcast address (255.255.255.255/32) and
/// the test networks used for documentation (192.0.2.0/24, 198.51.100.0/24 and 203.0.113.0/24)
pub fn is_global(&self) -> bool { pub fn is_global(&self) -> bool {
!self.is_private() && !self.is_loopback() && !self.is_link_local() !self.is_private() && !self.is_loopback() && !self.is_link_local() &&
!self.is_broadcast() && !self.is_documentation()
} }
/// Returns true if this is a multicast address. /// Returns true if this is a multicast address.
@ -127,7 +129,30 @@ impl Ipv4Addr {
self.octets()[0] >= 224 && self.octets()[0] <= 239 self.octets()[0] >= 224 && self.octets()[0] <= 239
} }
/// Convert this address to an IPv4-compatible IPv6 address /// Returns true if this is a broadcast address.
///
/// A broadcast address has all octets set to 255 as defined in RFC 919
pub fn is_broadcast(&self) -> bool {
self.octets()[0] == 255 && self.octets()[1] == 255 &&
self.octets()[2] == 255 && self.octets()[3] == 255
}
/// Returns true if this address is in a range designated for documentation
///
/// This is defined in RFC 5737
/// - 192.0.2.0/24 (TEST-NET-1)
/// - 198.51.100.0/24 (TEST-NET-2)
/// - 203.0.113.0/24 (TEST-NET-3)
pub fn is_documentation(&self) -> bool {
match(self.octets()[0], self.octets()[1], self.octets()[2], self.octets()[3]) {
(192, _, 2, _) => true,
(198, 51, 100, _) => true,
(203, _, 113, _) => true,
_ => false
}
}
/// Converts this address to an IPv4-compatible IPv6 address
/// ///
/// a.b.c.d becomes ::a.b.c.d /// a.b.c.d becomes ::a.b.c.d
#[stable(feature = "rust1", since = "1.0.0")] #[stable(feature = "rust1", since = "1.0.0")]
@ -137,7 +162,7 @@ impl Ipv4Addr {
((self.octets()[2] as u16) << 8) | self.octets()[3] as u16) ((self.octets()[2] as u16) << 8) | self.octets()[3] as u16)
} }
/// Convert this address to an IPv4-mapped IPv6 address /// Converts this address to an IPv4-mapped IPv6 address
/// ///
/// a.b.c.d becomes ::ffff:a.b.c.d /// a.b.c.d becomes ::ffff:a.b.c.d
#[stable(feature = "rust1", since = "1.0.0")] #[stable(feature = "rust1", since = "1.0.0")]
@ -220,7 +245,7 @@ impl FromInner<libc::in_addr> for Ipv4Addr {
} }
impl Ipv6Addr { impl Ipv6Addr {
/// Create a new IPv6 address from eight 16-bit segments. /// Creates a new IPv6 address from eight 16-bit segments.
/// ///
/// The result will represent the IP address a:b:c:d:e:f:g:h /// The result will represent the IP address a:b:c:d:e:f:g:h
#[stable(feature = "rust1", since = "1.0.0")] #[stable(feature = "rust1", since = "1.0.0")]
@ -234,7 +259,7 @@ impl Ipv6Addr {
} }
} }
/// Return the eight 16-bit segments that make up this address /// Returns the eight 16-bit segments that make up this address
#[stable(feature = "rust1", since = "1.0.0")] #[stable(feature = "rust1", since = "1.0.0")]
pub fn segments(&self) -> [u16; 8] { pub fn segments(&self) -> [u16; 8] {
[ntoh(self.inner.s6_addr[0]), [ntoh(self.inner.s6_addr[0]),
@ -324,7 +349,7 @@ impl Ipv6Addr {
(self.segments()[0] & 0xff00) == 0xff00 (self.segments()[0] & 0xff00) == 0xff00
} }
/// Convert this address to an IPv4 address. Returns None if this address is /// Converts this address to an IPv4 address. Returns None if this address is
/// neither IPv4-compatible or IPv4-mapped. /// neither IPv4-compatible or IPv4-mapped.
/// ///
/// ::a.b.c.d and ::ffff:a.b.c.d become a.b.c.d /// ::a.b.c.d and ::ffff:a.b.c.d become a.b.c.d

View File

@ -82,7 +82,7 @@ pub struct TcpListener(net_imp::TcpListener);
pub struct Incoming<'a> { listener: &'a TcpListener } pub struct Incoming<'a> { listener: &'a TcpListener }
impl TcpStream { impl TcpStream {
/// Open a TCP connection to a remote host. /// Opens a TCP connection to a remote host.
/// ///
/// `addr` is an address of the remote host. Anything which implements /// `addr` is an address of the remote host. Anything which implements
/// `ToSocketAddrs` trait can be supplied for the address; see this trait /// `ToSocketAddrs` trait can be supplied for the address; see this trait
@ -104,7 +104,7 @@ impl TcpStream {
self.0.socket_addr() self.0.socket_addr()
} }
/// Shut down the read, write, or both halves of this connection. /// Shuts down the read, write, or both halves of this connection.
/// ///
/// This function will cause all pending and future I/O on the specified /// This function will cause all pending and future I/O on the specified
/// portions to return immediately with an appropriate value (see the /// portions to return immediately with an appropriate value (see the
@ -114,7 +114,7 @@ impl TcpStream {
self.0.shutdown(how) self.0.shutdown(how)
} }
/// Create a new independently owned handle to the underlying socket. /// Creates a new independently owned handle to the underlying socket.
/// ///
/// The returned `TcpStream` is a reference to the same stream that this /// The returned `TcpStream` is a reference to the same stream that this
/// object references. Both handles will read and write the same stream of /// object references. Both handles will read and write the same stream of
@ -190,7 +190,7 @@ impl TcpListener {
self.0.socket_addr() self.0.socket_addr()
} }
/// Create a new independently owned handle to the underlying socket. /// Creates a new independently owned handle to the underlying socket.
/// ///
/// The returned `TcpListener` is a reference to the same socket that this /// The returned `TcpListener` is a reference to the same socket that this
/// object references. Both handles can be used to accept incoming /// object references. Both handles can be used to accept incoming

View File

@ -85,7 +85,7 @@ impl UdpSocket {
self.0.socket_addr() self.0.socket_addr()
} }
/// Create a new independently owned handle to the underlying socket. /// Creates a new independently owned handle to the underlying socket.
/// ///
/// The returned `UdpSocket` is a reference to the same socket that this /// The returned `UdpSocket` is a reference to the same socket that this
/// object references. Both handles will read and write the same port, and /// object references. Both handles will read and write the same port, and
@ -100,7 +100,7 @@ impl UdpSocket {
self.0.set_broadcast(on) self.0.set_broadcast(on)
} }
/// Set the multicast loop flag to the specified value /// Sets the multicast loop flag to the specified value
/// ///
/// This lets multicast packets loop back to local sockets (if enabled) /// This lets multicast packets loop back to local sockets (if enabled)
pub fn set_multicast_loop(&self, on: bool) -> io::Result<()> { pub fn set_multicast_loop(&self, on: bool) -> io::Result<()> {

View File

@ -527,7 +527,7 @@ impl f32 {
#[inline] #[inline]
pub fn round(self) -> f32 { num::Float::round(self) } pub fn round(self) -> f32 { num::Float::round(self) }
/// Return the integer part of a number. /// Returns the integer part of a number.
/// ///
/// ``` /// ```
/// let f = 3.3_f32; /// let f = 3.3_f32;
@ -666,7 +666,7 @@ impl f32 {
#[inline] #[inline]
pub fn mul_add(self, a: f32, b: f32) -> f32 { num::Float::mul_add(self, a, b) } pub fn mul_add(self, a: f32, b: f32) -> f32 { num::Float::mul_add(self, a, b) }
/// Take the reciprocal (inverse) of a number, `1/x`. /// Takes the reciprocal (inverse) of a number, `1/x`.
/// ///
/// ``` /// ```
/// use std::f32; /// use std::f32;
@ -680,7 +680,7 @@ impl f32 {
#[inline] #[inline]
pub fn recip(self) -> f32 { num::Float::recip(self) } pub fn recip(self) -> f32 { num::Float::recip(self) }
/// Raise a number to an integer power. /// Raises a number to an integer power.
/// ///
/// Using this function is generally faster than using `powf` /// Using this function is generally faster than using `powf`
/// ///
@ -696,7 +696,7 @@ impl f32 {
#[inline] #[inline]
pub fn powi(self, n: i32) -> f32 { num::Float::powi(self, n) } pub fn powi(self, n: i32) -> f32 { num::Float::powi(self, n) }
/// Raise a number to a floating point power. /// Raises a number to a floating point power.
/// ///
/// ``` /// ```
/// use std::f32; /// use std::f32;
@ -710,7 +710,7 @@ impl f32 {
#[inline] #[inline]
pub fn powf(self, n: f32) -> f32 { num::Float::powf(self, n) } pub fn powf(self, n: f32) -> f32 { num::Float::powf(self, n) }
/// Take the square root of a number. /// Takes the square root of a number.
/// ///
/// Returns NaN if `self` is a negative number. /// Returns NaN if `self` is a negative number.
/// ///
@ -729,7 +729,7 @@ impl f32 {
#[inline] #[inline]
pub fn sqrt(self) -> f32 { num::Float::sqrt(self) } pub fn sqrt(self) -> f32 { num::Float::sqrt(self) }
/// Take the reciprocal (inverse) square root of a number, `1/sqrt(x)`. /// Takes the reciprocal (inverse) square root of a number, `1/sqrt(x)`.
/// ///
/// ``` /// ```
/// # #![feature(std_misc)] /// # #![feature(std_misc)]
@ -852,7 +852,7 @@ impl f32 {
#[inline] #[inline]
pub fn log10(self) -> f32 { num::Float::log10(self) } pub fn log10(self) -> f32 { num::Float::log10(self) }
/// Convert radians to degrees. /// Converts radians to degrees.
/// ///
/// ``` /// ```
/// # #![feature(std_misc)] /// # #![feature(std_misc)]
@ -868,7 +868,7 @@ impl f32 {
#[inline] #[inline]
pub fn to_degrees(self) -> f32 { num::Float::to_degrees(self) } pub fn to_degrees(self) -> f32 { num::Float::to_degrees(self) }
/// Convert degrees to radians. /// Converts degrees to radians.
/// ///
/// ``` /// ```
/// # #![feature(std_misc)] /// # #![feature(std_misc)]
@ -1003,7 +1003,7 @@ impl f32 {
unsafe { cmath::fdimf(self, other) } unsafe { cmath::fdimf(self, other) }
} }
/// Take the cubic root of a number. /// Takes the cubic root of a number.
/// ///
/// ``` /// ```
/// use std::f32; /// use std::f32;
@ -1021,7 +1021,7 @@ impl f32 {
unsafe { cmath::cbrtf(self) } unsafe { cmath::cbrtf(self) }
} }
/// Calculate the length of the hypotenuse of a right-angle triangle given /// Calculates the length of the hypotenuse of a right-angle triangle given
/// legs of length `x` and `y`. /// legs of length `x` and `y`.
/// ///
/// ``` /// ```

View File

@ -534,7 +534,7 @@ impl f64 {
#[inline] #[inline]
pub fn round(self) -> f64 { num::Float::round(self) } pub fn round(self) -> f64 { num::Float::round(self) }
/// Return the integer part of a number. /// Returns the integer part of a number.
/// ///
/// ``` /// ```
/// let f = 3.3_f64; /// let f = 3.3_f64;
@ -671,7 +671,7 @@ impl f64 {
#[inline] #[inline]
pub fn mul_add(self, a: f64, b: f64) -> f64 { num::Float::mul_add(self, a, b) } pub fn mul_add(self, a: f64, b: f64) -> f64 { num::Float::mul_add(self, a, b) }
/// Take the reciprocal (inverse) of a number, `1/x`. /// Takes the reciprocal (inverse) of a number, `1/x`.
/// ///
/// ``` /// ```
/// let x = 2.0_f64; /// let x = 2.0_f64;
@ -683,7 +683,7 @@ impl f64 {
#[inline] #[inline]
pub fn recip(self) -> f64 { num::Float::recip(self) } pub fn recip(self) -> f64 { num::Float::recip(self) }
/// Raise a number to an integer power. /// Raises a number to an integer power.
/// ///
/// Using this function is generally faster than using `powf` /// Using this function is generally faster than using `powf`
/// ///
@ -697,7 +697,7 @@ impl f64 {
#[inline] #[inline]
pub fn powi(self, n: i32) -> f64 { num::Float::powi(self, n) } pub fn powi(self, n: i32) -> f64 { num::Float::powi(self, n) }
/// Raise a number to a floating point power. /// Raises a number to a floating point power.
/// ///
/// ``` /// ```
/// let x = 2.0_f64; /// let x = 2.0_f64;
@ -709,7 +709,7 @@ impl f64 {
#[inline] #[inline]
pub fn powf(self, n: f64) -> f64 { num::Float::powf(self, n) } pub fn powf(self, n: f64) -> f64 { num::Float::powf(self, n) }
/// Take the square root of a number. /// Takes the square root of a number.
/// ///
/// Returns NaN if `self` is a negative number. /// Returns NaN if `self` is a negative number.
/// ///
@ -726,7 +726,7 @@ impl f64 {
#[inline] #[inline]
pub fn sqrt(self) -> f64 { num::Float::sqrt(self) } pub fn sqrt(self) -> f64 { num::Float::sqrt(self) }
/// Take the reciprocal (inverse) square root of a number, `1/sqrt(x)`. /// Takes the reciprocal (inverse) square root of a number, `1/sqrt(x)`.
/// ///
/// ``` /// ```
/// # #![feature(std_misc)] /// # #![feature(std_misc)]
@ -835,7 +835,7 @@ impl f64 {
#[inline] #[inline]
pub fn log10(self) -> f64 { num::Float::log10(self) } pub fn log10(self) -> f64 { num::Float::log10(self) }
/// Convert radians to degrees. /// Converts radians to degrees.
/// ///
/// ``` /// ```
/// use std::f64::consts; /// use std::f64::consts;
@ -850,7 +850,7 @@ impl f64 {
#[inline] #[inline]
pub fn to_degrees(self) -> f64 { num::Float::to_degrees(self) } pub fn to_degrees(self) -> f64 { num::Float::to_degrees(self) }
/// Convert degrees to radians. /// Converts degrees to radians.
/// ///
/// ``` /// ```
/// use std::f64::consts; /// use std::f64::consts;
@ -978,7 +978,7 @@ impl f64 {
unsafe { cmath::fdim(self, other) } unsafe { cmath::fdim(self, other) }
} }
/// Take the cubic root of a number. /// Takes the cubic root of a number.
/// ///
/// ``` /// ```
/// let x = 8.0_f64; /// let x = 8.0_f64;
@ -994,7 +994,7 @@ impl f64 {
unsafe { cmath::cbrt(self) } unsafe { cmath::cbrt(self) }
} }
/// Calculate the length of the hypotenuse of a right-angle triangle given /// Calculates the length of the hypotenuse of a right-angle triangle given
/// legs of length `x` and `y`. /// legs of length `x` and `y`.
/// ///
/// ``` /// ```

View File

@ -383,7 +383,7 @@ pub trait Float
/// ``` /// ```
#[stable(feature = "rust1", since = "1.0.0")] #[stable(feature = "rust1", since = "1.0.0")]
fn round(self) -> Self; fn round(self) -> Self;
/// Return the integer part of a number. /// Returns the integer part of a number.
/// ///
/// ``` /// ```
/// use std::num::Float; /// use std::num::Float;
@ -509,7 +509,7 @@ pub trait Float
#[unstable(feature = "std_misc", #[unstable(feature = "std_misc",
reason = "unsure about its place in the world")] reason = "unsure about its place in the world")]
fn mul_add(self, a: Self, b: Self) -> Self; fn mul_add(self, a: Self, b: Self) -> Self;
/// Take the reciprocal (inverse) of a number, `1/x`. /// Takes the reciprocal (inverse) of a number, `1/x`.
/// ///
/// ``` /// ```
/// # #![feature(std_misc)] /// # #![feature(std_misc)]
@ -524,7 +524,7 @@ pub trait Float
reason = "unsure about its place in the world")] reason = "unsure about its place in the world")]
fn recip(self) -> Self; fn recip(self) -> Self;
/// Raise a number to an integer power. /// Raises a number to an integer power.
/// ///
/// Using this function is generally faster than using `powf` /// Using this function is generally faster than using `powf`
/// ///
@ -538,7 +538,7 @@ pub trait Float
/// ``` /// ```
#[stable(feature = "rust1", since = "1.0.0")] #[stable(feature = "rust1", since = "1.0.0")]
fn powi(self, n: i32) -> Self; fn powi(self, n: i32) -> Self;
/// Raise a number to a floating point power. /// Raises a number to a floating point power.
/// ///
/// ``` /// ```
/// use std::num::Float; /// use std::num::Float;
@ -550,7 +550,7 @@ pub trait Float
/// ``` /// ```
#[stable(feature = "rust1", since = "1.0.0")] #[stable(feature = "rust1", since = "1.0.0")]
fn powf(self, n: Self) -> Self; fn powf(self, n: Self) -> Self;
/// Take the square root of a number. /// Takes the square root of a number.
/// ///
/// Returns NaN if `self` is a negative number. /// Returns NaN if `self` is a negative number.
/// ///
@ -569,7 +569,7 @@ pub trait Float
#[stable(feature = "rust1", since = "1.0.0")] #[stable(feature = "rust1", since = "1.0.0")]
fn sqrt(self) -> Self; fn sqrt(self) -> Self;
/// Take the reciprocal (inverse) square root of a number, `1/sqrt(x)`. /// Takes the reciprocal (inverse) square root of a number, `1/sqrt(x)`.
/// ///
/// ``` /// ```
/// # #![feature(std_misc)] /// # #![feature(std_misc)]
@ -679,7 +679,7 @@ pub trait Float
#[stable(feature = "rust1", since = "1.0.0")] #[stable(feature = "rust1", since = "1.0.0")]
fn log10(self) -> Self; fn log10(self) -> Self;
/// Convert radians to degrees. /// Converts radians to degrees.
/// ///
/// ``` /// ```
/// use std::num::Float; /// use std::num::Float;
@ -693,7 +693,7 @@ pub trait Float
/// ``` /// ```
#[unstable(feature = "std_misc", reason = "desirability is unclear")] #[unstable(feature = "std_misc", reason = "desirability is unclear")]
fn to_degrees(self) -> Self; fn to_degrees(self) -> Self;
/// Convert degrees to radians. /// Converts degrees to radians.
/// ///
/// ``` /// ```
/// # #![feature(std_misc)] /// # #![feature(std_misc)]
@ -807,7 +807,7 @@ pub trait Float
/// ``` /// ```
#[unstable(feature = "std_misc", reason = "may be renamed")] #[unstable(feature = "std_misc", reason = "may be renamed")]
fn abs_sub(self, other: Self) -> Self; fn abs_sub(self, other: Self) -> Self;
/// Take the cubic root of a number. /// Takes the cubic root of a number.
/// ///
/// ``` /// ```
/// # #![feature(std_misc)] /// # #![feature(std_misc)]
@ -822,7 +822,7 @@ pub trait Float
/// ``` /// ```
#[unstable(feature = "std_misc", reason = "may be renamed")] #[unstable(feature = "std_misc", reason = "may be renamed")]
fn cbrt(self) -> Self; fn cbrt(self) -> Self;
/// Calculate the length of the hypotenuse of a right-angle triangle given /// Calculates the length of the hypotenuse of a right-angle triangle given
/// legs of length `x` and `y`. /// legs of length `x` and `y`.
/// ///
/// ``` /// ```

View File

@ -464,7 +464,7 @@ mod bench {
mod usize { mod usize {
use super::test::Bencher; use super::test::Bencher;
use rand::{weak_rng, Rng}; use rand::{thread_rng, Rng};
use std::fmt; use std::fmt;
#[inline] #[inline]
@ -474,38 +474,38 @@ mod bench {
#[bench] #[bench]
fn to_str_bin(b: &mut Bencher) { fn to_str_bin(b: &mut Bencher) {
let mut rng = weak_rng(); let mut rng = thread_rng();
b.iter(|| { to_string(rng.gen::<usize>(), 2); }) b.iter(|| { to_string(rng.gen::<usize>(), 2); })
} }
#[bench] #[bench]
fn to_str_oct(b: &mut Bencher) { fn to_str_oct(b: &mut Bencher) {
let mut rng = weak_rng(); let mut rng = thread_rng();
b.iter(|| { to_string(rng.gen::<usize>(), 8); }) b.iter(|| { to_string(rng.gen::<usize>(), 8); })
} }
#[bench] #[bench]
fn to_str_dec(b: &mut Bencher) { fn to_str_dec(b: &mut Bencher) {
let mut rng = weak_rng(); let mut rng = thread_rng();
b.iter(|| { to_string(rng.gen::<usize>(), 10); }) b.iter(|| { to_string(rng.gen::<usize>(), 10); })
} }
#[bench] #[bench]
fn to_str_hex(b: &mut Bencher) { fn to_str_hex(b: &mut Bencher) {
let mut rng = weak_rng(); let mut rng = thread_rng();
b.iter(|| { to_string(rng.gen::<usize>(), 16); }) b.iter(|| { to_string(rng.gen::<usize>(), 16); })
} }
#[bench] #[bench]
fn to_str_base_36(b: &mut Bencher) { fn to_str_base_36(b: &mut Bencher) {
let mut rng = weak_rng(); let mut rng = thread_rng();
b.iter(|| { to_string(rng.gen::<usize>(), 36); }) b.iter(|| { to_string(rng.gen::<usize>(), 36); })
} }
} }
mod isize { mod isize {
use super::test::Bencher; use super::test::Bencher;
use rand::{weak_rng, Rng}; use rand::{thread_rng, Rng};
use std::fmt; use std::fmt;
#[inline] #[inline]
@ -515,43 +515,43 @@ mod bench {
#[bench] #[bench]
fn to_str_bin(b: &mut Bencher) { fn to_str_bin(b: &mut Bencher) {
let mut rng = weak_rng(); let mut rng = thread_rng();
b.iter(|| { to_string(rng.gen::<isize>(), 2); }) b.iter(|| { to_string(rng.gen::<isize>(), 2); })
} }
#[bench] #[bench]
fn to_str_oct(b: &mut Bencher) { fn to_str_oct(b: &mut Bencher) {
let mut rng = weak_rng(); let mut rng = thread_rng();
b.iter(|| { to_string(rng.gen::<isize>(), 8); }) b.iter(|| { to_string(rng.gen::<isize>(), 8); })
} }
#[bench] #[bench]
fn to_str_dec(b: &mut Bencher) { fn to_str_dec(b: &mut Bencher) {
let mut rng = weak_rng(); let mut rng = thread_rng();
b.iter(|| { to_string(rng.gen::<isize>(), 10); }) b.iter(|| { to_string(rng.gen::<isize>(), 10); })
} }
#[bench] #[bench]
fn to_str_hex(b: &mut Bencher) { fn to_str_hex(b: &mut Bencher) {
let mut rng = weak_rng(); let mut rng = thread_rng();
b.iter(|| { to_string(rng.gen::<isize>(), 16); }) b.iter(|| { to_string(rng.gen::<isize>(), 16); })
} }
#[bench] #[bench]
fn to_str_base_36(b: &mut Bencher) { fn to_str_base_36(b: &mut Bencher) {
let mut rng = weak_rng(); let mut rng = thread_rng();
b.iter(|| { to_string(rng.gen::<isize>(), 36); }) b.iter(|| { to_string(rng.gen::<isize>(), 36); })
} }
} }
mod f64 { mod f64 {
use super::test::Bencher; use super::test::Bencher;
use rand::{weak_rng, Rng}; use rand::{thread_rng, Rng};
use f64; use f64;
#[bench] #[bench]
fn float_to_string(b: &mut Bencher) { fn float_to_string(b: &mut Bencher) {
let mut rng = weak_rng(); let mut rng = thread_rng();
b.iter(|| { f64::to_string(rng.gen()); }) b.iter(|| { f64::to_string(rng.gen()); })
} }
} }

View File

@ -1,702 +0,0 @@
// Copyright 2013 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.
//
// ignore-lexer-test FIXME #15883
//! Buffering wrappers for I/O traits
use cmp;
use fmt;
use old_io::{Reader, Writer, Stream, Buffer, DEFAULT_BUF_SIZE, IoResult};
use iter::{Iterator, ExactSizeIterator, repeat};
use ops::Drop;
use option::Option;
use option::Option::{Some, None};
use result::Result::Ok;
use slice;
use vec::Vec;
/// Wraps a Reader and buffers input from it
///
/// It can be excessively inefficient to work directly with a `Reader`. For
/// example, every call to `read` on `TcpStream` results in a system call. A
/// `BufferedReader` performs large, infrequent reads on the underlying
/// `Reader` and maintains an in-memory buffer of the results.
///
/// # Examples
///
/// ```
/// # #![feature(old_io, old_path)]
/// use std::old_io::*;
/// use std::old_path::Path;
///
/// let file = File::open(&Path::new("message.txt"));
/// let mut reader = BufferedReader::new(file);
///
/// let mut buf = [0; 100];
/// match reader.read(&mut buf) {
/// Ok(nread) => println!("Read {} bytes", nread),
/// Err(e) => println!("error reading: {}", e)
/// }
/// ```
pub struct BufferedReader<R> {
inner: R,
buf: Vec<u8>,
pos: usize,
cap: usize,
}
#[stable(feature = "rust1", since = "1.0.0")]
impl<R> fmt::Debug for BufferedReader<R> where R: fmt::Debug {
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
write!(fmt, "BufferedReader {{ reader: {:?}, buffer: {}/{} }}",
self.inner, self.cap - self.pos, self.buf.len())
}
}
impl<R: Reader> BufferedReader<R> {
/// Creates a new `BufferedReader` with the specified buffer capacity
pub fn with_capacity(cap: usize, inner: R) -> BufferedReader<R> {
BufferedReader {
inner: inner,
// We can't use the same trick here as we do for BufferedWriter,
// since this memory is visible to the inner Reader.
buf: repeat(0).take(cap).collect(),
pos: 0,
cap: 0,
}
}
/// Creates a new `BufferedReader` with a default buffer capacity
pub fn new(inner: R) -> BufferedReader<R> {
BufferedReader::with_capacity(DEFAULT_BUF_SIZE, inner)
}
/// Gets a reference to the underlying reader.
pub fn get_ref<'a>(&self) -> &R { &self.inner }
/// Gets a mutable reference to the underlying reader.
///
/// # Warning
///
/// It is inadvisable to directly read from the underlying reader.
pub fn get_mut(&mut self) -> &mut R { &mut self.inner }
/// Unwraps this `BufferedReader`, returning the underlying reader.
///
/// Note that any leftover data in the internal buffer is lost.
pub fn into_inner(self) -> R { self.inner }
}
impl<R: Reader> Buffer for BufferedReader<R> {
fn fill_buf<'a>(&'a mut self) -> IoResult<&'a [u8]> {
if self.pos == self.cap {
self.cap = try!(self.inner.read(&mut self.buf));
self.pos = 0;
}
Ok(&self.buf[self.pos..self.cap])
}
fn consume(&mut self, amt: usize) {
self.pos += amt;
assert!(self.pos <= self.cap);
}
}
impl<R: Reader> Reader for BufferedReader<R> {
fn read(&mut self, buf: &mut [u8]) -> IoResult<usize> {
if self.pos == self.cap && buf.len() >= self.buf.len() {
return self.inner.read(buf);
}
let nread = {
let available = try!(self.fill_buf());
let nread = cmp::min(available.len(), buf.len());
slice::bytes::copy_memory(&available[..nread], buf);
nread
};
self.pos += nread;
Ok(nread)
}
}
/// Wraps a Writer and buffers output to it
///
/// It can be excessively inefficient to work directly with a `Writer`. For
/// example, every call to `write` on `TcpStream` results in a system call. A
/// `BufferedWriter` keeps an in memory buffer of data and writes it to the
/// underlying `Writer` in large, infrequent batches.
///
/// This writer will be flushed when it is dropped.
///
/// # Examples
///
/// ```
/// # #![feature(old_io, old_path)]
/// use std::old_io::*;
/// use std::old_path::Path;
///
/// let file = File::create(&Path::new("message.txt")).unwrap();
/// let mut writer = BufferedWriter::new(file);
///
/// writer.write_str("hello, world").unwrap();
/// writer.flush().unwrap();
/// ```
pub struct BufferedWriter<W: Writer> {
inner: Option<W>,
buf: Vec<u8>,
pos: usize
}
#[stable(feature = "rust1", since = "1.0.0")]
impl<W: Writer> fmt::Debug for BufferedWriter<W> where W: fmt::Debug {
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
write!(fmt, "BufferedWriter {{ writer: {:?}, buffer: {}/{} }}",
self.inner.as_ref().unwrap(), self.pos, self.buf.len())
}
}
impl<W: Writer> BufferedWriter<W> {
/// Creates a new `BufferedWriter` with the specified buffer capacity
pub fn with_capacity(cap: usize, inner: W) -> BufferedWriter<W> {
// It's *much* faster to create an uninitialized buffer than it is to
// fill everything in with 0. This buffer is entirely an implementation
// detail and is never exposed, so we're safe to not initialize
// everything up-front. This allows creation of BufferedWriter instances
// to be very cheap (large mallocs are not nearly as expensive as large
// callocs).
let mut buf = Vec::with_capacity(cap);
unsafe { buf.set_len(cap); }
BufferedWriter {
inner: Some(inner),
buf: buf,
pos: 0
}
}
/// Creates a new `BufferedWriter` with a default buffer capacity
pub fn new(inner: W) -> BufferedWriter<W> {
BufferedWriter::with_capacity(DEFAULT_BUF_SIZE, inner)
}
fn flush_buf(&mut self) -> IoResult<()> {
if self.pos != 0 {
let ret = self.inner.as_mut().unwrap().write_all(&self.buf[..self.pos]);
self.pos = 0;
ret
} else {
Ok(())
}
}
/// Gets a reference to the underlying writer.
pub fn get_ref(&self) -> &W { self.inner.as_ref().unwrap() }
/// Gets a mutable reference to the underlying write.
///
/// # Warning
///
/// It is inadvisable to directly read from the underlying writer.
pub fn get_mut(&mut self) -> &mut W { self.inner.as_mut().unwrap() }
/// Unwraps this `BufferedWriter`, returning the underlying writer.
///
/// The buffer is flushed before returning the writer.
pub fn into_inner(mut self) -> W {
// FIXME(#12628): is panicking the right thing to do if flushing panicks?
self.flush_buf().unwrap();
self.inner.take().unwrap()
}
}
impl<W: Writer> Writer for BufferedWriter<W> {
fn write_all(&mut self, buf: &[u8]) -> IoResult<()> {
if self.pos + buf.len() > self.buf.len() {
try!(self.flush_buf());
}
if buf.len() > self.buf.len() {
self.inner.as_mut().unwrap().write_all(buf)
} else {
let dst = &mut self.buf[self.pos..];
slice::bytes::copy_memory(buf, dst);
self.pos += buf.len();
Ok(())
}
}
fn flush(&mut self) -> IoResult<()> {
self.flush_buf().and_then(|()| self.inner.as_mut().unwrap().flush())
}
}
#[unsafe_destructor]
impl<W: Writer> Drop for BufferedWriter<W> {
fn drop(&mut self) {
if self.inner.is_some() {
// dtors should not panic, so we ignore a panicked flush
let _ = self.flush_buf();
}
}
}
/// Wraps a Writer and buffers output to it, flushing whenever a newline (`0x0a`,
/// `'\n'`) is detected.
///
/// This writer will be flushed when it is dropped.
pub struct LineBufferedWriter<W: Writer> {
inner: BufferedWriter<W>,
}
#[stable(feature = "rust1", since = "1.0.0")]
impl<W: Writer> fmt::Debug for LineBufferedWriter<W> where W: fmt::Debug {
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
write!(fmt, "LineBufferedWriter {{ writer: {:?}, buffer: {}/{} }}",
self.inner.inner, self.inner.pos, self.inner.buf.len())
}
}
impl<W: Writer> LineBufferedWriter<W> {
/// Creates a new `LineBufferedWriter`
pub fn new(inner: W) -> LineBufferedWriter<W> {
// Lines typically aren't that long, don't use a giant buffer
LineBufferedWriter {
inner: BufferedWriter::with_capacity(1024, inner)
}
}
/// Gets a reference to the underlying writer.
///
/// This type does not expose the ability to get a mutable reference to the
/// underlying reader because that could possibly corrupt the buffer.
pub fn get_ref<'a>(&'a self) -> &'a W { self.inner.get_ref() }
/// Unwraps this `LineBufferedWriter`, returning the underlying writer.
///
/// The internal buffer is flushed before returning the writer.
pub fn into_inner(self) -> W { self.inner.into_inner() }
}
impl<W: Writer> Writer for LineBufferedWriter<W> {
fn write_all(&mut self, buf: &[u8]) -> IoResult<()> {
match buf.iter().rposition(|&b| b == b'\n') {
Some(i) => {
try!(self.inner.write_all(&buf[..i + 1]));
try!(self.inner.flush());
try!(self.inner.write_all(&buf[i + 1..]));
Ok(())
}
None => self.inner.write_all(buf),
}
}
fn flush(&mut self) -> IoResult<()> { self.inner.flush() }
}
struct InternalBufferedWriter<W: Writer>(BufferedWriter<W>);
impl<W: Writer> InternalBufferedWriter<W> {
fn get_mut<'a>(&'a mut self) -> &'a mut BufferedWriter<W> {
let InternalBufferedWriter(ref mut w) = *self;
return w;
}
}
impl<W: Reader + Writer> Reader for InternalBufferedWriter<W> {
fn read(&mut self, buf: &mut [u8]) -> IoResult<usize> {
self.get_mut().inner.as_mut().unwrap().read(buf)
}
}
/// Wraps a Stream and buffers input and output to and from it.
///
/// It can be excessively inefficient to work directly with a `Stream`. For
/// example, every call to `read` or `write` on `TcpStream` results in a system
/// call. A `BufferedStream` keeps in memory buffers of data, making large,
/// infrequent calls to `read` and `write` on the underlying `Stream`.
///
/// The output half will be flushed when this stream is dropped.
///
/// # Examples
///
/// ```
/// # #![feature(old_io, old_path)]
/// # #![allow(unused_must_use)]
/// use std::old_io::*;
/// use std::old_path::Path;
///
/// let file = File::open(&Path::new("message.txt"));
/// let mut stream = BufferedStream::new(file);
///
/// stream.write_all("hello, world".as_bytes());
/// stream.flush();
///
/// let mut buf = [0; 100];
/// match stream.read(&mut buf) {
/// Ok(nread) => println!("Read {} bytes", nread),
/// Err(e) => println!("error reading: {}", e)
/// }
/// ```
pub struct BufferedStream<S: Writer> {
inner: BufferedReader<InternalBufferedWriter<S>>
}
#[stable(feature = "rust1", since = "1.0.0")]
impl<S: Writer> fmt::Debug for BufferedStream<S> where S: fmt::Debug {
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
let reader = &self.inner;
let writer = &self.inner.inner.0;
write!(fmt, "BufferedStream {{ stream: {:?}, write_buffer: {}/{}, read_buffer: {}/{} }}",
writer.inner,
writer.pos, writer.buf.len(),
reader.cap - reader.pos, reader.buf.len())
}
}
impl<S: Stream> BufferedStream<S> {
/// Creates a new buffered stream with explicitly listed capacities for the
/// reader/writer buffer.
pub fn with_capacities(reader_cap: usize, writer_cap: usize, inner: S)
-> BufferedStream<S> {
let writer = BufferedWriter::with_capacity(writer_cap, inner);
let internal_writer = InternalBufferedWriter(writer);
let reader = BufferedReader::with_capacity(reader_cap,
internal_writer);
BufferedStream { inner: reader }
}
/// Creates a new buffered stream with the default reader/writer buffer
/// capacities.
pub fn new(inner: S) -> BufferedStream<S> {
BufferedStream::with_capacities(DEFAULT_BUF_SIZE, DEFAULT_BUF_SIZE,
inner)
}
/// Gets a reference to the underlying stream.
pub fn get_ref(&self) -> &S {
let InternalBufferedWriter(ref w) = self.inner.inner;
w.get_ref()
}
/// Gets a mutable reference to the underlying stream.
///
/// # Warning
///
/// It is inadvisable to read directly from or write directly to the
/// underlying stream.
pub fn get_mut(&mut self) -> &mut S {
let InternalBufferedWriter(ref mut w) = self.inner.inner;
w.get_mut()
}
/// Unwraps this `BufferedStream`, returning the underlying stream.
///
/// The internal buffer is flushed before returning the stream. Any leftover
/// data in the read buffer is lost.
pub fn into_inner(self) -> S {
let InternalBufferedWriter(w) = self.inner.inner;
w.into_inner()
}
}
impl<S: Stream> Buffer for BufferedStream<S> {
fn fill_buf<'a>(&'a mut self) -> IoResult<&'a [u8]> { self.inner.fill_buf() }
fn consume(&mut self, amt: usize) { self.inner.consume(amt) }
}
impl<S: Stream> Reader for BufferedStream<S> {
fn read(&mut self, buf: &mut [u8]) -> IoResult<usize> {
self.inner.read(buf)
}
}
impl<S: Stream> Writer for BufferedStream<S> {
fn write_all(&mut self, buf: &[u8]) -> IoResult<()> {
self.inner.inner.get_mut().write_all(buf)
}
fn flush(&mut self) -> IoResult<()> {
self.inner.inner.get_mut().flush()
}
}
#[cfg(test)]
mod test {
extern crate test;
use old_io::{self, Reader, Writer, Buffer, BufferPrelude};
use prelude::v1::*;
use super::*;
use super::super::{IoResult, EndOfFile};
use super::super::mem::MemReader;
use self::test::Bencher;
/// A type, free to create, primarily intended for benchmarking creation of
/// wrappers that, just for construction, don't need a Reader/Writer that
/// does anything useful. Is equivalent to `/dev/null` in semantics.
#[derive(Clone,PartialEq,PartialOrd)]
pub struct NullStream;
impl Reader for NullStream {
fn read(&mut self, _: &mut [u8]) -> old_io::IoResult<usize> {
Err(old_io::standard_error(old_io::EndOfFile))
}
}
impl Writer for NullStream {
fn write_all(&mut self, _: &[u8]) -> old_io::IoResult<()> { Ok(()) }
}
/// A dummy reader intended at testing short-reads propagation.
pub struct ShortReader {
lengths: Vec<usize>,
}
impl Reader for ShortReader {
fn read(&mut self, _: &mut [u8]) -> old_io::IoResult<usize> {
if self.lengths.is_empty() {
Err(old_io::standard_error(old_io::EndOfFile))
} else {
Ok(self.lengths.remove(0))
}
}
}
#[test]
fn test_buffered_reader() {
let inner = MemReader::new(vec!(5, 6, 7, 0, 1, 2, 3, 4));
let mut reader = BufferedReader::with_capacity(2, inner);
let mut buf = [0, 0, 0];
let nread = reader.read(&mut buf);
assert_eq!(Ok(3), nread);
let b: &[_] = &[5, 6, 7];
assert_eq!(buf, b);
let mut buf = [0, 0];
let nread = reader.read(&mut buf);
assert_eq!(Ok(2), nread);
let b: &[_] = &[0, 1];
assert_eq!(buf, b);
let mut buf = [0];
let nread = reader.read(&mut buf);
assert_eq!(Ok(1), nread);
let b: &[_] = &[2];
assert_eq!(buf, b);
let mut buf = [0, 0, 0];
let nread = reader.read(&mut buf);
assert_eq!(Ok(1), nread);
let b: &[_] = &[3, 0, 0];
assert_eq!(buf, b);
let nread = reader.read(&mut buf);
assert_eq!(Ok(1), nread);
let b: &[_] = &[4, 0, 0];
assert_eq!(buf, b);
assert!(reader.read(&mut buf).is_err());
}
#[test]
fn test_buffered_writer() {
let inner = Vec::new();
let mut writer = BufferedWriter::with_capacity(2, inner);
writer.write_all(&[0, 1]).unwrap();
let b: &[_] = &[];
assert_eq!(&writer.get_ref()[..], b);
writer.write_all(&[2]).unwrap();
let b: &[_] = &[0, 1];
assert_eq!(&writer.get_ref()[..], b);
writer.write_all(&[3]).unwrap();
assert_eq!(&writer.get_ref()[..], b);
writer.flush().unwrap();
let a: &[_] = &[0, 1, 2, 3];
assert_eq!(a, &writer.get_ref()[..]);
writer.write_all(&[4]).unwrap();
writer.write_all(&[5]).unwrap();
assert_eq!(a, &writer.get_ref()[..]);
writer.write_all(&[6]).unwrap();
let a: &[_] = &[0, 1, 2, 3, 4, 5];
assert_eq!(a, &writer.get_ref()[..]);
writer.write_all(&[7, 8]).unwrap();
let a: &[_] = &[0, 1, 2, 3, 4, 5, 6];
assert_eq!(a, &writer.get_ref()[..]);
writer.write_all(&[9, 10, 11]).unwrap();
let a: &[_] = &[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11];
assert_eq!(a, &writer.get_ref()[..]);
writer.flush().unwrap();
assert_eq!(a, &writer.get_ref()[..]);
}
#[test]
fn test_buffered_writer_inner_flushes() {
let mut w = BufferedWriter::with_capacity(3, Vec::new());
w.write_all(&[0, 1]).unwrap();
let a: &[_] = &[];
assert_eq!(&w.get_ref()[..], a);
let w = w.into_inner();
let a: &[_] = &[0, 1];
assert_eq!(a, &w[..]);
}
// This is just here to make sure that we don't infinite loop in the
// newtype struct autoderef weirdness
#[test]
fn test_buffered_stream() {
struct S;
impl old_io::Writer for S {
fn write_all(&mut self, _: &[u8]) -> old_io::IoResult<()> { Ok(()) }
}
impl old_io::Reader for S {
fn read(&mut self, _: &mut [u8]) -> old_io::IoResult<usize> {
Err(old_io::standard_error(old_io::EndOfFile))
}
}
let mut stream = BufferedStream::new(S);
let mut buf = [];
assert!(stream.read(&mut buf).is_err());
stream.write_all(&buf).unwrap();
stream.flush().unwrap();
}
#[test]
fn test_read_until() {
let inner = MemReader::new(vec!(0, 1, 2, 1, 0));
let mut reader = BufferedReader::with_capacity(2, inner);
assert_eq!(reader.read_until(0), Ok(vec!(0)));
assert_eq!(reader.read_until(2), Ok(vec!(1, 2)));
assert_eq!(reader.read_until(1), Ok(vec!(1)));
assert_eq!(reader.read_until(8), Ok(vec!(0)));
assert!(reader.read_until(9).is_err());
}
#[test]
fn test_line_buffer() {
let mut writer = LineBufferedWriter::new(Vec::new());
writer.write_all(&[0]).unwrap();
let b: &[_] = &[];
assert_eq!(&writer.get_ref()[..], b);
writer.write_all(&[1]).unwrap();
assert_eq!(&writer.get_ref()[..], b);
writer.flush().unwrap();
let b: &[_] = &[0, 1];
assert_eq!(&writer.get_ref()[..], b);
writer.write_all(&[0, b'\n', 1, b'\n', 2]).unwrap();
let b: &[_] = &[0, 1, 0, b'\n', 1, b'\n'];
assert_eq!(&writer.get_ref()[..], b);
writer.flush().unwrap();
let b: &[_] = &[0, 1, 0, b'\n', 1, b'\n', 2];
assert_eq!(&writer.get_ref()[..], b);
writer.write_all(&[3, b'\n']).unwrap();
let b: &[_] = &[0, 1, 0, b'\n', 1, b'\n', 2, 3, b'\n'];
assert_eq!(&writer.get_ref()[..], b);
}
#[test]
fn test_read_line() {
let in_buf = MemReader::new(b"a\nb\nc".to_vec());
let mut reader = BufferedReader::with_capacity(2, in_buf);
assert_eq!(reader.read_line(), Ok("a\n".to_string()));
assert_eq!(reader.read_line(), Ok("b\n".to_string()));
assert_eq!(reader.read_line(), Ok("c".to_string()));
assert!(reader.read_line().is_err());
}
#[test]
fn test_lines() {
let in_buf = MemReader::new(b"a\nb\nc".to_vec());
let mut reader = BufferedReader::with_capacity(2, in_buf);
let mut it = reader.lines();
assert_eq!(it.next(), Some(Ok("a\n".to_string())));
assert_eq!(it.next(), Some(Ok("b\n".to_string())));
assert_eq!(it.next(), Some(Ok("c".to_string())));
assert_eq!(it.next(), None);
}
#[test]
fn test_short_reads() {
let inner = ShortReader{lengths: vec![0, 1, 2, 0, 1, 0]};
let mut reader = BufferedReader::new(inner);
let mut buf = [0, 0];
assert_eq!(reader.read(&mut buf), Ok(0));
assert_eq!(reader.read(&mut buf), Ok(1));
assert_eq!(reader.read(&mut buf), Ok(2));
assert_eq!(reader.read(&mut buf), Ok(0));
assert_eq!(reader.read(&mut buf), Ok(1));
assert_eq!(reader.read(&mut buf), Ok(0));
assert!(reader.read(&mut buf).is_err());
}
#[test]
fn read_char_buffered() {
let buf = [195, 159];
let mut reader = BufferedReader::with_capacity(1, &buf[..]);
assert_eq!(reader.read_char(), Ok('ß'));
}
#[test]
fn test_chars() {
let buf = [195, 159, b'a'];
let mut reader = BufferedReader::with_capacity(1, &buf[..]);
let mut it = reader.chars();
assert_eq!(it.next(), Some(Ok('ß')));
assert_eq!(it.next(), Some(Ok('a')));
assert_eq!(it.next(), None);
}
#[test]
#[should_panic]
fn dont_panic_in_drop_on_panicked_flush() {
struct FailFlushWriter;
impl Writer for FailFlushWriter {
fn write_all(&mut self, _buf: &[u8]) -> IoResult<()> { Ok(()) }
fn flush(&mut self) -> IoResult<()> { Err(old_io::standard_error(EndOfFile)) }
}
let writer = FailFlushWriter;
let _writer = BufferedWriter::new(writer);
// If writer panics *again* due to the flush error then the process will abort.
panic!();
}
#[bench]
fn bench_buffered_reader(b: &mut Bencher) {
b.iter(|| {
BufferedReader::new(NullStream)
});
}
#[bench]
fn bench_buffered_writer(b: &mut Bencher) {
b.iter(|| {
BufferedWriter::new(NullStream)
});
}
#[bench]
fn bench_buffered_stream(b: &mut Bencher) {
b.iter(|| {
BufferedStream::new(NullStream);
});
}
}

View File

@ -1,247 +0,0 @@
// Copyright 2013 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.
use clone::Clone;
use cmp;
use sync::mpsc::{Sender, Receiver};
use old_io;
use option::Option::{None, Some};
use result::Result::{Ok, Err};
use slice::bytes;
use super::{Buffer, Reader, Writer, IoResult};
use vec::Vec;
/// Allows reading from a rx.
///
/// # Examples
///
/// ```
/// # #![feature(old_io)]
/// use std::sync::mpsc::channel;
/// use std::old_io::*;
///
/// let (tx, rx) = channel();
/// # drop(tx);
/// let mut reader = ChanReader::new(rx);
///
/// let mut buf = [0; 100];
/// match reader.read(&mut buf) {
/// Ok(nread) => println!("Read {} bytes", nread),
/// Err(e) => println!("read error: {}", e),
/// }
/// ```
pub struct ChanReader {
buf: Vec<u8>, // A buffer of bytes received but not consumed.
pos: usize, // How many of the buffered bytes have already be consumed.
rx: Receiver<Vec<u8>>, // The Receiver to pull data from.
closed: bool, // Whether the channel this Receiver connects to has been closed.
}
impl ChanReader {
/// Wraps a `Port` in a `ChanReader` structure
pub fn new(rx: Receiver<Vec<u8>>) -> ChanReader {
ChanReader {
buf: Vec::new(),
pos: 0,
rx: rx,
closed: false,
}
}
}
impl Buffer for ChanReader {
fn fill_buf<'a>(&'a mut self) -> IoResult<&'a [u8]> {
if self.pos >= self.buf.len() {
self.pos = 0;
match self.rx.recv() {
Ok(bytes) => {
self.buf = bytes;
},
Err(..) => {
self.closed = true;
self.buf = Vec::new();
}
}
}
if self.closed {
Err(old_io::standard_error(old_io::EndOfFile))
} else {
Ok(&self.buf[self.pos..])
}
}
fn consume(&mut self, amt: usize) {
self.pos += amt;
assert!(self.pos <= self.buf.len());
}
}
impl Reader for ChanReader {
fn read(&mut self, buf: &mut [u8]) -> IoResult<usize> {
let mut num_read = 0;
loop {
let count = match self.fill_buf().ok() {
Some(src) => {
let dst = &mut buf[num_read..];
let count = cmp::min(src.len(), dst.len());
bytes::copy_memory(&src[..count], dst);
count
},
None => 0,
};
self.consume(count);
num_read += count;
if num_read == buf.len() || self.closed {
break;
}
}
if self.closed && num_read == 0 {
Err(old_io::standard_error(old_io::EndOfFile))
} else {
Ok(num_read)
}
}
}
/// Allows writing to a tx.
///
/// # Examples
///
/// ```
/// # #![feature(old_io, io)]
/// # #![allow(unused_must_use)]
/// use std::sync::mpsc::channel;
/// use std::old_io::*;
///
/// let (tx, rx) = channel();
/// # drop(rx);
/// let mut writer = ChanWriter::new(tx);
/// writer.write("hello, world".as_bytes());
/// ```
pub struct ChanWriter {
tx: Sender<Vec<u8>>,
}
impl ChanWriter {
/// Wraps a channel in a `ChanWriter` structure
pub fn new(tx: Sender<Vec<u8>>) -> ChanWriter {
ChanWriter { tx: tx }
}
}
#[stable(feature = "rust1", since = "1.0.0")]
impl Clone for ChanWriter {
fn clone(&self) -> ChanWriter {
ChanWriter { tx: self.tx.clone() }
}
}
impl Writer for ChanWriter {
fn write_all(&mut self, buf: &[u8]) -> IoResult<()> {
self.tx.send(buf.to_vec()).map_err(|_| {
old_io::IoError {
kind: old_io::BrokenPipe,
desc: "Pipe closed",
detail: None
}
})
}
}
#[cfg(test)]
mod test {
use prelude::v1::*;
use sync::mpsc::channel;
use super::*;
use old_io::{self, Reader, Writer, Buffer};
use thread;
#[test]
fn test_rx_reader() {
let (tx, rx) = channel();
thread::spawn(move|| {
tx.send(vec![1, 2]).unwrap();
tx.send(vec![]).unwrap();
tx.send(vec![3, 4]).unwrap();
tx.send(vec![5, 6]).unwrap();
tx.send(vec![7, 8]).unwrap();
});
let mut reader = ChanReader::new(rx);
let mut buf = [0; 3];
assert_eq!(Ok(0), reader.read(&mut []));
assert_eq!(Ok(3), reader.read(&mut buf));
let a: &[u8] = &[1,2,3];
assert_eq!(a, buf);
assert_eq!(Ok(3), reader.read(&mut buf));
let a: &[u8] = &[4,5,6];
assert_eq!(a, buf);
assert_eq!(Ok(2), reader.read(&mut buf));
let a: &[u8] = &[7,8,6];
assert_eq!(a, buf);
match reader.read(&mut buf) {
Ok(..) => panic!(),
Err(e) => assert_eq!(e.kind, old_io::EndOfFile),
}
assert_eq!(a, buf);
// Ensure it continues to panic in the same way.
match reader.read(&mut buf) {
Ok(..) => panic!(),
Err(e) => assert_eq!(e.kind, old_io::EndOfFile),
}
assert_eq!(a, buf);
}
#[test]
fn test_rx_buffer() {
let (tx, rx) = channel();
thread::spawn(move|| {
tx.send(b"he".to_vec()).unwrap();
tx.send(b"llo wo".to_vec()).unwrap();
tx.send(b"".to_vec()).unwrap();
tx.send(b"rld\nhow ".to_vec()).unwrap();
tx.send(b"are you?".to_vec()).unwrap();
tx.send(b"".to_vec()).unwrap();
});
let mut reader = ChanReader::new(rx);
assert_eq!(Ok("hello world\n".to_string()), reader.read_line());
assert_eq!(Ok("how are you?".to_string()), reader.read_line());
match reader.read_line() {
Ok(..) => panic!(),
Err(e) => assert_eq!(e.kind, old_io::EndOfFile),
}
}
#[test]
fn test_chan_writer() {
let (tx, rx) = channel();
let mut writer = ChanWriter::new(tx);
writer.write_be_u32(42).unwrap();
let wanted = vec![0, 0, 0, 42];
let got = thread::scoped(move|| { rx.recv().unwrap() }).join();
assert_eq!(wanted, got);
match writer.write_u8(1) {
Ok(..) => panic!(),
Err(e) => assert_eq!(e.kind, old_io::BrokenPipe),
}
}
}

Some files were not shown because too many files have changed in this diff Show More