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

This commit is contained in:
bors 2015-03-24 17:38:09 +00:00
commit ed81038504
1977 changed files with 7620 additions and 1908 deletions

15
configure vendored
View file

@ -479,10 +479,19 @@ esac
# Detect 64 bit linux systems with 32 bit userland and force 32 bit compilation
if [ $CFG_OSTYPE = unknown-linux-gnu -a $CFG_CPUTYPE = x86_64 ]
then
file -L "$SHELL" | grep -q "x86[_-]64"
if [ $? != 0 ]; then
CFG_CPUTYPE=i686
# $SHELL does not exist in standard 'sh', so probably only exists
# if configure is running in an interactive bash shell. /usr/bin/env
# exists *everywhere*.
BIN_TO_PROBE="$SHELL"
if [ -z "$BIN_TO_PROBE" -a -e "/usr/bin/env" ]; then
BIN_TO_PROBE="/usr/bin/env"
fi
if [ -n "$BIN_TO_PROBE" ]; then
file -L "$BIN_TO_PROBE" | grep -q "x86[_-]64"
if [ $? != 0 ]; then
CFG_CPUTYPE=i686
fi
fi
fi

View file

@ -20,6 +20,8 @@
#![feature(std_misc)]
#![feature(test)]
#![feature(path_ext)]
#![feature(convert)]
#![feature(str_char)]
#![deny(warnings)]
@ -115,7 +117,7 @@ pub fn parse_config(args: Vec<String> ) -> Config {
fn opt_path(m: &getopts::Matches, nm: &str) -> PathBuf {
match m.opt_str(nm) {
Some(s) => PathBuf::new(&s),
Some(s) => PathBuf::from(&s),
None => panic!("no option (=path) found for {}", nm),
}
}
@ -130,10 +132,10 @@ pub fn parse_config(args: Vec<String> ) -> Config {
compile_lib_path: matches.opt_str("compile-lib-path").unwrap(),
run_lib_path: matches.opt_str("run-lib-path").unwrap(),
rustc_path: opt_path(matches, "rustc-path"),
clang_path: matches.opt_str("clang-path").map(|s| PathBuf::new(&s)),
clang_path: matches.opt_str("clang-path").map(|s| PathBuf::from(&s)),
valgrind_path: matches.opt_str("valgrind-path"),
force_valgrind: matches.opt_present("force-valgrind"),
llvm_bin_path: matches.opt_str("llvm-bin-path").map(|s| PathBuf::new(&s)),
llvm_bin_path: matches.opt_str("llvm-bin-path").map(|s| PathBuf::from(&s)),
src_base: opt_path(matches, "src-base"),
build_base: opt_path(matches, "build-base"),
aux_base: opt_path(matches, "aux-base"),
@ -141,7 +143,7 @@ pub fn parse_config(args: Vec<String> ) -> Config {
mode: matches.opt_str("mode").unwrap().parse().ok().expect("invalid mode"),
run_ignored: matches.opt_present("ignored"),
filter: filter,
logfile: matches.opt_str("logfile").map(|s| PathBuf::new(&s)),
logfile: matches.opt_str("logfile").map(|s| PathBuf::from(&s)),
runtool: matches.opt_str("runtool"),
host_rustcflags: matches.opt_str("host-rustcflags"),
target_rustcflags: matches.opt_str("target-rustcflags"),

View file

@ -40,8 +40,8 @@ pub struct TestProps {
pub check_stdout: bool,
// Don't force a --crate-type=dylib flag on the command line
pub no_prefer_dynamic: bool,
// Don't run --pretty expanded when running pretty printing tests
pub no_pretty_expanded: bool,
// Run --pretty expanded when running pretty printing tests
pub pretty_expanded: bool,
// Which pretty mode are we testing with, default to 'normal'
pub pretty_mode: String,
// Only compare pretty output and don't try compiling
@ -62,7 +62,7 @@ pub fn load_props(testfile: &Path) -> TestProps {
let mut force_host = false;
let mut check_stdout = false;
let mut no_prefer_dynamic = false;
let mut no_pretty_expanded = false;
let mut pretty_expanded = false;
let mut pretty_mode = None;
let mut pretty_compare_only = false;
let mut forbid_output = Vec::new();
@ -96,8 +96,8 @@ pub fn load_props(testfile: &Path) -> TestProps {
no_prefer_dynamic = parse_no_prefer_dynamic(ln);
}
if !no_pretty_expanded {
no_pretty_expanded = parse_no_pretty_expanded(ln);
if !pretty_expanded {
pretty_expanded = parse_pretty_expanded(ln);
}
if pretty_mode.is_none() {
@ -152,7 +152,7 @@ pub fn load_props(testfile: &Path) -> TestProps {
force_host: force_host,
check_stdout: check_stdout,
no_prefer_dynamic: no_prefer_dynamic,
no_pretty_expanded: no_pretty_expanded,
pretty_expanded: pretty_expanded,
pretty_mode: pretty_mode.unwrap_or("normal".to_string()),
pretty_compare_only: pretty_compare_only,
forbid_output: forbid_output,
@ -295,8 +295,8 @@ fn parse_no_prefer_dynamic(line: &str) -> bool {
parse_name_directive(line, "no-prefer-dynamic")
}
fn parse_no_pretty_expanded(line: &str) -> bool {
parse_name_directive(line, "no-pretty-expanded")
fn parse_pretty_expanded(line: &str) -> bool {
parse_name_directive(line, "pretty-expanded")
}
fn parse_pretty_mode(line: &str) -> Option<String> {
@ -328,10 +328,10 @@ fn parse_exec_env(line: &str) -> Option<(String, String)> {
fn parse_pp_exact(line: &str, testfile: &Path) -> Option<PathBuf> {
match parse_name_value_directive(line, "pp-exact") {
Some(s) => Some(PathBuf::new(&s)),
Some(s) => Some(PathBuf::from(&s)),
None => {
if parse_name_directive(line, "pp-exact") {
testfile.file_name().map(|s| PathBuf::new(s))
testfile.file_name().map(|s| PathBuf::from(s))
} else {
None
}
@ -340,7 +340,8 @@ fn parse_pp_exact(line: &str, testfile: &Path) -> Option<PathBuf> {
}
fn parse_name_directive(line: &str, directive: &str) -> bool {
line.contains(directive)
// This 'no-' rule is a quick hack to allow pretty-expanded and no-pretty-expanded to coexist
line.contains(directive) && !line.contains(&("no-".to_string() + directive))
}
pub fn parse_name_value_directive(line: &str, directive: &str)

View file

@ -245,7 +245,7 @@ fn run_pretty_test(config: &Config, props: &TestProps, testfile: &Path) {
if !proc_res.status.success() {
fatal_proc_rec("pretty-printed source does not typecheck", &proc_res);
}
if props.no_pretty_expanded { return }
if !props.pretty_expanded { return }
// additionally, run `--pretty expanded` and try to build it.
let proc_res = print_source(config, props, testfile, srcs[round].clone(), "expanded");
@ -1440,7 +1440,7 @@ fn aux_output_dir_name(config: &Config, testfile: &Path) -> PathBuf {
}
fn output_testname(testfile: &Path) -> PathBuf {
PathBuf::new(testfile.file_stem().unwrap())
PathBuf::from(testfile.file_stem().unwrap())
}
fn output_base_name(config: &Config, testfile: &Path) -> PathBuf {

View file

@ -446,16 +446,16 @@ It gives us this error:
error: aborting due to previous error
```
It mentions that "captured outer variable in an `FnMut` closure".
Because we declared the closure as a moving closure, and it referred
to `numbers`, the closure will try to take ownership of the
vector. But the closure itself is created in a loop, and hence we will
actually create three closures, one for every iteration of the
loop. This means that all three of those closures would try to own
`numbers`, which is impossible -- `numbers` must have just one
owner. Rust detects this and gives us the error: we claim that
`numbers` has ownership, but our code tries to make three owners. This
may cause a safety problem, so Rust disallows it.
This is a little confusing because there are two closures here: the one passed
to `map`, and the one passed to `thread::scoped`. In this case, the closure for
`thread::scoped` is attempting to reference `numbers`, a `Vec<i32>`. This
closure is a `FnOnce` closure, as thats what `thread::scoped` takes as an
argument. `FnOnce` closures take ownership of their environment. Thats fine,
but theres one detail: because of `map`, were going to make three of these
closures. And since all three try to take ownership of `numbers`, that would be
a problem. Thats what it means by cannot move out of captured outer
variable: our `thread::scoped` closure wants to take ownership, and it cant,
because the closure for `map` wont let it.
What to do here? Rust has two types that helps us: `Arc<T>` and `Mutex<T>`.
*Arc* stands for "atomically reference counted". In other words, an Arc will

View file

@ -816,8 +816,7 @@ may optionally begin with any number of `attributes` that apply to the
containing module. Attributes on the anonymous crate module define important
metadata that influences the behavior of the compiler.
```{.rust}
# #![allow(unused_attribute)]
```no_run
// Crate name
#![crate_name = "projx"]
@ -1020,6 +1019,7 @@ Use declarations support a number of convenient shortcuts:
An example of `use` declarations:
```
# #![feature(core)]
use std::iter::range_step;
use std::option::Option::{Some, None};
use std::collections::hash_map::{self, HashMap};
@ -1080,6 +1080,7 @@ declarations.
An example of what will and will not work for `use` items:
```
# #![feature(core)]
# #![allow(unused_imports)]
use foo::core::iter; // good: foo is at the root of the crate
use foo::baz::foobaz; // good: foo is at the root of the crate
@ -1781,6 +1782,7 @@ functions, with the exception that they may not have a body and are instead
terminated by a semicolon.
```
# #![feature(libc)]
extern crate libc;
use libc::{c_char, FILE};

View file

@ -47,7 +47,7 @@ This pattern is very powerful, and we'll see it repeated more later.
There are also a few things you can do with a tuple as a whole, without
destructuring. You can assign one tuple into another, if they have the same
contained types and arity. Tuples have the same arity when they have the same
contained types and [arity]. Tuples have the same arity when they have the same
length.
```rust
@ -196,8 +196,9 @@ Now, we have actual names, rather than positions. Good names are important,
and with a struct, we have actual names.
There _is_ one case when a tuple struct is very useful, though, and that's a
tuple struct with only one element. We call this a *newtype*, because it lets
you create a new type that's similar to another one:
tuple struct with only one element. We call this the *newtype* pattern, because
it allows you to create a new type, distinct from that of its contained value
and expressing its own semantic meaning:
```{rust}
struct Inches(i32);
@ -216,7 +217,7 @@ destructuring `let`, as we discussed previously in 'tuples.' In this case, the
Finally, Rust has a "sum type", an *enum*. Enums are an incredibly useful
feature of Rust, and are used throughout the standard library. An `enum` is
a type which ties a set of alternates to a specific name. For example, below
a type which relates a set of alternates to a specific name. For example, below
we define `Character` to be either a `Digit` or something else. These
can be used via their fully scoped names: `Character::Other` (more about `::`
below).
@ -228,8 +229,8 @@ enum Character {
}
```
An `enum` variant can be defined as most normal types. Below are some example
types which also would be allowed in an `enum`.
Most normal types are allowed as the variant components of an `enum`. Here are
some examples:
```rust
struct Empty;
@ -239,15 +240,15 @@ struct Status { Health: i32, Mana: i32, Attack: i32, Defense: i32 }
struct HeightDatabase(Vec<i32>);
```
So you see that depending on the sub-datastructure, the `enum` variant, same as
a struct, may or may not hold data. That is, in `Character`, `Digit` is a name
tied to an `i32` where `Other` is just a name. However, the fact that they are
distinct makes this very useful.
You see that, depending on its type, an `enum` variant may or may not hold data.
In `Character`, for instance, `Digit` gives a meaningful name for an `i32`
value, where `Other` is only a name. However, the fact that they represent
distinct categories of `Character` is a very useful property.
As with structures, enums don't by default have access to operators such as
compare ( `==` and `!=`), binary operations (`*` and `+`), and order
(`<` and `>=`). As such, using the previous `Character` type, the
following code is invalid:
As with structures, the variants of an enum by default are not comparable with
equality operators (`==`, `!=`), have no ordering (`<`, `>=`, etc.), and do not
support other binary operations such as `*` and `+`. As such, the following code
is invalid for the example `Character` type:
```{rust,ignore}
// These assignments both succeed
@ -265,9 +266,10 @@ let four_equals_ten = four == ten;
```
This may seem rather limiting, but it's a limitation which we can overcome.
There are two ways: by implementing equality ourselves, or by using the
[`match`][match] keyword. We don't know enough about Rust to implement equality
yet, but we can use the `Ordering` enum from the standard library, which does:
There are two ways: by implementing equality ourselves, or by pattern matching
variants with [`match`][match] expressions, which you'll learn in the next
chapter. We don't know enough about Rust to implement equality yet, but we can
use the `Ordering` enum from the standard library, which does:
```
enum Ordering {
@ -277,9 +279,8 @@ enum Ordering {
}
```
Because we did not define `Ordering`, we must import it (from the std
library) with the `use` keyword. Here's an example of how `Ordering` is
used:
Because `Ordering` has already been defined for us, we will import it with the
`use` keyword. Here's an example of how it is used:
```{rust}
use std::cmp::Ordering;
@ -313,17 +314,17 @@ the standard library if you need them.
Okay, let's talk about the actual code in the example. `cmp` is a function that
compares two things, and returns an `Ordering`. We return either
`Ordering::Less`, `Ordering::Greater`, or `Ordering::Equal`, depending on if
the two values are less, greater, or equal. Note that each variant of the
`enum` is namespaced under the `enum` itself: it's `Ordering::Greater` not
`Greater`.
`Ordering::Less`, `Ordering::Greater`, or `Ordering::Equal`, depending on
whether the first value is less than, greater than, or equal to the second. Note
that each variant of the `enum` is namespaced under the `enum` itself: it's
`Ordering::Greater`, not `Greater`.
The `ordering` variable has the type `Ordering`, and so contains one of the
three values. We then do a bunch of `if`/`else` comparisons to check which
one it is.
This `Ordering::Greater` notation is too long. Let's use `use` to import the
`enum` variants instead. This will avoid full scoping:
This `Ordering::Greater` notation is too long. Let's use another form of `use`
to import the `enum` variants instead. This will avoid full scoping:
```{rust}
use std::cmp::Ordering::{self, Equal, Less, Greater};
@ -347,16 +348,18 @@ fn main() {
```
Importing variants is convenient and compact, but can also cause name conflicts,
so do this with caution. It's considered good style to rarely import variants
for this reason.
so do this with caution. For this reason, it's normally considered better style
to `use` an enum rather than its variants directly.
As you can see, `enum`s are quite a powerful tool for data representation, and are
even more useful when they're [generic][generics] across types. Before we
get to generics, though, let's talk about how to use them with pattern matching, a
tool that will let us deconstruct this sum type (the type theory term for enums)
in a very elegant way and avoid all these messy `if`/`else`s.
As you can see, `enum`s are quite a powerful tool for data representation, and
are even more useful when they're [generic][generics] across types. Before we
get to generics, though, let's talk about how to use enums with pattern
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
and brittle `if`/`else`s.
[arity]: ./glossary.html#arity
[match]: ./match.html
[game]: ./guessing-game.html#comparing-guesses
[generics]: ./generics.html

View file

@ -40,14 +40,14 @@ us enforce that it can't leave the current thread.
### `Sync`
The second of these two trait is called [`Sync`](../std/marker/trait.Sync.html).
The second of these traits is called [`Sync`](../std/marker/trait.Sync.html).
When a type `T` implements `Sync`, it indicates to the compiler that something
of this type has no possibility of introducing memory unsafety when used from
multiple threads concurrently.
For example, sharing immutable data with an atomic reference count is
threadsafe. Rust provides a type like this, `Arc<T>`, and it implements `Sync`,
so that it could be safely shared between threads.
so it is safe to share between threads.
These two traits allow you to use the type system to make strong guarantees
about the properties of your code under concurrency. Before we demonstrate
@ -69,7 +69,7 @@ fn main() {
}
```
The `Thread::scoped()` method accepts a closure, which is executed in a new
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:
```
@ -88,6 +88,7 @@ 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()`:
```
# #![feature(old_io, std_misc)]
use std::thread;
use std::old_io::timer;
use std::time::Duration;
@ -146,6 +147,7 @@ As an example, here is a Rust program that would have a data race in many
languages. It will not compile:
```ignore
# #![feature(old_io, std_misc)]
use std::thread;
use std::old_io::timer;
use std::time::Duration;
@ -185,6 +187,7 @@ only one person at a time can mutate what's inside. For that, we can use the
but for a different reason:
```ignore
# #![feature(old_io, std_misc)]
use std::thread;
use std::old_io::timer;
use std::time::Duration;
@ -208,10 +211,10 @@ Here's the error:
```text
<anon>:11:9: 11:22 error: the trait `core::marker::Send` is not implemented for the type `std::sync::mutex::MutexGuard<'_, collections::vec::Vec<u32>>` [E0277]
<anon>:11 Thread::spawn(move || {
<anon>:11 thread::spawn(move || {
^~~~~~~~~~~~~
<anon>:11:9: 11:22 note: `std::sync::mutex::MutexGuard<'_, collections::vec::Vec<u32>>` cannot be sent between threads safely
<anon>:11 Thread::spawn(move || {
<anon>:11 thread::spawn(move || {
^~~~~~~~~~~~~
```
@ -229,6 +232,7 @@ guard across thread boundaries, which gives us our error.
We can use `Arc<T>` to fix this. Here's the working version:
```
# #![feature(old_io, std_misc)]
use std::sync::{Arc, Mutex};
use std::thread;
use std::old_io::timer;
@ -254,6 +258,7 @@ handle is then moved into the new thread. Let's examine the body of the
thread more closely:
```
# #![feature(old_io, std_misc)]
# use std::sync::{Arc, Mutex};
# use std::thread;
# use std::old_io::timer;
@ -322,7 +327,6 @@ While this channel is just sending a generic signal, we can send any data that
is `Send` over the channel!
```
use std::sync::{Arc, Mutex};
use std::thread;
use std::sync::mpsc;

View file

@ -1,6 +1,6 @@
% Crates and Modules
When a project starts getting large, it's considered a good software
When a project starts getting large, it's considered good software
engineering practice to split it up into a bunch of smaller pieces, and then
fit them together. It's also important to have a well-defined interface, so
that some of your functionality is private, and some is public. To facilitate
@ -24,23 +24,23 @@ in different languages. To keep things simple, we'll stick to "greetings" and
two languages for those phrases to be in. We'll use this module layout:
```text
+-----------+
+---| greetings |
| +-----------+
+---------+ |
| english |---+
+---------+ | +-----------+
| +---| farewells |
+---------+ | +-----------+
+-----------+
+---| greetings |
| +-----------+
+---------+ |
+---| english |---+
| +---------+ | +-----------+
| +---| farewells |
+---------+ | +-----------+
| phrases |---+
+---------+ | +-----------+
| +---| greetings |
+----------+ | +-----------+
| japanese |---+
+----------+ |
| +-----------+
+---| farewells |
+-----------+
+---------+ | +-----------+
| +---| greetings |
| +----------+ | +-----------+
+---| japanese |--+
+----------+ |
| +-----------+
+---| farewells |
+-----------+
```
In this example, `phrases` is the name of our crate. All of the rest are
@ -76,25 +76,19 @@ To define each of our modules, we use the `mod` keyword. Let's make our
`src/lib.rs` look like this:
```
// in src/lib.rs
mod english {
mod greetings {
}
mod farewells {
}
}
mod japanese {
mod greetings {
}
mod farewells {
}
}
```
@ -145,11 +139,7 @@ mod english;
```
If we do that, Rust will expect to find either a `english.rs` file, or a
`english/mod.rs` file with the contents of our module:
```{rust,ignore}
// contents of our module go here
```
`english/mod.rs` file with the contents of our module.
Note that in these files, you don't need to re-declare the module: that's
already been done with the initial `mod` declaration.
@ -181,10 +171,7 @@ $ tree .
`src/lib.rs` is our crate root, and looks like this:
```{rust,ignore}
// in src/lib.rs
mod english;
mod japanese;
```
@ -195,10 +182,7 @@ chosen the second. Both `src/english/mod.rs` and `src/japanese/mod.rs` look
like this:
```{rust,ignore}
// both src/english/mod.rs and src/japanese/mod.rs
mod greetings;
mod farewells;
```
@ -214,8 +198,6 @@ both empty at the moment. Let's add some functions.
Put this in `src/english/greetings.rs`:
```rust
// in src/english/greetings.rs
fn hello() -> String {
"Hello!".to_string()
}
@ -224,8 +206,6 @@ fn hello() -> String {
Put this in `src/english/farewells.rs`:
```rust
// in src/english/farewells.rs
fn goodbye() -> String {
"Goodbye.".to_string()
}
@ -248,8 +228,6 @@ about the module system.
Put this in `src/japanese/farewells.rs`:
```rust
// in src/japanese/farewells.rs
fn goodbye() -> String {
"さようなら".to_string()
}
@ -265,11 +243,9 @@ another crate.
We have a library crate. Let's make an executable crate that imports and uses
our library.
Make a `src/main.rs` and put this in it: (it won't quite compile yet)
Make a `src/main.rs` and put this in it (it won't quite compile yet):
```rust,ignore
// in src/main.rs
extern crate phrases;
fn main() {
@ -320,8 +296,6 @@ keyword. Let's focus on the `english` module first, so let's reduce our `src/mai
to just this:
```{rust,ignore}
// in src/main.rs
extern crate phrases;
fn main() {
@ -333,28 +307,20 @@ fn main() {
In our `src/lib.rs`, let's add `pub` to the `english` module declaration:
```{rust,ignore}
// in src/lib.rs
pub mod english;
mod japanese;
```
And in our `src/english/mod.rs`, let's make both `pub`:
```{rust,ignore}
// in src/english/mod.rs
pub mod greetings;
pub mod farewells;
```
In our `src/english/greetings.rs`, let's add `pub` to our `fn` declaration:
```{rust,ignore}
// in src/english/greetings.rs
pub fn hello() -> String {
"Hello!".to_string()
}
@ -363,8 +329,6 @@ pub fn hello() -> String {
And also in `src/english/farewells.rs`:
```{rust,ignore}
// in src/english/farewells.rs
pub fn goodbye() -> String {
"Goodbye.".to_string()
}
@ -400,8 +364,6 @@ Rust has a `use` keyword, which allows us to import names into our local scope.
Let's change our `src/main.rs` to look like this:
```{rust,ignore}
// in src/main.rs
extern crate phrases;
use phrases::english::greetings;
@ -430,7 +392,7 @@ fn main() {
}
```
But it is not idiomatic. This is significantly more likely to introducing a
But it is not idiomatic. This is significantly more likely to introduce a
naming conflict. In our short program, it's not a big deal, but as it grows, it
becomes a problem. If we have conflicting names, Rust will give a compilation
error. For example, if we made the `japanese` functions public, and tried to do
@ -460,21 +422,19 @@ Could not compile `phrases`.
```
If we're importing multiple names from the same module, we don't have to type it out
twice. Rust has a shortcut syntax for writing this:
twice. Instead of this:
```{rust,ignore}
use phrases::english::greetings;
use phrases::english::farewells;
```
You use curly braces:
We can use this shortcut:
```{rust,ignore}
use phrases::english::{greetings, farewells};
```
These two declarations are equivalent, but the second is a lot less typing.
## Re-exporting with `pub use`
You don't just use `use` to shorten identifiers. You can also use it inside of your crate
@ -484,8 +444,6 @@ interface that may not directly map to your internal code organization.
Let's look at an example. Modify your `src/main.rs` to read like this:
```{rust,ignore}
// in src/main.rs
extern crate phrases;
use phrases::english::{greetings,farewells};
@ -503,18 +461,13 @@ fn main() {
Then, modify your `src/lib.rs` to make the `japanese` mod public:
```{rust,ignore}
// in src/lib.rs
pub mod english;
pub mod japanese;
```
Next, make the two functions public, first in `src/japanese/greetings.rs`:
```{rust,ignore}
// in src/japanese/greetings.rs
pub fn hello() -> String {
"こんにちは".to_string()
}
@ -523,8 +476,6 @@ pub fn hello() -> String {
And then in `src/japanese/farewells.rs`:
```{rust,ignore}
// in src/japanese/farewells.rs
pub fn goodbye() -> String {
"さようなら".to_string()
}
@ -533,13 +484,10 @@ pub fn goodbye() -> String {
Finally, modify your `src/japanese/mod.rs` to read like this:
```{rust,ignore}
// in src/japanese/mod.rs
pub use self::greetings::hello;
pub use self::farewells::goodbye;
mod greetings;
mod farewells;
```

View file

@ -237,14 +237,17 @@ fn main() {
}
```
Here's the full algorithm:
Here's the full algorithm rustdoc uses to postprocess examples:
1. Given a code block, if it does not contain `fn main()`, it is wrapped in
`fn main() { your_code }`
2. Given that result, if it contains no `extern crate` directives but it also
contains the name of the crate being tested, then `extern crate <name>` is
injected at the top.
3. Some common allow attributes are added for documentation examples at the top.
1. Any leading `#![foo]` attributes are left intact as crate attributes.
2. Some common `allow` attributes are inserted, including
`unused_variables`, `unused_assignments`, `unused_mut`,
`unused_attributes`, and `dead_code`. Small examples often trigger
these lints.
3. If the example does not contain `extern crate`, then `extern crate
<mycrate>;` is inserted.
2. Finally, if the example does not contain `fn main`, the remainder of the
text is wrapped in `fn main() { your_code }`
Sometimes, this isn't enough, though. For example, all of these code samples
with `///` we've been talking about? The raw text:
@ -333,6 +336,42 @@ By repeating all parts of the example, you can ensure that your example still
compiles, while only showing the parts that are relevant to that part of your
explanation.
### Documenting macros
Heres an example of documenting a macro:
```
/// Panic with a given message unless an expression evaluates to true.
///
/// # Examples
///
/// ```
/// # #[macro_use] extern crate foo;
/// # fn main() {
/// panic_unless!(1 + 1 == 2, “Math is broken.”);
/// # }
/// ```
///
/// ```should_fail
/// # #[macro_use] extern crate foo;
/// # fn main() {
/// panic_unless!(true == false, “Im broken.”);
/// # }
/// ```
#[macro_export]
macro_rules! panic_unless {
($condition:expr, $($rest:expr),+) => ({ if ! $condition { panic!($($rest),+); } });
}
# fn main() {}
```
Youll note three things: we need to add our own `extern crate` line, so that
we can add the `#[macro_use]` attribute. Second, well need to add our own
`main()` as well. Finally, a judicious use of `#` to comment out those two
things, so they dont show up in the output.
### Running documentation tests
To run the tests, either
```bash

View file

@ -12,6 +12,7 @@ The following is a minimal example of calling a foreign function which will
compile if snappy is installed:
```no_run
# #![feature(libc)]
extern crate libc;
use libc::size_t;
@ -45,6 +46,7 @@ keeping the binding correct at runtime.
The `extern` block can be extended to cover the entire snappy API:
```no_run
# #![feature(libc)]
extern crate libc;
use libc::{c_int, size_t};
@ -80,6 +82,7 @@ length is number of elements currently contained, and the capacity is the total
the allocated memory. The length is less than or equal to the capacity.
```
# #![feature(libc)]
# extern crate libc;
# use libc::{c_int, size_t};
# unsafe fn snappy_validate_compressed_buffer(_: *const u8, _: size_t) -> c_int { 0 }
@ -104,6 +107,7 @@ required capacity to hold the compressed output. The vector can then be passed t
the true length after compression for setting the length.
```
# #![feature(libc)]
# extern crate libc;
# use libc::{size_t, c_int};
# unsafe fn snappy_compress(a: *const u8, b: size_t, c: *mut u8,
@ -130,6 +134,7 @@ Decompression is similar, because snappy stores the uncompressed size as part of
format and `snappy_uncompressed_length` will retrieve the exact buffer size required.
```
# #![feature(libc)]
# extern crate libc;
# use libc::{size_t, c_int};
# unsafe fn snappy_uncompress(compressed: *const u8,
@ -408,6 +413,7 @@ global state. In order to access these variables, you declare them in `extern`
blocks with the `static` keyword:
```no_run
# #![feature(libc)]
extern crate libc;
#[link(name = "readline")]
@ -426,6 +432,7 @@ interface. To do this, statics can be declared with `mut` so we can mutate
them.
```no_run
# #![feature(libc)]
extern crate libc;
use std::ffi::CString;
@ -458,6 +465,7 @@ calling foreign functions. Some foreign functions, most notably the Windows API,
conventions. Rust provides a way to tell the compiler which convention to use:
```
# #![feature(libc)]
extern crate libc;
#[cfg(all(target_os = "win32", target_arch = "x86"))]

View file

@ -246,6 +246,7 @@ These two basic iterators should serve you well. There are some more
advanced iterators, including ones that are infinite. Like `count`:
```rust
# #![feature(core)]
std::iter::count(1, 5);
```
@ -294,6 +295,7 @@ has no side effect on the original iterator. Let's try it out with our infinite
iterator from before, `count()`:
```rust
# #![feature(core)]
for i in std::iter::count(1, 5).take(5) {
println!("{}", i);
}

View file

@ -23,6 +23,7 @@ the ability to use this *method call syntax* via the `impl` keyword.
Here's how it works:
```{rust}
# #![feature(core)]
struct Circle {
x: f64,
y: f64,
@ -87,6 +88,7 @@ original example, `foo.bar().baz()`? This is called 'method chaining', and we
can do it by returning `self`.
```
# #![feature(core)]
struct Circle {
x: f64,
y: f64,
@ -164,6 +166,7 @@ have method overloading, named arguments, or variable arguments. We employ
the builder pattern instead. It looks like this:
```
# #![feature(core)]
struct Circle {
x: f64,
y: f64,

View file

@ -12,7 +12,7 @@ Additionally, strings are not null-terminated and can contain null bytes.
Rust has two main types of strings: `&str` and `String`.
# &str
# `&str`
The first kind is a `&str`. This is pronounced a 'string slice'.
String literals are of the type `&str`:
@ -36,7 +36,36 @@ Like vector slices, string slices are simply a pointer plus a length. This
means that they're a 'view' into an already-allocated string, such as a
string literal or a `String`.
# String
## `str`
You may occasionally see references to a `str` type, without the `&`. While
this type does exist, its not something you want to use yourself. Sometimes,
people confuse `str` for `String`, and write this:
```rust
struct S {
s: str,
}
```
This leads to ugly errors:
```text
error: the trait `core::marker::Sized` is not implemented for the type `str` [E0277]
note: `str` does not have a constant size known at compile-time
```
Instead, this `struct` should be
```rust
struct S {
s: String,
}
```
So lets talk about `String`s.
# `String`
A `String` is a heap-allocated string. This string is growable, and is
also guaranteed to be UTF-8. `String`s are commonly created by
@ -148,6 +177,7 @@ Rust provides iterators for each of these situations:
Usually, the `graphemes()` method on `&str` is what you want:
```
# #![feature(unicode)]
let s = "u͔n͈̰̎i̙̮͚̦c͚̉o̼̩̰͗d͔̆̓ͥé";
for l in s.graphemes(true) {

View file

@ -498,13 +498,10 @@ they go out of scope:
However, boxes do _not_ use reference counting or garbage collection. Boxes are
what's called an *affine type*. This means that the Rust compiler, at compile
time, determines when the box comes into and goes out of scope, and inserts the
appropriate calls there. Furthermore, boxes are a specific kind of affine type,
known as a *region*. You can read more about regions [in this paper on the
Cyclone programming
language](http://www.cs.umd.edu/projects/cyclone/papers/cyclone-regions.pdf).
appropriate calls there.
You don't need to fully grok the theory of affine types or regions to grok
boxes, though. As a rough approximation, you can treat this Rust code:
You don't need to fully grok the theory of affine types to grok boxes, though.
As a rough approximation, you can treat this Rust code:
```{rust}
{

View file

@ -5,7 +5,7 @@ we haven't seen before. Here's a simple program that reads some input,
and then prints it back out:
```{rust,ignore}
fn main() {
corefn main() {
println!("Type something!");
let input = std::old_io::stdin().read_line().ok().expect("Failed to read line");
@ -28,6 +28,7 @@ Since writing the fully qualified name all the time is annoying, we can use
the `use` statement to import it in:
```{rust}
# #![feature(old_io)]
use std::old_io::stdin;
stdin();
@ -37,6 +38,7 @@ However, it's considered better practice to not import individual functions, but
to import the module, and only use one level of qualification:
```{rust}
# #![feature(old_io)]
use std::old_io;
old_io::stdin();
@ -115,8 +117,9 @@ doesn't work, so we're okay with that. In most cases, we would want to handle
the error case explicitly. `expect()` allows us to give an error message if
this crash happens.
We will cover the exact details of how all of this works later in the Guide.
For now, this gives you enough of a basic understanding to work with.
We will cover the exact details of how all of this works later in the Guide in
[Error Handling]. For now, this gives you enough of a basic understanding to
work with.
Back to the code we were working on! Here's a refresher:
@ -157,3 +160,6 @@ here.
That's all you need to get basic input from the standard input! It's not too
complicated, but there are a number of small parts.
[Error Handling]: ./error-handling.html

View file

@ -546,6 +546,8 @@ is an opaque "black box" to the optimizer and so forces it to consider any
argument as used.
```rust
# #![feature(test)]
extern crate test;
# fn main() {

View file

@ -4,6 +4,7 @@ Do you remember the `impl` keyword, used to call a function with method
syntax?
```{rust}
# #![feature(core)]
struct Circle {
x: f64,
y: f64,
@ -21,6 +22,7 @@ Traits are similar, except that we define a trait with just the method
signature, then implement the trait for that struct. Like this:
```{rust}
# #![feature(core)]
struct Circle {
x: f64,
y: f64,
@ -84,6 +86,7 @@ which implements `HasArea` will have an `.area()` method.
Here's an extended example of how this works:
```{rust}
# #![feature(core)]
trait HasArea {
fn area(&self) -> f64;
}
@ -225,6 +228,7 @@ If we add a `use` line right above `main` and make the right things public,
everything is fine:
```{rust}
# #![feature(core)]
use shapes::HasArea;
mod shapes {
@ -408,6 +412,7 @@ but instead, we found a floating-point variable. We need a different bound. `Flo
to the rescue:
```
# #![feature(std_misc)]
use std::num::Float;
fn inverse<T: Float>(x: T) -> Result<T, String> {
@ -423,6 +428,7 @@ from the `Float` trait. Both `f32` and `f64` implement `Float`, so our function
works just fine:
```
# #![feature(std_misc)]
# use std::num::Float;
# fn inverse<T: Float>(x: T) -> Result<T, String> {
# if x == Float::zero() { return Err("x cannot be zero!".to_string()) }

View file

@ -187,6 +187,7 @@ As an example, we give a reimplementation of owned boxes by wrapping
reimplementation is as safe as the `Box` type.
```
# #![feature(libc)]
#![feature(unsafe_destructor)]
extern crate libc;
@ -443,6 +444,7 @@ The function marked `#[start]` is passed the command line parameters
in the same format as C:
```
# #![feature(libc)]
#![feature(lang_items, start, no_std)]
#![no_std]
@ -470,6 +472,7 @@ correct ABI and the correct name, which requires overriding the
compiler's name mangling too:
```ignore
# #![feature(libc)]
#![feature(no_std)]
#![no_std]
#![no_main]
@ -526,6 +529,7 @@ As an example, here is a program that will calculate the dot product of two
vectors provided from C, using idiomatic Rust practices.
```
# #![feature(libc, core)]
#![feature(lang_items, start, no_std)]
#![no_std]
@ -650,6 +654,7 @@ and one for deallocation. A freestanding program that uses the `Box`
sugar for dynamic allocations via `malloc` and `free`:
```
# #![feature(libc)]
#![feature(lang_items, box_syntax, start, no_std)]
#![no_std]

View file

@ -95,6 +95,7 @@ use heap::deallocate;
/// task.
///
/// ```
/// # #![feature(alloc, core)]
/// use std::sync::Arc;
/// use std::thread;
///
@ -127,8 +128,8 @@ unsafe impl<T: Sync + Send> Sync for Arc<T> { }
/// A weak pointer to an `Arc`.
///
/// Weak pointers will not keep the data inside of the `Arc` alive, and can be used to break cycles
/// between `Arc` pointers.
/// Weak pointers will not keep the data inside of the `Arc` alive, and can be
/// used to break cycles between `Arc` pointers.
#[unsafe_no_drop_flag]
#[unstable(feature = "alloc",
reason = "Weak pointers may not belong in this module.")]
@ -185,6 +186,7 @@ impl<T> Arc<T> {
/// # Examples
///
/// ```
/// # #![feature(alloc)]
/// use std::sync::Arc;
///
/// let five = Arc::new(5);
@ -216,8 +218,8 @@ impl<T> Arc<T> {
unsafe fn drop_slow(&mut self) {
let ptr = *self._ptr;
// Destroy the data at this time, even though we may not free the box allocation itself
// (there may still be weak pointers lying around).
// Destroy the data at this time, even though we may not free the box
// allocation itself (there may still be weak pointers lying around).
drop(ptr::read(&self.inner().data));
if self.inner().weak.fetch_sub(1, Release) == 1 {
@ -246,6 +248,7 @@ impl<T> Clone for Arc<T> {
/// # Examples
///
/// ```
/// # #![feature(alloc)]
/// use std::sync::Arc;
///
/// let five = Arc::new(5);
@ -283,12 +286,13 @@ impl<T> Deref for Arc<T> {
impl<T: Send + Sync + Clone> Arc<T> {
/// Make a mutable reference from the given `Arc<T>`.
///
/// This is also referred to as a copy-on-write operation because the inner data is cloned if
/// the reference count is greater than one.
/// This is also referred to as a copy-on-write operation because the inner
/// data is cloned if the reference count is greater than one.
///
/// # Examples
///
/// ```
/// # #![feature(alloc)]
/// use std::sync::Arc;
///
/// let mut five = Arc::new(5);
@ -298,16 +302,18 @@ impl<T: Send + Sync + Clone> Arc<T> {
#[inline]
#[unstable(feature = "alloc")]
pub fn make_unique(&mut self) -> &mut T {
// Note that we hold a strong reference, which also counts as a weak reference, so we only
// clone if there is an additional reference of either kind.
// Note that we hold a strong reference, which also counts as a weak
// reference, so we only clone if there is an additional reference of
// either kind.
if self.inner().strong.load(SeqCst) != 1 ||
self.inner().weak.load(SeqCst) != 1 {
*self = Arc::new((**self).clone())
}
// This unsafety is ok because we're guaranteed that the pointer returned is the *only*
// pointer that will ever be returned to T. Our reference count is guaranteed to be 1 at
// this point, and we required the Arc itself to be `mut`, so we're returning the only
// possible reference to the inner data.
// This unsafety is ok because we're guaranteed that the pointer
// returned is the *only* pointer that will ever be returned to T. Our
// reference count is guaranteed to be 1 at this point, and we required
// the Arc itself to be `mut`, so we're returning the only possible
// reference to the inner data.
let inner = unsafe { &mut **self._ptr };
&mut inner.data
}
@ -318,12 +324,14 @@ impl<T: Send + Sync + Clone> Arc<T> {
impl<T: Sync + Send> Drop for Arc<T> {
/// Drops the `Arc<T>`.
///
/// This will decrement the strong reference count. If the strong reference count becomes zero
/// and the only other references are `Weak<T>` ones, `drop`s the inner value.
/// This will decrement the strong reference count. If the strong reference
/// count becomes zero and the only other references are `Weak<T>` ones,
/// `drop`s the inner value.
///
/// # Examples
///
/// ```
/// # #![feature(alloc)]
/// use std::sync::Arc;
///
/// {
@ -342,29 +350,32 @@ impl<T: Sync + Send> Drop for Arc<T> {
/// ```
#[inline]
fn drop(&mut self) {
// This structure has #[unsafe_no_drop_flag], so this drop glue may run more than once (but
// it is guaranteed to be zeroed after the first if it's run more than once)
// This structure has #[unsafe_no_drop_flag], so this drop glue may run
// more than once (but it is guaranteed to be zeroed after the first if
// it's run more than once)
let ptr = *self._ptr;
if ptr.is_null() { return }
// Because `fetch_sub` is already atomic, we do not need to synchronize with other threads
// unless we are going to delete the object. This same logic applies to the below
// `fetch_sub` to the `weak` count.
// Because `fetch_sub` is already atomic, we do not need to synchronize
// with other threads unless we are going to delete the object. This
// same logic applies to the below `fetch_sub` to the `weak` count.
if self.inner().strong.fetch_sub(1, Release) != 1 { return }
// This fence is needed to prevent reordering of use of the data and deletion of the data.
// Because it is marked `Release`, the decreasing of the reference count synchronizes with
// this `Acquire` fence. This means that use of the data happens before decreasing the
// reference count, which happens before this fence, which happens before the deletion of
// the data.
// This fence is needed to prevent reordering of use of the data and
// deletion of the data. Because it is marked `Release`, the decreasing
// of the reference count synchronizes with this `Acquire` fence. This
// means that use of the data happens before decreasing the reference
// count, which happens before this fence, which happens before the
// deletion of the data.
//
// As explained in the [Boost documentation][1],
//
// > It is important to enforce any possible access to the object in one thread (through an
// > existing reference) to *happen before* deleting the object in a different thread. This
// > is achieved by a "release" operation after dropping a reference (any access to the
// > object through this reference must obviously happened before), and an "acquire"
// > operation before deleting the object.
// > It is important to enforce any possible access to the object in one
// > thread (through an existing reference) to *happen before* deleting
// > the object in a different thread. This is achieved by a "release"
// > operation after dropping a reference (any access to the object
// > through this reference must obviously happened before), and an
// > "acquire" operation before deleting the object.
//
// [1]: (www.boost.org/doc/libs/1_55_0/doc/html/atomic/usage_examples.html)
atomic::fence(Acquire);
@ -382,11 +393,13 @@ impl<T: Sync + Send> Weak<T> {
///
/// Upgrades the `Weak<T>` reference to an `Arc<T>`, if possible.
///
/// Returns `None` if there were no strong references and the data was destroyed.
/// Returns `None` if there were no strong references and the data was
/// destroyed.
///
/// # Examples
///
/// ```
/// # #![feature(alloc)]
/// use std::sync::Arc;
///
/// let five = Arc::new(5);
@ -396,8 +409,8 @@ impl<T: Sync + Send> Weak<T> {
/// let strong_five: Option<Arc<_>> = weak_five.upgrade();
/// ```
pub fn upgrade(&self) -> Option<Arc<T>> {
// We use a CAS loop to increment the strong count instead of a fetch_add because once the
// count hits 0 is must never be above 0.
// We use a CAS loop to increment the strong count instead of a
// fetch_add because once the count hits 0 is must never be above 0.
let inner = self.inner();
loop {
let n = inner.strong.load(SeqCst);
@ -424,6 +437,7 @@ impl<T: Sync + Send> Clone for Weak<T> {
/// # Examples
///
/// ```
/// # #![feature(alloc)]
/// use std::sync::Arc;
///
/// let weak_five = Arc::new(5).downgrade();
@ -448,6 +462,7 @@ impl<T: Sync + Send> Drop for Weak<T> {
/// # Examples
///
/// ```
/// # #![feature(alloc)]
/// use std::sync::Arc;
///
/// {
@ -472,8 +487,9 @@ impl<T: Sync + Send> Drop for Weak<T> {
// see comments above for why this check is here
if ptr.is_null() { return }
// If we find out that we were the last weak pointer, then its time to deallocate the data
// entirely. See the discussion in Arc::drop() about the memory orderings
// If we find out that we were the last weak pointer, then its time to
// deallocate the data entirely. See the discussion in Arc::drop() about
// the memory orderings
if self.inner().weak.fetch_sub(1, Release) == 1 {
atomic::fence(Acquire);
unsafe { deallocate(ptr as *mut u8, size_of::<ArcInner<T>>(),

View file

@ -65,6 +65,7 @@ use core::raw::TraitObject;
/// The following two examples are equivalent:
///
/// ```
/// # #![feature(alloc)]
/// #![feature(box_syntax)]
/// use std::boxed::HEAP;
///
@ -135,6 +136,7 @@ impl<T : ?Sized> Box<T> {
///
/// # Examples
/// ```
/// # #![feature(alloc)]
/// use std::boxed;
///
/// let seventeen = Box::new(17u32);
@ -178,6 +180,7 @@ impl<T: Clone> Clone for Box<T> {
/// # Examples
///
/// ```
/// # #![feature(alloc, core)]
/// let x = Box::new(5);
/// let mut y = Box::new(10);
///

View file

@ -26,6 +26,9 @@ pub unsafe fn allocate(size: usize, align: usize) -> *mut u8 {
///
/// On failure, return a null pointer and leave the original allocation intact.
///
/// If the allocation was relocated, the memory at the passed-in pointer is
/// undefined after the call.
///
/// Behavior is undefined if the requested size is 0 or the alignment is not a
/// power of 2. The alignment must be no larger than the largest supported page
/// size on the platform.

View file

@ -66,6 +66,7 @@
#![doc(html_logo_url = "http://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png",
html_favicon_url = "http://www.rust-lang.org/favicon.ico",
html_root_url = "http://doc.rust-lang.org/nightly/")]
#![doc(test(no_crate_inject))]
#![feature(no_std)]
#![no_std]

View file

@ -32,6 +32,7 @@
//! and have the `Owner` remain allocated as long as any `Gadget` points at it.
//!
//! ```rust
//! # #![feature(alloc, collections)]
//! use std::rc::Rc;
//!
//! struct Owner {
@ -58,12 +59,12 @@
//!
//! drop(gadget_owner);
//!
//! // Despite dropping gadget_owner, we're still able to print out the name of
//! // the Owner of the Gadgets. This is because we've only dropped the
//! // Despite dropping gadget_owner, we're still able to print out the name
//! // of the Owner of the Gadgets. This is because we've only dropped the
//! // reference count object, not the Owner it wraps. As long as there are
//! // other `Rc<T>` objects pointing at the same Owner, it will remain allocated. Notice
//! // that the `Rc<T>` wrapper around Gadget.owner gets automatically dereferenced
//! // for us.
//! // other `Rc<T>` objects pointing at the same Owner, it will remain
//! // allocated. Notice that the `Rc<T>` wrapper around Gadget.owner gets
//! // automatically dereferenced for us.
//! println!("Gadget {} owned by {}", gadget1.id, gadget1.owner.name);
//! println!("Gadget {} owned by {}", gadget2.id, gadget2.owner.name);
//!
@ -73,21 +74,25 @@
//! }
//! ```
//!
//! If our requirements change, and we also need to be able to traverse from Owner → Gadget, we
//! will run into problems: an `Rc<T>` pointer from Owner → Gadget introduces a cycle between the
//! objects. This means that their reference counts can never reach 0, and the objects will remain
//! allocated: a memory leak. In order to get around this, we can use `Weak<T>` pointers. These
//! pointers don't contribute to the total count.
//! If our requirements change, and we also need to be able to traverse from
//! Owner → Gadget, we will run into problems: an `Rc<T>` pointer from Owner
//! → Gadget introduces a cycle between the objects. This means that their
//! reference counts can never reach 0, and the objects will remain allocated: a
//! memory leak. In order to get around this, we can use `Weak<T>` pointers.
//! These pointers don't contribute to the total count.
//!
//! Rust actually makes it somewhat difficult to produce this loop in the first place: in order to
//! end up with two objects that point at each other, one of them needs to be mutable. This is
//! problematic because `Rc<T>` enforces memory safety by only giving out shared references to the
//! object it wraps, and these don't allow direct mutation. We need to wrap the part of the object
//! we wish to mutate in a `RefCell`, which provides *interior mutability*: a method to achieve
//! mutability through a shared reference. `RefCell` enforces Rust's borrowing rules at runtime.
//! Read the `Cell` documentation for more details on interior mutability.
//! Rust actually makes it somewhat difficult to produce this loop in the first
//! place: in order to end up with two objects that point at each other, one of
//! them needs to be mutable. This is problematic because `Rc<T>` enforces
//! memory safety by only giving out shared references to the object it wraps,
//! and these don't allow direct mutation. We need to wrap the part of the
//! object we wish to mutate in a `RefCell`, which provides *interior
//! mutability*: a method to achieve mutability through a shared reference.
//! `RefCell` enforces Rust's borrowing rules at runtime. Read the `Cell`
//! documentation for more details on interior mutability.
//!
//! ```rust
//! # #![feature(alloc)]
//! use std::rc::Rc;
//! use std::rc::Weak;
//! use std::cell::RefCell;
@ -128,9 +133,10 @@
//! for gadget_opt in gadget_owner.gadgets.borrow().iter() {
//!
//! // gadget_opt is a Weak<Gadget>. Since weak pointers can't guarantee
//! // that their object is still allocated, we need to call upgrade() on them
//! // to turn them into a strong reference. This returns an Option, which
//! // contains a reference to our object if it still exists.
//! // that their object is still allocated, we need to call upgrade()
//! // on them to turn them into a strong reference. This returns an
//! // Option, which contains a reference to our object if it still
//! // exists.
//! let gadget = gadget_opt.upgrade().unwrap();
//! println!("Gadget {} owned by {}", gadget.id, gadget.owner.name);
//! }
@ -178,8 +184,8 @@ struct RcBox<T> {
#[unsafe_no_drop_flag]
#[stable(feature = "rust1", since = "1.0.0")]
pub struct Rc<T> {
// FIXME #12808: strange names to try to avoid interfering with field accesses of the contained
// type via Deref
// FIXME #12808: strange names to try to avoid interfering with field
// accesses of the contained type via Deref
_ptr: NonZero<*mut RcBox<T>>,
}
@ -201,9 +207,10 @@ impl<T> Rc<T> {
pub fn new(value: T) -> Rc<T> {
unsafe {
Rc {
// there is an implicit weak pointer owned by all the strong pointers, which
// ensures that the weak destructor never frees the allocation while the strong
// destructor is running, even if the weak pointer is stored inside the strong one.
// there is an implicit weak pointer owned by all the strong
// pointers, which ensures that the weak destructor never frees
// the allocation while the strong destructor is running, even
// if the weak pointer is stored inside the strong one.
_ptr: NonZero::new(boxed::into_raw(box RcBox {
value: value,
strong: Cell::new(1),
@ -218,6 +225,7 @@ impl<T> Rc<T> {
/// # Examples
///
/// ```
/// # #![feature(alloc)]
/// use std::rc::Rc;
///
/// let five = Rc::new(5);
@ -242,11 +250,13 @@ pub fn weak_count<T>(this: &Rc<T>) -> usize { this.weak() - 1 }
#[unstable(feature = "alloc")]
pub fn strong_count<T>(this: &Rc<T>) -> usize { this.strong() }
/// Returns true if there are no other `Rc` or `Weak<T>` values that share the same inner value.
/// Returns true if there are no other `Rc` or `Weak<T>` values that share the
/// same inner value.
///
/// # Examples
///
/// ```
/// # #![feature(alloc)]
/// use std::rc;
/// use std::rc::Rc;
///
@ -267,6 +277,7 @@ pub fn is_unique<T>(rc: &Rc<T>) -> bool {
/// # Examples
///
/// ```
/// # #![feature(alloc)]
/// use std::rc::{self, Rc};
///
/// let x = Rc::new(3);
@ -301,6 +312,7 @@ pub fn try_unwrap<T>(rc: Rc<T>) -> Result<T, Rc<T>> {
/// # Examples
///
/// ```
/// # #![feature(alloc)]
/// use std::rc::{self, Rc};
///
/// let mut x = Rc::new(3);
@ -324,12 +336,13 @@ pub fn get_mut<'a, T>(rc: &'a mut Rc<T>) -> Option<&'a mut T> {
impl<T: Clone> Rc<T> {
/// Make a mutable reference from the given `Rc<T>`.
///
/// This is also referred to as a copy-on-write operation because the inner data is cloned if
/// the reference count is greater than one.
/// This is also referred to as a copy-on-write operation because the inner
/// data is cloned if the reference count is greater than one.
///
/// # Examples
///
/// ```
/// # #![feature(alloc)]
/// use std::rc::Rc;
///
/// let mut five = Rc::new(5);
@ -342,10 +355,11 @@ impl<T: Clone> Rc<T> {
if !is_unique(self) {
*self = Rc::new((**self).clone())
}
// This unsafety is ok because we're guaranteed that the pointer returned is the *only*
// pointer that will ever be returned to T. Our reference count is guaranteed to be 1 at
// this point, and we required the `Rc<T>` itself to be `mut`, so we're returning the only
// possible reference to the inner value.
// This unsafety is ok because we're guaranteed that the pointer
// returned is the *only* pointer that will ever be returned to T. Our
// reference count is guaranteed to be 1 at this point, and we required
// the `Rc<T>` itself to be `mut`, so we're returning the only possible
// reference to the inner value.
let inner = unsafe { &mut **self._ptr };
&mut inner.value
}
@ -366,12 +380,14 @@ impl<T> Deref for Rc<T> {
impl<T> Drop for Rc<T> {
/// Drops the `Rc<T>`.
///
/// This will decrement the strong reference count. If the strong reference count becomes zero
/// and the only other references are `Weak<T>` ones, `drop`s the inner value.
/// This will decrement the strong reference count. If the strong reference
/// count becomes zero and the only other references are `Weak<T>` ones,
/// `drop`s the inner value.
///
/// # Examples
///
/// ```
/// # #![feature(alloc)]
/// use std::rc::Rc;
///
/// {
@ -396,8 +412,8 @@ impl<T> Drop for Rc<T> {
if self.strong() == 0 {
ptr::read(&**self); // destroy the contained object
// remove the implicit "strong weak" pointer now that we've destroyed the
// contents.
// remove the implicit "strong weak" pointer now that we've
// destroyed the contents.
self.dec_weak();
if self.weak() == 0 {
@ -420,6 +436,7 @@ impl<T> Clone for Rc<T> {
/// # Examples
///
/// ```
/// # #![feature(alloc)]
/// use std::rc::Rc;
///
/// let five = Rc::new(5);
@ -618,7 +635,8 @@ impl<T: fmt::Debug> fmt::Debug for Rc<T> {
/// A weak version of `Rc<T>`.
///
/// Weak references do not count when determining if the inner value should be dropped.
/// Weak references do not count when determining if the inner value should be
/// dropped.
///
/// See the [module level documentation](./index.html) for more.
#[unsafe_no_drop_flag]
@ -643,11 +661,13 @@ impl<T> Weak<T> {
///
/// Upgrades the `Weak<T>` reference to an `Rc<T>`, if possible.
///
/// Returns `None` if there were no strong references and the data was destroyed.
/// Returns `None` if there were no strong references and the data was
/// destroyed.
///
/// # Examples
///
/// ```
/// # #![feature(alloc)]
/// use std::rc::Rc;
///
/// let five = Rc::new(5);
@ -676,6 +696,7 @@ impl<T> Drop for Weak<T> {
/// # Examples
///
/// ```
/// # #![feature(alloc)]
/// use std::rc::Rc;
///
/// {
@ -699,8 +720,8 @@ impl<T> Drop for Weak<T> {
let ptr = *self._ptr;
if !ptr.is_null() {
self.dec_weak();
// the weak count starts at 1, and will only go to zero if all the strong pointers
// have disappeared.
// the weak count starts at 1, and will only go to zero if all
// the strong pointers have disappeared.
if self.weak() == 0 {
deallocate(ptr as *mut u8, size_of::<RcBox<T>>(),
min_align_of::<RcBox<T>>())
@ -721,6 +742,7 @@ impl<T> Clone for Weak<T> {
/// # Examples
///
/// ```
/// # #![feature(alloc)]
/// use std::rc::Rc;
///
/// let weak_five = Rc::new(5).downgrade();

View file

@ -216,6 +216,7 @@ impl<T: Ord> BinaryHeap<T> {
/// # Examples
///
/// ```
/// # #![feature(collections)]
/// use std::collections::BinaryHeap;
/// let heap = BinaryHeap::from_vec(vec![9, 1, 2, 7, 3, 2]);
/// ```
@ -235,6 +236,7 @@ impl<T: Ord> BinaryHeap<T> {
/// # Examples
///
/// ```
/// # #![feature(collections)]
/// use std::collections::BinaryHeap;
/// let heap = BinaryHeap::from_vec(vec![1, 2, 3, 4]);
///
@ -255,6 +257,7 @@ impl<T: Ord> BinaryHeap<T> {
/// # Examples
///
/// ```
/// # #![feature(collections)]
/// use std::collections::BinaryHeap;
/// let heap = BinaryHeap::from_vec(vec![1, 2, 3, 4]);
///
@ -360,6 +363,7 @@ impl<T: Ord> BinaryHeap<T> {
/// # Examples
///
/// ```
/// # #![feature(collections)]
/// use std::collections::BinaryHeap;
/// let mut heap = BinaryHeap::from_vec(vec![1, 3]);
///
@ -405,6 +409,7 @@ impl<T: Ord> BinaryHeap<T> {
/// # Examples
///
/// ```
/// # #![feature(collections)]
/// use std::collections::BinaryHeap;
/// let mut heap = BinaryHeap::new();
/// heap.push(1);
@ -436,6 +441,7 @@ impl<T: Ord> BinaryHeap<T> {
/// # Examples
///
/// ```
/// # #![feature(collections)]
/// use std::collections::BinaryHeap;
/// let mut heap = BinaryHeap::new();
///
@ -461,6 +467,7 @@ impl<T: Ord> BinaryHeap<T> {
/// # Examples
///
/// ```
/// # #![feature(collections)]
/// use std::collections::BinaryHeap;
/// let heap = BinaryHeap::from_vec(vec![1, 2, 3, 4, 5, 6, 7]);
/// let vec = heap.into_vec();
@ -478,6 +485,7 @@ impl<T: Ord> BinaryHeap<T> {
/// # Examples
///
/// ```
/// # #![feature(collections)]
/// use std::collections::BinaryHeap;
///
/// let mut heap = BinaryHeap::from_vec(vec![1, 2, 4, 5, 7]);

View file

@ -38,6 +38,7 @@
//! [sieve]: http://en.wikipedia.org/wiki/Sieve_of_Eratosthenes
//!
//! ```
//! # #![feature(collections, core)]
//! use std::collections::{BitSet, BitVec};
//! use std::num::Float;
//! use std::iter;
@ -134,6 +135,7 @@ static FALSE: bool = false;
/// # Examples
///
/// ```
/// # #![feature(collections)]
/// use std::collections::BitVec;
///
/// let mut bv = BitVec::from_elem(10, false);
@ -169,6 +171,8 @@ pub struct BitVec {
impl Index<usize> for BitVec {
type Output = bool;
#[cfg(stage0)]
#[inline]
fn index(&self, i: &usize) -> &bool {
if self.get(*i).expect("index out of bounds") {
@ -177,6 +181,16 @@ impl Index<usize> for BitVec {
&FALSE
}
}
#[cfg(not(stage0))]
#[inline]
fn index(&self, i: usize) -> &bool {
if self.get(i).expect("index out of bounds") {
&TRUE
} else {
&FALSE
}
}
}
/// Computes how many blocks are needed to store that many bits
@ -250,6 +264,7 @@ impl BitVec {
/// # Examples
///
/// ```
/// # #![feature(collections)]
/// use std::collections::BitVec;
/// let mut bv = BitVec::new();
/// ```
@ -264,6 +279,7 @@ impl BitVec {
/// # Examples
///
/// ```
/// # #![feature(collections)]
/// use std::collections::BitVec;
///
/// let mut bv = BitVec::from_elem(10, false);
@ -304,6 +320,7 @@ impl BitVec {
/// # Examples
///
/// ```
/// # #![feature(collections)]
/// use std::collections::BitVec;
///
/// let bv = BitVec::from_bytes(&[0b10100000, 0b00010010]);
@ -346,6 +363,7 @@ impl BitVec {
/// # Examples
///
/// ```
/// # #![feature(collections)]
/// use std::collections::BitVec;
///
/// let bv = BitVec::from_fn(5, |i| { i % 2 == 0 });
@ -364,6 +382,7 @@ impl BitVec {
/// # Examples
///
/// ```
/// # #![feature(collections)]
/// use std::collections::BitVec;
///
/// let bv = BitVec::from_bytes(&[0b01100000]);
@ -396,6 +415,7 @@ impl BitVec {
/// # Examples
///
/// ```
/// # #![feature(collections)]
/// use std::collections::BitVec;
///
/// let mut bv = BitVec::from_elem(5, false);
@ -420,6 +440,7 @@ impl BitVec {
/// # Examples
///
/// ```
/// # #![feature(collections)]
/// use std::collections::BitVec;
///
/// let before = 0b01100000;
@ -440,6 +461,7 @@ impl BitVec {
/// # Examples
///
/// ```
/// # #![feature(collections)]
/// use std::collections::BitVec;
///
/// let before = 0b01100000;
@ -468,6 +490,7 @@ impl BitVec {
/// # Examples
///
/// ```
/// # #![feature(collections)]
/// use std::collections::BitVec;
///
/// let a = 0b01100100;
@ -498,6 +521,7 @@ impl BitVec {
/// # Examples
///
/// ```
/// # #![feature(collections)]
/// use std::collections::BitVec;
///
/// let a = 0b01100100;
@ -528,6 +552,7 @@ impl BitVec {
/// # Examples
///
/// ```
/// # #![feature(collections)]
/// use std::collections::BitVec;
///
/// let a = 0b01100100;
@ -557,6 +582,7 @@ impl BitVec {
/// # Examples
///
/// ```
/// # #![feature(collections)]
/// use std::collections::BitVec;
///
/// let mut bv = BitVec::from_elem(5, true);
@ -581,6 +607,7 @@ impl BitVec {
/// # Examples
///
/// ```
/// # #![feature(collections)]
/// use std::collections::BitVec;
///
/// let bv = BitVec::from_bytes(&[0b01110100, 0b10010010]);
@ -597,6 +624,7 @@ impl BitVec {
/// # Examples
///
/// ```
/// # #![feature(collections)]
/// use std::collections::BitVec;
///
/// let mut bv = BitVec::from_elem(10, false);
@ -614,6 +642,7 @@ impl BitVec {
/// # Examples
///
/// ```
/// # #![feature(collections)]
/// use std::collections::BitVec;
///
/// let mut bv = BitVec::from_elem(10, false);
@ -635,6 +664,7 @@ impl BitVec {
/// # Examples
///
/// ```
/// # #![feature(collections)]
/// use std::collections::BitVec;
///
/// let mut bv = BitVec::from_elem(3, true);
@ -682,6 +712,7 @@ impl BitVec {
/// # Examples
///
/// ```
/// # #![feature(collections)]
/// use std::collections::BitVec;
///
/// let bv = BitVec::from_bytes(&[0b10100000]);
@ -702,6 +733,7 @@ impl BitVec {
/// # Examples
///
/// ```
/// # #![feature(collections)]
/// use std::collections::BitVec;
///
/// let mut bv = BitVec::from_bytes(&[0b01001011]);
@ -728,6 +760,7 @@ impl BitVec {
/// # Examples
///
/// ```
/// # #![feature(collections)]
/// use std::collections::BitVec;
///
/// let mut bv = BitVec::from_elem(3, false);
@ -758,6 +791,7 @@ impl BitVec {
/// # Examples
///
/// ```
/// # #![feature(collections)]
/// use std::collections::BitVec;
///
/// let mut bv = BitVec::from_elem(3, false);
@ -780,6 +814,7 @@ impl BitVec {
/// # Examples
///
/// ```
/// # #![feature(collections)]
/// use std::collections::BitVec;
///
/// let mut bv = BitVec::new();
@ -801,6 +836,7 @@ impl BitVec {
/// # Examples
///
/// ```
/// # #![feature(collections)]
/// use std::collections::BitVec;
///
/// let mut bv = BitVec::from_bytes(&[0b01001011]);
@ -851,6 +887,7 @@ impl BitVec {
/// # Examples
///
/// ```
/// # #![feature(collections)]
/// use std::collections::BitVec;
///
/// let mut bv = BitVec::from_bytes(&[0b01001001]);
@ -881,6 +918,7 @@ impl BitVec {
/// # Examples
///
/// ```
/// # #![feature(collections)]
/// use std::collections::BitVec;
///
/// let mut bv = BitVec::new();
@ -1091,6 +1129,7 @@ impl<'a> IntoIterator for &'a BitVec {
/// # Examples
///
/// ```
/// # #![feature(collections)]
/// use std::collections::{BitSet, BitVec};
///
/// // It's a regular set
@ -1187,6 +1226,7 @@ impl BitSet {
/// # Examples
///
/// ```
/// # #![feature(collections)]
/// use std::collections::BitSet;
///
/// let mut s = BitSet::new();
@ -1203,6 +1243,7 @@ impl BitSet {
/// # Examples
///
/// ```
/// # #![feature(collections)]
/// use std::collections::BitSet;
///
/// let mut s = BitSet::with_capacity(100);
@ -1220,6 +1261,7 @@ impl BitSet {
/// # Examples
///
/// ```
/// # #![feature(collections)]
/// use std::collections::{BitVec, BitSet};
///
/// let bv = BitVec::from_bytes(&[0b01100000]);
@ -1249,6 +1291,7 @@ impl BitSet {
/// # Examples
///
/// ```
/// # #![feature(collections)]
/// use std::collections::BitSet;
///
/// let mut s = BitSet::with_capacity(100);
@ -1270,6 +1313,7 @@ impl BitSet {
/// # Examples
///
/// ```
/// # #![feature(collections)]
/// use std::collections::BitSet;
///
/// let mut s = BitSet::new();
@ -1296,6 +1340,7 @@ impl BitSet {
/// # Examples
///
/// ```
/// # #![feature(collections)]
/// use std::collections::BitSet;
///
/// let mut s = BitSet::new();
@ -1316,6 +1361,7 @@ impl BitSet {
/// # Examples
///
/// ```
/// # #![feature(collections)]
/// use std::collections::BitSet;
///
/// let mut s = BitSet::new();
@ -1336,6 +1382,7 @@ impl BitSet {
/// # Examples
///
/// ```
/// # #![feature(collections)]
/// use std::collections::BitSet;
///
/// let mut s = BitSet::new();
@ -1382,6 +1429,7 @@ impl BitSet {
/// # Examples
///
/// ```
/// # #![feature(collections)]
/// use std::collections::BitSet;
///
/// let mut s = BitSet::new();
@ -1414,6 +1462,7 @@ impl BitSet {
/// # Examples
///
/// ```
/// # #![feature(collections)]
/// use std::collections::{BitVec, BitSet};
///
/// let s = BitSet::from_bit_vec(BitVec::from_bytes(&[0b01001010]));
@ -1435,6 +1484,7 @@ impl BitSet {
/// # Examples
///
/// ```
/// # #![feature(collections)]
/// use std::collections::{BitVec, BitSet};
///
/// let a = BitSet::from_bit_vec(BitVec::from_bytes(&[0b01101000]));
@ -1465,6 +1515,7 @@ impl BitSet {
/// # Examples
///
/// ```
/// # #![feature(collections)]
/// use std::collections::{BitVec, BitSet};
///
/// let a = BitSet::from_bit_vec(BitVec::from_bytes(&[0b01101000]));
@ -1495,6 +1546,7 @@ impl BitSet {
/// # Examples
///
/// ```
/// # #![feature(collections)]
/// use std::collections::{BitSet, BitVec};
///
/// let a = BitSet::from_bit_vec(BitVec::from_bytes(&[0b01101000]));
@ -1533,6 +1585,7 @@ impl BitSet {
/// # Examples
///
/// ```
/// # #![feature(collections)]
/// use std::collections::{BitSet, BitVec};
///
/// let a = BitSet::from_bit_vec(BitVec::from_bytes(&[0b01101000]));
@ -1562,6 +1615,7 @@ impl BitSet {
/// # Examples
///
/// ```
/// # #![feature(collections)]
/// use std::collections::{BitSet, BitVec};
///
/// let a = 0b01101000;
@ -1585,6 +1639,7 @@ impl BitSet {
/// # Examples
///
/// ```
/// # #![feature(collections)]
/// use std::collections::{BitSet, BitVec};
///
/// let a = 0b01101000;
@ -1609,6 +1664,7 @@ impl BitSet {
/// # Examples
///
/// ```
/// # #![feature(collections)]
/// use std::collections::{BitSet, BitVec};
///
/// let a = 0b01101000;
@ -1641,6 +1697,7 @@ impl BitSet {
/// # Examples
///
/// ```
/// # #![feature(collections)]
/// use std::collections::{BitSet, BitVec};
///
/// let a = 0b01101000;
@ -1792,12 +1849,16 @@ struct TwoBitPositions<'a> {
next_idx: usize
}
#[derive(Clone)]
#[stable(feature = "rust1", since = "1.0.0")]
pub struct Union<'a>(TwoBitPositions<'a>);
#[derive(Clone)]
#[stable(feature = "rust1", since = "1.0.0")]
pub struct Intersection<'a>(Take<TwoBitPositions<'a>>);
#[derive(Clone)]
#[stable(feature = "rust1", since = "1.0.0")]
pub struct Difference<'a>(TwoBitPositions<'a>);
#[derive(Clone)]
#[stable(feature = "rust1", since = "1.0.0")]
pub struct SymmetricDifference<'a>(TwoBitPositions<'a>);

View file

@ -14,6 +14,7 @@
use core::clone::Clone;
use core::cmp::{Eq, Ord, Ordering, PartialEq, PartialOrd};
use core::convert::AsRef;
use core::hash::{Hash, Hasher};
use core::marker::Sized;
use core::ops::Deref;
@ -291,10 +292,9 @@ impl<'a, B: ?Sized> Hash for Cow<'a, B> where B: Hash + ToOwned
}
/// Trait for moving into a `Cow`
#[stable(feature = "rust1", since = "1.0.0")]
#[unstable(feature = "into_cow", reason = "may be replaced by `convert::Into`")]
pub trait IntoCow<'a, B: ?Sized> where B: ToOwned {
/// Moves `self` into `Cow`
#[stable(feature = "rust1", since = "1.0.0")]
fn into_cow(self) -> Cow<'a, B>;
}
@ -304,3 +304,10 @@ impl<'a, B: ?Sized> IntoCow<'a, B> for Cow<'a, B> where B: ToOwned {
self
}
}
#[stable(feature = "rust1", since = "1.0.0")]
impl<'a, T: Clone> AsRef<T> for Cow<'a, T> {
fn as_ref(&self) -> &T {
self
}
}

View file

@ -78,6 +78,7 @@ pub struct BTreeMap<K, V> {
}
/// An abstract base over-which all other BTree iterators are built.
#[derive(Clone)]
struct AbsIter<T> {
traversals: VecDeque<T>,
size: usize,
@ -124,26 +125,26 @@ pub struct RangeMut<'a, K: 'a, V: 'a> {
}
/// A view into a single entry in a map, which may either be vacant or occupied.
#[unstable(feature = "collections",
reason = "precise API still under development")]
#[stable(feature = "rust1", since = "1.0.0")]
pub enum Entry<'a, K:'a, V:'a> {
/// A vacant Entry
#[stable(feature = "rust1", since = "1.0.0")]
Vacant(VacantEntry<'a, K, V>),
/// An occupied Entry
#[stable(feature = "rust1", since = "1.0.0")]
Occupied(OccupiedEntry<'a, K, V>),
}
/// A vacant Entry.
#[unstable(feature = "collections",
reason = "precise API still under development")]
#[stable(feature = "rust1", since = "1.0.0")]
pub struct VacantEntry<'a, K:'a, V:'a> {
key: K,
stack: stack::SearchStack<'a, K, V, node::handle::Edge, node::handle::Leaf>,
}
/// An occupied Entry.
#[unstable(feature = "collections",
reason = "precise API still under development")]
#[stable(feature = "rust1", since = "1.0.0")]
pub struct OccupiedEntry<'a, K:'a, V:'a> {
stack: stack::SearchStack<'a, K, V, node::handle::KV, node::handle::LeafOrInternal>,
}
@ -264,7 +265,7 @@ impl<K: Ord, V> BTreeMap<K, V> {
/// Some(x) => *x = "b",
/// None => (),
/// }
/// assert_eq!(map[1], "b");
/// assert_eq!(map[&1], "b");
/// ```
// See `get` for implementation notes, this is basically a copy-paste with mut's added
#[stable(feature = "rust1", since = "1.0.0")]
@ -326,7 +327,7 @@ impl<K: Ord, V> BTreeMap<K, V> {
///
/// map.insert(37, "b");
/// assert_eq!(map.insert(37, "c"), Some("b"));
/// assert_eq!(map[37], "c");
/// assert_eq!(map[&37], "c");
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
pub fn insert(&mut self, mut key: K, mut value: V) -> Option<V> {
@ -914,12 +915,27 @@ impl<K: Debug, V: Debug> Debug for BTreeMap<K, V> {
}
}
#[cfg(stage0)]
#[stable(feature = "rust1", since = "1.0.0")]
impl<K: Ord, Q: ?Sized, V> Index<Q> for BTreeMap<K, V>
where K: Borrow<Q>, Q: Ord
{
type Output = V;
#[inline]
fn index(&self, key: &Q) -> &V {
self.get(key).expect("no entry found for key")
}
}
#[cfg(not(stage0))]
#[stable(feature = "rust1", since = "1.0.0")]
impl<'a, K: Ord, Q: ?Sized, V> Index<&'a Q> for BTreeMap<K, V>
where K: Borrow<Q>, Q: Ord
{
type Output = V;
#[inline]
fn index(&self, key: &Q) -> &V {
self.get(key).expect("no entry found for key")
}
@ -1025,6 +1041,9 @@ impl<K, V, E, T> DoubleEndedIterator for AbsIter<T> where
}
}
impl<'a, K, V> Clone for Iter<'a, K, V> {
fn clone(&self) -> Iter<'a, K, V> { Iter { inner: self.inner.clone() } }
}
#[stable(feature = "rust1", since = "1.0.0")]
impl<'a, K, V> Iterator for Iter<'a, K, V> {
type Item = (&'a K, &'a V);
@ -1067,6 +1086,9 @@ impl<K, V> DoubleEndedIterator for IntoIter<K, V> {
#[stable(feature = "rust1", since = "1.0.0")]
impl<K, V> ExactSizeIterator for IntoIter<K, V> {}
impl<'a, K, V> Clone for Keys<'a, K, V> {
fn clone(&self) -> Keys<'a, K, V> { Keys { inner: self.inner.clone() } }
}
#[stable(feature = "rust1", since = "1.0.0")]
impl<'a, K, V> Iterator for Keys<'a, K, V> {
type Item = &'a K;
@ -1082,6 +1104,9 @@ impl<'a, K, V> DoubleEndedIterator for Keys<'a, K, V> {
impl<'a, K, V> ExactSizeIterator for Keys<'a, K, V> {}
impl<'a, K, V> Clone for Values<'a, K, V> {
fn clone(&self) -> Values<'a, K, V> { Values { inner: self.inner.clone() } }
}
#[stable(feature = "rust1", since = "1.0.0")]
impl<'a, K, V> Iterator for Values<'a, K, V> {
type Item = &'a V;
@ -1096,6 +1121,9 @@ impl<'a, K, V> DoubleEndedIterator for Values<'a, K, V> {
#[stable(feature = "rust1", since = "1.0.0")]
impl<'a, K, V> ExactSizeIterator for Values<'a, K, V> {}
impl<'a, K, V> Clone for Range<'a, K, V> {
fn clone(&self) -> Range<'a, K, V> { Range { inner: self.inner.clone() } }
}
impl<'a, K, V> Iterator for Range<'a, K, V> {
type Item = (&'a K, &'a V);
@ -1115,9 +1143,9 @@ impl<'a, K, V> DoubleEndedIterator for RangeMut<'a, K, V> {
}
impl<'a, K: Ord, V> Entry<'a, K, V> {
#[unstable(feature = "collections",
reason = "matches collection reform v2 specification, waiting for dust to settle")]
/// Returns a mutable reference to the entry if occupied, or the VacantEntry if vacant
#[unstable(feature = "std_misc",
reason = "will soon be replaced by or_insert")]
pub fn get(self) -> Result<&'a mut V, VacantEntry<'a, K, V>> {
match self {
Occupied(entry) => Ok(entry.into_mut()),
@ -1269,6 +1297,7 @@ impl<K, V> BTreeMap<K, V> {
/// # Examples
///
/// ```
/// # #![feature(core)]
/// use std::collections::BTreeMap;
///
/// let mut a = BTreeMap::new();
@ -1291,6 +1320,7 @@ impl<K, V> BTreeMap<K, V> {
/// # Examples
///
/// ```
/// # #![feature(core)]
/// use std::collections::BTreeMap;
///
/// let mut a = BTreeMap::new();
@ -1478,6 +1508,7 @@ impl<K: Ord, V> BTreeMap<K, V> {
/// # Examples
///
/// ```
/// # #![feature(collections)]
/// use std::collections::BTreeMap;
/// use std::collections::Bound::{Included, Unbounded};
///
@ -1504,6 +1535,7 @@ impl<K: Ord, V> BTreeMap<K, V> {
/// # Examples
///
/// ```
/// # #![feature(collections)]
/// use std::collections::BTreeMap;
/// use std::collections::Bound::{Included, Excluded};
///
@ -1529,6 +1561,7 @@ impl<K: Ord, V> BTreeMap<K, V> {
/// # Examples
///
/// ```
/// # #![feature(collections)]
/// use std::collections::BTreeMap;
/// use std::collections::btree_map::Entry;
///

View file

@ -1326,6 +1326,7 @@ trait TraversalImpl {
/// A `TraversalImpl` that actually is backed by two iterators. This works in the non-moving case,
/// as no deallocation needs to be done.
#[derive(Clone)]
struct ElemsAndEdges<Elems, Edges>(Elems, Edges);
impl<K, V, E, Elems: DoubleEndedIterator, Edges: DoubleEndedIterator>
@ -1404,6 +1405,7 @@ impl<K, V> Drop for MoveTraversalImpl<K, V> {
}
/// An abstraction over all the different kinds of traversals a node supports
#[derive(Clone)]
struct AbsTraversal<Impl> {
inner: Impl,
head_is_edge: bool,
@ -1522,6 +1524,7 @@ macro_rules! node_slice_impl {
}
/// Returns a sub-slice with elements starting with `min_key`.
#[cfg(stage0)]
pub fn slice_from(self, min_key: &K) -> $NodeSlice<'a, K, V> {
// _______________
// |_1_|_3_|_5_|_7_|
@ -1549,7 +1552,37 @@ macro_rules! node_slice_impl {
}
}
/// Returns a sub-slice with elements starting with `min_key`.
#[cfg(not(stage0))]
pub fn slice_from(self, min_key: &K) -> $NodeSlice<'a, K, V> {
// _______________
// |_1_|_3_|_5_|_7_|
// | | | | |
// 0 0 1 1 2 2 3 3 4 index
// | | | | |
// \___|___|___|___/ slice_from(&0); pos = 0
// \___|___|___/ slice_from(&2); pos = 1
// |___|___|___/ slice_from(&3); pos = 1; result.head_is_edge = false
// \___|___/ slice_from(&4); pos = 2
// \___/ slice_from(&6); pos = 3
// \|/ slice_from(&999); pos = 4
let (pos, pos_is_kv) = self.search_linear(min_key);
$NodeSlice {
has_edges: self.has_edges,
edges: if !self.has_edges {
self.edges
} else {
self.edges.$index(pos ..)
},
keys: &self.keys[pos ..],
vals: self.vals.$index(pos ..),
head_is_edge: !pos_is_kv,
tail_is_edge: self.tail_is_edge,
}
}
/// Returns a sub-slice with elements up to and including `max_key`.
#[cfg(stage0)]
pub fn slice_to(self, max_key: &K) -> $NodeSlice<'a, K, V> {
// _______________
// |_1_|_3_|_5_|_7_|
@ -1577,6 +1610,36 @@ macro_rules! node_slice_impl {
tail_is_edge: !pos_is_kv,
}
}
/// Returns a sub-slice with elements up to and including `max_key`.
#[cfg(not(stage0))]
pub fn slice_to(self, max_key: &K) -> $NodeSlice<'a, K, V> {
// _______________
// |_1_|_3_|_5_|_7_|
// | | | | |
// 0 0 1 1 2 2 3 3 4 index
// | | | | |
//\|/ | | | | slice_to(&0); pos = 0
// \___/ | | | slice_to(&2); pos = 1
// \___|___| | | slice_to(&3); pos = 1; result.tail_is_edge = false
// \___|___/ | | slice_to(&4); pos = 2
// \___|___|___/ | slice_to(&6); pos = 3
// \___|___|___|___/ slice_to(&999); pos = 4
let (pos, pos_is_kv) = self.search_linear(max_key);
let pos = pos + if pos_is_kv { 1 } else { 0 };
$NodeSlice {
has_edges: self.has_edges,
edges: if !self.has_edges {
self.edges
} else {
self.edges.$index(.. (pos + 1))
},
keys: &self.keys[..pos],
vals: self.vals.$index(.. pos),
head_is_edge: self.head_is_edge,
tail_is_edge: !pos_is_kv,
}
}
}
impl<'a, K: 'a, V: 'a> $NodeSlice<'a, K, V> {

View file

@ -116,6 +116,7 @@ impl<T> BTreeSet<T> {
/// # Examples
///
/// ```
/// # #![feature(core)]
/// use std::collections::BTreeSet;
///
/// let set: BTreeSet<usize> = [1, 2, 3, 4].iter().cloned().collect();
@ -137,6 +138,7 @@ impl<T> BTreeSet<T> {
/// # Examples
///
/// ```
/// # #![feature(core)]
/// use std::collections::BTreeSet;
///
/// let set: BTreeSet<usize> = [1, 2, 3, 4].iter().cloned().collect();
@ -162,6 +164,7 @@ impl<T: Ord> BTreeSet<T> {
/// # Examples
///
/// ```
/// # #![feature(collections)]
/// use std::collections::BTreeSet;
/// use std::collections::Bound::{Included, Unbounded};
///
@ -190,6 +193,7 @@ impl<T: Ord> BTreeSet<T> {
/// # Examples
///
/// ```
/// # #![feature(core)]
/// use std::collections::BTreeSet;
///
/// let mut a = BTreeSet::new();
@ -213,6 +217,7 @@ impl<T: Ord> BTreeSet<T> {
/// # Examples
///
/// ```
/// # #![feature(core)]
/// use std::collections::BTreeSet;
///
/// let mut a = BTreeSet::new();
@ -237,6 +242,7 @@ impl<T: Ord> BTreeSet<T> {
/// # Examples
///
/// ```
/// # #![feature(core)]
/// use std::collections::BTreeSet;
///
/// let mut a = BTreeSet::new();
@ -261,6 +267,7 @@ impl<T: Ord> BTreeSet<T> {
/// # Examples
///
/// ```
/// # #![feature(core)]
/// use std::collections::BTreeSet;
///
/// let mut a = BTreeSet::new();
@ -333,6 +340,7 @@ impl<T: Ord> BTreeSet<T> {
/// # Examples
///
/// ```
/// # #![feature(core)]
/// use std::collections::BTreeSet;
///
/// let set: BTreeSet<_> = [1, 2, 3].iter().cloned().collect();
@ -350,6 +358,7 @@ impl<T: Ord> BTreeSet<T> {
/// # Examples
///
/// ```
/// # #![feature(core)]
/// use std::collections::BTreeSet;
///
/// let a: BTreeSet<_> = [1, 2, 3].iter().cloned().collect();
@ -371,6 +380,7 @@ impl<T: Ord> BTreeSet<T> {
/// # Examples
///
/// ```
/// # #![feature(core)]
/// use std::collections::BTreeSet;
///
/// let sup: BTreeSet<_> = [1, 2, 3].iter().cloned().collect();
@ -413,6 +423,7 @@ impl<T: Ord> BTreeSet<T> {
/// # Examples
///
/// ```
/// # #![feature(core)]
/// use std::collections::BTreeSet;
///
/// let sub: BTreeSet<_> = [1, 2].iter().cloned().collect();
@ -628,6 +639,9 @@ impl<T: Debug> Debug for BTreeSet<T> {
}
}
impl<'a, T> Clone for Iter<'a, T> {
fn clone(&self) -> Iter<'a, T> { Iter { iter: self.iter.clone() } }
}
#[stable(feature = "rust1", since = "1.0.0")]
impl<'a, T> Iterator for Iter<'a, T> {
type Item = &'a T;
@ -658,6 +672,9 @@ impl<T> DoubleEndedIterator for IntoIter<T> {
impl<T> ExactSizeIterator for IntoIter<T> {}
impl<'a, T> Clone for Range<'a, T> {
fn clone(&self) -> Range<'a, T> { Range { iter: self.iter.clone() } }
}
impl<'a, T> Iterator for Range<'a, T> {
type Item = &'a T;
@ -677,6 +694,11 @@ fn cmp_opt<T: Ord>(x: Option<&T>, y: Option<&T>,
}
}
impl<'a, T> Clone for Difference<'a, T> {
fn clone(&self) -> Difference<'a, T> {
Difference { a: self.a.clone(), b: self.b.clone() }
}
}
#[stable(feature = "rust1", since = "1.0.0")]
impl<'a, T: Ord> Iterator for Difference<'a, T> {
type Item = &'a T;
@ -692,6 +714,11 @@ impl<'a, T: Ord> Iterator for Difference<'a, T> {
}
}
impl<'a, T> Clone for SymmetricDifference<'a, T> {
fn clone(&self) -> SymmetricDifference<'a, T> {
SymmetricDifference { a: self.a.clone(), b: self.b.clone() }
}
}
#[stable(feature = "rust1", since = "1.0.0")]
impl<'a, T: Ord> Iterator for SymmetricDifference<'a, T> {
type Item = &'a T;
@ -707,6 +734,11 @@ impl<'a, T: Ord> Iterator for SymmetricDifference<'a, T> {
}
}
impl<'a, T> Clone for Intersection<'a, T> {
fn clone(&self) -> Intersection<'a, T> {
Intersection { a: self.a.clone(), b: self.b.clone() }
}
}
#[stable(feature = "rust1", since = "1.0.0")]
impl<'a, T: Ord> Iterator for Intersection<'a, T> {
type Item = &'a T;
@ -728,6 +760,11 @@ impl<'a, T: Ord> Iterator for Intersection<'a, T> {
}
}
impl<'a, T> Clone for Union<'a, T> {
fn clone(&self) -> Union<'a, T> {
Union { a: self.a.clone(), b: self.b.clone() }
}
}
#[stable(feature = "rust1", since = "1.0.0")]
impl<'a, T: Ord> Iterator for Union<'a, T> {
type Item = &'a T;

View file

@ -174,6 +174,7 @@
//! like:
//!
//! ```
//! # #![feature(core, std_misc)]
//! use std::fmt;
//! use std::f64;
//! use std::num::Float;
@ -261,6 +262,7 @@
//! Example usage is:
//!
//! ```
//! # #![feature(old_io)]
//! # #![allow(unused_must_use)]
//! use std::io::Write;
//! let mut w = Vec::new();
@ -288,6 +290,7 @@
//! off, some example usage is:
//!
//! ```
//! # #![feature(old_io)]
//! use std::fmt;
//! use std::io::{self, Write};
//!

View file

@ -22,6 +22,7 @@
html_favicon_url = "http://www.rust-lang.org/favicon.ico",
html_root_url = "http://doc.rust-lang.org/nightly/",
html_playground_url = "http://play.rust-lang.org/")]
#![doc(test(no_crate_inject))]
#![feature(alloc)]
#![feature(box_syntax)]
@ -36,7 +37,8 @@
#![feature(unsafe_no_drop_flag)]
#![feature(step_by)]
#![feature(str_char)]
#![cfg_attr(test, feature(rand, rustc_private, test))]
#![feature(convert)]
#![cfg_attr(test, feature(rand, rustc_private, test, hash, collections))]
#![cfg_attr(test, allow(deprecated))] // rand
#![feature(no_std)]

View file

@ -235,6 +235,7 @@ impl<T> LinkedList<T> {
/// # Examples
///
/// ```
/// # #![feature(collections)]
/// use std::collections::LinkedList;
///
/// let mut a = LinkedList::new();
@ -483,6 +484,7 @@ impl<T> LinkedList<T> {
/// # Examples
///
/// ```
/// # #![feature(collections)]
/// use std::collections::LinkedList;
///
/// let mut dl = LinkedList::new();
@ -530,6 +532,7 @@ impl<T> LinkedList<T> {
/// # Examples
///
/// ```
/// # #![feature(collections)]
/// use std::collections::LinkedList;
///
/// let mut d = LinkedList::new();
@ -548,6 +551,7 @@ impl<T> LinkedList<T> {
/// # Examples
///
/// ```
/// # #![feature(collections)]
/// use std::collections::LinkedList;
///
/// let mut d = LinkedList::new();
@ -573,6 +577,7 @@ impl<T> LinkedList<T> {
/// # Examples
///
/// ```
/// # #![feature(collections)]
/// use std::collections::LinkedList;
///
/// let mut d = LinkedList::new();
@ -765,6 +770,7 @@ impl<'a, A> IterMut<'a, A> {
/// # Examples
///
/// ```
/// # #![feature(collections)]
/// use std::collections::LinkedList;
///
/// let mut list: LinkedList<_> = vec![1, 3, 4].into_iter().collect();
@ -792,6 +798,7 @@ impl<'a, A> IterMut<'a, A> {
/// # Examples
///
/// ```
/// # #![feature(collections)]
/// use std::collections::LinkedList;
///
/// let mut list: LinkedList<_> = vec![1, 2, 3].into_iter().collect();
@ -832,6 +839,8 @@ impl<A> DoubleEndedIterator for IntoIter<A> {
fn next_back(&mut self) -> Option<A> { self.list.pop_back() }
}
impl<A> ExactSizeIterator for IntoIter<A> {}
#[stable(feature = "rust1", since = "1.0.0")]
impl<A> FromIterator<A> for LinkedList<A> {
fn from_iter<T: IntoIterator<Item=A>>(iter: T) -> LinkedList<A> {

View file

@ -14,6 +14,7 @@
//! Slices are a view into a block of memory represented as a pointer and a length.
//!
//! ```rust
//! # #![feature(core)]
//! // slicing a Vec
//! let vec = vec!(1, 2, 3);
//! let int_slice = vec.as_slice();
@ -88,6 +89,7 @@
#![stable(feature = "rust1", since = "1.0.0")]
use alloc::boxed::Box;
use core::convert::AsRef;
use core::clone::Clone;
use core::cmp::Ordering::{self, Greater, Less};
use core::cmp::{self, Ord, PartialEq};
@ -270,6 +272,7 @@ impl<T> [T] {
/// # Examples
///
/// ```rust
/// # #![feature(collections)]
/// let mut a = [1, 2, 3, 4, 5];
/// let b = vec![6, 7, 8];
/// let num_moved = a.move_from(b, 0, 3);
@ -560,6 +563,7 @@ impl<T> [T] {
/// found; the fourth could match any position in `[1,4]`.
///
/// ```rust
/// # #![feature(core)]
/// let s = [0, 1, 1, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55];
/// let s = s.as_slice();
///
@ -842,6 +846,7 @@ impl<T> [T] {
/// # Examples
///
/// ```rust
/// # #![feature(collections)]
/// let v = [1, 2, 3];
/// let mut perms = v.permutations();
///
@ -853,6 +858,7 @@ impl<T> [T] {
/// Iterating through permutations one by one.
///
/// ```rust
/// # #![feature(collections)]
/// let v = [1, 2, 3];
/// let mut perms = v.permutations();
///
@ -874,6 +880,7 @@ impl<T> [T] {
/// # Example
///
/// ```rust
/// # #![feature(collections)]
/// let mut dst = [0, 0, 0];
/// let src = [1, 2];
///
@ -921,6 +928,7 @@ impl<T> [T] {
/// found; the fourth could match any position in `[1,4]`.
///
/// ```rust
/// # #![feature(core)]
/// let s = [0, 1, 1, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55];
/// let s = s.as_slice();
///
@ -950,6 +958,7 @@ impl<T> [T] {
/// # Example
///
/// ```rust
/// # #![feature(collections)]
/// let v: &mut [_] = &mut [0, 1, 2];
/// v.next_permutation();
/// let b: &mut [_] = &mut [0, 2, 1];
@ -972,6 +981,7 @@ impl<T> [T] {
/// # Example
///
/// ```rust
/// # #![feature(collections)]
/// let v: &mut [_] = &mut [1, 0, 2];
/// v.prev_permutation();
/// let b: &mut [_] = &mut [0, 2, 1];
@ -1088,23 +1098,23 @@ pub trait SliceConcatExt<T: ?Sized, U> {
fn connect(&self, sep: &T) -> U;
}
impl<T: Clone, V: AsSlice<T>> SliceConcatExt<T, Vec<T>> for [V] {
impl<T: Clone, V: AsRef<[T]>> SliceConcatExt<T, Vec<T>> for [V] {
fn concat(&self) -> Vec<T> {
let size = self.iter().fold(0, |acc, v| acc + v.as_slice().len());
let size = self.iter().fold(0, |acc, v| acc + v.as_ref().len());
let mut result = Vec::with_capacity(size);
for v in self {
result.push_all(v.as_slice())
result.push_all(v.as_ref())
}
result
}
fn connect(&self, sep: &T) -> Vec<T> {
let size = self.iter().fold(0, |acc, v| acc + v.as_slice().len());
let size = self.iter().fold(0, |acc, v| acc + v.as_ref().len());
let mut result = Vec::with_capacity(size + self.len());
let mut first = true;
for v in self {
if first { first = false } else { result.push(sep.clone()) }
result.push_all(v.as_slice())
result.push_all(v.as_ref())
}
result
}

View file

@ -61,10 +61,10 @@ use core::iter::AdditiveIterator;
use core::iter::{Iterator, IteratorExt, Extend};
use core::option::Option::{self, Some, None};
use core::result::Result;
use core::slice::AsSlice;
use core::str as core_str;
use unicode::str::{UnicodeStr, Utf16Encoder};
use core::convert::AsRef;
use vec_deque::VecDeque;
use borrow::{Borrow, ToOwned};
use string::String;
@ -74,8 +74,8 @@ use slice::SliceConcatExt;
pub use core::str::{FromStr, Utf8Error, Str};
pub use core::str::{Lines, LinesAny, MatchIndices, SplitStr, CharRange};
pub use core::str::{Split, SplitTerminator};
pub use core::str::{SplitN, RSplitN};
pub use core::str::{Split, SplitTerminator, SplitN};
pub use core::str::{RSplit, RSplitN};
pub use core::str::{from_utf8, CharEq, Chars, CharIndices, Bytes};
pub use core::str::{from_utf8_unchecked, from_c_str, ParseBoolError};
pub use unicode::str::{Words, Graphemes, GraphemeIndices};
@ -86,51 +86,47 @@ pub use core::str::{Searcher, ReverseSearcher, DoubleEndedSearcher, SearchStep};
Section: Creating a string
*/
impl<S: Str> SliceConcatExt<str, String> for [S] {
impl<S: AsRef<str>> SliceConcatExt<str, String> for [S] {
fn concat(&self) -> String {
let s = self.as_slice();
if s.is_empty() {
if self.is_empty() {
return String::new();
}
// `len` calculation may overflow but push_str will check boundaries
let len = s.iter().map(|s| s.as_slice().len()).sum();
let len = self.iter().map(|s| s.as_ref().len()).sum();
let mut result = String::with_capacity(len);
for s in s {
result.push_str(s.as_slice())
for s in self {
result.push_str(s.as_ref())
}
result
}
fn connect(&self, sep: &str) -> String {
let s = self.as_slice();
if s.is_empty() {
if self.is_empty() {
return String::new();
}
// concat is faster
if sep.is_empty() {
return s.concat();
return self.concat();
}
// this is wrong without the guarantee that `self` is non-empty
// `len` calculation may overflow but push_str but will check boundaries
let len = sep.len() * (s.len() - 1)
+ s.iter().map(|s| s.as_slice().len()).sum();
let len = sep.len() * (self.len() - 1)
+ self.iter().map(|s| s.as_ref().len()).sum();
let mut result = String::with_capacity(len);
let mut first = true;
for s in s {
for s in self {
if first {
first = false;
} else {
result.push_str(sep);
}
result.push_str(s.as_slice());
result.push_str(s.as_ref());
}
result
}
@ -548,6 +544,7 @@ impl str {
/// # Examples
///
/// ```
/// # #![feature(collections)]
/// assert!("hello".contains_char('e'));
///
/// assert!(!"hello".contains_char('z'));
@ -699,23 +696,48 @@ impl str {
core_str::StrExt::split_terminator(&self[..], pat)
}
/// An iterator over substrings of `self`, separated by characters matched by a pattern,
/// An iterator over substrings of `self`, separated by a pattern,
/// starting from the end of the string.
///
/// Restricted to splitting at most `count` times.
///
/// The pattern can be a simple `&str`, or a closure that determines the split.
///
/// # Examples
///
/// Simple `&str` patterns:
/// Simple patterns:
///
/// ```
/// let v: Vec<&str> = "Mary had a little lamb".rsplit(' ').collect();
/// assert_eq!(v, ["lamb", "little", "a", "had", "Mary"]);
///
/// let v: Vec<&str> = "lion::tiger::leopard".rsplit("::").collect();
/// assert_eq!(v, ["leopard", "tiger", "lion"]);
/// ```
///
/// More complex patterns with a lambda:
///
/// ```
/// let v: Vec<&str> = "abc1def2ghi".rsplit(|c: char| c.is_numeric()).collect();
/// assert_eq!(v, ["ghi", "def", "abc"]);
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
pub fn rsplit<'a, P: Pattern<'a>>(&'a self, pat: P) -> RSplit<'a, P>
where P::Searcher: ReverseSearcher<'a>
{
core_str::StrExt::rsplit(&self[..], pat)
}
/// An iterator over substrings of `self`, separated by a pattern,
/// starting from the end of the string, restricted to splitting
/// at most `count` times.
///
/// # Examples
///
/// Simple patterns:
///
/// ```
/// let v: Vec<&str> = "Mary had a little lamb".rsplitn(2, ' ').collect();
/// assert_eq!(v, ["lamb", "little", "Mary had a"]);
///
/// let v: Vec<&str> = "lionXXtigerXleopard".rsplitn(2, 'X').collect();
/// assert_eq!(v, ["leopard", "tiger", "lionX"]);
/// let v: Vec<&str> = "lion::tiger::leopard".rsplitn(1, "::").collect();
/// assert_eq!(v, ["leopard", "lion::tiger"]);
/// ```
///
/// More complex patterns with a lambda:
@ -725,7 +747,9 @@ impl str {
/// assert_eq!(v, ["ghi", "abc1def"]);
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
pub fn rsplitn<'a, P: Pattern<'a>>(&'a self, count: usize, pat: P) -> RSplitN<'a, P> {
pub fn rsplitn<'a, P: Pattern<'a>>(&'a self, count: usize, pat: P) -> RSplitN<'a, P>
where P::Searcher: ReverseSearcher<'a>
{
core_str::StrExt::rsplitn(&self[..], count, pat)
}
@ -739,6 +763,7 @@ impl str {
/// # Examples
///
/// ```
/// # #![feature(collections)]
/// let v: Vec<(usize, usize)> = "abcXXXabcYYYabc".match_indices("abc").collect();
/// assert_eq!(v, [(0,3), (6,9), (12,15)]);
///
@ -761,6 +786,7 @@ impl str {
/// # Examples
///
/// ```
/// # #![feature(collections)]
/// let v: Vec<&str> = "abcXXXabcYYYabc".split_str("abc").collect();
/// assert_eq!(v, ["", "XXX", "YYY", ""]);
///
@ -869,6 +895,7 @@ impl str {
/// # Examples
///
/// ```
/// # #![feature(collections)]
/// let s = "Löwe 老虎 Léopard";
///
/// assert_eq!(s.slice_chars(0, 4), "Löwe");
@ -1019,6 +1046,7 @@ impl str {
/// # Examples
///
/// ```
/// # #![feature(str_char)]
/// let s = "Löwe 老虎 Léopard";
/// assert!(s.is_char_boundary(0));
/// // start of `老`
@ -1055,6 +1083,7 @@ impl str {
/// done by `.chars()` or `.char_indices()`.
///
/// ```
/// # #![feature(str_char, core)]
/// use std::str::CharRange;
///
/// let s = "中华Việt Nam";
@ -1105,6 +1134,7 @@ impl str {
/// done by `.chars().rev()` or `.char_indices()`.
///
/// ```
/// # #![feature(str_char, core)]
/// use std::str::CharRange;
///
/// let s = "中华Việt Nam";
@ -1148,6 +1178,7 @@ impl str {
/// # Examples
///
/// ```
/// # #![feature(str_char)]
/// let s = "abπc";
/// assert_eq!(s.char_at(1), 'b');
/// assert_eq!(s.char_at(2), 'π');
@ -1172,6 +1203,7 @@ impl str {
/// # Examples
///
/// ```
/// # #![feature(str_char)]
/// let s = "abπc";
/// assert_eq!(s.char_at_reverse(1), 'a');
/// assert_eq!(s.char_at_reverse(2), 'b');
@ -1286,6 +1318,7 @@ impl str {
/// # Examples
///
/// ```
/// # #![feature(collections)]
/// let s = "Löwe 老虎 Léopard";
///
/// assert_eq!(s.find_str("老虎 L"), Some(6));
@ -1307,6 +1340,7 @@ impl str {
/// # Examples
///
/// ```
/// # #![feature(str_char)]
/// let s = "Löwe 老虎 Léopard";
/// let (c, s1) = s.slice_shift_char().unwrap();
///
@ -1335,6 +1369,7 @@ impl str {
/// # Examples
///
/// ```
/// # #![feature(collections)]
/// let string = "a\nb\nc";
/// let lines: Vec<&str> = string.lines().collect();
///
@ -1434,6 +1469,7 @@ impl str {
/// # Examples
///
/// ```
/// # #![feature(unicode, core)]
/// let gr1 = "a\u{310}e\u{301}o\u{308}\u{332}".graphemes(true).collect::<Vec<&str>>();
/// let b: &[_] = &["a\u{310}", "e\u{301}", "o\u{308}\u{332}"];
///
@ -1456,6 +1492,7 @@ impl str {
/// # Examples
///
/// ```
/// # #![feature(unicode, core)]
/// let gr_inds = "a̐éö̲\r\n".grapheme_indices(true).collect::<Vec<(usize, &str)>>();
/// let b: &[_] = &[(0, "a̐"), (3, "é"), (6, "ö̲"), (11, "\r\n")];
///
@ -1475,6 +1512,7 @@ impl str {
/// # Examples
///
/// ```
/// # #![feature(str_words)]
/// let some_words = " Mary had\ta little \n\t lamb";
/// let v: Vec<&str> = some_words.words().collect();
///

View file

@ -25,6 +25,7 @@ use core::mem;
use core::ops::{self, Deref, Add, Index};
use core::ptr;
use core::slice;
use core::str::Pattern;
use unicode::str as unicode_str;
use unicode::str::Utf16Item;
@ -90,6 +91,7 @@ impl String {
/// # Examples
///
/// ```
/// # #![feature(collections, core)]
/// let s = String::from_str("hello");
/// assert_eq!(s.as_slice(), "hello");
/// ```
@ -122,6 +124,7 @@ impl String {
/// # Examples
///
/// ```
/// # #![feature(core)]
/// use std::str::Utf8Error;
///
/// let hello_vec = vec![104, 101, 108, 108, 111];
@ -350,6 +353,7 @@ impl String {
/// # Examples
///
/// ```
/// # #![feature(collections)]
/// let s = String::from_str("hello");
/// let bytes = s.into_bytes();
/// assert_eq!(bytes, [104, 101, 108, 108, 111]);
@ -365,6 +369,7 @@ impl String {
/// # Examples
///
/// ```
/// # #![feature(collections)]
/// let mut s = String::from_str("foo");
/// s.push_str("bar");
/// assert_eq!(s, "foobar");
@ -441,6 +446,7 @@ impl String {
/// # Examples
///
/// ```
/// # #![feature(collections)]
/// let mut s = String::from_str("foo");
/// s.reserve(100);
/// assert!(s.capacity() >= 100);
@ -458,6 +464,7 @@ impl String {
/// # Examples
///
/// ```
/// # #![feature(collections)]
/// let mut s = String::from_str("abc");
/// s.push('1');
/// s.push('2');
@ -493,6 +500,7 @@ impl String {
/// # Examples
///
/// ```
/// # #![feature(collections)]
/// let s = String::from_str("hello");
/// let b: &[_] = &[104, 101, 108, 108, 111];
/// assert_eq!(s.as_bytes(), b);
@ -513,6 +521,7 @@ impl String {
/// # Examples
///
/// ```
/// # #![feature(collections)]
/// let mut s = String::from_str("hello");
/// s.truncate(2);
/// assert_eq!(s, "he");
@ -530,6 +539,7 @@ impl String {
/// # Examples
///
/// ```
/// # #![feature(collections)]
/// let mut s = String::from_str("foo");
/// assert_eq!(s.pop(), Some('o'));
/// assert_eq!(s.pop(), Some('o'));
@ -567,6 +577,7 @@ impl String {
/// # Examples
///
/// ```
/// # #![feature(collections)]
/// let mut s = String::from_str("foo");
/// assert_eq!(s.remove(0), 'f');
/// assert_eq!(s.remove(1), 'o');
@ -629,6 +640,7 @@ impl String {
/// # Examples
///
/// ```
/// # #![feature(collections)]
/// let mut s = String::from_str("hello");
/// unsafe {
/// let vec = s.as_mut_vec();
@ -765,6 +777,25 @@ impl<'a> Extend<&'a str> for String {
}
}
/// A convenience impl that delegates to the impl for `&str`
impl<'a, 'b> Pattern<'a> for &'b String {
type Searcher = <&'b str as Pattern<'a>>::Searcher;
fn into_searcher(self, haystack: &'a str) -> <&'b str as Pattern<'a>>::Searcher {
self[..].into_searcher(haystack)
}
#[inline]
fn is_contained_in(self, haystack: &'a str) -> bool {
self[..].is_contained_in(haystack)
}
#[inline]
fn is_prefix_of(self, haystack: &'a str) -> bool {
self[..].is_prefix_of(haystack)
}
}
#[stable(feature = "rust1", since = "1.0.0")]
impl PartialEq for String {
#[inline]
@ -814,6 +845,7 @@ impl<'a, 'b> PartialEq<Cow<'a, str>> for &'b str {
}
#[unstable(feature = "collections", reason = "waiting on Str stabilization")]
#[allow(deprecated)]
impl Str for String {
#[inline]
#[stable(feature = "rust1", since = "1.0.0")]
@ -870,34 +902,66 @@ impl<'a> Add<&'a str> for String {
#[stable(feature = "rust1", since = "1.0.0")]
impl ops::Index<ops::Range<usize>> for String {
type Output = str;
#[cfg(stage0)]
#[inline]
fn index(&self, index: &ops::Range<usize>) -> &str {
&self[..][*index]
}
#[cfg(not(stage0))]
#[inline]
fn index(&self, index: ops::Range<usize>) -> &str {
&self[..][index]
}
}
#[stable(feature = "rust1", since = "1.0.0")]
impl ops::Index<ops::RangeTo<usize>> for String {
type Output = str;
#[cfg(stage0)]
#[inline]
fn index(&self, index: &ops::RangeTo<usize>) -> &str {
&self[..][*index]
}
#[cfg(not(stage0))]
#[inline]
fn index(&self, index: ops::RangeTo<usize>) -> &str {
&self[..][index]
}
}
#[stable(feature = "rust1", since = "1.0.0")]
impl ops::Index<ops::RangeFrom<usize>> for String {
type Output = str;
#[cfg(stage0)]
#[inline]
fn index(&self, index: &ops::RangeFrom<usize>) -> &str {
&self[..][*index]
}
#[cfg(not(stage0))]
#[inline]
fn index(&self, index: ops::RangeFrom<usize>) -> &str {
&self[..][index]
}
}
#[stable(feature = "rust1", since = "1.0.0")]
impl ops::Index<ops::RangeFull> for String {
type Output = str;
#[cfg(stage0)]
#[inline]
fn index(&self, _index: &ops::RangeFull) -> &str {
unsafe { mem::transmute(&*self.vec) }
}
#[cfg(not(stage0))]
#[inline]
fn index(&self, _index: ops::RangeFull) -> &str {
unsafe { mem::transmute(&*self.vec) }
}
}
#[stable(feature = "rust1", since = "1.0.0")]
@ -930,6 +994,7 @@ impl<'a> Deref for DerefString<'a> {
/// # Examples
///
/// ```
/// # #![feature(collections)]
/// use std::string::as_string;
///
/// fn string_consumer(s: String) {
@ -973,6 +1038,27 @@ impl<T: fmt::Display + ?Sized> ToString for T {
}
}
#[stable(feature = "rust1", since = "1.0.0")]
impl AsRef<str> for String {
fn as_ref(&self) -> &str {
self
}
}
#[stable(feature = "rust1", since = "1.0.0")]
impl<'a> From<&'a str> for String {
fn from(s: &'a str) -> String {
s.to_string()
}
}
#[stable(feature = "rust1", since = "1.0.0")]
impl Into<Vec<u8>> for String {
fn into(self) -> Vec<u8> {
self.into_bytes()
}
}
#[stable(feature = "rust1", since = "1.0.0")]
impl IntoCow<'static, str> for String {
#[inline]
@ -989,6 +1075,7 @@ impl<'a> IntoCow<'a, str> for &'a str {
}
}
#[allow(deprecated)]
impl<'a> Str for Cow<'a, str> {
#[inline]
fn as_slice<'b>(&'b self) -> &'b str {

View file

@ -8,7 +8,8 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
//! A growable list type with heap-allocated contents, written `Vec<T>` but pronounced 'vector.'
//! A growable list type with heap-allocated contents, written `Vec<T>` but
//! pronounced 'vector.'
//!
//! Vectors have `O(1)` indexing, push (to the end) and pop (from the end).
//!
@ -73,6 +74,7 @@ use borrow::{Cow, IntoCow};
/// # Examples
///
/// ```
/// # #![feature(collections)]
/// let mut vec = Vec::new();
/// vec.push(1);
/// vec.push(2);
@ -123,17 +125,19 @@ use borrow::{Cow, IntoCow};
///
/// # Capacity and reallocation
///
/// The capacity of a vector is the amount of space allocated for any future elements that will be
/// added onto the vector. This is not to be confused with the *length* of a vector, which
/// specifies the number of actual elements within the vector. If a vector's length exceeds its
/// capacity, its capacity will automatically be increased, but its elements will have to be
/// The capacity of a vector is the amount of space allocated for any future
/// elements that will be added onto the vector. This is not to be confused with
/// the *length* of a vector, which specifies the number of actual elements
/// within the vector. If a vector's length exceeds its capacity, its capacity
/// will automatically be increased, but its elements will have to be
/// reallocated.
///
/// For example, a vector with capacity 10 and length 0 would be an empty vector with space for 10
/// more elements. Pushing 10 or fewer elements onto the vector will not change its capacity or
/// cause reallocation to occur. However, if the vector's length is increased to 11, it will have
/// to reallocate, which can be slow. For this reason, it is recommended to use
/// `Vec::with_capacity` whenever possible to specify how big the vector is expected to get.
/// For example, a vector with capacity 10 and length 0 would be an empty vector
/// with space for 10 more elements. Pushing 10 or fewer elements onto the
/// vector will not change its capacity or cause reallocation to occur. However,
/// if the vector's length is increased to 11, it will have to reallocate, which
/// can be slow. For this reason, it is recommended to use `Vec::with_capacity`
/// whenever possible to specify how big the vector is expected to get.
#[unsafe_no_drop_flag]
#[stable(feature = "rust1", since = "1.0.0")]
pub struct Vec<T> {
@ -345,6 +349,7 @@ impl<T> Vec<T> {
/// # Examples
///
/// ```
/// # #![feature(collections)]
/// let mut vec = Vec::with_capacity(10);
/// vec.push_all(&[1, 2, 3]);
/// assert_eq!(vec.capacity(), 10);
@ -400,6 +405,7 @@ impl<T> Vec<T> {
/// # Examples
///
/// ```
/// # #![feature(collections)]
/// let mut vec = vec![1, 2, 3, 4];
/// vec.truncate(2);
/// assert_eq!(vec, [1, 2]);
@ -565,6 +571,7 @@ impl<T> Vec<T> {
/// # Examples
///
/// ```
/// # #![feature(collections)]
/// let mut v = vec![1, 2, 3];
/// assert_eq!(v.remove(1), 2);
/// assert_eq!(v, [1, 3]);
@ -696,6 +703,7 @@ impl<T> Vec<T> {
/// # Examples
///
/// ```
/// # #![feature(collections)]
/// let mut vec = vec![1, 2, 3];
/// let mut vec2 = vec![4, 5, 6];
/// vec.append(&mut vec2);
@ -732,6 +740,7 @@ impl<T> Vec<T> {
/// # Examples
///
/// ```
/// # #![feature(collections)]
/// let mut v = vec!["a".to_string(), "b".to_string()];
/// for s in v.drain() {
/// // s has type String, not &String
@ -813,6 +822,7 @@ impl<T> Vec<T> {
/// # Examples
///
/// ```
/// # #![feature(collections, core)]
/// let v = vec![0, 1, 2];
/// let w = v.map_in_place(|i| i + 3);
/// assert_eq!(w.as_slice(), [3, 4, 5].as_slice());
@ -1015,6 +1025,7 @@ impl<T> Vec<T> {
/// # Examples
///
/// ```
/// # #![feature(collections)]
/// let mut vec = vec![1,2,3];
/// let vec2 = vec.split_off(1);
/// assert_eq!(vec, [1]);
@ -1053,6 +1064,7 @@ impl<T: Clone> Vec<T> {
/// # Examples
///
/// ```
/// # #![feature(collections)]
/// let mut vec = vec!["hello"];
/// vec.resize(3, "world");
/// assert_eq!(vec, ["hello", "world", "world"]);
@ -1081,6 +1093,7 @@ impl<T: Clone> Vec<T> {
/// # Examples
///
/// ```
/// # #![feature(collections)]
/// let mut vec = vec![1];
/// vec.push_all(&[2, 3, 4]);
/// assert_eq!(vec, [1, 2, 3, 4]);
@ -1323,90 +1336,178 @@ impl<T: Hash> Hash for Vec<T> {
impl<T> Index<usize> for Vec<T> {
type Output = T;
#[cfg(stage0)]
#[inline]
fn index(&self, index: &usize) -> &T {
// NB built-in indexing via `&[T]`
&(**self)[*index]
}
#[cfg(not(stage0))]
#[inline]
fn index(&self, index: usize) -> &T {
// NB built-in indexing via `&[T]`
&(**self)[index]
}
}
#[stable(feature = "rust1", since = "1.0.0")]
impl<T> IndexMut<usize> for Vec<T> {
#[cfg(stage0)]
#[inline]
fn index_mut(&mut self, index: &usize) -> &mut T {
// NB built-in indexing via `&mut [T]`
&mut (**self)[*index]
}
#[cfg(not(stage0))]
#[inline]
fn index_mut(&mut self, index: usize) -> &mut T {
// NB built-in indexing via `&mut [T]`
&mut (**self)[index]
}
}
#[stable(feature = "rust1", since = "1.0.0")]
impl<T> ops::Index<ops::Range<usize>> for Vec<T> {
type Output = [T];
#[cfg(stage0)]
#[inline]
fn index(&self, index: &ops::Range<usize>) -> &[T] {
Index::index(&**self, index)
}
#[cfg(not(stage0))]
#[inline]
fn index(&self, index: ops::Range<usize>) -> &[T] {
Index::index(&**self, index)
}
}
#[stable(feature = "rust1", since = "1.0.0")]
impl<T> ops::Index<ops::RangeTo<usize>> for Vec<T> {
type Output = [T];
#[cfg(stage0)]
#[inline]
fn index(&self, index: &ops::RangeTo<usize>) -> &[T] {
Index::index(&**self, index)
}
#[cfg(not(stage0))]
#[inline]
fn index(&self, index: ops::RangeTo<usize>) -> &[T] {
Index::index(&**self, index)
}
}
#[stable(feature = "rust1", since = "1.0.0")]
impl<T> ops::Index<ops::RangeFrom<usize>> for Vec<T> {
type Output = [T];
#[cfg(stage0)]
#[inline]
fn index(&self, index: &ops::RangeFrom<usize>) -> &[T] {
Index::index(&**self, index)
}
#[cfg(not(stage0))]
#[inline]
fn index(&self, index: ops::RangeFrom<usize>) -> &[T] {
Index::index(&**self, index)
}
}
#[stable(feature = "rust1", since = "1.0.0")]
impl<T> ops::Index<ops::RangeFull> for Vec<T> {
type Output = [T];
#[cfg(stage0)]
#[inline]
fn index(&self, _index: &ops::RangeFull) -> &[T] {
self.as_slice()
self
}
#[cfg(not(stage0))]
#[inline]
fn index(&self, _index: ops::RangeFull) -> &[T] {
self
}
}
#[stable(feature = "rust1", since = "1.0.0")]
impl<T> ops::IndexMut<ops::Range<usize>> for Vec<T> {
#[cfg(stage0)]
#[inline]
fn index_mut(&mut self, index: &ops::Range<usize>) -> &mut [T] {
IndexMut::index_mut(&mut **self, index)
}
#[cfg(not(stage0))]
#[inline]
fn index_mut(&mut self, index: ops::Range<usize>) -> &mut [T] {
IndexMut::index_mut(&mut **self, index)
}
}
#[stable(feature = "rust1", since = "1.0.0")]
impl<T> ops::IndexMut<ops::RangeTo<usize>> for Vec<T> {
#[cfg(stage0)]
#[inline]
fn index_mut(&mut self, index: &ops::RangeTo<usize>) -> &mut [T] {
IndexMut::index_mut(&mut **self, index)
}
#[cfg(not(stage0))]
#[inline]
fn index_mut(&mut self, index: ops::RangeTo<usize>) -> &mut [T] {
IndexMut::index_mut(&mut **self, index)
}
}
#[stable(feature = "rust1", since = "1.0.0")]
impl<T> ops::IndexMut<ops::RangeFrom<usize>> for Vec<T> {
#[cfg(stage0)]
#[inline]
fn index_mut(&mut self, index: &ops::RangeFrom<usize>) -> &mut [T] {
IndexMut::index_mut(&mut **self, index)
}
#[cfg(not(stage0))]
#[inline]
fn index_mut(&mut self, index: ops::RangeFrom<usize>) -> &mut [T] {
IndexMut::index_mut(&mut **self, index)
}
}
#[stable(feature = "rust1", since = "1.0.0")]
impl<T> ops::IndexMut<ops::RangeFull> for Vec<T> {
#[cfg(stage0)]
#[inline]
fn index_mut(&mut self, _index: &ops::RangeFull) -> &mut [T] {
self.as_mut_slice()
}
#[cfg(not(stage0))]
#[inline]
fn index_mut(&mut self, _index: ops::RangeFull) -> &mut [T] {
self.as_mut_slice()
}
}
#[stable(feature = "rust1", since = "1.0.0")]
impl<T> ops::Deref for Vec<T> {
type Target = [T];
fn deref(&self) -> &[T] { self.as_slice() }
fn deref(&self) -> &[T] {
unsafe {
let p = *self.ptr;
assume(p != 0 as *mut T);
slice::from_raw_parts(p, self.len)
}
}
}
#[stable(feature = "rust1", since = "1.0.0")]
@ -1548,12 +1649,14 @@ impl<T: Ord> Ord for Vec<T> {
}
}
#[allow(deprecated)]
impl<T> AsSlice<T> for Vec<T> {
/// Returns a slice into `self`.
///
/// # Examples
///
/// ```
/// # #![feature(core)]
/// fn foo(slice: &[i32]) {}
///
/// let vec = vec![1, 2];
@ -1562,11 +1665,7 @@ impl<T> AsSlice<T> for Vec<T> {
#[inline]
#[stable(feature = "rust1", since = "1.0.0")]
fn as_slice(&self) -> &[T] {
unsafe {
let p = *self.ptr;
assume(p != 0 as *mut T);
slice::from_raw_parts(p, self.len)
}
self
}
}
@ -1614,6 +1713,46 @@ impl<T: fmt::Debug> fmt::Debug for Vec<T> {
}
}
#[stable(feature = "rust1", since = "1.0.0")]
impl<T> AsRef<Vec<T>> for Vec<T> {
fn as_ref(&self) -> &Vec<T> {
self
}
}
#[stable(feature = "rust1", since = "1.0.0")]
impl<T> Into<Vec<T>> for Vec<T> {
fn into(self) -> Vec<T> {
self
}
}
#[stable(feature = "rust1", since = "1.0.0")]
impl<T> AsRef<[T]> for Vec<T> {
fn as_ref(&self) -> &[T] {
self
}
}
#[stable(feature = "rust1", since = "1.0.0")]
impl<'a, T: Clone> From<&'a [T]> for Vec<T> {
#[cfg(not(test))]
fn from(s: &'a [T]) -> Vec<T> {
s.to_vec()
}
#[cfg(test)]
fn from(s: &'a [T]) -> Vec<T> {
::slice::to_vec(s)
}
}
#[stable(feature = "rust1", since = "1.0.0")]
impl<'a> From<&'a str> for Vec<u8> {
fn from(s: &'a str) -> Vec<u8> {
From::from(s.as_bytes())
}
}
////////////////////////////////////////////////////////////////////////////////
// Clone-on-write
////////////////////////////////////////////////////////////////////////////////

View file

@ -257,6 +257,7 @@ impl<T> VecDeque<T> {
/// # Examples
///
/// ```
/// # #![feature(collections)]
/// use std::collections::VecDeque;
///
/// let mut buf = VecDeque::new();
@ -284,6 +285,7 @@ impl<T> VecDeque<T> {
/// # Examples
///
/// ```
/// # #![feature(collections)]
/// use std::collections::VecDeque;
///
/// let buf: VecDeque<i32> = VecDeque::with_capacity(10);
@ -307,6 +309,7 @@ impl<T> VecDeque<T> {
/// # Examples
///
/// ```
/// # #![feature(collections)]
/// use std::collections::VecDeque;
///
/// let mut buf: VecDeque<i32> = vec![1].into_iter().collect();
@ -328,6 +331,7 @@ impl<T> VecDeque<T> {
/// # Examples
///
/// ```
/// # #![feature(collections)]
/// use std::collections::VecDeque;
///
/// let mut buf: VecDeque<i32> = vec![1].into_iter().collect();
@ -403,6 +407,7 @@ impl<T> VecDeque<T> {
/// # Examples
///
/// ```
/// # #![feature(collections)]
/// use std::collections::VecDeque;
///
/// let mut buf = VecDeque::with_capacity(15);
@ -489,6 +494,7 @@ impl<T> VecDeque<T> {
/// # Examples
///
/// ```
/// # #![feature(collections)]
/// use std::collections::VecDeque;
///
/// let mut buf = VecDeque::new();
@ -512,6 +518,7 @@ impl<T> VecDeque<T> {
/// # Examples
///
/// ```
/// # #![feature(core)]
/// use std::collections::VecDeque;
///
/// let mut buf = VecDeque::new();
@ -535,6 +542,7 @@ impl<T> VecDeque<T> {
/// # Examples
///
/// ```
/// # #![feature(core)]
/// use std::collections::VecDeque;
///
/// let mut buf = VecDeque::new();
@ -556,7 +564,7 @@ impl<T> VecDeque<T> {
}
}
/// Consumes the list into an iterator yielding elements by value.
/// Consumes the list into a front-to-back iterator yielding elements by value.
#[stable(feature = "rust1", since = "1.0.0")]
pub fn into_iter(self) -> IntoIter<T> {
IntoIter {
@ -644,6 +652,7 @@ impl<T> VecDeque<T> {
/// # Examples
///
/// ```
/// # #![feature(collections)]
/// use std::collections::VecDeque;
///
/// let mut v = VecDeque::new();
@ -882,6 +891,7 @@ impl<T> VecDeque<T> {
/// # Examples
///
/// ```
/// # #![feature(collections)]
/// use std::collections::VecDeque;
///
/// let mut buf = VecDeque::new();
@ -915,6 +925,7 @@ impl<T> VecDeque<T> {
/// # Examples
///
/// ```
/// # #![feature(collections)]
/// use std::collections::VecDeque;
///
/// let mut buf = VecDeque::new();
@ -948,6 +959,7 @@ impl<T> VecDeque<T> {
///
/// # Examples
/// ```
/// # #![feature(collections)]
/// use std::collections::VecDeque;
///
/// let mut buf = VecDeque::new();
@ -1321,6 +1333,7 @@ impl<T> VecDeque<T> {
/// # Examples
///
/// ```
/// # #![feature(collections)]
/// use std::collections::VecDeque;
///
/// let mut buf: VecDeque<_> = vec![1,2,3].into_iter().collect();
@ -1383,6 +1396,7 @@ impl<T> VecDeque<T> {
/// # Examples
///
/// ```
/// # #![feature(collections)]
/// use std::collections::VecDeque;
///
/// let mut buf: VecDeque<_> = vec![1, 2, 3].into_iter().collect();
@ -1407,6 +1421,7 @@ impl<T: Clone> VecDeque<T> {
/// # Examples
///
/// ```
/// # #![feature(collections)]
/// use std::collections::VecDeque;
///
/// let mut buf = VecDeque::new();
@ -1573,6 +1588,7 @@ impl<'a, T> DoubleEndedIterator for IterMut<'a, T> {
impl<'a, T> ExactSizeIterator for IterMut<'a, T> {}
/// A by-value VecDeque iterator
#[derive(Clone)]
#[stable(feature = "rust1", since = "1.0.0")]
pub struct IntoIter<T> {
inner: VecDeque<T>,
@ -1689,18 +1705,32 @@ impl<A: Hash> Hash for VecDeque<A> {
impl<A> Index<usize> for VecDeque<A> {
type Output = A;
#[cfg(stage0)]
#[inline]
fn index(&self, i: &usize) -> &A {
self.get(*i).expect("Out of bounds access")
}
#[cfg(not(stage0))]
#[inline]
fn index(&self, i: usize) -> &A {
self.get(i).expect("Out of bounds access")
}
}
#[stable(feature = "rust1", since = "1.0.0")]
impl<A> IndexMut<usize> for VecDeque<A> {
#[cfg(stage0)]
#[inline]
fn index_mut(&mut self, i: &usize) -> &mut A {
self.get_mut(*i).expect("Out of bounds access")
}
#[cfg(not(stage0))]
#[inline]
fn index_mut(&mut self, i: usize) -> &mut A {
self.get_mut(i).expect("Out of bounds access")
}
}
#[stable(feature = "rust1", since = "1.0.0")]

View file

@ -34,6 +34,7 @@ use vec::Vec;
/// # Examples
///
/// ```
/// # #![feature(collections)]
/// use std::collections::VecMap;
///
/// let mut months = VecMap::new();
@ -67,26 +68,28 @@ pub struct VecMap<V> {
}
/// A view into a single entry in a map, which may either be vacant or occupied.
#[unstable(feature = "collections",
reason = "precise API still under development")]
#[stable(feature = "rust1", since = "1.0.0")]
pub enum Entry<'a, V:'a> {
/// A vacant Entry
#[stable(feature = "rust1", since = "1.0.0")]
Vacant(VacantEntry<'a, V>),
/// An occupied Entry
#[stable(feature = "rust1", since = "1.0.0")]
Occupied(OccupiedEntry<'a, V>),
}
/// A vacant Entry.
#[unstable(feature = "collections",
reason = "precise API still under development")]
#[stable(feature = "rust1", since = "1.0.0")]
pub struct VacantEntry<'a, V:'a> {
map: &'a mut VecMap<V>,
index: usize,
}
/// An occupied Entry.
#[unstable(feature = "collections",
reason = "precise API still under development")]
#[stable(feature = "rust1", since = "1.0.0")]
pub struct OccupiedEntry<'a, V:'a> {
map: &'a mut VecMap<V>,
index: usize,
@ -132,6 +135,7 @@ impl<V> VecMap<V> {
/// # Examples
///
/// ```
/// # #![feature(collections)]
/// use std::collections::VecMap;
/// let mut map: VecMap<&str> = VecMap::new();
/// ```
@ -144,6 +148,7 @@ impl<V> VecMap<V> {
/// # Examples
///
/// ```
/// # #![feature(collections)]
/// use std::collections::VecMap;
/// let mut map: VecMap<&str> = VecMap::with_capacity(10);
/// ```
@ -158,6 +163,7 @@ impl<V> VecMap<V> {
/// # Examples
///
/// ```
/// # #![feature(collections)]
/// use std::collections::VecMap;
/// let map: VecMap<String> = VecMap::with_capacity(10);
/// assert!(map.capacity() >= 10);
@ -177,6 +183,7 @@ impl<V> VecMap<V> {
/// # Examples
///
/// ```
/// # #![feature(collections)]
/// use std::collections::VecMap;
/// let mut map: VecMap<&str> = VecMap::new();
/// map.reserve_len(10);
@ -201,6 +208,7 @@ impl<V> VecMap<V> {
/// # Examples
///
/// ```
/// # #![feature(collections)]
/// use std::collections::VecMap;
/// let mut map: VecMap<&str> = VecMap::new();
/// map.reserve_len_exact(10);
@ -240,6 +248,7 @@ impl<V> VecMap<V> {
/// # Examples
///
/// ```
/// # #![feature(collections)]
/// use std::collections::VecMap;
///
/// let mut map = VecMap::new();
@ -268,6 +277,7 @@ impl<V> VecMap<V> {
/// # Examples
///
/// ```
/// # #![feature(collections)]
/// use std::collections::VecMap;
///
/// let mut map = VecMap::new();
@ -299,6 +309,7 @@ impl<V> VecMap<V> {
/// # Examples
///
/// ```
/// # #![feature(collections)]
/// use std::collections::VecMap;
///
/// let mut map = VecMap::new();
@ -325,6 +336,7 @@ impl<V> VecMap<V> {
/// # Examples
///
/// ```
/// # #![feature(collections)]
/// use std::collections::VecMap;
///
/// let mut a = VecMap::new();
@ -360,6 +372,7 @@ impl<V> VecMap<V> {
/// # Examples
///
/// ```
/// # #![feature(collections)]
/// use std::collections::VecMap;
///
/// let mut a = VecMap::new();
@ -416,6 +429,7 @@ impl<V> VecMap<V> {
/// # Examples
///
/// ```
/// # #![feature(collections)]
/// use std::collections::VecMap;
///
/// let mut map = VecMap::new();
@ -443,6 +457,7 @@ impl<V> VecMap<V> {
/// # Examples
///
/// ```
/// # #![feature(collections)]
/// use std::collections::VecMap;
///
/// let mut a = VecMap::new();
@ -460,6 +475,7 @@ impl<V> VecMap<V> {
/// # Examples
///
/// ```
/// # #![feature(collections)]
/// use std::collections::VecMap;
///
/// let mut a = VecMap::new();
@ -477,6 +493,7 @@ impl<V> VecMap<V> {
/// # Examples
///
/// ```
/// # #![feature(collections)]
/// use std::collections::VecMap;
///
/// let mut a = VecMap::new();
@ -492,6 +509,7 @@ impl<V> VecMap<V> {
/// # Examples
///
/// ```
/// # #![feature(collections)]
/// use std::collections::VecMap;
///
/// let mut map = VecMap::new();
@ -516,6 +534,7 @@ impl<V> VecMap<V> {
/// # Examples
///
/// ```
/// # #![feature(collections)]
/// use std::collections::VecMap;
///
/// let mut map = VecMap::new();
@ -534,6 +553,7 @@ impl<V> VecMap<V> {
/// # Examples
///
/// ```
/// # #![feature(collections)]
/// use std::collections::VecMap;
///
/// let mut map = VecMap::new();
@ -562,6 +582,7 @@ impl<V> VecMap<V> {
/// # Examples
///
/// ```
/// # #![feature(collections)]
/// use std::collections::VecMap;
///
/// let mut map = VecMap::new();
@ -587,6 +608,7 @@ impl<V> VecMap<V> {
/// # Examples
///
/// ```
/// # #![feature(collections)]
/// use std::collections::VecMap;
///
/// let mut map = VecMap::new();
@ -608,6 +630,7 @@ impl<V> VecMap<V> {
/// # Examples
///
/// ```
/// # #![feature(collections)]
/// use std::collections::VecMap;
/// use std::collections::vec_map::Entry;
///
@ -651,7 +674,7 @@ impl<V> VecMap<V> {
impl<'a, V> Entry<'a, V> {
#[unstable(feature = "collections",
reason = "matches collection reform v2 specification, waiting for dust to settle")]
reason = "will soon be replaced by or_insert")]
/// Returns a mutable reference to the entry if occupied, or the VacantEntry if vacant
pub fn get(self) -> Result<&'a mut V, VacantEntry<'a, V>> {
match self {
@ -798,6 +821,7 @@ impl<V> Extend<(usize, V)> for VecMap<V> {
}
}
#[cfg(stage0)]
impl<V> Index<usize> for VecMap<V> {
type Output = V;
@ -807,10 +831,49 @@ impl<V> Index<usize> for VecMap<V> {
}
}
#[cfg(not(stage0))]
impl<V> Index<usize> for VecMap<V> {
type Output = V;
#[inline]
fn index<'a>(&'a self, i: usize) -> &'a V {
self.get(&i).expect("key not present")
}
}
#[cfg(not(stage0))]
impl<'a,V> Index<&'a usize> for VecMap<V> {
type Output = V;
#[inline]
fn index(&self, i: &usize) -> &V {
self.get(i).expect("key not present")
}
}
#[cfg(stage0)]
#[stable(feature = "rust1", since = "1.0.0")]
impl<V> IndexMut<usize> for VecMap<V> {
#[inline]
fn index_mut<'a>(&'a mut self, i: &usize) -> &'a mut V {
fn index_mut(&mut self, i: &usize) -> &mut V {
self.get_mut(&i).expect("key not present")
}
}
#[cfg(not(stage0))]
#[stable(feature = "rust1", since = "1.0.0")]
impl<V> IndexMut<usize> for VecMap<V> {
#[inline]
fn index_mut(&mut self, i: usize) -> &mut V {
self.get_mut(&i).expect("key not present")
}
}
#[cfg(not(stage0))]
#[stable(feature = "rust1", since = "1.0.0")]
impl<'a, V> IndexMut<&'a usize> for VecMap<V> {
#[inline]
fn index_mut(&mut self, i: &usize) -> &mut V {
self.get_mut(i).expect("key not present")
}
}

View file

@ -20,6 +20,8 @@
#![feature(unboxed_closures)]
#![feature(unicode)]
#![feature(unsafe_destructor)]
#![feature(into_cow)]
#![cfg_attr(test, feature(str_char))]
#[macro_use] extern crate log;

View file

@ -1428,7 +1428,7 @@ mod bench {
let mut v = Vec::<u8>::with_capacity(1024);
unsafe {
let vp = v.as_mut_ptr();
ptr::set_memory(vp, 0, 1024);
ptr::write_bytes(vp, 0, 1024);
v.set_len(1024);
}
v

View file

@ -910,6 +910,34 @@ fn test_split_char_iterator_no_trailing() {
assert_eq!(split, ["", "Märy häd ä little lämb", "Little lämb"]);
}
#[test]
fn test_rsplit() {
let data = "\nMäry häd ä little lämb\nLittle lämb\n";
let split: Vec<&str> = data.rsplit(' ').collect();
assert_eq!(split, ["lämb\n", "lämb\nLittle", "little", "ä", "häd", "\nMäry"]);
let split: Vec<&str> = data.rsplit("lämb").collect();
assert_eq!(split, ["\n", "\nLittle ", "\nMäry häd ä little "]);
let split: Vec<&str> = data.rsplit(|c: char| c == 'ä').collect();
assert_eq!(split, ["mb\n", "mb\nLittle l", " little l", "d ", "ry h", "\nM"]);
}
#[test]
fn test_rsplitn() {
let data = "\nMäry häd ä little lämb\nLittle lämb\n";
let split: Vec<&str> = data.rsplitn(1, ' ').collect();
assert_eq!(split, ["lämb\n", "\nMäry häd ä little lämb\nLittle"]);
let split: Vec<&str> = data.rsplitn(1, "lämb").collect();
assert_eq!(split, ["\n", "\nMäry häd ä little lämb\nLittle "]);
let split: Vec<&str> = data.rsplitn(1, |c: char| c == 'ä').collect();
assert_eq!(split, ["mb\n", "\nMäry häd ä little lämb\nLittle l"]);
}
#[test]
fn test_words() {
let data = "\n \tMäry häd\tä little lämb\nLittle lämb\n";

View file

@ -14,6 +14,8 @@
#![unstable(feature = "core")] // not yet reviewed
#![doc(primitive = "array")]
use clone::Clone;
use cmp::{PartialEq, Eq, PartialOrd, Ord, Ordering};
use fmt;

View file

@ -220,6 +220,7 @@ impl<T:Copy> Cell<T> {
/// # Examples
///
/// ```
/// # #![feature(core)]
/// use std::cell::Cell;
///
/// let c = Cell::new(5);

View file

@ -19,7 +19,8 @@
//! could do the following:
//!
//! ```
//! use core::num::SignedInt;
//! # #![feature(core)]
//! use std::num::SignedInt;
//!
//! struct FuzzyNum {
//! num: i32,
@ -398,6 +399,7 @@ pub fn max<T: Ord>(v1: T, v2: T) -> T {
/// # Examples
///
/// ```
/// # #![feature(core)]
/// use std::cmp;
///
/// assert_eq!(Some(1), cmp::partial_min(1, 2));
@ -407,6 +409,7 @@ pub fn max<T: Ord>(v1: T, v2: T) -> T {
/// When comparison is impossible:
///
/// ```
/// # #![feature(core)]
/// use std::cmp;
///
/// let result = cmp::partial_min(std::f64::NAN, 1.0);
@ -429,6 +432,7 @@ pub fn partial_min<T: PartialOrd>(v1: T, v2: T) -> Option<T> {
/// # Examples
///
/// ```
/// # #![feature(core)]
/// use std::cmp;
///
/// assert_eq!(Some(2), cmp::partial_max(1, 2));
@ -438,6 +442,7 @@ pub fn partial_min<T: PartialOrd>(v1: T, v2: T) -> Option<T> {
/// When comparison is impossible:
///
/// ```
/// # #![feature(core)]
/// use std::cmp;
///
/// let result = cmp::partial_max(std::f64::NAN, 1.0);

113
src/libcore/convert.rs Normal file
View file

@ -0,0 +1,113 @@
// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
//! Traits for conversions between types.
//!
//! The traits in this module provide a general way to talk about
//! conversions from one type to another. They follow the standard
//! Rust conventions of `as`/`to`/`into`/`from`.
#![unstable(feature = "convert",
reason = "recently added, experimental traits")]
use marker::Sized;
/// A cheap, reference-to-reference conversion.
pub trait AsRef<T: ?Sized> {
/// Perform the conversion.
fn as_ref(&self) -> &T;
}
/// A cheap, mutable reference-to-mutable reference conversion.
pub trait AsMut<T: ?Sized> {
/// Perform the conversion.
fn as_mut(&mut self) -> &mut T;
}
/// A conversion that consumes `self`, which may or may not be
/// expensive.
pub trait Into<T>: Sized {
/// Perform the conversion.
fn into(self) -> T;
}
/// Construct `Self` via a conversion.
pub trait From<T> {
/// Perform the conversion.
fn from(T) -> Self;
}
////////////////////////////////////////////////////////////////////////////////
// GENERIC IMPLS
////////////////////////////////////////////////////////////////////////////////
// As implies Into
impl<'a, T: ?Sized, U: ?Sized> Into<&'a U> for &'a T where T: AsRef<U> {
fn into(self) -> &'a U {
self.as_ref()
}
}
// As lifts over &
impl<'a, T: ?Sized, U: ?Sized> AsRef<U> for &'a T where T: AsRef<U> {
fn as_ref(&self) -> &U {
<T as AsRef<U>>::as_ref(*self)
}
}
// As lifts over &mut
impl<'a, T: ?Sized, U: ?Sized> AsRef<U> for &'a mut T where T: AsRef<U> {
fn as_ref(&self) -> &U {
<T as AsRef<U>>::as_ref(*self)
}
}
// AsMut implies Into
impl<'a, T: ?Sized, U: ?Sized> Into<&'a mut U> for &'a mut T where T: AsMut<U> {
fn into(self) -> &'a mut U {
(*self).as_mut()
}
}
// AsMut lifts over &mut
impl<'a, T: ?Sized, U: ?Sized> AsMut<U> for &'a mut T where T: AsMut<U> {
fn as_mut(&mut self) -> &mut U {
(*self).as_mut()
}
}
// From implies Into
impl<T, U> Into<U> for T where U: From<T> {
fn into(self) -> U {
U::from(self)
}
}
////////////////////////////////////////////////////////////////////////////////
// CONCRETE IMPLS
////////////////////////////////////////////////////////////////////////////////
impl<T> AsRef<[T]> for [T] {
fn as_ref(&self) -> &[T] {
self
}
}
impl<T> AsMut<[T]> for [T] {
fn as_mut(&mut self) -> &mut [T] {
self
}
}
impl AsRef<str> for str {
fn as_ref(&self) -> &str {
self
}
}

View file

@ -48,6 +48,7 @@
//! For example,
//!
//! ```
//! # #![feature(os, old_io, old_path)]
//! use std::error::FromError;
//! use std::old_io::{File, IoError};
//! use std::os::{MemoryMap, MapError};
@ -82,16 +83,21 @@
#![stable(feature = "rust1", since = "1.0.0")]
use prelude::*;
use fmt::Display;
use fmt::{Debug, Display};
/// Base functionality for all errors in Rust.
#[unstable(feature = "core",
reason = "the exact API of this trait may change")]
pub trait Error: Display {
/// A short description of the error; usually a static string.
#[stable(feature = "rust1", since = "1.0.0")]
pub trait Error: Debug + Display + Send {
/// A short description of the error.
///
/// The description should not contain newlines or sentence-ending
/// punctuation, to facilitate embedding in larger user-facing
/// strings.
#[stable(feature = "rust1", since = "1.0.0")]
fn description(&self) -> &str;
/// The lower-level cause of this error, if any.
#[stable(feature = "rust1", since = "1.0.0")]
fn cause(&self) -> Option<&Error> { None }
}

View file

@ -19,6 +19,7 @@
//! # Examples
//!
//! ```
//! # #![feature(core)]
//! # #![feature(unboxed_closures)]
//!
//! use std::finally::Finally;
@ -70,6 +71,7 @@ impl<T, F> Finally<T> for F where F: FnMut() -> T {
/// # Examples
///
/// ```
/// # #![feature(core)]
/// use std::finally::try_finally;
///
/// struct State<'a> { buffer: &'a mut [u8], len: usize }

View file

@ -624,6 +624,7 @@ impl<'a> Formatter<'a> {
/// # Examples
///
/// ```rust
/// # #![feature(debug_builders, core)]
/// use std::fmt;
///
/// struct Foo {
@ -655,6 +656,7 @@ impl<'a> Formatter<'a> {
/// # Examples
///
/// ```rust
/// # #![feature(debug_builders, core)]
/// use std::fmt;
///
/// struct Foo(i32, String);
@ -683,6 +685,7 @@ impl<'a> Formatter<'a> {
/// # Examples
///
/// ```rust
/// # #![feature(debug_builders, core)]
/// use std::fmt;
///
/// struct Foo(Vec<i32>);
@ -712,6 +715,7 @@ impl<'a> Formatter<'a> {
/// # Examples
///
/// ```rust
/// # #![feature(debug_builders, core)]
/// use std::fmt;
///
/// struct Foo(Vec<(String, i32)>);

View file

@ -146,6 +146,7 @@ pub struct RadixFmt<T, R>(T, R);
/// # Examples
///
/// ```
/// # #![feature(core)]
/// use std::fmt::radix;
/// assert_eq!(format!("{}", radix(55, 36)), "1j".to_string());
/// ```

View file

@ -16,6 +16,7 @@
//! # Examples
//!
//! ```rust
//! # #![feature(hash)]
//! use std::hash::{hash, Hash, SipHasher};
//!
//! #[derive(Hash)]
@ -35,6 +36,7 @@
//! the trait `Hash`:
//!
//! ```rust
//! # #![feature(hash)]
//! use std::hash::{hash, Hash, Hasher, SipHasher};
//!
//! struct Person {
@ -90,7 +92,7 @@ pub trait Hash {
#[stable(feature = "rust1", since = "1.0.0")]
pub trait Hasher {
/// Completes a round of hashing, producing the output hash generated.
#[unstable(feature = "hash", reason = "module was recently redesigned")]
#[stable(feature = "rust1", since = "1.0.0")]
fn finish(&self) -> u64;
/// Writes some data into this `Hasher`

View file

@ -44,6 +44,10 @@
use marker::Sized;
#[cfg(stage0)] pub use self::copy_memory as copy;
#[cfg(stage0)] pub use self::set_memory as write_bytes;
#[cfg(stage0)] pub use self::copy_nonoverlapping_memory as copy_nonoverlapping;
extern "rust-intrinsic" {
// NB: These intrinsics take unsafe pointers because they mutate aliased
@ -246,7 +250,7 @@ extern "rust-intrinsic" {
/// Copies `count * size_of<T>` bytes from `src` to `dst`. The source
/// and destination may *not* overlap.
///
/// `copy_nonoverlapping_memory` is semantically equivalent to C's `memcpy`.
/// `copy_nonoverlapping` is semantically equivalent to C's `memcpy`.
///
/// # Safety
///
@ -262,6 +266,7 @@ extern "rust-intrinsic" {
/// A safe swap function:
///
/// ```
/// # #![feature(core)]
/// use std::mem;
/// use std::ptr;
///
@ -271,9 +276,9 @@ extern "rust-intrinsic" {
/// let mut t: T = mem::uninitialized();
///
/// // Perform the swap, `&mut` pointers never alias
/// ptr::copy_nonoverlapping_memory(&mut t, &*x, 1);
/// ptr::copy_nonoverlapping_memory(x, &*y, 1);
/// ptr::copy_nonoverlapping_memory(y, &t, 1);
/// ptr::copy_nonoverlapping(&mut t, &*x, 1);
/// ptr::copy_nonoverlapping(x, &*y, 1);
/// ptr::copy_nonoverlapping(y, &t, 1);
///
/// // y and t now point to the same thing, but we need to completely forget `tmp`
/// // because it's no longer relevant.
@ -282,12 +287,18 @@ extern "rust-intrinsic" {
/// }
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
#[cfg(not(stage0))]
pub fn copy_nonoverlapping<T>(dst: *mut T, src: *const T, count: usize);
/// dox
#[stable(feature = "rust1", since = "1.0.0")]
#[cfg(stage0)]
pub fn copy_nonoverlapping_memory<T>(dst: *mut T, src: *const T, count: usize);
/// Copies `count * size_of<T>` bytes from `src` to `dst`. The source
/// and destination may overlap.
///
/// `copy_memory` is semantically equivalent to C's `memmove`.
/// `copy` is semantically equivalent to C's `memmove`.
///
/// # Safety
///
@ -301,21 +312,34 @@ extern "rust-intrinsic" {
/// Efficiently create a Rust vector from an unsafe buffer:
///
/// ```
/// # #![feature(core)]
/// use std::ptr;
///
/// unsafe fn from_buf_raw<T>(ptr: *const T, elts: uint) -> Vec<T> {
/// let mut dst = Vec::with_capacity(elts);
/// dst.set_len(elts);
/// ptr::copy_memory(dst.as_mut_ptr(), ptr, elts);
/// ptr::copy(dst.as_mut_ptr(), ptr, elts);
/// dst
/// }
/// ```
///
#[cfg(not(stage0))]
#[stable(feature = "rust1", since = "1.0.0")]
pub fn copy<T>(dst: *mut T, src: *const T, count: usize);
/// dox
#[cfg(stage0)]
#[stable(feature = "rust1", since = "1.0.0")]
pub fn copy_memory<T>(dst: *mut T, src: *const T, count: usize);
/// Invokes memset on the specified pointer, setting `count * size_of::<T>()`
/// bytes of memory starting at `dst` to `c`.
#[cfg(not(stage0))]
#[stable(feature = "rust1", since = "1.0.0")]
pub fn write_bytes<T>(dst: *mut T, val: u8, count: usize);
/// dox
#[cfg(stage0)]
#[stable(feature = "rust1", since = "1.0.0")]
pub fn set_memory<T>(dst: *mut T, val: u8, count: usize);

View file

@ -334,6 +334,7 @@ pub trait IteratorExt: Iterator + Sized {
/// # Examples
///
/// ```
/// # #![feature(core)]
/// let xs = [100, 200, 300];
/// let mut it = xs.iter().cloned().peekable();
/// assert_eq!(*it.peek().unwrap(), 100);
@ -465,6 +466,7 @@ pub trait IteratorExt: Iterator + Sized {
/// # Examples
///
/// ```
/// # #![feature(core)]
/// let xs = [2, 3];
/// let ys = [0, 1, 0, 1, 2];
/// let it = xs.iter().flat_map(|&x| std::iter::count(0, 1).take(x));
@ -521,6 +523,7 @@ pub trait IteratorExt: Iterator + Sized {
/// # Examples
///
/// ```
/// # #![feature(core)]
/// use std::iter::AdditiveIterator;
///
/// let a = [1, 4, 2, 3, 8, 9, 6];
@ -563,6 +566,7 @@ pub trait IteratorExt: Iterator + Sized {
/// # Examples
///
/// ```
/// # #![feature(core)]
/// let a = [1, 2, 3, 4, 5];
/// let b: Vec<_> = a.iter().cloned().collect();
/// assert_eq!(a, b);
@ -579,6 +583,7 @@ pub trait IteratorExt: Iterator + Sized {
/// do not.
///
/// ```
/// # #![feature(core)]
/// let vec = vec![1, 2, 3, 4];
/// let (even, odd): (Vec<_>, Vec<_>) = vec.into_iter().partition(|&n| n % 2 == 0);
/// assert_eq!(even, [2, 4]);
@ -648,6 +653,7 @@ pub trait IteratorExt: Iterator + Sized {
/// # Examples
///
/// ```
/// # #![feature(core)]
/// let a = [1, 2, 3, 4, 5];
/// let mut it = a.iter();
/// assert!(it.any(|x| *x == 3));
@ -668,6 +674,7 @@ pub trait IteratorExt: Iterator + Sized {
/// # Examples
///
/// ```
/// # #![feature(core)]
/// let a = [1, 2, 3, 4, 5];
/// let mut it = a.iter();
/// assert_eq!(it.find(|&x| *x == 3).unwrap(), &3);
@ -690,6 +697,7 @@ pub trait IteratorExt: Iterator + Sized {
/// # Examples
///
/// ```
/// # #![feature(core)]
/// let a = [1, 2, 3, 4, 5];
/// let mut it = a.iter();
/// assert_eq!(it.position(|x| *x == 3).unwrap(), 2);
@ -718,6 +726,7 @@ pub trait IteratorExt: Iterator + Sized {
/// # Examples
///
/// ```
/// # #![feature(core)]
/// let a = [1, 2, 2, 4, 5];
/// let mut it = a.iter();
/// assert_eq!(it.rposition(|x| *x == 2).unwrap(), 2);
@ -795,6 +804,7 @@ pub trait IteratorExt: Iterator + Sized {
/// # Examples
///
/// ```
/// # #![feature(core)]
/// use std::iter::MinMaxResult::{NoElements, OneElement, MinMax};
///
/// let a: [i32; 0] = [];
@ -860,7 +870,8 @@ pub trait IteratorExt: Iterator + Sized {
/// # Examples
///
/// ```
/// use core::num::SignedInt;
/// # #![feature(core)]
/// use std::num::SignedInt;
///
/// let a = [-3, 0, 1, 5, -10];
/// assert_eq!(*a.iter().max_by(|x| x.abs()).unwrap(), -10);
@ -890,7 +901,8 @@ pub trait IteratorExt: Iterator + Sized {
/// # Examples
///
/// ```
/// use core::num::SignedInt;
/// # #![feature(core)]
/// use std::num::SignedInt;
///
/// let a = [-3, 0, 1, 5, -10];
/// assert_eq!(*a.iter().min_by(|x| x.abs()).unwrap(), 0);
@ -940,6 +952,7 @@ pub trait IteratorExt: Iterator + Sized {
/// # Examples
///
/// ```
/// # #![feature(core)]
/// let a = [(1, 2), (3, 4)];
/// let (left, right): (Vec<_>, Vec<_>) = a.iter().cloned().unzip();
/// assert_eq!([1, 3], left);
@ -1146,6 +1159,7 @@ pub trait AdditiveIterator<A> {
/// # Examples
///
/// ```
/// # #![feature(core)]
/// use std::iter::AdditiveIterator;
///
/// let a = [1, 2, 3, 4, 5];
@ -1188,6 +1202,7 @@ pub trait MultiplicativeIterator<A> {
/// # Examples
///
/// ```
/// # #![feature(core)]
/// use std::iter::{count, MultiplicativeIterator};
///
/// fn factorial(n: usize) -> usize {
@ -1248,6 +1263,7 @@ impl<T: Clone> MinMaxResult<T> {
/// # Examples
///
/// ```
/// # #![feature(core)]
/// use std::iter::MinMaxResult::{self, NoElements, OneElement, MinMax};
///
/// let r: MinMaxResult<i32> = NoElements;
@ -2292,6 +2308,7 @@ impl<I: RandomAccessIterator, F> RandomAccessIterator for Inspect<I, F>
/// An iterator that yields sequential Fibonacci numbers, and stops on overflow.
///
/// ```
/// # #![feature(core)]
/// use std::iter::Unfold;
/// use std::num::Int; // For `.checked_add()`
///
@ -2693,6 +2710,7 @@ pub struct RangeStepInclusive<A> {
/// # Examples
///
/// ```
/// # #![feature(core)]
/// use std::iter::range_step_inclusive;
///
/// for i in range_step_inclusive(0, 10, 2) {

View file

@ -56,6 +56,7 @@
html_favicon_url = "http://www.rust-lang.org/favicon.ico",
html_root_url = "http://doc.rust-lang.org/nightly/",
html_playground_url = "http://play.rust-lang.org/")]
#![doc(test(no_crate_inject))]
#![feature(no_std)]
#![no_std]
@ -125,6 +126,7 @@ pub mod ops;
pub mod cmp;
pub mod clone;
pub mod default;
pub mod convert;
/* Core types and methods on primitives */

View file

@ -231,6 +231,7 @@ macro_rules! writeln {
/// Iterators:
///
/// ```
/// # #![feature(core)]
/// fn divide_by_three(x: u32) -> u32 { // one of the poorest implementations of x/3
/// for i in std::iter::count(0, 1) {
/// if 3*i < i { panic!("u32 overflow"); }

View file

@ -39,6 +39,8 @@ pub unsafe trait Send : MarkerTrait {
// empty.
}
unsafe impl Send for .. { }
impl<T> !Send for *const T { }
impl<T> !Send for *mut T { }
impl !Send for Managed { }
@ -203,6 +205,8 @@ pub unsafe trait Sync : MarkerTrait {
// Empty
}
unsafe impl Sync for .. { }
impl<T> !Sync for *const T { }
impl<T> !Sync for *mut T { }
impl !Sync for Managed { }
@ -270,6 +274,7 @@ macro_rules! impls{
/// any methods, but instead is used to gate access to data.
///
/// FIXME. Better documentation needed here!
#[stable(feature = "rust1", since = "1.0.0")]
pub trait MarkerTrait : PhantomFn<Self,Self> { }
// ~~~~~ <-- FIXME(#22806)?
//
@ -319,6 +324,7 @@ impl<T:?Sized> MarkerTrait for T { }
/// `MarkerTrait`:
///
/// ```
/// # #![feature(core)]
/// use std::marker::MarkerTrait;
/// trait Even : MarkerTrait { }
/// ```

View file

@ -282,7 +282,8 @@ impl Float for f32 {
/// The fractional part of the number, satisfying:
///
/// ```
/// use core::num::Float;
/// # #![feature(core)]
/// use std::num::Float;
///
/// let x = 1.65f32;
/// assert!(x == x.trunc() + x.fract())

View file

@ -289,7 +289,8 @@ impl Float for f64 {
/// The fractional part of the number, satisfying:
///
/// ```
/// use core::num::Float;
/// # #![feature(core)]
/// use std::num::Float;
///
/// let x = 1.65f64;
/// assert!(x == x.trunc() + x.fract())

View file

@ -85,6 +85,7 @@ pub trait Int
/// # Examples
///
/// ```
/// # #![feature(core)]
/// use std::num::Int;
///
/// let n = 0b01001100u8;
@ -100,6 +101,7 @@ pub trait Int
/// # Examples
///
/// ```
/// # #![feature(core)]
/// use std::num::Int;
///
/// let n = 0b01001100u8;
@ -119,6 +121,7 @@ pub trait Int
/// # Examples
///
/// ```
/// # #![feature(core)]
/// use std::num::Int;
///
/// let n = 0b0101000u16;
@ -135,6 +138,7 @@ pub trait Int
/// # Examples
///
/// ```
/// # #![feature(core)]
/// use std::num::Int;
///
/// let n = 0b0101000u16;
@ -151,6 +155,7 @@ pub trait Int
/// # Examples
///
/// ```
/// # #![feature(core)]
/// use std::num::Int;
///
/// let n = 0x0123456789ABCDEFu64;
@ -168,6 +173,7 @@ pub trait Int
/// # Examples
///
/// ```
/// # #![feature(core)]
/// use std::num::Int;
///
/// let n = 0x0123456789ABCDEFu64;
@ -392,6 +398,7 @@ pub trait Int
/// # Examples
///
/// ```
/// # #![feature(core)]
/// use std::num::Int;
///
/// assert_eq!(2.pow(4), 16);
@ -787,6 +794,7 @@ macro_rules! int_impl {
/// # Examples
///
/// ```rust
/// # #![feature(core)]
/// use std::num::Int;
///
/// let n = 0b01001100u8;
@ -803,6 +811,7 @@ macro_rules! int_impl {
/// # Examples
///
/// ```rust
/// # #![feature(core)]
/// use std::num::Int;
///
/// let n = 0b01001100u8;
@ -822,6 +831,7 @@ macro_rules! int_impl {
/// # Examples
///
/// ```rust
/// # #![feature(core)]
/// use std::num::Int;
///
/// let n = 0b0101000u16;
@ -841,6 +851,7 @@ macro_rules! int_impl {
/// # Examples
///
/// ```rust
/// # #![feature(core)]
/// use std::num::Int;
///
/// let n = 0b0101000u16;
@ -860,6 +871,7 @@ macro_rules! int_impl {
/// # Examples
///
/// ```rust
/// # #![feature(core)]
/// use std::num::Int;
///
/// let n = 0x0123456789ABCDEFu64;
@ -881,6 +893,7 @@ macro_rules! int_impl {
/// # Examples
///
/// ```rust
/// # #![feature(core)]
/// use std::num::Int;
///
/// let n = 0x0123456789ABCDEFu64;
@ -1112,6 +1125,7 @@ macro_rules! int_impl {
/// # Examples
///
/// ```rust
/// # #![feature(core)]
/// use std::num::Int;
///
/// assert_eq!(2.pow(4), 16);
@ -1277,6 +1291,7 @@ macro_rules! uint_impl {
/// # Examples
///
/// ```rust
/// # #![feature(core)]
/// use std::num::Int;
///
/// let n = 0b01001100u8;
@ -1295,6 +1310,7 @@ macro_rules! uint_impl {
/// # Examples
///
/// ```rust
/// # #![feature(core)]
/// use std::num::Int;
///
/// let n = 0b01001100u8;
@ -1314,6 +1330,7 @@ macro_rules! uint_impl {
/// # Examples
///
/// ```rust
/// # #![feature(core)]
/// use std::num::Int;
///
/// let n = 0b0101000u16;
@ -1333,6 +1350,7 @@ macro_rules! uint_impl {
/// # Examples
///
/// ```rust
/// # #![feature(core)]
/// use std::num::Int;
///
/// let n = 0b0101000u16;
@ -1352,6 +1370,7 @@ macro_rules! uint_impl {
/// # Examples
///
/// ```rust
/// # #![feature(core)]
/// use std::num::Int;
///
/// let n = 0x0123456789ABCDEFu64;
@ -1375,6 +1394,7 @@ macro_rules! uint_impl {
/// # Examples
///
/// ```rust
/// # #![feature(core)]
/// use std::num::Int;
///
/// let n = 0x0123456789ABCDEFu64;
@ -1606,6 +1626,7 @@ macro_rules! uint_impl {
/// # Examples
///
/// ```rust
/// # #![feature(core)]
/// use std::num::Int;
///
/// assert_eq!(2.pow(4), 16);
@ -2266,6 +2287,7 @@ impl_from_primitive! { f64, to_f64 }
/// # Examples
///
/// ```
/// # #![feature(core)]
/// use std::num;
///
/// let twenty: f32 = num::cast(0x14).unwrap();

View file

@ -898,7 +898,7 @@ shr_impl_all! { u8 u16 u32 u64 usize i8 i16 i32 i64 isize }
/// impl Index<Bar> for Foo {
/// type Output = Foo;
///
/// fn index<'a>(&'a self, _index: &Bar) -> &'a Foo {
/// fn index<'a>(&'a self, _index: Bar) -> &'a Foo {
/// println!("Indexing!");
/// self
/// }
@ -917,8 +917,14 @@ pub trait Index<Idx: ?Sized> {
type Output: ?Sized;
/// The method for the indexing (`Foo[Bar]`) operation
#[cfg(stage0)]
#[stable(feature = "rust1", since = "1.0.0")]
fn index<'a>(&'a self, index: &Idx) -> &'a Self::Output;
/// The method for the indexing (`Foo[Bar]`) operation
#[cfg(not(stage0))]
#[stable(feature = "rust1", since = "1.0.0")]
fn index<'a>(&'a self, index: Idx) -> &'a Self::Output;
}
/// The `IndexMut` trait is used to specify the functionality of indexing
@ -939,13 +945,13 @@ pub trait Index<Idx: ?Sized> {
/// impl Index<Bar> for Foo {
/// type Output = Foo;
///
/// fn index<'a>(&'a self, _index: &Bar) -> &'a Foo {
/// fn index<'a>(&'a self, _index: Bar) -> &'a Foo {
/// self
/// }
/// }
///
/// impl IndexMut<Bar> for Foo {
/// fn index_mut<'a>(&'a mut self, _index: &Bar) -> &'a mut Foo {
/// fn index_mut<'a>(&'a mut self, _index: Bar) -> &'a mut Foo {
/// println!("Indexing!");
/// self
/// }
@ -960,8 +966,14 @@ pub trait Index<Idx: ?Sized> {
#[stable(feature = "rust1", since = "1.0.0")]
pub trait IndexMut<Idx: ?Sized>: Index<Idx> {
/// The method for the indexing (`Foo[Bar]`) operation
#[cfg(stage0)]
#[stable(feature = "rust1", since = "1.0.0")]
fn index_mut<'a>(&'a mut self, index: &Idx) -> &'a mut Self::Output;
/// The method for the indexing (`Foo[Bar]`) operation
#[cfg(not(stage0))]
#[stable(feature = "rust1", since = "1.0.0")]
fn index_mut<'a>(&'a mut self, index: Idx) -> &'a mut Self::Output;
}
/// An unbounded range.

View file

@ -154,6 +154,7 @@ use mem;
use ops::{Deref, FnOnce};
use result::Result::{Ok, Err};
use result::Result;
#[allow(deprecated)]
use slice::AsSlice;
use slice;
@ -275,6 +276,7 @@ impl<T> Option<T> {
/// # Examples
///
/// ```
/// # #![feature(core)]
/// let mut x = Some("Diamonds");
/// {
/// let v = x.as_mut_slice();
@ -470,6 +472,7 @@ impl<T> Option<T> {
/// # Examples
///
/// ```
/// # #![feature(core)]
/// let x = Some("foo");
/// assert_eq!(x.ok_or(0), Ok("foo"));
///
@ -491,6 +494,7 @@ impl<T> Option<T> {
/// # Examples
///
/// ```
/// # #![feature(core)]
/// let x = Some("foo");
/// assert_eq!(x.ok_or_else(|| 0), Ok("foo"));
///
@ -532,6 +536,7 @@ impl<T> Option<T> {
/// # Examples
///
/// ```
/// # #![feature(core)]
/// let mut x = Some(4);
/// match x.iter_mut().next() {
/// Some(&mut ref mut v) => *v = 42,
@ -701,6 +706,19 @@ impl<T> Option<T> {
pub fn take(&mut self) -> Option<T> {
mem::replace(self, None)
}
/// Convert from `Option<T>` to `&[T]` (without copying)
#[inline]
#[unstable(feature = "as_slice", since = "unsure of the utility here")]
pub fn as_slice<'a>(&'a self) -> &'a [T] {
match *self {
Some(ref x) => slice::ref_slice(x),
None => {
let result: &[_] = &[];
result
}
}
}
}
impl<'a, T: Clone, D: Deref<Target=T>> Option<D> {
@ -752,6 +770,9 @@ impl<T: Default> Option<T> {
#[unstable(feature = "core",
reason = "waiting on the stability of the trait itself")]
#[deprecated(since = "1.0.0",
reason = "use the inherent method instead")]
#[allow(deprecated)]
impl<T> AsSlice<T> for Option<T> {
/// Convert from `Option<T>` to `&[T]` (without copying)
#[inline]

View file

@ -36,6 +36,7 @@ pub use mem::drop;
pub use char::CharExt;
pub use clone::Clone;
pub use cmp::{PartialEq, PartialOrd, Eq, Ord};
pub use convert::{AsRef, AsMut, Into, From};
pub use iter::{Extend, IteratorExt};
pub use iter::{Iterator, DoubleEndedIterator};
pub use iter::{ExactSizeIterator};

View file

@ -15,12 +15,9 @@
//! Working with unsafe pointers in Rust is uncommon,
//! typically limited to a few patterns.
//!
//! Use the [`null` function](fn.null.html) to create null pointers,
//! the [`is_null`](trait.PtrExt.html#tymethod.is_null)
//! methods of the [`PtrExt` trait](trait.PtrExt.html) to check for null.
//! The `PtrExt` trait is imported by the prelude, so `is_null` etc.
//! work everywhere. The `PtrExt` also defines the `offset` method,
//! for pointer math.
//! Use the [`null` function](fn.null.html) to create null pointers, and
//! the `is_null` method of the `*const T` type to check for null.
//! The `*const T` type also defines the `offset` method, for pointer math.
//!
//! # Common ways to create unsafe pointers
//!
@ -52,6 +49,7 @@
//! the raw pointer. It doesn't destroy `T` or deallocate any memory.
//!
//! ```
//! # #![feature(alloc)]
//! use std::boxed;
//!
//! unsafe {
@ -70,6 +68,7 @@
//! ## 3. Get it from C.
//!
//! ```
//! # #![feature(libc)]
//! extern crate libc;
//!
//! use std::mem;
@ -105,27 +104,13 @@ use cmp::Ordering::{self, Less, Equal, Greater};
// FIXME #19649: intrinsic docs don't render, so these have no docs :(
#[stable(feature = "rust1", since = "1.0.0")]
pub use intrinsics::copy_nonoverlapping_memory as copy_nonoverlapping;
pub use intrinsics::copy_nonoverlapping;
#[stable(feature = "rust1", since = "1.0.0")]
pub use intrinsics::copy_memory as copy;
pub use intrinsics::copy;
#[stable(feature = "rust1", since = "1.0.0")]
pub use intrinsics::set_memory as write_bytes;
extern "rust-intrinsic" {
#[unstable(feature = "core")]
#[deprecated(since = "1.0.0", reason = "renamed to `copy_nonoverlapping`")]
pub fn copy_nonoverlapping_memory<T>(dst: *mut T, src: *const T, count: usize);
#[unstable(feature = "core")]
#[deprecated(since = "1.0.0", reason = "renamed to `copy`")]
pub fn copy_memory<T>(dst: *mut T, src: *const T, count: usize);
#[unstable(feature = "core",
reason = "uncertain about naming and semantics")]
#[deprecated(since = "1.0.0", reason = "renamed to `write_bytes`")]
pub fn set_memory<T>(dst: *mut T, val: u8, count: usize);
}
pub use intrinsics::write_bytes;
/// Creates a null raw pointer.
///

View file

@ -48,6 +48,7 @@ use mem;
/// # Examples
///
/// ```
/// # #![feature(core)]
/// use std::raw::{self, Repr};
///
/// let slice: &[u16] = &[1, 2, 3, 4];
@ -106,6 +107,7 @@ pub struct Closure {
/// # Examples
///
/// ```
/// # #![feature(core)]
/// use std::mem;
/// use std::raw;
///

View file

@ -95,6 +95,7 @@
//! by the [`Writer`](../io/trait.Writer.html) trait:
//!
//! ```
//! # #![feature(old_io)]
//! use std::old_io::IoError;
//!
//! trait Writer {
@ -110,6 +111,7 @@
//! something like this:
//!
//! ```{.ignore}
//! # #![feature(old_io)]
//! use std::old_io::*;
//! use std::old_path::Path;
//!
@ -129,6 +131,7 @@
//! a marginally useful message indicating why:
//!
//! ```{.no_run}
//! # #![feature(old_io, old_path)]
//! use std::old_io::*;
//! use std::old_path::Path;
//!
@ -140,6 +143,7 @@
//! You might also simply assert success:
//!
//! ```{.no_run}
//! # #![feature(old_io, old_path)]
//! # use std::old_io::*;
//! # use std::old_path::Path;
//!
@ -151,6 +155,7 @@
//! Or propagate the error up the call stack with `try!`:
//!
//! ```
//! # #![feature(old_io, old_path)]
//! # use std::old_io::*;
//! # use std::old_path::Path;
//! fn write_message() -> Result<(), IoError> {
@ -171,6 +176,7 @@
//! It replaces this:
//!
//! ```
//! # #![feature(old_io, old_path)]
//! use std::old_io::*;
//! use std::old_path::Path;
//!
@ -196,6 +202,7 @@
//! With this:
//!
//! ```
//! # #![feature(old_io, old_path)]
//! use std::old_io::*;
//! use std::old_path::Path;
//!
@ -240,6 +247,7 @@ use iter::{Iterator, IteratorExt, DoubleEndedIterator,
FromIterator, ExactSizeIterator, IntoIterator};
use ops::{FnMut, FnOnce};
use option::Option::{self, None, Some};
#[allow(deprecated)]
use slice::AsSlice;
use slice;
@ -408,9 +416,24 @@ impl<T, E> Result<T, E> {
}
}
/// Convert from `Result<T, E>` to `&[T]` (without copying)
#[inline]
#[unstable(feature = "as_slice", since = "unsure of the utility here")]
pub fn as_slice(&self) -> &[T] {
match *self {
Ok(ref x) => slice::ref_slice(x),
Err(_) => {
// work around lack of implicit coercion from fixed-size array to slice
let emp: &[_] = &[];
emp
}
}
}
/// Convert from `Result<T, E>` to `&mut [T]` (without copying)
///
/// ```
/// # #![feature(core)]
/// let mut x: Result<&str, u32> = Ok("Gold");
/// {
/// let v = x.as_mut_slice();
@ -452,6 +475,7 @@ impl<T, E> Result<T, E> {
/// ignoring I/O and parse errors:
///
/// ```
/// # #![feature(old_io)]
/// use std::old_io::*;
///
/// let mut buffer: &[u8] = b"1\n2\n3\n4\n";
@ -788,10 +812,14 @@ impl<T: fmt::Debug, E> Result<T, E> {
// Trait implementations
/////////////////////////////////////////////////////////////////////////////
#[unstable(feature = "core",
reason = "waiting on the stability of the trait itself")]
#[deprecated(since = "1.0.0",
reason = "use inherent method instead")]
#[allow(deprecated)]
impl<T, E> AsSlice<T> for Result<T, E> {
/// Convert from `Result<T, E>` to `&[T]` (without copying)
#[inline]
#[stable(feature = "rust1", since = "1.0.0")]
fn as_slice<'a>(&'a self) -> &'a [T] {
match *self {
Ok(ref x) => slice::ref_slice(x),

View file

@ -19,7 +19,7 @@
//! provided beyond this module.
//!
//! ```rust
//!
//! # #![feature(core)]
//! fn main() {
//! use std::simd::f32x4;
//! let a = f32x4(40.0, 41.0, 42.0, 43.0);

View file

@ -263,6 +263,7 @@ impl<T> SliceExt for [T] {
#[inline]
fn as_mut_slice(&mut self) -> &mut [T] { self }
#[cfg(stage0)]
#[inline]
fn split_at_mut(&mut self, mid: usize) -> (&mut [T], &mut [T]) {
unsafe {
@ -273,6 +274,17 @@ impl<T> SliceExt for [T] {
}
}
#[cfg(not(stage0))]
#[inline]
fn split_at_mut(&mut self, mid: usize) -> (&mut [T], &mut [T]) {
unsafe {
let self2: &mut [T] = mem::transmute_copy(&self);
(ops::IndexMut::index_mut(self, ops::RangeTo { end: mid } ),
ops::IndexMut::index_mut(self2, ops::RangeFrom { start: mid } ))
}
}
#[inline]
fn iter_mut<'a>(&'a mut self) -> IterMut<'a, T> {
unsafe {
@ -495,25 +507,45 @@ impl<T> SliceExt for [T] {
impl<T> ops::Index<usize> for [T] {
type Output = T;
#[cfg(stage0)]
fn index(&self, &index: &usize) -> &T {
assert!(index < self.len());
unsafe { mem::transmute(self.repr().data.offset(index as isize)) }
}
#[cfg(not(stage0))]
fn index(&self, index: usize) -> &T {
assert!(index < self.len());
unsafe { mem::transmute(self.repr().data.offset(index as isize)) }
}
}
#[stable(feature = "rust1", since = "1.0.0")]
impl<T> ops::IndexMut<usize> for [T] {
#[cfg(stage0)]
#[inline]
fn index_mut(&mut self, &index: &usize) -> &mut T {
assert!(index < self.len());
unsafe { mem::transmute(self.repr().data.offset(index as isize)) }
}
#[cfg(not(stage0))]
#[inline]
fn index_mut(&mut self, index: usize) -> &mut T {
assert!(index < self.len());
unsafe { mem::transmute(self.repr().data.offset(index as isize)) }
}
}
#[stable(feature = "rust1", since = "1.0.0")]
impl<T> ops::Index<ops::Range<usize>> for [T] {
type Output = [T];
#[cfg(stage0)]
#[inline]
fn index(&self, index: &ops::Range<usize>) -> &[T] {
assert!(index.start <= index.end);
@ -525,34 +557,72 @@ impl<T> ops::Index<ops::Range<usize>> for [T] {
)
}
}
#[cfg(not(stage0))]
#[inline]
fn index(&self, index: ops::Range<usize>) -> &[T] {
assert!(index.start <= index.end);
assert!(index.end <= self.len());
unsafe {
from_raw_parts (
self.as_ptr().offset(index.start as isize),
index.end - index.start
)
}
}
}
#[stable(feature = "rust1", since = "1.0.0")]
impl<T> ops::Index<ops::RangeTo<usize>> for [T] {
type Output = [T];
#[cfg(stage0)]
#[inline]
fn index(&self, index: &ops::RangeTo<usize>) -> &[T] {
self.index(&ops::Range{ start: 0, end: index.end })
}
#[cfg(not(stage0))]
#[inline]
fn index(&self, index: ops::RangeTo<usize>) -> &[T] {
self.index(ops::Range{ start: 0, end: index.end })
}
}
#[stable(feature = "rust1", since = "1.0.0")]
impl<T> ops::Index<ops::RangeFrom<usize>> for [T] {
type Output = [T];
#[cfg(stage0)]
#[inline]
fn index(&self, index: &ops::RangeFrom<usize>) -> &[T] {
self.index(&ops::Range{ start: index.start, end: self.len() })
}
#[cfg(not(stage0))]
#[inline]
fn index(&self, index: ops::RangeFrom<usize>) -> &[T] {
self.index(ops::Range{ start: index.start, end: self.len() })
}
}
#[stable(feature = "rust1", since = "1.0.0")]
impl<T> ops::Index<RangeFull> for [T] {
type Output = [T];
#[cfg(stage0)]
#[inline]
fn index(&self, _index: &RangeFull) -> &[T] {
self
}
#[cfg(not(stage0))]
#[inline]
fn index(&self, _index: RangeFull) -> &[T] {
self
}
}
#[stable(feature = "rust1", since = "1.0.0")]
impl<T> ops::IndexMut<ops::Range<usize>> for [T] {
#[cfg(stage0)]
#[inline]
fn index_mut(&mut self, index: &ops::Range<usize>) -> &mut [T] {
assert!(index.start <= index.end);
@ -564,28 +634,64 @@ impl<T> ops::IndexMut<ops::Range<usize>> for [T] {
)
}
}
#[cfg(not(stage0))]
#[inline]
fn index_mut(&mut self, index: ops::Range<usize>) -> &mut [T] {
assert!(index.start <= index.end);
assert!(index.end <= self.len());
unsafe {
from_raw_parts_mut(
self.as_mut_ptr().offset(index.start as isize),
index.end - index.start
)
}
}
}
#[stable(feature = "rust1", since = "1.0.0")]
impl<T> ops::IndexMut<ops::RangeTo<usize>> for [T] {
#[cfg(stage0)]
#[inline]
fn index_mut(&mut self, index: &ops::RangeTo<usize>) -> &mut [T] {
self.index_mut(&ops::Range{ start: 0, end: index.end })
}
#[cfg(not(stage0))]
#[inline]
fn index_mut(&mut self, index: ops::RangeTo<usize>) -> &mut [T] {
self.index_mut(ops::Range{ start: 0, end: index.end })
}
}
#[stable(feature = "rust1", since = "1.0.0")]
impl<T> ops::IndexMut<ops::RangeFrom<usize>> for [T] {
#[cfg(stage0)]
#[inline]
fn index_mut(&mut self, index: &ops::RangeFrom<usize>) -> &mut [T] {
let len = self.len();
self.index_mut(&ops::Range{ start: index.start, end: len })
}
#[cfg(not(stage0))]
#[inline]
fn index_mut(&mut self, index: ops::RangeFrom<usize>) -> &mut [T] {
let len = self.len();
self.index_mut(ops::Range{ start: index.start, end: len })
}
}
#[stable(feature = "rust1", since = "1.0.0")]
impl<T> ops::IndexMut<RangeFull> for [T] {
#[cfg(stage0)]
#[inline]
fn index_mut(&mut self, _index: &RangeFull) -> &mut [T] {
self
}
#[cfg(not(stage0))]
#[inline]
fn index_mut(&mut self, _index: RangeFull) -> &mut [T] {
self
}
}
@ -596,24 +702,29 @@ impl<T> ops::IndexMut<RangeFull> for [T] {
/// Data that is viewable as a slice.
#[unstable(feature = "core",
reason = "will be replaced by slice syntax")]
#[deprecated(since = "1.0.0",
reason = "use std::convert::AsRef<[T]> instead")]
pub trait AsSlice<T> {
/// Work with `self` as a slice.
fn as_slice<'a>(&'a self) -> &'a [T];
}
#[unstable(feature = "core", reason = "trait is experimental")]
#[allow(deprecated)]
impl<T> AsSlice<T> for [T] {
#[inline(always)]
fn as_slice<'a>(&'a self) -> &'a [T] { self }
}
#[unstable(feature = "core", reason = "trait is experimental")]
#[allow(deprecated)]
impl<'a, T, U: ?Sized + AsSlice<T>> AsSlice<T> for &'a U {
#[inline(always)]
fn as_slice(&self) -> &[T] { AsSlice::as_slice(*self) }
}
#[unstable(feature = "core", reason = "trait is experimental")]
#[allow(deprecated)]
impl<'a, T, U: ?Sized + AsSlice<T>> AsSlice<T> for &'a mut U {
#[inline(always)]
fn as_slice(&self) -> &[T] { AsSlice::as_slice(*self) }
@ -763,37 +874,69 @@ unsafe impl<'a, T: Sync> Send for Iter<'a, T> {}
#[unstable(feature = "core")]
impl<'a, T> ops::Index<ops::Range<usize>> for Iter<'a, T> {
type Output = [T];
#[cfg(stage0)]
#[inline]
fn index(&self, index: &ops::Range<usize>) -> &[T] {
self.as_slice().index(index)
}
#[cfg(not(stage0))]
#[inline]
fn index(&self, index: ops::Range<usize>) -> &[T] {
self.as_slice().index(index)
}
}
#[unstable(feature = "core")]
impl<'a, T> ops::Index<ops::RangeTo<usize>> for Iter<'a, T> {
type Output = [T];
#[cfg(stage0)]
#[inline]
fn index(&self, index: &ops::RangeTo<usize>) -> &[T] {
self.as_slice().index(index)
}
#[cfg(not(stage0))]
#[inline]
fn index(&self, index: ops::RangeTo<usize>) -> &[T] {
self.as_slice().index(index)
}
}
#[unstable(feature = "core")]
impl<'a, T> ops::Index<ops::RangeFrom<usize>> for Iter<'a, T> {
type Output = [T];
#[cfg(stage0)]
#[inline]
fn index(&self, index: &ops::RangeFrom<usize>) -> &[T] {
self.as_slice().index(index)
}
#[cfg(not(stage0))]
#[inline]
fn index(&self, index: ops::RangeFrom<usize>) -> &[T] {
self.as_slice().index(index)
}
}
#[unstable(feature = "core")]
impl<'a, T> ops::Index<RangeFull> for Iter<'a, T> {
type Output = [T];
#[cfg(stage0)]
#[inline]
fn index(&self, _index: &RangeFull) -> &[T] {
self.as_slice()
}
#[cfg(not(stage0))]
#[inline]
fn index(&self, _index: RangeFull) -> &[T] {
self.as_slice()
}
}
impl<'a, T> Iter<'a, T> {
@ -856,63 +999,126 @@ unsafe impl<'a, T: Send> Send for IterMut<'a, T> {}
#[unstable(feature = "core")]
impl<'a, T> ops::Index<ops::Range<usize>> for IterMut<'a, T> {
type Output = [T];
#[cfg(stage0)]
#[inline]
fn index(&self, index: &ops::Range<usize>) -> &[T] {
self.index(&RangeFull).index(index)
}
#[cfg(not(stage0))]
#[inline]
fn index(&self, index: ops::Range<usize>) -> &[T] {
self.index(RangeFull).index(index)
}
}
#[unstable(feature = "core")]
impl<'a, T> ops::Index<ops::RangeTo<usize>> for IterMut<'a, T> {
type Output = [T];
#[cfg(stage0)]
#[inline]
fn index(&self, index: &ops::RangeTo<usize>) -> &[T] {
self.index(&RangeFull).index(index)
}
#[cfg(not(stage0))]
#[inline]
fn index(&self, index: ops::RangeTo<usize>) -> &[T] {
self.index(RangeFull).index(index)
}
}
#[unstable(feature = "core")]
impl<'a, T> ops::Index<ops::RangeFrom<usize>> for IterMut<'a, T> {
type Output = [T];
#[cfg(stage0)]
#[inline]
fn index(&self, index: &ops::RangeFrom<usize>) -> &[T] {
self.index(&RangeFull).index(index)
}
#[cfg(not(stage0))]
#[inline]
fn index(&self, index: ops::RangeFrom<usize>) -> &[T] {
self.index(RangeFull).index(index)
}
}
#[unstable(feature = "core")]
impl<'a, T> ops::Index<RangeFull> for IterMut<'a, T> {
type Output = [T];
#[cfg(stage0)]
#[inline]
fn index(&self, _index: &RangeFull) -> &[T] {
make_slice!(T => &[T]: self.ptr, self.end)
}
#[cfg(not(stage0))]
#[inline]
fn index(&self, _index: RangeFull) -> &[T] {
make_slice!(T => &[T]: self.ptr, self.end)
}
}
#[unstable(feature = "core")]
impl<'a, T> ops::IndexMut<ops::Range<usize>> for IterMut<'a, T> {
#[cfg(stage0)]
#[inline]
fn index_mut(&mut self, index: &ops::Range<usize>) -> &mut [T] {
self.index_mut(&RangeFull).index_mut(index)
}
#[cfg(not(stage0))]
#[inline]
fn index_mut(&mut self, index: ops::Range<usize>) -> &mut [T] {
self.index_mut(RangeFull).index_mut(index)
}
}
#[unstable(feature = "core")]
impl<'a, T> ops::IndexMut<ops::RangeTo<usize>> for IterMut<'a, T> {
#[cfg(stage0)]
#[inline]
fn index_mut(&mut self, index: &ops::RangeTo<usize>) -> &mut [T] {
self.index_mut(&RangeFull).index_mut(index)
}
#[cfg(not(stage0))]
#[inline]
fn index_mut(&mut self, index: ops::RangeTo<usize>) -> &mut [T] {
self.index_mut(RangeFull).index_mut(index)
}
}
#[unstable(feature = "core")]
impl<'a, T> ops::IndexMut<ops::RangeFrom<usize>> for IterMut<'a, T> {
#[cfg(stage0)]
#[inline]
fn index_mut(&mut self, index: &ops::RangeFrom<usize>) -> &mut [T] {
self.index_mut(&RangeFull).index_mut(index)
}
#[cfg(not(stage0))]
#[inline]
fn index_mut(&mut self, index: ops::RangeFrom<usize>) -> &mut [T] {
self.index_mut(RangeFull).index_mut(index)
}
}
#[unstable(feature = "core")]
impl<'a, T> ops::IndexMut<RangeFull> for IterMut<'a, T> {
#[cfg(stage0)]
#[inline]
fn index_mut(&mut self, _index: &RangeFull) -> &mut [T] {
make_mut_slice!(T => &mut [T]: self.ptr, self.end)
}
#[cfg(not(stage0))]
#[inline]
fn index_mut(&mut self, _index: RangeFull) -> &mut [T] {
make_mut_slice!(T => &mut [T]: self.ptr, self.end)
}
}
@ -1491,6 +1697,7 @@ pub unsafe fn from_raw_parts_mut<'a, T>(p: *mut T, len: usize) -> &'a mut [T] {
/// # Examples
///
/// ```
/// #![feature(core)]
/// use std::slice;
///
/// // manifest a slice out of thin air!

View file

@ -111,7 +111,24 @@ macro_rules! delegate_iter {
self.0.size_hint()
}
}
}
};
(pattern reverse $te:ty : $ti:ty) => {
#[stable(feature = "rust1", since = "1.0.0")]
impl<'a, P: Pattern<'a>> Iterator for $ti
where P::Searcher: ReverseSearcher<'a>
{
type Item = $te;
#[inline]
fn next(&mut self) -> Option<$te> {
self.0.next()
}
#[inline]
fn size_hint(&self) -> (usize, Option<usize>) {
self.0.size_hint()
}
}
};
}
/// A trait to abstract the idea of creating a new instance of a type from a
@ -550,7 +567,26 @@ struct CharSplitsN<'a, P: Pattern<'a>> {
iter: CharSplits<'a, P>,
/// The number of splits remaining
count: usize,
invert: bool,
}
/// An iterator over the substrings of a string, separated by a
/// pattern, in reverse order.
struct RCharSplits<'a, P: Pattern<'a>> {
/// The slice remaining to be iterated
start: usize,
end: usize,
matcher: P::Searcher,
/// Whether an empty string at the end of iteration is allowed
allow_final_empty: bool,
finished: bool,
}
/// An iterator over the substrings of a string, separated by a
/// pattern, splitting at most `count` times, in reverse order.
struct RCharSplitsN<'a, P: Pattern<'a>> {
iter: RCharSplits<'a, P>,
/// The number of splits remaining
count: usize,
}
/// An iterator over the lines of a string, separated by `\n`.
@ -631,21 +667,74 @@ where P::Searcher: DoubleEndedSearcher<'a> {
}
#[stable(feature = "rust1", since = "1.0.0")]
impl<'a, P: Pattern<'a>> Iterator for CharSplitsN<'a, P>
where P::Searcher: DoubleEndedSearcher<'a> {
impl<'a, P: Pattern<'a>> Iterator for CharSplitsN<'a, P> {
type Item = &'a str;
#[inline]
fn next(&mut self) -> Option<&'a str> {
if self.count != 0 {
self.count -= 1;
if self.invert { self.iter.next_back() } else { self.iter.next() }
self.iter.next()
} else {
self.iter.get_end()
}
}
}
impl<'a, P: Pattern<'a>> RCharSplits<'a, P> {
#[inline]
fn get_remainder(&mut self) -> Option<&'a str> {
if !self.finished && (self.allow_final_empty || self.end - self.start > 0) {
self.finished = true;
unsafe {
let string = self.matcher.haystack().slice_unchecked(self.start, self.end);
Some(string)
}
} else {
None
}
}
}
#[stable(feature = "rust1", since = "1.0.0")]
impl<'a, P: Pattern<'a>> Iterator for RCharSplits<'a, P>
where P::Searcher: ReverseSearcher<'a>
{
type Item = &'a str;
#[inline]
fn next(&mut self) -> Option<&'a str> {
if self.finished { return None }
let haystack = self.matcher.haystack();
match self.matcher.next_match_back() {
Some((a, b)) => unsafe {
let elt = haystack.slice_unchecked(b, self.end);
self.end = a;
Some(elt)
},
None => self.get_remainder(),
}
}
}
#[stable(feature = "rust1", since = "1.0.0")]
impl<'a, P: Pattern<'a>> Iterator for RCharSplitsN<'a, P>
where P::Searcher: ReverseSearcher<'a>
{
type Item = &'a str;
#[inline]
fn next(&mut self) -> Option<&'a str> {
if self.count != 0 {
self.count -= 1;
self.iter.next()
} else {
self.iter.get_remainder()
}
}
}
/// The internal state of an iterator that searches for matches of a substring
/// within a larger string using two-way search
#[derive(Clone)]
@ -1203,6 +1292,7 @@ mod traits {
/// // byte 100 is outside the string
/// // &s[3 .. 100];
/// ```
#[cfg(stage0)]
#[stable(feature = "rust1", since = "1.0.0")]
impl ops::Index<ops::Range<usize>> for str {
type Output = str;
@ -1219,6 +1309,49 @@ mod traits {
}
}
/// Returns a slice of the given string from the byte range
/// [`begin`..`end`).
///
/// This operation is `O(1)`.
///
/// Panics when `begin` and `end` do not point to valid characters
/// or point beyond the last character of the string.
///
/// # Examples
///
/// ```
/// let s = "Löwe 老虎 Léopard";
/// assert_eq!(&s[0 .. 1], "L");
///
/// assert_eq!(&s[1 .. 9], "öwe 老");
///
/// // these will panic:
/// // byte 2 lies within `ö`:
/// // &s[2 ..3];
///
/// // byte 8 lies within `老`
/// // &s[1 .. 8];
///
/// // byte 100 is outside the string
/// // &s[3 .. 100];
/// ```
#[cfg(not(stage0))]
#[stable(feature = "rust1", since = "1.0.0")]
impl ops::Index<ops::Range<usize>> for str {
type Output = str;
#[inline]
fn index(&self, index: ops::Range<usize>) -> &str {
// is_char_boundary checks that the index is in [0, .len()]
if index.start <= index.end &&
self.is_char_boundary(index.start) &&
self.is_char_boundary(index.end) {
unsafe { self.slice_unchecked(index.start, index.end) }
} else {
super::slice_error_fail(self, index.start, index.end)
}
}
}
/// Returns a slice of the string from the beginning to byte
/// `end`.
///
@ -1229,6 +1362,8 @@ mod traits {
#[stable(feature = "rust1", since = "1.0.0")]
impl ops::Index<ops::RangeTo<usize>> for str {
type Output = str;
#[cfg(stage0)]
#[inline]
fn index(&self, index: &ops::RangeTo<usize>) -> &str {
// is_char_boundary checks that the index is in [0, .len()]
@ -1238,6 +1373,17 @@ mod traits {
super::slice_error_fail(self, 0, index.end)
}
}
#[cfg(not(stage0))]
#[inline]
fn index(&self, index: ops::RangeTo<usize>) -> &str {
// is_char_boundary checks that the index is in [0, .len()]
if self.is_char_boundary(index.end) {
unsafe { self.slice_unchecked(0, index.end) }
} else {
super::slice_error_fail(self, 0, index.end)
}
}
}
/// Returns a slice of the string from `begin` to its end.
@ -1249,6 +1395,8 @@ mod traits {
#[stable(feature = "rust1", since = "1.0.0")]
impl ops::Index<ops::RangeFrom<usize>> for str {
type Output = str;
#[cfg(stage0)]
#[inline]
fn index(&self, index: &ops::RangeFrom<usize>) -> &str {
// is_char_boundary checks that the index is in [0, .len()]
@ -1258,15 +1406,34 @@ mod traits {
super::slice_error_fail(self, index.start, self.len())
}
}
#[cfg(not(stage0))]
#[inline]
fn index(&self, index: ops::RangeFrom<usize>) -> &str {
// is_char_boundary checks that the index is in [0, .len()]
if self.is_char_boundary(index.start) {
unsafe { self.slice_unchecked(index.start, self.len()) }
} else {
super::slice_error_fail(self, index.start, self.len())
}
}
}
#[stable(feature = "rust1", since = "1.0.0")]
impl ops::Index<ops::RangeFull> for str {
type Output = str;
#[cfg(stage0)]
#[inline]
fn index(&self, _index: &ops::RangeFull) -> &str {
self
}
#[cfg(not(stage0))]
#[inline]
fn index(&self, _index: ops::RangeFull) -> &str {
self
}
}
}
@ -1275,16 +1442,20 @@ mod traits {
reason = "Instead of taking this bound generically, this trait will be \
replaced with one of slicing syntax (&foo[..]), deref coercions, or \
a more generic conversion trait")]
#[deprecated(since = "1.0.0",
reason = "use std::convert::AsRef<str> instead")]
pub trait Str {
/// Work with `self` as a slice.
fn as_slice<'a>(&'a self) -> &'a str;
}
#[allow(deprecated)]
impl Str for str {
#[inline]
fn as_slice<'a>(&'a self) -> &'a str { self }
}
#[allow(deprecated)]
impl<'a, S: ?Sized> Str for &'a S where S: Str {
#[inline]
fn as_slice(&self) -> &str { Str::as_slice(*self) }
@ -1293,23 +1464,7 @@ impl<'a, S: ?Sized> Str for &'a S where S: Str {
/// Return type of `StrExt::split`
#[stable(feature = "rust1", since = "1.0.0")]
pub struct Split<'a, P: Pattern<'a>>(CharSplits<'a, P>);
#[stable(feature = "rust1", since = "1.0.0")]
impl<'a, P: Pattern<'a>> Iterator for Split<'a, P> {
type Item = &'a str;
#[inline]
fn next(&mut self) -> Option<&'a str> {
self.0.next()
}
}
#[stable(feature = "rust1", since = "1.0.0")]
impl<'a, P: Pattern<'a>> DoubleEndedIterator for Split<'a, P>
where P::Searcher: DoubleEndedSearcher<'a> {
#[inline]
fn next_back(&mut self) -> Option<&'a str> {
self.0.next_back()
}
}
delegate_iter!{pattern &'a str : Split<'a, P>}
/// Return type of `StrExt::split_terminator`
#[stable(feature = "rust1", since = "1.0.0")]
@ -1321,10 +1476,15 @@ delegate_iter!{pattern &'a str : SplitTerminator<'a, P>}
pub struct SplitN<'a, P: Pattern<'a>>(CharSplitsN<'a, P>);
delegate_iter!{pattern forward &'a str : SplitN<'a, P>}
/// Return type of `StrExt::rsplit`
#[stable(feature = "rust1", since = "1.0.0")]
pub struct RSplit<'a, P: Pattern<'a>>(RCharSplits<'a, P>);
delegate_iter!{pattern reverse &'a str : RSplit<'a, P>}
/// Return type of `StrExt::rsplitn`
#[stable(feature = "rust1", since = "1.0.0")]
pub struct RSplitN<'a, P: Pattern<'a>>(CharSplitsN<'a, P>);
delegate_iter!{pattern forward &'a str : RSplitN<'a, P>}
pub struct RSplitN<'a, P: Pattern<'a>>(RCharSplitsN<'a, P>);
delegate_iter!{pattern reverse &'a str : RSplitN<'a, P>}
/// Methods for string slices
#[allow(missing_docs)]
@ -1340,7 +1500,10 @@ pub trait StrExt {
fn split<'a, P: Pattern<'a>>(&'a self, pat: P) -> Split<'a, P>;
fn splitn<'a, P: Pattern<'a>>(&'a self, count: usize, pat: P) -> SplitN<'a, P>;
fn split_terminator<'a, P: Pattern<'a>>(&'a self, pat: P) -> SplitTerminator<'a, P>;
fn rsplitn<'a, P: Pattern<'a>>(&'a self, count: usize, pat: P) -> RSplitN<'a, P>;
fn rsplit<'a, P: Pattern<'a>>(&'a self, pat: P) -> RSplit<'a, P>
where P::Searcher: ReverseSearcher<'a>;
fn rsplitn<'a, P: Pattern<'a>>(&'a self, count: usize, pat: P) -> RSplitN<'a, P>
where P::Searcher: ReverseSearcher<'a>;
fn match_indices<'a, P: Pattern<'a>>(&'a self, pat: P) -> MatchIndices<'a, P>;
#[allow(deprecated) /* for SplitStr */]
fn split_str<'a, P: Pattern<'a>>(&'a self, pat: P) -> SplitStr<'a, P>;
@ -1424,7 +1587,6 @@ impl StrExt for str {
SplitN(CharSplitsN {
iter: self.split(pat).0,
count: count,
invert: false,
})
}
@ -1437,11 +1599,25 @@ impl StrExt for str {
}
#[inline]
fn rsplitn<'a, P: Pattern<'a>>(&'a self, count: usize, pat: P) -> RSplitN<'a, P> {
RSplitN(CharSplitsN {
iter: self.split(pat).0,
fn rsplit<'a, P: Pattern<'a>>(&'a self, pat: P) -> RSplit<'a, P>
where P::Searcher: ReverseSearcher<'a>
{
RSplit(RCharSplits {
start: 0,
end: self.len(),
matcher: pat.into_searcher(self),
allow_final_empty: true,
finished: false,
})
}
#[inline]
fn rsplitn<'a, P: Pattern<'a>>(&'a self, count: usize, pat: P) -> RSplitN<'a, P>
where P::Searcher: ReverseSearcher<'a>
{
RSplitN(RCharSplitsN {
iter: self.rsplit(pat).0,
count: count,
invert: true,
})
}

View file

@ -474,22 +474,16 @@ impl<'a, 'b> Pattern<'a> for &'b [char] {
s, CharEqPattern(s));
}
/// A convenience impl that delegates to the impl for `&str`
impl<'a, 'b> Pattern<'a> for &'b &'b str {
type Searcher = <&'b str as Pattern<'a>>::Searcher;
associated_items!(<&'b str as Pattern<'a>>::Searcher,
s, (*s));
}
/// Searches for chars that match the given predicate
impl<'a, F> Pattern<'a> for F where F: FnMut(char) -> bool {
type Searcher = <CharEqPattern<Self> as Pattern<'a>>::Searcher;
associated_items!(<CharEqPattern<Self> as Pattern<'a>>::Searcher,
s, CharEqPattern(s));
}
// Deref-forward impl
use ops::Deref;
/// Delegates to the next deref coercion of `Self` that implements `Pattern`
impl<'a, 'b, P: 'b + ?Sized, T: Deref<Target = P> + ?Sized> Pattern<'a> for &'b T
where &'b P: Pattern<'a>
{
type Searcher = <&'b P as Pattern<'a>>::Searcher;
associated_items!(<&'b P as Pattern<'a>>::Searcher,
s, (&**s));
}

View file

@ -24,6 +24,8 @@
#![feature(io)]
#![feature(collections)]
#![feature(debug_builders)]
#![feature(unique)]
#![feature(step_by)]
#![allow(deprecated)] // rand
extern crate core;

View file

@ -35,18 +35,18 @@ fn test() {
let v0 = vec![32000u16, 32001u16, 32002u16];
let mut v1 = vec![0u16, 0u16, 0u16];
copy_memory(v1.as_mut_ptr().offset(1),
v0.as_ptr().offset(1), 1);
copy(v1.as_mut_ptr().offset(1),
v0.as_ptr().offset(1), 1);
assert!((v1[0] == 0u16 &&
v1[1] == 32001u16 &&
v1[2] == 0u16));
copy_memory(v1.as_mut_ptr(),
v0.as_ptr().offset(2), 1);
copy(v1.as_mut_ptr(),
v0.as_ptr().offset(2), 1);
assert!((v1[0] == 32002u16 &&
v1[1] == 32001u16 &&
v1[2] == 0u16));
copy_memory(v1.as_mut_ptr().offset(2),
v0.as_ptr(), 1);
copy(v1.as_mut_ptr().offset(2),
v0.as_ptr(), 1);
assert!((v1[0] == 32002u16 &&
v1[1] == 32001u16 &&
v1[2] == 32000u16));
@ -164,7 +164,7 @@ fn test_ptr_subtraction() {
fn test_set_memory() {
let mut xs = [0u8; 20];
let ptr = xs.as_mut_ptr();
unsafe { set_memory(ptr, 5u8, xs.len()); }
unsafe { write_bytes(ptr, 5u8, xs.len()); }
assert!(xs == [5u8; 20]);
}

View file

@ -13,9 +13,7 @@ fn test_pattern_deref_forward() {
let data = "aabcdaa";
assert!(data.contains("bcd"));
assert!(data.contains(&"bcd"));
assert!(data.contains(&&"bcd"));
assert!(data.contains(&"bcd".to_string()));
assert!(data.contains(&&"bcd".to_string()));
}
#[test]

View file

@ -28,6 +28,7 @@
#![feature(libc)]
#![feature(staged_api)]
#![feature(unique)]
#![cfg_attr(test, feature(rustc_private, rand, collections))]
#[cfg(test)] #[macro_use] extern crate log;

View file

@ -47,12 +47,13 @@
//! which is cyclic.
//!
//! ```rust
//! # #![feature(rustc_private, core, into_cow)]
//! use std::borrow::IntoCow;
//! use std::io::Write;
//! use graphviz as dot;
//!
//! type Nd = int;
//! type Ed = (int,int);
//! type Nd = isize;
//! type Ed = (isize,isize);
//! struct Edges(Vec<Ed>);
//!
//! pub fn render_to<W: Write>(output: &mut W) {
@ -132,7 +133,7 @@
//! direct reference to the `(source,target)` pair stored in the graph's
//! internal vector (rather than passing around a copy of the pair
//! itself). Note that this implies that `fn edges(&'a self)` must
//! construct a fresh `Vec<&'a (uint,uint)>` from the `Vec<(uint,uint)>`
//! construct a fresh `Vec<&'a (usize,usize)>` from the `Vec<(usize,usize)>`
//! edges stored in `self`.
//!
//! Since both the set of nodes and the set of edges are always
@ -148,13 +149,14 @@
//! entity `&sube`).
//!
//! ```rust
//! # #![feature(rustc_private, core, into_cow)]
//! use std::borrow::IntoCow;
//! use std::io::Write;
//! use graphviz as dot;
//!
//! type Nd = uint;
//! type Ed<'a> = &'a (uint, uint);
//! struct Graph { nodes: Vec<&'static str>, edges: Vec<(uint,uint)> }
//! type Nd = usize;
//! type Ed<'a> = &'a (usize, usize);
//! struct Graph { nodes: Vec<&'static str>, edges: Vec<(usize,usize)> }
//!
//! pub fn render_to<W: Write>(output: &mut W) {
//! let nodes = vec!("{x,y}","{x}","{y}","{}");
@ -205,13 +207,14 @@
//! Hasse-diagram for the subsets of the set `{x, y}`.
//!
//! ```rust
//! # #![feature(rustc_private, core, into_cow)]
//! use std::borrow::IntoCow;
//! use std::io::Write;
//! use graphviz as dot;
//!
//! type Nd<'a> = (uint, &'a str);
//! type Nd<'a> = (usize, &'a str);
//! type Ed<'a> = (Nd<'a>, Nd<'a>);
//! struct Graph { nodes: Vec<&'static str>, edges: Vec<(uint,uint)> }
//! struct Graph { nodes: Vec<&'static str>, edges: Vec<(usize,usize)> }
//!
//! pub fn render_to<W: Write>(output: &mut W) {
//! let nodes = vec!("{x,y}","{x}","{y}","{}");
@ -228,7 +231,7 @@
//! }
//! fn node_label<'b>(&'b self, n: &Nd<'b>) -> dot::LabelText<'b> {
//! let &(i, _) = n;
//! dot::LabelText::LabelStr(self.nodes[i].as_slice().into_cow())
//! dot::LabelText::LabelStr(self.nodes[i].into_cow())
//! }
//! fn edge_label<'b>(&'b self, _: &Ed<'b>) -> dot::LabelText<'b> {
//! dot::LabelText::LabelStr("&sube;".into_cow())
@ -237,12 +240,12 @@
//!
//! impl<'a> dot::GraphWalk<'a, Nd<'a>, Ed<'a>> for Graph {
//! fn nodes(&'a self) -> dot::Nodes<'a,Nd<'a>> {
//! self.nodes.iter().map(|s|s.as_slice()).enumerate().collect()
//! self.nodes.iter().map(|s| &s[..]).enumerate().collect()
//! }
//! fn edges(&'a self) -> dot::Edges<'a,Ed<'a>> {
//! self.edges.iter()
//! .map(|&(i,j)|((i, self.nodes[i].as_slice()),
//! (j, self.nodes[j].as_slice())))
//! .map(|&(i,j)|((i, &self.nodes[i][..]),
//! (j, &self.nodes[j][..])))
//! .collect()
//! }
//! fn source(&self, e: &Ed<'a>) -> Nd<'a> { let &(s,_) = e; s }
@ -280,6 +283,7 @@
html_root_url = "http://doc.rust-lang.org/nightly/")]
#![feature(int_uint)]
#![feature(collections)]
#![feature(into_cow)]
use self::LabelText::*;
@ -381,7 +385,7 @@ impl<'a> Id<'a> {
is_letter_or_underscore(c) || in_range('0', c, '9')
}
fn in_range(low: char, c: char, high: char) -> bool {
low as uint <= c as uint && c as uint <= high as uint
low as usize <= c as usize && c as usize <= high as usize
}
}
@ -598,12 +602,12 @@ mod tests {
use std::iter::repeat;
/// each node is an index in a vector in the graph.
type Node = uint;
type Node = usize;
struct Edge {
from: uint, to: uint, label: &'static str
from: usize, to: usize, label: &'static str
}
fn edge(from: uint, to: uint, label: &'static str) -> Edge {
fn edge(from: usize, to: usize, label: &'static str) -> Edge {
Edge { from: from, to: to, label: label }
}
@ -633,7 +637,7 @@ mod tests {
enum NodeLabels<L> {
AllNodesLabelled(Vec<L>),
UnlabelledNodes(uint),
UnlabelledNodes(usize),
SomeNodesLabelled(Vec<Option<L>>),
}

View file

@ -2495,10 +2495,24 @@ pub mod consts {
pub const TCP_NODELAY: c_int = 0x0001;
pub const SOL_SOCKET: c_int = 0xffff;
pub const SO_KEEPALIVE: c_int = 8;
pub const SO_BROADCAST: c_int = 32;
pub const SO_REUSEADDR: c_int = 4;
pub const SO_DEBUG: c_int = 0x0001;
pub const SO_ACCEPTCONN: c_int = 0x0002;
pub const SO_REUSEADDR: c_int = 0x0004;
pub const SO_KEEPALIVE: c_int = 0x0008;
pub const SO_DONTROUTE: c_int = 0x0010;
pub const SO_BROADCAST: c_int = 0x0020;
pub const SO_USELOOPBACK: c_int = 0x0040;
pub const SO_LINGER: c_int = 0x0080;
pub const SO_OOBINLINE: c_int = 0x0100;
pub const SO_SNDBUF: c_int = 0x1001;
pub const SO_RCVBUF: c_int = 0x1002;
pub const SO_SNDLOWAT: c_int = 0x1003;
pub const SO_RCVLOWAT: c_int = 0x1004;
pub const SO_SNDTIMEO: c_int = 0x1005;
pub const SO_RCVTIMEO: c_int = 0x1006;
pub const SO_ERROR: c_int = 0x1007;
pub const SO_TYPE: c_int = 0x1008;
pub const IFF_LOOPBACK: c_int = 4;
@ -3441,10 +3455,24 @@ pub mod consts {
pub const TCP_NODELAY: c_int = 1;
pub const SOL_SOCKET: c_int = 1;
pub const SO_KEEPALIVE: c_int = 9;
pub const SO_BROADCAST: c_int = 6;
pub const SO_DEBUG: c_int = 1;
pub const SO_REUSEADDR: c_int = 2;
pub const SO_TYPE: c_int = 3;
pub const SO_ERROR: c_int = 4;
pub const SO_DONTROUTE: c_int = 5;
pub const SO_BROADCAST: c_int = 6;
pub const SO_SNDBUF: c_int = 7;
pub const SO_RCVBUF: c_int = 8;
pub const SO_KEEPALIVE: c_int = 9;
pub const SO_OOBINLINE: c_int = 10;
pub const SO_LINGER: c_int = 13;
pub const SO_REUSEPORT: c_int = 15;
pub const SO_RCVLOWAT: c_int = 18;
pub const SO_SNDLOWAT: c_int = 19;
pub const SO_RCVTIMEO: c_int = 20;
pub const SO_SNDTIMEO: c_int = 21;
pub const SO_ACCEPTCONN: c_int = 30;
pub const SHUT_RD: c_int = 0;
pub const SHUT_WR: c_int = 1;
@ -3487,10 +3515,24 @@ pub mod consts {
pub const TCP_NODELAY: c_int = 1;
pub const SOL_SOCKET: c_int = 65535;
pub const SO_KEEPALIVE: c_int = 8;
pub const SO_BROADCAST: c_int = 32;
pub const SO_REUSEADDR: c_int = 4;
pub const SO_ERROR: c_int = 4103;
pub const SO_DEBUG: c_int = 0x0001;
pub const SO_REUSEADDR: c_int = 0x0004;
pub const SO_KEEPALIVE: c_int = 0x0008;
pub const SO_DONTROUTE: c_int = 0x0010;
pub const SO_BROADCAST: c_int = 0x0020;
pub const SO_LINGER: c_int = 0x0080;
pub const SO_OOBINLINE: c_int = 0x100;
pub const SO_REUSEPORT: c_int = 0x0200;
pub const SO_SNDBUF: c_int = 0x1001;
pub const SO_RCVBUF: c_int = 0x1002;
pub const SO_SNDLOWAT: c_int = 0x1003;
pub const SO_RCVLOWAT: c_int = 0x1004;
pub const SO_SNDTIMEO: c_int = 0x1005;
pub const SO_RCVTIMEO: c_int = 0x1006;
pub const SO_ERROR: c_int = 0x1007;
pub const SO_TYPE: c_int = 0x1008;
pub const SO_ACCEPTCONN: c_int = 0x1009;
pub const SHUT_RD: c_int = 0;
pub const SHUT_WR: c_int = 1;
@ -4002,10 +4044,24 @@ pub mod consts {
pub const TCP_NODELAY: c_int = 1;
pub const TCP_KEEPIDLE: c_int = 256;
pub const SOL_SOCKET: c_int = 0xffff;
pub const SO_KEEPALIVE: c_int = 0x0008;
pub const SO_BROADCAST: c_int = 0x0020;
pub const SO_DEBUG: c_int = 0x01;
pub const SO_ACCEPTCONN: c_int = 0x0002;
pub const SO_REUSEADDR: c_int = 0x0004;
pub const SO_KEEPALIVE: c_int = 0x0008;
pub const SO_DONTROUTE: c_int = 0x0010;
pub const SO_BROADCAST: c_int = 0x0020;
pub const SO_USELOOPBACK: c_int = 0x0040;
pub const SO_LINGER: c_int = 0x0080;
pub const SO_OOBINLINE: c_int = 0x0100;
pub const SO_REUSEPORT: c_int = 0x0200;
pub const SO_SNDBUF: c_int = 0x1001;
pub const SO_RCVBUF: c_int = 0x1002;
pub const SO_SNDLOWAT: c_int = 0x1003;
pub const SO_RCVLOWAT: c_int = 0x1004;
pub const SO_SNDTIMEO: c_int = 0x1005;
pub const SO_RCVTIMEO: c_int = 0x1006;
pub const SO_ERROR: c_int = 0x1007;
pub const SO_TYPE: c_int = 0x1008;
pub const IFF_LOOPBACK: c_int = 0x8;
@ -4403,10 +4459,24 @@ pub mod consts {
pub const TCP_NODELAY: c_int = 0x01;
pub const SOL_SOCKET: c_int = 0xffff;
pub const SO_KEEPALIVE: c_int = 0x0008;
pub const SO_BROADCAST: c_int = 0x0020;
pub const SO_DEBUG: c_int = 0x01;
pub const SO_ACCEPTCONN: c_int = 0x0002;
pub const SO_REUSEADDR: c_int = 0x0004;
pub const SO_KEEPALIVE: c_int = 0x0008;
pub const SO_DONTROUTE: c_int = 0x0010;
pub const SO_BROADCAST: c_int = 0x0020;
pub const SO_USELOOPBACK: c_int = 0x0040;
pub const SO_LINGER: c_int = 0x0080;
pub const SO_OOBINLINE: c_int = 0x0100;
pub const SO_REUSEPORT: c_int = 0x0200;
pub const SO_SNDBUF: c_int = 0x1001;
pub const SO_RCVBUF: c_int = 0x1002;
pub const SO_SNDLOWAT: c_int = 0x1003;
pub const SO_RCVLOWAT: c_int = 0x1004;
pub const SO_SNDTIMEO: c_int = 0x1005;
pub const SO_RCVTIMEO: c_int = 0x1006;
pub const SO_ERROR: c_int = 0x1007;
pub const SO_TYPE: c_int = 0x1008;
pub const IFF_LOOPBACK: c_int = 0x8;
@ -4820,10 +4890,25 @@ pub mod consts {
pub const TCP_NODELAY: c_int = 0x01;
pub const TCP_KEEPALIVE: c_int = 0x10;
pub const SOL_SOCKET: c_int = 0xffff;
pub const SO_KEEPALIVE: c_int = 0x0008;
pub const SO_BROADCAST: c_int = 0x0020;
pub const SO_DEBUG: c_int = 0x01;
pub const SO_ACCEPTCONN: c_int = 0x0002;
pub const SO_REUSEADDR: c_int = 0x0004;
pub const SO_KEEPALIVE: c_int = 0x0008;
pub const SO_DONTROUTE: c_int = 0x0010;
pub const SO_BROADCAST: c_int = 0x0020;
pub const SO_USELOOPBACK: c_int = 0x0040;
pub const SO_LINGER: c_int = 0x0080;
pub const SO_OOBINLINE: c_int = 0x0100;
pub const SO_REUSEPORT: c_int = 0x0200;
pub const SO_SNDBUF: c_int = 0x1001;
pub const SO_RCVBUF: c_int = 0x1002;
pub const SO_SNDLOWAT: c_int = 0x1003;
pub const SO_RCVLOWAT: c_int = 0x1004;
pub const SO_SNDTIMEO: c_int = 0x1005;
pub const SO_RCVTIMEO: c_int = 0x1006;
pub const SO_ERROR: c_int = 0x1007;
pub const SO_TYPE: c_int = 0x1008;
pub const IFF_LOOPBACK: c_int = 0x8;
@ -4849,6 +4934,15 @@ pub mod consts {
pub const MAP_STACK : c_int = 0;
pub const IPPROTO_RAW : c_int = 255;
pub const SO_NREAD: c_int = 0x1020;
pub const SO_NKE: c_int = 0x1021;
pub const SO_NOSIGPIPE: c_int = 0x1022;
pub const SO_NOADDRERR: c_int = 0x1023;
pub const SO_NWRITE: c_int = 0x1024;
pub const SO_DONTTRUNC: c_int = 0x2000;
pub const SO_WANTMORE: c_int = 0x4000;
pub const SO_WANTOOBFLAG: c_int = 0x8000;
}
pub mod sysconf {
use types::os::arch::c95::c_int;
@ -5031,7 +5125,7 @@ pub mod funcs {
///
/// # Examples
///
/// ```no_run
/// ```no_run,ignore
/// extern crate libc;
///
/// fn main() {

View file

@ -60,6 +60,7 @@ impl Rand for Exp1 {
/// # Examples
///
/// ```
/// # #![feature(rand)]
/// use std::rand;
/// use std::rand::distributions::{Exp, IndependentSample};
///

View file

@ -40,6 +40,7 @@ use super::{IndependentSample, Sample, Exp};
/// # Examples
///
/// ```
/// # #![feature(rand)]
/// use std::rand;
/// use std::rand::distributions::{IndependentSample, Gamma};
///
@ -187,6 +188,7 @@ impl IndependentSample<f64> for GammaLargeShape {
/// # Examples
///
/// ```
/// # #![feature(rand)]
/// use std::rand;
/// use std::rand::distributions::{ChiSquared, IndependentSample};
///
@ -244,6 +246,7 @@ impl IndependentSample<f64> for ChiSquared {
/// # Examples
///
/// ```
/// # #![feature(rand)]
/// use std::rand;
/// use std::rand::distributions::{FisherF, IndependentSample};
///
@ -288,6 +291,7 @@ impl IndependentSample<f64> for FisherF {
/// # Examples
///
/// ```
/// # #![feature(rand)]
/// use std::rand;
/// use std::rand::distributions::{StudentT, IndependentSample};
///

View file

@ -94,6 +94,7 @@ pub struct Weighted<T> {
/// # Examples
///
/// ```
/// # #![feature(rand)]
/// use std::rand;
/// use std::rand::distributions::{Weighted, WeightedChoice, IndependentSample};
///

View file

@ -76,6 +76,7 @@ impl Rand for StandardNormal {
/// # Examples
///
/// ```
/// # #![feature(rand)]
/// use std::rand;
/// use std::rand::distributions::{Normal, IndependentSample};
///
@ -124,6 +125,7 @@ impl IndependentSample<f64> for Normal {
/// # Examples
///
/// ```
/// # #![feature(rand)]
/// use std::rand;
/// use std::rand::distributions::{LogNormal, IndependentSample};
///

View file

@ -36,6 +36,7 @@ use distributions::{Sample, IndependentSample};
/// # Examples
///
/// ```
/// # #![feature(rand)]
/// use std::rand::distributions::{IndependentSample, Range};
///
/// fn main() {

View file

@ -34,7 +34,7 @@
#![deprecated(reason = "use the crates.io `rand` library instead",
since = "1.0.0-alpha")]
#![cfg_attr(test, feature(test, rand))]
#![cfg_attr(test, feature(test, rand, rustc_private))]
#![allow(deprecated)]
@ -149,6 +149,7 @@ pub trait Rng : Sized {
/// # Examples
///
/// ```
/// # #![feature(rand, core)]
/// use std::rand::{thread_rng, Rng};
///
/// let mut v = [0; 13579];
@ -184,6 +185,7 @@ pub trait Rng : Sized {
/// # Examples
///
/// ```
/// # #![feature(rand)]
/// use std::rand::{thread_rng, Rng};
///
/// let mut rng = thread_rng();
@ -202,6 +204,7 @@ pub trait Rng : Sized {
/// # Examples
///
/// ```
/// # #![feature(rand)]
/// use std::rand::{thread_rng, Rng};
///
/// let mut rng = thread_rng();
@ -229,6 +232,7 @@ pub trait Rng : Sized {
/// # Examples
///
/// ```
/// # #![feature(rand)]
/// use std::rand::{thread_rng, Rng};
///
/// let mut rng = thread_rng();
@ -247,6 +251,7 @@ pub trait Rng : Sized {
/// # Examples
///
/// ```
/// # #![feature(rand)]
/// use std::rand::{thread_rng, Rng};
///
/// let mut rng = thread_rng();
@ -261,6 +266,7 @@ pub trait Rng : Sized {
/// # Examples
///
/// ```
/// # #![feature(rand)]
/// use std::rand::{thread_rng, Rng};
///
/// let s: String = thread_rng().gen_ascii_chars().take(10).collect();
@ -277,6 +283,7 @@ pub trait Rng : Sized {
/// # Examples
///
/// ```
/// # #![feature(rand)]
/// use std::rand::{thread_rng, Rng};
///
/// let choices = [1, 2, 4, 8, 16, 32];
@ -297,6 +304,7 @@ pub trait Rng : Sized {
/// # Examples
///
/// ```
/// # #![feature(rand, core)]
/// use std::rand::{thread_rng, Rng};
///
/// let mut rng = thread_rng();
@ -360,6 +368,7 @@ pub trait SeedableRng<Seed>: Rng {
/// # Examples
///
/// ```
/// # #![feature(rand)]
/// use std::rand::{Rng, SeedableRng, StdRng};
///
/// let seed: &[_] = &[1, 2, 3, 4];
@ -375,6 +384,7 @@ pub trait SeedableRng<Seed>: Rng {
/// # Examples
///
/// ```
/// # #![feature(rand)]
/// use std::rand::{Rng, SeedableRng, StdRng};
///
/// let seed: &[_] = &[1, 2, 3, 4];
@ -480,6 +490,7 @@ impl Rand for XorShiftRng {
/// # Examples
///
/// ```
/// # #![feature(rand)]
/// use std::rand::{random, Open01};
///
/// let Open01(val) = random::<Open01<f32>>();
@ -497,6 +508,7 @@ pub struct Open01<F>(pub F);
/// # Examples
///
/// ```
/// # #![feature(rand)]
/// use std::rand::{random, Closed01};
///
/// let Closed01(val) = random::<Closed01<f32>>();

View file

@ -103,6 +103,7 @@ impl<S, R: SeedableRng<S>, Rsdr: Reseeder<R> + Default>
/// # Examples
///
/// ```
/// # #![feature(rand)]
/// use std::rand::{Rng, SeedableRng, StdRng};
/// use std::rand::reseeding::{Reseeder, ReseedingRng};
///

View file

@ -43,6 +43,8 @@
#![feature(path_ext)]
#![feature(str_words)]
#![feature(str_char)]
#![feature(convert)]
#![feature(into_cow)]
#![cfg_attr(test, feature(test))]
extern crate arena;

View file

@ -212,7 +212,7 @@ impl LintStore {
fn maybe_stage_features(&mut self, sess: &Session) {
let lvl = match sess.opts.unstable_features {
UnstableFeatures::Default => return,
UnstableFeatures::Disallow => Warn,
UnstableFeatures::Disallow => Forbid,
UnstableFeatures::Cheat => Allow
};
match self.by_name.get("unstable_features") {

View file

@ -111,7 +111,7 @@ impl CStore {
}
pub fn get_crate_data(&self, cnum: ast::CrateNum) -> Rc<crate_metadata> {
(*self.metas.borrow())[cnum].clone()
self.metas.borrow().get(&cnum).unwrap().clone()
}
pub fn get_crate_hash(&self, cnum: ast::CrateNum) -> Svh {
@ -243,7 +243,7 @@ impl crate_metadata {
impl MetadataBlob {
pub fn as_slice<'a>(&'a self) -> &'a [u8] {
let slice = match *self {
MetadataVec(ref vec) => vec.as_slice(),
MetadataVec(ref vec) => &vec[..],
MetadataArchive(ref ar) => ar.as_slice(),
};
if slice.len() < 4 {

View file

@ -375,7 +375,7 @@ fn encode_reexported_static_base_methods(ecx: &EncodeContext,
match ecx.tcx.inherent_impls.borrow().get(&exp.def_id) {
Some(implementations) => {
for base_impl_did in &**implementations {
for &method_did in &*(*impl_items)[*base_impl_did] {
for &method_did in impl_items.get(base_impl_did).unwrap() {
let impl_item = ty::impl_or_trait_item(
ecx.tcx,
method_did.def_id());
@ -1175,7 +1175,7 @@ fn encode_info_for_item(ecx: &EncodeContext,
// We need to encode information about the default methods we
// have inherited, so we drive this based on the impl structure.
let impl_items = tcx.impl_items.borrow();
let items = &(*impl_items)[def_id];
let items = impl_items.get(&def_id).unwrap();
add_to_index(item, rbml_w, index);
rbml_w.start_tag(tag_items_data_item);
@ -1816,7 +1816,7 @@ struct ImplVisitor<'a, 'b:'a, 'c:'a, 'tcx:'b> {
impl<'a, 'b, 'c, 'tcx, 'v> Visitor<'v> for ImplVisitor<'a, 'b, 'c, 'tcx> {
fn visit_item(&mut self, item: &ast::Item) {
if let ast::ItemImpl(_, _, _, Some(ref trait_ref), _, _) = item.node {
let def_id = self.ecx.tcx.def_map.borrow()[trait_ref.ref_id].def_id();
let def_id = self.ecx.tcx.def_map.borrow().get(&trait_ref.ref_id).unwrap().def_id();
// Load eagerly if this is an implementation of the Drop trait
// or if the trait is not defined in this crate.

View file

@ -156,7 +156,7 @@ impl<'a> FileSearch<'a> {
// Returns a list of directories where target-specific tool binaries are located.
pub fn get_tools_search_paths(&self) -> Vec<PathBuf> {
let mut p = PathBuf::new(self.sysroot);
let mut p = PathBuf::from(self.sysroot);
p.push(&find_libdir(self.sysroot));
p.push(&rustlibdir());
p.push(&self.triple);
@ -166,7 +166,7 @@ impl<'a> FileSearch<'a> {
}
pub fn relative_target_lib_path(sysroot: &Path, target_triple: &str) -> PathBuf {
let mut p = PathBuf::new(&find_libdir(sysroot));
let mut p = PathBuf::from(&find_libdir(sysroot));
assert!(p.is_relative());
p.push(&rustlibdir());
p.push(target_triple);
@ -224,7 +224,7 @@ pub fn rust_path() -> Vec<PathBuf> {
Some(env_path) => {
let env_path_components =
env_path.split(PATH_ENTRY_SEPARATOR);
env_path_components.map(|s| PathBuf::new(s)).collect()
env_path_components.map(|s| PathBuf::from(s)).collect()
}
None => Vec::new()
};

View file

@ -628,7 +628,7 @@ impl<'a> Context<'a> {
let mut rlibs = HashMap::new();
let mut dylibs = HashMap::new();
{
let locs = locs.iter().map(|l| PathBuf::new(&l[..])).filter(|loc| {
let locs = locs.iter().map(|l| PathBuf::from(l)).filter(|loc| {
if !loc.exists() {
sess.err(&format!("extern location for {} does not exist: {}",
self.crate_name, loc.display()));

View file

@ -1228,7 +1228,7 @@ fn encode_side_tables_for_id(ecx: &e::EncodeContext,
var_id: var_id,
closure_expr_id: id
};
let upvar_capture = tcx.upvar_capture_map.borrow()[upvar_id].clone();
let upvar_capture = tcx.upvar_capture_map.borrow().get(&upvar_id).unwrap().clone();
var_id.encode(rbml_w);
upvar_capture.encode(rbml_w);
})

View file

@ -874,7 +874,7 @@ pub fn specialize<'a>(cx: &MatchCheckCtxt, r: &[&'a Pat],
}
ast::PatEnum(_, ref args) => {
let def = cx.tcx.def_map.borrow()[pat_id].full_def();
let def = cx.tcx.def_map.borrow().get(&pat_id).unwrap().full_def();
match def {
DefConst(..) =>
cx.tcx.sess.span_bug(pat_span, "const pattern should've \
@ -892,7 +892,7 @@ pub fn specialize<'a>(cx: &MatchCheckCtxt, r: &[&'a Pat],
ast::PatStruct(_, ref pattern_fields, _) => {
// Is this a struct or an enum variant?
let def = cx.tcx.def_map.borrow()[pat_id].full_def();
let def = cx.tcx.def_map.borrow().get(&pat_id).unwrap().full_def();
let class_id = match def {
DefConst(..) =>
cx.tcx.sess.span_bug(pat_span, "const pattern should've \

View file

@ -150,7 +150,7 @@ pub fn const_expr_to_pat(tcx: &ty::ctxt, expr: &Expr, span: Span) -> P<ast::Pat>
ast::PatTup(exprs.iter().map(|expr| const_expr_to_pat(tcx, &**expr, span)).collect()),
ast::ExprCall(ref callee, ref args) => {
let def = tcx.def_map.borrow()[callee.id];
let def = *tcx.def_map.borrow().get(&callee.id).unwrap();
if let Vacant(entry) = tcx.def_map.borrow_mut().entry(expr.id) {
entry.insert(def);
}

View file

@ -158,7 +158,7 @@ impl<'a, 'tcx> MarkSymbolVisitor<'a, 'tcx> {
fn handle_field_pattern_match(&mut self, lhs: &ast::Pat,
pats: &[codemap::Spanned<ast::FieldPat>]) {
let id = match self.tcx.def_map.borrow()[lhs.id].full_def() {
let id = match self.tcx.def_map.borrow().get(&lhs.id).unwrap().full_def() {
def::DefVariant(_, id, _) => id,
_ => {
match ty::ty_to_def_id(ty::node_id_to_type(self.tcx,
@ -496,7 +496,7 @@ impl<'a, 'tcx> DeadVisitor<'a, 'tcx> {
None => (),
Some(impl_list) => {
for impl_did in &**impl_list {
for item_did in &(*impl_items)[*impl_did] {
for item_did in &*impl_items.get(impl_did).unwrap() {
if self.live_symbols.contains(&item_did.def_id()
.node) {
return true;

View file

@ -141,7 +141,7 @@ impl<'a, 'tcx, 'v> Visitor<'v> for EffectCheckVisitor<'a, 'tcx> {
match expr.node {
ast::ExprMethodCall(_, _, _) => {
let method_call = MethodCall::expr(expr.id);
let base_type = (*self.tcx.method_map.borrow())[method_call].ty;
let base_type = self.tcx.method_map.borrow().get(&method_call).unwrap().ty;
debug!("effect: method call case, base type is {}",
ppaux::ty_to_string(self.tcx, base_type));
if type_is_unsafe_function(base_type) {

View file

@ -442,7 +442,7 @@ impl<'d,'t,'tcx,TYPER:mc::Typer<'tcx>> ExprUseVisitor<'d,'t,'tcx,TYPER> {
if !self.walk_overloaded_operator(expr,
&**lhs,
vec![&**rhs],
PassArgs::ByRef) {
PassArgs::ByValue) {
self.select_from_expr(&**lhs);
self.consume_expr(&**rhs);
}
@ -1012,7 +1012,7 @@ impl<'d,'t,'tcx,TYPER:mc::Typer<'tcx>> ExprUseVisitor<'d,'t,'tcx,TYPER> {
// Each match binding is effectively an assignment to the
// binding being produced.
let def = def_map.borrow()[pat.id].full_def();
let def = def_map.borrow().get(&pat.id).unwrap().full_def();
match mc.cat_def(pat.id, pat.span, pat_ty, def) {
Ok(binding_cmt) => {
delegate.mutate(pat.id, pat.span, binding_cmt, Init);

View file

@ -557,18 +557,7 @@ pub fn super_tys<'tcx, C>(this: &C,
(&ty::ty_rptr(a_r, ref a_mt), &ty::ty_rptr(b_r, ref b_mt)) => {
let r = try!(this.regions_with_variance(ty::Contravariant, *a_r, *b_r));
// FIXME(14985) If we have mutable references to trait objects, we
// used to use covariant subtyping. I have preserved this behaviour,
// even though it is probably incorrect. So don't go down the usual
// path which would require invariance.
let mt = match (&a_mt.ty.sty, &b_mt.ty.sty) {
(&ty::ty_trait(..), &ty::ty_trait(..)) if a_mt.mutbl == b_mt.mutbl => {
let ty = try!(this.tys(a_mt.ty, b_mt.ty));
ty::mt { ty: ty, mutbl: a_mt.mutbl }
}
_ => try!(this.mts(a_mt, b_mt))
};
let mt = try!(this.mts(a_mt, b_mt));
Ok(ty::mk_rptr(tcx, tcx.mk_region(r), mt))
}

View file

@ -1533,7 +1533,7 @@ impl<'a, 'tcx> RegionVarBindings<'a, 'tcx> {
ConstrainVarSubReg(_, region) => {
state.result.push(RegionAndOrigin {
region: region,
origin: this.constraints.borrow()[edge.data].clone()
origin: this.constraints.borrow().get(&edge.data).unwrap().clone()
});
}
}

View file

@ -448,7 +448,7 @@ fn visit_expr(ir: &mut IrMaps, expr: &Expr) {
match expr.node {
// live nodes required for uses or definitions of variables:
ast::ExprPath(..) => {
let def = ir.tcx.def_map.borrow()[expr.id].full_def();
let def = ir.tcx.def_map.borrow().get(&expr.id).unwrap().full_def();
debug!("expr {}: path that leads to {:?}", expr.id, def);
if let DefLocal(..) = def {
ir.add_live_node_for_node(expr.id, ExprNode(expr.span));
@ -1302,7 +1302,7 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> {
fn access_path(&mut self, expr: &Expr, succ: LiveNode, acc: u32)
-> LiveNode {
match self.ir.tcx.def_map.borrow()[expr.id].full_def() {
match self.ir.tcx.def_map.borrow().get(&expr.id).unwrap().full_def() {
DefLocal(nid) => {
let ln = self.live_node(expr.id, expr.span);
if acc != 0 {
@ -1564,7 +1564,9 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> {
fn check_lvalue(&mut self, expr: &Expr) {
match expr.node {
ast::ExprPath(..) => {
if let DefLocal(nid) = self.ir.tcx.def_map.borrow()[expr.id].full_def() {
if let DefLocal(nid) = self.ir.tcx.def_map.borrow().get(&expr.id)
.unwrap()
.full_def() {
// Assignment to an immutable variable or argument: only legal
// if there is no later assignment. If this local is actually
// mutable, then check for a reassignment to flag the mutability

View file

@ -531,7 +531,7 @@ impl<'t,'tcx,TYPER:Typer<'tcx>> MemCategorizationContext<'t,TYPER> {
}
ast::ExprPath(..) => {
let def = self.tcx().def_map.borrow()[expr.id].full_def();
let def = self.tcx().def_map.borrow().get(&expr.id).unwrap().full_def();
self.cat_def(expr.id, expr.span, expr_ty, def)
}

View file

@ -119,6 +119,24 @@ pub fn pat_contains_bindings(dm: &DefMap, pat: &ast::Pat) -> bool {
contains_bindings
}
/// Checks if the pattern contains any `ref` or `ref mut` bindings.
pub fn pat_contains_ref_binding(dm: &DefMap, pat: &ast::Pat) -> bool {
let mut result = false;
pat_bindings(dm, pat, |mode, _, _, _| {
match mode {
ast::BindingMode::BindByRef(_) => { result = true; }
ast::BindingMode::BindByValue(_) => { }
}
});
result
}
/// Checks if the patterns for this arm contain any `ref` or `ref mut`
/// bindings.
pub fn arm_contains_ref_binding(dm: &DefMap, arm: &ast::Arm) -> bool {
arm.pats.iter().any(|pat| pat_contains_ref_binding(dm, pat))
}
/// Checks if the pattern contains any patterns that bind something to
/// an ident or wildcard, e.g. `foo`, or `Foo(_)`, `foo @ Bar(..)`,
pub fn pat_contains_bindings_or_wild(dm: &DefMap, pat: &ast::Pat) -> bool {

View file

@ -128,7 +128,7 @@ impl<'a, 'tcx, 'v> Visitor<'v> for ReachableContext<'a, 'tcx> {
}
ast::ExprMethodCall(..) => {
let method_call = ty::MethodCall::expr(expr.id);
match (*self.tcx.method_map.borrow())[method_call].origin {
match (*self.tcx.method_map.borrow()).get(&method_call).unwrap().origin {
ty::MethodStatic(def_id) => {
if is_local(def_id) {
if self.def_id_represents_local_inlined_item(def_id) {

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