diff --git a/configure b/configure
index fc8d57999ffde..a83b9e6bed7bc 100755
--- a/configure
+++ b/configure
@@ -759,6 +759,15 @@ then
fi
fi
+# By default the test suite *requires* valgrind. Detect its absence.
+if [ -z "$CFG_VALGRIND" ]
+then
+ if [ ! -z "$CFG_ENABLE_VALGRIND" ] || [ -z "$CFG_DISABLE_VALGRIND_RPASS" ]
+ then
+ err "valgrind not found, but needed. consider adding --disable-valgrind-rpass"
+ fi
+fi
+
step_msg "looking for target specific programs"
probe CFG_ADB adb
diff --git a/src/doc/grammar.md b/src/doc/grammar.md
index 3d9a5bafbd71e..542815e7afe3c 100644
--- a/src/doc/grammar.md
+++ b/src/doc/grammar.md
@@ -152,19 +152,19 @@ token : simple_token | ident | literal | symbol | whitespace token ;
-| | | | | |
-|----------|----------|----------|----------|--------|
-| abstract | alignof | as | become | box |
-| break | const | continue | crate | do |
-| else | enum | extern | false | final |
-| fn | for | if | impl | in |
-| let | loop | match | mod | move |
-| mut | offsetof | once | override | priv |
-| proc | pub | pure | ref | return |
-| sizeof | static | self | struct | super |
-| true | trait | type | typeof | unsafe |
-| unsized | use | virtual | where | while |
-| yield | | | | |
+| | | | | |
+|----------|----------|----------|----------|---------|
+| abstract | alignof | as | become | box |
+| break | const | continue | crate | do |
+| else | enum | extern | false | final |
+| fn | for | if | impl | in |
+| let | loop | macro | match | mod |
+| move | mut | offsetof | override | priv |
+| 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
@@ -524,6 +524,15 @@ array_elems : [expr [',' expr]*] | [expr ',' ".." expr] ;
idx_expr : expr '[' expr ']' ;
```
+### Range expressions
+
+```antlr
+range_expr : expr ".." expr |
+ expr ".." |
+ ".." expr |
+ ".." ;
+```
+
### Unary operator expressions
**FIXME:** grammar?
@@ -610,7 +619,7 @@ lambda_expr : '|' ident_list '|' expr ;
### While loops
```antlr
-while_expr : "while" no_struct_literal_expr '{' block '}' ;
+while_expr : [ lifetime ':' ] "while" no_struct_literal_expr '{' block '}' ;
```
### Infinite loops
@@ -634,7 +643,7 @@ continue_expr : "continue" [ lifetime ];
### For expressions
```antlr
-for_expr : "for" pat "in" no_struct_literal_expr '{' block '}' ;
+for_expr : [ lifetime ':' ] "for" pat "in" no_struct_literal_expr '{' block '}' ;
```
### If expressions
diff --git a/src/doc/reference.md b/src/doc/reference.md
index f5a4f12e5faee..059da89192576 100644
--- a/src/doc/reference.md
+++ b/src/doc/reference.md
@@ -29,41 +29,6 @@ You may also be interested in the [grammar].
# Notation
-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
-supported by common automated LL(k) parsing tools such as `llgen`, rather than
-the dialect given in ISO 14977. The dialect can be defined self-referentially
-as follows:
-
-```{.ebnf .notation}
-grammar : rule + ;
-rule : nonterminal ':' productionrule ';' ;
-productionrule : production [ '|' production ] * ;
-production : term * ;
-term : element repeats ;
-element : LITERAL | IDENTIFIER | '[' productionrule ']' ;
-repeats : [ '*' | '+' ] NUMBER ? | NUMBER ? | '?' ;
-```
-
-Where:
-
-- Whitespace in the grammar is ignored.
-- 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 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
- - `*` means zero or more repetitions
- - `+` means one or more repetitions
- - NUMBER trailing a repeat symbol gives a maximum repetition count
- - NUMBER on its own gives an exact repetition count
-
-This EBNF dialect should hopefully be familiar to many readers.
-
## Unicode productions
A few productions in Rust's grammar permit Unicode code points outside the ASCII
@@ -132,13 +97,6 @@ Some productions are defined by exclusion of particular Unicode characters:
## Comments
-```{.ebnf .gram}
-comment : block_comment | line_comment ;
-block_comment : "/*" block_comment_body * "*/" ;
-block_comment_body : [block_comment | character] * ;
-line_comment : "//" non_eol * ;
-```
-
Comments in Rust code follow the general C++ style of line and block-comment
forms. Nested block comments are supported.
@@ -159,11 +117,6 @@ Non-doc comments are interpreted as a form of whitespace.
## Whitespace
-```{.ebnf .gram}
-whitespace_char : '\x20' | '\x09' | '\x0a' | '\x0d' ;
-whitespace : [ whitespace_char | comment ] + ;
-```
-
The `whitespace_char` production is any nonempty Unicode string consisting of
any of the following Unicode characters: `U+0020` (space, `' '`), `U+0009`
(tab, `'\t'`), `U+000A` (LF, `'\n'`), `U+000D` (CR, `'\r'`).
@@ -176,41 +129,11 @@ with any other legal whitespace element, such as a single space character.
## Tokens
-```{.ebnf .gram}
-simple_token : keyword | unop | binop ;
-token : simple_token | ident | literal | symbol | whitespace token ;
-```
-
Tokens are primitive productions in the grammar defined by regular
(non-recursive) languages. "Simple" tokens are given in [string table
production](#string-table-productions) form, and occur in the rest of the
grammar as double-quoted strings. Other tokens have exact rules given.
-### Keywords
-
-
-
-| | | | | |
-|----------|----------|----------|----------|---------|
-| abstract | alignof | as | become | box |
-| break | const | continue | crate | do |
-| else | enum | extern | false | final |
-| fn | for | if | impl | in |
-| let | loop | macro | match | mod |
-| move | mut | offsetof | override | priv |
-| 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
-excluded from the `ident` rule.
-
-Note that some of these keywords are reserved, and do not currently do
-anything.
-
### Literals
A literal is an expression consisting of a single token, rather than a sequence
@@ -218,11 +141,6 @@ of tokens, that immediately and directly denotes the value it evaluates to,
rather than referring to it by name or some other evaluation rule. A literal is
a form of constant expression, so is evaluated (primarily) at compile time.
-```{.ebnf .gram}
-lit_suffix : ident;
-literal : [ string_lit | char_lit | byte_string_lit | byte_lit | num_lit ] lit_suffix ?;
-```
-
The optional suffix is only used for certain numeric literals, but is
reserved for future extension, that is, the above gives the lexical
grammar, but a Rust parser will reject everything but the 12 special
@@ -275,32 +193,6 @@ cases mentioned in [Number literals](#number-literals) below.
#### Character and string literals
-```{.ebnf .gram}
-char_lit : '\x27' char_body '\x27' ;
-string_lit : '"' string_body * '"' | 'r' raw_string ;
-
-char_body : non_single_quote
- | '\x5c' [ '\x27' | common_escape | unicode_escape ] ;
-
-string_body : non_double_quote
- | '\x5c' [ '\x22' | common_escape | unicode_escape ] ;
-raw_string : '"' raw_string_body '"' | '#' raw_string '#' ;
-
-common_escape : '\x5c'
- | 'n' | 'r' | 't' | '0'
- | 'x' hex_digit 2
-
-unicode_escape : 'u' '{' hex_digit+ 6 '}';
-
-hex_digit : 'a' | 'b' | 'c' | 'd' | 'e' | 'f'
- | 'A' | 'B' | 'C' | 'D' | 'E' | 'F'
- | dec_digit ;
-oct_digit : '0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' ;
-dec_digit : '0' | nonzero_dec ;
-nonzero_dec: '1' | '2' | '3' | '4'
- | '5' | '6' | '7' | '8' | '9' ;
-```
-
##### Character literals
A _character literal_ is a single Unicode character enclosed within two
@@ -349,11 +241,10 @@ following forms:
Raw string literals do not process any escapes. They start with the character
`U+0072` (`r`), followed by zero or more of the character `U+0023` (`#`) and a
-`U+0022` (double-quote) character. The _raw string body_ is not defined in the
-EBNF grammar above: it can contain any sequence of Unicode characters and is
-terminated only by another `U+0022` (double-quote) character, followed by the
-same number of `U+0023` (`#`) characters that preceded the opening `U+0022`
-(double-quote) character.
+`U+0022` (double-quote) character. The _raw string body_ can contain any sequence
+of Unicode characters and is terminated only by another `U+0022` (double-quote)
+character, followed by the same number of `U+0023` (`#`) characters that preceded
+the opening `U+0022` (double-quote) character.
All Unicode characters contained in the raw string body represent themselves,
the characters `U+0022` (double-quote) (except when followed by at least as
@@ -375,19 +266,6 @@ r##"foo #"# bar"##; // foo #"# bar
#### Byte and byte string literals
-```{.ebnf .gram}
-byte_lit : "b\x27" byte_body '\x27' ;
-byte_string_lit : "b\x22" string_body * '\x22' | "br" raw_byte_string ;
-
-byte_body : ascii_non_single_quote
- | '\x5c' [ '\x27' | common_escape ] ;
-
-byte_string_body : ascii_non_double_quote
- | '\x5c' [ '\x22' | common_escape ] ;
-raw_byte_string : '"' raw_byte_string_body '"' | '#' raw_byte_string '#' ;
-
-```
-
##### Byte literals
A _byte literal_ is a single ASCII character (in the `U+0000` to `U+007F`
@@ -403,7 +281,7 @@ preceded by the characters `U+0062` (`b`) and `U+0022` (double-quote), and
followed by the character `U+0022`. If the character `U+0022` is present within
the literal, it must be _escaped_ by a preceding `U+005C` (`\`) character.
Alternatively, a byte string literal can be a _raw byte string literal_, defined
-below. A byte string literal is equivalent to a `&'static [u8]` borrowed array
+below. A byte string literal of length `n` is equivalent to a `&'static [u8; n]` borrowed fixed-sized array
of unsigned 8-bit integers.
Some additional _escapes_ are available in either byte or non-raw byte string
@@ -424,11 +302,10 @@ following forms:
Raw byte string literals do not process any escapes. They start with the
character `U+0062` (`b`), followed by `U+0072` (`r`), followed by zero or more
of the character `U+0023` (`#`), and a `U+0022` (double-quote) character. The
-_raw string body_ is not defined in the EBNF grammar above: it can contain any
-sequence of ASCII characters and is terminated only by another `U+0022`
-(double-quote) character, followed by the same number of `U+0023` (`#`)
-characters that preceded the opening `U+0022` (double-quote) character. A raw
-byte string literal can not contain any non-ASCII byte.
+_raw string body_ can contain any sequence of ASCII characters and is terminated
+only by another `U+0022` (double-quote) character, followed by the same number of
+`U+0023` (`#`) characters that preceded the opening `U+0022` (double-quote)
+character. A raw byte string literal can not contain any non-ASCII byte.
All characters contained in the raw string body represent their ASCII encoding,
the characters `U+0022` (double-quote) (except when followed by at least as
@@ -450,19 +327,6 @@ b"\\x52"; br"\x52"; // \x52
#### Number literals
-```{.ebnf .gram}
-num_lit : nonzero_dec [ dec_digit | '_' ] * float_suffix ?
- | '0' [ [ dec_digit | '_' ] * float_suffix ?
- | 'b' [ '1' | '0' | '_' ] +
- | 'o' [ oct_digit | '_' ] +
- | 'x' [ hex_digit | '_' ] + ] ;
-
-float_suffix : [ exponent | '.' dec_lit exponent ? ] ? ;
-
-exponent : ['E' | 'e'] ['-' | '+' ] ? dec_lit ;
-dec_lit : [ dec_digit | '_' ] + ;
-```
-
A _number literal_ is either an _integer literal_ or a _floating-point
literal_. The grammar for recognizing the two kinds of literals is mixed.
@@ -540,12 +404,6 @@ The two values of the boolean type are written `true` and `false`.
### Symbols
-```{.ebnf .gram}
-symbol : "::" | "->"
- | '#' | '[' | ']' | '(' | ')' | '{' | '}'
- | ',' | ';' ;
-```
-
Symbols are a general class of printable [token](#tokens) that play structural
roles in a variety of grammar productions. They are catalogued here for
completeness as the set of remaining miscellaneous printable tokens that do not
@@ -555,16 +413,6 @@ operators](#binary-operator-expressions), or [keywords](#keywords).
## Paths
-```{.ebnf .gram}
-expr_path : [ "::" ] ident [ "::" expr_path_tail ] + ;
-expr_path_tail : '<' type_expr [ ',' type_expr ] + '>'
- | expr_path ;
-
-type_path : ident [ type_path_tail ] + ;
-type_path_tail : '<' type_expr [ ',' type_expr ] + '>'
- | "::" type_path ;
-```
-
A _path_ is a sequence of one or more path components _logically_ separated by
a namespace qualifier (`::`). If a path consists of only one component, it may
refer to either an [item](#items) or a [variable](#variables) in a local control
@@ -660,19 +508,6 @@ Users of `rustc` can define new syntax extensions in two ways:
## Macros
-```{.ebnf .gram}
-expr_macro_rules : "macro_rules" '!' ident '(' macro_rule * ')' ;
-macro_rule : '(' matcher * ')' "=>" '(' transcriber * ')' ';' ;
-matcher : '(' matcher * ')' | '[' matcher * ']'
- | '{' matcher * '}' | '$' ident ':' ident
- | '$' '(' matcher * ')' sep_token? [ '*' | '+' ]
- | non_special_token ;
-transcriber : '(' transcriber * ')' | '[' transcriber * ']'
- | '{' transcriber * '}' | '$' ident
- | '$' '(' transcriber * ')' sep_token? [ '*' | '+' ]
- | non_special_token ;
-```
-
`macro_rules` allows users to define syntax extension in a declarative way. We
call such extensions "macros by example" or simply "macros" — to be distinguished
from the "procedural macros" defined in [compiler plugins][plugin].
@@ -811,12 +646,6 @@ Crates contain [items](#items), each of which may have some number of
## Items
-```{.ebnf .gram}
-item : extern_crate_decl | use_decl | mod_item | fn_item | type_item
- | struct_item | enum_item | static_item | trait_item | impl_item
- | extern_block ;
-```
-
An _item_ is a component of a crate. Items are organized within a crate by a
nested set of [modules](#modules). Every crate has a single "outermost"
anonymous module; all further items within the crate have [paths](#paths)
@@ -863,11 +692,6 @@ no notion of type abstraction: there are no first-class "forall" types.
### Modules
-```{.ebnf .gram}
-mod_item : "mod" ident ( ';' | '{' mod '}' );
-mod : item * ;
-```
-
A module is a container for zero or more [items](#items).
A _module item_ is a module, surrounded in braces, named, and prefixed with the
@@ -928,11 +752,6 @@ mod thread {
##### Extern crate declarations
-```{.ebnf .gram}
-extern_crate_decl : "extern" "crate" crate_name
-crate_name: ident | ( string_lit "as" ident )
-```
-
An _`extern crate` declaration_ specifies a dependency on an external crate.
The external crate is then bound into the declaring scope as the `ident`
provided in the `extern_crate_decl`.
@@ -958,17 +777,6 @@ extern crate std as ruststd; // linking to 'std' under another name
##### Use declarations
-```{.ebnf .gram}
-use_decl : "pub" ? "use" [ path "as" ident
- | path_glob ] ;
-
-path_glob : ident [ "::" [ path_glob
- | '*' ] ] ?
- | '{' path_item [ ',' path_item ] * '}' ;
-
-path_item : ident | "self" ;
-```
-
A _use declaration_ creates one or more local name bindings synonymous with
some other [path](#paths). Usually a `use` declaration is used to shorten the
path required to refer to a module item. These declarations may appear at the
@@ -1413,10 +1221,6 @@ it were `Bar(i32)`, this is disallowed.
### Constant items
-```{.ebnf .gram}
-const_item : "const" ident ':' type '=' expr ';' ;
-```
-
A *constant item* is a named _constant value_ which is not associated with a
specific memory location in the program. Constants are essentially inlined
wherever they are used, meaning that they are copied directly into the relevant
@@ -1453,10 +1257,6 @@ const BITS_N_STRINGS: BitsNStrings<'static> = BitsNStrings {
### Static items
-```{.ebnf .gram}
-static_item : "static" ident ':' type '=' expr ';' ;
-```
-
A *static item* is similar to a *constant*, except that it represents a precise
memory location in the program. A static is never "inlined" at the usage site,
and all references to it refer to the same memory location. Static items have
@@ -1711,11 +1511,6 @@ impl Seq for u32 {
### External blocks
-```{.ebnf .gram}
-extern_block_item : "extern" '{' extern_block '}' ;
-extern_block : [ foreign_fn ] * ;
-```
-
External blocks form the basis for Rust's foreign function interface.
Declarations in an external block describe symbols in external, non-Rust
libraries.
@@ -1915,13 +1710,6 @@ the namespace hierarchy as it normally would.
## Attributes
-```{.ebnf .gram}
-attribute : '#' '!' ? '[' meta_item ']' ;
-meta_item : ident [ '=' literal
- | '(' meta_seq ')' ] ? ;
-meta_seq : meta_item [ ',' meta_seq ] ? ;
-```
-
Any item declaration may have an _attribute_ applied to it. Attributes in Rust
are modeled on Attributes in ECMA-335, with the syntax coming from ECMA-334
(C#). An attribute is a general, free-form metadatum that is interpreted
@@ -2503,7 +2291,7 @@ The currently implemented features of the reference compiler are:
terms of encapsulation).
If a feature is promoted to a language feature, then all existing programs will
-start to receive compilation warnings about #[feature] directives which enabled
+start to receive compilation warnings about `#![feature]` directives which enabled
the new feature (because the directive is no longer necessary). However, if a
feature is decided to be removed from the language, errors will be issued (if
there isn't a parser error first). The directive in this case is no longer
@@ -2554,11 +2342,6 @@ in meaning to declaring the item outside the statement block.
#### Variable declarations
-```{.ebnf .gram}
-let_decl : "let" pat [':' type ] ? [ init ] ? ';' ;
-init : [ '=' ] expr ;
-```
-
A _variable declaration_ introduces a new set of variable, given by a pattern. The
pattern may be followed by a type annotation, and/or an initializer expression.
When no type annotation is given, the compiler will infer the type, or signal
@@ -2649,7 +2432,7 @@ parentheses. They are used to create [tuple-typed](#tuple-types) values.
```{.tuple}
(0,);
(0.0, 4.5);
-("a", 4us, true);
+("a", 4usize, true);
```
### Unit expressions
@@ -2659,15 +2442,6 @@ the same name.
### Structure expressions
-```{.ebnf .gram}
-struct_expr : expr_path '{' ident ':' expr
- [ ',' ident ':' expr ] *
- [ ".." expr ] '}' |
- expr_path '(' expr
- [ ',' expr ] * ')' |
- expr_path ;
-```
-
There are several forms of structure expressions. A _structure expression_
consists of the [path](#paths) of a [structure item](#structures), followed by
a brace-enclosed list of one or more comma-separated name-value pairs,
@@ -2718,11 +2492,6 @@ Point3d {y: 0, z: 10, .. base};
### Block expressions
-```{.ebnf .gram}
-block_expr : '{' [ stmt ';' | item ] *
- [ expr ] '}' ;
-```
-
A _block expression_ is similar to a module in terms of the declarations that
are possible. Each block conceptually introduces a new namespace scope. Use
items can bring new names into scopes and declared items are in scope for only
@@ -2745,10 +2514,6 @@ assert_eq!(5, x);
### Method-call expressions
-```{.ebnf .gram}
-method_call_expr : expr '.' ident paren_expr_list ;
-```
-
A _method call_ consists of an expression followed by a single dot, an
identifier, and a parenthesized expression-list. Method calls are resolved to
methods on specific traits, either statically dispatching to a method if the
@@ -2757,10 +2522,6 @@ the left-hand-side expression is an indirect [trait object](#trait-objects).
### Field expressions
-```{.ebnf .gram}
-field_expr : expr '.' ident ;
-```
-
A _field expression_ consists of an expression followed by a single dot and an
identifier, when not immediately followed by a parenthesized expression-list
(the latter is a [method call expression](#method-call-expressions)). A field
@@ -2781,12 +2542,6 @@ automatically dereferenced to make the field access possible.
### Array expressions
-```{.ebnf .gram}
-array_expr : '[' "mut" ? array_elems? ']' ;
-
-array_elems : [expr [',' expr]*] | [expr ';' expr] ;
-```
-
An [array](#array,-and-slice-types) _expression_ is written by enclosing zero
or more comma-separated expressions of uniform type in square brackets.
@@ -2803,10 +2558,6 @@ constant expression that can be evaluated at compile time, such as a
### Index expressions
-```{.ebnf .gram}
-idx_expr : expr '[' expr ']' ;
-```
-
[Array](#array,-and-slice-types)-typed expressions can be indexed by
writing a square-bracket-enclosed expression (the index) after them. When the
array is mutable, the resulting [lvalue](#lvalues,-rvalues-and-temporaries) can
@@ -2823,13 +2574,6 @@ _panicked state_.
### Range expressions
-```{.ebnf .gram}
-range_expr : expr ".." expr |
- expr ".." |
- ".." expr |
- ".." ;
-```
-
The `..` operator will construct an object of one of the `std::ops::Range` variants.
```
@@ -2872,10 +2616,6 @@ before the expression they apply to.
### Binary operator expressions
-```{.ebnf .gram}
-binop_expr : expr binop expr ;
-```
-
Binary operators expressions are given in terms of [operator
precedence](#operator-precedence).
@@ -3036,10 +2776,6 @@ An expression enclosed in parentheses evaluates to the result of the enclosed
expression. Parentheses can be used to explicitly specify evaluation order
within an expression.
-```{.ebnf .gram}
-paren_expr : '(' expr ')' ;
-```
-
An example of a parenthesized expression:
```
@@ -3049,12 +2785,6 @@ let x: i32 = (2 + 3) * 4;
### Call expressions
-```{.ebnf .gram}
-expr_list : [ expr [ ',' expr ]* ] ? ;
-paren_expr_list : '(' expr_list ')' ;
-call_expr : expr paren_expr_list ;
-```
-
A _call expression_ invokes a function, providing zero or more input variables
and an optional location to move the function's output into. If the function
eventually returns, then the expression completes.
@@ -3070,11 +2800,6 @@ let pi: Result = "3.14".parse();
### Lambda expressions
-```{.ebnf .gram}
-ident_list : [ ident [ ',' ident ]* ] ? ;
-lambda_expr : '|' ident_list '|' expr ;
-```
-
A _lambda expression_ (sometimes called an "anonymous function expression")
defines a function and denotes it as a value, in a single expression. A lambda
expression is a pipe-symbol-delimited (`|`) list of identifiers followed by an
@@ -3118,10 +2843,6 @@ ten_times(|j| println!("hello, {}", j));
A `loop` expression denotes an infinite loop.
-```{.ebnf .gram}
-loop_expr : [ lifetime ':' ] "loop" '{' block '}';
-```
-
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
@@ -3131,10 +2852,6 @@ expressions](#continue-expressions).
### Break expressions
-```{.ebnf .gram}
-break_expr : "break" [ lifetime ];
-```
-
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
@@ -3143,10 +2860,6 @@ be the innermost label enclosing the `break` expression, but must enclose it.
### Continue expressions
-```{.ebnf .gram}
-continue_expr : "continue" [ lifetime ];
-```
-
A `continue` expression has an optional _label_. If the label is absent, then
executing a `continue` expression immediately terminates the current iteration
of the innermost loop enclosing it, returning control to the loop *head*. In
@@ -3160,10 +2873,6 @@ 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
@@ -3187,26 +2896,22 @@ loops](#infinite-loops), [break expressions](#break-expressions), and
### For expressions
-```{.ebnf .gram}
-for_expr : [ lifetime ':' ] "for" pat "in" no_struct_literal_expr '{' block '}' ;
-```
-
A `for` expression is a syntactic construct for looping over elements provided
-by an implementation of `std::iter::Iterator`.
+by an implementation of `std::iter::IntoIterator`.
An example of a for loop over the contents of an array:
```
# type Foo = i32;
-# fn bar(f: Foo) { }
+# fn bar(f: &Foo) { }
# let a = 0;
# let b = 0;
# let c = 0;
let v: &[Foo] = &[a, b, c];
-for e in v.iter() {
- bar(*e);
+for e in v {
+ bar(e);
}
```
@@ -3226,14 +2931,6 @@ loops](#infinite-loops), [break expressions](#break-expressions), and
### If expressions
-```{.ebnf .gram}
-if_expr : "if" no_struct_literal_expr '{' block '}'
- else_tail ? ;
-
-else_tail : "else" [ if_expr | if_let_expr
- | '{' block '}' ] ;
-```
-
An `if` expression is a conditional branch in program control. The form of an
`if` expression is a condition expression, followed by a consequent block, any
number of `else if` conditions and blocks, and an optional trailing `else`
@@ -3246,14 +2943,6 @@ if` condition is evaluated. If all `if` and `else if` conditions evaluate to
### Match expressions
-```{.ebnf .gram}
-match_expr : "match" no_struct_literal_expr '{' match_arm * '}' ;
-
-match_arm : attribute * match_pat "=>" [ expr "," | '{' block '}' ] ;
-
-match_pat : pat [ '|' pat ] * [ "if" expr ] ? ;
-```
-
A `match` expression branches on a *pattern*. The exact form of matching that
occurs depends on the pattern. Patterns consist of some combination of
literals, destructured arrays or enum constructors, structures and tuples,
@@ -3370,12 +3059,6 @@ let message = match maybe_digit {
### If let expressions
-```{.ebnf .gram}
-if_let_expr : "if" "let" pat '=' expr '{' block '}'
- else_tail ? ;
-else_tail : "else" [ if_expr | if_let_expr | '{' block '}' ] ;
-```
-
An `if let` expression is semantically identical to an `if` expression but in place
of a condition expression it expects a refutable let statement. If the value of the
expression on the right hand side of the let statement matches the pattern, the corresponding
@@ -3383,10 +3066,6 @@ block will execute, otherwise flow proceeds to the first `else` block that follo
### While let loops
-```{.ebnf .gram}
-while_let_expr : "while" "let" pat '=' expr '{' block '}' ;
-```
-
A `while let` loop is semantically identical to a `while` loop but in place of a
condition expression it expects a refutable let statement. If the value of the
expression on the right hand side of the let statement matches the pattern, the
@@ -3395,10 +3074,6 @@ Otherwise, the while expression completes.
### Return expressions
-```{.ebnf .gram}
-return_expr : "return" expr ? ;
-```
-
Return expressions are denoted with the keyword `return`. Evaluating a `return`
expression moves its argument into the designated output location for the
current function call, destroys the current function activation frame, and
diff --git a/src/libcore/convert.rs b/src/libcore/convert.rs
index 1c1ad5fd33fb8..d9cda58d9ebed 100644
--- a/src/libcore/convert.rs
+++ b/src/libcore/convert.rs
@@ -11,7 +11,7 @@
//! Traits for conversions between types.
//!
//! The traits in this module provide a general way to talk about conversions from one type to
-//! another. They follow the standard Rust conventions of `as`/`to`/`into`/`from`.
+//! another. They follow the standard Rust conventions of `as`/`into`/`from`.
//!
//! Like many traits, these are often used as bounds for generic functions, to support arguments of
//! multiple types.
diff --git a/src/librustc/middle/astencode.rs b/src/librustc/middle/astencode.rs
index ee8373279d976..cc42bd9b08b80 100644
--- a/src/librustc/middle/astencode.rs
+++ b/src/librustc/middle/astencode.rs
@@ -1835,29 +1835,31 @@ fn decode_item_ast(par_doc: rbml::Doc) -> ast::Item {
}
#[cfg(test)]
-trait fake_ext_ctxt {
+trait FakeExtCtxt {
+ fn call_site(&self) -> codemap::Span;
fn cfg(&self) -> ast::CrateConfig;
- fn parse_sess<'a>(&'a self) -> &'a parse::ParseSess;
- fn call_site(&self) -> Span;
fn ident_of(&self, st: &str) -> ast::Ident;
+ fn name_of(&self, st: &str) -> ast::Name;
+ fn parse_sess(&self) -> &parse::ParseSess;
}
#[cfg(test)]
-impl fake_ext_ctxt for parse::ParseSess {
- fn cfg(&self) -> ast::CrateConfig {
- Vec::new()
- }
- fn parse_sess<'a>(&'a self) -> &'a parse::ParseSess { self }
- fn call_site(&self) -> Span {
+impl FakeExtCtxt for parse::ParseSess {
+ fn call_site(&self) -> codemap::Span {
codemap::Span {
lo: codemap::BytePos(0),
hi: codemap::BytePos(0),
- expn_id: codemap::NO_EXPANSION
+ expn_id: codemap::NO_EXPANSION,
}
}
+ fn cfg(&self) -> ast::CrateConfig { Vec::new() }
fn ident_of(&self, st: &str) -> ast::Ident {
- token::str_to_ident(st)
+ parse::token::str_to_ident(st)
+ }
+ fn name_of(&self, st: &str) -> ast::Name {
+ parse::token::intern(st)
}
+ fn parse_sess(&self) -> &parse::ParseSess { self }
}
#[cfg(test)]
@@ -1883,7 +1885,7 @@ fn test_basic() {
fn foo() {}
));
}
-/* NOTE: When there's a snapshot, update this (yay quasiquoter!)
+
#[test]
fn test_smalltalk() {
let cx = mk_ctxt();
@@ -1891,7 +1893,6 @@ fn test_smalltalk() {
fn foo() -> isize { 3 + 4 } // first smalltalk program ever executed.
));
}
-*/
#[test]
fn test_more() {
diff --git a/src/test/compile-fail-fulldeps/qquote.rs b/src/test/compile-fail-fulldeps/qquote.rs
new file mode 100644
index 0000000000000..cf81f59434363
--- /dev/null
+++ b/src/test/compile-fail-fulldeps/qquote.rs
@@ -0,0 +1,55 @@
+// Copyright 2012-2014 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 or the MIT license
+// , at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// ignore-cross-compile
+
+#![feature(quote, rustc_private)]
+
+extern crate syntax;
+
+use syntax::ast;
+use syntax::codemap;
+use syntax::parse;
+use syntax::print::pprust;
+
+trait FakeExtCtxt {
+ fn call_site(&self) -> codemap::Span;
+ fn cfg(&self) -> ast::CrateConfig;
+ fn ident_of(&self, st: &str) -> ast::Ident;
+ fn name_of(&self, st: &str) -> ast::Name;
+ fn parse_sess(&self) -> &parse::ParseSess;
+}
+
+impl FakeExtCtxt for parse::ParseSess {
+ fn call_site(&self) -> codemap::Span {
+ codemap::Span {
+ lo: codemap::BytePos(0),
+ hi: codemap::BytePos(0),
+ expn_id: codemap::NO_EXPANSION,
+ }
+ }
+ fn cfg(&self) -> ast::CrateConfig { Vec::new() }
+ fn ident_of(&self, st: &str) -> ast::Ident {
+ parse::token::str_to_ident(st)
+ }
+ fn name_of(&self, st: &str) -> ast::Name {
+ parse::token::intern(st)
+ }
+ fn parse_sess(&self) -> &parse::ParseSess { self }
+}
+
+fn main() {
+ let cx = parse::new_parse_sess();
+
+ assert_eq!(pprust::expr_to_string(&*quote_expr!(&cx, 23)), "23");
+
+ let expr = quote_expr!(&cx, 2 - $abcd + 7); //~ ERROR unresolved name: `abcd`
+ assert_eq!(pprust::expr_to_string(&*expr), "2 - $abcd + 7");
+}
diff --git a/src/test/compile-fail/gated-box-patterns.rs b/src/test/compile-fail/gated-box-patterns.rs
deleted file mode 100644
index d82d0dec72bba..0000000000000
--- a/src/test/compile-fail/gated-box-patterns.rs
+++ /dev/null
@@ -1,21 +0,0 @@
-// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 or the MIT license
-// , at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-// Test that patterns including the box syntax are gated by `box_patterns` feature gate.
-
-fn main() {
- let x = Box::new(1);
-
- match x {
- box 1 => (),
- //~^ box pattern syntax is experimental
- _ => ()
- };
-}
diff --git a/src/test/compile-fail/gated-simd-ffi.rs b/src/test/compile-fail/gated-simd-ffi.rs
deleted file mode 100644
index 883e1be04b228..0000000000000
--- a/src/test/compile-fail/gated-simd-ffi.rs
+++ /dev/null
@@ -1,27 +0,0 @@
-// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 or the MIT license
-// , at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-// Test that the use of smid types in the ffi is gated by `smid_ffi` feature gate.
-
-#![feature(simd)]
-
-#[repr(C)]
-#[derive(Copy, Clone)]
-#[simd]
-pub struct f32x4(f32, f32, f32, f32);
-
-#[allow(dead_code)]
-extern {
- fn foo(x: f32x4);
- //~^ ERROR use of SIMD type `f32x4` in FFI is highly experimental and may result in invalid code
- //~| HELP add #![feature(simd_ffi)] to the crate attributes to enable
-}
-
-fn main() {}
diff --git a/src/test/parse-fail/qquote-1.rs b/src/test/parse-fail/qquote-1.rs
deleted file mode 100644
index e30308b295a37..0000000000000
--- a/src/test/parse-fail/qquote-1.rs
+++ /dev/null
@@ -1,70 +0,0 @@
-// Copyright 2012-2014 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 or the MIT license
-// , at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-// compile-flags: -Z parse-only
-
-// ignore-test Can't use syntax crate here
-
-#![feature(quote)]
-
-extern crate syntax;
-
-use io::*;
-
-use syntax::diagnostic;
-use syntax::ast;
-use syntax::codemap;
-use syntax::parse;
-use syntax::print::*;
-
-
-trait fake_ext_ctxt {
- fn cfg() -> ast::CrateConfig;
- fn parse_sess() -> parse::parse_sess;
- fn call_site() -> span;
- fn ident_of(st: &str) -> ast::ident;
-}
-
-type fake_session = parse::parse_sess;
-
-impl fake_ext_ctxt for fake_session {
- fn cfg() -> ast::CrateConfig { Vec::new() }
- fn parse_sess() -> parse::parse_sess { self }
- fn call_site() -> span {
- codemap::span {
- lo: codemap::BytePos(0),
- hi: codemap::BytePos(0),
- expn_id: NO_EXPANSION
- }
- }
- fn ident_of(st: &str) -> ast::ident {
- self.interner.intern(st)
- }
-}
-
-fn mk_ctxt() -> fake_ext_ctxt {
- parse::new_parse_sess(None) as fake_ext_ctxt
-}
-
-
-
-fn main() {
- let cx = mk_ctxt();
-
- let abc = quote_expr!(cx, 23);
- check_pp(abc, pprust::print_expr, "23");
-
- let expr3 = quote_expr!(cx, 2 - $abcd + 7); //~ ERROR unresolved name: abcd
- check_pp(expr3, pprust::print_expr, "2 - 23 + 7");
-}
-
-fn check_pp(expr: T, f: |pprust::ps, T|, expect: str) {
- panic!();
-}
diff --git a/src/test/parse-fail/qquote-2.rs b/src/test/parse-fail/qquote-2.rs
deleted file mode 100644
index ac501d31beebd..0000000000000
--- a/src/test/parse-fail/qquote-2.rs
+++ /dev/null
@@ -1,63 +0,0 @@
-// Copyright 2012-2014 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 or the MIT license
-// , at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-// compile-flags: -Z parse-only
-
-// ignore-test Can't use syntax crate here
-
-#![feature(quote)]
-
-extern crate syntax;
-
-use syntax::diagnostic;
-use syntax::ast;
-use syntax::codemap;
-use syntax::parse::parser;
-use syntax::print::*;
-
-trait fake_ext_ctxt {
- fn cfg() -> ast::CrateConfig;
- fn parse_sess() -> parse::parse_sess;
- fn call_site() -> span;
- fn ident_of(st: &str) -> ast::ident;
-}
-
-type fake_session = parse::parse_sess;
-
-impl fake_ext_ctxt for fake_session {
- fn cfg() -> ast::CrateConfig { Vec::new() }
- fn parse_sess() -> parse::parse_sess { self }
- fn call_site() -> span {
- codemap::span {
- lo: codemap::BytePos(0),
- hi: codemap::BytePos(0),
- expn_id: codemap::NO_EXPANSION
- }
- }
- fn ident_of(st: &str) -> ast::ident {
- self.interner.intern(st)
- }
-}
-
-fn mk_ctxt() -> fake_ext_ctxt {
- parse::new_parse_sess(None) as fake_ext_ctxt
-}
-
-
-fn main() {
- let cx = mk_ctxt();
-
- let stmt = quote_stmt!(cx, let x isize = 20;); //~ ERROR expected end-of-string
- check_pp(*stmt, pprust::print_stmt, "");
-}
-
-fn check_pp(expr: T, f: |pprust::ps, T|, expect: str) {
- panic!();
-}
diff --git a/src/test/run-fail/qquote.rs b/src/test/run-fail/qquote.rs
new file mode 100644
index 0000000000000..fe582bc9bf780
--- /dev/null
+++ b/src/test/run-fail/qquote.rs
@@ -0,0 +1,57 @@
+// Copyright 2012-2014 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 or the MIT license
+// , at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// ignore-cross-compile
+
+// error-pattern:expected identifier, found keyword `let`
+
+#![feature(quote, rustc_private)]
+
+extern crate syntax;
+
+use syntax::ast;
+use syntax::codemap;
+use syntax::parse;
+use syntax::print::pprust;
+
+trait FakeExtCtxt {
+ fn call_site(&self) -> codemap::Span;
+ fn cfg(&self) -> ast::CrateConfig;
+ fn ident_of(&self, st: &str) -> ast::Ident;
+ fn name_of(&self, st: &str) -> ast::Name;
+ fn parse_sess(&self) -> &parse::ParseSess;
+}
+
+impl FakeExtCtxt for parse::ParseSess {
+ fn call_site(&self) -> codemap::Span {
+ codemap::Span {
+ lo: codemap::BytePos(0),
+ hi: codemap::BytePos(0),
+ expn_id: codemap::NO_EXPANSION,
+ }
+ }
+ fn cfg(&self) -> ast::CrateConfig { Vec::new() }
+ fn ident_of(&self, st: &str) -> ast::Ident {
+ parse::token::str_to_ident(st)
+ }
+ fn name_of(&self, st: &str) -> ast::Name {
+ parse::token::intern(st)
+ }
+ fn parse_sess(&self) -> &parse::ParseSess { self }
+}
+
+fn main() {
+ let cx = parse::new_parse_sess();
+
+ assert_eq!(pprust::expr_to_string(&*quote_expr!(&cx, 23)), "23");
+
+ let expr = quote_expr!(&cx, let x isize = 20;);
+ assert_eq!(pprust::expr_to_string(&*expr), "let x isize = 20;");
+}
diff --git a/src/test/run-pass-fulldeps/qquote.rs b/src/test/run-pass-fulldeps/qquote.rs
index 710b3b07549f9..995dd80df65a0 100644
--- a/src/test/run-pass-fulldeps/qquote.rs
+++ b/src/test/run-pass-fulldeps/qquote.rs
@@ -10,86 +10,58 @@
// ignore-cross-compile
// ignore-pretty
-// ignore-test
-#![feature(quote)]
+#![feature(quote, rustc_private)]
extern crate syntax;
-use std::io::*;
-
-use syntax::diagnostic;
use syntax::ast;
use syntax::codemap;
-use syntax::codemap::span;
use syntax::parse;
-use syntax::print::*;
-
-
-trait fake_ext_ctxt {
- fn cfg() -> ast::CrateConfig;
- fn parse_sess() -> parse::parse_sess;
- fn call_site() -> span;
- fn ident_of(st: &str) -> ast::ident;
+use syntax::print::pprust;
+
+trait FakeExtCtxt {
+ fn call_site(&self) -> codemap::Span;
+ fn cfg(&self) -> ast::CrateConfig;
+ fn ident_of(&self, st: &str) -> ast::Ident;
+ fn name_of(&self, st: &str) -> ast::Name;
+ fn parse_sess(&self) -> &parse::ParseSess;
}
-type fake_session = parse::parse_sess;
-
-impl fake_ext_ctxt for fake_session {
- fn cfg() -> ast::CrateConfig { Vec::new() }
- fn parse_sess() -> parse::parse_sess { self }
- fn call_site() -> span {
- codemap::span {
+impl FakeExtCtxt for parse::ParseSess {
+ fn call_site(&self) -> codemap::Span {
+ codemap::Span {
lo: codemap::BytePos(0),
hi: codemap::BytePos(0),
- expn_id: codemap::NO_EXPANSION
+ expn_id: codemap::NO_EXPANSION,
}
}
- fn ident_of(st: &str) -> ast::ident {
- self.interner.intern(st)
+ fn cfg(&self) -> ast::CrateConfig { Vec::new() }
+ fn ident_of(&self, st: &str) -> ast::Ident {
+ parse::token::str_to_ident(st)
}
-}
-
-fn mk_ctxt() -> fake_ext_ctxt {
- parse::new_parse_sess(None) as fake_ext_ctxt
+ fn name_of(&self, st: &str) -> ast::Name {
+ parse::token::intern(st)
+ }
+ fn parse_sess(&self) -> &parse::ParseSess { self }
}
fn main() {
- let cx = mk_ctxt();
+ let cx = parse::new_parse_sess();
- let abc = quote_expr!(cx, 23);
- check_pp(ext_cx, abc, pprust::print_expr, "23".to_string());
+ assert_eq!(pprust::expr_to_string(&*quote_expr!(&cx, 23)), "23");
+ assert_eq!(pprust::pat_to_string(&*quote_pat!(&cx, Some(_))), "Some(_)");
+ assert_eq!(pprust::ty_to_string(&*quote_ty!(&cx, isize)), "isize");
+ let arm = quote_arm!(&cx, (ref x, ref y) => (x, y),);
+ assert_eq!(pprust::arm_to_string(&arm), " (ref x, ref y) => (x, y),");
- let ty = quote_ty!(cx, isize);
- check_pp(ext_cx, ty, pprust::print_type, "isize".to_string());
+ let attr = quote_attr!(&cx, #![cfg(foo = "bar")]);
+ assert_eq!(pprust::attr_to_string(&attr), "#![cfg(foo = \"bar\")]");
- let item = quote_item!(cx, static x : isize = 10;).get();
- check_pp(ext_cx, item, pprust::print_item, "static x: isize = 10;".to_string());
+ let item = quote_item!(&cx, static x : isize = 10;).unwrap();
+ assert_eq!(pprust::item_to_string(&*item), "static x: isize = 10;");
- let stmt = quote_stmt!(cx, let x = 20;);
- check_pp(ext_cx, *stmt, pprust::print_stmt, "let x = 20;".to_string());
-
- let pat = quote_pat!(cx, Some(_));
- check_pp(ext_cx, pat, pprust::print_pat, "Some(_)".to_string());
-
- let arm = quote_arm!(cx, (ref x, ref y) => (x, y));
- check_pp(ext_cx, arm, pprust::print_stmt, "(ref x, ref y) = (x, y)".to_string());
-
- let attr = quote_attr!(cx, #![cfg(foo = "bar")]);
- check_pp(ext_cx, attr, pprust::print_attribute, "#![cfg(foo = "bar")]".to_string());
-}
-
-fn check_pp(cx: fake_ext_ctxt,
- expr: T, f: |pprust::ps, T|, expect: String) {
- let s = io::with_str_writer(|wr| {
- let pp = pprust::rust_printer(wr, cx.parse_sess().interner);
- f(pp, expr);
- pp::eof(pp.s);
- });
- stdout().write_line(s);
- if expect != "".to_string() {
- println!("expect: '%s', got: '%s'", expect, s);
- assert_eq!(s, expect);
- }
+ let stmt = quote_stmt!(&cx, let x = 20;).unwrap();
+ assert_eq!(pprust::stmt_to_string(&*stmt), "let x = 20;");
}