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