Rollup merge of #23855 - tshepang:doc-nit, r=Manishearth

This commit is contained in:
Manish Goregaokar 2015-03-30 20:18:16 +05:30
commit 3b45470100
1658 changed files with 7917 additions and 7765 deletions

View file

@ -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>

View file

@ -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)]

View file

@ -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) == '|' {

View file

@ -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;
}

View file

@ -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);
}

View file

@ -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();

View file

@ -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 {

View file

@ -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 &mdash; once it has been spawned &mdash; 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 &mdash;
when a message arrives at a sender, or a buffer opens to receive a message
&mdash; 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

View file

@ -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.

View file

@ -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)

View file

@ -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

View file

@ -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.

View file

@ -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.

View file

@ -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

View file

@ -352,7 +352,7 @@ Heres an example of documenting a macro:
/// # }
/// ```
///
/// ```should_fail
/// ```should_panic
/// # #[macro_use] extern crate foo;
/// # fn main() {
/// panic_unless!(true == false, “Im 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;

View file

@ -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);
}
```

View 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.

View file

@ -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
```

View 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.

View 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
View 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.

View file

@ -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);

View file

@ -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

View file

@ -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
View 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.

View file

@ -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"];

View file

@ -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

View file

@ -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));
}
```

View file

@ -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

View 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.

View file

@ -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!"

View file

@ -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
View file

@ -0,0 +1 @@
% Unstable Rust

View file

@ -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

View file

@ -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))]

View file

@ -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.

View file

@ -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()
}
}

View file

@ -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;

View file

@ -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()
}
}

View file

@ -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

View file

@ -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;

View file

@ -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)
}

View file

@ -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;

View file

@ -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

View file

@ -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;

View file

@ -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;

View file

@ -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] {

View file

@ -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) }
}
}

View file

@ -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 {

View file

@ -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

View file

@ -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 {

View file

@ -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:

View file

@ -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()
}
}

View file

@ -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;

View file

@ -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.

View file

@ -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);

View file

@ -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")]

View file

@ -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)]

View file

@ -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)"),

View file

@ -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

View file

@ -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")]

View file

@ -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")]

View file

@ -12,6 +12,5 @@
#![stable(feature = "rust1", since = "1.0.0")]
#![doc(primitive = "i16")]
#![allow(trivial_numeric_casts)]
int_module! { i16, 16 }

View file

@ -12,6 +12,5 @@
#![stable(feature = "rust1", since = "1.0.0")]
#![doc(primitive = "i32")]
#![allow(trivial_numeric_casts)]
int_module! { i32, 32 }

View file

@ -12,6 +12,5 @@
#![stable(feature = "rust1", since = "1.0.0")]
#![doc(primitive = "i64")]
#![allow(trivial_numeric_casts)]
int_module! { i64, 64 }

View file

@ -12,6 +12,5 @@
#![stable(feature = "rust1", since = "1.0.0")]
#![doc(primitive = "i8")]
#![allow(trivial_numeric_casts)]
int_module! { i8, 8 }

View file

@ -9,7 +9,6 @@
// except according to those terms.
#![doc(hidden)]
#![allow(trivial_numeric_casts)]
macro_rules! int_module { ($T:ty, $bits:expr) => (

View file

@ -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 }

View file

@ -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 }),
};

View file

@ -12,6 +12,5 @@
#![stable(feature = "rust1", since = "1.0.0")]
#![doc(primitive = "u16")]
#![allow(trivial_numeric_casts)]
uint_module! { u16, i16, 16 }

View file

@ -12,6 +12,5 @@
#![stable(feature = "rust1", since = "1.0.0")]
#![doc(primitive = "u32")]
#![allow(trivial_numeric_casts)]
uint_module! { u32, i32, 32 }

View file

@ -12,6 +12,5 @@
#![stable(feature = "rust1", since = "1.0.0")]
#![doc(primitive = "u64")]
#![allow(trivial_numeric_casts)]
uint_module! { u64, i64, 64 }

View file

@ -12,6 +12,5 @@
#![stable(feature = "rust1", since = "1.0.0")]
#![doc(primitive = "u8")]
#![allow(trivial_numeric_casts)]
uint_module! { u8, i8, 8 }

View file

@ -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) => (

View file

@ -16,6 +16,5 @@
#![stable(feature = "rust1", since = "1.0.0")]
#![doc(primitive = "usize")]
#![allow(trivial_numeric_casts)]
uint_module! { usize, isize, ::isize::BITS }

View file

@ -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)
}
}

View file

@ -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())
}
}

View file

@ -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) }
}

View file

@ -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};

View file

@ -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.
///

View file

@ -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`
/// ```

View file

@ -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]

View file

@ -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,
})
}

View file

@ -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));
});
}

View file

@ -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());
}

View file

@ -114,7 +114,7 @@ fn test_user_defined_eq() {
// Our type.
struct SketchyNum {
num : int
num : isize
}
// Our implementation of `PartialEq` to support `==` and `!=`.

View file

@ -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));
}
}

View file

@ -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);
});

View file

@ -26,6 +26,7 @@
#![feature(debug_builders)]
#![feature(unique)]
#![feature(step_by)]
#![feature(slice_patterns)]
#![allow(deprecated)] // rand
extern crate core;

View file

@ -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
}
}

View file

@ -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![])"),
_ => {}

View file

@ -14,7 +14,7 @@ use core::ops::{Range, RangeFull, RangeFrom, RangeTo};
// Overhead of dtors
struct HasDtor {
_x: int
_x: isize
}
impl Drop for HasDtor {

View file

@ -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));

View file

@ -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;
}

View file

@ -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);
}

View file

@ -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));

View file

@ -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)]

View file

@ -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 {

View file

@ -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())

View file

@ -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