Rollup merge of #23855 - tshepang:doc-nit, r=Manishearth
This commit is contained in:
commit
3b45470100
1658 changed files with 7917 additions and 7765 deletions
|
|
@ -606,7 +606,7 @@ Peter Schuller <peter.schuller@infidyne.com>
|
|||
Peter Williams <peter@newton.cx>
|
||||
Peter Zotov <whitequark@whitequark.org>
|
||||
Petter Remen <petter.remen@gmail.com>
|
||||
Phil Dawes <pdawes@drw.com>
|
||||
Phil Dawes <phil@phildawes.net>
|
||||
Phil Ruffwind <rf@rufflewind.com>
|
||||
Philip Munksgaard <pmunksgaard@gmail.com>
|
||||
Philipp Brüschweiler <blei42@gmail.com>
|
||||
|
|
|
|||
|
|
@ -12,9 +12,7 @@
|
|||
|
||||
#![feature(box_syntax)]
|
||||
#![feature(collections)]
|
||||
#![feature(int_uint)]
|
||||
#![feature(old_io)]
|
||||
#![feature(old_path)]
|
||||
#![feature(rustc_private)]
|
||||
#![feature(unboxed_closures)]
|
||||
#![feature(std_misc)]
|
||||
|
|
|
|||
|
|
@ -15,13 +15,13 @@ use std::io::prelude::*;
|
|||
use std::path::Path;
|
||||
|
||||
pub struct ExpectedError {
|
||||
pub line: uint,
|
||||
pub line: usize,
|
||||
pub kind: String,
|
||||
pub msg: String,
|
||||
}
|
||||
|
||||
#[derive(PartialEq, Debug)]
|
||||
enum WhichLine { ThisLine, FollowPrevious(uint), AdjustBackward(uint) }
|
||||
enum WhichLine { ThisLine, FollowPrevious(usize), AdjustBackward(usize) }
|
||||
|
||||
/// Looks for either "//~| KIND MESSAGE" or "//~^^... KIND MESSAGE"
|
||||
/// The former is a "follow" that inherits its target from the preceding line;
|
||||
|
|
@ -58,8 +58,8 @@ pub fn load_errors(testfile: &Path) -> Vec<ExpectedError> {
|
|||
}).collect()
|
||||
}
|
||||
|
||||
fn parse_expected(last_nonfollow_error: Option<uint>,
|
||||
line_num: uint,
|
||||
fn parse_expected(last_nonfollow_error: Option<usize>,
|
||||
line_num: usize,
|
||||
line: &str) -> Option<(WhichLine, ExpectedError)> {
|
||||
let start = match line.find("//~") { Some(i) => i, None => return None };
|
||||
let (follow, adjusts) = if line.char_at(start + 3) == '|' {
|
||||
|
|
|
|||
|
|
@ -357,7 +357,7 @@ pub fn parse_name_value_directive(line: &str, directive: &str)
|
|||
}
|
||||
}
|
||||
|
||||
pub fn gdb_version_to_int(version_string: &str) -> int {
|
||||
pub fn gdb_version_to_int(version_string: &str) -> isize {
|
||||
let error_string = format!(
|
||||
"Encountered GDB version string with unexpected format: {}",
|
||||
version_string);
|
||||
|
|
@ -369,17 +369,17 @@ pub fn gdb_version_to_int(version_string: &str) -> int {
|
|||
panic!("{}", error_string);
|
||||
}
|
||||
|
||||
let major: int = components[0].parse().ok().expect(&error_string);
|
||||
let minor: int = components[1].parse().ok().expect(&error_string);
|
||||
let major: isize = components[0].parse().ok().expect(&error_string);
|
||||
let minor: isize = components[1].parse().ok().expect(&error_string);
|
||||
|
||||
return major * 1000 + minor;
|
||||
}
|
||||
|
||||
pub fn lldb_version_to_int(version_string: &str) -> int {
|
||||
pub fn lldb_version_to_int(version_string: &str) -> isize {
|
||||
let error_string = format!(
|
||||
"Encountered LLDB version string with unexpected format: {}",
|
||||
version_string);
|
||||
let error_string = error_string;
|
||||
let major: int = version_string.parse().ok().expect(&error_string);
|
||||
let major: isize = version_string.parse().ok().expect(&error_string);
|
||||
return major;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,11 +8,9 @@
|
|||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
#![allow(deprecated)] // for old path, for dynamic_lib
|
||||
|
||||
use std::dynamic_lib::DynamicLibrary;
|
||||
use std::io::prelude::*;
|
||||
use std::old_path::Path;
|
||||
use std::path::PathBuf;
|
||||
use std::process::{ExitStatus, Command, Child, Output, Stdio};
|
||||
|
||||
fn add_target_env(cmd: &mut Command, lib_path: &str, aux_path: Option<&str>) {
|
||||
|
|
@ -20,15 +18,15 @@ fn add_target_env(cmd: &mut Command, lib_path: &str, aux_path: Option<&str>) {
|
|||
// search path for the child.
|
||||
let mut path = DynamicLibrary::search_path();
|
||||
match aux_path {
|
||||
Some(p) => path.insert(0, Path::new(p)),
|
||||
Some(p) => path.insert(0, PathBuf::from(p)),
|
||||
None => {}
|
||||
}
|
||||
path.insert(0, Path::new(lib_path));
|
||||
path.insert(0, PathBuf::from(lib_path));
|
||||
|
||||
// Add the new dylib search path var
|
||||
let var = DynamicLibrary::envvar();
|
||||
let newpath = DynamicLibrary::create_path(&path);
|
||||
let newpath = String::from_utf8(newpath).unwrap();
|
||||
let newpath = newpath.to_str().unwrap().to_string();
|
||||
cmd.env(var, &newpath);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -758,7 +758,7 @@ fn run_debuginfo_lldb_test(config: &Config, props: &TestProps, testfile: &Path)
|
|||
struct DebuggerCommands {
|
||||
commands: Vec<String>,
|
||||
check_lines: Vec<String>,
|
||||
breakpoint_lines: Vec<uint>,
|
||||
breakpoint_lines: Vec<usize>,
|
||||
}
|
||||
|
||||
fn parse_debugger_commands(file_path: &Path, debugger_prefix: &str)
|
||||
|
|
@ -1036,7 +1036,7 @@ fn is_compiler_error_or_warning(line: &str) -> bool {
|
|||
scan_string(line, "warning", &mut i));
|
||||
}
|
||||
|
||||
fn scan_until_char(haystack: &str, needle: char, idx: &mut uint) -> bool {
|
||||
fn scan_until_char(haystack: &str, needle: char, idx: &mut usize) -> bool {
|
||||
if *idx >= haystack.len() {
|
||||
return false;
|
||||
}
|
||||
|
|
@ -1048,7 +1048,7 @@ fn scan_until_char(haystack: &str, needle: char, idx: &mut uint) -> bool {
|
|||
return true;
|
||||
}
|
||||
|
||||
fn scan_char(haystack: &str, needle: char, idx: &mut uint) -> bool {
|
||||
fn scan_char(haystack: &str, needle: char, idx: &mut usize) -> bool {
|
||||
if *idx >= haystack.len() {
|
||||
return false;
|
||||
}
|
||||
|
|
@ -1060,7 +1060,7 @@ fn scan_char(haystack: &str, needle: char, idx: &mut uint) -> bool {
|
|||
return true;
|
||||
}
|
||||
|
||||
fn scan_integer(haystack: &str, idx: &mut uint) -> bool {
|
||||
fn scan_integer(haystack: &str, idx: &mut usize) -> bool {
|
||||
let mut i = *idx;
|
||||
while i < haystack.len() {
|
||||
let ch = haystack.char_at(i);
|
||||
|
|
@ -1076,7 +1076,7 @@ fn scan_integer(haystack: &str, idx: &mut uint) -> bool {
|
|||
return true;
|
||||
}
|
||||
|
||||
fn scan_string(haystack: &str, needle: &str, idx: &mut uint) -> bool {
|
||||
fn scan_string(haystack: &str, needle: &str, idx: &mut usize) -> bool {
|
||||
let mut haystack_i = *idx;
|
||||
let mut needle_i = 0;
|
||||
while needle_i < needle.len() {
|
||||
|
|
@ -1725,7 +1725,7 @@ fn disassemble_extract(config: &Config, _props: &TestProps,
|
|||
}
|
||||
|
||||
|
||||
fn count_extracted_lines(p: &Path) -> uint {
|
||||
fn count_extracted_lines(p: &Path) -> usize {
|
||||
let mut x = Vec::new();
|
||||
File::open(&p.with_extension("ll")).unwrap().read_to_end(&mut x).unwrap();
|
||||
let x = str::from_utf8(&x).unwrap();
|
||||
|
|
|
|||
|
|
@ -13,33 +13,34 @@ use common::Config;
|
|||
|
||||
/// Conversion table from triple OS name to Rust SYSNAME
|
||||
const OS_TABLE: &'static [(&'static str, &'static str)] = &[
|
||||
("android", "android"),
|
||||
("bitrig", "bitrig"),
|
||||
("darwin", "macos"),
|
||||
("dragonfly", "dragonfly"),
|
||||
("freebsd", "freebsd"),
|
||||
("ios", "ios"),
|
||||
("linux", "linux"),
|
||||
("mingw32", "windows"),
|
||||
("openbsd", "openbsd"),
|
||||
("win32", "windows"),
|
||||
("windows", "windows"),
|
||||
("darwin", "macos"),
|
||||
("android", "android"),
|
||||
("linux", "linux"),
|
||||
("freebsd", "freebsd"),
|
||||
("dragonfly", "dragonfly"),
|
||||
("bitrig", "bitrig"),
|
||||
("openbsd", "openbsd"),
|
||||
];
|
||||
|
||||
const ARCH_TABLE: &'static [(&'static str, &'static str)] = &[
|
||||
("aarch64", "aarch64"),
|
||||
("amd64", "x86_64"),
|
||||
("arm", "arm"),
|
||||
("arm64", "aarch64"),
|
||||
("hexagon", "hexagon"),
|
||||
("i386", "x86"),
|
||||
("i686", "x86"),
|
||||
("amd64", "x86_64"),
|
||||
("x86_64", "x86_64"),
|
||||
("sparc", "sparc"),
|
||||
("powerpc", "powerpc"),
|
||||
("arm64", "aarch64"),
|
||||
("arm", "arm"),
|
||||
("aarch64", "aarch64"),
|
||||
("mips", "mips"),
|
||||
("xcore", "xcore"),
|
||||
("msp430", "msp430"),
|
||||
("hexagon", "hexagon"),
|
||||
("powerpc", "powerpc"),
|
||||
("s390x", "systemz"),
|
||||
("sparc", "sparc"),
|
||||
("x86_64", "x86_64"),
|
||||
("xcore", "xcore"),
|
||||
];
|
||||
|
||||
pub fn get_os(triple: &str) -> &'static str {
|
||||
|
|
|
|||
|
|
@ -645,18 +645,7 @@ fn bar() {
|
|||
|
||||
A number of minor features of Rust are not central enough to have their own
|
||||
syntax, and yet are not implementable as functions. Instead, they are given
|
||||
names, and invoked through a consistent syntax: `name!(...)`. Examples include:
|
||||
|
||||
* `format!` : format data into a string
|
||||
* `env!` : look up an environment variable's value at compile time
|
||||
* `file!`: return the path to the file being compiled
|
||||
* `stringify!` : pretty-print the Rust expression given as an argument
|
||||
* `include!` : include the Rust expression in the given file
|
||||
* `include_str!` : include the contents of the given file as a string
|
||||
* `include_bytes!` : include the contents of the given file as a binary blob
|
||||
* `error!`, `warn!`, `info!`, `debug!` : provide diagnostic information.
|
||||
|
||||
All of the above extensions are expressions with values.
|
||||
names, and invoked through a consistent syntax: `some_extension!(...)`.
|
||||
|
||||
Users of `rustc` can define new syntax extensions in two ways:
|
||||
|
||||
|
|
@ -744,38 +733,6 @@ Rust syntax is restricted in two ways:
|
|||
pairs when they occur at the beginning of, or immediately after, a `$(...)*`;
|
||||
requiring a distinctive token in front can solve the problem.
|
||||
|
||||
## Syntax extensions useful in macros
|
||||
|
||||
* `stringify!` : turn the identifier argument into a string literal
|
||||
* `concat!` : concatenates a comma-separated list of literals
|
||||
|
||||
## Syntax extensions for macro debugging
|
||||
|
||||
* `log_syntax!` : print out the arguments at compile time
|
||||
* `trace_macros!` : supply `true` or `false` to enable or disable macro expansion logging
|
||||
|
||||
## Quasiquoting
|
||||
|
||||
The following syntax extensions are used for quasiquoting Rust syntax trees,
|
||||
usually in [procedural macros](book/plugins.html#syntax-extensions):
|
||||
|
||||
* `quote_expr!`
|
||||
* `quote_item!`
|
||||
* `quote_pat!`
|
||||
* `quote_stmt!`
|
||||
* `quote_tokens!`
|
||||
* `quote_matcher!`
|
||||
* `quote_ty!`
|
||||
* `quote_attr!`
|
||||
|
||||
Keep in mind that when `$name : ident` appears in the input to
|
||||
`quote_tokens!`, the result contains unquoted `name` followed by two tokens.
|
||||
However, input of the same form passed to `quote_matcher!` becomes a
|
||||
quasiquoted MBE-matcher of a nonterminal. No unquotation happens. Otherwise
|
||||
the result of `quote_matcher!` is identical to that of `quote_tokens!`.
|
||||
|
||||
Documentation is very limited at the moment.
|
||||
|
||||
# Crates and source files
|
||||
|
||||
Rust is a *compiled* language. Its semantics obey a *phase distinction*
|
||||
|
|
@ -980,7 +937,7 @@ extern crate pcre;
|
|||
|
||||
extern crate std; // equivalent to: extern crate std as std;
|
||||
|
||||
extern crate "std" as ruststd; // linking to 'std' under another name
|
||||
extern crate std as ruststd; // linking to 'std' under another name
|
||||
```
|
||||
|
||||
##### Use declarations
|
||||
|
|
@ -1521,22 +1478,6 @@ statics:
|
|||
Constants should in general be preferred over statics, unless large amounts of
|
||||
data are being stored, or single-address and mutability properties are required.
|
||||
|
||||
```
|
||||
use std::sync::atomic::{AtomicUsize, Ordering, ATOMIC_USIZE_INIT};
|
||||
|
||||
// Note that ATOMIC_USIZE_INIT is a *const*, but it may be used to initialize a
|
||||
// static. This static can be modified, so it is not placed in read-only memory.
|
||||
static COUNTER: AtomicUsize = ATOMIC_USIZE_INIT;
|
||||
|
||||
// This table is a candidate to be placed in read-only memory.
|
||||
static TABLE: &'static [usize] = &[1, 2, 3, /* ... */];
|
||||
|
||||
for slot in TABLE.iter() {
|
||||
println!("{}", slot);
|
||||
}
|
||||
COUNTER.fetch_add(1, Ordering::SeqCst);
|
||||
```
|
||||
|
||||
#### Mutable statics
|
||||
|
||||
If a static item is declared with the `mut` keyword, then it is allowed to
|
||||
|
|
@ -2376,18 +2317,6 @@ impl<T: PartialEq> PartialEq for Foo<T> {
|
|||
}
|
||||
```
|
||||
|
||||
Supported traits for `derive` are:
|
||||
|
||||
* Comparison traits: `PartialEq`, `Eq`, `PartialOrd`, `Ord`.
|
||||
* Serialization: `Encodable`, `Decodable`. These require `serialize`.
|
||||
* `Clone`, to create `T` from `&T` via a copy.
|
||||
* `Default`, to create an empty instance of a data type.
|
||||
* `FromPrimitive`, to create an instance from a numeric primitive.
|
||||
* `Hash`, to iterate over the bytes in a data type.
|
||||
* `Rand`, to create a random instance of a data type.
|
||||
* `Debug`, to format a value using the `{:?}` formatter.
|
||||
* `Copy`, for "Plain Old Data" types which can be copied by simply moving bits.
|
||||
|
||||
### Compiler Features
|
||||
|
||||
Certain aspects of Rust may be implemented in the compiler, but they're not
|
||||
|
|
@ -2408,9 +2337,13 @@ considered off, and using the features will result in a compiler error.
|
|||
|
||||
The currently implemented features of the reference compiler are:
|
||||
|
||||
* `advanced_slice_patterns` - see the [match expressions](#match-expressions)
|
||||
* `advanced_slice_patterns` - See the [match expressions](#match-expressions)
|
||||
section for discussion; the exact semantics of
|
||||
slice patterns are subject to change.
|
||||
slice patterns are subject to change, so some types
|
||||
are still unstable.
|
||||
|
||||
* `slice_patterns` - OK, actually, slice patterns are just scary and
|
||||
completely unstable.
|
||||
|
||||
* `asm` - The `asm!` macro provides a means for inline assembly. This is often
|
||||
useful, but the exact syntax for this feature along with its
|
||||
|
|
@ -2440,9 +2373,6 @@ The currently implemented features of the reference compiler are:
|
|||
* `intrinsics` - Allows use of the "rust-intrinsics" ABI. Compiler intrinsics
|
||||
are inherently unstable and no promise about them is made.
|
||||
|
||||
* `int_uint` - Allows the use of the `int` and `uint` types, which are deprecated.
|
||||
Use `isize` and `usize` instead.
|
||||
|
||||
* `lang_items` - Allows use of the `#[lang]` attribute. Like `intrinsics`,
|
||||
lang items are inherently unstable and no promise about them
|
||||
is made.
|
||||
|
|
@ -2759,7 +2689,7 @@ The following are examples of structure expressions:
|
|||
```
|
||||
# struct Point { x: f64, y: f64 }
|
||||
# struct TuplePoint(f64, f64);
|
||||
# mod game { pub struct User<'a> { pub name: &'a str, pub age: u32, pub score: uint } }
|
||||
# mod game { pub struct User<'a> { pub name: &'a str, pub age: u32, pub score: usize } }
|
||||
# struct Cookie; fn some_fn<T>(t: T) {}
|
||||
Point {x: 10.0, y: 20.0};
|
||||
TuplePoint(10.0, 20.0);
|
||||
|
|
@ -3329,7 +3259,7 @@ array, like `[.., 42, ..]`. If preceded by a variable name, it will bind the
|
|||
corresponding slice to the variable. Example:
|
||||
|
||||
```
|
||||
# #![feature(advanced_slice_patterns)]
|
||||
# #![feature(advanced_slice_patterns, slice_patterns)]
|
||||
fn is_symmetric(list: &[u32]) -> bool {
|
||||
match list {
|
||||
[] | [_] => true,
|
||||
|
|
@ -3402,7 +3332,7 @@ subpattern`. For example:
|
|||
#![feature(box_patterns)]
|
||||
#![feature(box_syntax)]
|
||||
|
||||
enum List { Nil, Cons(uint, Box<List>) }
|
||||
enum List { Nil, Cons(u32, Box<List>) }
|
||||
|
||||
fn is_sorted(list: &List) -> bool {
|
||||
match *list {
|
||||
|
|
@ -3886,75 +3816,27 @@ impl Printable for String {
|
|||
`self` refers to the value of type `String` that is the receiver for a call to
|
||||
the method `make_string`.
|
||||
|
||||
## Type kinds
|
||||
# The `Copy` trait
|
||||
|
||||
Types in Rust are categorized into kinds, based on various properties of the
|
||||
components of the type. The kinds are:
|
||||
Rust has a special trait, `Copy`, which when implemented changes the semantics
|
||||
of a value. Values whose type implements `Copy` are copied rather than moved
|
||||
upon assignment.
|
||||
|
||||
* `Send`
|
||||
: Types of this kind can be safely sent between threads.
|
||||
This kind includes scalars, boxes, procs, and
|
||||
structural types containing only other owned types.
|
||||
All `Send` types are `'static`.
|
||||
* `Copy`
|
||||
: Types of this kind consist of "Plain Old Data"
|
||||
which can be copied by simply moving bits.
|
||||
All values of this kind can be implicitly copied.
|
||||
This kind includes scalars and immutable references,
|
||||
as well as structural types containing other `Copy` types.
|
||||
* `'static`
|
||||
: Types of this kind do not contain any references (except for
|
||||
references with the `static` lifetime, which are allowed).
|
||||
This can be a useful guarantee for code
|
||||
that breaks borrowing assumptions
|
||||
using [`unsafe` operations](#unsafe-functions).
|
||||
* `Drop`
|
||||
: This is not strictly a kind,
|
||||
but its presence interacts with kinds:
|
||||
the `Drop` trait provides a single method `drop`
|
||||
that takes no parameters,
|
||||
and is run when values of the type are dropped.
|
||||
Such a method is called a "destructor",
|
||||
and are always executed in "top-down" order:
|
||||
a value is completely destroyed
|
||||
before any of the values it owns run their destructors.
|
||||
Only `Send` types can implement `Drop`.
|
||||
# The `Sized` trait
|
||||
|
||||
* _Default_
|
||||
: Types with destructors, closure environments,
|
||||
and various other _non-first-class_ types,
|
||||
are not copyable at all.
|
||||
Such types can usually only be accessed through pointers,
|
||||
or in some cases, moved between mutable locations.
|
||||
`Sized` is a special trait which indicates that the size of this type is known
|
||||
at compile-time.
|
||||
|
||||
Kinds can be supplied as _bounds_ on type parameters, like traits, in which
|
||||
case the parameter is constrained to types satisfying that kind.
|
||||
# The `Drop` trait
|
||||
|
||||
By default, type parameters do not carry any assumed kind-bounds at all. When
|
||||
instantiating a type parameter, the kind bounds on the parameter are checked to
|
||||
be the same or narrower than the kind of the type that it is instantiated with.
|
||||
The `Drop` trait provides a destructor, to be run whenever a value of this type
|
||||
is to be destroyed.
|
||||
|
||||
Sending operations are not part of the Rust language, but are implemented in
|
||||
the library. Generic functions that send values bound the kind of these values
|
||||
to sendable.
|
||||
# Memory model
|
||||
|
||||
# Memory and concurrency models
|
||||
|
||||
Rust has a memory model centered around concurrently-executing _threads_. Thus
|
||||
its memory model and its concurrency model are best discussed simultaneously,
|
||||
as parts of each only make sense when considered from the perspective of the
|
||||
other.
|
||||
|
||||
When reading about the memory model, keep in mind that it is partitioned in
|
||||
order to support threads; and when reading about threads, keep in mind that their
|
||||
isolation and communication mechanisms are only possible due to the ownership
|
||||
and lifetime semantics of the memory model.
|
||||
|
||||
## Memory model
|
||||
|
||||
A Rust program's memory consists of a static set of *items*, a set of
|
||||
[threads](#threads) each with its own *stack*, and a *heap*. Immutable portions of
|
||||
the heap may be shared between threads, mutable portions may not.
|
||||
A Rust program's memory consists of a static set of *items* and a *heap*.
|
||||
Immutable portions of the heap may be shared between threads, mutable portions
|
||||
may not.
|
||||
|
||||
Allocations in the stack consist of *slots*, and allocations in the heap
|
||||
consist of *boxes*.
|
||||
|
|
@ -3965,10 +3847,6 @@ The _items_ of a program are those functions, modules and types that have their
|
|||
value calculated at compile-time and stored uniquely in the memory image of the
|
||||
rust process. Items are neither dynamically allocated nor freed.
|
||||
|
||||
A thread's _stack_ consists of activation frames automatically allocated on entry
|
||||
to each function as the thread executes. A stack allocation is reclaimed when
|
||||
control leaves the frame containing it.
|
||||
|
||||
The _heap_ is a general term that describes boxes. The lifetime of an
|
||||
allocation in the heap depends on the lifetime of the box values pointing to
|
||||
it. Since box values may themselves be passed in and out of frames, or stored
|
||||
|
|
@ -3976,25 +3854,11 @@ in the heap, heap allocations may outlive the frame they are allocated within.
|
|||
|
||||
### Memory ownership
|
||||
|
||||
A thread owns all memory it can *safely* reach through local variables, as well
|
||||
as boxes and references.
|
||||
|
||||
When a thread sends a value that has the `Send` trait to another thread, it loses
|
||||
ownership of the value sent and can no longer refer to it. This is statically
|
||||
guaranteed by the combined use of "move semantics", and the compiler-checked
|
||||
_meaning_ of the `Send` trait: it is only instantiated for (transitively)
|
||||
sendable kinds of data constructor and pointers, never including references.
|
||||
|
||||
When a stack frame is exited, its local allocations are all released, and its
|
||||
references to boxes are dropped.
|
||||
|
||||
When a thread finishes, its stack is necessarily empty and it therefore has no
|
||||
references to any boxes; the remainder of its heap is immediately freed.
|
||||
|
||||
### Memory slots
|
||||
|
||||
A thread's stack contains slots.
|
||||
|
||||
A _slot_ is a component of a stack frame, either a function parameter, a
|
||||
[temporary](#lvalues,-rvalues-and-temporaries), or a local variable.
|
||||
|
||||
|
|
@ -4024,86 +3888,6 @@ state. Subsequent statements within a function may or may not initialize the
|
|||
local variables. Local variables can be used only after they have been
|
||||
initialized; this is enforced by the compiler.
|
||||
|
||||
### Boxes
|
||||
|
||||
A _box_ is a reference to a heap allocation holding another value, which is
|
||||
constructed by the prefix operator `box`. When the standard library is in use,
|
||||
the type of a box is `std::owned::Box<T>`.
|
||||
|
||||
An example of a box type and value:
|
||||
|
||||
```
|
||||
let x: Box<i32> = Box::new(10);
|
||||
```
|
||||
|
||||
Box values exist in 1:1 correspondence with their heap allocation, copying a
|
||||
box value makes a shallow copy of the pointer. Rust will consider a shallow
|
||||
copy of a box to move ownership of the value. After a value has been moved,
|
||||
the source location cannot be used unless it is reinitialized.
|
||||
|
||||
```
|
||||
let x: Box<i32> = Box::new(10);
|
||||
let y = x;
|
||||
// attempting to use `x` will result in an error here
|
||||
```
|
||||
|
||||
## Threads
|
||||
|
||||
Rust's primary concurrency mechanism is called a **thread**.
|
||||
|
||||
### Communication between threads
|
||||
|
||||
Rust threads are isolated and generally unable to interfere with one another's
|
||||
memory directly, except through [`unsafe` code](#unsafe-functions). All
|
||||
contact between threads is mediated by safe forms of ownership transfer, and data
|
||||
races on memory are prohibited by the type system.
|
||||
|
||||
When you wish to send data between threads, the values are restricted to the
|
||||
[`Send` type-kind](#type-kinds). Restricting communication interfaces to this
|
||||
kind ensures that no references move between threads. Thus access to an entire
|
||||
data structure can be mediated through its owning "root" value; no further
|
||||
locking or copying is required to avoid data races within the substructure of
|
||||
such a value.
|
||||
|
||||
### Thread
|
||||
|
||||
The _lifecycle_ of a threads consists of a finite set of states and events that
|
||||
cause transitions between the states. The lifecycle states of a thread are:
|
||||
|
||||
* running
|
||||
* blocked
|
||||
* panicked
|
||||
* dead
|
||||
|
||||
A thread begins its lifecycle — once it has been spawned — in the
|
||||
*running* state. In this state it executes the statements of its entry
|
||||
function, and any functions called by the entry function.
|
||||
|
||||
A thread may transition from the *running* state to the *blocked* state any time
|
||||
it makes a blocking communication call. When the call can be completed —
|
||||
when a message arrives at a sender, or a buffer opens to receive a message
|
||||
— then the blocked thread will unblock and transition back to *running*.
|
||||
|
||||
A thread may transition to the *panicked* state at any time, due being killed by
|
||||
some external event or internally, from the evaluation of a `panic!()` macro.
|
||||
Once *panicking*, a thread unwinds its stack and transitions to the *dead* state.
|
||||
Unwinding the stack of a thread is done by the thread itself, on its own control
|
||||
stack. If a value with a destructor is freed during unwinding, the code for the
|
||||
destructor is run, also on the thread's control stack. Running the destructor
|
||||
code causes a temporary transition to a *running* state, and allows the
|
||||
destructor code to cause any subsequent state transitions. The original thread
|
||||
of unwinding and panicking thereby may suspend temporarily, and may involve
|
||||
(recursive) unwinding of the stack of a failed destructor. Nonetheless, the
|
||||
outermost unwinding activity will continue until the stack is unwound and the
|
||||
thread transitions to the *dead* state. There is no way to "recover" from thread
|
||||
panics. Once a thread has temporarily suspended its unwinding in the *panicking*
|
||||
state, a panic occurring from within this destructor results in *hard* panic.
|
||||
A hard panic currently results in the process aborting.
|
||||
|
||||
A thread in the *dead* state cannot transition to other states; it exists only to
|
||||
have its termination status inspected by other threads, and/or to await
|
||||
reclamation when the last reference to it drops.
|
||||
|
||||
# Runtime services, linkage and debugging
|
||||
|
||||
The Rust _runtime_ is a relatively compact collection of Rust code that
|
||||
|
|
|
|||
|
|
@ -11,8 +11,7 @@ navigate through the menu on the left.
|
|||
<h2 class="section-header"><a href="basic.html">Basics</a></h2>
|
||||
|
||||
This section is a linear introduction to the basic syntax and semantics of
|
||||
Rust. It has individual sections on each part of Rust's syntax, and culminates
|
||||
in a small project: a guessing game.
|
||||
Rust. It has individual sections on each part of Rust's syntax.
|
||||
|
||||
After reading "Basics," you will have a good foundation to learn more about
|
||||
Rust, and can write very simple programs.
|
||||
|
|
@ -29,7 +28,12 @@ and will be able to understand most Rust code and write more complex programs.
|
|||
|
||||
In a similar fashion to "Intermediate," this section is full of individual,
|
||||
deep-dive chapters, which stand alone and can be read in any order. These
|
||||
chapters focus on the most complex features, as well as some things that
|
||||
are only available in upcoming versions of Rust.
|
||||
chapters focus on the most complex features,
|
||||
|
||||
After reading "Advanced," you'll be a Rust expert!
|
||||
<h2 class="section-header"><a href="unstable.html">Unstable</a></h2>
|
||||
|
||||
In a similar fashion to "Intermediate," this section is full of individual,
|
||||
deep-dive chapters, which stand alone and can be read in any order.
|
||||
|
||||
This chapter contains things that are only available on the nightly channel of
|
||||
Rust.
|
||||
|
|
|
|||
|
|
@ -13,7 +13,6 @@
|
|||
* [Looping](looping.md)
|
||||
* [Strings](strings.md)
|
||||
* [Arrays, Vectors, and Slices](arrays-vectors-and-slices.md)
|
||||
* [Standard Input](standard-input.md)
|
||||
* [Intermediate Rust](intermediate.md)
|
||||
* [Crates and Modules](crates-and-modules.md)
|
||||
* [Testing](testing.md)
|
||||
|
|
@ -36,6 +35,12 @@
|
|||
* [FFI](ffi.md)
|
||||
* [Unsafe Code](unsafe.md)
|
||||
* [Advanced Macros](advanced-macros.md)
|
||||
* [Unstable Rust](unstable.md)
|
||||
* [Compiler Plugins](plugins.md)
|
||||
* [Inline Assembly](inline-assembly.md)
|
||||
* [No stdlib](no-stdlib.md)
|
||||
* [Intrinsics](intrinsics.md)
|
||||
* [Lang items](lang-items.md)
|
||||
* [Link args](link-args.md)
|
||||
* [Conclusion](conclusion.md)
|
||||
* [Glossary](glossary.md)
|
||||
|
|
|
|||
|
|
@ -206,8 +206,6 @@ the [Bitwise Cyclic Tag](http://esolangs.org/wiki/Bitwise_Cyclic_Tag) automaton
|
|||
within Rust's macro system.
|
||||
|
||||
```rust
|
||||
#![feature(trace_macros)]
|
||||
|
||||
macro_rules! bct {
|
||||
// cmd 0: d ... => ...
|
||||
(0, $($ps:tt),* ; $_d:tt)
|
||||
|
|
@ -229,13 +227,6 @@ macro_rules! bct {
|
|||
( $($ps:tt),* ; )
|
||||
=> (());
|
||||
}
|
||||
|
||||
fn main() {
|
||||
trace_macros!(true);
|
||||
# /* just check the definition
|
||||
bct!(0, 0, 1, 1, 1 ; 1, 0, 1);
|
||||
# */
|
||||
}
|
||||
```
|
||||
|
||||
Exercise: use macros to reduce duplication in the above definition of the
|
||||
|
|
|
|||
|
|
@ -99,7 +99,5 @@ You can also take a slice of a vector, `String`, or `&str`, because they are
|
|||
backed by arrays. Slices have type `&[T]`, which we'll talk about when we cover
|
||||
generics.
|
||||
|
||||
We have now learned all of the most basic Rust concepts. We're ready to start
|
||||
building ourselves a guessing game, we just need to know one last thing: how to
|
||||
get input from the keyboard. You can't have a guessing game without the ability
|
||||
to guess!
|
||||
We have now learned all of the most basic Rust concepts. Next, we learn how to
|
||||
get input from the keyboard.
|
||||
|
|
|
|||
|
|
@ -1,8 +1,7 @@
|
|||
% Basics
|
||||
|
||||
This section is a linear introduction to the basic syntax and semantics of
|
||||
Rust. It has individual sections on each part of Rust's syntax, and cumulates
|
||||
in a small project: a guessing game.
|
||||
Rust. It has individual sections on each part of Rust's syntax.
|
||||
|
||||
After reading "Basics," you will have a good foundation to learn more about
|
||||
Rust, and can write very simple programs.
|
||||
|
|
|
|||
|
|
@ -361,5 +361,4 @@ and brittle `if`/`else`s.
|
|||
|
||||
[arity]: ./glossary.html#arity
|
||||
[match]: ./match.html
|
||||
[game]: ./guessing-game.html#comparing-guesses
|
||||
[generics]: ./generics.html
|
||||
|
|
|
|||
|
|
@ -352,7 +352,7 @@ Here’s an example of documenting a macro:
|
|||
/// # }
|
||||
/// ```
|
||||
///
|
||||
/// ```should_fail
|
||||
/// ```should_panic
|
||||
/// # #[macro_use] extern crate foo;
|
||||
/// # fn main() {
|
||||
/// panic_unless!(true == false, “I’m broken.”);
|
||||
|
|
@ -517,7 +517,7 @@ can be useful when changing some options, or when writing a macro.
|
|||
|
||||
### Re-exports
|
||||
|
||||
`rustdoc` will show the documentation for a publc re-export in both places:
|
||||
`rustdoc` will show the documentation for a public re-export in both places:
|
||||
|
||||
```ignore
|
||||
extern crate foo;
|
||||
|
|
|
|||
|
|
@ -366,31 +366,6 @@ A few examples of how this model can be used are:
|
|||
|
||||
On OSX, frameworks behave with the same semantics as a dynamic library.
|
||||
|
||||
## The `link_args` attribute
|
||||
|
||||
There is one other way to tell rustc how to customize linking, and that is via
|
||||
the `link_args` attribute. This attribute is applied to `extern` blocks and
|
||||
specifies raw flags which need to get passed to the linker when producing an
|
||||
artifact. An example usage would be:
|
||||
|
||||
``` no_run
|
||||
#![feature(link_args)]
|
||||
|
||||
#[link_args = "-foo -bar -baz"]
|
||||
extern {}
|
||||
# fn main() {}
|
||||
```
|
||||
|
||||
Note that this feature is currently hidden behind the `feature(link_args)` gate
|
||||
because this is not a sanctioned way of performing linking. Right now rustc
|
||||
shells out to the system linker, so it makes sense to provide extra command line
|
||||
arguments, but this will not always be the case. In the future rustc may use
|
||||
LLVM directly to link native libraries in which case `link_args` will have no
|
||||
meaning.
|
||||
|
||||
It is highly recommended to *not* use this attribute, and rather use the more
|
||||
formal `#[link(...)]` attribute on `extern` blocks instead.
|
||||
|
||||
# Unsafe blocks
|
||||
|
||||
Some operations, like dereferencing unsafe pointers or calling functions that have been marked
|
||||
|
|
@ -401,7 +376,7 @@ Unsafe functions, on the other hand, advertise it to the world. An unsafe functi
|
|||
this:
|
||||
|
||||
```
|
||||
unsafe fn kaboom(ptr: *const int) -> int { *ptr }
|
||||
unsafe fn kaboom(ptr: *const i32) -> i32 { *ptr }
|
||||
```
|
||||
|
||||
This function can only be called from an `unsafe` block or another `unsafe` function.
|
||||
|
|
@ -423,7 +398,7 @@ extern {
|
|||
|
||||
fn main() {
|
||||
println!("You have readline version {} installed.",
|
||||
rl_readline_version as int);
|
||||
rl_readline_version as i32);
|
||||
}
|
||||
```
|
||||
|
||||
|
|
|
|||
141
src/doc/trpl/inline-assembly.md
Normal file
141
src/doc/trpl/inline-assembly.md
Normal file
|
|
@ -0,0 +1,141 @@
|
|||
% Inline Assembly
|
||||
|
||||
For extremely low-level manipulations and performance reasons, one
|
||||
might wish to control the CPU directly. Rust supports using inline
|
||||
assembly to do this via the `asm!` macro. The syntax roughly matches
|
||||
that of GCC & Clang:
|
||||
|
||||
```ignore
|
||||
asm!(assembly template
|
||||
: output operands
|
||||
: input operands
|
||||
: clobbers
|
||||
: options
|
||||
);
|
||||
```
|
||||
|
||||
Any use of `asm` is feature gated (requires `#![feature(asm)]` on the
|
||||
crate to allow) and of course requires an `unsafe` block.
|
||||
|
||||
> **Note**: the examples here are given in x86/x86-64 assembly, but
|
||||
> all platforms are supported.
|
||||
|
||||
## Assembly template
|
||||
|
||||
The `assembly template` is the only required parameter and must be a
|
||||
literal string (i.e. `""`)
|
||||
|
||||
```
|
||||
#![feature(asm)]
|
||||
|
||||
#[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
|
||||
fn foo() {
|
||||
unsafe {
|
||||
asm!("NOP");
|
||||
}
|
||||
}
|
||||
|
||||
// other platforms
|
||||
#[cfg(not(any(target_arch = "x86", target_arch = "x86_64")))]
|
||||
fn foo() { /* ... */ }
|
||||
|
||||
fn main() {
|
||||
// ...
|
||||
foo();
|
||||
// ...
|
||||
}
|
||||
```
|
||||
|
||||
(The `feature(asm)` and `#[cfg]`s are omitted from now on.)
|
||||
|
||||
Output operands, input operands, clobbers and options are all optional
|
||||
but you must add the right number of `:` if you skip them:
|
||||
|
||||
```
|
||||
# #![feature(asm)]
|
||||
# #[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
|
||||
# fn main() { unsafe {
|
||||
asm!("xor %eax, %eax"
|
||||
:
|
||||
:
|
||||
: "eax"
|
||||
);
|
||||
# } }
|
||||
```
|
||||
|
||||
Whitespace also doesn't matter:
|
||||
|
||||
```
|
||||
# #![feature(asm)]
|
||||
# #[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
|
||||
# fn main() { unsafe {
|
||||
asm!("xor %eax, %eax" ::: "eax");
|
||||
# } }
|
||||
```
|
||||
|
||||
## Operands
|
||||
|
||||
Input and output operands follow the same format: `:
|
||||
"constraints1"(expr1), "constraints2"(expr2), ..."`. Output operand
|
||||
expressions must be mutable lvalues:
|
||||
|
||||
```
|
||||
# #![feature(asm)]
|
||||
# #[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
|
||||
fn add(a: i32, b: i32) -> i32 {
|
||||
let mut c = 0;
|
||||
unsafe {
|
||||
asm!("add $2, $0"
|
||||
: "=r"(c)
|
||||
: "0"(a), "r"(b)
|
||||
);
|
||||
}
|
||||
c
|
||||
}
|
||||
# #[cfg(not(any(target_arch = "x86", target_arch = "x86_64")))]
|
||||
# fn add(a: i32, b: i32) -> i32 { a + b }
|
||||
|
||||
fn main() {
|
||||
assert_eq!(add(3, 14159), 14162)
|
||||
}
|
||||
```
|
||||
|
||||
## Clobbers
|
||||
|
||||
Some instructions modify registers which might otherwise have held
|
||||
different values so we use the clobbers list to indicate to the
|
||||
compiler not to assume any values loaded into those registers will
|
||||
stay valid.
|
||||
|
||||
```
|
||||
# #![feature(asm)]
|
||||
# #[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
|
||||
# fn main() { unsafe {
|
||||
// Put the value 0x200 in eax
|
||||
asm!("mov $$0x200, %eax" : /* no outputs */ : /* no inputs */ : "eax");
|
||||
# } }
|
||||
```
|
||||
|
||||
Input and output registers need not be listed since that information
|
||||
is already communicated by the given constraints. Otherwise, any other
|
||||
registers used either implicitly or explicitly should be listed.
|
||||
|
||||
If the assembly changes the condition code register `cc` should be
|
||||
specified as one of the clobbers. Similarly, if the assembly modifies
|
||||
memory, `memory` should also be specified.
|
||||
|
||||
## Options
|
||||
|
||||
The last section, `options` is specific to Rust. The format is comma
|
||||
separated literal strings (i.e. `:"foo", "bar", "baz"`). It's used to
|
||||
specify some extra info about the inline assembly:
|
||||
|
||||
Current valid options are:
|
||||
|
||||
1. *volatile* - specifying this is analogous to
|
||||
`__asm__ __volatile__ (...)` in gcc/clang.
|
||||
2. *alignstack* - certain instructions expect the stack to be
|
||||
aligned a certain way (i.e. SSE) and specifying this indicates to
|
||||
the compiler to insert its usual stack alignment code
|
||||
3. *intel* - use intel syntax instead of the default AT&T.
|
||||
|
||||
|
|
@ -6,14 +6,14 @@ Linux or a Mac, all you need to do is this (note that you don't need to type
|
|||
in the `$`s, they just indicate the start of each command):
|
||||
|
||||
```bash
|
||||
$ curl -L https://static.rust-lang.org/rustup.sh | sudo sh
|
||||
$ curl -sf -L https://static.rust-lang.org/rustup.sh | sudo sh
|
||||
```
|
||||
|
||||
If you're concerned about the [potential insecurity](http://curlpipesh.tumblr.com/) of using `curl | sudo sh`,
|
||||
please keep reading and see our disclaimer below. And feel free to use a two-step version of the installation and examine our installation script:
|
||||
|
||||
```bash
|
||||
$ curl -L https://static.rust-lang.org/rustup.sh -O
|
||||
$ curl -f -L https://static.rust-lang.org/rustup.sh -O
|
||||
$ sudo sh rustup.sh
|
||||
```
|
||||
|
||||
|
|
|
|||
25
src/doc/trpl/intrinsics.md
Normal file
25
src/doc/trpl/intrinsics.md
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
% Intrinsics
|
||||
|
||||
> **Note**: intrinsics will forever have an unstable interface, it is
|
||||
> recommended to use the stable interfaces of libcore rather than intrinsics
|
||||
> directly.
|
||||
|
||||
These are imported as if they were FFI functions, with the special
|
||||
`rust-intrinsic` ABI. For example, if one was in a freestanding
|
||||
context, but wished to be able to `transmute` between types, and
|
||||
perform efficient pointer arithmetic, one would import those functions
|
||||
via a declaration like
|
||||
|
||||
```
|
||||
# #![feature(intrinsics)]
|
||||
# fn main() {}
|
||||
|
||||
extern "rust-intrinsic" {
|
||||
fn transmute<T, U>(x: T) -> U;
|
||||
|
||||
fn offset<T>(dst: *const T, offset: isize) -> *const T;
|
||||
}
|
||||
```
|
||||
|
||||
As with any other FFI functions, these are always `unsafe` to call.
|
||||
|
||||
79
src/doc/trpl/lang-items.md
Normal file
79
src/doc/trpl/lang-items.md
Normal file
|
|
@ -0,0 +1,79 @@
|
|||
% Lang items
|
||||
|
||||
> **Note**: lang items are often provided by crates in the Rust distribution,
|
||||
> and lang items themselves have an unstable interface. It is recommended to use
|
||||
> officially distributed crates instead of defining your own lang items.
|
||||
|
||||
The `rustc` compiler has certain pluggable operations, that is,
|
||||
functionality that isn't hard-coded into the language, but is
|
||||
implemented in libraries, with a special marker to tell the compiler
|
||||
it exists. The marker is the attribute `#[lang="..."]` and there are
|
||||
various different values of `...`, i.e. various different 'lang
|
||||
items'.
|
||||
|
||||
For example, `Box` pointers require two lang items, one for allocation
|
||||
and one for deallocation. A freestanding program that uses the `Box`
|
||||
sugar for dynamic allocations via `malloc` and `free`:
|
||||
|
||||
```
|
||||
#![feature(lang_items, box_syntax, start, no_std, libc)]
|
||||
#![no_std]
|
||||
|
||||
extern crate libc;
|
||||
|
||||
extern {
|
||||
fn abort() -> !;
|
||||
}
|
||||
|
||||
#[lang = "owned_box"]
|
||||
pub struct Box<T>(*mut T);
|
||||
|
||||
#[lang="exchange_malloc"]
|
||||
unsafe fn allocate(size: usize, _align: usize) -> *mut u8 {
|
||||
let p = libc::malloc(size as libc::size_t) as *mut u8;
|
||||
|
||||
// malloc failed
|
||||
if p as usize == 0 {
|
||||
abort();
|
||||
}
|
||||
|
||||
p
|
||||
}
|
||||
#[lang="exchange_free"]
|
||||
unsafe fn deallocate(ptr: *mut u8, _size: usize, _align: usize) {
|
||||
libc::free(ptr as *mut libc::c_void)
|
||||
}
|
||||
|
||||
#[start]
|
||||
fn main(argc: isize, argv: *const *const u8) -> isize {
|
||||
let x = box 1;
|
||||
|
||||
0
|
||||
}
|
||||
|
||||
#[lang = "stack_exhausted"] extern fn stack_exhausted() {}
|
||||
#[lang = "eh_personality"] extern fn eh_personality() {}
|
||||
#[lang = "panic_fmt"] fn panic_fmt() -> ! { loop {} }
|
||||
```
|
||||
|
||||
Note the use of `abort`: the `exchange_malloc` lang item is assumed to
|
||||
return a valid pointer, and so needs to do the check internally.
|
||||
|
||||
Other features provided by lang items include:
|
||||
|
||||
- overloadable operators via traits: the traits corresponding to the
|
||||
`==`, `<`, dereferencing (`*`) and `+` (etc.) operators are all
|
||||
marked with lang items; those specific four are `eq`, `ord`,
|
||||
`deref`, and `add` respectively.
|
||||
- stack unwinding and general failure; the `eh_personality`, `fail`
|
||||
and `fail_bounds_checks` lang items.
|
||||
- the traits in `std::marker` used to indicate types of
|
||||
various kinds; lang items `send`, `sync` and `copy`.
|
||||
- the marker types and variance indicators found in
|
||||
`std::marker`; lang items `covariant_type`,
|
||||
`contravariant_lifetime`, etc.
|
||||
|
||||
Lang items are loaded lazily by the compiler; e.g. if one never uses
|
||||
`Box` then there is no need to define functions for `exchange_malloc`
|
||||
and `exchange_free`. `rustc` will emit an error when an item is needed
|
||||
but not found in the current crate or any that it depends on.
|
||||
25
src/doc/trpl/link-args.md
Normal file
25
src/doc/trpl/link-args.md
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
% Link args
|
||||
|
||||
There is one other way to tell rustc how to customize linking, and that is via
|
||||
the `link_args` attribute. This attribute is applied to `extern` blocks and
|
||||
specifies raw flags which need to get passed to the linker when producing an
|
||||
artifact. An example usage would be:
|
||||
|
||||
``` no_run
|
||||
#![feature(link_args)]
|
||||
|
||||
#[link_args = "-foo -bar -baz"]
|
||||
extern {}
|
||||
# fn main() {}
|
||||
```
|
||||
|
||||
Note that this feature is currently hidden behind the `feature(link_args)` gate
|
||||
because this is not a sanctioned way of performing linking. Right now rustc
|
||||
shells out to the system linker, so it makes sense to provide extra command line
|
||||
arguments, but this will not always be the case. In the future rustc may use
|
||||
LLVM directly to link native libraries in which case `link_args` will have no
|
||||
meaning.
|
||||
|
||||
It is highly recommended to *not* use this attribute, and rather use the more
|
||||
formal `#[link(...)]` attribute on `extern` blocks instead.
|
||||
|
||||
|
|
@ -123,7 +123,7 @@ We now loop forever with `loop` and use `break` to break out early.
|
|||
iteration. This will only print the odd numbers:
|
||||
|
||||
```{rust}
|
||||
for x in 0u32..10 {
|
||||
for x in 0..10 {
|
||||
if x % 2 == 0 { continue; }
|
||||
|
||||
println!("{}", x);
|
||||
|
|
|
|||
|
|
@ -46,12 +46,13 @@ This will print `12.566371`.
|
|||
|
||||
We've made a struct that represents a circle. We then write an `impl` block,
|
||||
and inside it, define a method, `area`. Methods take a special first
|
||||
parameter, `&self`. There are three variants: `self`, `&self`, and `&mut self`.
|
||||
parameter, of which there are three variants: `self`, `&self`, and `&mut self`.
|
||||
You can think of this first parameter as being the `x` in `x.foo()`. The three
|
||||
variants correspond to the three kinds of thing `x` could be: `self` if it's
|
||||
just a value on the stack, `&self` if it's a reference, and `&mut self` if it's
|
||||
a mutable reference. We should default to using `&self`, as it's the most
|
||||
common. Here's an example of all three variants:
|
||||
a mutable reference. We should default to using `&self`, as you should prefer
|
||||
borrowing over taking ownership, as well as taking immutable references
|
||||
over mutable ones. Here's an example of all three variants:
|
||||
|
||||
```rust
|
||||
struct Circle {
|
||||
|
|
@ -100,8 +101,8 @@ impl Circle {
|
|||
std::f64::consts::PI * (self.radius * self.radius)
|
||||
}
|
||||
|
||||
fn grow(&self) -> Circle {
|
||||
Circle { x: self.x, y: self.y, radius: (self.radius * 10.0) }
|
||||
fn grow(&self, increment: f64) -> Circle {
|
||||
Circle { x: self.x, y: self.y, radius: self.radius + increment }
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -109,7 +110,7 @@ fn main() {
|
|||
let c = Circle { x: 0.0, y: 0.0, radius: 2.0 };
|
||||
println!("{}", c.area());
|
||||
|
||||
let d = c.grow().area();
|
||||
let d = c.grow(2.0).area();
|
||||
println!("{}", d);
|
||||
}
|
||||
```
|
||||
|
|
@ -124,7 +125,7 @@ fn grow(&self) -> Circle {
|
|||
```
|
||||
|
||||
We just say we're returning a `Circle`. With this method, we can grow a new
|
||||
circle with an area that's 100 times larger than the old one.
|
||||
circle to any arbitrary size.
|
||||
|
||||
## Static methods
|
||||
|
||||
|
|
|
|||
|
|
@ -129,7 +129,7 @@ need, and it can make your lifetimes more complex.
|
|||
To write a function that's generic over types of strings, use `&str`.
|
||||
|
||||
```
|
||||
fn some_string_length(x: &str) -> uint {
|
||||
fn some_string_length(x: &str) -> usize {
|
||||
x.len()
|
||||
}
|
||||
|
||||
|
|
|
|||
168
src/doc/trpl/no-stdlib.md
Normal file
168
src/doc/trpl/no-stdlib.md
Normal file
|
|
@ -0,0 +1,168 @@
|
|||
% No stdlib
|
||||
|
||||
By default, `std` is linked to every Rust crate. In some contexts,
|
||||
this is undesirable, and can be avoided with the `#![no_std]`
|
||||
attribute attached to the crate.
|
||||
|
||||
```ignore
|
||||
// a minimal library
|
||||
#![crate_type="lib"]
|
||||
#![feature(no_std)]
|
||||
#![no_std]
|
||||
# // fn main() {} tricked you, rustdoc!
|
||||
```
|
||||
|
||||
Obviously there's more to life than just libraries: one can use
|
||||
`#[no_std]` with an executable, controlling the entry point is
|
||||
possible in two ways: the `#[start]` attribute, or overriding the
|
||||
default shim for the C `main` function with your own.
|
||||
|
||||
The function marked `#[start]` is passed the command line parameters
|
||||
in the same format as C:
|
||||
|
||||
```
|
||||
#![feature(lang_items, start, no_std, libc)]
|
||||
#![no_std]
|
||||
|
||||
// Pull in the system libc library for what crt0.o likely requires
|
||||
extern crate libc;
|
||||
|
||||
// Entry point for this program
|
||||
#[start]
|
||||
fn start(_argc: isize, _argv: *const *const u8) -> isize {
|
||||
0
|
||||
}
|
||||
|
||||
// These functions and traits are used by the compiler, but not
|
||||
// for a bare-bones hello world. These are normally
|
||||
// provided by libstd.
|
||||
#[lang = "stack_exhausted"] extern fn stack_exhausted() {}
|
||||
#[lang = "eh_personality"] extern fn eh_personality() {}
|
||||
#[lang = "panic_fmt"] fn panic_fmt() -> ! { loop {} }
|
||||
# // fn main() {} tricked you, rustdoc!
|
||||
```
|
||||
|
||||
To override the compiler-inserted `main` shim, one has to disable it
|
||||
with `#![no_main]` and then create the appropriate symbol with the
|
||||
correct ABI and the correct name, which requires overriding the
|
||||
compiler's name mangling too:
|
||||
|
||||
```ignore
|
||||
#![feature(no_std)]
|
||||
#![no_std]
|
||||
#![no_main]
|
||||
#![feature(lang_items, start)]
|
||||
|
||||
extern crate libc;
|
||||
|
||||
#[no_mangle] // ensure that this symbol is called `main` in the output
|
||||
pub extern fn main(argc: i32, argv: *const *const u8) -> i32 {
|
||||
0
|
||||
}
|
||||
|
||||
#[lang = "stack_exhausted"] extern fn stack_exhausted() {}
|
||||
#[lang = "eh_personality"] extern fn eh_personality() {}
|
||||
#[lang = "panic_fmt"] fn panic_fmt() -> ! { loop {} }
|
||||
# // fn main() {} tricked you, rustdoc!
|
||||
```
|
||||
|
||||
|
||||
The compiler currently makes a few assumptions about symbols which are available
|
||||
in the executable to call. Normally these functions are provided by the standard
|
||||
library, but without it you must define your own.
|
||||
|
||||
The first of these three functions, `stack_exhausted`, is invoked whenever stack
|
||||
overflow is detected. This function has a number of restrictions about how it
|
||||
can be called and what it must do, but if the stack limit register is not being
|
||||
maintained then a thread always has an "infinite stack" and this function
|
||||
shouldn't get triggered.
|
||||
|
||||
The second of these three functions, `eh_personality`, is used by the
|
||||
failure mechanisms of the compiler. This is often mapped to GCC's
|
||||
personality function (see the
|
||||
[libstd implementation](../std/rt/unwind/index.html) for more
|
||||
information), but crates which do not trigger a panic can be assured
|
||||
that this function is never called. The final function, `panic_fmt`, is
|
||||
also used by the failure mechanisms of the compiler.
|
||||
|
||||
## Using libcore
|
||||
|
||||
> **Note**: the core library's structure is unstable, and it is recommended to
|
||||
> use the standard library instead wherever possible.
|
||||
|
||||
With the above techniques, we've got a bare-metal executable running some Rust
|
||||
code. There is a good deal of functionality provided by the standard library,
|
||||
however, that is necessary to be productive in Rust. If the standard library is
|
||||
not sufficient, then [libcore](../core/index.html) is designed to be used
|
||||
instead.
|
||||
|
||||
The core library has very few dependencies and is much more portable than the
|
||||
standard library itself. Additionally, the core library has most of the
|
||||
necessary functionality for writing idiomatic and effective Rust code.
|
||||
|
||||
As an example, here is a program that will calculate the dot product of two
|
||||
vectors provided from C, using idiomatic Rust practices.
|
||||
|
||||
```
|
||||
#![feature(lang_items, start, no_std, core, libc)]
|
||||
#![no_std]
|
||||
|
||||
# extern crate libc;
|
||||
extern crate core;
|
||||
|
||||
use core::prelude::*;
|
||||
|
||||
use core::mem;
|
||||
|
||||
#[no_mangle]
|
||||
pub extern fn dot_product(a: *const u32, a_len: u32,
|
||||
b: *const u32, b_len: u32) -> u32 {
|
||||
use core::raw::Slice;
|
||||
|
||||
// Convert the provided arrays into Rust slices.
|
||||
// The core::raw module guarantees that the Slice
|
||||
// structure has the same memory layout as a &[T]
|
||||
// slice.
|
||||
//
|
||||
// This is an unsafe operation because the compiler
|
||||
// cannot tell the pointers are valid.
|
||||
let (a_slice, b_slice): (&[u32], &[u32]) = unsafe {
|
||||
mem::transmute((
|
||||
Slice { data: a, len: a_len as usize },
|
||||
Slice { data: b, len: b_len as usize },
|
||||
))
|
||||
};
|
||||
|
||||
// Iterate over the slices, collecting the result
|
||||
let mut ret = 0;
|
||||
for (i, j) in a_slice.iter().zip(b_slice.iter()) {
|
||||
ret += (*i) * (*j);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
#[lang = "panic_fmt"]
|
||||
extern fn panic_fmt(args: &core::fmt::Arguments,
|
||||
file: &str,
|
||||
line: u32) -> ! {
|
||||
loop {}
|
||||
}
|
||||
|
||||
#[lang = "stack_exhausted"] extern fn stack_exhausted() {}
|
||||
#[lang = "eh_personality"] extern fn eh_personality() {}
|
||||
# #[start] fn start(argc: isize, argv: *const *const u8) -> isize { 0 }
|
||||
# fn main() {}
|
||||
```
|
||||
|
||||
Note that there is one extra lang item here which differs from the examples
|
||||
above, `panic_fmt`. This must be defined by consumers of libcore because the
|
||||
core library declares panics, but it does not define it. The `panic_fmt`
|
||||
lang item is this crate's definition of panic, and it must be guaranteed to
|
||||
never return.
|
||||
|
||||
As can be seen in this example, the core library is intended to provide the
|
||||
power of Rust in all circumstances, regardless of platform requirements. Further
|
||||
libraries, such as liballoc, add functionality to libcore which make other
|
||||
platform-specific assumptions, but continue to be more portable than the
|
||||
standard library itself.
|
||||
|
||||
|
|
@ -177,6 +177,7 @@ match origin {
|
|||
If you want to match against a slice or array, you can use `&`:
|
||||
|
||||
```{rust}
|
||||
# #![feature(slice_patterns)]
|
||||
fn main() {
|
||||
let v = vec!["match_this", "1"];
|
||||
|
||||
|
|
|
|||
|
|
@ -1,29 +1,5 @@
|
|||
% Compiler Plugins
|
||||
|
||||
<div class="unstable-feature">
|
||||
|
||||
<p>
|
||||
<b>Warning:</b> Plugins are an advanced, unstable feature! For many details,
|
||||
the only available documentation is the <a
|
||||
href="../syntax/index.html"><code>libsyntax</code></a> and <a
|
||||
href="../rustc/index.html"><code>librustc</code></a> API docs, or even the source
|
||||
code itself. These internal compiler APIs are also subject to change at any
|
||||
time.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
For defining new syntax it is often much easier to use Rust's <a
|
||||
href="macros.html">built-in macro system</a>.
|
||||
</p>
|
||||
|
||||
<p style="margin-bottom: 0">
|
||||
The code in this document uses language features not covered in the Rust
|
||||
Guide. See the <a href="../reference.html">Reference Manual</a> for more
|
||||
information.
|
||||
</p>
|
||||
|
||||
</div>
|
||||
|
||||
# Introduction
|
||||
|
||||
`rustc` can load compiler plugins, which are user-provided libraries that
|
||||
|
|
|
|||
|
|
@ -568,8 +568,8 @@ fn add(x: &i32, y: &i32) -> i32 {
|
|||
fn main() {
|
||||
let x = Box::new(5);
|
||||
|
||||
println!("{}", add(&x, &x));
|
||||
println!("{}", add(&x, &x));
|
||||
println!("{}", add(&*x, &*x));
|
||||
println!("{}", add(&*x, &*x));
|
||||
}
|
||||
```
|
||||
|
||||
|
|
|
|||
|
|
@ -1,165 +0,0 @@
|
|||
% Standard Input
|
||||
|
||||
Getting input from the keyboard is pretty easy, but uses some things
|
||||
we haven't seen before. Here's a simple program that reads some input,
|
||||
and then prints it back out:
|
||||
|
||||
```{rust,ignore}
|
||||
corefn main() {
|
||||
println!("Type something!");
|
||||
|
||||
let input = std::old_io::stdin().read_line().ok().expect("Failed to read line");
|
||||
|
||||
println!("{}", input);
|
||||
}
|
||||
```
|
||||
|
||||
Let's go over these chunks, one by one:
|
||||
|
||||
```{rust,ignore}
|
||||
std::old_io::stdin();
|
||||
```
|
||||
|
||||
This calls a function, `stdin()`, that lives inside the `std::old_io` module. As
|
||||
you can imagine, everything in `std` is provided by Rust, the 'standard
|
||||
library.' We'll talk more about the module system later.
|
||||
|
||||
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();
|
||||
```
|
||||
|
||||
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();
|
||||
```
|
||||
|
||||
Let's update our example to use this style:
|
||||
|
||||
```{rust,ignore}
|
||||
use std::old_io;
|
||||
|
||||
fn main() {
|
||||
println!("Type something!");
|
||||
|
||||
let input = old_io::stdin().read_line().ok().expect("Failed to read line");
|
||||
|
||||
println!("{}", input);
|
||||
}
|
||||
```
|
||||
|
||||
Next up:
|
||||
|
||||
```{rust,ignore}
|
||||
.read_line()
|
||||
```
|
||||
|
||||
The `read_line()` method can be called on the result of `stdin()` to return
|
||||
a full line of input. Nice and easy.
|
||||
|
||||
```{rust,ignore}
|
||||
.ok().expect("Failed to read line");
|
||||
```
|
||||
|
||||
Do you remember this code?
|
||||
|
||||
```{rust}
|
||||
enum OptionalInt {
|
||||
Value(i32),
|
||||
Missing,
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let x = OptionalInt::Value(5);
|
||||
let y = OptionalInt::Missing;
|
||||
|
||||
match x {
|
||||
OptionalInt::Value(n) => println!("x is {}", n),
|
||||
OptionalInt::Missing => println!("x is missing!"),
|
||||
}
|
||||
|
||||
match y {
|
||||
OptionalInt::Value(n) => println!("y is {}", n),
|
||||
OptionalInt::Missing => println!("y is missing!"),
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
We had to match each time to see if we had a value or not. In this case,
|
||||
though, we _know_ that `x` has a `Value`, but `match` forces us to handle
|
||||
the `missing` case. This is what we want 99% of the time, but sometimes, we
|
||||
know better than the compiler.
|
||||
|
||||
Likewise, `read_line()` does not return a line of input. It _might_ return a
|
||||
line of input, though it might also fail to do so. This could happen if our program
|
||||
isn't running in a terminal, but as part of a cron job, or some other context
|
||||
where there's no standard input. Because of this, `read_line` returns a type
|
||||
very similar to our `OptionalInt`: an `IoResult<T>`. We haven't talked about
|
||||
`IoResult<T>` yet because it is the *generic* form of our `OptionalInt`.
|
||||
Until then, you can think of it as being the same thing, just for any type –
|
||||
not just `i32`s.
|
||||
|
||||
Rust provides a method on these `IoResult<T>`s called `ok()`, which does the
|
||||
same thing as our `match` statement but assumes that we have a valid value.
|
||||
We then call `expect()` on the result, which will terminate our program if we
|
||||
don't have a valid value. In this case, if we can't get input, our program
|
||||
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 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:
|
||||
|
||||
```{rust,ignore}
|
||||
use std::old_io;
|
||||
|
||||
fn main() {
|
||||
println!("Type something!");
|
||||
|
||||
let input = old_io::stdin().read_line().ok().expect("Failed to read line");
|
||||
|
||||
println!("{}", input);
|
||||
}
|
||||
```
|
||||
|
||||
With long lines like this, Rust gives you some flexibility with the whitespace.
|
||||
We _could_ write the example like this:
|
||||
|
||||
```{rust,ignore}
|
||||
use std::old_io;
|
||||
|
||||
fn main() {
|
||||
println!("Type something!");
|
||||
|
||||
// here, we'll show the types at each step
|
||||
|
||||
let input = old_io::stdin() // std::old_io::stdio::StdinReader
|
||||
.read_line() // IoResult<String>
|
||||
.ok() // Option<String>
|
||||
.expect("Failed to read line"); // String
|
||||
|
||||
println!("{}", input);
|
||||
}
|
||||
```
|
||||
|
||||
Sometimes, this makes things more readable – sometimes, less. Use your judgement
|
||||
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
|
||||
91
src/doc/trpl/tracing-macros.md
Normal file
91
src/doc/trpl/tracing-macros.md
Normal file
|
|
@ -0,0 +1,91 @@
|
|||
% Tracing Macros
|
||||
|
||||
The `trace_macros` feature allows you to use a special feature: tracing macro
|
||||
invocations.
|
||||
|
||||
In the advanced macros chapter, we defined a `bct` macro:
|
||||
|
||||
```rust
|
||||
macro_rules! bct {
|
||||
// cmd 0: d ... => ...
|
||||
(0, $($ps:tt),* ; $_d:tt)
|
||||
=> (bct!($($ps),*, 0 ; ));
|
||||
(0, $($ps:tt),* ; $_d:tt, $($ds:tt),*)
|
||||
=> (bct!($($ps),*, 0 ; $($ds),*));
|
||||
|
||||
// cmd 1p: 1 ... => 1 ... p
|
||||
(1, $p:tt, $($ps:tt),* ; 1)
|
||||
=> (bct!($($ps),*, 1, $p ; 1, $p));
|
||||
(1, $p:tt, $($ps:tt),* ; 1, $($ds:tt),*)
|
||||
=> (bct!($($ps),*, 1, $p ; 1, $($ds),*, $p));
|
||||
|
||||
// cmd 1p: 0 ... => 0 ...
|
||||
(1, $p:tt, $($ps:tt),* ; $($ds:tt),*)
|
||||
=> (bct!($($ps),*, 1, $p ; $($ds),*));
|
||||
|
||||
// halt on empty data string
|
||||
( $($ps:tt),* ; )
|
||||
=> (());
|
||||
}
|
||||
```
|
||||
|
||||
This is pretty complex! we can see the output
|
||||
|
||||
```rust,ignore
|
||||
#![feature(trace_macros)]
|
||||
|
||||
macro_rules! bct {
|
||||
// cmd 0: d ... => ...
|
||||
(0, $($ps:tt),* ; $_d:tt)
|
||||
=> (bct!($($ps),*, 0 ; ));
|
||||
(0, $($ps:tt),* ; $_d:tt, $($ds:tt),*)
|
||||
=> (bct!($($ps),*, 0 ; $($ds),*));
|
||||
|
||||
// cmd 1p: 1 ... => 1 ... p
|
||||
(1, $p:tt, $($ps:tt),* ; 1)
|
||||
=> (bct!($($ps),*, 1, $p ; 1, $p));
|
||||
(1, $p:tt, $($ps:tt),* ; 1, $($ds:tt),*)
|
||||
=> (bct!($($ps),*, 1, $p ; 1, $($ds),*, $p));
|
||||
|
||||
// cmd 1p: 0 ... => 0 ...
|
||||
(1, $p:tt, $($ps:tt),* ; $($ds:tt),*)
|
||||
=> (bct!($($ps),*, 1, $p ; $($ds),*));
|
||||
|
||||
// halt on empty data string
|
||||
( $($ps:tt),* ; )
|
||||
=> (());
|
||||
}
|
||||
|
||||
fn main() {
|
||||
trace_macros!(true);
|
||||
|
||||
bct!(0, 0, 1, 1, 1 ; 1, 0, 1);
|
||||
}
|
||||
```
|
||||
|
||||
This will print out a wall of text:
|
||||
|
||||
```text
|
||||
bct! { 0 , 0 , 1 , 1 , 1 ; 1 , 0 , 1 }
|
||||
bct! { 0 , 1 , 1 , 1 , 0 ; 0 , 1 }
|
||||
bct! { 1 , 1 , 1 , 0 , 0 ; 1 }
|
||||
bct! { 1 , 0 , 0 , 1 , 1 ; 1 , 1 }
|
||||
bct! { 0 , 1 , 1 , 1 , 0 ; 1 , 1 , 0 }
|
||||
bct! { 1 , 1 , 1 , 0 , 0 ; 1 , 0 }
|
||||
bct! { 1 , 0 , 0 , 1 , 1 ; 1 , 0 , 1 }
|
||||
bct! { 0 , 1 , 1 , 1 , 0 ; 1 , 0 , 1 , 0 }
|
||||
bct! { 1 , 1 , 1 , 0 , 0 ; 0 , 1 , 0 }
|
||||
bct! { 1 , 0 , 0 , 1 , 1 ; 0 , 1 , 0 }
|
||||
bct! { 0 , 1 , 1 , 1 , 0 ; 0 , 1 , 0 }
|
||||
```
|
||||
|
||||
And eventually, error:
|
||||
|
||||
```text
|
||||
18:45 error: recursion limit reached while expanding the macro `bct`
|
||||
=> (bct!($($ps),*, 1, $p ; $($ds),*));
|
||||
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
```
|
||||
|
||||
The `trace_macros!` call is what produces this output, showing how we match
|
||||
each time.
|
||||
|
|
@ -479,7 +479,7 @@ impl Foo for OverrideDefault {
|
|||
}
|
||||
|
||||
let default = UseDefault;
|
||||
default.baz(); // prints "We called bar."
|
||||
default.baz(); // prints "We called baz."
|
||||
|
||||
let over = OverrideDefault;
|
||||
over.baz(); // prints "Override baz!"
|
||||
|
|
|
|||
|
|
@ -181,539 +181,3 @@ code:
|
|||
that clean-up is always run, even when the thread panics.
|
||||
- ensure that any data stored behind a raw pointer is destroyed at the
|
||||
appropriate time.
|
||||
|
||||
As an example, we give a reimplementation of owned boxes by wrapping
|
||||
`malloc` and `free`. Rust's move semantics and lifetimes mean this
|
||||
reimplementation is as safe as the `Box` type.
|
||||
|
||||
```
|
||||
# #![feature(libc)]
|
||||
#![feature(unsafe_destructor)]
|
||||
|
||||
extern crate libc;
|
||||
use libc::{c_void, size_t, malloc, free};
|
||||
use std::mem;
|
||||
use std::ptr;
|
||||
|
||||
// Define a wrapper around the handle returned by the foreign code.
|
||||
// Unique<T> has the same semantics as Box<T>
|
||||
//
|
||||
// NB: For simplicity and correctness, we require that T has kind Send
|
||||
// (owned boxes relax this restriction).
|
||||
pub struct Unique<T: Send> {
|
||||
// It contains a single raw, mutable pointer to the object in question.
|
||||
ptr: *mut T
|
||||
}
|
||||
|
||||
// Implement methods for creating and using the values in the box.
|
||||
|
||||
impl<T: Send> Unique<T> {
|
||||
pub fn new(value: T) -> Unique<T> {
|
||||
unsafe {
|
||||
let ptr = malloc(mem::size_of::<T>() as size_t) as *mut T;
|
||||
// we *need* valid pointer.
|
||||
assert!(!ptr.is_null());
|
||||
// `*ptr` is uninitialized, and `*ptr = value` would
|
||||
// attempt to destroy it `overwrite` moves a value into
|
||||
// this memory without attempting to drop the original
|
||||
// value.
|
||||
ptr::write(&mut *ptr, value);
|
||||
Unique{ptr: ptr}
|
||||
}
|
||||
}
|
||||
|
||||
// the 'r lifetime results in the same semantics as `&*x` with
|
||||
// Box<T>
|
||||
pub fn borrow<'r>(&'r self) -> &'r T {
|
||||
// By construction, self.ptr is valid
|
||||
unsafe { &*self.ptr }
|
||||
}
|
||||
|
||||
// the 'r lifetime results in the same semantics as `&mut *x` with
|
||||
// Box<T>
|
||||
pub fn borrow_mut<'r>(&'r mut self) -> &'r mut T {
|
||||
unsafe { &mut *self.ptr }
|
||||
}
|
||||
}
|
||||
|
||||
// A key ingredient for safety, we associate a destructor with
|
||||
// Unique<T>, making the struct manage the raw pointer: when the
|
||||
// struct goes out of scope, it will automatically free the raw pointer.
|
||||
//
|
||||
// NB: This is an unsafe destructor; rustc will not normally allow
|
||||
// destructors to be associated with parameterized types (due to
|
||||
// historically failing to check them soundly). Note that the
|
||||
// `#[unsafe_destructor]` feature gate is currently required to use
|
||||
// unsafe destructors.
|
||||
#[unsafe_destructor]
|
||||
impl<T: Send> Drop for Unique<T> {
|
||||
fn drop(&mut self) {
|
||||
unsafe {
|
||||
// Copy the object out from the pointer onto the stack,
|
||||
// where it is covered by normal Rust destructor semantics
|
||||
// and cleans itself up, if necessary
|
||||
ptr::read(self.ptr);
|
||||
|
||||
// clean-up our allocation
|
||||
free(self.ptr as *mut c_void)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// A comparison between the built-in `Box` and this reimplementation
|
||||
fn main() {
|
||||
{
|
||||
let mut x = Box::new(5);
|
||||
*x = 10;
|
||||
} // `x` is freed here
|
||||
|
||||
{
|
||||
let mut y = Unique::new(5);
|
||||
*y.borrow_mut() = 10;
|
||||
} // `y` is freed here
|
||||
}
|
||||
```
|
||||
|
||||
Notably, the only way to construct a `Unique` is via the `new`
|
||||
function, and this function ensures that the internal pointer is valid
|
||||
and hidden in the private field. The two `borrow` methods are safe
|
||||
because the compiler statically guarantees that objects are never used
|
||||
before creation or after destruction (unless you use some `unsafe`
|
||||
code...).
|
||||
|
||||
# Inline assembly
|
||||
|
||||
For extremely low-level manipulations and performance reasons, one
|
||||
might wish to control the CPU directly. Rust supports using inline
|
||||
assembly to do this via the `asm!` macro. The syntax roughly matches
|
||||
that of GCC & Clang:
|
||||
|
||||
```ignore
|
||||
asm!(assembly template
|
||||
: output operands
|
||||
: input operands
|
||||
: clobbers
|
||||
: options
|
||||
);
|
||||
```
|
||||
|
||||
Any use of `asm` is feature gated (requires `#![feature(asm)]` on the
|
||||
crate to allow) and of course requires an `unsafe` block.
|
||||
|
||||
> **Note**: the examples here are given in x86/x86-64 assembly, but
|
||||
> all platforms are supported.
|
||||
|
||||
## Assembly template
|
||||
|
||||
The `assembly template` is the only required parameter and must be a
|
||||
literal string (i.e. `""`)
|
||||
|
||||
```
|
||||
#![feature(asm)]
|
||||
|
||||
#[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
|
||||
fn foo() {
|
||||
unsafe {
|
||||
asm!("NOP");
|
||||
}
|
||||
}
|
||||
|
||||
// other platforms
|
||||
#[cfg(not(any(target_arch = "x86", target_arch = "x86_64")))]
|
||||
fn foo() { /* ... */ }
|
||||
|
||||
fn main() {
|
||||
// ...
|
||||
foo();
|
||||
// ...
|
||||
}
|
||||
```
|
||||
|
||||
(The `feature(asm)` and `#[cfg]`s are omitted from now on.)
|
||||
|
||||
Output operands, input operands, clobbers and options are all optional
|
||||
but you must add the right number of `:` if you skip them:
|
||||
|
||||
```
|
||||
# #![feature(asm)]
|
||||
# #[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
|
||||
# fn main() { unsafe {
|
||||
asm!("xor %eax, %eax"
|
||||
:
|
||||
:
|
||||
: "eax"
|
||||
);
|
||||
# } }
|
||||
```
|
||||
|
||||
Whitespace also doesn't matter:
|
||||
|
||||
```
|
||||
# #![feature(asm)]
|
||||
# #[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
|
||||
# fn main() { unsafe {
|
||||
asm!("xor %eax, %eax" ::: "eax");
|
||||
# } }
|
||||
```
|
||||
|
||||
## Operands
|
||||
|
||||
Input and output operands follow the same format: `:
|
||||
"constraints1"(expr1), "constraints2"(expr2), ..."`. Output operand
|
||||
expressions must be mutable lvalues:
|
||||
|
||||
```
|
||||
# #![feature(asm)]
|
||||
# #[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
|
||||
fn add(a: i32, b: i32) -> i32 {
|
||||
let mut c = 0;
|
||||
unsafe {
|
||||
asm!("add $2, $0"
|
||||
: "=r"(c)
|
||||
: "0"(a), "r"(b)
|
||||
);
|
||||
}
|
||||
c
|
||||
}
|
||||
# #[cfg(not(any(target_arch = "x86", target_arch = "x86_64")))]
|
||||
# fn add(a: i32, b: i32) -> i32 { a + b }
|
||||
|
||||
fn main() {
|
||||
assert_eq!(add(3, 14159), 14162)
|
||||
}
|
||||
```
|
||||
|
||||
## Clobbers
|
||||
|
||||
Some instructions modify registers which might otherwise have held
|
||||
different values so we use the clobbers list to indicate to the
|
||||
compiler not to assume any values loaded into those registers will
|
||||
stay valid.
|
||||
|
||||
```
|
||||
# #![feature(asm)]
|
||||
# #[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
|
||||
# fn main() { unsafe {
|
||||
// Put the value 0x200 in eax
|
||||
asm!("mov $$0x200, %eax" : /* no outputs */ : /* no inputs */ : "eax");
|
||||
# } }
|
||||
```
|
||||
|
||||
Input and output registers need not be listed since that information
|
||||
is already communicated by the given constraints. Otherwise, any other
|
||||
registers used either implicitly or explicitly should be listed.
|
||||
|
||||
If the assembly changes the condition code register `cc` should be
|
||||
specified as one of the clobbers. Similarly, if the assembly modifies
|
||||
memory, `memory` should also be specified.
|
||||
|
||||
## Options
|
||||
|
||||
The last section, `options` is specific to Rust. The format is comma
|
||||
separated literal strings (i.e. `:"foo", "bar", "baz"`). It's used to
|
||||
specify some extra info about the inline assembly:
|
||||
|
||||
Current valid options are:
|
||||
|
||||
1. *volatile* - specifying this is analogous to
|
||||
`__asm__ __volatile__ (...)` in gcc/clang.
|
||||
2. *alignstack* - certain instructions expect the stack to be
|
||||
aligned a certain way (i.e. SSE) and specifying this indicates to
|
||||
the compiler to insert its usual stack alignment code
|
||||
3. *intel* - use intel syntax instead of the default AT&T.
|
||||
|
||||
# Avoiding the standard library
|
||||
|
||||
By default, `std` is linked to every Rust crate. In some contexts,
|
||||
this is undesirable, and can be avoided with the `#![no_std]`
|
||||
attribute attached to the crate.
|
||||
|
||||
```ignore
|
||||
// a minimal library
|
||||
#![crate_type="lib"]
|
||||
#![feature(no_std)]
|
||||
#![no_std]
|
||||
# // fn main() {} tricked you, rustdoc!
|
||||
```
|
||||
|
||||
Obviously there's more to life than just libraries: one can use
|
||||
`#[no_std]` with an executable, controlling the entry point is
|
||||
possible in two ways: the `#[start]` attribute, or overriding the
|
||||
default shim for the C `main` function with your own.
|
||||
|
||||
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]
|
||||
|
||||
// Pull in the system libc library for what crt0.o likely requires
|
||||
extern crate libc;
|
||||
|
||||
// Entry point for this program
|
||||
#[start]
|
||||
fn start(_argc: isize, _argv: *const *const u8) -> isize {
|
||||
0
|
||||
}
|
||||
|
||||
// These functions and traits are used by the compiler, but not
|
||||
// for a bare-bones hello world. These are normally
|
||||
// provided by libstd.
|
||||
#[lang = "stack_exhausted"] extern fn stack_exhausted() {}
|
||||
#[lang = "eh_personality"] extern fn eh_personality() {}
|
||||
#[lang = "panic_fmt"] fn panic_fmt() -> ! { loop {} }
|
||||
# // fn main() {} tricked you, rustdoc!
|
||||
```
|
||||
|
||||
To override the compiler-inserted `main` shim, one has to disable it
|
||||
with `#![no_main]` and then create the appropriate symbol with the
|
||||
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]
|
||||
#![feature(lang_items, start)]
|
||||
|
||||
extern crate libc;
|
||||
|
||||
#[no_mangle] // ensure that this symbol is called `main` in the output
|
||||
pub extern fn main(argc: i32, argv: *const *const u8) -> i32 {
|
||||
0
|
||||
}
|
||||
|
||||
#[lang = "stack_exhausted"] extern fn stack_exhausted() {}
|
||||
#[lang = "eh_personality"] extern fn eh_personality() {}
|
||||
#[lang = "panic_fmt"] fn panic_fmt() -> ! { loop {} }
|
||||
# // fn main() {} tricked you, rustdoc!
|
||||
```
|
||||
|
||||
|
||||
The compiler currently makes a few assumptions about symbols which are available
|
||||
in the executable to call. Normally these functions are provided by the standard
|
||||
library, but without it you must define your own.
|
||||
|
||||
The first of these three functions, `stack_exhausted`, is invoked whenever stack
|
||||
overflow is detected. This function has a number of restrictions about how it
|
||||
can be called and what it must do, but if the stack limit register is not being
|
||||
maintained then a thread always has an "infinite stack" and this function
|
||||
shouldn't get triggered.
|
||||
|
||||
The second of these three functions, `eh_personality`, is used by the
|
||||
failure mechanisms of the compiler. This is often mapped to GCC's
|
||||
personality function (see the
|
||||
[libstd implementation](../std/rt/unwind/index.html) for more
|
||||
information), but crates which do not trigger a panic can be assured
|
||||
that this function is never called. The final function, `panic_fmt`, is
|
||||
also used by the failure mechanisms of the compiler.
|
||||
|
||||
## Using libcore
|
||||
|
||||
> **Note**: the core library's structure is unstable, and it is recommended to
|
||||
> use the standard library instead wherever possible.
|
||||
|
||||
With the above techniques, we've got a bare-metal executable running some Rust
|
||||
code. There is a good deal of functionality provided by the standard library,
|
||||
however, that is necessary to be productive in Rust. If the standard library is
|
||||
not sufficient, then [libcore](../core/index.html) is designed to be used
|
||||
instead.
|
||||
|
||||
The core library has very few dependencies and is much more portable than the
|
||||
standard library itself. Additionally, the core library has most of the
|
||||
necessary functionality for writing idiomatic and effective Rust code.
|
||||
|
||||
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]
|
||||
|
||||
# extern crate libc;
|
||||
extern crate core;
|
||||
|
||||
use core::prelude::*;
|
||||
|
||||
use core::mem;
|
||||
|
||||
#[no_mangle]
|
||||
pub extern fn dot_product(a: *const u32, a_len: u32,
|
||||
b: *const u32, b_len: u32) -> u32 {
|
||||
use core::raw::Slice;
|
||||
|
||||
// Convert the provided arrays into Rust slices.
|
||||
// The core::raw module guarantees that the Slice
|
||||
// structure has the same memory layout as a &[T]
|
||||
// slice.
|
||||
//
|
||||
// This is an unsafe operation because the compiler
|
||||
// cannot tell the pointers are valid.
|
||||
let (a_slice, b_slice): (&[u32], &[u32]) = unsafe {
|
||||
mem::transmute((
|
||||
Slice { data: a, len: a_len as usize },
|
||||
Slice { data: b, len: b_len as usize },
|
||||
))
|
||||
};
|
||||
|
||||
// Iterate over the slices, collecting the result
|
||||
let mut ret = 0;
|
||||
for (i, j) in a_slice.iter().zip(b_slice.iter()) {
|
||||
ret += (*i) * (*j);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
#[lang = "panic_fmt"]
|
||||
extern fn panic_fmt(args: &core::fmt::Arguments,
|
||||
file: &str,
|
||||
line: u32) -> ! {
|
||||
loop {}
|
||||
}
|
||||
|
||||
#[lang = "stack_exhausted"] extern fn stack_exhausted() {}
|
||||
#[lang = "eh_personality"] extern fn eh_personality() {}
|
||||
# #[start] fn start(argc: isize, argv: *const *const u8) -> isize { 0 }
|
||||
# fn main() {}
|
||||
```
|
||||
|
||||
Note that there is one extra lang item here which differs from the examples
|
||||
above, `panic_fmt`. This must be defined by consumers of libcore because the
|
||||
core library declares panics, but it does not define it. The `panic_fmt`
|
||||
lang item is this crate's definition of panic, and it must be guaranteed to
|
||||
never return.
|
||||
|
||||
As can be seen in this example, the core library is intended to provide the
|
||||
power of Rust in all circumstances, regardless of platform requirements. Further
|
||||
libraries, such as liballoc, add functionality to libcore which make other
|
||||
platform-specific assumptions, but continue to be more portable than the
|
||||
standard library itself.
|
||||
|
||||
# Interacting with the compiler internals
|
||||
|
||||
> **Note**: this section is specific to the `rustc` compiler; these
|
||||
> parts of the language may never be fully specified and so details may
|
||||
> differ wildly between implementations (and even versions of `rustc`
|
||||
> itself).
|
||||
>
|
||||
> Furthermore, this is just an overview; the best form of
|
||||
> documentation for specific instances of these features are their
|
||||
> definitions and uses in `std`.
|
||||
|
||||
The Rust language currently has two orthogonal mechanisms for allowing
|
||||
libraries to interact directly with the compiler and vice versa:
|
||||
|
||||
- intrinsics, functions built directly into the compiler providing
|
||||
very basic low-level functionality,
|
||||
- lang-items, special functions, types and traits in libraries marked
|
||||
with specific `#[lang]` attributes
|
||||
|
||||
## Intrinsics
|
||||
|
||||
> **Note**: intrinsics will forever have an unstable interface, it is
|
||||
> recommended to use the stable interfaces of libcore rather than intrinsics
|
||||
> directly.
|
||||
|
||||
These are imported as if they were FFI functions, with the special
|
||||
`rust-intrinsic` ABI. For example, if one was in a freestanding
|
||||
context, but wished to be able to `transmute` between types, and
|
||||
perform efficient pointer arithmetic, one would import those functions
|
||||
via a declaration like
|
||||
|
||||
```
|
||||
# #![feature(intrinsics)]
|
||||
# fn main() {}
|
||||
|
||||
extern "rust-intrinsic" {
|
||||
fn transmute<T, U>(x: T) -> U;
|
||||
|
||||
fn offset<T>(dst: *const T, offset: isize) -> *const T;
|
||||
}
|
||||
```
|
||||
|
||||
As with any other FFI functions, these are always `unsafe` to call.
|
||||
|
||||
## Lang items
|
||||
|
||||
> **Note**: lang items are often provided by crates in the Rust distribution,
|
||||
> and lang items themselves have an unstable interface. It is recommended to use
|
||||
> officially distributed crates instead of defining your own lang items.
|
||||
|
||||
The `rustc` compiler has certain pluggable operations, that is,
|
||||
functionality that isn't hard-coded into the language, but is
|
||||
implemented in libraries, with a special marker to tell the compiler
|
||||
it exists. The marker is the attribute `#[lang="..."]` and there are
|
||||
various different values of `...`, i.e. various different 'lang
|
||||
items'.
|
||||
|
||||
For example, `Box` pointers require two lang items, one for allocation
|
||||
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]
|
||||
|
||||
extern crate libc;
|
||||
|
||||
extern {
|
||||
fn abort() -> !;
|
||||
}
|
||||
|
||||
#[lang = "owned_box"]
|
||||
pub struct Box<T>(*mut T);
|
||||
|
||||
#[lang="exchange_malloc"]
|
||||
unsafe fn allocate(size: usize, _align: usize) -> *mut u8 {
|
||||
let p = libc::malloc(size as libc::size_t) as *mut u8;
|
||||
|
||||
// malloc failed
|
||||
if p as usize == 0 {
|
||||
abort();
|
||||
}
|
||||
|
||||
p
|
||||
}
|
||||
#[lang="exchange_free"]
|
||||
unsafe fn deallocate(ptr: *mut u8, _size: usize, _align: usize) {
|
||||
libc::free(ptr as *mut libc::c_void)
|
||||
}
|
||||
|
||||
#[start]
|
||||
fn main(argc: isize, argv: *const *const u8) -> isize {
|
||||
let x = box 1;
|
||||
|
||||
0
|
||||
}
|
||||
|
||||
#[lang = "stack_exhausted"] extern fn stack_exhausted() {}
|
||||
#[lang = "eh_personality"] extern fn eh_personality() {}
|
||||
#[lang = "panic_fmt"] fn panic_fmt() -> ! { loop {} }
|
||||
```
|
||||
|
||||
Note the use of `abort`: the `exchange_malloc` lang item is assumed to
|
||||
return a valid pointer, and so needs to do the check internally.
|
||||
|
||||
Other features provided by lang items include:
|
||||
|
||||
- overloadable operators via traits: the traits corresponding to the
|
||||
`==`, `<`, dereferencing (`*`) and `+` (etc.) operators are all
|
||||
marked with lang items; those specific four are `eq`, `ord`,
|
||||
`deref`, and `add` respectively.
|
||||
- stack unwinding and general failure; the `eh_personality`, `fail`
|
||||
and `fail_bounds_checks` lang items.
|
||||
- the traits in `std::marker` used to indicate types of
|
||||
various kinds; lang items `send`, `sync` and `copy`.
|
||||
- the marker types and variance indicators found in
|
||||
`std::marker`; lang items `covariant_type`,
|
||||
`contravariant_lifetime`, etc.
|
||||
|
||||
Lang items are loaded lazily by the compiler; e.g. if one never uses
|
||||
`Box` then there is no need to define functions for `exchange_malloc`
|
||||
and `exchange_free`. `rustc` will emit an error when an item is needed
|
||||
but not found in the current crate or any that it depends on.
|
||||
|
|
|
|||
1
src/doc/trpl/unstable.md
Normal file
1
src/doc/trpl/unstable.md
Normal file
|
|
@ -0,0 +1 @@
|
|||
% Unstable Rust
|
||||
|
|
@ -33,7 +33,7 @@
|
|||
//!
|
||||
//! Sharing some immutable data between tasks:
|
||||
//!
|
||||
//! ```
|
||||
//! ```no_run
|
||||
//! use std::sync::Arc;
|
||||
//! use std::thread;
|
||||
//!
|
||||
|
|
@ -50,7 +50,7 @@
|
|||
//!
|
||||
//! Sharing mutable data safely between tasks with a `Mutex`:
|
||||
//!
|
||||
//! ```
|
||||
//! ```no_run
|
||||
//! use std::sync::{Arc, Mutex};
|
||||
//! use std::thread;
|
||||
//!
|
||||
|
|
@ -76,7 +76,7 @@ use core::prelude::*;
|
|||
use core::atomic;
|
||||
use core::atomic::Ordering::{Relaxed, Release, Acquire, SeqCst};
|
||||
use core::fmt;
|
||||
use core::cmp::{Ordering};
|
||||
use core::cmp::Ordering;
|
||||
use core::default::Default;
|
||||
use core::mem::{min_align_of, size_of};
|
||||
use core::mem;
|
||||
|
|
@ -94,6 +94,9 @@ use heap::deallocate;
|
|||
/// With simple pipes, without `Arc`, a copy would have to be made for each
|
||||
/// task.
|
||||
///
|
||||
/// When you clone an `Arc<T>`, it will create another pointer to the data and
|
||||
/// increase the reference counter.
|
||||
///
|
||||
/// ```
|
||||
/// # #![feature(alloc, core)]
|
||||
/// use std::sync::Arc;
|
||||
|
|
@ -354,7 +357,8 @@ impl<T> Drop for Arc<T> {
|
|||
// 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 }
|
||||
// if ptr.is_null() { return }
|
||||
if ptr.is_null() || ptr as usize == mem::POST_DROP_USIZE { 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
|
||||
|
|
@ -485,7 +489,7 @@ impl<T> Drop for Weak<T> {
|
|||
let ptr = *self._ptr;
|
||||
|
||||
// see comments above for why this check is here
|
||||
if ptr.is_null() { return }
|
||||
if ptr.is_null() || ptr as usize == mem::POST_DROP_USIZE { 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
|
||||
|
|
|
|||
|
|
@ -75,7 +75,7 @@
|
|||
#![feature(box_syntax)]
|
||||
#![feature(optin_builtin_traits)]
|
||||
#![feature(unboxed_closures)]
|
||||
#![feature(unsafe_no_drop_flag)]
|
||||
#![feature(unsafe_no_drop_flag, filling_drop)]
|
||||
#![feature(core)]
|
||||
#![feature(unique)]
|
||||
#![cfg_attr(test, feature(test, alloc, rustc_private))]
|
||||
|
|
|
|||
|
|
@ -160,7 +160,7 @@ use core::default::Default;
|
|||
use core::fmt;
|
||||
use core::hash::{Hasher, Hash};
|
||||
use core::marker;
|
||||
use core::mem::{min_align_of, size_of, forget};
|
||||
use core::mem::{self, min_align_of, size_of, forget};
|
||||
use core::nonzero::NonZero;
|
||||
use core::ops::{Deref, Drop};
|
||||
use core::option::Option;
|
||||
|
|
@ -407,7 +407,7 @@ impl<T> Drop for Rc<T> {
|
|||
fn drop(&mut self) {
|
||||
unsafe {
|
||||
let ptr = *self._ptr;
|
||||
if !ptr.is_null() {
|
||||
if !ptr.is_null() && ptr as usize != mem::POST_DROP_USIZE {
|
||||
self.dec_strong();
|
||||
if self.strong() == 0 {
|
||||
ptr::read(&**self); // destroy the contained object
|
||||
|
|
@ -431,7 +431,8 @@ impl<T> Clone for Rc<T> {
|
|||
|
||||
/// Makes a clone of the `Rc<T>`.
|
||||
///
|
||||
/// This increases the strong reference count.
|
||||
/// When you clone an `Rc<T>`, it will create another pointer to the data and
|
||||
/// increase the strong reference counter.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
|
|
@ -718,7 +719,7 @@ impl<T> Drop for Weak<T> {
|
|||
fn drop(&mut self) {
|
||||
unsafe {
|
||||
let ptr = *self._ptr;
|
||||
if !ptr.is_null() {
|
||||
if !ptr.is_null() && ptr as usize != mem::POST_DROP_USIZE {
|
||||
self.dec_weak();
|
||||
// the weak count starts at 1, and will only go to zero if all
|
||||
// the strong pointers have disappeared.
|
||||
|
|
|
|||
|
|
@ -24,7 +24,7 @@ use core::default::Default;
|
|||
use core::fmt::Debug;
|
||||
use core::hash::{Hash, Hasher};
|
||||
use core::iter::{Map, FromIterator, IntoIterator};
|
||||
use core::ops::{Index};
|
||||
use core::ops::Index;
|
||||
use core::{iter, fmt, mem, usize};
|
||||
use Bound::{self, Included, Excluded, Unbounded};
|
||||
|
||||
|
|
@ -904,14 +904,7 @@ impl<K: Ord, V: Ord> Ord for BTreeMap<K, V> {
|
|||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
impl<K: Debug, V: Debug> Debug for BTreeMap<K, V> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
try!(write!(f, "{{"));
|
||||
|
||||
for (i, (k, v)) in self.iter().enumerate() {
|
||||
if i != 0 { try!(write!(f, ", ")); }
|
||||
try!(write!(f, "{:?}: {:?}", *k, *v));
|
||||
}
|
||||
|
||||
write!(f, "}}")
|
||||
self.iter().fold(f.debug_map(), |b, (k, v)| b.entry(k, v)).finish()
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -280,9 +280,11 @@ impl<T> Drop for RawItems<T> {
|
|||
#[unsafe_destructor]
|
||||
impl<K, V> Drop for Node<K, V> {
|
||||
fn drop(&mut self) {
|
||||
if self.keys.is_null() {
|
||||
if self.keys.is_null() ||
|
||||
(unsafe { self.keys.get() as *const K as usize == mem::POST_DROP_USIZE })
|
||||
{
|
||||
// Since we have #[unsafe_no_drop_flag], we have to watch
|
||||
// out for a null value being stored in self.keys. (Using
|
||||
// out for the sentinel value being stored in self.keys. (Using
|
||||
// null is technically a violation of the `Unique`
|
||||
// requirements, though.)
|
||||
return;
|
||||
|
|
|
|||
|
|
@ -628,14 +628,7 @@ impl<'a, 'b, T: Ord + Clone> BitOr<&'b BTreeSet<T>> for &'a BTreeSet<T> {
|
|||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
impl<T: Debug> Debug for BTreeSet<T> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
try!(write!(f, "{{"));
|
||||
|
||||
for (i, x) in self.iter().enumerate() {
|
||||
if i != 0 { try!(write!(f, ", ")); }
|
||||
try!(write!(f, "{:?}", *x));
|
||||
}
|
||||
|
||||
write!(f, "}}")
|
||||
self.iter().fold(f.debug_set(), |b, e| b.entry(e)).finish()
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -25,7 +25,6 @@
|
|||
#![doc(test(no_crate_inject))]
|
||||
|
||||
#![allow(trivial_casts)]
|
||||
#![allow(trivial_numeric_casts)]
|
||||
#![feature(alloc)]
|
||||
#![feature(box_syntax)]
|
||||
#![feature(box_patterns)]
|
||||
|
|
@ -36,10 +35,12 @@
|
|||
#![feature(unicode)]
|
||||
#![feature(unsafe_destructor)]
|
||||
#![feature(unique)]
|
||||
#![feature(unsafe_no_drop_flag)]
|
||||
#![feature(unsafe_no_drop_flag, filling_drop)]
|
||||
#![feature(step_by)]
|
||||
#![feature(str_char)]
|
||||
#![feature(convert)]
|
||||
#![feature(slice_patterns)]
|
||||
#![feature(debug_builders)]
|
||||
#![cfg_attr(test, feature(rand, rustc_private, test, hash, collections))]
|
||||
#![cfg_attr(test, allow(deprecated))] // rand
|
||||
|
||||
|
|
|
|||
|
|
@ -927,14 +927,7 @@ impl<A: Clone> Clone for LinkedList<A> {
|
|||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
impl<A: fmt::Debug> fmt::Debug for LinkedList<A> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
try!(write!(f, "["));
|
||||
|
||||
for (i, e) in self.iter().enumerate() {
|
||||
if i != 0 { try!(write!(f, ", ")); }
|
||||
try!(write!(f, "{:?}", *e));
|
||||
}
|
||||
|
||||
write!(f, "]")
|
||||
self.iter().fold(f.debug_list(), |b, e| b.entry(e)).finish()
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -951,7 +944,7 @@ impl<A: Hash> Hash for LinkedList<A> {
|
|||
#[cfg(test)]
|
||||
mod test {
|
||||
use std::clone::Clone;
|
||||
use std::iter::{Iterator, IteratorExt};
|
||||
use std::iter::Iterator;
|
||||
use std::option::Option::{Some, None, self};
|
||||
use std::rand;
|
||||
use std::thread;
|
||||
|
|
|
|||
|
|
@ -50,8 +50,8 @@
|
|||
//!
|
||||
//! ## Iteration
|
||||
//!
|
||||
//! The slices implement `IntoIterator`. The iterators of yield references
|
||||
//! to the slice elements.
|
||||
//! The slices implement `IntoIterator`. The iterator yields references to the
|
||||
//! slice elements.
|
||||
//!
|
||||
//! ```
|
||||
//! let numbers = &[0, 1, 2];
|
||||
|
|
@ -76,7 +76,6 @@
|
|||
//! iterators.
|
||||
//! * Further methods that return iterators are `.split()`, `.splitn()`,
|
||||
//! `.chunks()`, `.windows()` and more.
|
||||
|
||||
#![doc(primitive = "slice")]
|
||||
#![stable(feature = "rust1", since = "1.0.0")]
|
||||
|
||||
|
|
@ -85,7 +84,7 @@ use core::convert::AsRef;
|
|||
use core::clone::Clone;
|
||||
use core::cmp::Ordering::{self, Greater, Less};
|
||||
use core::cmp::{self, Ord, PartialEq};
|
||||
use core::iter::{Iterator, IteratorExt};
|
||||
use core::iter::Iterator;
|
||||
use core::iter::MultiplicativeIterator;
|
||||
use core::marker::Sized;
|
||||
use core::mem::size_of;
|
||||
|
|
@ -131,7 +130,7 @@ mod hack {
|
|||
use alloc::boxed::Box;
|
||||
use core::clone::Clone;
|
||||
#[cfg(test)]
|
||||
use core::iter::{Iterator, IteratorExt};
|
||||
use core::iter::Iterator;
|
||||
use core::mem;
|
||||
#[cfg(test)]
|
||||
use core::option::Option::{Some, None};
|
||||
|
|
@ -611,9 +610,11 @@ impl<T> [T] {
|
|||
core_slice::SliceExt::get_mut(self, index)
|
||||
}
|
||||
|
||||
/// Work with `self` as a mut slice.
|
||||
/// Primarily intended for getting a &mut [T] from a [T; N].
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
/// Deprecated: use `&mut s[..]` instead.
|
||||
#[unstable(feature = "collections",
|
||||
reason = "will be replaced by slice syntax")]
|
||||
#[deprecated(since = "1.0.0", reason = "use &mut s[..] instead")]
|
||||
#[allow(deprecated)]
|
||||
pub fn as_mut_slice(&mut self) -> &mut [T] {
|
||||
core_slice::SliceExt::as_mut_slice(self)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -58,7 +58,7 @@ use self::DecompositionType::*;
|
|||
|
||||
use core::clone::Clone;
|
||||
use core::iter::AdditiveIterator;
|
||||
use core::iter::{Iterator, IteratorExt, Extend};
|
||||
use core::iter::{Iterator, Extend};
|
||||
use core::option::Option::{self, Some, None};
|
||||
use core::result::Result;
|
||||
use core::str as core_str;
|
||||
|
|
|
|||
|
|
@ -52,7 +52,7 @@ use core::prelude::*;
|
|||
use alloc::boxed::Box;
|
||||
use alloc::heap::{EMPTY, allocate, reallocate, deallocate};
|
||||
use core::cmp::max;
|
||||
use core::cmp::{Ordering};
|
||||
use core::cmp::Ordering;
|
||||
use core::default::Default;
|
||||
use core::fmt;
|
||||
use core::hash::{self, Hash};
|
||||
|
|
@ -423,24 +423,13 @@ impl<T> Vec<T> {
|
|||
}
|
||||
}
|
||||
|
||||
/// Returns a mutable slice of the elements of `self`.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// fn foo(slice: &mut [i32]) {}
|
||||
///
|
||||
/// let mut vec = vec![1, 2];
|
||||
/// foo(vec.as_mut_slice());
|
||||
/// ```
|
||||
/// Deprecated: use `&mut s[..]` instead.
|
||||
#[inline]
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
#[unstable(feature = "collections",
|
||||
reason = "will be replaced by slice syntax")]
|
||||
#[deprecated(since = "1.0.0", reason = "use &mut s[..] instead")]
|
||||
pub fn as_mut_slice(&mut self) -> &mut [T] {
|
||||
unsafe {
|
||||
let ptr = *self.ptr;
|
||||
assume(!ptr.is_null());
|
||||
slice::from_raw_parts_mut(ptr, self.len)
|
||||
}
|
||||
&mut self[..]
|
||||
}
|
||||
|
||||
/// Creates a consuming iterator, that is, one that moves each value out of
|
||||
|
|
@ -1426,7 +1415,7 @@ impl<T> ops::IndexMut<ops::RangeFull> for Vec<T> {
|
|||
|
||||
#[inline]
|
||||
fn index_mut(&mut self, _index: ops::RangeFull) -> &mut [T] {
|
||||
self.as_mut_slice()
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1445,7 +1434,13 @@ impl<T> ops::Deref for Vec<T> {
|
|||
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
impl<T> ops::DerefMut for Vec<T> {
|
||||
fn deref_mut(&mut self) -> &mut [T] { self.as_mut_slice() }
|
||||
fn deref_mut(&mut self) -> &mut [T] {
|
||||
unsafe {
|
||||
let ptr = *self.ptr;
|
||||
assume(!ptr.is_null());
|
||||
slice::from_raw_parts_mut(ptr, self.len)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
|
|
@ -1582,21 +1577,13 @@ impl<T: Ord> Ord for Vec<T> {
|
|||
}
|
||||
}
|
||||
|
||||
#[unstable(feature = "collections",
|
||||
reason = "will be replaced by slice syntax")]
|
||||
#[deprecated(since = "1.0.0", reason = "use &mut s[..] instead")]
|
||||
#[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];
|
||||
/// foo(vec.as_slice());
|
||||
/// ```
|
||||
/// Deprecated: use `&mut s[..]` instead.
|
||||
#[inline]
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
fn as_slice(&self) -> &[T] {
|
||||
self
|
||||
}
|
||||
|
|
@ -1620,7 +1607,7 @@ impl<T> Drop for Vec<T> {
|
|||
fn drop(&mut self) {
|
||||
// This is (and should always remain) a no-op if the fields are
|
||||
// zeroed (when moving out, because of #[unsafe_no_drop_flag]).
|
||||
if self.cap != 0 {
|
||||
if self.cap != 0 && self.cap != mem::POST_DROP_USIZE {
|
||||
unsafe {
|
||||
for x in &*self {
|
||||
ptr::read(x);
|
||||
|
|
@ -1903,7 +1890,7 @@ impl<'a, T> ExactSizeIterator for Drain<'a, T> {}
|
|||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
impl<'a, T> Drop for Drain<'a, T> {
|
||||
fn drop(&mut self) {
|
||||
// self.ptr == self.end == null if drop has already been called,
|
||||
// self.ptr == self.end == mem::POST_DROP_USIZE if drop has already been called,
|
||||
// so we can use #[unsafe_no_drop_flag].
|
||||
|
||||
// destroy the remaining elements
|
||||
|
|
|
|||
|
|
@ -1785,7 +1785,7 @@ impl<T: fmt::Debug> fmt::Debug for VecDeque<T> {
|
|||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use core::iter::{IteratorExt, self};
|
||||
use core::iter::{Iterator, self};
|
||||
use core::option::Option::Some;
|
||||
|
||||
use test;
|
||||
|
|
|
|||
|
|
@ -66,7 +66,7 @@ macro_rules! map_find_rand_bench {
|
|||
($name: ident, $n: expr, $map: ident) => (
|
||||
#[bench]
|
||||
pub fn $name(b: &mut ::test::Bencher) {
|
||||
use std::iter::IteratorExt;
|
||||
use std::iter::Iterator;
|
||||
use std::rand::Rng;
|
||||
use std::rand;
|
||||
use std::vec::Vec;
|
||||
|
|
|
|||
|
|
@ -18,6 +18,7 @@
|
|||
|
||||
use clone::Clone;
|
||||
use cmp::{PartialEq, Eq, PartialOrd, Ord, Ordering};
|
||||
use convert::{AsRef, AsMut};
|
||||
use fmt;
|
||||
use hash::{Hash, self};
|
||||
use iter::IntoIterator;
|
||||
|
|
@ -53,6 +54,24 @@ macro_rules! array_impls {
|
|||
}
|
||||
}
|
||||
|
||||
#[unstable(feature = "array_as_ref",
|
||||
reason = "should ideally be implemented for all fixed-sized arrays")]
|
||||
impl<T> AsRef<[T]> for [T; $N] {
|
||||
#[inline]
|
||||
fn as_ref(&self) -> &[T] {
|
||||
&self[..]
|
||||
}
|
||||
}
|
||||
|
||||
#[unstable(feature = "array_as_ref",
|
||||
reason = "should ideally be implemented for all fixed-sized arrays")]
|
||||
impl<T> AsMut<[T]> for [T; $N] {
|
||||
#[inline]
|
||||
fn as_mut(&mut self) -> &mut [T] {
|
||||
&mut self[..]
|
||||
}
|
||||
}
|
||||
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
impl<T:Copy> Clone for [T; $N] {
|
||||
fn clone(&self) -> [T; $N] {
|
||||
|
|
|
|||
|
|
@ -252,7 +252,8 @@ impl AtomicBool {
|
|||
|
||||
/// Stores a value into the bool if the current value is the same as the expected value.
|
||||
///
|
||||
/// If the return value is equal to `old` then the value was updated.
|
||||
/// The return value is always the previous value. If it is equal to `old`, then the value was
|
||||
/// updated.
|
||||
///
|
||||
/// `swap` also takes an `Ordering` argument which describes the memory ordering of this
|
||||
/// operation.
|
||||
|
|
@ -489,7 +490,8 @@ impl AtomicIsize {
|
|||
|
||||
/// Stores a value into the isize if the current value is the same as the expected value.
|
||||
///
|
||||
/// If the return value is equal to `old` then the value was updated.
|
||||
/// The return value is always the previous value. If it is equal to `old`, then the value was
|
||||
/// updated.
|
||||
///
|
||||
/// `compare_and_swap` also takes an `Ordering` argument which describes the memory ordering of
|
||||
/// this operation.
|
||||
|
|
@ -676,7 +678,8 @@ impl AtomicUsize {
|
|||
|
||||
/// Stores a value into the usize if the current value is the same as the expected value.
|
||||
///
|
||||
/// If the return value is equal to `old` then the value was updated.
|
||||
/// The return value is always the previous value. If it is equal to `old`, then the value was
|
||||
/// updated.
|
||||
///
|
||||
/// `compare_and_swap` also takes an `Ordering` argument which describes the memory ordering of
|
||||
/// this operation.
|
||||
|
|
@ -873,7 +876,8 @@ impl<T> AtomicPtr<T> {
|
|||
|
||||
/// Stores a value into the pointer if the current value is the same as the expected value.
|
||||
///
|
||||
/// If the return value is equal to `old` then the value was updated.
|
||||
/// The return value is always the previous value. If it is equal to `old`, then the value was
|
||||
/// updated.
|
||||
///
|
||||
/// `compare_and_swap` also takes an `Ordering` argument which describes the memory ordering of
|
||||
/// this operation.
|
||||
|
|
@ -1064,7 +1068,7 @@ pub fn fence(order: Ordering) {
|
|||
reason = "renamed to AtomicIsize")]
|
||||
#[allow(missing_docs)]
|
||||
pub struct AtomicInt {
|
||||
v: UnsafeCell<int>,
|
||||
v: UnsafeCell<isize>,
|
||||
}
|
||||
|
||||
#[allow(deprecated)]
|
||||
|
|
@ -1075,7 +1079,7 @@ unsafe impl Sync for AtomicInt {}
|
|||
reason = "renamed to AtomicUsize")]
|
||||
#[allow(missing_docs)]
|
||||
pub struct AtomicUint {
|
||||
v: UnsafeCell<uint>,
|
||||
v: UnsafeCell<usize>,
|
||||
}
|
||||
|
||||
#[allow(deprecated)]
|
||||
|
|
@ -1097,52 +1101,52 @@ pub const ATOMIC_UINT_INIT: AtomicUint =
|
|||
#[allow(missing_docs, deprecated)]
|
||||
impl AtomicInt {
|
||||
#[inline]
|
||||
pub fn new(v: int) -> AtomicInt {
|
||||
pub fn new(v: isize) -> AtomicInt {
|
||||
AtomicInt {v: UnsafeCell::new(v)}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn load(&self, order: Ordering) -> int {
|
||||
pub fn load(&self, order: Ordering) -> isize {
|
||||
unsafe { atomic_load(self.v.get(), order) }
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn store(&self, val: int, order: Ordering) {
|
||||
pub fn store(&self, val: isize, order: Ordering) {
|
||||
unsafe { atomic_store(self.v.get(), val, order); }
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn swap(&self, val: int, order: Ordering) -> int {
|
||||
pub fn swap(&self, val: isize, order: Ordering) -> isize {
|
||||
unsafe { atomic_swap(self.v.get(), val, order) }
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn compare_and_swap(&self, old: int, new: int, order: Ordering) -> int {
|
||||
pub fn compare_and_swap(&self, old: isize, new: isize, order: Ordering) -> isize {
|
||||
unsafe { atomic_compare_and_swap(self.v.get(), old, new, order) }
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn fetch_add(&self, val: int, order: Ordering) -> int {
|
||||
pub fn fetch_add(&self, val: isize, order: Ordering) -> isize {
|
||||
unsafe { atomic_add(self.v.get(), val, order) }
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn fetch_sub(&self, val: int, order: Ordering) -> int {
|
||||
pub fn fetch_sub(&self, val: isize, order: Ordering) -> isize {
|
||||
unsafe { atomic_sub(self.v.get(), val, order) }
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn fetch_and(&self, val: int, order: Ordering) -> int {
|
||||
pub fn fetch_and(&self, val: isize, order: Ordering) -> isize {
|
||||
unsafe { atomic_and(self.v.get(), val, order) }
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn fetch_or(&self, val: int, order: Ordering) -> int {
|
||||
pub fn fetch_or(&self, val: isize, order: Ordering) -> isize {
|
||||
unsafe { atomic_or(self.v.get(), val, order) }
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn fetch_xor(&self, val: int, order: Ordering) -> int {
|
||||
pub fn fetch_xor(&self, val: isize, order: Ordering) -> isize {
|
||||
unsafe { atomic_xor(self.v.get(), val, order) }
|
||||
}
|
||||
}
|
||||
|
|
@ -1150,52 +1154,52 @@ impl AtomicInt {
|
|||
#[allow(missing_docs, deprecated)]
|
||||
impl AtomicUint {
|
||||
#[inline]
|
||||
pub fn new(v: uint) -> AtomicUint {
|
||||
pub fn new(v: usize) -> AtomicUint {
|
||||
AtomicUint { v: UnsafeCell::new(v) }
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn load(&self, order: Ordering) -> uint {
|
||||
pub fn load(&self, order: Ordering) -> usize {
|
||||
unsafe { atomic_load(self.v.get(), order) }
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn store(&self, val: uint, order: Ordering) {
|
||||
pub fn store(&self, val: usize, order: Ordering) {
|
||||
unsafe { atomic_store(self.v.get(), val, order); }
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn swap(&self, val: uint, order: Ordering) -> uint {
|
||||
pub fn swap(&self, val: usize, order: Ordering) -> usize {
|
||||
unsafe { atomic_swap(self.v.get(), val, order) }
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn compare_and_swap(&self, old: uint, new: uint, order: Ordering) -> uint {
|
||||
pub fn compare_and_swap(&self, old: usize, new: usize, order: Ordering) -> usize {
|
||||
unsafe { atomic_compare_and_swap(self.v.get(), old, new, order) }
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn fetch_add(&self, val: uint, order: Ordering) -> uint {
|
||||
pub fn fetch_add(&self, val: usize, order: Ordering) -> usize {
|
||||
unsafe { atomic_add(self.v.get(), val, order) }
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn fetch_sub(&self, val: uint, order: Ordering) -> uint {
|
||||
pub fn fetch_sub(&self, val: usize, order: Ordering) -> usize {
|
||||
unsafe { atomic_sub(self.v.get(), val, order) }
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn fetch_and(&self, val: uint, order: Ordering) -> uint {
|
||||
pub fn fetch_and(&self, val: usize, order: Ordering) -> usize {
|
||||
unsafe { atomic_and(self.v.get(), val, order) }
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn fetch_or(&self, val: uint, order: Ordering) -> uint {
|
||||
pub fn fetch_or(&self, val: usize, order: Ordering) -> usize {
|
||||
unsafe { atomic_or(self.v.get(), val, order) }
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn fetch_xor(&self, val: uint, order: Ordering) -> uint {
|
||||
pub fn fetch_xor(&self, val: usize, order: Ordering) -> usize {
|
||||
unsafe { atomic_xor(self.v.get(), val, order) }
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -69,6 +69,14 @@ impl<'a, T: ?Sized, U: ?Sized> AsRef<U> for &'a mut T where T: AsRef<U> {
|
|||
}
|
||||
}
|
||||
|
||||
// FIXME (#23442): replace the above impls for &/&mut with the following more general one:
|
||||
// // As lifts over Deref
|
||||
// impl<D: ?Sized + Deref, U: ?Sized> AsRef<U> for D where D::Target: AsRef<U> {
|
||||
// fn as_ref(&self) -> &U {
|
||||
// self.deref().as_ref()
|
||||
// }
|
||||
// }
|
||||
|
||||
// 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 {
|
||||
|
|
@ -83,6 +91,14 @@ impl<'a, T: ?Sized, U: ?Sized> AsMut<U> for &'a mut T where T: AsMut<U> {
|
|||
}
|
||||
}
|
||||
|
||||
// FIXME (#23442): replace the above impl for &mut with the following more general one:
|
||||
// // AsMut lifts over DerefMut
|
||||
// impl<D: ?Sized + Deref, U: ?Sized> AsMut<U> for D where D::Target: AsMut<U> {
|
||||
// fn as_mut(&mut self) -> &mut U {
|
||||
// self.deref_mut().as_mut()
|
||||
// }
|
||||
// }
|
||||
|
||||
// From implies Into
|
||||
impl<T, U> Into<U> for T where U: From<T> {
|
||||
fn into(self) -> U {
|
||||
|
|
|
|||
|
|
@ -87,7 +87,7 @@ use fmt::{Debug, Display};
|
|||
|
||||
/// Base functionality for all errors in Rust.
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
pub trait Error: Debug + Display + Send {
|
||||
pub trait Error: Debug + Display {
|
||||
/// A short description of the error.
|
||||
///
|
||||
/// The description should not contain newlines or sentence-ending
|
||||
|
|
|
|||
|
|
@ -177,22 +177,54 @@ impl<'a, 'b: 'a> DebugTuple<'a, 'b> {
|
|||
}
|
||||
}
|
||||
|
||||
/// A struct to help with `fmt::Debug` implementations.
|
||||
///
|
||||
/// Constructed by the `Formatter::debug_set` method.
|
||||
#[must_use]
|
||||
pub struct DebugSet<'a, 'b: 'a> {
|
||||
struct DebugInner<'a, 'b: 'a> {
|
||||
fmt: &'a mut fmt::Formatter<'b>,
|
||||
result: fmt::Result,
|
||||
has_fields: bool,
|
||||
}
|
||||
|
||||
pub fn debug_set_new<'a, 'b>(fmt: &'a mut fmt::Formatter<'b>, name: &str) -> DebugSet<'a, 'b> {
|
||||
let result = write!(fmt, "{} {{", name);
|
||||
impl<'a, 'b: 'a> DebugInner<'a, 'b> {
|
||||
fn entry(&mut self, entry: &fmt::Debug) {
|
||||
self.result = self.result.and_then(|_| {
|
||||
if self.is_pretty() {
|
||||
let mut writer = PadAdapter::new(self.fmt);
|
||||
let prefix = if self.has_fields { "," } else { "" };
|
||||
fmt::write(&mut writer, format_args!("{}\n{:#?}", prefix, entry))
|
||||
} else {
|
||||
let prefix = if self.has_fields { ", " } else { "" };
|
||||
write!(self.fmt, "{}{:?}", prefix, entry)
|
||||
}
|
||||
});
|
||||
|
||||
self.has_fields = true;
|
||||
}
|
||||
|
||||
pub fn finish(&mut self) {
|
||||
let prefix = if self.is_pretty() && self.has_fields { "\n" } else { "" };
|
||||
self.result = self.result.and_then(|_| self.fmt.write_str(prefix));
|
||||
}
|
||||
|
||||
fn is_pretty(&self) -> bool {
|
||||
self.fmt.flags() & (1 << (FlagV1::Alternate as usize)) != 0
|
||||
}
|
||||
}
|
||||
|
||||
/// A struct to help with `fmt::Debug` implementations.
|
||||
///
|
||||
/// Constructed by the `Formatter::debug_set` method.
|
||||
#[must_use]
|
||||
pub struct DebugSet<'a, 'b: 'a> {
|
||||
inner: DebugInner<'a, 'b>,
|
||||
}
|
||||
|
||||
pub fn debug_set_new<'a, 'b>(fmt: &'a mut fmt::Formatter<'b>) -> DebugSet<'a, 'b> {
|
||||
let result = write!(fmt, "{{");
|
||||
DebugSet {
|
||||
fmt: fmt,
|
||||
result: result,
|
||||
has_fields: false,
|
||||
inner: DebugInner {
|
||||
fmt: fmt,
|
||||
result: result,
|
||||
has_fields: false,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -200,41 +232,52 @@ impl<'a, 'b: 'a> DebugSet<'a, 'b> {
|
|||
/// Adds a new entry to the set output.
|
||||
#[unstable(feature = "debug_builders", reason = "method was just created")]
|
||||
pub fn entry(mut self, entry: &fmt::Debug) -> DebugSet<'a, 'b> {
|
||||
self.result = self.result.and_then(|_| {
|
||||
let prefix = if self.has_fields {
|
||||
","
|
||||
} else {
|
||||
""
|
||||
};
|
||||
|
||||
if self.is_pretty() {
|
||||
let mut writer = PadAdapter::new(self.fmt);
|
||||
fmt::write(&mut writer, format_args!("{}\n{:#?}", prefix, entry))
|
||||
} else {
|
||||
write!(self.fmt, "{} {:?}", prefix, entry)
|
||||
}
|
||||
});
|
||||
|
||||
self.has_fields = true;
|
||||
self.inner.entry(entry);
|
||||
self
|
||||
}
|
||||
|
||||
/// Consumes the `DebugSet`, finishing output and returning any error
|
||||
/// encountered.
|
||||
#[unstable(feature = "debug_builders", reason = "method was just created")]
|
||||
pub fn finish(self) -> fmt::Result {
|
||||
self.result.and_then(|_| {
|
||||
let end = match (self.has_fields, self.is_pretty()) {
|
||||
(false, _) => "}",
|
||||
(true, false) => " }",
|
||||
(true, true) => "\n}",
|
||||
};
|
||||
self.fmt.write_str(end)
|
||||
})
|
||||
pub fn finish(mut self) -> fmt::Result {
|
||||
self.inner.finish();
|
||||
self.inner.result.and_then(|_| self.inner.fmt.write_str("}"))
|
||||
}
|
||||
}
|
||||
|
||||
/// A struct to help with `fmt::Debug` implementations.
|
||||
///
|
||||
/// Constructed by the `Formatter::debug_list` method.
|
||||
#[must_use]
|
||||
pub struct DebugList<'a, 'b: 'a> {
|
||||
inner: DebugInner<'a, 'b>,
|
||||
}
|
||||
|
||||
pub fn debug_list_new<'a, 'b>(fmt: &'a mut fmt::Formatter<'b>) -> DebugList<'a, 'b> {
|
||||
let result = write!(fmt, "[");
|
||||
DebugList {
|
||||
inner: DebugInner {
|
||||
fmt: fmt,
|
||||
result: result,
|
||||
has_fields: false,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, 'b: 'a> DebugList<'a, 'b> {
|
||||
/// Adds a new entry to the set output.
|
||||
#[unstable(feature = "debug_builders", reason = "method was just created")]
|
||||
pub fn entry(mut self, entry: &fmt::Debug) -> DebugList<'a, 'b> {
|
||||
self.inner.entry(entry);
|
||||
self
|
||||
}
|
||||
|
||||
fn is_pretty(&self) -> bool {
|
||||
self.fmt.flags() & (1 << (FlagV1::Alternate as usize)) != 0
|
||||
/// Consumes the `DebugSet`, finishing output and returning any error
|
||||
/// encountered.
|
||||
#[unstable(feature = "debug_builders", reason = "method was just created")]
|
||||
pub fn finish(mut self) -> fmt::Result {
|
||||
self.inner.finish();
|
||||
self.inner.result.and_then(|_| self.inner.fmt.write_str("]"))
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -248,8 +291,8 @@ pub struct DebugMap<'a, 'b: 'a> {
|
|||
has_fields: bool,
|
||||
}
|
||||
|
||||
pub fn debug_map_new<'a, 'b>(fmt: &'a mut fmt::Formatter<'b>, name: &str) -> DebugMap<'a, 'b> {
|
||||
let result = write!(fmt, "{} {{", name);
|
||||
pub fn debug_map_new<'a, 'b>(fmt: &'a mut fmt::Formatter<'b>) -> DebugMap<'a, 'b> {
|
||||
let result = write!(fmt, "{{");
|
||||
DebugMap {
|
||||
fmt: fmt,
|
||||
result: result,
|
||||
|
|
@ -262,22 +305,17 @@ impl<'a, 'b: 'a> DebugMap<'a, 'b> {
|
|||
#[unstable(feature = "debug_builders", reason = "method was just created")]
|
||||
pub fn entry(mut self, key: &fmt::Debug, value: &fmt::Debug) -> DebugMap<'a, 'b> {
|
||||
self.result = self.result.and_then(|_| {
|
||||
let prefix = if self.has_fields {
|
||||
","
|
||||
} else {
|
||||
""
|
||||
};
|
||||
|
||||
if self.is_pretty() {
|
||||
let mut writer = PadAdapter::new(self.fmt);
|
||||
let prefix = if self.has_fields { "," } else { "" };
|
||||
fmt::write(&mut writer, format_args!("{}\n{:#?}: {:#?}", prefix, key, value))
|
||||
} else {
|
||||
write!(self.fmt, "{} {:?}: {:?}", prefix, key, value)
|
||||
let prefix = if self.has_fields { ", " } else { "" };
|
||||
write!(self.fmt, "{}{:?}: {:?}", prefix, key, value)
|
||||
}
|
||||
});
|
||||
|
||||
self.has_fields = true;
|
||||
|
||||
self
|
||||
}
|
||||
|
||||
|
|
@ -285,14 +323,8 @@ impl<'a, 'b: 'a> DebugMap<'a, 'b> {
|
|||
/// encountered.
|
||||
#[unstable(feature = "debug_builders", reason = "method was just created")]
|
||||
pub fn finish(self) -> fmt::Result {
|
||||
self.result.and_then(|_| {
|
||||
let end = match (self.has_fields, self.is_pretty()) {
|
||||
(false, _) => "}",
|
||||
(true, false) => " }",
|
||||
(true, true) => "\n}",
|
||||
};
|
||||
self.fmt.write_str(end)
|
||||
})
|
||||
let prefix = if self.is_pretty() && self.has_fields { "\n" } else { "" };
|
||||
self.result.and_then(|_| write!(self.fmt, "{}}}", prefix))
|
||||
}
|
||||
|
||||
fn is_pretty(&self) -> bool {
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@ pub use self::SignFormat::*;
|
|||
use char;
|
||||
use char::CharExt;
|
||||
use fmt;
|
||||
use iter::IteratorExt;
|
||||
use iter::Iterator;
|
||||
use num::{cast, Float, ToPrimitive};
|
||||
use num::FpCategory as Fp;
|
||||
use ops::FnOnce;
|
||||
|
|
@ -125,7 +125,7 @@ pub fn float_to_str_bytes_common<T: Float, U, F>(
|
|||
// otherwise as well.
|
||||
let mut buf = [0; 1536];
|
||||
let mut end = 0;
|
||||
let radix_gen: T = cast(radix as int).unwrap();
|
||||
let radix_gen: T = cast(radix as isize).unwrap();
|
||||
|
||||
let (num, exp) = match exp_format {
|
||||
ExpNone => (num, 0),
|
||||
|
|
@ -235,7 +235,7 @@ pub fn float_to_str_bytes_common<T: Float, U, F>(
|
|||
let extra_digit = ascii2value(buf[end - 1]);
|
||||
end -= 1;
|
||||
if extra_digit >= radix / 2 { // -> need to round
|
||||
let mut i: int = end as int - 1;
|
||||
let mut i: isize = end as isize - 1;
|
||||
loop {
|
||||
// If reached left end of number, have to
|
||||
// insert additional digit:
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@
|
|||
use any;
|
||||
use cell::{Cell, RefCell, Ref, RefMut, BorrowState};
|
||||
use char::CharExt;
|
||||
use iter::{Iterator, IteratorExt};
|
||||
use iter::Iterator;
|
||||
use marker::{Copy, PhantomData, Sized};
|
||||
use mem;
|
||||
use option::Option;
|
||||
|
|
@ -32,7 +32,7 @@ pub use self::num::radix;
|
|||
pub use self::num::Radix;
|
||||
pub use self::num::RadixFmt;
|
||||
|
||||
pub use self::builders::{DebugStruct, DebugTuple, DebugSet, DebugMap};
|
||||
pub use self::builders::{DebugStruct, DebugTuple, DebugSet, DebugList, DebugMap};
|
||||
|
||||
mod num;
|
||||
mod float;
|
||||
|
|
@ -644,7 +644,7 @@ impl<'a> Formatter<'a> {
|
|||
/// // prints "Foo { bar: 10, baz: "Hello World" }"
|
||||
/// println!("{:?}", Foo { bar: 10, baz: "Hello World".to_string() });
|
||||
/// ```
|
||||
#[unstable(feature = "core", reason = "method was just created")]
|
||||
#[unstable(feature = "debug_builders", reason = "method was just created")]
|
||||
#[inline]
|
||||
pub fn debug_struct<'b>(&'b mut self, name: &str) -> DebugStruct<'b, 'a> {
|
||||
builders::debug_struct_new(self, name)
|
||||
|
|
@ -673,12 +673,38 @@ impl<'a> Formatter<'a> {
|
|||
/// // prints "Foo(10, "Hello World")"
|
||||
/// println!("{:?}", Foo(10, "Hello World".to_string()));
|
||||
/// ```
|
||||
#[unstable(feature = "core", reason = "method was just created")]
|
||||
#[unstable(feature = "debug_builders", reason = "method was just created")]
|
||||
#[inline]
|
||||
pub fn debug_tuple<'b>(&'b mut self, name: &str) -> DebugTuple<'b, 'a> {
|
||||
builders::debug_tuple_new(self, name)
|
||||
}
|
||||
|
||||
/// Creates a `DebugList` builder designed to assist with creation of
|
||||
/// `fmt::Debug` implementations for list-like structures.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```rust
|
||||
/// # #![feature(debug_builders, core)]
|
||||
/// use std::fmt;
|
||||
///
|
||||
/// struct Foo(Vec<i32>);
|
||||
///
|
||||
/// impl fmt::Debug for Foo {
|
||||
/// fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
|
||||
/// self.0.iter().fold(fmt.debug_list(), |b, e| b.entry(e)).finish()
|
||||
/// }
|
||||
/// }
|
||||
///
|
||||
/// // prints "[10, 11]"
|
||||
/// println!("{:?}", Foo(vec![10, 11]));
|
||||
/// ```
|
||||
#[unstable(feature = "debug_builders", reason = "method was just created")]
|
||||
#[inline]
|
||||
pub fn debug_list<'b>(&'b mut self) -> DebugList<'b, 'a> {
|
||||
builders::debug_list_new(self)
|
||||
}
|
||||
|
||||
/// Creates a `DebugSet` builder designed to assist with creation of
|
||||
/// `fmt::Debug` implementations for set-like structures.
|
||||
///
|
||||
|
|
@ -692,21 +718,17 @@ impl<'a> Formatter<'a> {
|
|||
///
|
||||
/// impl fmt::Debug for Foo {
|
||||
/// fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
|
||||
/// let mut builder = fmt.debug_set("Foo");
|
||||
/// for i in &self.0 {
|
||||
/// builder = builder.entry(i);
|
||||
/// }
|
||||
/// builder.finish()
|
||||
/// self.0.iter().fold(fmt.debug_set(), |b, e| b.entry(e)).finish()
|
||||
/// }
|
||||
/// }
|
||||
///
|
||||
/// // prints "Foo { 10, 11 }"
|
||||
/// // prints "{10, 11}"
|
||||
/// println!("{:?}", Foo(vec![10, 11]));
|
||||
/// ```
|
||||
#[unstable(feature = "core", reason = "method was just created")]
|
||||
#[unstable(feature = "debug_builders", reason = "method was just created")]
|
||||
#[inline]
|
||||
pub fn debug_set<'b>(&'b mut self, name: &str) -> DebugSet<'b, 'a> {
|
||||
builders::debug_set_new(self, name)
|
||||
pub fn debug_set<'b>(&'b mut self) -> DebugSet<'b, 'a> {
|
||||
builders::debug_set_new(self)
|
||||
}
|
||||
|
||||
/// Creates a `DebugMap` builder designed to assist with creation of
|
||||
|
|
@ -722,21 +744,17 @@ impl<'a> Formatter<'a> {
|
|||
///
|
||||
/// impl fmt::Debug for Foo {
|
||||
/// fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
|
||||
/// let mut builder = fmt.debug_map("Foo");
|
||||
/// for &(ref key, ref value) in &self.0 {
|
||||
/// builder = builder.entry(key, value);
|
||||
/// }
|
||||
/// builder.finish()
|
||||
/// self.0.iter().fold(fmt.debug_map(), |b, &(ref k, ref v)| b.entry(k, v)).finish()
|
||||
/// }
|
||||
/// }
|
||||
///
|
||||
/// // prints "Foo { "A": 10, "B": 11 }"
|
||||
/// // prints "{"A": 10, "B": 11}"
|
||||
/// println!("{:?}", Foo(vec![("A".to_string(), 10), ("B".to_string(), 11)]));
|
||||
/// ```
|
||||
#[unstable(feature = "core", reason = "method was just created")]
|
||||
#[unstable(feature = "debug_builders", reason = "method was just created")]
|
||||
#[inline]
|
||||
pub fn debug_map<'b>(&'b mut self, name: &str) -> DebugMap<'b, 'a> {
|
||||
builders::debug_map_new(self, name)
|
||||
pub fn debug_map<'b>(&'b mut self) -> DebugMap<'b, 'a> {
|
||||
builders::debug_map_new(self)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -987,22 +1005,7 @@ impl<'a> Debug for &'a (any::Any+'a) {
|
|||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
impl<T: Debug> Debug for [T] {
|
||||
fn fmt(&self, f: &mut Formatter) -> Result {
|
||||
if f.flags & (1 << (FlagV1::Alternate as u32)) == 0 {
|
||||
try!(write!(f, "["));
|
||||
}
|
||||
let mut is_first = true;
|
||||
for x in self {
|
||||
if is_first {
|
||||
is_first = false;
|
||||
} else {
|
||||
try!(write!(f, ", "));
|
||||
}
|
||||
try!(write!(f, "{:?}", *x))
|
||||
}
|
||||
if f.flags & (1 << (FlagV1::Alternate as u32)) == 0 {
|
||||
try!(write!(f, "]"));
|
||||
}
|
||||
Ok(())
|
||||
self.iter().fold(f.debug_list(), |b, e| b.entry(e)).finish()
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -13,10 +13,9 @@
|
|||
// FIXME: #6220 Implement floating point formatting
|
||||
|
||||
#![allow(unsigned_negation)]
|
||||
#![allow(trivial_numeric_casts)]
|
||||
|
||||
use fmt;
|
||||
use iter::IteratorExt;
|
||||
use iter::Iterator;
|
||||
use num::{Int, cast};
|
||||
use slice::SliceExt;
|
||||
use str;
|
||||
|
|
|
|||
|
|
@ -73,6 +73,16 @@ mod sip;
|
|||
///
|
||||
/// The `H` type parameter is an abstract hash state that is used by the `Hash`
|
||||
/// to compute the hash.
|
||||
///
|
||||
/// If you are also implementing `Eq`, there is an additional property that
|
||||
/// is important:
|
||||
///
|
||||
/// ```text
|
||||
/// k1 == k2 -> hash(k1) == hash(k2)
|
||||
/// ```
|
||||
///
|
||||
/// In other words, if two keys are equal, their hashes should also be equal.
|
||||
/// `HashMap` and `HashSet` both rely on this behavior.
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
pub trait Hash {
|
||||
/// Feeds this value into the state given, updating the hasher as necessary.
|
||||
|
|
|
|||
|
|
@ -186,13 +186,35 @@ extern "rust-intrinsic" {
|
|||
/// crate it is invoked in.
|
||||
pub fn type_id<T: ?Sized + 'static>() -> u64;
|
||||
|
||||
/// Create a value initialized to so that its drop flag,
|
||||
/// if any, says that it has been dropped.
|
||||
///
|
||||
/// `init_dropped` is unsafe because it returns a datum with all
|
||||
/// of its bytes set to the drop flag, which generally does not
|
||||
/// correspond to a valid value.
|
||||
///
|
||||
/// This intrinsic is likely to be deprecated in the future when
|
||||
/// Rust moves to non-zeroing dynamic drop (and thus removes the
|
||||
/// embedded drop flags that are being established by this
|
||||
/// intrinsic).
|
||||
#[cfg(not(stage0))]
|
||||
pub fn init_dropped<T>() -> T;
|
||||
|
||||
/// Create a value initialized to zero.
|
||||
///
|
||||
/// `init` is unsafe because it returns a zeroed-out datum,
|
||||
/// which is unsafe unless T is Copy.
|
||||
/// which is unsafe unless T is `Copy`. Also, even if T is
|
||||
/// `Copy`, an all-zero value may not correspond to any legitimate
|
||||
/// state for the type in question.
|
||||
pub fn init<T>() -> T;
|
||||
|
||||
/// Create an uninitialized value.
|
||||
///
|
||||
/// `uninit` is unsafe because there is no guarantee of what its
|
||||
/// contents are. In particular its drop-flag may be set to any
|
||||
/// state, which means it may claim either dropped or
|
||||
/// undropped. In the general case one must use `ptr::write` to
|
||||
/// initialize memory previous set to the result of `uninit`.
|
||||
pub fn uninit<T>() -> T;
|
||||
|
||||
/// Move a value out of scope without running drop glue.
|
||||
|
|
@ -304,7 +326,7 @@ extern "rust-intrinsic" {
|
|||
/// # #![feature(core)]
|
||||
/// use std::ptr;
|
||||
///
|
||||
/// unsafe fn from_buf_raw<T>(ptr: *const T, elts: uint) -> Vec<T> {
|
||||
/// unsafe fn from_buf_raw<T>(ptr: *const T, elts: usize) -> Vec<T> {
|
||||
/// let mut dst = Vec::with_capacity(elts);
|
||||
/// dst.set_len(elts);
|
||||
/// ptr::copy(dst.as_mut_ptr(), ptr, elts);
|
||||
|
|
|
|||
|
|
@ -71,6 +71,8 @@ use option::Option::{Some, None};
|
|||
use marker::Sized;
|
||||
use usize;
|
||||
|
||||
fn _assert_is_object_safe(_: &Iterator) {}
|
||||
|
||||
/// An interface for dealing with "external iterators". These types of iterators
|
||||
/// can be resumed at any time as all state is stored internally as opposed to
|
||||
/// being located on the call stack.
|
||||
|
|
@ -101,62 +103,7 @@ pub trait Iterator {
|
|||
#[inline]
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
fn size_hint(&self) -> (usize, Option<usize>) { (0, None) }
|
||||
}
|
||||
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
impl<'a, I: Iterator + ?Sized> Iterator for &'a mut I {
|
||||
type Item = I::Item;
|
||||
fn next(&mut self) -> Option<I::Item> { (**self).next() }
|
||||
fn size_hint(&self) -> (usize, Option<usize>) { (**self).size_hint() }
|
||||
}
|
||||
|
||||
/// Conversion from an `Iterator`
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
#[rustc_on_unimplemented="a collection of type `{Self}` cannot be \
|
||||
built from an iterator over elements of type `{A}`"]
|
||||
pub trait FromIterator<A> {
|
||||
/// Build a container with elements from something iterable.
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
fn from_iter<T: IntoIterator<Item=A>>(iterator: T) -> Self;
|
||||
}
|
||||
|
||||
/// Conversion into an `Iterator`
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
pub trait IntoIterator {
|
||||
/// The type of the elements being iterated
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
type Item;
|
||||
|
||||
/// A container for iterating over elements of type Item
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
type IntoIter: Iterator<Item=Self::Item>;
|
||||
|
||||
/// Consumes `Self` and returns an iterator over it
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
fn into_iter(self) -> Self::IntoIter;
|
||||
}
|
||||
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
impl<I: Iterator> IntoIterator for I {
|
||||
type Item = I::Item;
|
||||
type IntoIter = I;
|
||||
|
||||
fn into_iter(self) -> I {
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
/// A type growable from an `Iterator` implementation
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
pub trait Extend<A> {
|
||||
/// Extend a container with the elements yielded by an arbitrary iterator
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
fn extend<T: IntoIterator<Item=A>>(&mut self, iterable: T);
|
||||
}
|
||||
|
||||
/// An extension trait providing numerous methods applicable to all iterators.
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
pub trait IteratorExt: Iterator + Sized {
|
||||
/// Counts the number of elements in this iterator.
|
||||
///
|
||||
/// # Examples
|
||||
|
|
@ -167,7 +114,7 @@ pub trait IteratorExt: Iterator + Sized {
|
|||
/// ```
|
||||
#[inline]
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
fn count(self) -> usize {
|
||||
fn count(self) -> usize where Self: Sized {
|
||||
self.fold(0, |cnt, _x| cnt + 1)
|
||||
}
|
||||
|
||||
|
|
@ -181,7 +128,7 @@ pub trait IteratorExt: Iterator + Sized {
|
|||
/// ```
|
||||
#[inline]
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
fn last(self) -> Option<Self::Item> {
|
||||
fn last(self) -> Option<Self::Item> where Self: Sized {
|
||||
let mut last = None;
|
||||
for x in self { last = Some(x); }
|
||||
last
|
||||
|
|
@ -200,7 +147,7 @@ pub trait IteratorExt: Iterator + Sized {
|
|||
/// ```
|
||||
#[inline]
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
fn nth(&mut self, mut n: usize) -> Option<Self::Item> {
|
||||
fn nth(&mut self, mut n: usize) -> Option<Self::Item> where Self: Sized {
|
||||
for x in self.by_ref() {
|
||||
if n == 0 { return Some(x) }
|
||||
n -= 1;
|
||||
|
|
@ -225,7 +172,7 @@ pub trait IteratorExt: Iterator + Sized {
|
|||
#[inline]
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
fn chain<U>(self, other: U) -> Chain<Self, U> where
|
||||
U: Iterator<Item=Self::Item>,
|
||||
Self: Sized, U: Iterator<Item=Self::Item>,
|
||||
{
|
||||
Chain{a: self, b: other, flag: false}
|
||||
}
|
||||
|
|
@ -244,9 +191,23 @@ pub trait IteratorExt: Iterator + Sized {
|
|||
/// assert_eq!(it.next().unwrap(), (&0, &1));
|
||||
/// assert!(it.next().is_none());
|
||||
/// ```
|
||||
///
|
||||
/// `zip` can provide similar functionality to `enumerate`:
|
||||
///
|
||||
/// ```
|
||||
/// for pair in "foo".chars().enumerate() {
|
||||
/// println!("{:?}", pair);
|
||||
/// }
|
||||
///
|
||||
/// for pair in (0..).zip("foo".chars()) {
|
||||
/// println!("{:?}", pair);
|
||||
/// }
|
||||
/// ```
|
||||
///
|
||||
/// both produce the same output.
|
||||
#[inline]
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
fn zip<U: Iterator>(self, other: U) -> Zip<Self, U> {
|
||||
fn zip<U: Iterator>(self, other: U) -> Zip<Self, U> where Self: Sized {
|
||||
Zip{a: self, b: other}
|
||||
}
|
||||
|
||||
|
|
@ -265,7 +226,7 @@ pub trait IteratorExt: Iterator + Sized {
|
|||
#[inline]
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
fn map<B, F>(self, f: F) -> Map<Self, F> where
|
||||
F: FnMut(Self::Item) -> B,
|
||||
Self: Sized, F: FnMut(Self::Item) -> B,
|
||||
{
|
||||
Map{iter: self, f: f}
|
||||
}
|
||||
|
|
@ -285,7 +246,7 @@ pub trait IteratorExt: Iterator + Sized {
|
|||
#[inline]
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
fn filter<P>(self, predicate: P) -> Filter<Self, P> where
|
||||
P: FnMut(&Self::Item) -> bool,
|
||||
Self: Sized, P: FnMut(&Self::Item) -> bool,
|
||||
{
|
||||
Filter{iter: self, predicate: predicate}
|
||||
}
|
||||
|
|
@ -305,7 +266,7 @@ pub trait IteratorExt: Iterator + Sized {
|
|||
#[inline]
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
fn filter_map<B, F>(self, f: F) -> FilterMap<Self, F> where
|
||||
F: FnMut(Self::Item) -> Option<B>,
|
||||
Self: Sized, F: FnMut(Self::Item) -> Option<B>,
|
||||
{
|
||||
FilterMap { iter: self, f: f }
|
||||
}
|
||||
|
|
@ -313,6 +274,9 @@ pub trait IteratorExt: Iterator + Sized {
|
|||
/// Creates an iterator that yields a pair of the value returned by this
|
||||
/// iterator plus the current index of iteration.
|
||||
///
|
||||
/// `enumerate` keeps its count as a `usize`. If you want to count by a
|
||||
/// different sized integer, the `zip` function provides similar functionality.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
|
|
@ -324,7 +288,7 @@ pub trait IteratorExt: Iterator + Sized {
|
|||
/// ```
|
||||
#[inline]
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
fn enumerate(self) -> Enumerate<Self> {
|
||||
fn enumerate(self) -> Enumerate<Self> where Self: Sized {
|
||||
Enumerate{iter: self, count: 0}
|
||||
}
|
||||
|
||||
|
|
@ -348,7 +312,7 @@ pub trait IteratorExt: Iterator + Sized {
|
|||
/// ```
|
||||
#[inline]
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
fn peekable(self) -> Peekable<Self> {
|
||||
fn peekable(self) -> Peekable<Self> where Self: Sized {
|
||||
Peekable{iter: self, peeked: None}
|
||||
}
|
||||
|
||||
|
|
@ -369,7 +333,7 @@ pub trait IteratorExt: Iterator + Sized {
|
|||
#[inline]
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
fn skip_while<P>(self, predicate: P) -> SkipWhile<Self, P> where
|
||||
P: FnMut(&Self::Item) -> bool,
|
||||
Self: Sized, P: FnMut(&Self::Item) -> bool,
|
||||
{
|
||||
SkipWhile{iter: self, flag: false, predicate: predicate}
|
||||
}
|
||||
|
|
@ -390,7 +354,7 @@ pub trait IteratorExt: Iterator + Sized {
|
|||
#[inline]
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
fn take_while<P>(self, predicate: P) -> TakeWhile<Self, P> where
|
||||
P: FnMut(&Self::Item) -> bool,
|
||||
Self: Sized, P: FnMut(&Self::Item) -> bool,
|
||||
{
|
||||
TakeWhile{iter: self, flag: false, predicate: predicate}
|
||||
}
|
||||
|
|
@ -409,7 +373,7 @@ pub trait IteratorExt: Iterator + Sized {
|
|||
/// ```
|
||||
#[inline]
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
fn skip(self, n: usize) -> Skip<Self> {
|
||||
fn skip(self, n: usize) -> Skip<Self> where Self: Sized {
|
||||
Skip{iter: self, n: n}
|
||||
}
|
||||
|
||||
|
|
@ -428,7 +392,7 @@ pub trait IteratorExt: Iterator + Sized {
|
|||
/// ```
|
||||
#[inline]
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
fn take(self, n: usize) -> Take<Self> {
|
||||
fn take(self, n: usize) -> Take<Self> where Self: Sized, {
|
||||
Take{iter: self, n: n}
|
||||
}
|
||||
|
||||
|
|
@ -455,7 +419,7 @@ pub trait IteratorExt: Iterator + Sized {
|
|||
#[inline]
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
fn scan<St, B, F>(self, initial_state: St, f: F) -> Scan<Self, St, F>
|
||||
where F: FnMut(&mut St, Self::Item) -> Option<B>,
|
||||
where Self: Sized, F: FnMut(&mut St, Self::Item) -> Option<B>,
|
||||
{
|
||||
Scan{iter: self, f: f, state: initial_state}
|
||||
}
|
||||
|
|
@ -478,7 +442,7 @@ pub trait IteratorExt: Iterator + Sized {
|
|||
#[inline]
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
fn flat_map<U, F>(self, f: F) -> FlatMap<Self, U, F>
|
||||
where U: Iterator, F: FnMut(Self::Item) -> U,
|
||||
where Self: Sized, U: Iterator, F: FnMut(Self::Item) -> U,
|
||||
{
|
||||
FlatMap{iter: self, f: f, frontiter: None, backiter: None }
|
||||
}
|
||||
|
|
@ -512,7 +476,7 @@ pub trait IteratorExt: Iterator + Sized {
|
|||
/// ```
|
||||
#[inline]
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
fn fuse(self) -> Fuse<Self> {
|
||||
fn fuse(self) -> Fuse<Self> where Self: Sized {
|
||||
Fuse{iter: self, done: false}
|
||||
}
|
||||
|
||||
|
|
@ -538,7 +502,7 @@ pub trait IteratorExt: Iterator + Sized {
|
|||
#[inline]
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
fn inspect<F>(self, f: F) -> Inspect<Self, F> where
|
||||
F: FnMut(&Self::Item),
|
||||
Self: Sized, F: FnMut(&Self::Item),
|
||||
{
|
||||
Inspect{iter: self, f: f}
|
||||
}
|
||||
|
|
@ -558,7 +522,7 @@ pub trait IteratorExt: Iterator + Sized {
|
|||
/// assert!(it.next() == Some(5));
|
||||
/// ```
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
fn by_ref(&mut self) -> &mut Self { self }
|
||||
fn by_ref(&mut self) -> &mut Self where Self: Sized { self }
|
||||
|
||||
/// Loops through the entire iterator, collecting all of the elements into
|
||||
/// a container implementing `FromIterator`.
|
||||
|
|
@ -573,7 +537,7 @@ pub trait IteratorExt: Iterator + Sized {
|
|||
/// ```
|
||||
#[inline]
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
fn collect<B: FromIterator<Self::Item>>(self) -> B {
|
||||
fn collect<B: FromIterator<Self::Item>>(self) -> B where Self: Sized {
|
||||
FromIterator::from_iter(self)
|
||||
}
|
||||
|
||||
|
|
@ -592,6 +556,7 @@ pub trait IteratorExt: Iterator + Sized {
|
|||
#[unstable(feature = "core",
|
||||
reason = "recently added as part of collections reform")]
|
||||
fn partition<B, F>(self, mut f: F) -> (B, B) where
|
||||
Self: Sized,
|
||||
B: Default + Extend<Self::Item>,
|
||||
F: FnMut(&Self::Item) -> bool
|
||||
{
|
||||
|
|
@ -621,7 +586,7 @@ pub trait IteratorExt: Iterator + Sized {
|
|||
#[inline]
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
fn fold<B, F>(self, init: B, mut f: F) -> B where
|
||||
F: FnMut(B, Self::Item) -> B,
|
||||
Self: Sized, F: FnMut(B, Self::Item) -> B,
|
||||
{
|
||||
let mut accum = init;
|
||||
for x in self {
|
||||
|
|
@ -641,7 +606,9 @@ pub trait IteratorExt: Iterator + Sized {
|
|||
/// ```
|
||||
#[inline]
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
fn all<F>(&mut self, mut f: F) -> bool where F: FnMut(Self::Item) -> bool {
|
||||
fn all<F>(&mut self, mut f: F) -> bool where
|
||||
Self: Sized, F: FnMut(Self::Item) -> bool
|
||||
{
|
||||
for x in self.by_ref() { if !f(x) { return false; } }
|
||||
true
|
||||
}
|
||||
|
|
@ -662,7 +629,10 @@ pub trait IteratorExt: Iterator + Sized {
|
|||
/// ```
|
||||
#[inline]
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
fn any<F>(&mut self, mut f: F) -> bool where F: FnMut(Self::Item) -> bool {
|
||||
fn any<F>(&mut self, mut f: F) -> bool where
|
||||
Self: Sized,
|
||||
F: FnMut(Self::Item) -> bool
|
||||
{
|
||||
for x in self.by_ref() { if f(x) { return true; } }
|
||||
false
|
||||
}
|
||||
|
|
@ -682,6 +652,7 @@ pub trait IteratorExt: Iterator + Sized {
|
|||
#[inline]
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
fn find<P>(&mut self, mut predicate: P) -> Option<Self::Item> where
|
||||
Self: Sized,
|
||||
P: FnMut(&Self::Item) -> bool,
|
||||
{
|
||||
for x in self.by_ref() {
|
||||
|
|
@ -705,6 +676,7 @@ pub trait IteratorExt: Iterator + Sized {
|
|||
#[inline]
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
fn position<P>(&mut self, mut predicate: P) -> Option<usize> where
|
||||
Self: Sized,
|
||||
P: FnMut(Self::Item) -> bool,
|
||||
{
|
||||
let mut i = 0;
|
||||
|
|
@ -735,7 +707,7 @@ pub trait IteratorExt: Iterator + Sized {
|
|||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
fn rposition<P>(&mut self, mut predicate: P) -> Option<usize> where
|
||||
P: FnMut(Self::Item) -> bool,
|
||||
Self: ExactSizeIterator + DoubleEndedIterator
|
||||
Self: Sized + ExactSizeIterator + DoubleEndedIterator
|
||||
{
|
||||
let mut i = self.len();
|
||||
|
||||
|
|
@ -758,7 +730,7 @@ pub trait IteratorExt: Iterator + Sized {
|
|||
/// ```
|
||||
#[inline]
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
fn max(self) -> Option<Self::Item> where Self::Item: Ord
|
||||
fn max(self) -> Option<Self::Item> where Self: Sized, Self::Item: Ord
|
||||
{
|
||||
self.fold(None, |max, x| {
|
||||
match max {
|
||||
|
|
@ -778,7 +750,7 @@ pub trait IteratorExt: Iterator + Sized {
|
|||
/// ```
|
||||
#[inline]
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
fn min(self) -> Option<Self::Item> where Self::Item: Ord
|
||||
fn min(self) -> Option<Self::Item> where Self: Sized, Self::Item: Ord
|
||||
{
|
||||
self.fold(None, |min, x| {
|
||||
match min {
|
||||
|
|
@ -820,7 +792,7 @@ pub trait IteratorExt: Iterator + Sized {
|
|||
/// assert!(a.iter().min_max() == MinMax(&1, &1));
|
||||
/// ```
|
||||
#[unstable(feature = "core", reason = "return type may change")]
|
||||
fn min_max(mut self) -> MinMaxResult<Self::Item> where Self::Item: Ord
|
||||
fn min_max(mut self) -> MinMaxResult<Self::Item> where Self: Sized, Self::Item: Ord
|
||||
{
|
||||
let (mut min, mut max) = match self.next() {
|
||||
None => return NoElements,
|
||||
|
|
@ -880,6 +852,7 @@ pub trait IteratorExt: Iterator + Sized {
|
|||
#[unstable(feature = "core",
|
||||
reason = "may want to produce an Ordering directly; see #15311")]
|
||||
fn max_by<B: Ord, F>(self, mut f: F) -> Option<Self::Item> where
|
||||
Self: Sized,
|
||||
F: FnMut(&Self::Item) -> B,
|
||||
{
|
||||
self.fold(None, |max: Option<(Self::Item, B)>, x| {
|
||||
|
|
@ -911,6 +884,7 @@ pub trait IteratorExt: Iterator + Sized {
|
|||
#[unstable(feature = "core",
|
||||
reason = "may want to produce an Ordering directly; see #15311")]
|
||||
fn min_by<B: Ord, F>(self, mut f: F) -> Option<Self::Item> where
|
||||
Self: Sized,
|
||||
F: FnMut(&Self::Item) -> B,
|
||||
{
|
||||
self.fold(None, |min: Option<(Self::Item, B)>, x| {
|
||||
|
|
@ -940,7 +914,7 @@ pub trait IteratorExt: Iterator + Sized {
|
|||
/// `std::usize::MAX` elements of the original iterator.
|
||||
#[inline]
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
fn rev(self) -> Rev<Self> {
|
||||
fn rev(self) -> Rev<Self> where Self: Sized {
|
||||
Rev{iter: self}
|
||||
}
|
||||
|
||||
|
|
@ -962,7 +936,7 @@ pub trait IteratorExt: Iterator + Sized {
|
|||
fn unzip<A, B, FromA, FromB>(self) -> (FromA, FromB) where
|
||||
FromA: Default + Extend<A>,
|
||||
FromB: Default + Extend<B>,
|
||||
Self: Iterator<Item=(A, B)>,
|
||||
Self: Sized + Iterator<Item=(A, B)>,
|
||||
{
|
||||
struct SizeHint<A>(usize, Option<usize>, marker::PhantomData<A>);
|
||||
impl<A> Iterator for SizeHint<A> {
|
||||
|
|
@ -993,7 +967,7 @@ pub trait IteratorExt: Iterator + Sized {
|
|||
/// converting an Iterator<&T> to an Iterator<T>.
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
fn cloned<'a, T: 'a>(self) -> Cloned<Self>
|
||||
where Self: Iterator<Item=&'a T>, T: Clone
|
||||
where Self: Sized + Iterator<Item=&'a T>, T: Clone
|
||||
{
|
||||
Cloned { it: self }
|
||||
}
|
||||
|
|
@ -1011,7 +985,7 @@ pub trait IteratorExt: Iterator + Sized {
|
|||
/// ```
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
#[inline]
|
||||
fn cycle(self) -> Cycle<Self> where Self: Clone {
|
||||
fn cycle(self) -> Cycle<Self> where Self: Sized + Clone {
|
||||
Cycle{orig: self.clone(), iter: self}
|
||||
}
|
||||
|
||||
|
|
@ -1019,7 +993,7 @@ pub trait IteratorExt: Iterator + Sized {
|
|||
#[unstable(feature = "core",
|
||||
reason = "uncertain about placement or widespread use")]
|
||||
fn reverse_in_place<'a, T: 'a>(&mut self) where
|
||||
Self: Iterator<Item=&'a mut T> + DoubleEndedIterator
|
||||
Self: Sized + Iterator<Item=&'a mut T> + DoubleEndedIterator
|
||||
{
|
||||
loop {
|
||||
match (self.next(), self.next_back()) {
|
||||
|
|
@ -1031,7 +1005,76 @@ pub trait IteratorExt: Iterator + Sized {
|
|||
}
|
||||
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
impl<I> IteratorExt for I where I: Iterator {}
|
||||
impl<'a, I: Iterator + ?Sized> Iterator for &'a mut I {
|
||||
type Item = I::Item;
|
||||
fn next(&mut self) -> Option<I::Item> { (**self).next() }
|
||||
fn size_hint(&self) -> (usize, Option<usize>) { (**self).size_hint() }
|
||||
}
|
||||
|
||||
/// Conversion from an `Iterator`
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
#[rustc_on_unimplemented="a collection of type `{Self}` cannot be \
|
||||
built from an iterator over elements of type `{A}`"]
|
||||
pub trait FromIterator<A> {
|
||||
/// Build a container with elements from something iterable.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// use std::collections::HashSet;
|
||||
/// use std::iter::FromIterator;
|
||||
///
|
||||
/// let colors_vec = vec!["red", "red", "yellow", "blue"];
|
||||
/// let colors_set = HashSet::<&str>::from_iter(colors_vec);
|
||||
/// assert_eq!(colors_set.len(), 3);
|
||||
/// ```
|
||||
///
|
||||
/// `FromIterator` is more commonly used implicitly via the `Iterator::collect` method:
|
||||
///
|
||||
/// ```
|
||||
/// use std::collections::HashSet;
|
||||
///
|
||||
/// let colors_vec = vec!["red", "red", "yellow", "blue"];
|
||||
/// let colors_set = colors_vec.into_iter().collect::<HashSet<&str>>();
|
||||
/// assert_eq!(colors_set.len(), 3);
|
||||
/// ```
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
fn from_iter<T: IntoIterator<Item=A>>(iterator: T) -> Self;
|
||||
}
|
||||
|
||||
/// Conversion into an `Iterator`
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
pub trait IntoIterator {
|
||||
/// The type of the elements being iterated
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
type Item;
|
||||
|
||||
/// A container for iterating over elements of type Item
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
type IntoIter: Iterator<Item=Self::Item>;
|
||||
|
||||
/// Consumes `Self` and returns an iterator over it
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
fn into_iter(self) -> Self::IntoIter;
|
||||
}
|
||||
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
impl<I: Iterator> IntoIterator for I {
|
||||
type Item = I::Item;
|
||||
type IntoIter = I;
|
||||
|
||||
fn into_iter(self) -> I {
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
/// A type growable from an `Iterator` implementation
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
pub trait Extend<A> {
|
||||
/// Extend a container with the elements yielded by an arbitrary iterator
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
fn extend<T: IntoIterator<Item=A>>(&mut self, iterable: T);
|
||||
}
|
||||
|
||||
/// A range iterator able to yield elements from both ends
|
||||
///
|
||||
|
|
@ -1239,7 +1282,7 @@ impl_multiplicative! { usize, 1 }
|
|||
impl_multiplicative! { f32, 1.0 }
|
||||
impl_multiplicative! { f64, 1.0 }
|
||||
|
||||
/// `MinMaxResult` is an enum returned by `min_max`. See `IteratorOrdExt::min_max` for more detail.
|
||||
/// `MinMaxResult` is an enum returned by `min_max`. See `Iterator::min_max` for more detail.
|
||||
#[derive(Clone, PartialEq, Debug)]
|
||||
#[unstable(feature = "core",
|
||||
reason = "unclear whether such a fine-grained result is widely useful")]
|
||||
|
|
|
|||
|
|
@ -63,7 +63,6 @@
|
|||
#![allow(raw_pointer_derive)]
|
||||
#![deny(missing_docs)]
|
||||
|
||||
#![feature(int_uint)]
|
||||
#![feature(intrinsics, lang_items)]
|
||||
#![feature(on_unimplemented)]
|
||||
#![feature(simd, unsafe_destructor)]
|
||||
|
|
|
|||
|
|
@ -218,7 +218,7 @@ macro_rules! writeln {
|
|||
/// Match arms:
|
||||
///
|
||||
/// ```
|
||||
/// fn foo(x: Option<int>) {
|
||||
/// fn foo(x: Option<i32>) {
|
||||
/// match x {
|
||||
/// Some(n) if n >= 0 => println!("Some(Non-negative)"),
|
||||
/// Some(n) if n < 0 => println!("Some(Negative)"),
|
||||
|
|
|
|||
|
|
@ -158,6 +158,32 @@ pub unsafe fn zeroed<T>() -> T {
|
|||
intrinsics::init()
|
||||
}
|
||||
|
||||
/// Create a value initialized to an unspecified series of bytes.
|
||||
///
|
||||
/// The byte sequence usually indicates that the value at the memory
|
||||
/// in question has been dropped. Thus, *if* T carries a drop flag,
|
||||
/// any associated destructor will not be run when the value falls out
|
||||
/// of scope.
|
||||
///
|
||||
/// Some code at one time used the `zeroed` function above to
|
||||
/// accomplish this goal.
|
||||
///
|
||||
/// This function is expected to be deprecated with the transition
|
||||
/// to non-zeroing drop.
|
||||
#[inline]
|
||||
#[unstable(feature = "filling_drop")]
|
||||
pub unsafe fn dropped<T>() -> T {
|
||||
#[cfg(stage0)]
|
||||
#[inline(always)]
|
||||
unsafe fn dropped_impl<T>() -> T { zeroed() }
|
||||
|
||||
#[cfg(not(stage0))]
|
||||
#[inline(always)]
|
||||
unsafe fn dropped_impl<T>() -> T { intrinsics::init_dropped() }
|
||||
|
||||
dropped_impl()
|
||||
}
|
||||
|
||||
/// Create an uninitialized value.
|
||||
///
|
||||
/// Care must be taken when using this function, if the type `T` has a destructor and the value
|
||||
|
|
@ -291,6 +317,49 @@ pub fn replace<T>(dest: &mut T, mut src: T) -> T {
|
|||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
pub fn drop<T>(_x: T) { }
|
||||
|
||||
macro_rules! repeat_u8_as_u32 {
|
||||
($name:expr) => { (($name as u32) << 24 |
|
||||
($name as u32) << 16 |
|
||||
($name as u32) << 8 |
|
||||
($name as u32)) }
|
||||
}
|
||||
macro_rules! repeat_u8_as_u64 {
|
||||
($name:expr) => { ((repeat_u8_as_u32!($name) as u64) << 32 |
|
||||
(repeat_u8_as_u32!($name) as u64)) }
|
||||
}
|
||||
|
||||
// NOTE: Keep synchronized with values used in librustc_trans::trans::adt.
|
||||
//
|
||||
// In particular, the POST_DROP_U8 marker must never equal the
|
||||
// DTOR_NEEDED_U8 marker.
|
||||
//
|
||||
// For a while pnkfelix was using 0xc1 here.
|
||||
// But having the sign bit set is a pain, so 0x1d is probably better.
|
||||
//
|
||||
// And of course, 0x00 brings back the old world of zero'ing on drop.
|
||||
#[cfg(not(stage0))] #[unstable(feature = "filling_drop")]
|
||||
pub const POST_DROP_U8: u8 = 0x1d;
|
||||
#[cfg(not(stage0))] #[unstable(feature = "filling_drop")]
|
||||
pub const POST_DROP_U32: u32 = repeat_u8_as_u32!(POST_DROP_U8);
|
||||
#[cfg(not(stage0))] #[unstable(feature = "filling_drop")]
|
||||
pub const POST_DROP_U64: u64 = repeat_u8_as_u64!(POST_DROP_U8);
|
||||
|
||||
#[cfg(target_pointer_width = "32")]
|
||||
#[cfg(not(stage0))] #[unstable(feature = "filling_drop")]
|
||||
pub const POST_DROP_USIZE: usize = POST_DROP_U32 as usize;
|
||||
#[cfg(target_pointer_width = "64")]
|
||||
#[cfg(not(stage0))] #[unstable(feature = "filling_drop")]
|
||||
pub const POST_DROP_USIZE: usize = POST_DROP_U64 as usize;
|
||||
|
||||
#[cfg(stage0)] #[unstable(feature = "filling_drop")]
|
||||
pub const POST_DROP_U8: u8 = 0;
|
||||
#[cfg(stage0)] #[unstable(feature = "filling_drop")]
|
||||
pub const POST_DROP_U32: u32 = 0;
|
||||
#[cfg(stage0)] #[unstable(feature = "filling_drop")]
|
||||
pub const POST_DROP_U64: u64 = 0;
|
||||
#[cfg(stage0)] #[unstable(feature = "filling_drop")]
|
||||
pub const POST_DROP_USIZE: usize = 0;
|
||||
|
||||
/// Interprets `src` as `&U`, and then reads `src` without moving the contained value.
|
||||
///
|
||||
/// This function will unsafely assume the pointer `src` is valid for `sizeof(U)` bytes by
|
||||
|
|
|
|||
|
|
@ -193,12 +193,12 @@ impl Float for f32 {
|
|||
#[inline]
|
||||
#[unstable(feature = "core")]
|
||||
#[deprecated(since = "1.0.0")]
|
||||
fn mantissa_digits(_: Option<f32>) -> uint { MANTISSA_DIGITS as uint }
|
||||
fn mantissa_digits(_: Option<f32>) -> usize { MANTISSA_DIGITS as usize }
|
||||
|
||||
#[inline]
|
||||
#[unstable(feature = "core")]
|
||||
#[deprecated(since = "1.0.0")]
|
||||
fn digits(_: Option<f32>) -> uint { DIGITS as uint }
|
||||
fn digits(_: Option<f32>) -> usize { DIGITS as usize }
|
||||
|
||||
#[inline]
|
||||
#[unstable(feature = "core")]
|
||||
|
|
@ -208,22 +208,22 @@ impl Float for f32 {
|
|||
#[inline]
|
||||
#[unstable(feature = "core")]
|
||||
#[deprecated(since = "1.0.0")]
|
||||
fn min_exp(_: Option<f32>) -> int { MIN_EXP as int }
|
||||
fn min_exp(_: Option<f32>) -> isize { MIN_EXP as isize }
|
||||
|
||||
#[inline]
|
||||
#[unstable(feature = "core")]
|
||||
#[deprecated(since = "1.0.0")]
|
||||
fn max_exp(_: Option<f32>) -> int { MAX_EXP as int }
|
||||
fn max_exp(_: Option<f32>) -> isize { MAX_EXP as isize }
|
||||
|
||||
#[inline]
|
||||
#[unstable(feature = "core")]
|
||||
#[deprecated(since = "1.0.0")]
|
||||
fn min_10_exp(_: Option<f32>) -> int { MIN_10_EXP as int }
|
||||
fn min_10_exp(_: Option<f32>) -> isize { MIN_10_EXP as isize }
|
||||
|
||||
#[inline]
|
||||
#[unstable(feature = "core")]
|
||||
#[deprecated(since = "1.0.0")]
|
||||
fn max_10_exp(_: Option<f32>) -> int { MAX_10_EXP as int }
|
||||
fn max_10_exp(_: Option<f32>) -> isize { MAX_10_EXP as isize }
|
||||
|
||||
#[inline]
|
||||
#[unstable(feature = "core")]
|
||||
|
|
|
|||
|
|
@ -200,12 +200,12 @@ impl Float for f64 {
|
|||
#[inline]
|
||||
#[unstable(feature = "core")]
|
||||
#[deprecated(since = "1.0.0")]
|
||||
fn mantissa_digits(_: Option<f64>) -> uint { MANTISSA_DIGITS as uint }
|
||||
fn mantissa_digits(_: Option<f64>) -> usize { MANTISSA_DIGITS as usize }
|
||||
|
||||
#[inline]
|
||||
#[unstable(feature = "core")]
|
||||
#[deprecated(since = "1.0.0")]
|
||||
fn digits(_: Option<f64>) -> uint { DIGITS as uint }
|
||||
fn digits(_: Option<f64>) -> usize { DIGITS as usize }
|
||||
|
||||
#[inline]
|
||||
#[unstable(feature = "core")]
|
||||
|
|
@ -215,22 +215,22 @@ impl Float for f64 {
|
|||
#[inline]
|
||||
#[unstable(feature = "core")]
|
||||
#[deprecated(since = "1.0.0")]
|
||||
fn min_exp(_: Option<f64>) -> int { MIN_EXP as int }
|
||||
fn min_exp(_: Option<f64>) -> isize { MIN_EXP as isize }
|
||||
|
||||
#[inline]
|
||||
#[unstable(feature = "core")]
|
||||
#[deprecated(since = "1.0.0")]
|
||||
fn max_exp(_: Option<f64>) -> int { MAX_EXP as int }
|
||||
fn max_exp(_: Option<f64>) -> isize { MAX_EXP as isize }
|
||||
|
||||
#[inline]
|
||||
#[unstable(feature = "core")]
|
||||
#[deprecated(since = "1.0.0")]
|
||||
fn min_10_exp(_: Option<f64>) -> int { MIN_10_EXP as int }
|
||||
fn min_10_exp(_: Option<f64>) -> isize { MIN_10_EXP as isize }
|
||||
|
||||
#[inline]
|
||||
#[unstable(feature = "core")]
|
||||
#[deprecated(since = "1.0.0")]
|
||||
fn max_10_exp(_: Option<f64>) -> int { MAX_10_EXP as int }
|
||||
fn max_10_exp(_: Option<f64>) -> isize { MAX_10_EXP as isize }
|
||||
|
||||
#[inline]
|
||||
#[unstable(feature = "core")]
|
||||
|
|
|
|||
|
|
@ -12,6 +12,5 @@
|
|||
|
||||
#![stable(feature = "rust1", since = "1.0.0")]
|
||||
#![doc(primitive = "i16")]
|
||||
#![allow(trivial_numeric_casts)]
|
||||
|
||||
int_module! { i16, 16 }
|
||||
|
|
|
|||
|
|
@ -12,6 +12,5 @@
|
|||
|
||||
#![stable(feature = "rust1", since = "1.0.0")]
|
||||
#![doc(primitive = "i32")]
|
||||
#![allow(trivial_numeric_casts)]
|
||||
|
||||
int_module! { i32, 32 }
|
||||
|
|
|
|||
|
|
@ -12,6 +12,5 @@
|
|||
|
||||
#![stable(feature = "rust1", since = "1.0.0")]
|
||||
#![doc(primitive = "i64")]
|
||||
#![allow(trivial_numeric_casts)]
|
||||
|
||||
int_module! { i64, 64 }
|
||||
|
|
|
|||
|
|
@ -12,6 +12,5 @@
|
|||
|
||||
#![stable(feature = "rust1", since = "1.0.0")]
|
||||
#![doc(primitive = "i8")]
|
||||
#![allow(trivial_numeric_casts)]
|
||||
|
||||
int_module! { i8, 8 }
|
||||
|
|
|
|||
|
|
@ -9,7 +9,6 @@
|
|||
// except according to those terms.
|
||||
|
||||
#![doc(hidden)]
|
||||
#![allow(trivial_numeric_casts)]
|
||||
|
||||
macro_rules! int_module { ($T:ty, $bits:expr) => (
|
||||
|
||||
|
|
|
|||
|
|
@ -16,7 +16,6 @@
|
|||
|
||||
#![stable(feature = "rust1", since = "1.0.0")]
|
||||
#![doc(primitive = "isize")]
|
||||
#![allow(trivial_numeric_casts)]
|
||||
|
||||
#[cfg(target_pointer_width = "32")]
|
||||
int_module! { isize, 32 }
|
||||
|
|
|
|||
|
|
@ -14,7 +14,6 @@
|
|||
|
||||
#![stable(feature = "rust1", since = "1.0.0")]
|
||||
#![allow(missing_docs)]
|
||||
#![allow(trivial_numeric_casts)]
|
||||
|
||||
use self::wrapping::{OverflowingOps, WrappingOps};
|
||||
|
||||
|
|
@ -24,7 +23,7 @@ use cmp::{PartialEq, Eq, PartialOrd, Ord};
|
|||
use error::Error;
|
||||
use fmt;
|
||||
use intrinsics;
|
||||
use iter::IteratorExt;
|
||||
use iter::Iterator;
|
||||
use marker::Copy;
|
||||
use mem::size_of;
|
||||
use ops::{Add, Sub, Mul, Div, Rem, Neg};
|
||||
|
|
@ -52,8 +51,8 @@ pub trait Int
|
|||
+ BitAnd<Output=Self>
|
||||
+ BitOr<Output=Self>
|
||||
+ BitXor<Output=Self>
|
||||
+ Shl<uint, Output=Self>
|
||||
+ Shr<uint, Output=Self>
|
||||
+ Shl<usize, Output=Self>
|
||||
+ Shr<usize, Output=Self>
|
||||
+ WrappingOps
|
||||
+ OverflowingOps
|
||||
{
|
||||
|
|
@ -565,7 +564,7 @@ uint_impl! { u64 = u64, 64,
|
|||
intrinsics::u64_mul_with_overflow }
|
||||
|
||||
#[cfg(target_pointer_width = "32")]
|
||||
uint_impl! { uint = u32, 32,
|
||||
uint_impl! { usize = u32, 32,
|
||||
intrinsics::ctpop32,
|
||||
intrinsics::ctlz32,
|
||||
intrinsics::cttz32,
|
||||
|
|
@ -575,7 +574,7 @@ uint_impl! { uint = u32, 32,
|
|||
intrinsics::u32_mul_with_overflow }
|
||||
|
||||
#[cfg(target_pointer_width = "64")]
|
||||
uint_impl! { uint = u64, 64,
|
||||
uint_impl! { usize = u64, 64,
|
||||
intrinsics::ctpop64,
|
||||
intrinsics::ctlz64,
|
||||
intrinsics::cttz64,
|
||||
|
|
@ -680,13 +679,13 @@ int_impl! { i64 = i64, u64, 64,
|
|||
intrinsics::i64_mul_with_overflow }
|
||||
|
||||
#[cfg(target_pointer_width = "32")]
|
||||
int_impl! { int = i32, u32, 32,
|
||||
int_impl! { isize = i32, u32, 32,
|
||||
intrinsics::i32_add_with_overflow,
|
||||
intrinsics::i32_sub_with_overflow,
|
||||
intrinsics::i32_mul_with_overflow }
|
||||
|
||||
#[cfg(target_pointer_width = "64")]
|
||||
int_impl! { int = i64, u64, 64,
|
||||
int_impl! { isize = i64, u64, 64,
|
||||
intrinsics::i64_add_with_overflow,
|
||||
intrinsics::i64_sub_with_overflow,
|
||||
intrinsics::i64_mul_with_overflow }
|
||||
|
|
@ -752,7 +751,7 @@ signed_int_impl! { i8 }
|
|||
signed_int_impl! { i16 }
|
||||
signed_int_impl! { i32 }
|
||||
signed_int_impl! { i64 }
|
||||
signed_int_impl! { int }
|
||||
signed_int_impl! { isize }
|
||||
|
||||
// `Int` + `SignedInt` implemented for signed integers
|
||||
macro_rules! int_impl {
|
||||
|
|
@ -1232,7 +1231,7 @@ impl i64 {
|
|||
#[cfg(target_pointer_width = "32")]
|
||||
#[lang = "isize"]
|
||||
impl isize {
|
||||
int_impl! { int = i32, u32, 32,
|
||||
int_impl! { isize = i32, u32, 32,
|
||||
intrinsics::i32_add_with_overflow,
|
||||
intrinsics::i32_sub_with_overflow,
|
||||
intrinsics::i32_mul_with_overflow }
|
||||
|
|
@ -1241,7 +1240,7 @@ impl isize {
|
|||
#[cfg(target_pointer_width = "64")]
|
||||
#[lang = "isize"]
|
||||
impl isize {
|
||||
int_impl! { int = i64, u64, 64,
|
||||
int_impl! { isize = i64, u64, 64,
|
||||
intrinsics::i64_add_with_overflow,
|
||||
intrinsics::i64_sub_with_overflow,
|
||||
intrinsics::i64_mul_with_overflow }
|
||||
|
|
@ -1746,7 +1745,7 @@ impl u64 {
|
|||
#[cfg(target_pointer_width = "32")]
|
||||
#[lang = "usize"]
|
||||
impl usize {
|
||||
uint_impl! { uint = u32, 32,
|
||||
uint_impl! { usize = u32, 32,
|
||||
intrinsics::ctpop32,
|
||||
intrinsics::ctlz32,
|
||||
intrinsics::cttz32,
|
||||
|
|
@ -1759,7 +1758,7 @@ impl usize {
|
|||
#[cfg(target_pointer_width = "64")]
|
||||
#[lang = "usize"]
|
||||
impl usize {
|
||||
uint_impl! { uint = u64, 64,
|
||||
uint_impl! { usize = u64, 64,
|
||||
intrinsics::ctpop64,
|
||||
intrinsics::ctlz64,
|
||||
intrinsics::cttz64,
|
||||
|
|
@ -1772,11 +1771,11 @@ impl usize {
|
|||
/// A generic trait for converting a value to a number.
|
||||
#[unstable(feature = "core", reason = "trait is likely to be removed")]
|
||||
pub trait ToPrimitive {
|
||||
/// Converts the value of `self` to an `int`.
|
||||
/// Converts the value of `self` to an `isize`.
|
||||
#[inline]
|
||||
#[unstable(feature = "core")]
|
||||
#[deprecated(since = "1.0.0", reason = "use to_isize")]
|
||||
fn to_int(&self) -> Option<int> {
|
||||
fn to_int(&self) -> Option<isize> {
|
||||
self.to_i64().and_then(|x| x.to_isize())
|
||||
}
|
||||
|
||||
|
|
@ -1807,11 +1806,11 @@ pub trait ToPrimitive {
|
|||
/// Converts the value of `self` to an `i64`.
|
||||
fn to_i64(&self) -> Option<i64>;
|
||||
|
||||
/// Converts the value of `self` to an `uint`.
|
||||
/// Converts the value of `self` to an `usize`.
|
||||
#[inline]
|
||||
#[unstable(feature = "core")]
|
||||
#[deprecated(since = "1.0.0", reason = "use to_usize")]
|
||||
fn to_uint(&self) -> Option<uint> {
|
||||
fn to_uint(&self) -> Option<usize> {
|
||||
self.to_u64().and_then(|x| x.to_usize())
|
||||
}
|
||||
|
||||
|
|
@ -1893,7 +1892,7 @@ macro_rules! impl_to_primitive_int {
|
|||
($T:ty) => (
|
||||
impl ToPrimitive for $T {
|
||||
#[inline]
|
||||
fn to_int(&self) -> Option<int> { impl_to_primitive_int_to_int!($T, int, *self) }
|
||||
fn to_int(&self) -> Option<isize> { impl_to_primitive_int_to_int!($T, isize, *self) }
|
||||
#[inline]
|
||||
fn to_isize(&self) -> Option<isize> { impl_to_primitive_int_to_int!($T, isize, *self) }
|
||||
#[inline]
|
||||
|
|
@ -1906,7 +1905,7 @@ macro_rules! impl_to_primitive_int {
|
|||
fn to_i64(&self) -> Option<i64> { impl_to_primitive_int_to_int!($T, i64, *self) }
|
||||
|
||||
#[inline]
|
||||
fn to_uint(&self) -> Option<uint> { impl_to_primitive_int_to_uint!($T, uint, *self) }
|
||||
fn to_uint(&self) -> Option<usize> { impl_to_primitive_int_to_uint!($T, usize, *self) }
|
||||
#[inline]
|
||||
fn to_usize(&self) -> Option<usize> { impl_to_primitive_int_to_uint!($T, usize, *self) }
|
||||
#[inline]
|
||||
|
|
@ -1967,9 +1966,9 @@ macro_rules! impl_to_primitive_uint {
|
|||
($T:ty) => (
|
||||
impl ToPrimitive for $T {
|
||||
#[inline]
|
||||
fn to_int(&self) -> Option<int> { impl_to_primitive_uint_to_int!(int, *self) }
|
||||
fn to_int(&self) -> Option<isize> { impl_to_primitive_uint_to_int!(isize, *self) }
|
||||
#[inline]
|
||||
fn to_isize(&self) -> Option<int> { impl_to_primitive_uint_to_int!(isize, *self) }
|
||||
fn to_isize(&self) -> Option<isize> { impl_to_primitive_uint_to_int!(isize, *self) }
|
||||
#[inline]
|
||||
fn to_i8(&self) -> Option<i8> { impl_to_primitive_uint_to_int!(i8, *self) }
|
||||
#[inline]
|
||||
|
|
@ -1980,9 +1979,11 @@ macro_rules! impl_to_primitive_uint {
|
|||
fn to_i64(&self) -> Option<i64> { impl_to_primitive_uint_to_int!(i64, *self) }
|
||||
|
||||
#[inline]
|
||||
fn to_uint(&self) -> Option<uint> { impl_to_primitive_uint_to_uint!($T, uint, *self) }
|
||||
fn to_uint(&self) -> Option<usize> { impl_to_primitive_uint_to_uint!($T, usize, *self) }
|
||||
#[inline]
|
||||
fn to_usize(&self) -> Option<uint> { impl_to_primitive_uint_to_uint!($T, usize, *self) }
|
||||
fn to_usize(&self) -> Option<usize> {
|
||||
impl_to_primitive_uint_to_uint!($T, usize, *self)
|
||||
}
|
||||
#[inline]
|
||||
fn to_u8(&self) -> Option<u8> { impl_to_primitive_uint_to_uint!($T, u8, *self) }
|
||||
#[inline]
|
||||
|
|
@ -2026,9 +2027,9 @@ macro_rules! impl_to_primitive_float {
|
|||
($T:ident) => (
|
||||
impl ToPrimitive for $T {
|
||||
#[inline]
|
||||
fn to_int(&self) -> Option<int> { Some(*self as int) }
|
||||
fn to_int(&self) -> Option<isize> { Some(*self as isize) }
|
||||
#[inline]
|
||||
fn to_isize(&self) -> Option<int> { Some(*self as isize) }
|
||||
fn to_isize(&self) -> Option<isize> { Some(*self as isize) }
|
||||
#[inline]
|
||||
fn to_i8(&self) -> Option<i8> { Some(*self as i8) }
|
||||
#[inline]
|
||||
|
|
@ -2039,9 +2040,9 @@ macro_rules! impl_to_primitive_float {
|
|||
fn to_i64(&self) -> Option<i64> { Some(*self as i64) }
|
||||
|
||||
#[inline]
|
||||
fn to_uint(&self) -> Option<uint> { Some(*self as uint) }
|
||||
fn to_uint(&self) -> Option<usize> { Some(*self as usize) }
|
||||
#[inline]
|
||||
fn to_usize(&self) -> Option<uint> { Some(*self as usize) }
|
||||
fn to_usize(&self) -> Option<usize> { Some(*self as usize) }
|
||||
#[inline]
|
||||
fn to_u8(&self) -> Option<u8> { Some(*self as u8) }
|
||||
#[inline]
|
||||
|
|
@ -2065,12 +2066,12 @@ impl_to_primitive_float! { f64 }
|
|||
/// A generic trait for converting a number to a value.
|
||||
#[unstable(feature = "core", reason = "trait is likely to be removed")]
|
||||
pub trait FromPrimitive : ::marker::Sized {
|
||||
/// Convert an `int` to return an optional value of this type. If the
|
||||
/// Convert an `isize` to return an optional value of this type. If the
|
||||
/// value cannot be represented by this value, the `None` is returned.
|
||||
#[inline]
|
||||
#[unstable(feature = "core")]
|
||||
#[deprecated(since = "1.0.0", reason = "use from_isize")]
|
||||
fn from_int(n: int) -> Option<Self> {
|
||||
fn from_int(n: isize) -> Option<Self> {
|
||||
FromPrimitive::from_i64(n as i64)
|
||||
}
|
||||
|
||||
|
|
@ -2106,12 +2107,12 @@ pub trait FromPrimitive : ::marker::Sized {
|
|||
/// type cannot be represented by this value, the `None` is returned.
|
||||
fn from_i64(n: i64) -> Option<Self>;
|
||||
|
||||
/// Convert an `uint` to return an optional value of this type. If the
|
||||
/// Convert an `usize` to return an optional value of this type. If the
|
||||
/// type cannot be represented by this value, the `None` is returned.
|
||||
#[inline]
|
||||
#[unstable(feature = "core")]
|
||||
#[deprecated(since = "1.0.0", reason = "use from_usize")]
|
||||
fn from_uint(n: uint) -> Option<Self> {
|
||||
fn from_uint(n: usize) -> Option<Self> {
|
||||
FromPrimitive::from_u64(n as u64)
|
||||
}
|
||||
|
||||
|
|
@ -2165,7 +2166,7 @@ pub trait FromPrimitive : ::marker::Sized {
|
|||
/// A utility function that just calls `FromPrimitive::from_int`.
|
||||
#[unstable(feature = "core", reason = "likely to be removed")]
|
||||
#[deprecated(since = "1.0.0", reason = "use from_isize")]
|
||||
pub fn from_int<A: FromPrimitive>(n: int) -> Option<A> {
|
||||
pub fn from_int<A: FromPrimitive>(n: isize) -> Option<A> {
|
||||
FromPrimitive::from_isize(n)
|
||||
}
|
||||
|
||||
|
|
@ -2202,7 +2203,7 @@ pub fn from_i64<A: FromPrimitive>(n: i64) -> Option<A> {
|
|||
/// A utility function that just calls `FromPrimitive::from_uint`.
|
||||
#[unstable(feature = "core", reason = "likely to be removed")]
|
||||
#[deprecated(since = "1.0.0", reason = "use from_uint")]
|
||||
pub fn from_uint<A: FromPrimitive>(n: uint) -> Option<A> {
|
||||
pub fn from_uint<A: FromPrimitive>(n: usize) -> Option<A> {
|
||||
FromPrimitive::from_usize(n)
|
||||
}
|
||||
|
||||
|
|
@ -2252,13 +2253,13 @@ macro_rules! impl_from_primitive {
|
|||
($T:ty, $to_ty:ident) => (
|
||||
#[allow(deprecated)]
|
||||
impl FromPrimitive for $T {
|
||||
#[inline] fn from_int(n: int) -> Option<$T> { n.$to_ty() }
|
||||
#[inline] fn from_int(n: isize) -> Option<$T> { n.$to_ty() }
|
||||
#[inline] fn from_i8(n: i8) -> Option<$T> { n.$to_ty() }
|
||||
#[inline] fn from_i16(n: i16) -> Option<$T> { n.$to_ty() }
|
||||
#[inline] fn from_i32(n: i32) -> Option<$T> { n.$to_ty() }
|
||||
#[inline] fn from_i64(n: i64) -> Option<$T> { n.$to_ty() }
|
||||
|
||||
#[inline] fn from_uint(n: uint) -> Option<$T> { n.$to_ty() }
|
||||
#[inline] fn from_uint(n: usize) -> Option<$T> { n.$to_ty() }
|
||||
#[inline] fn from_u8(n: u8) -> Option<$T> { n.$to_ty() }
|
||||
#[inline] fn from_u16(n: u16) -> Option<$T> { n.$to_ty() }
|
||||
#[inline] fn from_u32(n: u32) -> Option<$T> { n.$to_ty() }
|
||||
|
|
@ -2270,12 +2271,12 @@ macro_rules! impl_from_primitive {
|
|||
)
|
||||
}
|
||||
|
||||
impl_from_primitive! { int, to_int }
|
||||
impl_from_primitive! { isize, to_int }
|
||||
impl_from_primitive! { i8, to_i8 }
|
||||
impl_from_primitive! { i16, to_i16 }
|
||||
impl_from_primitive! { i32, to_i32 }
|
||||
impl_from_primitive! { i64, to_i64 }
|
||||
impl_from_primitive! { uint, to_uint }
|
||||
impl_from_primitive! { usize, to_uint }
|
||||
impl_from_primitive! { u8, to_u8 }
|
||||
impl_from_primitive! { u16, to_u16 }
|
||||
impl_from_primitive! { u32, to_u32 }
|
||||
|
|
@ -2327,12 +2328,12 @@ impl_num_cast! { u8, to_u8 }
|
|||
impl_num_cast! { u16, to_u16 }
|
||||
impl_num_cast! { u32, to_u32 }
|
||||
impl_num_cast! { u64, to_u64 }
|
||||
impl_num_cast! { uint, to_uint }
|
||||
impl_num_cast! { usize, to_uint }
|
||||
impl_num_cast! { i8, to_i8 }
|
||||
impl_num_cast! { i16, to_i16 }
|
||||
impl_num_cast! { i32, to_i32 }
|
||||
impl_num_cast! { i64, to_i64 }
|
||||
impl_num_cast! { int, to_int }
|
||||
impl_num_cast! { isize, to_int }
|
||||
impl_num_cast! { f32, to_f32 }
|
||||
impl_num_cast! { f64, to_f64 }
|
||||
|
||||
|
|
@ -2392,12 +2393,12 @@ pub trait Float
|
|||
#[deprecated(since = "1.0.0",
|
||||
reason = "use `std::f32::MANTISSA_DIGITS` or \
|
||||
`std::f64::MANTISSA_DIGITS` as appropriate")]
|
||||
fn mantissa_digits(unused_self: Option<Self>) -> uint;
|
||||
fn mantissa_digits(unused_self: Option<Self>) -> usize;
|
||||
/// Returns the number of base-10 digits of precision that this type supports.
|
||||
#[unstable(feature = "core")]
|
||||
#[deprecated(since = "1.0.0",
|
||||
reason = "use `std::f32::DIGITS` or `std::f64::DIGITS` as appropriate")]
|
||||
fn digits(unused_self: Option<Self>) -> uint;
|
||||
fn digits(unused_self: Option<Self>) -> usize;
|
||||
/// Returns the difference between 1.0 and the smallest representable number larger than 1.0.
|
||||
#[unstable(feature = "core")]
|
||||
#[deprecated(since = "1.0.0",
|
||||
|
|
@ -2407,22 +2408,22 @@ pub trait Float
|
|||
#[unstable(feature = "core")]
|
||||
#[deprecated(since = "1.0.0",
|
||||
reason = "use `std::f32::MIN_EXP` or `std::f64::MIN_EXP` as appropriate")]
|
||||
fn min_exp(unused_self: Option<Self>) -> int;
|
||||
fn min_exp(unused_self: Option<Self>) -> isize;
|
||||
/// Returns the maximum binary exponent that this type can represent.
|
||||
#[unstable(feature = "core")]
|
||||
#[deprecated(since = "1.0.0",
|
||||
reason = "use `std::f32::MAX_EXP` or `std::f64::MAX_EXP` as appropriate")]
|
||||
fn max_exp(unused_self: Option<Self>) -> int;
|
||||
fn max_exp(unused_self: Option<Self>) -> isize;
|
||||
/// Returns the minimum base-10 exponent that this type can represent.
|
||||
#[unstable(feature = "core")]
|
||||
#[deprecated(since = "1.0.0",
|
||||
reason = "use `std::f32::MIN_10_EXP` or `std::f64::MIN_10_EXP` as appropriate")]
|
||||
fn min_10_exp(unused_self: Option<Self>) -> int;
|
||||
fn min_10_exp(unused_self: Option<Self>) -> isize;
|
||||
/// Returns the maximum base-10 exponent that this type can represent.
|
||||
#[unstable(feature = "core")]
|
||||
#[deprecated(since = "1.0.0",
|
||||
reason = "use `std::f32::MAX_10_EXP` or `std::f64::MAX_10_EXP` as appropriate")]
|
||||
fn max_10_exp(unused_self: Option<Self>) -> int;
|
||||
fn max_10_exp(unused_self: Option<Self>) -> isize;
|
||||
/// Returns the smallest finite value that this type can represent.
|
||||
#[unstable(feature = "core")]
|
||||
#[deprecated(since = "1.0.0",
|
||||
|
|
@ -2625,7 +2626,7 @@ macro_rules! from_str_radix_float_impl {
|
|||
let mut prev_sig = sig;
|
||||
let mut cs = src.chars().enumerate();
|
||||
// Exponent prefix and exponent index offset
|
||||
let mut exp_info = None::<(char, uint)>;
|
||||
let mut exp_info = None::<(char, usize)>;
|
||||
|
||||
// Parse the integer part of the significand
|
||||
for (i, c) in cs.by_ref() {
|
||||
|
|
@ -2636,9 +2637,9 @@ macro_rules! from_str_radix_float_impl {
|
|||
|
||||
// add/subtract current digit depending on sign
|
||||
if is_positive {
|
||||
sig = sig + ((digit as int) as $T);
|
||||
sig = sig + ((digit as isize) as $T);
|
||||
} else {
|
||||
sig = sig - ((digit as int) as $T);
|
||||
sig = sig - ((digit as isize) as $T);
|
||||
}
|
||||
|
||||
// Detect overflow by comparing to last value, except
|
||||
|
|
@ -2719,9 +2720,9 @@ macro_rules! from_str_radix_float_impl {
|
|||
// Parse the exponent as decimal integer
|
||||
let src = &src[offset..];
|
||||
let (is_positive, exp) = match src.slice_shift_char() {
|
||||
Some(('-', src)) => (false, src.parse::<uint>()),
|
||||
Some(('+', src)) => (true, src.parse::<uint>()),
|
||||
Some((_, _)) => (true, src.parse::<uint>()),
|
||||
Some(('-', src)) => (false, src.parse::<usize>()),
|
||||
Some(('+', src)) => (true, src.parse::<usize>()),
|
||||
Some((_, _)) => (true, src.parse::<usize>()),
|
||||
None => return Err(PFE { kind: Invalid }),
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -12,6 +12,5 @@
|
|||
|
||||
#![stable(feature = "rust1", since = "1.0.0")]
|
||||
#![doc(primitive = "u16")]
|
||||
#![allow(trivial_numeric_casts)]
|
||||
|
||||
uint_module! { u16, i16, 16 }
|
||||
|
|
|
|||
|
|
@ -12,6 +12,5 @@
|
|||
|
||||
#![stable(feature = "rust1", since = "1.0.0")]
|
||||
#![doc(primitive = "u32")]
|
||||
#![allow(trivial_numeric_casts)]
|
||||
|
||||
uint_module! { u32, i32, 32 }
|
||||
|
|
|
|||
|
|
@ -12,6 +12,5 @@
|
|||
|
||||
#![stable(feature = "rust1", since = "1.0.0")]
|
||||
#![doc(primitive = "u64")]
|
||||
#![allow(trivial_numeric_casts)]
|
||||
|
||||
uint_module! { u64, i64, 64 }
|
||||
|
|
|
|||
|
|
@ -12,6 +12,5 @@
|
|||
|
||||
#![stable(feature = "rust1", since = "1.0.0")]
|
||||
#![doc(primitive = "u8")]
|
||||
#![allow(trivial_numeric_casts)]
|
||||
|
||||
uint_module! { u8, i8, 8 }
|
||||
|
|
|
|||
|
|
@ -9,7 +9,6 @@
|
|||
// except according to those terms.
|
||||
|
||||
#![doc(hidden)]
|
||||
#![allow(trivial_numeric_casts)]
|
||||
|
||||
macro_rules! uint_module { ($T:ty, $T_SIGNED:ty, $bits:expr) => (
|
||||
|
||||
|
|
|
|||
|
|
@ -16,6 +16,5 @@
|
|||
|
||||
#![stable(feature = "rust1", since = "1.0.0")]
|
||||
#![doc(primitive = "usize")]
|
||||
#![allow(trivial_numeric_casts)]
|
||||
|
||||
uint_module! { usize, isize, ::isize::BITS }
|
||||
|
|
|
|||
|
|
@ -64,10 +64,10 @@ macro_rules! wrapping_impl {
|
|||
)*)
|
||||
}
|
||||
|
||||
wrapping_impl! { uint u8 u16 u32 u64 int i8 i16 i32 i64 }
|
||||
wrapping_impl! { usize u8 u16 u32 u64 isize i8 i16 i32 i64 }
|
||||
|
||||
#[unstable(feature = "core", reason = "may be removed, renamed, or relocated")]
|
||||
#[derive(PartialEq,Eq,PartialOrd,Ord,Clone,Copy)]
|
||||
#[derive(PartialEq, Eq, PartialOrd, Ord, Debug, Clone, Copy)]
|
||||
pub struct Wrapping<T>(pub T);
|
||||
|
||||
impl<T:WrappingOps> Add for Wrapping<T> {
|
||||
|
|
@ -132,20 +132,20 @@ impl<T:WrappingOps+BitAnd<Output=T>> BitAnd for Wrapping<T> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<T:WrappingOps+Shl<uint,Output=T>> Shl<uint> for Wrapping<T> {
|
||||
impl<T:WrappingOps+Shl<usize,Output=T>> Shl<usize> for Wrapping<T> {
|
||||
type Output = Wrapping<T>;
|
||||
|
||||
#[inline(always)]
|
||||
fn shl(self, other: uint) -> Wrapping<T> {
|
||||
fn shl(self, other: usize) -> Wrapping<T> {
|
||||
Wrapping(self.0 << other)
|
||||
}
|
||||
}
|
||||
|
||||
impl<T:WrappingOps+Shr<uint,Output=T>> Shr<uint> for Wrapping<T> {
|
||||
impl<T:WrappingOps+Shr<usize,Output=T>> Shr<usize> for Wrapping<T> {
|
||||
type Output = Wrapping<T>;
|
||||
|
||||
#[inline(always)]
|
||||
fn shr(self, other: uint) -> Wrapping<T> {
|
||||
fn shr(self, other: usize) -> Wrapping<T> {
|
||||
Wrapping(self.0 >> other)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -148,10 +148,10 @@ use self::Option::*;
|
|||
use clone::Clone;
|
||||
use cmp::{Eq, Ord};
|
||||
use default::Default;
|
||||
use iter::{ExactSizeIterator};
|
||||
use iter::{Iterator, IteratorExt, DoubleEndedIterator, FromIterator, IntoIterator};
|
||||
use iter::ExactSizeIterator;
|
||||
use iter::{Iterator, DoubleEndedIterator, FromIterator, IntoIterator};
|
||||
use mem;
|
||||
use ops::{Deref, FnOnce};
|
||||
use ops::FnOnce;
|
||||
use result::Result::{Ok, Err};
|
||||
use result::Result;
|
||||
#[allow(deprecated)]
|
||||
|
|
@ -320,7 +320,7 @@ impl<T> Option<T> {
|
|||
/// assert_eq!(x.expect("the world is ending"), "value");
|
||||
/// ```
|
||||
///
|
||||
/// ```{.should_fail}
|
||||
/// ```{.should_panic}
|
||||
/// let x: Option<&str> = None;
|
||||
/// x.expect("the world is ending"); // panics with `world is ending`
|
||||
/// ```
|
||||
|
|
@ -333,7 +333,7 @@ impl<T> Option<T> {
|
|||
}
|
||||
}
|
||||
|
||||
/// Returns the inner `T` of a `Some(T)`.
|
||||
/// Moves the value `v` out of the `Option<T>` if the content of the `Option<T>` is a `Some(v)`.
|
||||
///
|
||||
/// # Panics
|
||||
///
|
||||
|
|
@ -352,7 +352,7 @@ impl<T> Option<T> {
|
|||
/// assert_eq!(x.unwrap(), "air");
|
||||
/// ```
|
||||
///
|
||||
/// ```{.should_fail}
|
||||
/// ```{.should_panic}
|
||||
/// let x: Option<&str> = None;
|
||||
/// assert_eq!(x.unwrap(), "air"); // fails
|
||||
/// ```
|
||||
|
|
@ -480,7 +480,7 @@ impl<T> Option<T> {
|
|||
/// assert_eq!(x.ok_or(0), Err(0));
|
||||
/// ```
|
||||
#[inline]
|
||||
#[unstable(feature = "core")]
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
pub fn ok_or<E>(self, err: E) -> Result<T, E> {
|
||||
match self {
|
||||
Some(v) => Ok(v),
|
||||
|
|
@ -502,7 +502,7 @@ impl<T> Option<T> {
|
|||
/// assert_eq!(x.ok_or_else(|| 0), Err(0));
|
||||
/// ```
|
||||
#[inline]
|
||||
#[unstable(feature = "core")]
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
pub fn ok_or_else<E, F: FnOnce() -> E>(self, err: F) -> Result<T, E> {
|
||||
match self {
|
||||
Some(v) => Ok(v),
|
||||
|
|
@ -548,8 +548,7 @@ impl<T> Option<T> {
|
|||
/// assert_eq!(x.iter_mut().next(), None);
|
||||
/// ```
|
||||
#[inline]
|
||||
#[unstable(feature = "core",
|
||||
reason = "waiting for iterator conventions")]
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
pub fn iter_mut(&mut self) -> IterMut<T> {
|
||||
IterMut { inner: Item { opt: self.as_mut() } }
|
||||
}
|
||||
|
|
@ -721,13 +720,11 @@ impl<T> Option<T> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<'a, T: Clone, D: Deref<Target=T>> Option<D> {
|
||||
/// Maps an Option<D> to an Option<T> by dereffing and cloning the contents of the Option.
|
||||
/// Useful for converting an Option<&T> to an Option<T>.
|
||||
#[unstable(feature = "core",
|
||||
reason = "recently added as part of collections reform")]
|
||||
impl<'a, T: Clone> Option<&'a T> {
|
||||
/// Maps an Option<&T> to an Option<T> by cloning the contents of the Option.
|
||||
#[stable(feature = "rust1", since = "1.0.0")]
|
||||
pub fn cloned(self) -> Option<T> {
|
||||
self.map(|t| t.deref().clone())
|
||||
self.map(|t| t.clone())
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@
|
|||
//! interface for panicking is:
|
||||
//!
|
||||
//! ```ignore
|
||||
//! fn panic_impl(fmt: fmt::Arguments, &(&'static str, uint)) -> !;
|
||||
//! fn panic_impl(fmt: fmt::Arguments, &(&'static str, usize)) -> !;
|
||||
//! ```
|
||||
//!
|
||||
//! This definition allows for panicking with any general message, but it does not
|
||||
|
|
@ -58,8 +58,8 @@ pub fn panic_fmt(fmt: fmt::Arguments, file_line: &(&'static str, u32)) -> ! {
|
|||
#[allow(improper_ctypes)]
|
||||
extern {
|
||||
#[lang = "panic_fmt"]
|
||||
fn panic_impl(fmt: fmt::Arguments, file: &'static str, line: uint) -> !;
|
||||
fn panic_impl(fmt: fmt::Arguments, file: &'static str, line: usize) -> !;
|
||||
}
|
||||
let (file, line) = *file_line;
|
||||
unsafe { panic_impl(fmt, file, line as uint) }
|
||||
unsafe { panic_impl(fmt, file, line as usize) }
|
||||
}
|
||||
|
|
|
|||
|
|
@ -37,7 +37,7 @@ 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::Extend;
|
||||
pub use iter::{Iterator, DoubleEndedIterator};
|
||||
pub use iter::{ExactSizeIterator};
|
||||
pub use option::Option::{self, Some, None};
|
||||
|
|
|
|||
|
|
@ -230,6 +230,21 @@ pub unsafe fn read_and_zero<T>(dest: *mut T) -> T {
|
|||
tmp
|
||||
}
|
||||
|
||||
/// Variant of read_and_zero that writes the specific drop-flag byte
|
||||
/// (which may be more appropriate than zero).
|
||||
#[inline(always)]
|
||||
#[unstable(feature = "core",
|
||||
reason = "may play a larger role in std::ptr future extensions")]
|
||||
pub unsafe fn read_and_drop<T>(dest: *mut T) -> T {
|
||||
// Copy the data out from `dest`:
|
||||
let tmp = read(&*dest);
|
||||
|
||||
// Now mark `dest` as dropped:
|
||||
write_bytes(dest, mem::POST_DROP_U8, 1);
|
||||
|
||||
tmp
|
||||
}
|
||||
|
||||
/// Overwrites a memory location with the given value without reading or
|
||||
/// dropping the old value.
|
||||
///
|
||||
|
|
|
|||
|
|
@ -60,22 +60,22 @@
|
|||
//! that make working with it more succinct.
|
||||
//!
|
||||
//! ```
|
||||
//! let good_result: Result<int, int> = Ok(10);
|
||||
//! let bad_result: Result<int, int> = Err(10);
|
||||
//! let good_result: Result<i32, i32> = Ok(10);
|
||||
//! let bad_result: Result<i32, i32> = Err(10);
|
||||
//!
|
||||
//! // The `is_ok` and `is_err` methods do what they say.
|
||||
//! assert!(good_result.is_ok() && !good_result.is_err());
|
||||
//! assert!(bad_result.is_err() && !bad_result.is_ok());
|
||||
//!
|
||||
//! // `map` consumes the `Result` and produces another.
|
||||
//! let good_result: Result<int, int> = good_result.map(|i| i + 1);
|
||||
//! let bad_result: Result<int, int> = bad_result.map(|i| i - 1);
|
||||
//! let good_result: Result<i32, i32> = good_result.map(|i| i + 1);
|
||||
//! let bad_result: Result<i32, i32> = bad_result.map(|i| i - 1);
|
||||
//!
|
||||
//! // Use `and_then` to continue the computation.
|
||||
//! let good_result: Result<bool, int> = good_result.and_then(|i| Ok(i == 11));
|
||||
//! let good_result: Result<bool, i32> = good_result.and_then(|i| Ok(i == 11));
|
||||
//!
|
||||
//! // Use `or_else` to handle the error.
|
||||
//! let bad_result: Result<int, int> = bad_result.or_else(|i| Ok(11));
|
||||
//! let bad_result: Result<i32, i32> = bad_result.or_else(|i| Ok(11));
|
||||
//!
|
||||
//! // Consume the result and return the contents with `unwrap`.
|
||||
//! let final_awesome_result = good_result.unwrap();
|
||||
|
|
@ -92,7 +92,7 @@
|
|||
//! useful value.
|
||||
//!
|
||||
//! Consider the `write_line` method defined for I/O types
|
||||
//! by the [`Writer`](../io/trait.Writer.html) trait:
|
||||
//! by the [`Writer`](../old_io/trait.Writer.html) trait:
|
||||
//!
|
||||
//! ```
|
||||
//! # #![feature(old_io)]
|
||||
|
|
@ -182,8 +182,8 @@
|
|||
//!
|
||||
//! struct Info {
|
||||
//! name: String,
|
||||
//! age: int,
|
||||
//! rating: int
|
||||
//! age: i32,
|
||||
//! rating: i32,
|
||||
//! }
|
||||
//!
|
||||
//! fn write_info(info: &Info) -> Result<(), IoError> {
|
||||
|
|
@ -208,8 +208,8 @@
|
|||
//!
|
||||
//! struct Info {
|
||||
//! name: String,
|
||||
//! age: int,
|
||||
//! rating: int
|
||||
//! age: i32,
|
||||
//! rating: i32,
|
||||
//! }
|
||||
//!
|
||||
//! fn write_info(info: &Info) -> Result<(), IoError> {
|
||||
|
|
@ -243,8 +243,7 @@ use self::Result::{Ok, Err};
|
|||
|
||||
use clone::Clone;
|
||||
use fmt;
|
||||
use iter::{Iterator, IteratorExt, DoubleEndedIterator,
|
||||
FromIterator, ExactSizeIterator, IntoIterator};
|
||||
use iter::{Iterator, DoubleEndedIterator, FromIterator, ExactSizeIterator, IntoIterator};
|
||||
use ops::{FnMut, FnOnce};
|
||||
use option::Option::{self, None, Some};
|
||||
#[allow(deprecated)]
|
||||
|
|
@ -282,10 +281,10 @@ impl<T, E> Result<T, E> {
|
|||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// let x: Result<int, &str> = Ok(-3);
|
||||
/// let x: Result<i32, &str> = Ok(-3);
|
||||
/// assert_eq!(x.is_ok(), true);
|
||||
///
|
||||
/// let x: Result<int, &str> = Err("Some error message");
|
||||
/// let x: Result<i32, &str> = Err("Some error message");
|
||||
/// assert_eq!(x.is_ok(), false);
|
||||
/// ```
|
||||
#[inline]
|
||||
|
|
@ -302,10 +301,10 @@ impl<T, E> Result<T, E> {
|
|||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// let x: Result<int, &str> = Ok(-3);
|
||||
/// let x: Result<i32, &str> = Ok(-3);
|
||||
/// assert_eq!(x.is_err(), false);
|
||||
///
|
||||
/// let x: Result<int, &str> = Err("Some error message");
|
||||
/// let x: Result<i32, &str> = Err("Some error message");
|
||||
/// assert_eq!(x.is_err(), true);
|
||||
/// ```
|
||||
#[inline]
|
||||
|
|
@ -392,18 +391,18 @@ impl<T, E> Result<T, E> {
|
|||
/// Convert from `Result<T, E>` to `Result<&mut T, &mut E>`
|
||||
///
|
||||
/// ```
|
||||
/// fn mutate(r: &mut Result<int, int>) {
|
||||
/// fn mutate(r: &mut Result<i32, i32>) {
|
||||
/// match r.as_mut() {
|
||||
/// Ok(&mut ref mut v) => *v = 42,
|
||||
/// Err(&mut ref mut e) => *e = 0,
|
||||
/// }
|
||||
/// }
|
||||
///
|
||||
/// let mut x: Result<int, int> = Ok(2);
|
||||
/// let mut x: Result<i32, i32> = Ok(2);
|
||||
/// mutate(&mut x);
|
||||
/// assert_eq!(x.unwrap(), 42);
|
||||
///
|
||||
/// let mut x: Result<int, int> = Err(13);
|
||||
/// let mut x: Result<i32, i32> = Err(13);
|
||||
/// mutate(&mut x);
|
||||
/// assert_eq!(x.unwrap_err(), 0);
|
||||
/// ```
|
||||
|
|
@ -486,8 +485,8 @@ impl<T, E> Result<T, E> {
|
|||
/// while !buffer.is_empty() {
|
||||
/// let line: IoResult<String> = buffer.read_line();
|
||||
/// // Convert the string line to a number using `map` and `from_str`
|
||||
/// let val: IoResult<int> = line.map(|line| {
|
||||
/// line.trim_right().parse::<int>().unwrap_or(0)
|
||||
/// let val: IoResult<i32> = line.map(|line| {
|
||||
/// line.trim_right().parse::<i32>().unwrap_or(0)
|
||||
/// });
|
||||
/// // Add the value if there were no errors, otherwise add 0
|
||||
/// sum += val.unwrap_or(0);
|
||||
|
|
@ -762,7 +761,7 @@ impl<T, E: fmt::Debug> Result<T, E> {
|
|||
/// assert_eq!(x.unwrap(), 2);
|
||||
/// ```
|
||||
///
|
||||
/// ```{.should_fail}
|
||||
/// ```{.should_panic}
|
||||
/// let x: Result<u32, &str> = Err("emergency failure");
|
||||
/// x.unwrap(); // panics with `emergency failure`
|
||||
/// ```
|
||||
|
|
@ -788,7 +787,7 @@ impl<T: fmt::Debug, E> Result<T, E> {
|
|||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```{.should_fail}
|
||||
/// ```{.should_panic}
|
||||
/// let x: Result<u32, &str> = Ok(2);
|
||||
/// x.unwrap_err(); // panics with `2`
|
||||
/// ```
|
||||
|
|
|
|||
|
|
@ -88,6 +88,9 @@ pub trait SliceExt {
|
|||
fn len(&self) -> usize;
|
||||
fn is_empty(&self) -> bool { self.len() == 0 }
|
||||
fn get_mut<'a>(&'a mut self, index: usize) -> Option<&'a mut Self::Item>;
|
||||
#[unstable(feature = "core",
|
||||
reason = "will be replaced by slice syntax")]
|
||||
#[deprecated(since = "1.0.0", reason = "use &mut s[..] instead")]
|
||||
fn as_mut_slice<'a>(&'a mut self) -> &'a mut [Self::Item];
|
||||
fn iter_mut<'a>(&'a mut self) -> IterMut<'a, Self::Item>;
|
||||
fn first_mut<'a>(&'a mut self) -> Option<&'a mut Self::Item>;
|
||||
|
|
@ -261,6 +264,9 @@ impl<T> SliceExt for [T] {
|
|||
}
|
||||
|
||||
#[inline]
|
||||
#[unstable(feature = "core",
|
||||
reason = "will be replaced by slice syntax")]
|
||||
#[deprecated(since = "1.0.0", reason = "use &mut s[..] instead")]
|
||||
fn as_mut_slice(&mut self) -> &mut [T] { self }
|
||||
|
||||
#[inline]
|
||||
|
|
|
|||
|
|
@ -25,7 +25,7 @@ use default::Default;
|
|||
use error::Error;
|
||||
use fmt;
|
||||
use iter::ExactSizeIterator;
|
||||
use iter::{Map, Iterator, IteratorExt, DoubleEndedIterator};
|
||||
use iter::{Map, Iterator, DoubleEndedIterator};
|
||||
use marker::Sized;
|
||||
use mem;
|
||||
#[allow(deprecated)]
|
||||
|
|
@ -1237,7 +1237,7 @@ Section: Trait implementations
|
|||
mod traits {
|
||||
use cmp::{Ordering, Ord, PartialEq, PartialOrd, Eq};
|
||||
use cmp::Ordering::{Less, Equal, Greater};
|
||||
use iter::IteratorExt;
|
||||
use iter::Iterator;
|
||||
use option::Option;
|
||||
use option::Option::Some;
|
||||
use ops;
|
||||
|
|
@ -1616,7 +1616,7 @@ impl StrExt for str {
|
|||
#[inline]
|
||||
unsafe fn slice_unchecked(&self, begin: usize, end: usize) -> &str {
|
||||
mem::transmute(Slice {
|
||||
data: self.as_ptr().offset(begin as int),
|
||||
data: self.as_ptr().offset(begin as isize),
|
||||
len: end - begin,
|
||||
})
|
||||
}
|
||||
|
|
|
|||
|
|
@ -37,9 +37,9 @@ fn any_referenced() {
|
|||
fn any_owning() {
|
||||
let (a, b, c) = (box 5_usize as Box<Any>, box TEST as Box<Any>, box Test as Box<Any>);
|
||||
|
||||
assert!(a.is::<uint>());
|
||||
assert!(!b.is::<uint>());
|
||||
assert!(!c.is::<uint>());
|
||||
assert!(a.is::<usize>());
|
||||
assert!(!b.is::<usize>());
|
||||
assert!(!c.is::<usize>());
|
||||
|
||||
assert!(!a.is::<&'static str>());
|
||||
assert!(b.is::<&'static str>());
|
||||
|
|
@ -54,7 +54,7 @@ fn any_owning() {
|
|||
fn any_downcast_ref() {
|
||||
let a = &5_usize as &Any;
|
||||
|
||||
match a.downcast_ref::<uint>() {
|
||||
match a.downcast_ref::<usize>() {
|
||||
Some(&5) => {}
|
||||
x => panic!("Unexpected value {:?}", x)
|
||||
}
|
||||
|
|
@ -71,10 +71,10 @@ fn any_downcast_mut() {
|
|||
let mut b: Box<_> = box 7_usize;
|
||||
|
||||
let a_r = &mut a as &mut Any;
|
||||
let tmp: &mut uint = &mut *b;
|
||||
let tmp: &mut usize = &mut *b;
|
||||
let b_r = tmp as &mut Any;
|
||||
|
||||
match a_r.downcast_mut::<uint>() {
|
||||
match a_r.downcast_mut::<usize>() {
|
||||
Some(x) => {
|
||||
assert_eq!(*x, 5);
|
||||
*x = 612;
|
||||
|
|
@ -82,7 +82,7 @@ fn any_downcast_mut() {
|
|||
x => panic!("Unexpected value {:?}", x)
|
||||
}
|
||||
|
||||
match b_r.downcast_mut::<uint>() {
|
||||
match b_r.downcast_mut::<usize>() {
|
||||
Some(x) => {
|
||||
assert_eq!(*x, 7);
|
||||
*x = 413;
|
||||
|
|
@ -100,12 +100,12 @@ fn any_downcast_mut() {
|
|||
x => panic!("Unexpected value {:?}", x)
|
||||
}
|
||||
|
||||
match a_r.downcast_mut::<uint>() {
|
||||
match a_r.downcast_mut::<usize>() {
|
||||
Some(&mut 612) => {}
|
||||
x => panic!("Unexpected value {:?}", x)
|
||||
}
|
||||
|
||||
match b_r.downcast_mut::<uint>() {
|
||||
match b_r.downcast_mut::<usize>() {
|
||||
Some(&mut 413) => {}
|
||||
x => panic!("Unexpected value {:?}", x)
|
||||
}
|
||||
|
|
@ -115,8 +115,8 @@ fn any_downcast_mut() {
|
|||
fn any_fixed_vec() {
|
||||
let test = [0_usize; 8];
|
||||
let test = &test as &Any;
|
||||
assert!(test.is::<[uint; 8]>());
|
||||
assert!(!test.is::<[uint; 10]>());
|
||||
assert!(test.is::<[usize; 8]>());
|
||||
assert!(!test.is::<[usize; 10]>());
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -126,6 +126,6 @@ fn bench_downcast_ref(b: &mut Bencher) {
|
|||
let mut x = 0;
|
||||
let mut y = &mut x as &mut Any;
|
||||
test::black_box(&mut y);
|
||||
test::black_box(y.downcast_ref::<int>() == Some(&0));
|
||||
test::black_box(y.downcast_ref::<isize>() == Some(&0));
|
||||
});
|
||||
}
|
||||
|
|
|
|||
|
|
@ -134,19 +134,19 @@ fn clone_ref_updates_flag() {
|
|||
|
||||
#[test]
|
||||
fn as_unsafe_cell() {
|
||||
let c1: Cell<uint> = Cell::new(0);
|
||||
let c1: Cell<usize> = Cell::new(0);
|
||||
c1.set(1);
|
||||
assert_eq!(1, unsafe { *c1.as_unsafe_cell().get() });
|
||||
|
||||
let c2: Cell<uint> = Cell::new(0);
|
||||
let c2: Cell<usize> = Cell::new(0);
|
||||
unsafe { *c2.as_unsafe_cell().get() = 1; }
|
||||
assert_eq!(1, c2.get());
|
||||
|
||||
let r1: RefCell<uint> = RefCell::new(0);
|
||||
let r1: RefCell<usize> = RefCell::new(0);
|
||||
*r1.borrow_mut() = 1;
|
||||
assert_eq!(1, unsafe { *r1.as_unsafe_cell().get() });
|
||||
|
||||
let r2: RefCell<uint> = RefCell::new(0);
|
||||
let r2: RefCell<usize> = RefCell::new(0);
|
||||
unsafe { *r2.as_unsafe_cell().get() = 1; }
|
||||
assert_eq!(1, *r2.borrow());
|
||||
}
|
||||
|
|
|
|||
|
|
@ -114,7 +114,7 @@ fn test_user_defined_eq() {
|
|||
|
||||
// Our type.
|
||||
struct SketchyNum {
|
||||
num : int
|
||||
num : isize
|
||||
}
|
||||
|
||||
// Our implementation of `PartialEq` to support `==` and `!=`.
|
||||
|
|
|
|||
|
|
@ -211,12 +211,12 @@ mod debug_map {
|
|||
|
||||
impl fmt::Debug for Foo {
|
||||
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
|
||||
fmt.debug_map("Foo").finish()
|
||||
fmt.debug_map().finish()
|
||||
}
|
||||
}
|
||||
|
||||
assert_eq!("Foo {}", format!("{:?}", Foo));
|
||||
assert_eq!("Foo {}", format!("{:#?}", Foo));
|
||||
assert_eq!("{}", format!("{:?}", Foo));
|
||||
assert_eq!("{}", format!("{:#?}", Foo));
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
|
@ -225,15 +225,15 @@ mod debug_map {
|
|||
|
||||
impl fmt::Debug for Foo {
|
||||
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
|
||||
fmt.debug_map("Foo")
|
||||
fmt.debug_map()
|
||||
.entry(&"bar", &true)
|
||||
.finish()
|
||||
}
|
||||
}
|
||||
|
||||
assert_eq!("Foo { \"bar\": true }", format!("{:?}", Foo));
|
||||
assert_eq!("{\"bar\": true}", format!("{:?}", Foo));
|
||||
assert_eq!(
|
||||
"Foo {
|
||||
"{
|
||||
\"bar\": true
|
||||
}",
|
||||
format!("{:#?}", Foo));
|
||||
|
|
@ -245,16 +245,16 @@ mod debug_map {
|
|||
|
||||
impl fmt::Debug for Foo {
|
||||
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
|
||||
fmt.debug_map("Foo")
|
||||
fmt.debug_map()
|
||||
.entry(&"bar", &true)
|
||||
.entry(&10i32, &format_args!("{}/{}", 10i32, 20i32))
|
||||
.finish()
|
||||
}
|
||||
}
|
||||
|
||||
assert_eq!("Foo { \"bar\": true, 10: 10/20 }", format!("{:?}", Foo));
|
||||
assert_eq!("{\"bar\": true, 10: 10/20}", format!("{:?}", Foo));
|
||||
assert_eq!(
|
||||
"Foo {
|
||||
"{
|
||||
\"bar\": true,
|
||||
10: 10/20
|
||||
}",
|
||||
|
|
@ -267,7 +267,7 @@ mod debug_map {
|
|||
|
||||
impl fmt::Debug for Foo {
|
||||
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
|
||||
fmt.debug_map("Foo")
|
||||
fmt.debug_map()
|
||||
.entry(&"bar", &true)
|
||||
.entry(&10i32, &format_args!("{}/{}", 10i32, 20i32))
|
||||
.finish()
|
||||
|
|
@ -278,23 +278,23 @@ mod debug_map {
|
|||
|
||||
impl fmt::Debug for Bar {
|
||||
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
|
||||
fmt.debug_map("Bar")
|
||||
fmt.debug_map()
|
||||
.entry(&"foo", &Foo)
|
||||
.entry(&Foo, &"world")
|
||||
.finish()
|
||||
}
|
||||
}
|
||||
|
||||
assert_eq!("Bar { \"foo\": Foo { \"bar\": true, 10: 10/20 }, \
|
||||
Foo { \"bar\": true, 10: 10/20 }: \"world\" }",
|
||||
assert_eq!("{\"foo\": {\"bar\": true, 10: 10/20}, \
|
||||
{\"bar\": true, 10: 10/20}: \"world\"}",
|
||||
format!("{:?}", Bar));
|
||||
assert_eq!(
|
||||
"Bar {
|
||||
\"foo\": Foo {
|
||||
"{
|
||||
\"foo\": {
|
||||
\"bar\": true,
|
||||
10: 10/20
|
||||
},
|
||||
Foo {
|
||||
{
|
||||
\"bar\": true,
|
||||
10: 10/20
|
||||
}: \"world\"
|
||||
|
|
@ -312,12 +312,12 @@ mod debug_set {
|
|||
|
||||
impl fmt::Debug for Foo {
|
||||
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
|
||||
fmt.debug_set("Foo").finish()
|
||||
fmt.debug_set().finish()
|
||||
}
|
||||
}
|
||||
|
||||
assert_eq!("Foo {}", format!("{:?}", Foo));
|
||||
assert_eq!("Foo {}", format!("{:#?}", Foo));
|
||||
assert_eq!("{}", format!("{:?}", Foo));
|
||||
assert_eq!("{}", format!("{:#?}", Foo));
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
|
@ -326,15 +326,15 @@ mod debug_set {
|
|||
|
||||
impl fmt::Debug for Foo {
|
||||
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
|
||||
fmt.debug_set("Foo")
|
||||
fmt.debug_set()
|
||||
.entry(&true)
|
||||
.finish()
|
||||
}
|
||||
}
|
||||
|
||||
assert_eq!("Foo { true }", format!("{:?}", Foo));
|
||||
assert_eq!("{true}", format!("{:?}", Foo));
|
||||
assert_eq!(
|
||||
"Foo {
|
||||
"{
|
||||
true
|
||||
}",
|
||||
format!("{:#?}", Foo));
|
||||
|
|
@ -346,16 +346,16 @@ mod debug_set {
|
|||
|
||||
impl fmt::Debug for Foo {
|
||||
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
|
||||
fmt.debug_set("Foo")
|
||||
fmt.debug_set()
|
||||
.entry(&true)
|
||||
.entry(&format_args!("{}/{}", 10i32, 20i32))
|
||||
.finish()
|
||||
}
|
||||
}
|
||||
|
||||
assert_eq!("Foo { true, 10/20 }", format!("{:?}", Foo));
|
||||
assert_eq!("{true, 10/20}", format!("{:?}", Foo));
|
||||
assert_eq!(
|
||||
"Foo {
|
||||
"{
|
||||
true,
|
||||
10/20
|
||||
}",
|
||||
|
|
@ -368,7 +368,7 @@ mod debug_set {
|
|||
|
||||
impl fmt::Debug for Foo {
|
||||
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
|
||||
fmt.debug_set("Foo")
|
||||
fmt.debug_set()
|
||||
.entry(&true)
|
||||
.entry(&format_args!("{}/{}", 10i32, 20i32))
|
||||
.finish()
|
||||
|
|
@ -379,18 +379,18 @@ mod debug_set {
|
|||
|
||||
impl fmt::Debug for Bar {
|
||||
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
|
||||
fmt.debug_set("Bar")
|
||||
fmt.debug_set()
|
||||
.entry(&Foo)
|
||||
.entry(&"world")
|
||||
.finish()
|
||||
}
|
||||
}
|
||||
|
||||
assert_eq!("Bar { Foo { true, 10/20 }, \"world\" }",
|
||||
assert_eq!("{{true, 10/20}, \"world\"}",
|
||||
format!("{:?}", Bar));
|
||||
assert_eq!(
|
||||
"Bar {
|
||||
Foo {
|
||||
"{
|
||||
{
|
||||
true,
|
||||
10/20
|
||||
},
|
||||
|
|
@ -399,3 +399,100 @@ mod debug_set {
|
|||
format!("{:#?}", Bar));
|
||||
}
|
||||
}
|
||||
|
||||
mod debug_list {
|
||||
use std::fmt;
|
||||
|
||||
#[test]
|
||||
fn test_empty() {
|
||||
struct Foo;
|
||||
|
||||
impl fmt::Debug for Foo {
|
||||
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
|
||||
fmt.debug_list().finish()
|
||||
}
|
||||
}
|
||||
|
||||
assert_eq!("[]", format!("{:?}", Foo));
|
||||
assert_eq!("[]", format!("{:#?}", Foo));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_single() {
|
||||
struct Foo;
|
||||
|
||||
impl fmt::Debug for Foo {
|
||||
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
|
||||
fmt.debug_list()
|
||||
.entry(&true)
|
||||
.finish()
|
||||
}
|
||||
}
|
||||
|
||||
assert_eq!("[true]", format!("{:?}", Foo));
|
||||
assert_eq!(
|
||||
"[
|
||||
true
|
||||
]",
|
||||
format!("{:#?}", Foo));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_multiple() {
|
||||
struct Foo;
|
||||
|
||||
impl fmt::Debug for Foo {
|
||||
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
|
||||
fmt.debug_list()
|
||||
.entry(&true)
|
||||
.entry(&format_args!("{}/{}", 10i32, 20i32))
|
||||
.finish()
|
||||
}
|
||||
}
|
||||
|
||||
assert_eq!("[true, 10/20]", format!("{:?}", Foo));
|
||||
assert_eq!(
|
||||
"[
|
||||
true,
|
||||
10/20
|
||||
]",
|
||||
format!("{:#?}", Foo));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_nested() {
|
||||
struct Foo;
|
||||
|
||||
impl fmt::Debug for Foo {
|
||||
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
|
||||
fmt.debug_list()
|
||||
.entry(&true)
|
||||
.entry(&format_args!("{}/{}", 10i32, 20i32))
|
||||
.finish()
|
||||
}
|
||||
}
|
||||
|
||||
struct Bar;
|
||||
|
||||
impl fmt::Debug for Bar {
|
||||
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
|
||||
fmt.debug_list()
|
||||
.entry(&Foo)
|
||||
.entry(&"world")
|
||||
.finish()
|
||||
}
|
||||
}
|
||||
|
||||
assert_eq!("[[true, 10/20], \"world\"]",
|
||||
format!("{:?}", Bar));
|
||||
assert_eq!(
|
||||
"[
|
||||
[
|
||||
true,
|
||||
10/20
|
||||
],
|
||||
\"world\"
|
||||
]",
|
||||
format!("{:#?}", Bar));
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@ use test::Bencher;
|
|||
|
||||
#[test]
|
||||
fn test_lt() {
|
||||
let empty: [int; 0] = [];
|
||||
let empty: [isize; 0] = [];
|
||||
let xs = [1,2,3];
|
||||
let ys = [1,2,0];
|
||||
|
||||
|
|
@ -73,7 +73,7 @@ fn test_multi_iter() {
|
|||
#[test]
|
||||
fn test_counter_from_iter() {
|
||||
let it = count(0, 5).take(10);
|
||||
let xs: Vec<int> = FromIterator::from_iter(it);
|
||||
let xs: Vec<isize> = FromIterator::from_iter(it);
|
||||
assert_eq!(xs, [0, 5, 10, 15, 20, 25, 30, 35, 40, 45]);
|
||||
}
|
||||
|
||||
|
|
@ -104,7 +104,7 @@ fn test_iterator_chain() {
|
|||
fn test_filter_map() {
|
||||
let it = count(0, 1).take(10)
|
||||
.filter_map(|x| if x % 2 == 0 { Some(x*x) } else { None });
|
||||
assert_eq!(it.collect::<Vec<uint>>(), [0*0, 2*2, 4*4, 6*6, 8*8]);
|
||||
assert_eq!(it.collect::<Vec<usize>>(), [0*0, 2*2, 4*4, 6*6, 8*8]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
|
@ -224,8 +224,8 @@ fn test_iterator_take_short() {
|
|||
#[test]
|
||||
fn test_iterator_scan() {
|
||||
// test the type inference
|
||||
fn add(old: &mut int, new: &uint) -> Option<f64> {
|
||||
*old += *new as int;
|
||||
fn add(old: &mut isize, new: &usize) -> Option<f64> {
|
||||
*old += *new as isize;
|
||||
Some(*old as f64)
|
||||
}
|
||||
let xs = [0, 1, 2, 3, 4];
|
||||
|
|
@ -261,7 +261,7 @@ fn test_inspect() {
|
|||
let ys = xs.iter()
|
||||
.cloned()
|
||||
.inspect(|_| n += 1)
|
||||
.collect::<Vec<uint>>();
|
||||
.collect::<Vec<usize>>();
|
||||
|
||||
assert_eq!(n, xs.len());
|
||||
assert_eq!(&xs[..], &ys[..]);
|
||||
|
|
@ -269,7 +269,7 @@ fn test_inspect() {
|
|||
|
||||
#[test]
|
||||
fn test_unfoldr() {
|
||||
fn count(st: &mut uint) -> Option<uint> {
|
||||
fn count(st: &mut usize) -> Option<usize> {
|
||||
if *st < 10 {
|
||||
let ret = Some(*st);
|
||||
*st += 1;
|
||||
|
|
@ -398,14 +398,14 @@ fn test_iterator_size_hint() {
|
|||
#[test]
|
||||
fn test_collect() {
|
||||
let a = vec![1, 2, 3, 4, 5];
|
||||
let b: Vec<int> = a.iter().cloned().collect();
|
||||
let b: Vec<isize> = a.iter().cloned().collect();
|
||||
assert!(a == b);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_all() {
|
||||
// FIXME (#22405): Replace `Box::new` with `box` here when/if possible.
|
||||
let v: Box<[int]> = Box::new([1, 2, 3, 4, 5]);
|
||||
let v: Box<[isize]> = Box::new([1, 2, 3, 4, 5]);
|
||||
assert!(v.iter().all(|&x| x < 10));
|
||||
assert!(!v.iter().all(|&x| x % 2 == 0));
|
||||
assert!(!v.iter().all(|&x| x > 100));
|
||||
|
|
@ -415,7 +415,7 @@ fn test_all() {
|
|||
#[test]
|
||||
fn test_any() {
|
||||
// FIXME (#22405): Replace `Box::new` with `box` here when/if possible.
|
||||
let v: Box<[int]> = Box::new([1, 2, 3, 4, 5]);
|
||||
let v: Box<[isize]> = Box::new([1, 2, 3, 4, 5]);
|
||||
assert!(v.iter().any(|&x| x < 10));
|
||||
assert!(v.iter().any(|&x| x % 2 == 0));
|
||||
assert!(!v.iter().any(|&x| x > 100));
|
||||
|
|
@ -424,7 +424,7 @@ fn test_any() {
|
|||
|
||||
#[test]
|
||||
fn test_find() {
|
||||
let v: &[int] = &[1, 3, 9, 27, 103, 14, 11];
|
||||
let v: &[isize] = &[1, 3, 9, 27, 103, 14, 11];
|
||||
assert_eq!(*v.iter().find(|&&x| x & 1 == 0).unwrap(), 14);
|
||||
assert_eq!(*v.iter().find(|&&x| x % 3 == 0).unwrap(), 3);
|
||||
assert!(v.iter().find(|&&x| x % 12 == 0).is_none());
|
||||
|
|
@ -448,13 +448,13 @@ fn test_count() {
|
|||
|
||||
#[test]
|
||||
fn test_max_by() {
|
||||
let xs: &[int] = &[-3, 0, 1, 5, -10];
|
||||
let xs: &[isize] = &[-3, 0, 1, 5, -10];
|
||||
assert_eq!(*xs.iter().max_by(|x| x.abs()).unwrap(), -10);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_min_by() {
|
||||
let xs: &[int] = &[-3, 0, 1, 5, -10];
|
||||
let xs: &[isize] = &[-3, 0, 1, 5, -10];
|
||||
assert_eq!(*xs.iter().min_by(|x| x.abs()).unwrap(), 0);
|
||||
}
|
||||
|
||||
|
|
@ -473,7 +473,7 @@ fn test_rev() {
|
|||
let mut it = xs.iter();
|
||||
it.next();
|
||||
it.next();
|
||||
assert!(it.rev().cloned().collect::<Vec<int>>() ==
|
||||
assert!(it.rev().cloned().collect::<Vec<isize>>() ==
|
||||
vec![16, 14, 12, 10, 8, 6]);
|
||||
}
|
||||
|
||||
|
|
@ -572,8 +572,8 @@ fn test_double_ended_chain() {
|
|||
|
||||
#[test]
|
||||
fn test_rposition() {
|
||||
fn f(xy: &(int, char)) -> bool { let (_x, y) = *xy; y == 'b' }
|
||||
fn g(xy: &(int, char)) -> bool { let (_x, y) = *xy; y == 'd' }
|
||||
fn f(xy: &(isize, char)) -> bool { let (_x, y) = *xy; y == 'b' }
|
||||
fn g(xy: &(isize, char)) -> bool { let (_x, y) = *xy; y == 'd' }
|
||||
let v = [(0, 'a'), (1, 'b'), (2, 'c'), (3, 'b')];
|
||||
|
||||
assert_eq!(v.iter().rposition(f), Some(3));
|
||||
|
|
@ -598,7 +598,7 @@ fn test_rposition_panic() {
|
|||
|
||||
|
||||
#[cfg(test)]
|
||||
fn check_randacc_iter<A, T>(a: T, len: uint) where
|
||||
fn check_randacc_iter<A, T>(a: T, len: usize) where
|
||||
A: PartialEq,
|
||||
T: Clone + RandomAccessIterator + Iterator<Item=A>,
|
||||
{
|
||||
|
|
@ -684,7 +684,7 @@ fn test_random_access_zip() {
|
|||
#[test]
|
||||
fn test_random_access_take() {
|
||||
let xs = [1, 2, 3, 4, 5];
|
||||
let empty: &[int] = &[];
|
||||
let empty: &[isize] = &[];
|
||||
check_randacc_iter(xs.iter().take(3), 3);
|
||||
check_randacc_iter(xs.iter().take(20), xs.len());
|
||||
check_randacc_iter(xs.iter().take(0), 0);
|
||||
|
|
@ -694,7 +694,7 @@ fn test_random_access_take() {
|
|||
#[test]
|
||||
fn test_random_access_skip() {
|
||||
let xs = [1, 2, 3, 4, 5];
|
||||
let empty: &[int] = &[];
|
||||
let empty: &[isize] = &[];
|
||||
check_randacc_iter(xs.iter().skip(2), xs.len() - 2);
|
||||
check_randacc_iter(empty.iter().skip(2), 0);
|
||||
}
|
||||
|
|
@ -726,7 +726,7 @@ fn test_random_access_map() {
|
|||
#[test]
|
||||
fn test_random_access_cycle() {
|
||||
let xs = [1, 2, 3, 4, 5];
|
||||
let empty: &[int] = &[];
|
||||
let empty: &[isize] = &[];
|
||||
check_randacc_iter(xs.iter().cycle().take(27), 27);
|
||||
check_randacc_iter(empty.iter().cycle(), 0);
|
||||
}
|
||||
|
|
@ -755,7 +755,7 @@ fn test_range() {
|
|||
assert_eq!((200..200).rev().count(), 0);
|
||||
|
||||
assert_eq!((0..100).size_hint(), (100, Some(100)));
|
||||
// this test is only meaningful when sizeof uint < sizeof u64
|
||||
// this test is only meaningful when sizeof usize < sizeof u64
|
||||
assert_eq!((usize::MAX - 1..usize::MAX).size_hint(), (1, Some(1)));
|
||||
assert_eq!((-10..-1).size_hint(), (9, Some(9)));
|
||||
assert_eq!((-1..-10).size_hint(), (0, Some(0)));
|
||||
|
|
@ -763,34 +763,34 @@ fn test_range() {
|
|||
|
||||
#[test]
|
||||
fn test_range_inclusive() {
|
||||
assert!(range_inclusive(0, 5).collect::<Vec<int>>() ==
|
||||
assert!(range_inclusive(0, 5).collect::<Vec<isize>>() ==
|
||||
vec![0, 1, 2, 3, 4, 5]);
|
||||
assert!(range_inclusive(0, 5).rev().collect::<Vec<int>>() ==
|
||||
assert!(range_inclusive(0, 5).rev().collect::<Vec<isize>>() ==
|
||||
vec![5, 4, 3, 2, 1, 0]);
|
||||
assert_eq!(range_inclusive(200, -5).count(), 0);
|
||||
assert_eq!(range_inclusive(200, -5).rev().count(), 0);
|
||||
assert_eq!(range_inclusive(200, 200).collect::<Vec<int>>(), [200]);
|
||||
assert_eq!(range_inclusive(200, 200).rev().collect::<Vec<int>>(), [200]);
|
||||
assert_eq!(range_inclusive(200, 200).collect::<Vec<isize>>(), [200]);
|
||||
assert_eq!(range_inclusive(200, 200).rev().collect::<Vec<isize>>(), [200]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_range_step() {
|
||||
assert_eq!((0..20).step_by(5).collect::<Vec<int>>(), [0, 5, 10, 15]);
|
||||
assert_eq!((20..0).step_by(-5).collect::<Vec<int>>(), [20, 15, 10, 5]);
|
||||
assert_eq!((20..0).step_by(-6).collect::<Vec<int>>(), [20, 14, 8, 2]);
|
||||
assert_eq!((0..20).step_by(5).collect::<Vec<isize>>(), [0, 5, 10, 15]);
|
||||
assert_eq!((20..0).step_by(-5).collect::<Vec<isize>>(), [20, 15, 10, 5]);
|
||||
assert_eq!((20..0).step_by(-6).collect::<Vec<isize>>(), [20, 14, 8, 2]);
|
||||
assert_eq!((200..255).step_by(50).collect::<Vec<u8>>(), [200, 250]);
|
||||
assert_eq!((200..-5).step_by(1).collect::<Vec<int>>(), []);
|
||||
assert_eq!((200..200).step_by(1).collect::<Vec<int>>(), []);
|
||||
assert_eq!((200..-5).step_by(1).collect::<Vec<isize>>(), []);
|
||||
assert_eq!((200..200).step_by(1).collect::<Vec<isize>>(), []);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_range_step_inclusive() {
|
||||
assert_eq!(range_step_inclusive(0, 20, 5).collect::<Vec<int>>(), [0, 5, 10, 15, 20]);
|
||||
assert_eq!(range_step_inclusive(20, 0, -5).collect::<Vec<int>>(), [20, 15, 10, 5, 0]);
|
||||
assert_eq!(range_step_inclusive(20, 0, -6).collect::<Vec<int>>(), [20, 14, 8, 2]);
|
||||
assert_eq!(range_step_inclusive(0, 20, 5).collect::<Vec<isize>>(), [0, 5, 10, 15, 20]);
|
||||
assert_eq!(range_step_inclusive(20, 0, -5).collect::<Vec<isize>>(), [20, 15, 10, 5, 0]);
|
||||
assert_eq!(range_step_inclusive(20, 0, -6).collect::<Vec<isize>>(), [20, 14, 8, 2]);
|
||||
assert_eq!(range_step_inclusive(200, 255, 50).collect::<Vec<u8>>(), [200, 250]);
|
||||
assert_eq!(range_step_inclusive(200, -5, 1).collect::<Vec<int>>(), []);
|
||||
assert_eq!(range_step_inclusive(200, 200, 1).collect::<Vec<int>>(), [200]);
|
||||
assert_eq!(range_step_inclusive(200, -5, 1).collect::<Vec<isize>>(), []);
|
||||
assert_eq!(range_step_inclusive(200, 200, 1).collect::<Vec<isize>>(), [200]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
|
@ -811,7 +811,7 @@ fn test_peekable_is_empty() {
|
|||
|
||||
#[test]
|
||||
fn test_min_max() {
|
||||
let v: [int; 0] = [];
|
||||
let v: [isize; 0] = [];
|
||||
assert_eq!(v.iter().min_max(), NoElements);
|
||||
|
||||
let v = [1];
|
||||
|
|
@ -829,7 +829,7 @@ fn test_min_max() {
|
|||
|
||||
#[test]
|
||||
fn test_min_max_result() {
|
||||
let r: MinMaxResult<int> = NoElements;
|
||||
let r: MinMaxResult<isize> = NoElements;
|
||||
assert_eq!(r.into_option(), None);
|
||||
|
||||
let r = OneElement(1);
|
||||
|
|
@ -876,7 +876,7 @@ fn test_fuse() {
|
|||
|
||||
#[bench]
|
||||
fn bench_rposition(b: &mut Bencher) {
|
||||
let it: Vec<uint> = (0..300).collect();
|
||||
let it: Vec<usize> = (0..300).collect();
|
||||
b.iter(|| {
|
||||
it.iter().rposition(|&x| x <= 150);
|
||||
});
|
||||
|
|
|
|||
|
|
@ -26,6 +26,7 @@
|
|||
#![feature(debug_builders)]
|
||||
#![feature(unique)]
|
||||
#![feature(step_by)]
|
||||
#![feature(slice_patterns)]
|
||||
#![allow(deprecated)] // rand
|
||||
|
||||
extern crate core;
|
||||
|
|
|
|||
|
|
@ -21,15 +21,15 @@ fn size_of_basic() {
|
|||
#[test]
|
||||
#[cfg(target_pointer_width = "32")]
|
||||
fn size_of_32() {
|
||||
assert_eq!(size_of::<uint>(), 4);
|
||||
assert_eq!(size_of::<*const uint>(), 4);
|
||||
assert_eq!(size_of::<usize>(), 4);
|
||||
assert_eq!(size_of::<*const usize>(), 4);
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[cfg(target_pointer_width = "64")]
|
||||
fn size_of_64() {
|
||||
assert_eq!(size_of::<uint>(), 8);
|
||||
assert_eq!(size_of::<*const uint>(), 8);
|
||||
assert_eq!(size_of::<usize>(), 8);
|
||||
assert_eq!(size_of::<*const usize>(), 8);
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
|
@ -50,15 +50,15 @@ fn align_of_basic() {
|
|||
#[test]
|
||||
#[cfg(target_pointer_width = "32")]
|
||||
fn align_of_32() {
|
||||
assert_eq!(align_of::<uint>(), 4);
|
||||
assert_eq!(align_of::<*const uint>(), 4);
|
||||
assert_eq!(align_of::<usize>(), 4);
|
||||
assert_eq!(align_of::<*const usize>(), 4);
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[cfg(target_pointer_width = "64")]
|
||||
fn align_of_64() {
|
||||
assert_eq!(align_of::<uint>(), 8);
|
||||
assert_eq!(align_of::<*const uint>(), 8);
|
||||
assert_eq!(align_of::<usize>(), 8);
|
||||
assert_eq!(align_of::<*const usize>(), 8);
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
|
@ -93,12 +93,12 @@ fn test_transmute_copy() {
|
|||
#[test]
|
||||
fn test_transmute() {
|
||||
trait Foo { fn dummy(&self) { } }
|
||||
impl Foo for int {}
|
||||
impl Foo for isize {}
|
||||
|
||||
let a = box 100isize as Box<Foo>;
|
||||
unsafe {
|
||||
let x: ::core::raw::TraitObject = transmute(a);
|
||||
assert!(*(x.data as *const int) == 100);
|
||||
assert!(*(x.data as *const isize) == 100);
|
||||
let _x: Box<Foo> = transmute(x);
|
||||
}
|
||||
|
||||
|
|
@ -112,15 +112,15 @@ fn test_transmute() {
|
|||
// Static/dynamic method dispatch
|
||||
|
||||
struct Struct {
|
||||
field: int
|
||||
field: isize
|
||||
}
|
||||
|
||||
trait Trait {
|
||||
fn method(&self) -> int;
|
||||
fn method(&self) -> isize;
|
||||
}
|
||||
|
||||
impl Trait for Struct {
|
||||
fn method(&self) -> int {
|
||||
fn method(&self) -> isize {
|
||||
self.field
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -43,7 +43,7 @@ fn test_match_on_nonzero_option() {
|
|||
|
||||
#[test]
|
||||
fn test_match_option_empty_vec() {
|
||||
let a: Option<Vec<int>> = Some(vec![]);
|
||||
let a: Option<Vec<isize>> = Some(vec![]);
|
||||
match a {
|
||||
None => panic!("unexpected None while matching on Some(vec![])"),
|
||||
_ => {}
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@ use core::ops::{Range, RangeFull, RangeFrom, RangeTo};
|
|||
// Overhead of dtors
|
||||
|
||||
struct HasDtor {
|
||||
_x: int
|
||||
_x: isize
|
||||
}
|
||||
|
||||
impl Drop for HasDtor {
|
||||
|
|
|
|||
|
|
@ -17,10 +17,10 @@ use core::clone::Clone;
|
|||
fn test_get_ptr() {
|
||||
unsafe {
|
||||
let x: Box<_> = box 0;
|
||||
let addr_x: *const int = mem::transmute(&*x);
|
||||
let addr_x: *const isize = mem::transmute(&*x);
|
||||
let opt = Some(x);
|
||||
let y = opt.unwrap();
|
||||
let addr_y: *const int = mem::transmute(&*y);
|
||||
let addr_y: *const isize = mem::transmute(&*y);
|
||||
assert_eq!(addr_x, addr_y);
|
||||
}
|
||||
}
|
||||
|
|
@ -41,7 +41,7 @@ fn test_get_resource() {
|
|||
use core::cell::RefCell;
|
||||
|
||||
struct R {
|
||||
i: Rc<RefCell<int>>,
|
||||
i: Rc<RefCell<isize>>,
|
||||
}
|
||||
|
||||
#[unsafe_destructor]
|
||||
|
|
@ -53,7 +53,7 @@ fn test_get_resource() {
|
|||
}
|
||||
}
|
||||
|
||||
fn r(i: Rc<RefCell<int>>) -> R {
|
||||
fn r(i: Rc<RefCell<isize>>) -> R {
|
||||
R {
|
||||
i: i
|
||||
}
|
||||
|
|
@ -89,44 +89,44 @@ fn test_option_too_much_dance() {
|
|||
|
||||
#[test]
|
||||
fn test_and() {
|
||||
let x: Option<int> = Some(1);
|
||||
let x: Option<isize> = Some(1);
|
||||
assert_eq!(x.and(Some(2)), Some(2));
|
||||
assert_eq!(x.and(None::<int>), None);
|
||||
assert_eq!(x.and(None::<isize>), None);
|
||||
|
||||
let x: Option<int> = None;
|
||||
let x: Option<isize> = None;
|
||||
assert_eq!(x.and(Some(2)), None);
|
||||
assert_eq!(x.and(None::<int>), None);
|
||||
assert_eq!(x.and(None::<isize>), None);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_and_then() {
|
||||
let x: Option<int> = Some(1);
|
||||
let x: Option<isize> = Some(1);
|
||||
assert_eq!(x.and_then(|x| Some(x + 1)), Some(2));
|
||||
assert_eq!(x.and_then(|_| None::<int>), None);
|
||||
assert_eq!(x.and_then(|_| None::<isize>), None);
|
||||
|
||||
let x: Option<int> = None;
|
||||
let x: Option<isize> = None;
|
||||
assert_eq!(x.and_then(|x| Some(x + 1)), None);
|
||||
assert_eq!(x.and_then(|_| None::<int>), None);
|
||||
assert_eq!(x.and_then(|_| None::<isize>), None);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_or() {
|
||||
let x: Option<int> = Some(1);
|
||||
let x: Option<isize> = Some(1);
|
||||
assert_eq!(x.or(Some(2)), Some(1));
|
||||
assert_eq!(x.or(None), Some(1));
|
||||
|
||||
let x: Option<int> = None;
|
||||
let x: Option<isize> = None;
|
||||
assert_eq!(x.or(Some(2)), Some(2));
|
||||
assert_eq!(x.or(None), None);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_or_else() {
|
||||
let x: Option<int> = Some(1);
|
||||
let x: Option<isize> = Some(1);
|
||||
assert_eq!(x.or_else(|| Some(2)), Some(1));
|
||||
assert_eq!(x.or_else(|| None), Some(1));
|
||||
|
||||
let x: Option<int> = None;
|
||||
let x: Option<isize> = None;
|
||||
assert_eq!(x.or_else(|| Some(2)), Some(2));
|
||||
assert_eq!(x.or_else(|| None), None);
|
||||
}
|
||||
|
|
@ -141,7 +141,7 @@ fn test_unwrap() {
|
|||
#[test]
|
||||
#[should_panic]
|
||||
fn test_unwrap_panic1() {
|
||||
let x: Option<int> = None;
|
||||
let x: Option<isize> = None;
|
||||
x.unwrap();
|
||||
}
|
||||
|
||||
|
|
@ -154,19 +154,19 @@ fn test_unwrap_panic2() {
|
|||
|
||||
#[test]
|
||||
fn test_unwrap_or() {
|
||||
let x: Option<int> = Some(1);
|
||||
let x: Option<isize> = Some(1);
|
||||
assert_eq!(x.unwrap_or(2), 1);
|
||||
|
||||
let x: Option<int> = None;
|
||||
let x: Option<isize> = None;
|
||||
assert_eq!(x.unwrap_or(2), 2);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_unwrap_or_else() {
|
||||
let x: Option<int> = Some(1);
|
||||
let x: Option<isize> = Some(1);
|
||||
assert_eq!(x.unwrap_or_else(|| 2), 1);
|
||||
|
||||
let x: Option<int> = None;
|
||||
let x: Option<isize> = None;
|
||||
assert_eq!(x.unwrap_or_else(|| 2), 2);
|
||||
}
|
||||
|
||||
|
|
@ -223,13 +223,13 @@ fn test_ord() {
|
|||
/* FIXME(#20575)
|
||||
#[test]
|
||||
fn test_collect() {
|
||||
let v: Option<Vec<int>> = (0..0).map(|_| Some(0)).collect();
|
||||
let v: Option<Vec<isize>> = (0..0).map(|_| Some(0)).collect();
|
||||
assert!(v == Some(vec![]));
|
||||
|
||||
let v: Option<Vec<int>> = (0..3).map(|x| Some(x)).collect();
|
||||
let v: Option<Vec<isize>> = (0..3).map(|x| Some(x)).collect();
|
||||
assert!(v == Some(vec![0, 1, 2]));
|
||||
|
||||
let v: Option<Vec<int>> = (0..3).map(|x| {
|
||||
let v: Option<Vec<isize>> = (0..3).map(|x| {
|
||||
if x > 1 { None } else { Some(x) }
|
||||
}).collect();
|
||||
assert!(v == None);
|
||||
|
|
@ -258,9 +258,6 @@ fn test_cloned() {
|
|||
assert_eq!(opt_none.clone(), None);
|
||||
assert_eq!(opt_none.cloned(), None);
|
||||
|
||||
// Mutable refs work
|
||||
assert_eq!(opt_mut_ref.cloned(), Some(2u32));
|
||||
|
||||
// Immutable ref works
|
||||
assert_eq!(opt_ref.clone(), Some(&val1));
|
||||
assert_eq!(opt_ref.cloned(), Some(1u32));
|
||||
|
|
|
|||
|
|
@ -16,12 +16,12 @@ use std::iter::repeat;
|
|||
fn test() {
|
||||
unsafe {
|
||||
struct Pair {
|
||||
fst: int,
|
||||
snd: int
|
||||
fst: isize,
|
||||
snd: isize
|
||||
};
|
||||
let mut p = Pair {fst: 10, snd: 20};
|
||||
let pptr: *mut Pair = &mut p;
|
||||
let iptr: *mut int = mem::transmute(pptr);
|
||||
let iptr: *mut isize = mem::transmute(pptr);
|
||||
assert_eq!(*iptr, 10);
|
||||
*iptr = 30;
|
||||
assert_eq!(*iptr, 30);
|
||||
|
|
@ -55,13 +55,13 @@ fn test() {
|
|||
|
||||
#[test]
|
||||
fn test_is_null() {
|
||||
let p: *const int = null();
|
||||
let p: *const isize = null();
|
||||
assert!(p.is_null());
|
||||
|
||||
let q = unsafe { p.offset(1) };
|
||||
assert!(!q.is_null());
|
||||
|
||||
let mp: *mut int = null_mut();
|
||||
let mp: *mut isize = null_mut();
|
||||
assert!(mp.is_null());
|
||||
|
||||
let mq = unsafe { mp.offset(1) };
|
||||
|
|
@ -71,22 +71,22 @@ fn test_is_null() {
|
|||
#[test]
|
||||
fn test_as_ref() {
|
||||
unsafe {
|
||||
let p: *const int = null();
|
||||
let p: *const isize = null();
|
||||
assert_eq!(p.as_ref(), None);
|
||||
|
||||
let q: *const int = &2;
|
||||
let q: *const isize = &2;
|
||||
assert_eq!(q.as_ref().unwrap(), &2);
|
||||
|
||||
let p: *mut int = null_mut();
|
||||
let p: *mut isize = null_mut();
|
||||
assert_eq!(p.as_ref(), None);
|
||||
|
||||
let q: *mut int = &mut 2;
|
||||
let q: *mut isize = &mut 2;
|
||||
assert_eq!(q.as_ref().unwrap(), &2);
|
||||
|
||||
// Lifetime inference
|
||||
let u = 2isize;
|
||||
{
|
||||
let p = &u as *const int;
|
||||
let p = &u as *const isize;
|
||||
assert_eq!(p.as_ref().unwrap(), &2);
|
||||
}
|
||||
}
|
||||
|
|
@ -95,16 +95,16 @@ fn test_as_ref() {
|
|||
#[test]
|
||||
fn test_as_mut() {
|
||||
unsafe {
|
||||
let p: *mut int = null_mut();
|
||||
let p: *mut isize = null_mut();
|
||||
assert!(p.as_mut() == None);
|
||||
|
||||
let q: *mut int = &mut 2;
|
||||
let q: *mut isize = &mut 2;
|
||||
assert!(q.as_mut().unwrap() == &mut 2);
|
||||
|
||||
// Lifetime inference
|
||||
let mut u = 2isize;
|
||||
{
|
||||
let p = &mut u as *mut int;
|
||||
let p = &mut u as *mut isize;
|
||||
assert!(p.as_mut().unwrap() == &mut 2);
|
||||
}
|
||||
}
|
||||
|
|
@ -143,7 +143,7 @@ fn test_ptr_subtraction() {
|
|||
let ptr = xs.as_ptr();
|
||||
|
||||
while idx >= 0 {
|
||||
assert_eq!(*(ptr.offset(idx as int)), idx as int);
|
||||
assert_eq!(*(ptr.offset(idx as isize)), idx as isize);
|
||||
idx = idx - 1;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -8,8 +8,8 @@
|
|||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
pub fn op1() -> Result<int, &'static str> { Ok(666) }
|
||||
pub fn op2() -> Result<int, &'static str> { Err("sadface") }
|
||||
pub fn op1() -> Result<isize, &'static str> { Ok(666) }
|
||||
pub fn op2() -> Result<isize, &'static str> { Err("sadface") }
|
||||
|
||||
#[test]
|
||||
pub fn test_and() {
|
||||
|
|
@ -24,13 +24,13 @@ pub fn test_and() {
|
|||
|
||||
#[test]
|
||||
pub fn test_and_then() {
|
||||
assert_eq!(op1().and_then(|i| Ok::<int, &'static str>(i + 1)).unwrap(), 667);
|
||||
assert_eq!(op1().and_then(|_| Err::<int, &'static str>("bad")).unwrap_err(),
|
||||
assert_eq!(op1().and_then(|i| Ok::<isize, &'static str>(i + 1)).unwrap(), 667);
|
||||
assert_eq!(op1().and_then(|_| Err::<isize, &'static str>("bad")).unwrap_err(),
|
||||
"bad");
|
||||
|
||||
assert_eq!(op2().and_then(|i| Ok::<int, &'static str>(i + 1)).unwrap_err(),
|
||||
assert_eq!(op2().and_then(|i| Ok::<isize, &'static str>(i + 1)).unwrap_err(),
|
||||
"sadface");
|
||||
assert_eq!(op2().and_then(|_| Err::<int, &'static str>("bad")).unwrap_err(),
|
||||
assert_eq!(op2().and_then(|_| Err::<isize, &'static str>("bad")).unwrap_err(),
|
||||
"sadface");
|
||||
}
|
||||
|
||||
|
|
@ -45,53 +45,53 @@ pub fn test_or() {
|
|||
|
||||
#[test]
|
||||
pub fn test_or_else() {
|
||||
assert_eq!(op1().or_else(|_| Ok::<int, &'static str>(667)).unwrap(), 666);
|
||||
assert_eq!(op1().or_else(|e| Err::<int, &'static str>(e)).unwrap(), 666);
|
||||
assert_eq!(op1().or_else(|_| Ok::<isize, &'static str>(667)).unwrap(), 666);
|
||||
assert_eq!(op1().or_else(|e| Err::<isize, &'static str>(e)).unwrap(), 666);
|
||||
|
||||
assert_eq!(op2().or_else(|_| Ok::<int, &'static str>(667)).unwrap(), 667);
|
||||
assert_eq!(op2().or_else(|e| Err::<int, &'static str>(e)).unwrap_err(),
|
||||
assert_eq!(op2().or_else(|_| Ok::<isize, &'static str>(667)).unwrap(), 667);
|
||||
assert_eq!(op2().or_else(|e| Err::<isize, &'static str>(e)).unwrap_err(),
|
||||
"sadface");
|
||||
}
|
||||
|
||||
#[test]
|
||||
pub fn test_impl_map() {
|
||||
assert!(Ok::<int, int>(1).map(|x| x + 1) == Ok(2));
|
||||
assert!(Err::<int, int>(1).map(|x| x + 1) == Err(1));
|
||||
assert!(Ok::<isize, isize>(1).map(|x| x + 1) == Ok(2));
|
||||
assert!(Err::<isize, isize>(1).map(|x| x + 1) == Err(1));
|
||||
}
|
||||
|
||||
#[test]
|
||||
pub fn test_impl_map_err() {
|
||||
assert!(Ok::<int, int>(1).map_err(|x| x + 1) == Ok(1));
|
||||
assert!(Err::<int, int>(1).map_err(|x| x + 1) == Err(2));
|
||||
assert!(Ok::<isize, isize>(1).map_err(|x| x + 1) == Ok(1));
|
||||
assert!(Err::<isize, isize>(1).map_err(|x| x + 1) == Err(2));
|
||||
}
|
||||
|
||||
/* FIXME(#20575)
|
||||
#[test]
|
||||
fn test_collect() {
|
||||
let v: Result<Vec<int>, ()> = (0..0).map(|_| Ok::<int, ()>(0)).collect();
|
||||
let v: Result<Vec<isize>, ()> = (0..0).map(|_| Ok::<isize, ()>(0)).collect();
|
||||
assert!(v == Ok(vec![]));
|
||||
|
||||
let v: Result<Vec<int>, ()> = (0..3).map(|x| Ok::<int, ()>(x)).collect();
|
||||
let v: Result<Vec<isize>, ()> = (0..3).map(|x| Ok::<isize, ()>(x)).collect();
|
||||
assert!(v == Ok(vec![0, 1, 2]));
|
||||
|
||||
let v: Result<Vec<int>, int> = (0..3).map(|x| {
|
||||
let v: Result<Vec<isize>, isize> = (0..3).map(|x| {
|
||||
if x > 1 { Err(x) } else { Ok(x) }
|
||||
}).collect();
|
||||
assert!(v == Err(2));
|
||||
|
||||
// test that it does not take more elements than it needs
|
||||
let mut functions: [Box<Fn() -> Result<(), int>>; 3] =
|
||||
let mut functions: [Box<Fn() -> Result<(), isize>>; 3] =
|
||||
[box || Ok(()), box || Err(1), box || panic!()];
|
||||
|
||||
let v: Result<Vec<()>, int> = functions.iter_mut().map(|f| (*f)()).collect();
|
||||
let v: Result<Vec<()>, isize> = functions.iter_mut().map(|f| (*f)()).collect();
|
||||
assert!(v == Err(1));
|
||||
}
|
||||
*/
|
||||
|
||||
#[test]
|
||||
pub fn test_fmt_default() {
|
||||
let ok: Result<int, &'static str> = Ok(100);
|
||||
let err: Result<int, &'static str> = Err("Err");
|
||||
let ok: Result<isize, &'static str> = Ok(100);
|
||||
let err: Result<isize, &'static str> = Err("Err");
|
||||
|
||||
let s = format!("{:?}", ok);
|
||||
assert_eq!(s, "Ok(100)");
|
||||
|
|
@ -101,8 +101,8 @@ pub fn test_fmt_default() {
|
|||
|
||||
#[test]
|
||||
pub fn test_unwrap_or() {
|
||||
let ok: Result<int, &'static str> = Ok(100);
|
||||
let ok_err: Result<int, &'static str> = Err("Err");
|
||||
let ok: Result<isize, &'static str> = Ok(100);
|
||||
let ok_err: Result<isize, &'static str> = Err("Err");
|
||||
|
||||
assert_eq!(ok.unwrap_or(50), 100);
|
||||
assert_eq!(ok_err.unwrap_or(50), 50);
|
||||
|
|
@ -110,7 +110,7 @@ pub fn test_unwrap_or() {
|
|||
|
||||
#[test]
|
||||
pub fn test_unwrap_or_else() {
|
||||
fn handler(msg: &'static str) -> int {
|
||||
fn handler(msg: &'static str) -> isize {
|
||||
if msg == "I got this." {
|
||||
50
|
||||
} else {
|
||||
|
|
@ -118,8 +118,8 @@ pub fn test_unwrap_or_else() {
|
|||
}
|
||||
}
|
||||
|
||||
let ok: Result<int, &'static str> = Ok(100);
|
||||
let ok_err: Result<int, &'static str> = Err("I got this.");
|
||||
let ok: Result<isize, &'static str> = Ok(100);
|
||||
let ok_err: Result<isize, &'static str> = Err("I got this.");
|
||||
|
||||
assert_eq!(ok.unwrap_or_else(handler), 100);
|
||||
assert_eq!(ok_err.unwrap_or_else(handler), 50);
|
||||
|
|
@ -128,7 +128,7 @@ pub fn test_unwrap_or_else() {
|
|||
#[test]
|
||||
#[should_panic]
|
||||
pub fn test_unwrap_or_else_panic() {
|
||||
fn handler(msg: &'static str) -> int {
|
||||
fn handler(msg: &'static str) -> isize {
|
||||
if msg == "I got this." {
|
||||
50
|
||||
} else {
|
||||
|
|
@ -136,6 +136,6 @@ pub fn test_unwrap_or_else_panic() {
|
|||
}
|
||||
}
|
||||
|
||||
let bad_err: Result<int, &'static str> = Err("Unrecoverable mess.");
|
||||
let _ : int = bad_err.unwrap_or_else(handler);
|
||||
let bad_err: Result<isize, &'static str> = Err("Unrecoverable mess.");
|
||||
let _ : isize = bad_err.unwrap_or_else(handler);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -92,7 +92,6 @@
|
|||
html_playground_url = "http://play.rust-lang.org/")]
|
||||
|
||||
#![deny(missing_docs)]
|
||||
#![feature(int_uint)]
|
||||
#![feature(staged_api)]
|
||||
#![feature(str_words)]
|
||||
#![feature(str_char)]
|
||||
|
|
@ -311,7 +310,7 @@ impl Matches {
|
|||
}
|
||||
|
||||
/// Returns the number of times an option was matched.
|
||||
pub fn opt_count(&self, nm: &str) -> uint {
|
||||
pub fn opt_count(&self, nm: &str) -> usize {
|
||||
self.opt_vals(nm).len()
|
||||
}
|
||||
|
||||
|
|
@ -389,7 +388,7 @@ fn is_arg(arg: &str) -> bool {
|
|||
arg.len() > 1 && arg.as_bytes()[0] == b'-'
|
||||
}
|
||||
|
||||
fn find_opt(opts: &[Opt], nm: Name) -> Option<uint> {
|
||||
fn find_opt(opts: &[Opt], nm: Name) -> Option<usize> {
|
||||
// Search main options.
|
||||
let pos = opts.iter().position(|opt| opt.name == nm);
|
||||
if pos.is_some() {
|
||||
|
|
@ -587,7 +586,7 @@ pub fn getopts(args: &[String], optgrps: &[OptGroup]) -> Result {
|
|||
let opts: Vec<Opt> = optgrps.iter().map(|x| x.long_to_short()).collect();
|
||||
let n_opts = opts.len();
|
||||
|
||||
fn f(_x: uint) -> Vec<Optval> { return Vec::new(); }
|
||||
fn f(_x: usize) -> Vec<Optval> { return Vec::new(); }
|
||||
|
||||
let mut vals: Vec<_> = (0..n_opts).map(f).collect();
|
||||
let mut free: Vec<String> = Vec::new();
|
||||
|
|
@ -873,7 +872,7 @@ enum LengthLimit {
|
|||
///
|
||||
/// Panics during iteration if the string contains a non-whitespace
|
||||
/// sequence longer than the limit.
|
||||
fn each_split_within<F>(ss: &str, lim: uint, mut it: F) -> bool where
|
||||
fn each_split_within<F>(ss: &str, lim: usize, mut it: F) -> bool where
|
||||
F: FnMut(&str) -> bool
|
||||
{
|
||||
// Just for fun, let's write this as a state machine:
|
||||
|
|
@ -892,7 +891,7 @@ fn each_split_within<F>(ss: &str, lim: uint, mut it: F) -> bool where
|
|||
lim = fake_i;
|
||||
}
|
||||
|
||||
let mut machine = |cont: &mut bool, (i, c): (uint, char)| -> bool {
|
||||
let mut machine = |cont: &mut bool, (i, c): (usize, char)| -> bool {
|
||||
let whitespace = if c.is_whitespace() { Ws } else { Cr };
|
||||
let limit = if (i - slice_start + 1) <= lim { UnderLim } else { OverLim };
|
||||
|
||||
|
|
@ -954,7 +953,7 @@ fn each_split_within<F>(ss: &str, lim: uint, mut it: F) -> bool where
|
|||
|
||||
#[test]
|
||||
fn test_split_within() {
|
||||
fn t(s: &str, i: uint, u: &[String]) {
|
||||
fn t(s: &str, i: usize, u: &[String]) {
|
||||
let mut v = Vec::new();
|
||||
each_split_within(s, i, |s| { v.push(s.to_string()); true });
|
||||
assert!(v.iter().zip(u.iter()).all(|(a,b)| a == b));
|
||||
|
|
|
|||
|
|
@ -281,7 +281,6 @@
|
|||
#![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/")]
|
||||
#![feature(int_uint)]
|
||||
#![feature(collections)]
|
||||
#![feature(into_cow)]
|
||||
|
||||
|
|
|
|||
|
|
@ -307,7 +307,10 @@ pub mod types {
|
|||
#[derive(Copy)] pub struct sockaddr_storage {
|
||||
pub ss_family: sa_family_t,
|
||||
pub __ss_align: isize,
|
||||
pub __ss_pad2: [u8; 128 - 2 * (::core::isize::BYTES as usize)],
|
||||
#[cfg(target_pointer_width = "32")]
|
||||
pub __ss_pad2: [u8; 128 - 2 * 4],
|
||||
#[cfg(target_pointer_width = "64")]
|
||||
pub __ss_pad2: [u8; 128 - 2 * 8],
|
||||
}
|
||||
#[repr(C)]
|
||||
#[derive(Copy)] pub struct sockaddr_in {
|
||||
|
|
|
|||
|
|
@ -172,7 +172,6 @@
|
|||
#![feature(alloc)]
|
||||
#![feature(staged_api)]
|
||||
#![feature(box_syntax)]
|
||||
#![feature(int_uint)]
|
||||
#![feature(core)]
|
||||
#![feature(std_misc)]
|
||||
|
||||
|
|
@ -246,7 +245,7 @@ pub struct LogLevel(pub u32);
|
|||
impl fmt::Display for LogLevel {
|
||||
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
|
||||
let LogLevel(level) = *self;
|
||||
match LOG_LEVEL_NAMES.get(level as uint - 1) {
|
||||
match LOG_LEVEL_NAMES.get(level as usize - 1) {
|
||||
Some(ref name) => fmt::Display::fmt(name, fmt),
|
||||
None => fmt::Display::fmt(&level, fmt)
|
||||
}
|
||||
|
|
@ -289,7 +288,7 @@ pub fn log(level: u32, loc: &'static LogLocation, args: fmt::Arguments) {
|
|||
// is one.
|
||||
unsafe {
|
||||
let _g = LOCK.lock();
|
||||
match FILTER as uint {
|
||||
match FILTER as usize {
|
||||
0 => {}
|
||||
1 => panic!("cannot log after main thread has exited"),
|
||||
n => {
|
||||
|
|
@ -383,8 +382,8 @@ pub fn mod_enabled(level: u32, module: &str) -> bool {
|
|||
|
||||
let _g = LOCK.lock();
|
||||
unsafe {
|
||||
assert!(DIRECTIVES as uint != 0);
|
||||
assert!(DIRECTIVES as uint != 1,
|
||||
assert!(DIRECTIVES as usize != 0);
|
||||
assert!(DIRECTIVES as usize != 1,
|
||||
"cannot log after the main thread has exited");
|
||||
|
||||
enabled(level, module, (*DIRECTIVES).iter())
|
||||
|
|
|
|||
|
|
@ -15,9 +15,9 @@ use core::num::Int;
|
|||
use core::num::wrapping::WrappingOps;
|
||||
use {Rng, SeedableRng, Rand};
|
||||
|
||||
const KEY_WORDS : uint = 8; // 8 words for the 256-bit key
|
||||
const STATE_WORDS : uint = 16;
|
||||
const CHACHA_ROUNDS: uint = 20; // Cryptographically secure from 8 upwards as of this writing
|
||||
const KEY_WORDS : usize = 8; // 8 words for the 256-bit key
|
||||
const STATE_WORDS : usize = 16;
|
||||
const CHACHA_ROUNDS: usize = 20; // Cryptographically secure from 8 upwards as of this writing
|
||||
|
||||
/// A random number generator that uses the ChaCha20 algorithm [1].
|
||||
///
|
||||
|
|
@ -32,7 +32,7 @@ const CHACHA_ROUNDS: uint = 20; // Cryptographically secure from 8 upwards as of
|
|||
pub struct ChaChaRng {
|
||||
buffer: [u32; STATE_WORDS], // Internal buffer of output
|
||||
state: [u32; STATE_WORDS], // Initial state
|
||||
index: uint, // Index into state
|
||||
index: usize, // Index into state
|
||||
}
|
||||
|
||||
static EMPTY: ChaChaRng = ChaChaRng {
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue