Auto merge of #23654 - alexcrichton:rollup, r=alexcrichton
This commit is contained in:
commit
ed81038504
1977 changed files with 7620 additions and 1908 deletions
15
configure
vendored
15
configure
vendored
|
@ -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
|
||||
|
||||
|
||||
|
|
|
@ -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"),
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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 that’s what `thread::scoped` takes as an
|
||||
argument. `FnOnce` closures take ownership of their environment. That’s fine,
|
||||
but there’s one detail: because of `map`, we’re going to make three of these
|
||||
closures. And since all three try to take ownership of `numbers`, that would be
|
||||
a problem. That’s what it means by ‘cannot move out of captured outer
|
||||
variable’: our `thread::scoped` closure wants to take ownership, and it can’t,
|
||||
because the closure for `map` won’t 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
|
||||
|
|
|
@ -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};
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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;
|
||||
```
|
||||
|
||||
|
|
|
@ -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
|
||||
|
||||
Here’s 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, “I’m broken.”);
|
||||
/// # }
|
||||
/// ```
|
||||
#[macro_export]
|
||||
macro_rules! panic_unless {
|
||||
($condition:expr, $($rest:expr),+) => ({ if ! $condition { panic!($($rest),+); } });
|
||||
}
|
||||
# fn main() {}
|
||||
```
|
||||
|
||||
You’ll note three things: we need to add our own `extern crate` line, so that
|
||||
we can add the `#[macro_use]` attribute. Second, we’ll need to add our own
|
||||
`main()` as well. Finally, a judicious use of `#` to comment out those two
|
||||
things, so they don’t show up in the output.
|
||||
|
||||
### Running documentation tests
|
||||
|
||||
To run the tests, either
|
||||
|
||||
```bash
|
||||
|
|
|
@ -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"))]
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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, it’s 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 let’s 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) {
|
||||
|
|
|
@ -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}
|
||||
{
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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() {
|
||||
|
|
|
@ -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()) }
|
||||
|
|
|
@ -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]
|
||||
|
||||
|
|
|
@ -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>>(),
|
||||
|
|
|
@ -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);
|
||||
///
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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]
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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]);
|
||||
|
|
|
@ -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>);
|
||||
|
||||
|
|
|
@ -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
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
///
|
||||
|
|
|
@ -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> {
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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};
|
||||
//!
|
||||
|
|
|
@ -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)]
|
||||
|
|
|
@ -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> {
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
///
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
|
|
@ -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")]
|
||||
|
|
|
@ -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")
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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";
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -220,6 +220,7 @@ impl<T:Copy> Cell<T> {
|
|||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// # #![feature(core)]
|
||||
/// use std::cell::Cell;
|
||||
///
|
||||
/// let c = Cell::new(5);
|
||||
|
|
|
@ -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
113
src/libcore/convert.rs
Normal 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
|
||||
}
|
||||
}
|
|
@ -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 }
|
||||
}
|
||||
|
||||
|
|
|
@ -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 }
|
||||
|
|
|
@ -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)>);
|
||||
|
|
|
@ -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());
|
||||
/// ```
|
||||
|
|
|
@ -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`
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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 */
|
||||
|
||||
|
|
|
@ -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"); }
|
||||
|
|
|
@ -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 { }
|
||||
/// ```
|
||||
|
|
|
@ -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())
|
||||
|
|
|
@ -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())
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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]
|
||||
|
|
|
@ -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};
|
||||
|
|
|
@ -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.
|
||||
///
|
||||
|
|
|
@ -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;
|
||||
///
|
||||
|
|
|
@ -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),
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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!
|
||||
|
|
|
@ -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,
|
||||
})
|
||||
}
|
||||
|
||||
|
|
|
@ -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));
|
||||
}
|
||||
|
|
|
@ -24,6 +24,8 @@
|
|||
#![feature(io)]
|
||||
#![feature(collections)]
|
||||
#![feature(debug_builders)]
|
||||
#![feature(unique)]
|
||||
#![feature(step_by)]
|
||||
#![allow(deprecated)] // rand
|
||||
|
||||
extern crate core;
|
||||
|
|
|
@ -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]);
|
||||
}
|
||||
|
||||
|
|
|
@ -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]
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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("⊆".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>>),
|
||||
}
|
||||
|
||||
|
|
|
@ -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() {
|
||||
|
|
|
@ -60,6 +60,7 @@ impl Rand for Exp1 {
|
|||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// # #![feature(rand)]
|
||||
/// use std::rand;
|
||||
/// use std::rand::distributions::{Exp, IndependentSample};
|
||||
///
|
||||
|
|
|
@ -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};
|
||||
///
|
||||
|
|
|
@ -94,6 +94,7 @@ pub struct Weighted<T> {
|
|||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// # #![feature(rand)]
|
||||
/// use std::rand;
|
||||
/// use std::rand::distributions::{Weighted, WeightedChoice, IndependentSample};
|
||||
///
|
||||
|
|
|
@ -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};
|
||||
///
|
||||
|
|
|
@ -36,6 +36,7 @@ use distributions::{Sample, IndependentSample};
|
|||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// # #![feature(rand)]
|
||||
/// use std::rand::distributions::{IndependentSample, Range};
|
||||
///
|
||||
/// fn main() {
|
||||
|
|
|
@ -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>>();
|
||||
|
|
|
@ -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};
|
||||
///
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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") {
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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()
|
||||
};
|
||||
|
|
|
@ -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()));
|
||||
|
|
|
@ -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);
|
||||
})
|
||||
|
|
|
@ -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 \
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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))
|
||||
}
|
||||
|
||||
|
|
|
@ -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()
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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
Loading…
Add table
Reference in a new issue