`us` and `is` were replaced with `usize` and `isize` some time ago. Other than that, 3.5.2.1.5 is correct.
PRETTY_DEPS_pretty-rfail = $(RFAIL_TESTS)
PRETTY_DEPS_pretty-bench = $(BENCH_TESTS)
PRETTY_DEPS_pretty-pretty = $(PRETTY_TESTS)
-# The stage- and host-specific dependencies are for e.g. macro_crate_test which pulls in
-# external crates.
-PRETTY_DEPS$(1)_H_$(3)_pretty-rpass =
-PRETTY_DEPS$(1)_H_$(3)_pretty-rpass-full = $$(HLIB$(1)_H_$(3))/stamp.syntax $$(HLIB$(1)_H_$(3))/stamp.rustc
-PRETTY_DEPS$(1)_H_$(3)_pretty-rfail =
-PRETTY_DEPS$(1)_H_$(3)_pretty-bench =
-PRETTY_DEPS$(1)_H_$(3)_pretty-pretty =
PRETTY_DIRNAME_pretty-rpass = run-pass
PRETTY_DIRNAME_pretty-rpass-valgrind = run-pass-valgrind
PRETTY_DIRNAME_pretty-rpass-full = run-pass-fulldeps
PRETTY_DIRNAME_pretty-bench = bench
PRETTY_DIRNAME_pretty-pretty = pretty
+define DEF_PRETTY_FULLDEPS
+PRETTY_DEPS$(1)_T_$(2)_H_$(3)_pretty-rpass-full = $$(CSREQ$(1)_T_$(3)_H_$(3))
+endef
+
+$(foreach host,$(CFG_HOST), \
+ $(foreach target,$(CFG_TARGET), \
+ $(foreach stage,$(STAGES), \
+ $(eval $(call DEF_PRETTY_FULLDEPS,$(stage),$(target),$(host))))))
+
define DEF_RUN_PRETTY_TEST
PRETTY_ARGS$(1)-T-$(2)-H-$(3)-$(4) := \
$$(call TEST_OK_FILE,$(1),$(2),$(3),$(4)): \
$$(TEST_SREQ$(1)_T_$(2)_H_$(3)) \
$$(PRETTY_DEPS_$(4)) \
- $$(PRETTY_DEPS$(1)_H_$(3)_$(4))
+ $$(PRETTY_DEPS$(1)_T_$(2)_H_$(3)_$(4))
@$$(call E, run pretty-rpass [$(2)]: $$<)
$$(Q)touch $$@.start_time
$$(Q)$$(call CFG_RUN_CTEST_$(2),$(1),$$<,$(3)) \
fn aux_output_dir_name(config: &Config, testfile: &Path) -> PathBuf {
let f = output_base_name(config, testfile);
let mut fname = f.file_name().unwrap().to_os_string();
- fname.push("libaux");
+ fname.push(&format!(".{}.libaux", config.mode));
f.with_file_name(&fname)
}
# Notation
-Rust's grammar is defined over Unicode codepoints, each conventionally denoted
+Rust's grammar is defined over Unicode code points, each conventionally denoted
`U+XXXX`, for 4 or more hexadecimal digits `X`. _Most_ of Rust's grammar is
confined to the ASCII range of Unicode, and is described in this document by a
dialect of Extended Backus-Naur Form (EBNF), specifically a dialect of EBNF
- Square brackets are used to group rules.
- `LITERAL` is a single printable ASCII character, or an escaped hexadecimal
ASCII code of the form `\xQQ`, in single quotes, denoting the corresponding
- Unicode codepoint `U+00QQ`.
+ Unicode code point `U+00QQ`.
- `IDENTIFIER` is a nonempty string of ASCII letters and underscores.
- The `repeat` forms apply to the adjacent `element`, and are as follows:
- `?` means zero or one repetition
## Unicode productions
-A few productions in Rust's grammar permit Unicode codepoints outside the ASCII
+A few productions in Rust's grammar permit Unicode code points outside the ASCII
range. We define these productions in terms of character properties specified
-in the Unicode standard, rather than in terms of ASCII-range codepoints. The
+in the Unicode standard, rather than in terms of ASCII-range code points. The
section [Special Unicode Productions](#special-unicode-productions) lists these
productions.
## Input format
-Rust input is interpreted as a sequence of Unicode codepoints encoded in UTF-8.
+Rust input is interpreted as a sequence of Unicode code points encoded in UTF-8.
Most Rust grammar rules are defined in terms of printable ASCII-range
-codepoints, but a small number are defined in terms of Unicode properties or
-explicit codepoint lists. [^inputformat]
+code points, but a small number are defined in terms of Unicode properties or
+explicit code point lists. [^inputformat]
[^inputformat]: Substitute definitions for the special Unicode productions are
provided to the grammar verifier, restricted to ASCII range, when verifying the
sequence (`/**`), are interpreted as a special syntax for `doc`
[attributes](#attributes). That is, they are equivalent to writing
`#[doc="..."]` around the body of the comment (this includes the comment
-characters themselves, ie `/// Foo` turns into `#[doc="/// Foo"]`).
+characters themselves, i.e. `/// Foo` turns into `#[doc="/// Foo"]`).
-`//!` comments apply to the parent of the comment, rather than the item that
-follows. `//!` comments are usually used to display information on the crate
-index page.
+Line comments beginning with `//!` and block comments beginning with `/*!` are
+doc comments that apply to the parent of the comment, rather than the item
+that follows. That is, they are equivalent to writing `#![doc="..."]` around
+the body of the comment. `//!` comments are usually used to display
+information on the crate index page.
Non-doc comments are interpreted as a form of whitespace.
| fn | for | if | impl | in |
| let | loop | macro | match | mod |
| move | mut | offsetof | override | priv |
-| pub | pure | ref | return | sizeof |
-| static | self | struct | super | true |
-| trait | type | typeof | unsafe | unsized |
-| use | virtual | where | while | yield |
+| proc | pub | pure | ref | return |
+| Self | self | sizeof | static | struct |
+| super | trait | true | type | typeof |
+| unsafe | unsized | use | virtual | where |
+| while | yield | | | |
Each of these keywords has special meaning in its grammar, and all of them are
literals. An escape starts with a `U+005C` (`\`) and continues with one of the
following forms:
-* An _8-bit codepoint escape_ escape starts with `U+0078` (`x`) and is
- followed by exactly two _hex digits_. It denotes the Unicode codepoint
+* An _8-bit code point escape_ starts with `U+0078` (`x`) and is
+ followed by exactly two _hex digits_. It denotes the Unicode code point
equal to the provided hex value.
-* A _24-bit codepoint escape_ starts with `U+0075` (`u`) and is followed
+* A _24-bit code point escape_ starts with `U+0075` (`u`) and is followed
by up to six _hex digits_ surrounded by braces `U+007B` (`{`) and `U+007D`
- (`}`). It denotes the Unicode codepoint equal to the provided hex value.
+ (`}`). It denotes the Unicode code point equal to the provided hex value.
* A _whitespace escape_ is one of the characters `U+006E` (`n`), `U+0072`
- (`r`), or `U+0074` (`t`), denoting the unicode values `U+000A` (LF),
+ (`r`), or `U+0074` (`t`), denoting the Unicode values `U+000A` (LF),
`U+000D` (CR) or `U+0009` (HT) respectively.
* The _backslash escape_ is the character `U+005C` (`\`) which must be
escaped in order to denote *itself*.
literals. An escape starts with a `U+005C` (`\`) and continues with one of the
following forms:
-* An _byte escape_ escape starts with `U+0078` (`x`) and is
+* A _byte escape_ escape starts with `U+0078` (`x`) and is
followed by exactly two _hex digits_. It denotes the byte
equal to the provided hex value.
* A _whitespace escape_ is one of the characters `U+006E` (`n`), `U+0072`
only the name of a matched nonterminal comes after the dollar sign.
In both the matcher and transcriber, the Kleene star-like operator indicates
-repetition. The Kleene star operator consists of `$` and parens, optionally
+repetition. The Kleene star operator consists of `$` and parentheses, optionally
followed by a separator token, followed by `*` or `+`. `*` means zero or more
-repetitions, `+` means at least one repetition. The parens are not matched or
+repetitions, `+` means at least one repetition. The parentheses are not matched or
transcribed. On the matcher side, a name is bound to _all_ of the names it
matches, in a structure that mimics the structure of the repetition encountered
on a successful match. The job of the transcriber is to sort that structure
angle-bracket-enclosed, comma-separated list following the function name.
```{.ignore}
-fn iter<T>(seq: &[T], f: |T|) {
- for elt in seq.iter() { f(elt); }
+fn iter<T, F>(seq: &[T], f: F) where T: Copy, F: Fn(T) {
+ for elt in seq { f(*elt); }
}
-fn map<T, U>(seq: &[T], f: |T| -> U) -> Vec<U> {
+fn map<T, U, F>(seq: &[T], f: F) -> Vec<U> where T: Copy, U: Copy, F: Fn(T) -> U {
let mut acc = vec![];
- for elt in seq.iter() { acc.push(f(elt)); }
+ for elt in seq { acc.push(f(*elt)); }
acc
}
```
Inside the function signature and body, the name of the type parameter can be
-used as a type name.
+used as a type name. [Trait](#traits) bounds can be specified for type parameters
+to allow methods with that trait to be called on values of that type. This is
+specified using the `where` syntax, as in the above example.
When a generic function is referenced, its type is instantiated based on the
context of the reference. For example, calling the `iter` function defined
above on `[1, 2]` will instantiate type parameter `T` with `i32`, and require
-the closure parameter to have type `fn(i32)`.
+the closure parameter to have type `Fn(i32)`.
The type parameters can also be explicitly supplied in a trailing
[path](#paths) component after the function name. This might be necessary if
there is not sufficient context to determine the type parameters. For example,
`mem::size_of::<u32>() == 4`.
-Since a parameter type is opaque to the generic function, the set of operations
-that can be performed on it is limited. Values of parameter type can only be
-moved, not copied.
-
-```
-fn id<T>(x: T) -> T { x }
-```
-
-Similarly, [trait](#traits) bounds can be specified for type parameters to
-allow methods with that trait to be called on values of that type.
-
#### Unsafety
Unsafe operations are those that potentially violate the memory-safety
[noalias]: http://llvm.org/docs/LangRef.html#noalias
-##### Behaviour not considered unsafe
+##### Behavior not considered unsafe
-This is a list of behaviour not considered *unsafe* in Rust terms, but that may
+This is a list of behavior not considered *unsafe* in Rust terms, but that may
be undesired.
* Deadlocks
several different type constraints.
For example, the following defines the type `Point` as a synonym for the type
-`(u8, u8)`, the type of pairs of unsigned 8 bit integers.:
+`(u8, u8)`, the type of pairs of unsigned 8 bit integers:
```
type Point = (u8, u8);
}
```
-Traits also define an [object type](#object-types) with the same name as the
+Traits also define an [trait object](#trait-objects) with the same name as the
trait. Values of this type are created by [casting](#type-cast-expressions)
pointer values (pointing to a type for which an implementation of the given
trait is in scope) to pointers to the trait name, used as a type.
### Crate-only attributes
-- `crate_name` - specify the this crate's crate name.
+- `crate_name` - specify the crate's crate name.
- `crate_type` - see [linkage](#linkage).
- `feature` - see [compiler features](#compiler-features).
- `no_builtins` - disable optimizing certain code patterns to invocations of
`"unix"` or `"windows"`. The value of this configuration option is defined
as a configuration itself, like `unix` or `windows`.
* `target_os = "..."`. Operating system of the target, examples include
- `"win32"`, `"macos"`, `"linux"`, `"android"`, `"freebsd"`, `"dragonfly"`,
+ `"windows"`, `"macos"`, `"ios"`, `"linux"`, `"android"`, `"freebsd"`, `"dragonfly"`,
`"bitrig"` or `"openbsd"`.
* `target_pointer_width = "..."`. Target pointer width in bits. This is set
to `"32"` for targets with 32-bit pointers, and likewise set to `"64"` for
identifier, and a parenthesized expression-list. Method calls are resolved to
methods on specific traits, either statically dispatching to a method if the
exact `self`-type of the left-hand-side is known, or dynamically dispatching if
-the left-hand-side expression is an indirect [object type](#object-types).
+the left-hand-side expression is an indirect [trait object](#trait-objects).
### Field expressions
(["a", "b"])[10]; // panics
```
+### Range expressions
+
+```{.ebnf .gram}
+range_expr : expr ".." expr |
+ expr ".." |
+ ".." expr |
+ ".." ;
+```
+
+The `..` operator will construct an object of one of the `std::ops::Range` variants.
+
+```
+1..2; // std::ops::Range
+3..; // std::ops::RangeFrom
+..4; // std::ops::RangeTo
+..; // std::ops::RangeFull
+```
+
+The following expressions are equivalent.
+
+```
+let x = std::ops::Range {start: 0, end: 10};
+let y = 0..10;
+
+assert_eq!(x,y);
+```
+
### Unary operator expressions
Rust defines three unary operators. They are all written as prefix operators,
ten_times(|j| println!("hello, {}", j));
```
-### While loops
-
-```{.ebnf .gram}
-while_expr : [ lifetime ':' ] "while" no_struct_literal_expr '{' block '}' ;
-```
-
-A `while` loop begins by evaluating the boolean loop conditional expression.
-If the loop conditional expression evaluates to `true`, the loop body block
-executes and control returns to the loop conditional expression. If the loop
-conditional expression evaluates to `false`, the `while` expression completes.
-
-An example:
-
-```
-let mut i = 0;
-
-while i < 10 {
- println!("hello");
- i = i + 1;
-}
-```
-
### Infinite loops
A `loop` expression denotes an infinite loop.
loop_expr : [ lifetime ':' ] "loop" '{' block '}';
```
-A `loop` expression may optionally have a _label_. If a label is present, then
-labeled `break` and `continue` expressions nested within this loop may exit out
-of this loop or return control to its head. See [Break
-expressions](#break-expressions) and [Continue
+A `loop` expression may optionally have a _label_. The label is written as
+a lifetime preceding the loop expression, as in `'foo: loop{ }`. If a
+label is present, then labeled `break` and `continue` expressions nested
+within this loop may exit out of this loop or return control to its head.
+See [Break expressions](#break-expressions) and [Continue
expressions](#continue-expressions).
### Break expressions
A `break` expression has an optional _label_. If the label is absent, then
executing a `break` expression immediately terminates the innermost loop
enclosing it. It is only permitted in the body of a loop. If the label is
-present, then `break foo` terminates the loop with label `foo`, which need not
+present, then `break 'foo` terminates the loop with label `'foo`, which need not
be the innermost label enclosing the `break` expression, but must enclose it.
### Continue expressions
of the innermost loop enclosing it, returning control to the loop *head*. In
the case of a `while` loop, the head is the conditional expression controlling
the loop. In the case of a `for` loop, the head is the call-expression
-controlling the loop. If the label is present, then `continue foo` returns
-control to the head of the loop with label `foo`, which need not be the
+controlling the loop. If the label is present, then `continue 'foo` returns
+control to the head of the loop with label `'foo`, which need not be the
innermost label enclosing the `break` expression, but must enclose it.
A `continue` expression is only permitted in the body of a loop.
+### While loops
+
+```{.ebnf .gram}
+while_expr : [ lifetime ':' ] "while" no_struct_literal_expr '{' block '}' ;
+```
+
+A `while` loop begins by evaluating the boolean loop conditional expression.
+If the loop conditional expression evaluates to `true`, the loop body block
+executes and control returns to the loop conditional expression. If the loop
+conditional expression evaluates to `false`, the `while` expression completes.
+
+An example:
+
+```
+let mut i = 0;
+
+while i < 10 {
+ println!("hello");
+ i = i + 1;
+}
+```
+
+Like `loop` expressions, `while` loops can be controlled with `break` or
+`continue`, and may optionally have a _label_. See [infinite
+loops](#infinite-loops), [break expressions](#break-expressions), and
+[continue expressions](#continue-expressions) for more information.
+
### For expressions
```{.ebnf .gram}
}
```
+Like `loop` expressions, `for` loops can be controlled with `break` or
+`continue`, and may optionally have a _label_. See [infinite
+loops](#infinite-loops), [break expressions](#break-expressions), and
+[continue expressions](#continue-expressions) for more information.
+
### If expressions
```{.ebnf .gram}
UTF-32 string.
A value of type `str` is a Unicode string, represented as an array of 8-bit
-unsigned bytes holding a sequence of UTF-8 codepoints. Since `str` is of
+unsigned bytes holding a sequence of UTF-8 code points. Since `str` is of
unknown size, it is not a _first-class_ type, but can only be instantiated
through a pointer type, such as `&str` or `String`.
```
-### Object types
+### Trait objects
Every trait item (see [traits](#traits)) defines a type with the same name as
-the trait. This type is called the _object type_ of the trait. Object types
+the trait. This type is called the _trait object_ of the trait. Trait objects
permit "late binding" of methods, dispatched using _virtual method tables_
("vtables"). Whereas most calls to trait methods are "early bound" (statically
resolved) to specific implementations at compile time, a call to a method on an
-object type is only resolved to a vtable entry at compile time. The actual
+trait objects is only resolved to a vtable entry at compile time. The actual
implementation for each vtable entry can vary on an object-by-object basis.
Given a pointer-typed expression `E` of type `&T` or `Box<T>`, where `T`
implements trait `R`, casting `E` to the corresponding pointer type `&R` or
-`Box<R>` results in a value of the _object type_ `R`. This result is
+`Box<R>` results in a value of the _trait object_ `R`. This result is
represented as a pair of pointers: the vtable pointer for the `T`
implementation of `R`, and the pointer value of `E`.
-An example of an object type:
+An example of a trait object:
```
trait Printable {
}
```
-In this example, the trait `Printable` occurs as an object type in both the
+In this example, the trait `Printable` occurs as a trait object in both the
type signature of `print`, and the cast expression in `main`.
### Type parameters
* [Learn Rust](learn-rust.md)
* [Effective Rust](effective-rust.md)
* [The Stack and the Heap](the-stack-and-the-heap.md)
- * [Debug and Display](debug-and-display.md)
* [Testing](testing.md)
* [Conditional Compilation](conditional-compilation.md)
* [Documentation](documentation.md)
+++ /dev/null
-% Debug and Display
-
-Coming soon!
We can implement this shorthand, using a macro: [^actual]
[^actual]: The actual definition of `vec!` in libcollections differs from the
- one presented here, for reasons of efficiency and reusability. Some
- of these are mentioned in the [advanced macros chapter][].
+ one presented here, for reasons of efficiency and reusability.
```rust
macro_rules! vec {
The matcher `$x:expr` will match any Rust expression, binding that syntax tree
to the ‘metavariable’ `$x`. The identifier `expr` is a ‘fragment specifier’;
-the full possibilities are enumerated in the [advanced macros chapter][].
+the full possibilities are enumerated later in this chapter.
Surrounding the matcher with `$(...),*` will match zero or more expressions,
separated by commas.
be imported.
The Rust Reference has a [listing of macro-related
-attributes](../reference.html#macro--and-plugin-related-attributes).
+attributes](../reference.html#macro-related-attributes).
# The variable `$crate`
}
#[stable(feature = "rust1", since = "1.0.0")]
-impl<T: Default + Sync + Send> Default for Arc<T> {
+impl<T: Default> Default for Arc<T> {
#[stable(feature = "rust1", since = "1.0.0")]
fn default() -> Arc<T> { Arc::new(Default::default()) }
}
/// `TraitObject` is guaranteed to match layouts, but it is not the
/// type of trait objects (e.g. the fields are not directly accessible
/// on a `&SomeTrait`) nor does it control that layout (changing the
-/// definition will not change the layout of a `&SometTrait`). It is
+/// definition will not change the layout of a `&SomeTrait`). It is
/// only designed to be used by unsafe code that needs to manipulate
/// the low-level details.
///
into a variable called `op_string` while simultaneously requiring the inner
String to be moved into a variable called `s`.
+```
let x = Some("s".to_string());
match x {
op_string @ Some(s) => ...
None => ...
}
+```
See also Error 303.
"##,
referenced in the pattern guard code. Doing so however would prevent the name
from being available in the body of the match arm. Consider the following:
+```
match Some("hi".to_string()) {
Some(s) if s.len() == 0 => // use s.
...
}
+```
The variable `s` has type String, and its use in the guard is as a variable of
type String. The guard code effectively executes in a separate scope to the body
innocuous, the problem is most clear when considering functions that take their
argument by value.
+```
match Some("hi".to_string()) {
Some(s) if { drop(s); false } => (),
Some(s) => // use s.
...
}
+```
The value would be dropped in the guard then become unavailable not only in the
body of that arm but also in all subsequent arms! The solution is to bind by
You can build a free-standing crate by adding `#![no_std]` to the crate
attributes:
+```
#![feature(no_std)]
#![no_std]
+```
See also https://doc.rust-lang.org/book/no-stdlib.html
"##,
If you want to match against a `static`, consider using a guard instead:
+```
static FORTY_TWO: i32 = 42;
match Some(42) {
Some(x) if x == FORTY_TWO => ...
...
}
+```
"##,
E0161: r##"
match was succesful. If the match is irrefutable (when it cannot fail to match),
use a regular `let`-binding instead. For instance:
+```
struct Irrefutable(i32);
let irr = Irrefutable(0);
// Try this instead:
let Irrefutable(x) = irr;
foo(x);
+```
"##,
E0165: r##"
match was succesful. If the match is irrefutable (when it cannot fail to match),
use a regular `let`-binding inside a `loop` instead. For instance:
+```
struct Irrefutable(i32);
let irr = Irrefutable(0);
let Irrefutable(x) = irr;
...
}
+```
"##,
E0170: r##"
Enum variants are qualified by default. For example, given this type:
+```
enum Method {
GET,
POST
}
+```
you would match it using:
+```
match m {
Method::GET => ...
Method::POST => ...
}
+```
If you don't qualify the names, the code will bind new variables named "GET" and
"POST" instead. This behavior is likely not what you want, so rustc warns when
Qualified names are good practice, and most code works well with them. But if
you prefer them unqualified, you can import the variants into scope:
+```
use Method::*;
enum Method { GET, POST }
+```
"##,
E0267: r##"
This error indicates that the given recursion limit could not be parsed. Ensure
that the value provided is a positive integer between quotes, like so:
+```
#![recursion_limit="1000"]
+```
"##,
E0297: r##"
loop variable, consider using a `match` or `if let` inside the loop body. For
instance:
+```
// This fails because `None` is not covered.
for Some(x) in xs {
...
...
}
}
+```
"##,
E0301: r##"
exhaustive. For instance, the following would not match any arm if mutable
borrows were allowed:
+```
match Some(()) {
None => { },
option if option.take().is_none() => { /* impossible, option is `Some` */ },
Some(_) => { } // When the previous match failed, the option became `None`.
}
+```
"##,
E0302: r##"
exhaustive. For instance, the following would not match any arm if assignments
were allowed:
+```
match Some(()) {
None => { },
option if { option = None; false } { },
Some(_) => { } // When the previous match failed, the option became `None`.
}
+```
"##,
E0303: r##"
Updates to the borrow checker in a future version of Rust may remove this
restriction, but for now patterns must be rewritten without sub-bindings.
-// Before.
-match Some("hi".to_string()) {
- ref op_string_ref @ Some(ref s) => ...
+```
+// Code like this...
+match Some(5) {
+ ref op_num @ Some(num) => ...
None => ...
}
}
None => ...
}
+```
The `op_string_ref` binding has type &Option<&String> in both cases.
obligation.repr(self.tcx()));
self.infcx.probe(|snapshot| {
- let (skol_obligation_trait_ref, skol_map) =
- self.infcx().skolemize_late_bound_regions(&obligation.predicate, snapshot);
- match self.match_impl(impl_def_id, obligation, snapshot,
- &skol_map, skol_obligation_trait_ref.trait_ref.clone()) {
- Ok(substs) => {
+ match self.match_impl(impl_def_id, obligation, snapshot) {
+ Ok((substs, skol_map)) => {
let vtable_impl = self.vtable_impl(impl_def_id,
substs,
obligation.cause.clone(),
let all_impls = self.all_impls(def_id);
for &impl_def_id in &all_impls {
self.infcx.probe(|snapshot| {
- let (skol_obligation_trait_pred, skol_map) =
- self.infcx().skolemize_late_bound_regions(&obligation.predicate, snapshot);
- match self.match_impl(impl_def_id, obligation, snapshot,
- &skol_map, skol_obligation_trait_pred.trait_ref.clone()) {
+ match self.match_impl(impl_def_id, obligation, snapshot) {
Ok(_) => {
candidates.vec.push(ImplCandidate(impl_def_id));
}
// First, create the substitutions by matching the impl again,
// this time not in a probe.
self.infcx.commit_if_ok(|snapshot| {
- let (skol_obligation_trait_ref, skol_map) =
- self.infcx().skolemize_late_bound_regions(&obligation.predicate, snapshot);
- let substs =
+ let (substs, skol_map) =
self.rematch_impl(impl_def_id, obligation,
- snapshot, &skol_map, skol_obligation_trait_ref.trait_ref);
+ snapshot);
debug!("confirm_impl_candidate substs={}", substs.repr(self.tcx()));
Ok(self.vtable_impl(impl_def_id, substs, obligation.cause.clone(),
obligation.recursion_depth + 1, skol_map, snapshot))
fn rematch_impl(&mut self,
impl_def_id: ast::DefId,
obligation: &TraitObligation<'tcx>,
- snapshot: &infer::CombinedSnapshot,
- skol_map: &infer::SkolemizationMap,
- skol_obligation_trait_ref: Rc<ty::TraitRef<'tcx>>)
- -> Normalized<'tcx, Substs<'tcx>>
+ snapshot: &infer::CombinedSnapshot)
+ -> (Normalized<'tcx, Substs<'tcx>>, infer::SkolemizationMap)
{
- match self.match_impl(impl_def_id, obligation, snapshot,
- skol_map, skol_obligation_trait_ref) {
- Ok(substs) => substs,
+ match self.match_impl(impl_def_id, obligation, snapshot) {
+ Ok((substs, skol_map)) => (substs, skol_map),
Err(()) => {
self.tcx().sess.bug(
&format!("Impl {} was matchable against {} but now is not",
fn match_impl(&mut self,
impl_def_id: ast::DefId,
obligation: &TraitObligation<'tcx>,
- snapshot: &infer::CombinedSnapshot,
- skol_map: &infer::SkolemizationMap,
- skol_obligation_trait_ref: Rc<ty::TraitRef<'tcx>>)
- -> Result<Normalized<'tcx, Substs<'tcx>>, ()>
+ snapshot: &infer::CombinedSnapshot)
+ -> Result<(Normalized<'tcx, Substs<'tcx>>,
+ infer::SkolemizationMap), ()>
{
let impl_trait_ref = ty::impl_trait_ref(self.tcx(), impl_def_id).unwrap();
return Err(());
}
+ let (skol_obligation, skol_map) = self.infcx().skolemize_late_bound_regions(
+ &obligation.predicate,
+ snapshot);
+ let skol_obligation_trait_ref = skol_obligation.trait_ref;
+
let impl_substs = util::fresh_type_vars_for_impl(self.infcx,
obligation.cause.span,
impl_def_id);
return Err(());
}
- if let Err(e) = self.infcx.leak_check(skol_map, snapshot) {
+ if let Err(e) = self.infcx.leak_check(&skol_map, snapshot) {
debug!("match_impl: failed leak check due to `{}`",
ty::type_err_to_str(self.tcx(), &e));
return Err(());
}
debug!("match_impl: success impl_substs={}", impl_substs.repr(self.tcx()));
- Ok(Normalized {
+ Ok((Normalized {
value: impl_substs,
obligations: impl_trait_ref.obligations
- })
+ }, skol_map))
}
fn fast_reject_trait_refs(&mut self,
try!(write!(fmt, "<span class='out-of-band'>"));
try!(write!(fmt,
r##"<span id='render-detail'>
- <a id="collapse-all" href="#">[-]</a> <a id="expand-all" href="#">[+]</a>
+ <a id="toggle-all-docs" href="#" title="collapse all docs">[-]</a>
</span>"##));
// Write `src` tag
match self.href(self.cx) {
Some(l) => {
try!(write!(fmt, "<a id='src-{}' class='srclink' \
- href='{}'>[src]</a>",
- self.item.def_id.node, l));
+ href='{}' title='{}'>[src]</a>",
+ self.item.def_id.node, l, "goto source code"));
}
None => {}
}
window.location = $('.srclink').attr('href');
}
- $("#expand-all").on("click", function() {
- $(".docblock").show();
- $(".toggle-label").hide();
- $(".toggle-wrapper").removeClass("collapsed");
- $(".collapse-toggle").children(".inner").html("-");
- });
-
- $("#collapse-all").on("click", function() {
- $(".docblock").hide();
- $(".toggle-label").show();
- $(".toggle-wrapper").addClass("collapsed");
- $(".collapse-toggle").children(".inner").html("+");
+ $("#toggle-all-docs").on("click", function() {
+ var toggle = $("#toggle-all-docs");
+ if (toggle.html() == "[-]") {
+ toggle.html("[+]");
+ toggle.attr("title", "expand all docs");
+ $(".docblock").hide();
+ $(".toggle-label").show();
+ $(".toggle-wrapper").addClass("collapsed");
+ $(".collapse-toggle").children(".inner").html("+");
+ } else {
+ toggle.html("[-]");
+ toggle.attr("title", "collapse all docs");
+ $(".docblock").show();
+ $(".toggle-label").hide();
+ $(".toggle-wrapper").removeClass("collapsed");
+ $(".collapse-toggle").children(".inner").html("-");
+ }
});
$(document).on("click", ".collapse-toggle", function() {
var toggle = $(this);
var relatedDoc = toggle.parent().next();
+ if (relatedDoc.is(".stability")) {
+ relatedDoc = relatedDoc.next();
+ }
if (relatedDoc.is(".docblock")) {
if (relatedDoc.is(":visible")) {
relatedDoc.slideUp({duration:'fast', easing:'linear'});
.html("[<span class='inner'>-</span>]");
$(".method").each(function() {
- if ($(this).next().is(".docblock")) {
- $(this).children().first().after(toggle.clone());
- }
+ if ($(this).next().is(".docblock") ||
+ ($(this).next().is(".stability") && $(this).next().next().is(".docblock"))) {
+ $(this).children().first().after(toggle.clone());
+ }
});
var mainToggle =
}
impl DynamicLibrary {
- // FIXME (#12938): Until DST lands, we cannot decompose &str into
- // & and str, so we cannot usefully take ToCStr arguments by
- // reference (without forcing an additional & around &str). So we
- // are instead temporarily adding an instance for &Path, so that
- // we can take ToCStr as owned. When DST lands, the &Path instance
- // should be removed, and arguments bound by ToCStr should be
- // passed by reference. (Here: in the `open` method.)
-
/// Lazily open a dynamic library. When passed None it gives a
/// handle to the calling process
pub fn open(filename: Option<&Path>) -> Result<DynamicLibrary, String> {
///
/// This handle implements the `Read` trait, but beware that concurrent reads
/// of `Stdin` must be executed with care.
+///
+/// Created by the function `io::stdin()`.
#[stable(feature = "rust1", since = "1.0.0")]
pub struct Stdin {
inner: Arc<Mutex<BufReader<StdinRaw>>>,
/// Each handle shares a global buffer of data to be written to the standard
/// output stream. Access is also synchronized via a lock and explicit control
/// over locking is available via the `lock` method.
+///
+/// Created by the function `io::stdout()`.
#[stable(feature = "rust1", since = "1.0.0")]
pub struct Stdout {
// FIXME: this should be LineWriter or BufWriter depending on the state of
rx: &'a Receiver<T>
}
+/// An owning iterator over messages on a receiver, this iterator will block
+/// whenever `next` is called, waiting for a new message, and `None` will be
+/// returned when the corresponding channel has hung up.
+#[stable(feature = "receiver_into_iter", since = "1.1.0")]
+pub struct IntoIter<T> {
+ rx: Receiver<T>
+}
+
/// The sending-half of Rust's asynchronous channel type. This half can only be
/// owned by one task, but it can be cloned to send to other tasks.
#[stable(feature = "rust1", since = "1.0.0")]
fn next(&mut self) -> Option<T> { self.rx.recv().ok() }
}
+#[stable(feature = "receiver_into_iter", since = "1.1.0")]
+impl<'a, T> IntoIterator for &'a Receiver<T> {
+ type Item = T;
+ type IntoIter = Iter<'a, T>;
+
+ fn into_iter(self) -> Iter<'a, T> { self.iter() }
+}
+
+impl<T> Iterator for IntoIter<T> {
+ type Item = T;
+ fn next(&mut self) -> Option<T> { self.rx.recv().ok() }
+}
+
+#[stable(feature = "receiver_into_iter", since = "1.1.0")]
+impl <T> IntoIterator for Receiver<T> {
+ type Item = T;
+ type IntoIter = IntoIter<T>;
+
+ fn into_iter(self) -> IntoIter<T> {
+ IntoIter { rx: self }
+ }
+}
+
#[unsafe_destructor]
#[stable(feature = "rust1", since = "1.0.0")]
impl<T> Drop for Receiver<T> {
assert_eq!(count_rx.recv().unwrap(), 4);
}
+ #[test]
+ fn test_recv_into_iter_owned() {
+ let mut iter = {
+ let (tx, rx) = channel::<i32>();
+ tx.send(1).unwrap();
+ tx.send(2).unwrap();
+
+ rx.into_iter()
+ };
+ assert_eq!(iter.next().unwrap(), 1);
+ assert_eq!(iter.next().unwrap(), 2);
+ assert_eq!(iter.next().is_none(), true);
+ }
+
+ #[test]
+ fn test_recv_into_iter_borrowed() {
+ let (tx, rx) = channel::<i32>();
+ tx.send(1).unwrap();
+ tx.send(2).unwrap();
+ drop(tx);
+ let mut iter = (&rx).into_iter();
+ assert_eq!(iter.next().unwrap(), 1);
+ assert_eq!(iter.next().unwrap(), 2);
+ assert_eq!(iter.next().is_none(), true);
+ }
+
#[test]
fn try_recv_states() {
let (tx1, rx1) = channel::<i32>();
&token::CloseDelim(token::Brace),
seq_sep_none(),
|p| {
- let lo = p.span.lo;
let mut attrs = p.parse_outer_attributes();
+ let lo = p.span.lo;
let (name, node) = if try!(p.eat_keyword(keywords::Type)) {
let TyParam {ident, bounds, default, ..} = try!(p.parse_ty_param());
}
}
- let lo = self.span.lo;
let attrs = self.parse_outer_attributes();
+ let lo = self.span.lo;
Ok(Some(if self.check_keyword(keywords::Let) {
check_expected_item(self, &attrs);
/// Parse an impl item.
pub fn parse_impl_item(&mut self) -> PResult<P<ImplItem>> {
- let lo = self.span.lo;
let mut attrs = self.parse_outer_attributes();
+ let lo = self.span.lo;
let vis = try!(self.parse_visibility());
let (name, node) = if try!(self.eat_keyword(keywords::Type)) {
let name = try!(self.parse_ident());
/// Parse a foreign item.
fn parse_foreign_item(&mut self) -> PResult<Option<P<ForeignItem>>> {
- let lo = self.span.lo;
-
let attrs = self.parse_outer_attributes();
+ let lo = self.span.lo;
let visibility = try!(self.parse_visibility());
if self.check_keyword(keywords::Static) {
// aux-build:rlib_crate_test.rs
// ignore-stage1
// ignore-tidy-linelength
-// ignore-android
// ignore-cross-compile gives a different error message
#![feature(plugin)]
# on some platforms, but LLVM just prints a warning so that's fine for
# now.
$(1): simd.rs
- $$(RUSTC) --target=$(1) --emit=llvm-ir,asm simd.rs -C target-feature='+neon,+sse2'
+ $$(RUSTC) --target=$(1) --emit=llvm-ir,asm simd.rs \
+ -C target-feature='+neon,+sse2' -C extra-filename=-$(1)
endef
$(foreach targetxxx,$(TARGETS),$(eval $(call MK_TARGETS,$(targetxxx))))
// Test that the CompilerCalls interface to the compiler works.
-// ignore-android
+// ignore-cross-compile
#![feature(rustc_private, path)]
#![feature(core)]
// option. This file may not be copied, modified, or distributed
// except according to those terms.
-// ignore-android
+// ignore-cross-compile
#![feature(rustc_private)]
// except according to those terms.
// no-prefer-dynamic
-// ignore-android
+// ignore-cross-compile
#![feature(rustc_private)]
// except according to those terms.
// ignore-pretty
-// ignore-android
+// ignore-cross-compile
#![feature(quote, rustc_private)]
// option. This file may not be copied, modified, or distributed
// except according to those terms.
-// ignore-android
+// ignore-cross-compile
// ignore-pretty: does not work well with `--test`
#![feature(quote, rustc_private)]
// option. This file may not be copied, modified, or distributed
// except according to those terms.
+// ignore-cross-compile
// ignore-pretty
// ignore-test
// option. This file may not be copied, modified, or distributed
// except according to those terms.
-// ignore-android
+// ignore-cross-compile
// ignore-pretty: does not work well with `--test`
#![feature(quote, rustc_private)]
// option. This file may not be copied, modified, or distributed
// except according to those terms.
-// ignore-android
+// ignore-cross-compile
// ignore-pretty: does not work well with `--test`
#![feature(quote, rustc_private)]
// This test can't be a unit test in std,
// because it needs TempDir, which is in extra
-// ignore-android
+// ignore-cross-compile
#![feature(rustc_private, path_ext)]
// except according to those terms.
// aux-build:rustdoc-default-impl.rs
-// ignore-android
+// ignore-cross-compile
extern crate rustdoc_default_impl as foo;
// except according to those terms.
// aux-build:rustdoc-extern-default-method.rs
-// ignore-android
+// ignore-cross-compile
extern crate rustdoc_extern_default_method as ext;
// except according to those terms.
// aux-build:rustdoc-extern-method.rs
-// ignore-android
+// ignore-cross-compile
#![feature(unboxed_closures)]
// except according to those terms.
// aux-build:rustdoc-ffi.rs
-// ignore-android
+// ignore-cross-compile
extern crate rustdoc_ffi as lib;
// except according to those terms.
// aux-build:inline-default-methods.rs
-// ignore-android
+// ignore-cross-compile
extern crate inline_default_methods;
// except according to those terms.
// aux-build:issue-13698.rs
-// ignore-android
+// ignore-cross-compile
extern crate issue_13698;
// except according to those terms.
// aux-build:issue-15318.rs
-// ignore-android
+// ignore-cross-compile
extern crate issue_15318;
// except according to those terms.
// aux-build:issue-15318.rs
-// ignore-android
+// ignore-cross-compile
#![feature(no_std)]
#![no_std]
// except according to those terms.
// aux-build:issue-17476.rs
-// ignore-android
+// ignore-cross-compile
extern crate issue_17476;
// except according to those terms.
// aux-build:issue-19190-3.rs
-// ignore-android
+// ignore-cross-compile
extern crate issue_19190_3;
// except according to those terms.
// aux-build:issue-20646.rs
-// ignore-android
+// ignore-cross-compile
#![feature(associated_types)]
// except according to those terms.
// aux-build:issue-20727.rs
-// ignore-android
+// ignore-cross-compile
extern crate issue_20727;
// except according to those terms.
// aux-build:issue-20727.rs
-// ignore-android
+// ignore-cross-compile
extern crate issue_20727;
// except according to those terms.
// aux-build:issue-20727.rs
-// ignore-android
+// ignore-cross-compile
extern crate issue_20727;
// except according to those terms.
// aux-build:issue-20727.rs
-// ignore-android
+// ignore-cross-compile
extern crate issue_20727;
// except according to those terms.
// aux-build:issue-21092.rs
-// ignore-android
+// ignore-cross-compile
extern crate issue_21092;
// except according to those terms.
// aux-build:issue-21801.rs
-// ignore-android
+// ignore-cross-compile
extern crate issue_21801;
// except according to those terms.
// aux-build:issue-22025.rs
-// ignore-android
+// ignore-cross-compile
extern crate issue_22025;
// aux-build:issue-23207-1.rs
// aux-build:issue-23207-2.rs
-// ignore-android
+// ignore-cross-compile
extern crate issue_23207_2;