diff --git a/README.md b/README.md
index 495ee46a9acb3..9462b10494c93 100644
--- a/README.md
+++ b/README.md
@@ -33,7 +33,7 @@ or reading the [rustc guide][rustcguidebuild].
* `curl`
* `git`
* `ssl` which comes in `libssl-dev` or `openssl-devel`
- * `pkg-config` if you are on compiling on Linux and targeting Linux
+ * `pkg-config` if you are compiling on Linux and targeting Linux
2. Clone the [source] with `git`:
diff --git a/src/doc/grammar.md b/src/doc/grammar.md
index ee9135b6578f6..0b2a531f896ba 100644
--- a/src/doc/grammar.md
+++ b/src/doc/grammar.md
@@ -1,812 +1,5 @@
-% Grammar
+The Rust grammar may now be found in the [reference]. Additionally, the [grammar
+working group] is working on producing a testable grammar.
-# Introduction
-
-This document is the primary reference for the Rust programming language grammar. It
-provides only one kind of material:
-
- - Chapters that formally define the language grammar.
-
-This document does not serve as an introduction to the language. Background
-familiarity with the language is assumed. A separate [guide] is available to
-help acquire such background.
-
-This document also does not serve as a reference to the [standard] library
-included in the language distribution. Those libraries are documented
-separately by extracting documentation attributes from their source code. Many
-of the features that one might expect to be language features are library
-features in Rust, so what you're looking for may be there, not here.
-
-[guide]: guide.html
-[standard]: std/index.html
-
-# Notation
-
-Rust's grammar is defined over Unicode codepoints, 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:
-
-```antlr
-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 codepoint `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 codepoints 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
-section [Special Unicode Productions](#special-unicode-productions) lists these
-productions.
-
-## String table productions
-
-Some rules in the grammar — notably [unary
-operators](#unary-operator-expressions), [binary
-operators](#binary-operator-expressions), and [keywords](#keywords) — are
-given in a simplified form: as a listing of a table of unquoted, printable
-whitespace-separated strings. These cases form a subset of the rules regarding
-the [token](#tokens) rule, and are assumed to be the result of a
-lexical-analysis phase feeding the parser, driven by a DFA, operating over the
-disjunction of all such string table entries.
-
-When such a string enclosed in double-quotes (`"`) occurs inside the grammar,
-it is an implicit reference to a single member of such a string table
-production. See [tokens](#tokens) for more information.
-
-# Lexical structure
-
-## Input format
-
-Rust input is interpreted as a sequence of Unicode codepoints 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]
-
-[^inputformat]: Substitute definitions for the special Unicode productions are
- provided to the grammar verifier, restricted to ASCII range, when verifying the
- grammar in this document.
-
-## Special Unicode Productions
-
-The following productions in the Rust grammar are defined in terms of Unicode
-properties: `ident`, `non_null`, `non_eol`, `non_single_quote` and
-`non_double_quote`.
-
-### Identifiers
-
-The `ident` production is any nonempty Unicode string of
-the following form:
-
-- The first character is in one of the following ranges `U+0041` to `U+005A`
-("A" to "Z"), `U+0061` to `U+007A` ("a" to "z"), or `U+005F` ("\_").
-- The remaining characters are in the range `U+0030` to `U+0039` ("0" to "9"),
-or any of the prior valid initial characters.
-
-as long as the identifier does _not_ occur in the set of [keywords](#keywords).
-
-### Delimiter-restricted productions
-
-Some productions are defined by exclusion of particular Unicode characters:
-
-- `non_null` is any single Unicode character aside from `U+0000` (null)
-- `non_eol` is any single Unicode character aside from `U+000A` (`'\n'`)
-- `non_single_quote` is any single Unicode character aside from `U+0027` (`'`)
-- `non_double_quote` is any single Unicode character aside from `U+0022` (`"`)
-
-## Comments
-
-```antlr
-comment : block_comment | line_comment ;
-block_comment : "/*" block_comment_body * "*/" ;
-block_comment_body : [block_comment | character] * ;
-line_comment : "//" non_eol * ;
-```
-
-**FIXME:** add doc grammar?
-
-## Whitespace
-
-```antlr
-whitespace_char : '\x20' | '\x09' | '\x0a' | '\x0d' ;
-whitespace : [ whitespace_char | comment ] + ;
-```
-
-## Tokens
-
-```antlr
-simple_token : keyword | unop | binop ;
-token : simple_token | ident | literal | symbol | whitespace token ;
-```
-
-### 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.
-
-Not all of these keywords are used by the language. Some of them were used
-before Rust 1.0, and were left reserved once their implementations were
-removed. Some of them were reserved before 1.0 to make space for possible
-future features.
-
-### Literals
-
-```antlr
-lit_suffix : ident;
-literal : [ string_lit | char_lit | byte_string_lit | byte_lit | num_lit | bool_lit ] lit_suffix ?;
-```
-
-The optional `lit_suffix` production 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 cases
-mentioned in [Number literals](reference/tokens.html#number-literals) in the
-reference.
-
-#### Character and string literals
-
-```antlr
-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' ;
-```
-
-#### Byte and byte string literals
-
-```antlr
-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 '#' ;
-
-```
-
-#### Number literals
-
-```antlr
-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 | '_' ] + ;
-```
-
-#### Boolean literals
-
-```antlr
-bool_lit : [ "true" | "false" ] ;
-```
-
-The two values of the boolean type are written `true` and `false`.
-
-### Symbols
-
-```antlr
-symbol : "::" | "->"
- | '#' | '[' | ']' | '(' | ')' | '{' | '}'
- | ',' | ';' ;
-```
-
-Symbols are a general class of printable [tokens](#tokens) that play structural
-roles in a variety of grammar productions. They are cataloged here for
-completeness as the set of remaining miscellaneous printable tokens that do not
-otherwise appear as [unary operators](#unary-operator-expressions), [binary
-operators](#binary-operator-expressions), or [keywords](#keywords).
-
-## Paths
-
-```antlr
-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 ;
-```
-
-# Syntax extensions
-
-## Macros
-
-```antlr
-expr_macro_rules : "macro_rules" '!' ident '(' macro_rule * ')' ';'
- | "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 ;
-```
-
-# Crates and source files
-
-**FIXME:** grammar? What production covers #![crate_id = "foo"] ?
-
-# Items and attributes
-
-**FIXME:** grammar?
-
-## Items
-
-```antlr
-item : vis ? mod_item | fn_item | type_item | struct_item | enum_item
- | const_item | static_item | trait_item | impl_item | extern_block_item ;
-```
-
-### Type Parameters
-
-**FIXME:** grammar?
-
-### Modules
-
-```antlr
-mod_item : "mod" ident ( ';' | '{' mod '}' );
-mod : [ view_item | item ] * ;
-```
-
-#### View items
-
-```antlr
-view_item : extern_crate_decl | use_decl ';' ;
-```
-
-##### Extern crate declarations
-
-```antlr
-extern_crate_decl : "extern" "crate" crate_name
-crate_name: ident | ( ident "as" ident )
-```
-
-##### Use declarations
-
-```antlr
-use_decl : vis ? "use" [ path "as" ident
- | path_glob ] ;
-
-path_glob : ident [ "::" [ path_glob
- | '*' ] ] ?
- | '{' path_item [ ',' path_item ] * '}' ;
-
-path_item : ident | "self" ;
-```
-
-### Functions
-
-**FIXME:** grammar?
-
-#### Generic functions
-
-**FIXME:** grammar?
-
-#### Unsafety
-
-**FIXME:** grammar?
-
-##### Unsafe functions
-
-**FIXME:** grammar?
-
-##### Unsafe blocks
-
-**FIXME:** grammar?
-
-#### Diverging functions
-
-**FIXME:** grammar?
-
-### Type definitions
-
-**FIXME:** grammar?
-
-### Structures
-
-**FIXME:** grammar?
-
-### Enumerations
-
-**FIXME:** grammar?
-
-### Constant items
-
-```antlr
-const_item : "const" ident ':' type '=' expr ';' ;
-```
-
-### Static items
-
-```antlr
-static_item : "static" ident ':' type '=' expr ';' ;
-```
-
-#### Mutable statics
-
-**FIXME:** grammar?
-
-### Traits
-
-**FIXME:** grammar?
-
-### Implementations
-
-**FIXME:** grammar?
-
-### External blocks
-
-```antlr
-extern_block_item : "extern" '{' extern_block '}' ;
-extern_block : [ foreign_fn ] * ;
-```
-
-## Visibility and Privacy
-
-```antlr
-vis : "pub" ;
-```
-### Re-exporting and Visibility
-
-See [Use declarations](#use-declarations).
-
-## Attributes
-
-```antlr
-attribute : '#' '!' ? '[' meta_item ']' ;
-meta_item : ident [ '=' literal
- | '(' meta_seq ')' ] ? ;
-meta_seq : meta_item [ ',' meta_seq ] ? ;
-```
-
-# Statements and expressions
-
-## Statements
-
-```antlr
-stmt : decl_stmt | expr_stmt | ';' ;
-```
-
-### Declaration statements
-
-```antlr
-decl_stmt : item | let_decl ;
-```
-
-#### Item declarations
-
-See [Items](#items).
-
-#### Variable declarations
-
-```antlr
-let_decl : "let" pat [':' type ] ? [ init ] ? ';' ;
-init : [ '=' ] expr ;
-```
-
-### Expression statements
-
-```antlr
-expr_stmt : expr ';' ;
-```
-
-## Expressions
-
-```antlr
-expr : literal | path | tuple_expr | unit_expr | struct_expr
- | block_expr | method_call_expr | field_expr | array_expr
- | idx_expr | range_expr | unop_expr | binop_expr
- | paren_expr | call_expr | lambda_expr | while_expr
- | loop_expr | break_expr | continue_expr | for_expr
- | if_expr | match_expr | if_let_expr | while_let_expr
- | return_expr ;
-```
-
-#### Lvalues, rvalues and temporaries
-
-**FIXME:** grammar?
-
-#### Moved and copied types
-
-**FIXME:** Do we want to capture this in the grammar as different productions?
-
-### Literal expressions
-
-See [Literals](#literals).
-
-### Path expressions
-
-See [Paths](#paths).
-
-### Tuple expressions
-
-```antlr
-tuple_expr : '(' [ expr [ ',' expr ] * | expr ',' ] ? ')' ;
-```
-
-### Unit expressions
-
-```antlr
-unit_expr : "()" ;
-```
-
-### Structure expressions
-
-```antlr
-struct_expr_field_init : ident | ident ':' expr ;
-struct_expr : expr_path '{' struct_expr_field_init
- [ ',' struct_expr_field_init ] *
- [ ".." expr ] '}' |
- expr_path '(' expr
- [ ',' expr ] * ')' |
- expr_path ;
-```
-
-### Block expressions
-
-```antlr
-block_expr : '{' [ stmt | item ] *
- [ expr ] '}' ;
-```
-
-### Method-call expressions
-
-```antlr
-method_call_expr : expr '.' ident paren_expr_list ;
-```
-
-### Field expressions
-
-```antlr
-field_expr : expr '.' ident ;
-```
-
-### Array expressions
-
-```antlr
-array_expr : '[' "mut" ? array_elems? ']' ;
-
-array_elems : [expr [',' expr]*] | [expr ';' expr] ;
-```
-
-### Index expressions
-
-```antlr
-idx_expr : expr '[' expr ']' ;
-```
-
-### Range expressions
-
-```antlr
-range_expr : expr ".." expr |
- expr ".." |
- ".." expr |
- ".." ;
-```
-
-### Unary operator expressions
-
-```antlr
-unop_expr : unop expr ;
-unop : '-' | '*' | '!' ;
-```
-
-### Binary operator expressions
-
-```antlr
-binop_expr : expr binop expr | type_cast_expr
- | assignment_expr | compound_assignment_expr ;
-binop : arith_op | bitwise_op | lazy_bool_op | comp_op
-```
-
-#### Arithmetic operators
-
-```antlr
-arith_op : '+' | '-' | '*' | '/' | '%' ;
-```
-
-#### Bitwise operators
-
-```antlr
-bitwise_op : '&' | '|' | '^' | "<<" | ">>" ;
-```
-
-#### Lazy boolean operators
-
-```antlr
-lazy_bool_op : "&&" | "||" ;
-```
-
-#### Comparison operators
-
-```antlr
-comp_op : "==" | "!=" | '<' | '>' | "<=" | ">=" ;
-```
-
-#### Type cast expressions
-
-```antlr
-type_cast_expr : value "as" type ;
-```
-
-#### Assignment expressions
-
-```antlr
-assignment_expr : expr '=' expr ;
-```
-
-#### Compound assignment expressions
-
-```antlr
-compound_assignment_expr : expr [ arith_op | bitwise_op ] '=' expr ;
-```
-
-### Grouped expressions
-
-```antlr
-paren_expr : '(' expr ')' ;
-```
-
-### Call expressions
-
-```antlr
-expr_list : [ expr [ ',' expr ]* ] ? ;
-paren_expr_list : '(' expr_list ')' ;
-call_expr : expr paren_expr_list ;
-```
-
-### Lambda expressions
-
-```antlr
-ident_list : [ ident [ ',' ident ]* ] ? ;
-lambda_expr : '|' ident_list '|' expr ;
-```
-
-### While loops
-
-```antlr
-while_expr : [ lifetime ':' ] ? "while" no_struct_literal_expr '{' block '}' ;
-```
-
-### Infinite loops
-
-```antlr
-loop_expr : [ lifetime ':' ] ? "loop" '{' block '}';
-```
-
-### Break expressions
-
-```antlr
-break_expr : "break" [ lifetime ] ?;
-```
-
-### Continue expressions
-
-```antlr
-continue_expr : "continue" [ lifetime ] ?;
-```
-
-### For expressions
-
-```antlr
-for_expr : [ lifetime ':' ] ? "for" pat "in" no_struct_literal_expr '{' block '}' ;
-```
-
-### If expressions
-
-```antlr
-if_expr : "if" no_struct_literal_expr '{' block '}'
- else_tail ? ;
-
-else_tail : "else" [ if_expr | if_let_expr
- | '{' block '}' ] ;
-```
-
-### Match expressions
-
-```antlr
-match_expr : "match" no_struct_literal_expr '{' match_arm * '}' ;
-
-match_arm : attribute * match_pat "=>" [ expr "," | '{' block '}' ] ;
-
-match_pat : pat [ '|' pat ] * [ "if" expr ] ? ;
-```
-
-### If let expressions
-
-```antlr
-if_let_expr : "if" "let" pat '=' expr '{' block '}'
- else_tail ? ;
-```
-
-### While let loops
-
-```antlr
-while_let_expr : [ lifetime ':' ] ? "while" "let" pat '=' expr '{' block '}' ;
-```
-
-### Return expressions
-
-```antlr
-return_expr : "return" expr ? ;
-```
-
-# Type system
-
-**FIXME:** is this entire chapter relevant here? Or should it all have been covered by some production already?
-
-## Types
-
-### Primitive types
-
-**FIXME:** grammar?
-
-#### Machine types
-
-**FIXME:** grammar?
-
-#### Machine-dependent integer types
-
-**FIXME:** grammar?
-
-### Textual types
-
-**FIXME:** grammar?
-
-### Tuple types
-
-**FIXME:** grammar?
-
-### Array, and Slice types
-
-**FIXME:** grammar?
-
-### Structure types
-
-**FIXME:** grammar?
-
-### Enumerated types
-
-**FIXME:** grammar?
-
-### Pointer types
-
-**FIXME:** grammar?
-
-### Function types
-
-**FIXME:** grammar?
-
-### Closure types
-
-```antlr
-closure_type := [ 'unsafe' ] [ '<' lifetime-list '>' ] '|' arg-list '|'
- [ ':' bound-list ] [ '->' type ]
-lifetime-list := lifetime | lifetime ',' lifetime-list
-arg-list := ident ':' type | ident ':' type ',' arg-list
-```
-
-### Never type
-An empty type
-
-```antlr
-never_type : "!" ;
-```
-
-### Object types
-
-**FIXME:** grammar?
-
-### Type parameters
-
-**FIXME:** grammar?
-
-### Type parameter bounds
-
-```antlr
-bound-list := bound | bound '+' bound-list '+' ?
-bound := ty_bound | lt_bound
-lt_bound := lifetime
-ty_bound := ty_bound_noparen | (ty_bound_noparen)
-ty_bound_noparen := [?] [ for ] simple_path
-```
-
-### Self types
-
-**FIXME:** grammar?
-
-## Type kinds
-
-**FIXME:** this is probably not relevant to the grammar...
-
-# Memory and concurrency models
-
-**FIXME:** is this entire chapter relevant here? Or should it all have been covered by some production already?
-
-## Memory model
-
-### Memory allocation and lifetime
-
-### Memory ownership
-
-### Variables
-
-### Boxes
-
-## Threads
-
-### Communication between threads
-
-### Thread lifecycle
+[reference]: https://doc.rust-lang.org/reference/
+[grammar working group]: https://github.com/rust-lang/wg-grammar
diff --git a/src/grammar/.gitignore b/src/grammar/.gitignore
deleted file mode 100644
index 3e4498759434f..0000000000000
--- a/src/grammar/.gitignore
+++ /dev/null
@@ -1,3 +0,0 @@
-*.class
-*.java
-*.tokens
diff --git a/src/grammar/lexer.l b/src/grammar/lexer.l
deleted file mode 100644
index 1feb781b2b39f..0000000000000
--- a/src/grammar/lexer.l
+++ /dev/null
@@ -1,350 +0,0 @@
-%{
-#include
-#include
-
-static int num_hashes;
-static int end_hashes;
-static int saw_non_hash;
-
-%}
-
-%option stack
-%option yylineno
-
-%x str
-%x rawstr
-%x rawstr_esc_begin
-%x rawstr_esc_body
-%x rawstr_esc_end
-%x byte
-%x bytestr
-%x rawbytestr
-%x rawbytestr_nohash
-%x pound
-%x shebang_or_attr
-%x ltorchar
-%x linecomment
-%x doc_line
-%x blockcomment
-%x doc_block
-%x suffix
-
-ident [a-zA-Z\x80-\xff_][a-zA-Z0-9\x80-\xff_]*
-
-%%
-
-{ident} { BEGIN(INITIAL); }
-(.|\n) { yyless(0); BEGIN(INITIAL); }
-
-[ \n\t\r] { }
-
-\xef\xbb\xbf {
- // UTF-8 byte order mark (BOM), ignore if in line 1, error otherwise
- if (yyget_lineno() != 1) {
- return -1;
- }
-}
-
-\/\/(\/|\!) { BEGIN(doc_line); yymore(); }
-\n { BEGIN(INITIAL);
- yyleng--;
- yytext[yyleng] = 0;
- return ((yytext[2] == '!') ? INNER_DOC_COMMENT : OUTER_DOC_COMMENT);
- }
-[^\n]* { yymore(); }
-
-\/\/|\/\/\/\/ { BEGIN(linecomment); }
-\n { BEGIN(INITIAL); }
-[^\n]* { }
-
-\/\*(\*|\!)[^*] { yy_push_state(INITIAL); yy_push_state(doc_block); yymore(); }
-\/\* { yy_push_state(doc_block); yymore(); }
-\*\/ {
- yy_pop_state();
- if (yy_top_state() == doc_block) {
- yymore();
- } else {
- return ((yytext[2] == '!') ? INNER_DOC_COMMENT : OUTER_DOC_COMMENT);
- }
-}
-(.|\n) { yymore(); }
-
-\/\* { yy_push_state(blockcomment); }
-\/\* { yy_push_state(blockcomment); }
-\*\/ { yy_pop_state(); }
-(.|\n) { }
-
-_ { return UNDERSCORE; }
-abstract { return ABSTRACT; }
-alignof { return ALIGNOF; }
-as { return AS; }
-become { return BECOME; }
-box { return BOX; }
-break { return BREAK; }
-catch { return CATCH; }
-const { return CONST; }
-continue { return CONTINUE; }
-crate { return CRATE; }
-default { return DEFAULT; }
-do { return DO; }
-else { return ELSE; }
-enum { return ENUM; }
-extern { return EXTERN; }
-false { return FALSE; }
-final { return FINAL; }
-fn { return FN; }
-for { return FOR; }
-if { return IF; }
-impl { return IMPL; }
-in { return IN; }
-let { return LET; }
-loop { return LOOP; }
-macro { return MACRO; }
-match { return MATCH; }
-mod { return MOD; }
-move { return MOVE; }
-mut { return MUT; }
-offsetof { return OFFSETOF; }
-override { return OVERRIDE; }
-priv { return PRIV; }
-proc { return PROC; }
-pure { return PURE; }
-pub { return PUB; }
-ref { return REF; }
-return { return RETURN; }
-self { return SELF; }
-sizeof { return SIZEOF; }
-static { return STATIC; }
-struct { return STRUCT; }
-super { return SUPER; }
-trait { return TRAIT; }
-true { return TRUE; }
-type { return TYPE; }
-typeof { return TYPEOF; }
-union { return UNION; }
-unsafe { return UNSAFE; }
-unsized { return UNSIZED; }
-use { return USE; }
-virtual { return VIRTUAL; }
-where { return WHERE; }
-while { return WHILE; }
-yield { return YIELD; }
-
-{ident} { return IDENT; }
-
-0x[0-9a-fA-F_]+ { BEGIN(suffix); return LIT_INTEGER; }
-0o[0-7_]+ { BEGIN(suffix); return LIT_INTEGER; }
-0b[01_]+ { BEGIN(suffix); return LIT_INTEGER; }
-[0-9][0-9_]* { BEGIN(suffix); return LIT_INTEGER; }
-[0-9][0-9_]*\.(\.|[a-zA-Z]) { yyless(yyleng - 2); BEGIN(suffix); return LIT_INTEGER; }
-
-[0-9][0-9_]*\.[0-9_]*([eE][-\+]?[0-9_]+)? { BEGIN(suffix); return LIT_FLOAT; }
-[0-9][0-9_]*(\.[0-9_]*)?[eE][-\+]?[0-9_]+ { BEGIN(suffix); return LIT_FLOAT; }
-
-; { return ';'; }
-, { return ','; }
-\.\.\. { return DOTDOTDOT; }
-\.\. { return DOTDOT; }
-\. { return '.'; }
-\( { return '('; }
-\) { return ')'; }
-\{ { return '{'; }
-\} { return '}'; }
-\[ { return '['; }
-\] { return ']'; }
-@ { return '@'; }
-# { BEGIN(pound); yymore(); }
-\! { BEGIN(shebang_or_attr); yymore(); }
-\[ {
- BEGIN(INITIAL);
- yyless(2);
- return SHEBANG;
-}
-[^\[\n]*\n {
- // Since the \n was eaten as part of the token, yylineno will have
- // been incremented to the value 2 if the shebang was on the first
- // line. This yyless undoes that, setting yylineno back to 1.
- yyless(yyleng - 1);
- if (yyget_lineno() == 1) {
- BEGIN(INITIAL);
- return SHEBANG_LINE;
- } else {
- BEGIN(INITIAL);
- yyless(2);
- return SHEBANG;
- }
-}
-. { BEGIN(INITIAL); yyless(1); return '#'; }
-
-\~ { return '~'; }
-:: { return MOD_SEP; }
-: { return ':'; }
-\$ { return '$'; }
-\? { return '?'; }
-
-== { return EQEQ; }
-=> { return FAT_ARROW; }
-= { return '='; }
-\!= { return NE; }
-\! { return '!'; }
-\<= { return LE; }
-\<\< { return SHL; }
-\<\<= { return SHLEQ; }
-\< { return '<'; }
-\>= { return GE; }
-\>\> { return SHR; }
-\>\>= { return SHREQ; }
-\> { return '>'; }
-
-\x27 { BEGIN(ltorchar); yymore(); }
-static { BEGIN(INITIAL); return STATIC_LIFETIME; }
-{ident} { BEGIN(INITIAL); return LIFETIME; }
-\\[nrt\\\x27\x220]\x27 { BEGIN(suffix); return LIT_CHAR; }
-\\x[0-9a-fA-F]{2}\x27 { BEGIN(suffix); return LIT_CHAR; }
-\\u\{([0-9a-fA-F]_*){1,6}\}\x27 { BEGIN(suffix); return LIT_CHAR; }
-.\x27 { BEGIN(suffix); return LIT_CHAR; }
-[\x80-\xff]{2,4}\x27 { BEGIN(suffix); return LIT_CHAR; }
-<> { BEGIN(INITIAL); return -1; }
-
-b\x22 { BEGIN(bytestr); yymore(); }
-\x22 { BEGIN(suffix); return LIT_BYTE_STR; }
-
-<> { return -1; }
-\\[n\nrt\\\x27\x220] { yymore(); }
-\\x[0-9a-fA-F]{2} { yymore(); }
-\\u\{([0-9a-fA-F]_*){1,6}\} { yymore(); }
-\\[^n\nrt\\\x27\x220] { return -1; }
-(.|\n) { yymore(); }
-
-br\x22 { BEGIN(rawbytestr_nohash); yymore(); }
-\x22 { BEGIN(suffix); return LIT_BYTE_STR_RAW; }
-(.|\n) { yymore(); }
-<> { return -1; }
-
-br/# {
- BEGIN(rawbytestr);
- yymore();
- num_hashes = 0;
- saw_non_hash = 0;
- end_hashes = 0;
-}
-# {
- if (!saw_non_hash) {
- num_hashes++;
- } else if (end_hashes != 0) {
- end_hashes++;
- if (end_hashes == num_hashes) {
- BEGIN(INITIAL);
- return LIT_BYTE_STR_RAW;
- }
- }
- yymore();
-}
-\x22# {
- end_hashes = 1;
- if (end_hashes == num_hashes) {
- BEGIN(INITIAL);
- return LIT_BYTE_STR_RAW;
- }
- yymore();
-}
-(.|\n) {
- if (!saw_non_hash) {
- saw_non_hash = 1;
- }
- if (end_hashes != 0) {
- end_hashes = 0;
- }
- yymore();
-}
-<> { return -1; }
-
-b\x27 { BEGIN(byte); yymore(); }
-\\[nrt\\\x27\x220]\x27 { BEGIN(INITIAL); return LIT_BYTE; }
-\\x[0-9a-fA-F]{2}\x27 { BEGIN(INITIAL); return LIT_BYTE; }
-\\u([0-9a-fA-F]_*){4}\x27 { BEGIN(INITIAL); return LIT_BYTE; }
-\\U([0-9a-fA-F]_*){8}\x27 { BEGIN(INITIAL); return LIT_BYTE; }
-.\x27 { BEGIN(INITIAL); return LIT_BYTE; }
-<> { BEGIN(INITIAL); return -1; }
-
-r\x22 { BEGIN(rawstr); yymore(); }
-\x22 { BEGIN(suffix); return LIT_STR_RAW; }
-(.|\n) { yymore(); }
-<> { return -1; }
-
-r/# {
- BEGIN(rawstr_esc_begin);
- yymore();
- num_hashes = 0;
- saw_non_hash = 0;
- end_hashes = 0;
-}
-
-# {
- num_hashes++;
- yymore();
-}
-\x22 {
- BEGIN(rawstr_esc_body);
- yymore();
-}
-(.|\n) { return -1; }
-
-\x22/# {
- BEGIN(rawstr_esc_end);
- yymore();
- }
-(.|\n) {
- yymore();
- }
-
-# {
- end_hashes++;
- if (end_hashes == num_hashes) {
- BEGIN(INITIAL);
- return LIT_STR_RAW;
- }
- yymore();
- }
-[^#] {
- end_hashes = 0;
- BEGIN(rawstr_esc_body);
- yymore();
- }
-
-<> { return -1; }
-
-\x22 { BEGIN(str); yymore(); }
-\x22 { BEGIN(suffix); return LIT_STR; }
-
-<> { return -1; }
-\\[n\nr\rt\\\x27\x220] { yymore(); }
-\\x[0-9a-fA-F]{2} { yymore(); }
-\\u\{([0-9a-fA-F]_*){1,6}\} { yymore(); }
-\\[^n\nrt\\\x27\x220] { return -1; }
-(.|\n) { yymore(); }
-
-\<- { return LARROW; }
--\> { return RARROW; }
-- { return '-'; }
--= { return MINUSEQ; }
-&& { return ANDAND; }
-& { return '&'; }
-&= { return ANDEQ; }
-\|\| { return OROR; }
-\| { return '|'; }
-\|= { return OREQ; }
-\+ { return '+'; }
-\+= { return PLUSEQ; }
-\* { return '*'; }
-\*= { return STAREQ; }
-\/ { return '/'; }
-\/= { return SLASHEQ; }
-\^ { return '^'; }
-\^= { return CARETEQ; }
-% { return '%'; }
-%= { return PERCENTEQ; }
-
-<> { return 0; }
-
-%%
diff --git a/src/grammar/parser-lalr-main.c b/src/grammar/parser-lalr-main.c
deleted file mode 100644
index 6348190cc140b..0000000000000
--- a/src/grammar/parser-lalr-main.c
+++ /dev/null
@@ -1,193 +0,0 @@
-#include
-#include
-#include
-#include
-
-extern int yylex();
-extern int rsparse();
-
-#define PUSHBACK_LEN 4
-
-static char pushback[PUSHBACK_LEN];
-static int verbose;
-
-void print(const char* format, ...) {
- va_list args;
- va_start(args, format);
- if (verbose) {
- vprintf(format, args);
- }
- va_end(args);
-}
-
-// If there is a non-null char at the head of the pushback queue,
-// dequeue it and shift the rest of the queue forwards. Otherwise,
-// return the token from calling yylex.
-int rslex() {
- if (pushback[0] == '\0') {
- return yylex();
- } else {
- char c = pushback[0];
- memmove(pushback, pushback + 1, PUSHBACK_LEN - 1);
- pushback[PUSHBACK_LEN - 1] = '\0';
- return c;
- }
-}
-
-// Note: this does nothing if the pushback queue is full. As long as
-// there aren't more than PUSHBACK_LEN consecutive calls to push_back
-// in an action, this shouldn't be a problem.
-void push_back(char c) {
- for (int i = 0; i < PUSHBACK_LEN; ++i) {
- if (pushback[i] == '\0') {
- pushback[i] = c;
- break;
- }
- }
-}
-
-extern int rsdebug;
-
-struct node {
- struct node *next;
- struct node *prev;
- int own_string;
- char const *name;
- int n_elems;
- struct node *elems[];
-};
-
-struct node *nodes = NULL;
-int n_nodes;
-
-struct node *mk_node(char const *name, int n, ...) {
- va_list ap;
- int i = 0;
- unsigned sz = sizeof(struct node) + (n * sizeof(struct node *));
- struct node *nn, *nd = (struct node *)malloc(sz);
-
- print("# New %d-ary node: %s = %p\n", n, name, nd);
-
- nd->own_string = 0;
- nd->prev = NULL;
- nd->next = nodes;
- if (nodes) {
- nodes->prev = nd;
- }
- nodes = nd;
-
- nd->name = name;
- nd->n_elems = n;
-
- va_start(ap, n);
- while (i < n) {
- nn = va_arg(ap, struct node *);
- print("# arg[%d]: %p\n", i, nn);
- print("# (%s ...)\n", nn->name);
- nd->elems[i++] = nn;
- }
- va_end(ap);
- n_nodes++;
- return nd;
-}
-
-struct node *mk_atom(char *name) {
- struct node *nd = mk_node((char const *)strdup(name), 0);
- nd->own_string = 1;
- return nd;
-}
-
-struct node *mk_none() {
- return mk_atom("");
-}
-
-struct node *ext_node(struct node *nd, int n, ...) {
- va_list ap;
- int i = 0, c = nd->n_elems + n;
- unsigned sz = sizeof(struct node) + (c * sizeof(struct node *));
- struct node *nn;
-
- print("# Extending %d-ary node by %d nodes: %s = %p",
- nd->n_elems, c, nd->name, nd);
-
- if (nd->next) {
- nd->next->prev = nd->prev;
- }
- if (nd->prev) {
- nd->prev->next = nd->next;
- }
- nd = realloc(nd, sz);
- nd->prev = NULL;
- nd->next = nodes;
- nodes->prev = nd;
- nodes = nd;
-
- print(" ==> %p\n", nd);
-
- va_start(ap, n);
- while (i < n) {
- nn = va_arg(ap, struct node *);
- print("# arg[%d]: %p\n", i, nn);
- print("# (%s ...)\n", nn->name);
- nd->elems[nd->n_elems++] = nn;
- ++i;
- }
- va_end(ap);
- return nd;
-}
-
-int const indent_step = 4;
-
-void print_indent(int depth) {
- while (depth) {
- if (depth-- % indent_step == 0) {
- print("|");
- } else {
- print(" ");
- }
- }
-}
-
-void print_node(struct node *n, int depth) {
- int i = 0;
- print_indent(depth);
- if (n->n_elems == 0) {
- print("%s\n", n->name);
- } else {
- print("(%s\n", n->name);
- for (i = 0; i < n->n_elems; ++i) {
- print_node(n->elems[i], depth + indent_step);
- }
- print_indent(depth);
- print(")\n");
- }
-}
-
-int main(int argc, char **argv) {
- if (argc == 2 && strcmp(argv[1], "-v") == 0) {
- verbose = 1;
- } else {
- verbose = 0;
- }
- int ret = 0;
- struct node *tmp;
- memset(pushback, '\0', PUSHBACK_LEN);
- ret = rsparse();
- print("--- PARSE COMPLETE: ret:%d, n_nodes:%d ---\n", ret, n_nodes);
- if (nodes) {
- print_node(nodes, 0);
- }
- while (nodes) {
- tmp = nodes;
- nodes = tmp->next;
- if (tmp->own_string) {
- free((void*)tmp->name);
- }
- free(tmp);
- }
- return ret;
-}
-
-void rserror(char const *s) {
- fprintf(stderr, "%s\n", s);
-}
diff --git a/src/grammar/parser-lalr.y b/src/grammar/parser-lalr.y
deleted file mode 100644
index 5585c95a5a63a..0000000000000
--- a/src/grammar/parser-lalr.y
+++ /dev/null
@@ -1,1982 +0,0 @@
-%{
-#define YYERROR_VERBOSE
-#define YYSTYPE struct node *
-struct node;
-extern int yylex();
-extern void yyerror(char const *s);
-extern struct node *mk_node(char const *name, int n, ...);
-extern struct node *mk_atom(char *text);
-extern struct node *mk_none();
-extern struct node *ext_node(struct node *nd, int n, ...);
-extern void push_back(char c);
-extern char *yytext;
-%}
-%debug
-
-%token SHL
-%token SHR
-%token LE
-%token EQEQ
-%token NE
-%token GE
-%token ANDAND
-%token OROR
-%token SHLEQ
-%token SHREQ
-%token MINUSEQ
-%token ANDEQ
-%token OREQ
-%token PLUSEQ
-%token STAREQ
-%token SLASHEQ
-%token CARETEQ
-%token PERCENTEQ
-%token DOTDOT
-%token DOTDOTDOT
-%token MOD_SEP
-%token RARROW
-%token LARROW
-%token FAT_ARROW
-%token LIT_BYTE
-%token LIT_CHAR
-%token LIT_INTEGER
-%token LIT_FLOAT
-%token LIT_STR
-%token LIT_STR_RAW
-%token LIT_BYTE_STR
-%token LIT_BYTE_STR_RAW
-%token IDENT
-%token UNDERSCORE
-%token LIFETIME
-
-// keywords
-%token SELF
-%token STATIC
-%token ABSTRACT
-%token ALIGNOF
-%token AS
-%token BECOME
-%token BREAK
-%token CATCH
-%token CRATE
-%token DO
-%token ELSE
-%token ENUM
-%token EXTERN
-%token FALSE
-%token FINAL
-%token FN
-%token FOR
-%token IF
-%token IMPL
-%token IN
-%token LET
-%token LOOP
-%token MACRO
-%token MATCH
-%token MOD
-%token MOVE
-%token MUT
-%token OFFSETOF
-%token OVERRIDE
-%token PRIV
-%token PUB
-%token PURE
-%token REF
-%token RETURN
-%token SIZEOF
-%token STRUCT
-%token SUPER
-%token UNION
-%token UNSIZED
-%token TRUE
-%token TRAIT
-%token TYPE
-%token UNSAFE
-%token VIRTUAL
-%token YIELD
-%token DEFAULT
-%token USE
-%token WHILE
-%token CONTINUE
-%token PROC
-%token BOX
-%token CONST
-%token WHERE
-%token TYPEOF
-%token INNER_DOC_COMMENT
-%token OUTER_DOC_COMMENT
-
-%token SHEBANG
-%token SHEBANG_LINE
-%token STATIC_LIFETIME
-
- /*
- Quoting from the Bison manual:
-
- "Finally, the resolution of conflicts works by comparing the precedence
- of the rule being considered with that of the lookahead token. If the
- token's precedence is higher, the choice is to shift. If the rule's
- precedence is higher, the choice is to reduce. If they have equal
- precedence, the choice is made based on the associativity of that
- precedence level. The verbose output file made by ‘-v’ (see Invoking
- Bison) says how each conflict was resolved"
- */
-
-// We expect no shift/reduce or reduce/reduce conflicts in this grammar;
-// all potential ambiguities are scrutinized and eliminated manually.
-%expect 0
-
-// fake-precedence symbol to cause '|' bars in lambda context to parse
-// at low precedence, permit things like |x| foo = bar, where '=' is
-// otherwise lower-precedence than '|'. Also used for proc() to cause
-// things like proc() a + b to parse as proc() { a + b }.
-%precedence LAMBDA
-
-%precedence SELF
-
-// MUT should be lower precedence than IDENT so that in the pat rule,
-// "& MUT pat" has higher precedence than "binding_mode ident [@ pat]"
-%precedence MUT
-
-// IDENT needs to be lower than '{' so that 'foo {' is shifted when
-// trying to decide if we've got a struct-construction expr (esp. in
-// contexts like 'if foo { .')
-//
-// IDENT also needs to be lower precedence than '<' so that '<' in
-// 'foo:bar . <' is shifted (in a trait reference occurring in a
-// bounds list), parsing as foo:(bar) rather than (foo:bar).
-%precedence IDENT
- // Put the weak keywords that can be used as idents here as well
-%precedence CATCH
-%precedence DEFAULT
-%precedence UNION
-
-// A couple fake-precedence symbols to use in rules associated with +
-// and < in trailing type contexts. These come up when you have a type
-// in the RHS of operator-AS, such as "foo as bar". The "<" there
-// has to be shifted so the parser keeps trying to parse a type, even
-// though it might well consider reducing the type "bar" and then
-// going on to "<" as a subsequent binop. The "+" case is with
-// trailing type-bounds ("foo as bar:A+B"), for the same reason.
-%precedence SHIFTPLUS
-
-%precedence MOD_SEP
-%precedence RARROW ':'
-
-// In where clauses, "for" should have greater precedence when used as
-// a higher ranked constraint than when used as the beginning of a
-// for_in_type (which is a ty)
-%precedence FORTYPE
-%precedence FOR
-
-// Binops & unops, and their precedences
-%precedence '?'
-%precedence BOX
-%nonassoc DOTDOT
-
-// RETURN needs to be lower-precedence than tokens that start
-// prefix_exprs
-%precedence RETURN YIELD
-
-%right '=' SHLEQ SHREQ MINUSEQ ANDEQ OREQ PLUSEQ STAREQ SLASHEQ CARETEQ PERCENTEQ
-%right LARROW
-%left OROR
-%left ANDAND
-%left EQEQ NE
-%left '<' '>' LE GE
-%left '|'
-%left '^'
-%left '&'
-%left SHL SHR
-%left '+' '-'
-%precedence AS
-%left '*' '/' '%'
-%precedence '!'
-
-%precedence '{' '[' '(' '.'
-
-%precedence RANGE
-
-%start crate
-
-%%
-
-////////////////////////////////////////////////////////////////////////
-// Part 1: Items and attributes
-////////////////////////////////////////////////////////////////////////
-
-crate
-: maybe_shebang inner_attrs maybe_mod_items { mk_node("crate", 2, $2, $3); }
-| maybe_shebang maybe_mod_items { mk_node("crate", 1, $2); }
-;
-
-maybe_shebang
-: SHEBANG_LINE
-| %empty
-;
-
-maybe_inner_attrs
-: inner_attrs
-| %empty { $$ = mk_none(); }
-;
-
-inner_attrs
-: inner_attr { $$ = mk_node("InnerAttrs", 1, $1); }
-| inner_attrs inner_attr { $$ = ext_node($1, 1, $2); }
-;
-
-inner_attr
-: SHEBANG '[' meta_item ']' { $$ = mk_node("InnerAttr", 1, $3); }
-| INNER_DOC_COMMENT { $$ = mk_node("InnerAttr", 1, mk_node("doc-comment", 1, mk_atom(yytext))); }
-;
-
-maybe_outer_attrs
-: outer_attrs
-| %empty { $$ = mk_none(); }
-;
-
-outer_attrs
-: outer_attr { $$ = mk_node("OuterAttrs", 1, $1); }
-| outer_attrs outer_attr { $$ = ext_node($1, 1, $2); }
-;
-
-outer_attr
-: '#' '[' meta_item ']' { $$ = $3; }
-| OUTER_DOC_COMMENT { $$ = mk_node("doc-comment", 1, mk_atom(yytext)); }
-;
-
-meta_item
-: ident { $$ = mk_node("MetaWord", 1, $1); }
-| ident '=' lit { $$ = mk_node("MetaNameValue", 2, $1, $3); }
-| ident '(' meta_seq ')' { $$ = mk_node("MetaList", 2, $1, $3); }
-| ident '(' meta_seq ',' ')' { $$ = mk_node("MetaList", 2, $1, $3); }
-;
-
-meta_seq
-: %empty { $$ = mk_none(); }
-| meta_item { $$ = mk_node("MetaItems", 1, $1); }
-| meta_seq ',' meta_item { $$ = ext_node($1, 1, $3); }
-;
-
-maybe_mod_items
-: mod_items
-| %empty { $$ = mk_none(); }
-;
-
-mod_items
-: mod_item { $$ = mk_node("Items", 1, $1); }
-| mod_items mod_item { $$ = ext_node($1, 1, $2); }
-;
-
-attrs_and_vis
-: maybe_outer_attrs visibility { $$ = mk_node("AttrsAndVis", 2, $1, $2); }
-;
-
-mod_item
-: attrs_and_vis item { $$ = mk_node("Item", 2, $1, $2); }
-;
-
-// items that can appear outside of a fn block
-item
-: stmt_item
-| item_macro
-;
-
-// items that can appear in "stmts"
-stmt_item
-: item_static
-| item_const
-| item_type
-| block_item
-| view_item
-;
-
-item_static
-: STATIC ident ':' ty '=' expr ';' { $$ = mk_node("ItemStatic", 3, $2, $4, $6); }
-| STATIC MUT ident ':' ty '=' expr ';' { $$ = mk_node("ItemStatic", 3, $3, $5, $7); }
-;
-
-item_const
-: CONST ident ':' ty '=' expr ';' { $$ = mk_node("ItemConst", 3, $2, $4, $6); }
-;
-
-item_macro
-: path_expr '!' maybe_ident parens_delimited_token_trees ';' { $$ = mk_node("ItemMacro", 3, $1, $3, $4); }
-| path_expr '!' maybe_ident braces_delimited_token_trees { $$ = mk_node("ItemMacro", 3, $1, $3, $4); }
-| path_expr '!' maybe_ident brackets_delimited_token_trees ';'{ $$ = mk_node("ItemMacro", 3, $1, $3, $4); }
-;
-
-view_item
-: use_item
-| extern_fn_item
-| EXTERN CRATE ident ';' { $$ = mk_node("ViewItemExternCrate", 1, $3); }
-| EXTERN CRATE ident AS ident ';' { $$ = mk_node("ViewItemExternCrate", 2, $3, $5); }
-;
-
-extern_fn_item
-: EXTERN maybe_abi item_fn { $$ = mk_node("ViewItemExternFn", 2, $2, $3); }
-;
-
-use_item
-: USE view_path ';' { $$ = mk_node("ViewItemUse", 1, $2); }
-;
-
-view_path
-: path_no_types_allowed { $$ = mk_node("ViewPathSimple", 1, $1); }
-| path_no_types_allowed MOD_SEP '{' '}' { $$ = mk_node("ViewPathList", 2, $1, mk_atom("ViewPathListEmpty")); }
-| MOD_SEP '{' '}' { $$ = mk_node("ViewPathList", 1, mk_atom("ViewPathListEmpty")); }
-| path_no_types_allowed MOD_SEP '{' idents_or_self '}' { $$ = mk_node("ViewPathList", 2, $1, $4); }
-| MOD_SEP '{' idents_or_self '}' { $$ = mk_node("ViewPathList", 1, $3); }
-| path_no_types_allowed MOD_SEP '{' idents_or_self ',' '}' { $$ = mk_node("ViewPathList", 2, $1, $4); }
-| MOD_SEP '{' idents_or_self ',' '}' { $$ = mk_node("ViewPathList", 1, $3); }
-| path_no_types_allowed MOD_SEP '*' { $$ = mk_node("ViewPathGlob", 1, $1); }
-| MOD_SEP '*' { $$ = mk_atom("ViewPathGlob"); }
-| '*' { $$ = mk_atom("ViewPathGlob"); }
-| '{' '}' { $$ = mk_atom("ViewPathListEmpty"); }
-| '{' idents_or_self '}' { $$ = mk_node("ViewPathList", 1, $2); }
-| '{' idents_or_self ',' '}' { $$ = mk_node("ViewPathList", 1, $2); }
-| path_no_types_allowed AS ident { $$ = mk_node("ViewPathSimple", 2, $1, $3); }
-;
-
-block_item
-: item_fn
-| item_unsafe_fn
-| item_mod
-| item_foreign_mod { $$ = mk_node("ItemForeignMod", 1, $1); }
-| item_struct
-| item_enum
-| item_union
-| item_trait
-| item_impl
-;
-
-maybe_ty_ascription
-: ':' ty_sum { $$ = $2; }
-| %empty { $$ = mk_none(); }
-;
-
-maybe_init_expr
-: '=' expr { $$ = $2; }
-| %empty { $$ = mk_none(); }
-;
-
-// structs
-item_struct
-: STRUCT ident generic_params maybe_where_clause struct_decl_args
-{
- $$ = mk_node("ItemStruct", 4, $2, $3, $4, $5);
-}
-| STRUCT ident generic_params struct_tuple_args maybe_where_clause ';'
-{
- $$ = mk_node("ItemStruct", 4, $2, $3, $4, $5);
-}
-| STRUCT ident generic_params maybe_where_clause ';'
-{
- $$ = mk_node("ItemStruct", 3, $2, $3, $4);
-}
-;
-
-struct_decl_args
-: '{' struct_decl_fields '}' { $$ = $2; }
-| '{' struct_decl_fields ',' '}' { $$ = $2; }
-;
-
-struct_tuple_args
-: '(' struct_tuple_fields ')' { $$ = $2; }
-| '(' struct_tuple_fields ',' ')' { $$ = $2; }
-;
-
-struct_decl_fields
-: struct_decl_field { $$ = mk_node("StructFields", 1, $1); }
-| struct_decl_fields ',' struct_decl_field { $$ = ext_node($1, 1, $3); }
-| %empty { $$ = mk_none(); }
-;
-
-struct_decl_field
-: attrs_and_vis ident ':' ty_sum { $$ = mk_node("StructField", 3, $1, $2, $4); }
-;
-
-struct_tuple_fields
-: struct_tuple_field { $$ = mk_node("StructFields", 1, $1); }
-| struct_tuple_fields ',' struct_tuple_field { $$ = ext_node($1, 1, $3); }
-| %empty { $$ = mk_none(); }
-;
-
-struct_tuple_field
-: attrs_and_vis ty_sum { $$ = mk_node("StructField", 2, $1, $2); }
-;
-
-// enums
-item_enum
-: ENUM ident generic_params maybe_where_clause '{' enum_defs '}' { $$ = mk_node("ItemEnum", 0); }
-| ENUM ident generic_params maybe_where_clause '{' enum_defs ',' '}' { $$ = mk_node("ItemEnum", 0); }
-;
-
-enum_defs
-: enum_def { $$ = mk_node("EnumDefs", 1, $1); }
-| enum_defs ',' enum_def { $$ = ext_node($1, 1, $3); }
-| %empty { $$ = mk_none(); }
-;
-
-enum_def
-: attrs_and_vis ident enum_args { $$ = mk_node("EnumDef", 3, $1, $2, $3); }
-;
-
-enum_args
-: '{' struct_decl_fields '}' { $$ = mk_node("EnumArgs", 1, $2); }
-| '{' struct_decl_fields ',' '}' { $$ = mk_node("EnumArgs", 1, $2); }
-| '(' maybe_ty_sums ')' { $$ = mk_node("EnumArgs", 1, $2); }
-| '=' expr { $$ = mk_node("EnumArgs", 1, $2); }
-| %empty { $$ = mk_none(); }
-;
-
-// unions
-item_union
-: UNION ident generic_params maybe_where_clause '{' struct_decl_fields '}' { $$ = mk_node("ItemUnion", 0); }
-| UNION ident generic_params maybe_where_clause '{' struct_decl_fields ',' '}' { $$ = mk_node("ItemUnion", 0); }
-
-item_mod
-: MOD ident ';' { $$ = mk_node("ItemMod", 1, $2); }
-| MOD ident '{' maybe_mod_items '}' { $$ = mk_node("ItemMod", 2, $2, $4); }
-| MOD ident '{' inner_attrs maybe_mod_items '}' { $$ = mk_node("ItemMod", 3, $2, $4, $5); }
-;
-
-item_foreign_mod
-: EXTERN maybe_abi '{' maybe_foreign_items '}' { $$ = mk_node("ItemForeignMod", 1, $4); }
-| EXTERN maybe_abi '{' inner_attrs maybe_foreign_items '}' { $$ = mk_node("ItemForeignMod", 2, $4, $5); }
-;
-
-maybe_abi
-: str
-| %empty { $$ = mk_none(); }
-;
-
-maybe_foreign_items
-: foreign_items
-| %empty { $$ = mk_none(); }
-;
-
-foreign_items
-: foreign_item { $$ = mk_node("ForeignItems", 1, $1); }
-| foreign_items foreign_item { $$ = ext_node($1, 1, $2); }
-;
-
-foreign_item
-: attrs_and_vis STATIC item_foreign_static { $$ = mk_node("ForeignItem", 2, $1, $3); }
-| attrs_and_vis item_foreign_fn { $$ = mk_node("ForeignItem", 2, $1, $2); }
-| attrs_and_vis UNSAFE item_foreign_fn { $$ = mk_node("ForeignItem", 2, $1, $3); }
-;
-
-item_foreign_static
-: maybe_mut ident ':' ty ';' { $$ = mk_node("StaticItem", 3, $1, $2, $4); }
-;
-
-item_foreign_fn
-: FN ident generic_params fn_decl_allow_variadic maybe_where_clause ';' { $$ = mk_node("ForeignFn", 4, $2, $3, $4, $5); }
-;
-
-fn_decl_allow_variadic
-: fn_params_allow_variadic ret_ty { $$ = mk_node("FnDecl", 2, $1, $2); }
-;
-
-fn_params_allow_variadic
-: '(' ')' { $$ = mk_none(); }
-| '(' params ')' { $$ = $2; }
-| '(' params ',' ')' { $$ = $2; }
-| '(' params ',' DOTDOTDOT ')' { $$ = $2; }
-;
-
-visibility
-: PUB { $$ = mk_atom("Public"); }
-| %empty { $$ = mk_atom("Inherited"); }
-;
-
-idents_or_self
-: ident_or_self { $$ = mk_node("IdentsOrSelf", 1, $1); }
-| idents_or_self AS ident { $$ = mk_node("IdentsOrSelf", 2, $1, $3); }
-| idents_or_self ',' ident_or_self { $$ = ext_node($1, 1, $3); }
-;
-
-ident_or_self
-: ident
-| SELF { $$ = mk_atom(yytext); }
-;
-
-item_type
-: TYPE ident generic_params maybe_where_clause '=' ty_sum ';' { $$ = mk_node("ItemTy", 4, $2, $3, $4, $6); }
-;
-
-for_sized
-: FOR '?' ident { $$ = mk_node("ForSized", 1, $3); }
-| FOR ident '?' { $$ = mk_node("ForSized", 1, $2); }
-| %empty { $$ = mk_none(); }
-;
-
-item_trait
-: maybe_unsafe TRAIT ident generic_params for_sized maybe_ty_param_bounds maybe_where_clause '{' maybe_trait_items '}'
-{
- $$ = mk_node("ItemTrait", 7, $1, $3, $4, $5, $6, $7, $9);
-}
-;
-
-maybe_trait_items
-: trait_items
-| %empty { $$ = mk_none(); }
-;
-
-trait_items
-: trait_item { $$ = mk_node("TraitItems", 1, $1); }
-| trait_items trait_item { $$ = ext_node($1, 1, $2); }
-;
-
-trait_item
-: trait_const
-| trait_type
-| trait_method
-| maybe_outer_attrs item_macro { $$ = mk_node("TraitMacroItem", 2, $1, $2); }
-;
-
-trait_const
-: maybe_outer_attrs CONST ident maybe_ty_ascription maybe_const_default ';' { $$ = mk_node("ConstTraitItem", 4, $1, $3, $4, $5); }
-;
-
-maybe_const_default
-: '=' expr { $$ = mk_node("ConstDefault", 1, $2); }
-| %empty { $$ = mk_none(); }
-;
-
-trait_type
-: maybe_outer_attrs TYPE ty_param ';' { $$ = mk_node("TypeTraitItem", 2, $1, $3); }
-;
-
-maybe_unsafe
-: UNSAFE { $$ = mk_atom("Unsafe"); }
-| %empty { $$ = mk_none(); }
-;
-
-maybe_default_maybe_unsafe
-: DEFAULT UNSAFE { $$ = mk_atom("DefaultUnsafe"); }
-| DEFAULT { $$ = mk_atom("Default"); }
-| UNSAFE { $$ = mk_atom("Unsafe"); }
-| %empty { $$ = mk_none(); }
-
-trait_method
-: type_method { $$ = mk_node("Required", 1, $1); }
-| method { $$ = mk_node("Provided", 1, $1); }
-;
-
-type_method
-: maybe_outer_attrs maybe_unsafe FN ident generic_params fn_decl_with_self_allow_anon_params maybe_where_clause ';'
-{
- $$ = mk_node("TypeMethod", 6, $1, $2, $4, $5, $6, $7);
-}
-| maybe_outer_attrs CONST maybe_unsafe FN ident generic_params fn_decl_with_self_allow_anon_params maybe_where_clause ';'
-{
- $$ = mk_node("TypeMethod", 6, $1, $3, $5, $6, $7, $8);
-}
-| maybe_outer_attrs maybe_unsafe EXTERN maybe_abi FN ident generic_params fn_decl_with_self_allow_anon_params maybe_where_clause ';'
-{
- $$ = mk_node("TypeMethod", 7, $1, $2, $4, $6, $7, $8, $9);
-}
-;
-
-method
-: maybe_outer_attrs maybe_unsafe FN ident generic_params fn_decl_with_self_allow_anon_params maybe_where_clause inner_attrs_and_block
-{
- $$ = mk_node("Method", 7, $1, $2, $4, $5, $6, $7, $8);
-}
-| maybe_outer_attrs CONST maybe_unsafe FN ident generic_params fn_decl_with_self_allow_anon_params maybe_where_clause inner_attrs_and_block
-{
- $$ = mk_node("Method", 7, $1, $3, $5, $6, $7, $8, $9);
-}
-| maybe_outer_attrs maybe_unsafe EXTERN maybe_abi FN ident generic_params fn_decl_with_self_allow_anon_params maybe_where_clause inner_attrs_and_block
-{
- $$ = mk_node("Method", 8, $1, $2, $4, $6, $7, $8, $9, $10);
-}
-;
-
-impl_method
-: attrs_and_vis maybe_default maybe_unsafe FN ident generic_params fn_decl_with_self maybe_where_clause inner_attrs_and_block
-{
- $$ = mk_node("Method", 8, $1, $2, $3, $5, $6, $7, $8, $9);
-}
-| attrs_and_vis maybe_default CONST maybe_unsafe FN ident generic_params fn_decl_with_self maybe_where_clause inner_attrs_and_block
-{
- $$ = mk_node("Method", 8, $1, $2, $4, $6, $7, $8, $9, $10);
-}
-| attrs_and_vis maybe_default maybe_unsafe EXTERN maybe_abi FN ident generic_params fn_decl_with_self maybe_where_clause inner_attrs_and_block
-{
- $$ = mk_node("Method", 9, $1, $2, $3, $5, $7, $8, $9, $10, $11);
-}
-;
-
-// There are two forms of impl:
-//
-// impl (<...>)? TY { ... }
-// impl (<...>)? TRAIT for TY { ... }
-//
-// Unfortunately since TY can begin with '<' itself -- as part of a
-// TyQualifiedPath type -- there's an s/r conflict when we see '<' after IMPL:
-// should we reduce one of the early rules of TY (such as maybe_once)
-// or shall we continue shifting into the generic_params list for the
-// impl?
-//
-// The production parser disambiguates a different case here by
-// permitting / requiring the user to provide parens around types when
-// they are ambiguous with traits. We do the same here, regrettably,
-// by splitting ty into ty and ty_prim.
-item_impl
-: maybe_default_maybe_unsafe IMPL generic_params ty_prim_sum maybe_where_clause '{' maybe_inner_attrs maybe_impl_items '}'
-{
- $$ = mk_node("ItemImpl", 6, $1, $3, $4, $5, $7, $8);
-}
-| maybe_default_maybe_unsafe IMPL generic_params '(' ty ')' maybe_where_clause '{' maybe_inner_attrs maybe_impl_items '}'
-{
- $$ = mk_node("ItemImpl", 6, $1, $3, 5, $6, $9, $10);
-}
-| maybe_default_maybe_unsafe IMPL generic_params trait_ref FOR ty_sum maybe_where_clause '{' maybe_inner_attrs maybe_impl_items '}'
-{
- $$ = mk_node("ItemImpl", 6, $3, $4, $6, $7, $9, $10);
-}
-| maybe_default_maybe_unsafe IMPL generic_params '!' trait_ref FOR ty_sum maybe_where_clause '{' maybe_inner_attrs maybe_impl_items '}'
-{
- $$ = mk_node("ItemImplNeg", 7, $1, $3, $5, $7, $8, $10, $11);
-}
-| maybe_default_maybe_unsafe IMPL generic_params trait_ref FOR DOTDOT '{' '}'
-{
- $$ = mk_node("ItemImplDefault", 3, $1, $3, $4);
-}
-| maybe_default_maybe_unsafe IMPL generic_params '!' trait_ref FOR DOTDOT '{' '}'
-{
- $$ = mk_node("ItemImplDefaultNeg", 3, $1, $3, $4);
-}
-;
-
-maybe_impl_items
-: impl_items
-| %empty { $$ = mk_none(); }
-;
-
-impl_items
-: impl_item { $$ = mk_node("ImplItems", 1, $1); }
-| impl_item impl_items { $$ = ext_node($1, 1, $2); }
-;
-
-impl_item
-: impl_method
-| attrs_and_vis item_macro { $$ = mk_node("ImplMacroItem", 2, $1, $2); }
-| impl_const
-| impl_type
-;
-
-maybe_default
-: DEFAULT { $$ = mk_atom("Default"); }
-| %empty { $$ = mk_none(); }
-;
-
-impl_const
-: attrs_and_vis maybe_default item_const { $$ = mk_node("ImplConst", 3, $1, $2, $3); }
-;
-
-impl_type
-: attrs_and_vis maybe_default TYPE ident generic_params '=' ty_sum ';' { $$ = mk_node("ImplType", 5, $1, $2, $4, $5, $7); }
-;
-
-item_fn
-: FN ident generic_params fn_decl maybe_where_clause inner_attrs_and_block
-{
- $$ = mk_node("ItemFn", 5, $2, $3, $4, $5, $6);
-}
-| CONST FN ident generic_params fn_decl maybe_where_clause inner_attrs_and_block
-{
- $$ = mk_node("ItemFn", 5, $3, $4, $5, $6, $7);
-}
-;
-
-item_unsafe_fn
-: UNSAFE FN ident generic_params fn_decl maybe_where_clause inner_attrs_and_block
-{
- $$ = mk_node("ItemUnsafeFn", 5, $3, $4, $5, $6, $7);
-}
-| CONST UNSAFE FN ident generic_params fn_decl maybe_where_clause inner_attrs_and_block
-{
- $$ = mk_node("ItemUnsafeFn", 5, $4, $5, $6, $7, $8);
-}
-| UNSAFE EXTERN maybe_abi FN ident generic_params fn_decl maybe_where_clause inner_attrs_and_block
-{
- $$ = mk_node("ItemUnsafeFn", 6, $3, $5, $6, $7, $8, $9);
-}
-;
-
-fn_decl
-: fn_params ret_ty { $$ = mk_node("FnDecl", 2, $1, $2); }
-;
-
-fn_decl_with_self
-: fn_params_with_self ret_ty { $$ = mk_node("FnDecl", 2, $1, $2); }
-;
-
-fn_decl_with_self_allow_anon_params
-: fn_anon_params_with_self ret_ty { $$ = mk_node("FnDecl", 2, $1, $2); }
-;
-
-fn_params
-: '(' maybe_params ')' { $$ = $2; }
-;
-
-fn_anon_params
-: '(' anon_param anon_params_allow_variadic_tail ')' { $$ = ext_node($2, 1, $3); }
-| '(' ')' { $$ = mk_none(); }
-;
-
-fn_params_with_self
-: '(' maybe_mut SELF maybe_ty_ascription maybe_comma_params ')' { $$ = mk_node("SelfLower", 3, $2, $4, $5); }
-| '(' '&' maybe_mut SELF maybe_ty_ascription maybe_comma_params ')' { $$ = mk_node("SelfRegion", 3, $3, $5, $6); }
-| '(' '&' lifetime maybe_mut SELF maybe_ty_ascription maybe_comma_params ')' { $$ = mk_node("SelfRegion", 4, $3, $4, $6, $7); }
-| '(' maybe_params ')' { $$ = mk_node("SelfStatic", 1, $2); }
-;
-
-fn_anon_params_with_self
-: '(' maybe_mut SELF maybe_ty_ascription maybe_comma_anon_params ')' { $$ = mk_node("SelfLower", 3, $2, $4, $5); }
-| '(' '&' maybe_mut SELF maybe_ty_ascription maybe_comma_anon_params ')' { $$ = mk_node("SelfRegion", 3, $3, $5, $6); }
-| '(' '&' lifetime maybe_mut SELF maybe_ty_ascription maybe_comma_anon_params ')' { $$ = mk_node("SelfRegion", 4, $3, $4, $6, $7); }
-| '(' maybe_anon_params ')' { $$ = mk_node("SelfStatic", 1, $2); }
-;
-
-maybe_params
-: params
-| params ','
-| %empty { $$ = mk_none(); }
-;
-
-params
-: param { $$ = mk_node("Args", 1, $1); }
-| params ',' param { $$ = ext_node($1, 1, $3); }
-;
-
-param
-: pat ':' ty_sum { $$ = mk_node("Arg", 2, $1, $3); }
-;
-
-inferrable_params
-: inferrable_param { $$ = mk_node("InferrableParams", 1, $1); }
-| inferrable_params ',' inferrable_param { $$ = ext_node($1, 1, $3); }
-;
-
-inferrable_param
-: pat maybe_ty_ascription { $$ = mk_node("InferrableParam", 2, $1, $2); }
-;
-
-maybe_comma_params
-: ',' { $$ = mk_none(); }
-| ',' params { $$ = $2; }
-| ',' params ',' { $$ = $2; }
-| %empty { $$ = mk_none(); }
-;
-
-maybe_comma_anon_params
-: ',' { $$ = mk_none(); }
-| ',' anon_params { $$ = $2; }
-| ',' anon_params ',' { $$ = $2; }
-| %empty { $$ = mk_none(); }
-;
-
-maybe_anon_params
-: anon_params
-| anon_params ','
-| %empty { $$ = mk_none(); }
-;
-
-anon_params
-: anon_param { $$ = mk_node("Args", 1, $1); }
-| anon_params ',' anon_param { $$ = ext_node($1, 1, $3); }
-;
-
-// anon means it's allowed to be anonymous (type-only), but it can
-// still have a name
-anon_param
-: named_arg ':' ty { $$ = mk_node("Arg", 2, $1, $3); }
-| ty
-;
-
-anon_params_allow_variadic_tail
-: ',' DOTDOTDOT { $$ = mk_none(); }
-| ',' anon_param anon_params_allow_variadic_tail { $$ = mk_node("Args", 2, $2, $3); }
-| %empty { $$ = mk_none(); }
-;
-
-named_arg
-: ident
-| UNDERSCORE { $$ = mk_atom("PatWild"); }
-| '&' ident { $$ = $2; }
-| '&' UNDERSCORE { $$ = mk_atom("PatWild"); }
-| ANDAND ident { $$ = $2; }
-| ANDAND UNDERSCORE { $$ = mk_atom("PatWild"); }
-| MUT ident { $$ = $2; }
-;
-
-ret_ty
-: RARROW '!' { $$ = mk_none(); }
-| RARROW ty { $$ = mk_node("ret-ty", 1, $2); }
-| %prec IDENT %empty { $$ = mk_none(); }
-;
-
-generic_params
-: '<' '>' { $$ = mk_node("Generics", 2, mk_none(), mk_none()); }
-| '<' lifetimes '>' { $$ = mk_node("Generics", 2, $2, mk_none()); }
-| '<' lifetimes ',' '>' { $$ = mk_node("Generics", 2, $2, mk_none()); }
-| '<' lifetimes SHR { push_back('>'); $$ = mk_node("Generics", 2, $2, mk_none()); }
-| '<' lifetimes ',' SHR { push_back('>'); $$ = mk_node("Generics", 2, $2, mk_none()); }
-| '<' lifetimes ',' ty_params '>' { $$ = mk_node("Generics", 2, $2, $4); }
-| '<' lifetimes ',' ty_params ',' '>' { $$ = mk_node("Generics", 2, $2, $4); }
-| '<' lifetimes ',' ty_params SHR { push_back('>'); $$ = mk_node("Generics", 2, $2, $4); }
-| '<' lifetimes ',' ty_params ',' SHR { push_back('>'); $$ = mk_node("Generics", 2, $2, $4); }
-| '<' ty_params '>' { $$ = mk_node("Generics", 2, mk_none(), $2); }
-| '<' ty_params ',' '>' { $$ = mk_node("Generics", 2, mk_none(), $2); }
-| '<' ty_params SHR { push_back('>'); $$ = mk_node("Generics", 2, mk_none(), $2); }
-| '<' ty_params ',' SHR { push_back('>'); $$ = mk_node("Generics", 2, mk_none(), $2); }
-| %empty { $$ = mk_none(); }
-;
-
-maybe_where_clause
-: %empty { $$ = mk_none(); }
-| where_clause
-;
-
-where_clause
-: WHERE where_predicates { $$ = mk_node("WhereClause", 1, $2); }
-| WHERE where_predicates ',' { $$ = mk_node("WhereClause", 1, $2); }
-;
-
-where_predicates
-: where_predicate { $$ = mk_node("WherePredicates", 1, $1); }
-| where_predicates ',' where_predicate { $$ = ext_node($1, 1, $3); }
-;
-
-where_predicate
-: maybe_for_lifetimes lifetime ':' bounds { $$ = mk_node("WherePredicate", 3, $1, $2, $4); }
-| maybe_for_lifetimes ty ':' ty_param_bounds { $$ = mk_node("WherePredicate", 3, $1, $2, $4); }
-;
-
-maybe_for_lifetimes
-: FOR '<' lifetimes '>' { $$ = mk_none(); }
-| %prec FORTYPE %empty { $$ = mk_none(); }
-
-ty_params
-: ty_param { $$ = mk_node("TyParams", 1, $1); }
-| ty_params ',' ty_param { $$ = ext_node($1, 1, $3); }
-;
-
-// A path with no type parameters; e.g. `foo::bar::Baz`
-//
-// These show up in 'use' view-items, because these are processed
-// without respect to types.
-path_no_types_allowed
-: ident { $$ = mk_node("ViewPath", 1, $1); }
-| MOD_SEP ident { $$ = mk_node("ViewPath", 1, $2); }
-| SELF { $$ = mk_node("ViewPath", 1, mk_atom("Self")); }
-| MOD_SEP SELF { $$ = mk_node("ViewPath", 1, mk_atom("Self")); }
-| SUPER { $$ = mk_node("ViewPath", 1, mk_atom("Super")); }
-| MOD_SEP SUPER { $$ = mk_node("ViewPath", 1, mk_atom("Super")); }
-| path_no_types_allowed MOD_SEP ident { $$ = ext_node($1, 1, $3); }
-;
-
-// A path with a lifetime and type parameters, with no double colons
-// before the type parameters; e.g. `foo::bar<'a>::Baz`
-//
-// These show up in "trait references", the components of
-// type-parameter bounds lists, as well as in the prefix of the
-// path_generic_args_and_bounds rule, which is the full form of a
-// named typed expression.
-//
-// They do not have (nor need) an extra '::' before '<' because
-// unlike in expr context, there are no "less-than" type exprs to
-// be ambiguous with.
-path_generic_args_without_colons
-: %prec IDENT
- ident { $$ = mk_node("components", 1, $1); }
-| %prec IDENT
- ident generic_args { $$ = mk_node("components", 2, $1, $2); }
-| %prec IDENT
- ident '(' maybe_ty_sums ')' ret_ty { $$ = mk_node("components", 2, $1, $3); }
-| %prec IDENT
- path_generic_args_without_colons MOD_SEP ident { $$ = ext_node($1, 1, $3); }
-| %prec IDENT
- path_generic_args_without_colons MOD_SEP ident generic_args { $$ = ext_node($1, 2, $3, $4); }
-| %prec IDENT
- path_generic_args_without_colons MOD_SEP ident '(' maybe_ty_sums ')' ret_ty { $$ = ext_node($1, 2, $3, $5); }
-;
-
-generic_args
-: '<' generic_values '>' { $$ = $2; }
-| '<' generic_values SHR { push_back('>'); $$ = $2; }
-| '<' generic_values GE { push_back('='); $$ = $2; }
-| '<' generic_values SHREQ { push_back('>'); push_back('='); $$ = $2; }
-// If generic_args starts with "<<", the first arg must be a
-// TyQualifiedPath because that's the only type that can start with a
-// '<'. This rule parses that as the first ty_sum and then continues
-// with the rest of generic_values.
-| SHL ty_qualified_path_and_generic_values '>' { $$ = $2; }
-| SHL ty_qualified_path_and_generic_values SHR { push_back('>'); $$ = $2; }
-| SHL ty_qualified_path_and_generic_values GE { push_back('='); $$ = $2; }
-| SHL ty_qualified_path_and_generic_values SHREQ { push_back('>'); push_back('='); $$ = $2; }
-;
-
-generic_values
-: maybe_ty_sums_and_or_bindings { $$ = mk_node("GenericValues", 1, $1); }
-;
-
-maybe_ty_sums_and_or_bindings
-: ty_sums
-| ty_sums ','
-| ty_sums ',' bindings { $$ = mk_node("TySumsAndBindings", 2, $1, $3); }
-| bindings
-| bindings ','
-| %empty { $$ = mk_none(); }
-;
-
-maybe_bindings
-: ',' bindings { $$ = $2; }
-| %empty { $$ = mk_none(); }
-;
-
-////////////////////////////////////////////////////////////////////////
-// Part 2: Patterns
-////////////////////////////////////////////////////////////////////////
-
-pat
-: UNDERSCORE { $$ = mk_atom("PatWild"); }
-| '&' pat { $$ = mk_node("PatRegion", 1, $2); }
-| '&' MUT pat { $$ = mk_node("PatRegion", 1, $3); }
-| ANDAND pat { $$ = mk_node("PatRegion", 1, mk_node("PatRegion", 1, $2)); }
-| '(' ')' { $$ = mk_atom("PatUnit"); }
-| '(' pat_tup ')' { $$ = mk_node("PatTup", 1, $2); }
-| '[' pat_vec ']' { $$ = mk_node("PatVec", 1, $2); }
-| lit_or_path
-| lit_or_path DOTDOTDOT lit_or_path { $$ = mk_node("PatRange", 2, $1, $3); }
-| path_expr '{' pat_struct '}' { $$ = mk_node("PatStruct", 2, $1, $3); }
-| path_expr '(' ')' { $$ = mk_node("PatEnum", 2, $1, mk_none()); }
-| path_expr '(' pat_tup ')' { $$ = mk_node("PatEnum", 2, $1, $3); }
-| path_expr '!' maybe_ident delimited_token_trees { $$ = mk_node("PatMac", 3, $1, $3, $4); }
-| binding_mode ident { $$ = mk_node("PatIdent", 2, $1, $2); }
-| ident '@' pat { $$ = mk_node("PatIdent", 3, mk_node("BindByValue", 1, mk_atom("MutImmutable")), $1, $3); }
-| binding_mode ident '@' pat { $$ = mk_node("PatIdent", 3, $1, $2, $4); }
-| BOX pat { $$ = mk_node("PatUniq", 1, $2); }
-| '<' ty_sum maybe_as_trait_ref '>' MOD_SEP ident { $$ = mk_node("PatQualifiedPath", 3, $2, $3, $6); }
-| SHL ty_sum maybe_as_trait_ref '>' MOD_SEP ident maybe_as_trait_ref '>' MOD_SEP ident
-{
- $$ = mk_node("PatQualifiedPath", 3, mk_node("PatQualifiedPath", 3, $2, $3, $6), $7, $10);
-}
-;
-
-pats_or
-: pat { $$ = mk_node("Pats", 1, $1); }
-| pats_or '|' pat { $$ = ext_node($1, 1, $3); }
-;
-
-binding_mode
-: REF { $$ = mk_node("BindByRef", 1, mk_atom("MutImmutable")); }
-| REF MUT { $$ = mk_node("BindByRef", 1, mk_atom("MutMutable")); }
-| MUT { $$ = mk_node("BindByValue", 1, mk_atom("MutMutable")); }
-;
-
-lit_or_path
-: path_expr { $$ = mk_node("PatLit", 1, $1); }
-| lit { $$ = mk_node("PatLit", 1, $1); }
-| '-' lit { $$ = mk_node("PatLit", 1, $2); }
-;
-
-pat_field
-: ident { $$ = mk_node("PatField", 1, $1); }
-| binding_mode ident { $$ = mk_node("PatField", 2, $1, $2); }
-| BOX ident { $$ = mk_node("PatField", 2, mk_atom("box"), $2); }
-| BOX binding_mode ident { $$ = mk_node("PatField", 3, mk_atom("box"), $2, $3); }
-| ident ':' pat { $$ = mk_node("PatField", 2, $1, $3); }
-| binding_mode ident ':' pat { $$ = mk_node("PatField", 3, $1, $2, $4); }
-| LIT_INTEGER ':' pat { $$ = mk_node("PatField", 2, mk_atom(yytext), $3); }
-;
-
-pat_fields
-: pat_field { $$ = mk_node("PatFields", 1, $1); }
-| pat_fields ',' pat_field { $$ = ext_node($1, 1, $3); }
-;
-
-pat_struct
-: pat_fields { $$ = mk_node("PatStruct", 2, $1, mk_atom("false")); }
-| pat_fields ',' { $$ = mk_node("PatStruct", 2, $1, mk_atom("false")); }
-| pat_fields ',' DOTDOT { $$ = mk_node("PatStruct", 2, $1, mk_atom("true")); }
-| DOTDOT { $$ = mk_node("PatStruct", 1, mk_atom("true")); }
-| %empty { $$ = mk_node("PatStruct", 1, mk_none()); }
-;
-
-pat_tup
-: pat_tup_elts { $$ = mk_node("PatTup", 2, $1, mk_none()); }
-| pat_tup_elts ',' { $$ = mk_node("PatTup", 2, $1, mk_none()); }
-| pat_tup_elts DOTDOT { $$ = mk_node("PatTup", 2, $1, mk_none()); }
-| pat_tup_elts ',' DOTDOT { $$ = mk_node("PatTup", 2, $1, mk_none()); }
-| pat_tup_elts DOTDOT ',' pat_tup_elts { $$ = mk_node("PatTup", 2, $1, $4); }
-| pat_tup_elts DOTDOT ',' pat_tup_elts ',' { $$ = mk_node("PatTup", 2, $1, $4); }
-| pat_tup_elts ',' DOTDOT ',' pat_tup_elts { $$ = mk_node("PatTup", 2, $1, $5); }
-| pat_tup_elts ',' DOTDOT ',' pat_tup_elts ',' { $$ = mk_node("PatTup", 2, $1, $5); }
-| DOTDOT ',' pat_tup_elts { $$ = mk_node("PatTup", 2, mk_none(), $3); }
-| DOTDOT ',' pat_tup_elts ',' { $$ = mk_node("PatTup", 2, mk_none(), $3); }
-| DOTDOT { $$ = mk_node("PatTup", 2, mk_none(), mk_none()); }
-;
-
-pat_tup_elts
-: pat { $$ = mk_node("PatTupElts", 1, $1); }
-| pat_tup_elts ',' pat { $$ = ext_node($1, 1, $3); }
-;
-
-pat_vec
-: pat_vec_elts { $$ = mk_node("PatVec", 2, $1, mk_none()); }
-| pat_vec_elts ',' { $$ = mk_node("PatVec", 2, $1, mk_none()); }
-| pat_vec_elts DOTDOT { $$ = mk_node("PatVec", 2, $1, mk_none()); }
-| pat_vec_elts ',' DOTDOT { $$ = mk_node("PatVec", 2, $1, mk_none()); }
-| pat_vec_elts DOTDOT ',' pat_vec_elts { $$ = mk_node("PatVec", 2, $1, $4); }
-| pat_vec_elts DOTDOT ',' pat_vec_elts ',' { $$ = mk_node("PatVec", 2, $1, $4); }
-| pat_vec_elts ',' DOTDOT ',' pat_vec_elts { $$ = mk_node("PatVec", 2, $1, $5); }
-| pat_vec_elts ',' DOTDOT ',' pat_vec_elts ',' { $$ = mk_node("PatVec", 2, $1, $5); }
-| DOTDOT ',' pat_vec_elts { $$ = mk_node("PatVec", 2, mk_none(), $3); }
-| DOTDOT ',' pat_vec_elts ',' { $$ = mk_node("PatVec", 2, mk_none(), $3); }
-| DOTDOT { $$ = mk_node("PatVec", 2, mk_none(), mk_none()); }
-| %empty { $$ = mk_node("PatVec", 2, mk_none(), mk_none()); }
-;
-
-pat_vec_elts
-: pat { $$ = mk_node("PatVecElts", 1, $1); }
-| pat_vec_elts ',' pat { $$ = ext_node($1, 1, $3); }
-;
-
-////////////////////////////////////////////////////////////////////////
-// Part 3: Types
-////////////////////////////////////////////////////////////////////////
-
-ty
-: ty_prim
-| ty_closure
-| '<' ty_sum maybe_as_trait_ref '>' MOD_SEP ident { $$ = mk_node("TyQualifiedPath", 3, $2, $3, $6); }
-| SHL ty_sum maybe_as_trait_ref '>' MOD_SEP ident maybe_as_trait_ref '>' MOD_SEP ident { $$ = mk_node("TyQualifiedPath", 3, mk_node("TyQualifiedPath", 3, $2, $3, $6), $7, $10); }
-| '(' ty_sums ')' { $$ = mk_node("TyTup", 1, $2); }
-| '(' ty_sums ',' ')' { $$ = mk_node("TyTup", 1, $2); }
-| '(' ')' { $$ = mk_atom("TyNil"); }
-;
-
-ty_prim
-: %prec IDENT path_generic_args_without_colons { $$ = mk_node("TyPath", 2, mk_node("global", 1, mk_atom("false")), $1); }
-| %prec IDENT MOD_SEP path_generic_args_without_colons { $$ = mk_node("TyPath", 2, mk_node("global", 1, mk_atom("true")), $2); }
-| %prec IDENT SELF MOD_SEP path_generic_args_without_colons { $$ = mk_node("TyPath", 2, mk_node("self", 1, mk_atom("true")), $3); }
-| %prec IDENT path_generic_args_without_colons '!' maybe_ident delimited_token_trees { $$ = mk_node("TyMacro", 3, $1, $3, $4); }
-| %prec IDENT MOD_SEP path_generic_args_without_colons '!' maybe_ident delimited_token_trees { $$ = mk_node("TyMacro", 3, $2, $4, $5); }
-| BOX ty { $$ = mk_node("TyBox", 1, $2); }
-| '*' maybe_mut_or_const ty { $$ = mk_node("TyPtr", 2, $2, $3); }
-| '&' ty { $$ = mk_node("TyRptr", 2, mk_atom("MutImmutable"), $2); }
-| '&' MUT ty { $$ = mk_node("TyRptr", 2, mk_atom("MutMutable"), $3); }
-| ANDAND ty { $$ = mk_node("TyRptr", 1, mk_node("TyRptr", 2, mk_atom("MutImmutable"), $2)); }
-| ANDAND MUT ty { $$ = mk_node("TyRptr", 1, mk_node("TyRptr", 2, mk_atom("MutMutable"), $3)); }
-| '&' lifetime maybe_mut ty { $$ = mk_node("TyRptr", 3, $2, $3, $4); }
-| ANDAND lifetime maybe_mut ty { $$ = mk_node("TyRptr", 1, mk_node("TyRptr", 3, $2, $3, $4)); }
-| '[' ty ']' { $$ = mk_node("TyVec", 1, $2); }
-| '[' ty ',' DOTDOT expr ']' { $$ = mk_node("TyFixedLengthVec", 2, $2, $5); }
-| '[' ty ';' expr ']' { $$ = mk_node("TyFixedLengthVec", 2, $2, $4); }
-| TYPEOF '(' expr ')' { $$ = mk_node("TyTypeof", 1, $3); }
-| UNDERSCORE { $$ = mk_atom("TyInfer"); }
-| ty_bare_fn
-| for_in_type
-;
-
-ty_bare_fn
-: FN ty_fn_decl { $$ = $2; }
-| UNSAFE FN ty_fn_decl { $$ = $3; }
-| EXTERN maybe_abi FN ty_fn_decl { $$ = $4; }
-| UNSAFE EXTERN maybe_abi FN ty_fn_decl { $$ = $5; }
-;
-
-ty_fn_decl
-: generic_params fn_anon_params ret_ty { $$ = mk_node("TyFnDecl", 3, $1, $2, $3); }
-;
-
-ty_closure
-: UNSAFE '|' anon_params '|' maybe_bounds ret_ty { $$ = mk_node("TyClosure", 3, $3, $5, $6); }
-| '|' anon_params '|' maybe_bounds ret_ty { $$ = mk_node("TyClosure", 3, $2, $4, $5); }
-| UNSAFE OROR maybe_bounds ret_ty { $$ = mk_node("TyClosure", 2, $3, $4); }
-| OROR maybe_bounds ret_ty { $$ = mk_node("TyClosure", 2, $2, $3); }
-;
-
-for_in_type
-: FOR '<' maybe_lifetimes '>' for_in_type_suffix { $$ = mk_node("ForInType", 2, $3, $5); }
-;
-
-for_in_type_suffix
-: ty_bare_fn
-| trait_ref
-| ty_closure
-;
-
-maybe_mut
-: MUT { $$ = mk_atom("MutMutable"); }
-| %prec MUT %empty { $$ = mk_atom("MutImmutable"); }
-;
-
-maybe_mut_or_const
-: MUT { $$ = mk_atom("MutMutable"); }
-| CONST { $$ = mk_atom("MutImmutable"); }
-| %empty { $$ = mk_atom("MutImmutable"); }
-;
-
-ty_qualified_path_and_generic_values
-: ty_qualified_path maybe_bindings
-{
- $$ = mk_node("GenericValues", 3, mk_none(), mk_node("TySums", 1, mk_node("TySum", 1, $1)), $2);
-}
-| ty_qualified_path ',' ty_sums maybe_bindings
-{
- $$ = mk_node("GenericValues", 3, mk_none(), mk_node("TySums", 2, $1, $3), $4);
-}
-;
-
-ty_qualified_path
-: ty_sum AS trait_ref '>' MOD_SEP ident { $$ = mk_node("TyQualifiedPath", 3, $1, $3, $6); }
-| ty_sum AS trait_ref '>' MOD_SEP ident '+' ty_param_bounds { $$ = mk_node("TyQualifiedPath", 3, $1, $3, $6); }
-;
-
-maybe_ty_sums
-: ty_sums
-| ty_sums ','
-| %empty { $$ = mk_none(); }
-;
-
-ty_sums
-: ty_sum { $$ = mk_node("TySums", 1, $1); }
-| ty_sums ',' ty_sum { $$ = ext_node($1, 1, $3); }
-;
-
-ty_sum
-: ty_sum_elt { $$ = mk_node("TySum", 1, $1); }
-| ty_sum '+' ty_sum_elt { $$ = ext_node($1, 1, $3); }
-;
-
-ty_sum_elt
-: ty
-| lifetime
-;
-
-ty_prim_sum
-: ty_prim_sum_elt { $$ = mk_node("TySum", 1, $1); }
-| ty_prim_sum '+' ty_prim_sum_elt { $$ = ext_node($1, 1, $3); }
-;
-
-ty_prim_sum_elt
-: ty_prim
-| lifetime
-;
-
-maybe_ty_param_bounds
-: ':' ty_param_bounds { $$ = $2; }
-| %empty { $$ = mk_none(); }
-;
-
-ty_param_bounds
-: boundseq
-| %empty { $$ = mk_none(); }
-;
-
-boundseq
-: polybound
-| boundseq '+' polybound { $$ = ext_node($1, 1, $3); }
-;
-
-polybound
-: FOR '<' maybe_lifetimes '>' bound { $$ = mk_node("PolyBound", 2, $3, $5); }
-| bound
-| '?' FOR '<' maybe_lifetimes '>' bound { $$ = mk_node("PolyBound", 2, $4, $6); }
-| '?' bound { $$ = $2; }
-;
-
-bindings
-: binding { $$ = mk_node("Bindings", 1, $1); }
-| bindings ',' binding { $$ = ext_node($1, 1, $3); }
-;
-
-binding
-: ident '=' ty { mk_node("Binding", 2, $1, $3); }
-;
-
-ty_param
-: ident maybe_ty_param_bounds maybe_ty_default { $$ = mk_node("TyParam", 3, $1, $2, $3); }
-| ident '?' ident maybe_ty_param_bounds maybe_ty_default { $$ = mk_node("TyParam", 4, $1, $3, $4, $5); }
-;
-
-maybe_bounds
-: %prec SHIFTPLUS
- ':' bounds { $$ = $2; }
-| %prec SHIFTPLUS %empty { $$ = mk_none(); }
-;
-
-bounds
-: bound { $$ = mk_node("bounds", 1, $1); }
-| bounds '+' bound { $$ = ext_node($1, 1, $3); }
-;
-
-bound
-: lifetime
-| trait_ref
-;
-
-maybe_ltbounds
-: %prec SHIFTPLUS
- ':' ltbounds { $$ = $2; }
-| %empty { $$ = mk_none(); }
-;
-
-ltbounds
-: lifetime { $$ = mk_node("ltbounds", 1, $1); }
-| ltbounds '+' lifetime { $$ = ext_node($1, 1, $3); }
-;
-
-maybe_ty_default
-: '=' ty_sum { $$ = mk_node("TyDefault", 1, $2); }
-| %empty { $$ = mk_none(); }
-;
-
-maybe_lifetimes
-: lifetimes
-| lifetimes ','
-| %empty { $$ = mk_none(); }
-;
-
-lifetimes
-: lifetime_and_bounds { $$ = mk_node("Lifetimes", 1, $1); }
-| lifetimes ',' lifetime_and_bounds { $$ = ext_node($1, 1, $3); }
-;
-
-lifetime_and_bounds
-: LIFETIME maybe_ltbounds { $$ = mk_node("lifetime", 2, mk_atom(yytext), $2); }
-| STATIC_LIFETIME { $$ = mk_atom("static_lifetime"); }
-;
-
-lifetime
-: LIFETIME { $$ = mk_node("lifetime", 1, mk_atom(yytext)); }
-| STATIC_LIFETIME { $$ = mk_atom("static_lifetime"); }
-;
-
-trait_ref
-: %prec IDENT path_generic_args_without_colons
-| %prec IDENT MOD_SEP path_generic_args_without_colons { $$ = $2; }
-;
-
-////////////////////////////////////////////////////////////////////////
-// Part 4: Blocks, statements, and expressions
-////////////////////////////////////////////////////////////////////////
-
-inner_attrs_and_block
-: '{' maybe_inner_attrs maybe_stmts '}' { $$ = mk_node("ExprBlock", 2, $2, $3); }
-;
-
-block
-: '{' maybe_stmts '}' { $$ = mk_node("ExprBlock", 1, $2); }
-;
-
-maybe_stmts
-: stmts
-| stmts nonblock_expr { $$ = ext_node($1, 1, $2); }
-| nonblock_expr
-| %empty { $$ = mk_none(); }
-;
-
-// There are two sub-grammars within a "stmts: exprs" derivation
-// depending on whether each stmt-expr is a block-expr form; this is to
-// handle the "semicolon rule" for stmt sequencing that permits
-// writing
-//
-// if foo { bar } 10
-//
-// as a sequence of two stmts (one if-expr stmt, one lit-10-expr
-// stmt). Unfortunately by permitting juxtaposition of exprs in
-// sequence like that, the non-block expr grammar has to have a
-// second limited sub-grammar that excludes the prefix exprs that
-// are ambiguous with binops. That is to say:
-//
-// {10} - 1
-//
-// should parse as (progn (progn 10) (- 1)) not (- (progn 10) 1), that
-// is to say, two statements rather than one, at least according to
-// the mainline rust parser.
-//
-// So we wind up with a 3-way split in exprs that occur in stmt lists:
-// block, nonblock-prefix, and nonblock-nonprefix.
-//
-// In non-stmts contexts, expr can relax this trichotomy.
-
-stmts
-: stmt { $$ = mk_node("stmts", 1, $1); }
-| stmts stmt { $$ = ext_node($1, 1, $2); }
-;
-
-stmt
-: maybe_outer_attrs let { $$ = $2; }
-| stmt_item
-| PUB stmt_item { $$ = $2; }
-| outer_attrs stmt_item { $$ = $2; }
-| outer_attrs PUB stmt_item { $$ = $3; }
-| full_block_expr
-| maybe_outer_attrs block { $$ = $2; }
-| nonblock_expr ';'
-| outer_attrs nonblock_expr ';' { $$ = $2; }
-| ';' { $$ = mk_none(); }
-;
-
-maybe_exprs
-: exprs
-| exprs ','
-| %empty { $$ = mk_none(); }
-;
-
-maybe_expr
-: expr
-| %empty { $$ = mk_none(); }
-;
-
-exprs
-: expr { $$ = mk_node("exprs", 1, $1); }
-| exprs ',' expr { $$ = ext_node($1, 1, $3); }
-;
-
-path_expr
-: path_generic_args_with_colons
-| MOD_SEP path_generic_args_with_colons { $$ = $2; }
-| SELF MOD_SEP path_generic_args_with_colons { $$ = mk_node("SelfPath", 1, $3); }
-;
-
-// A path with a lifetime and type parameters with double colons before
-// the type parameters; e.g. `foo::bar::<'a>::Baz::`
-//
-// These show up in expr context, in order to disambiguate from "less-than"
-// expressions.
-path_generic_args_with_colons
-: ident { $$ = mk_node("components", 1, $1); }
-| SUPER { $$ = mk_atom("Super"); }
-| path_generic_args_with_colons MOD_SEP ident { $$ = ext_node($1, 1, $3); }
-| path_generic_args_with_colons MOD_SEP SUPER { $$ = ext_node($1, 1, mk_atom("Super")); }
-| path_generic_args_with_colons MOD_SEP generic_args { $$ = ext_node($1, 1, $3); }
-;
-
-// the braces-delimited macro is a block_expr so it doesn't appear here
-macro_expr
-: path_expr '!' maybe_ident parens_delimited_token_trees { $$ = mk_node("MacroExpr", 3, $1, $3, $4); }
-| path_expr '!' maybe_ident brackets_delimited_token_trees { $$ = mk_node("MacroExpr", 3, $1, $3, $4); }
-;
-
-nonblock_expr
-: lit { $$ = mk_node("ExprLit", 1, $1); }
-| %prec IDENT
- path_expr { $$ = mk_node("ExprPath", 1, $1); }
-| SELF { $$ = mk_node("ExprPath", 1, mk_node("ident", 1, mk_atom("self"))); }
-| macro_expr { $$ = mk_node("ExprMac", 1, $1); }
-| path_expr '{' struct_expr_fields '}' { $$ = mk_node("ExprStruct", 2, $1, $3); }
-| nonblock_expr '?' { $$ = mk_node("ExprTry", 1, $1); }
-| nonblock_expr '.' path_generic_args_with_colons { $$ = mk_node("ExprField", 2, $1, $3); }
-| nonblock_expr '.' LIT_INTEGER { $$ = mk_node("ExprTupleIndex", 1, $1); }
-| nonblock_expr '[' maybe_expr ']' { $$ = mk_node("ExprIndex", 2, $1, $3); }
-| nonblock_expr '(' maybe_exprs ')' { $$ = mk_node("ExprCall", 2, $1, $3); }
-| '[' vec_expr ']' { $$ = mk_node("ExprVec", 1, $2); }
-| '(' maybe_exprs ')' { $$ = mk_node("ExprParen", 1, $2); }
-| CONTINUE { $$ = mk_node("ExprAgain", 0); }
-| CONTINUE lifetime { $$ = mk_node("ExprAgain", 1, $2); }
-| RETURN { $$ = mk_node("ExprRet", 0); }
-| RETURN expr { $$ = mk_node("ExprRet", 1, $2); }
-| BREAK { $$ = mk_node("ExprBreak", 0); }
-| BREAK lifetime { $$ = mk_node("ExprBreak", 1, $2); }
-| YIELD { $$ = mk_node("ExprYield", 0); }
-| YIELD expr { $$ = mk_node("ExprYield", 1, $2); }
-| nonblock_expr '=' expr { $$ = mk_node("ExprAssign", 2, $1, $3); }
-| nonblock_expr SHLEQ expr { $$ = mk_node("ExprAssignShl", 2, $1, $3); }
-| nonblock_expr SHREQ expr { $$ = mk_node("ExprAssignShr", 2, $1, $3); }
-| nonblock_expr MINUSEQ expr { $$ = mk_node("ExprAssignSub", 2, $1, $3); }
-| nonblock_expr ANDEQ expr { $$ = mk_node("ExprAssignBitAnd", 2, $1, $3); }
-| nonblock_expr OREQ expr { $$ = mk_node("ExprAssignBitOr", 2, $1, $3); }
-| nonblock_expr PLUSEQ expr { $$ = mk_node("ExprAssignAdd", 2, $1, $3); }
-| nonblock_expr STAREQ expr { $$ = mk_node("ExprAssignMul", 2, $1, $3); }
-| nonblock_expr SLASHEQ expr { $$ = mk_node("ExprAssignDiv", 2, $1, $3); }
-| nonblock_expr CARETEQ expr { $$ = mk_node("ExprAssignBitXor", 2, $1, $3); }
-| nonblock_expr PERCENTEQ expr { $$ = mk_node("ExprAssignRem", 2, $1, $3); }
-| nonblock_expr OROR expr { $$ = mk_node("ExprBinary", 3, mk_atom("BiOr"), $1, $3); }
-| nonblock_expr ANDAND expr { $$ = mk_node("ExprBinary", 3, mk_atom("BiAnd"), $1, $3); }
-| nonblock_expr EQEQ expr { $$ = mk_node("ExprBinary", 3, mk_atom("BiEq"), $1, $3); }
-| nonblock_expr NE expr { $$ = mk_node("ExprBinary", 3, mk_atom("BiNe"), $1, $3); }
-| nonblock_expr '<' expr { $$ = mk_node("ExprBinary", 3, mk_atom("BiLt"), $1, $3); }
-| nonblock_expr '>' expr { $$ = mk_node("ExprBinary", 3, mk_atom("BiGt"), $1, $3); }
-| nonblock_expr LE expr { $$ = mk_node("ExprBinary", 3, mk_atom("BiLe"), $1, $3); }
-| nonblock_expr GE expr { $$ = mk_node("ExprBinary", 3, mk_atom("BiGe"), $1, $3); }
-| nonblock_expr '|' expr { $$ = mk_node("ExprBinary", 3, mk_atom("BiBitOr"), $1, $3); }
-| nonblock_expr '^' expr { $$ = mk_node("ExprBinary", 3, mk_atom("BiBitXor"), $1, $3); }
-| nonblock_expr '&' expr { $$ = mk_node("ExprBinary", 3, mk_atom("BiBitAnd"), $1, $3); }
-| nonblock_expr SHL expr { $$ = mk_node("ExprBinary", 3, mk_atom("BiShl"), $1, $3); }
-| nonblock_expr SHR expr { $$ = mk_node("ExprBinary", 3, mk_atom("BiShr"), $1, $3); }
-| nonblock_expr '+' expr { $$ = mk_node("ExprBinary", 3, mk_atom("BiAdd"), $1, $3); }
-| nonblock_expr '-' expr { $$ = mk_node("ExprBinary", 3, mk_atom("BiSub"), $1, $3); }
-| nonblock_expr '*' expr { $$ = mk_node("ExprBinary", 3, mk_atom("BiMul"), $1, $3); }
-| nonblock_expr '/' expr { $$ = mk_node("ExprBinary", 3, mk_atom("BiDiv"), $1, $3); }
-| nonblock_expr '%' expr { $$ = mk_node("ExprBinary", 3, mk_atom("BiRem"), $1, $3); }
-| nonblock_expr DOTDOT { $$ = mk_node("ExprRange", 2, $1, mk_none()); }
-| nonblock_expr DOTDOT expr { $$ = mk_node("ExprRange", 2, $1, $3); }
-| DOTDOT expr { $$ = mk_node("ExprRange", 2, mk_none(), $2); }
-| DOTDOT { $$ = mk_node("ExprRange", 2, mk_none(), mk_none()); }
-| nonblock_expr AS ty { $$ = mk_node("ExprCast", 2, $1, $3); }
-| nonblock_expr ':' ty { $$ = mk_node("ExprTypeAscr", 2, $1, $3); }
-| BOX expr { $$ = mk_node("ExprBox", 1, $2); }
-| expr_qualified_path
-| nonblock_prefix_expr
-;
-
-expr
-: lit { $$ = mk_node("ExprLit", 1, $1); }
-| %prec IDENT
- path_expr { $$ = mk_node("ExprPath", 1, $1); }
-| SELF { $$ = mk_node("ExprPath", 1, mk_node("ident", 1, mk_atom("self"))); }
-| macro_expr { $$ = mk_node("ExprMac", 1, $1); }
-| path_expr '{' struct_expr_fields '}' { $$ = mk_node("ExprStruct", 2, $1, $3); }
-| expr '?' { $$ = mk_node("ExprTry", 1, $1); }
-| expr '.' path_generic_args_with_colons { $$ = mk_node("ExprField", 2, $1, $3); }
-| expr '.' LIT_INTEGER { $$ = mk_node("ExprTupleIndex", 1, $1); }
-| expr '[' maybe_expr ']' { $$ = mk_node("ExprIndex", 2, $1, $3); }
-| expr '(' maybe_exprs ')' { $$ = mk_node("ExprCall", 2, $1, $3); }
-| '(' maybe_exprs ')' { $$ = mk_node("ExprParen", 1, $2); }
-| '[' vec_expr ']' { $$ = mk_node("ExprVec", 1, $2); }
-| CONTINUE { $$ = mk_node("ExprAgain", 0); }
-| CONTINUE ident { $$ = mk_node("ExprAgain", 1, $2); }
-| RETURN { $$ = mk_node("ExprRet", 0); }
-| RETURN expr { $$ = mk_node("ExprRet", 1, $2); }
-| BREAK { $$ = mk_node("ExprBreak", 0); }
-| BREAK ident { $$ = mk_node("ExprBreak", 1, $2); }
-| YIELD { $$ = mk_node("ExprYield", 0); }
-| YIELD expr { $$ = mk_node("ExprYield", 1, $2); }
-| expr '=' expr { $$ = mk_node("ExprAssign", 2, $1, $3); }
-| expr SHLEQ expr { $$ = mk_node("ExprAssignShl", 2, $1, $3); }
-| expr SHREQ expr { $$ = mk_node("ExprAssignShr", 2, $1, $3); }
-| expr MINUSEQ expr { $$ = mk_node("ExprAssignSub", 2, $1, $3); }
-| expr ANDEQ expr { $$ = mk_node("ExprAssignBitAnd", 2, $1, $3); }
-| expr OREQ expr { $$ = mk_node("ExprAssignBitOr", 2, $1, $3); }
-| expr PLUSEQ expr { $$ = mk_node("ExprAssignAdd", 2, $1, $3); }
-| expr STAREQ expr { $$ = mk_node("ExprAssignMul", 2, $1, $3); }
-| expr SLASHEQ expr { $$ = mk_node("ExprAssignDiv", 2, $1, $3); }
-| expr CARETEQ expr { $$ = mk_node("ExprAssignBitXor", 2, $1, $3); }
-| expr PERCENTEQ expr { $$ = mk_node("ExprAssignRem", 2, $1, $3); }
-| expr OROR expr { $$ = mk_node("ExprBinary", 3, mk_atom("BiOr"), $1, $3); }
-| expr ANDAND expr { $$ = mk_node("ExprBinary", 3, mk_atom("BiAnd"), $1, $3); }
-| expr EQEQ expr { $$ = mk_node("ExprBinary", 3, mk_atom("BiEq"), $1, $3); }
-| expr NE expr { $$ = mk_node("ExprBinary", 3, mk_atom("BiNe"), $1, $3); }
-| expr '<' expr { $$ = mk_node("ExprBinary", 3, mk_atom("BiLt"), $1, $3); }
-| expr '>' expr { $$ = mk_node("ExprBinary", 3, mk_atom("BiGt"), $1, $3); }
-| expr LE expr { $$ = mk_node("ExprBinary", 3, mk_atom("BiLe"), $1, $3); }
-| expr GE expr { $$ = mk_node("ExprBinary", 3, mk_atom("BiGe"), $1, $3); }
-| expr '|' expr { $$ = mk_node("ExprBinary", 3, mk_atom("BiBitOr"), $1, $3); }
-| expr '^' expr { $$ = mk_node("ExprBinary", 3, mk_atom("BiBitXor"), $1, $3); }
-| expr '&' expr { $$ = mk_node("ExprBinary", 3, mk_atom("BiBitAnd"), $1, $3); }
-| expr SHL expr { $$ = mk_node("ExprBinary", 3, mk_atom("BiShl"), $1, $3); }
-| expr SHR expr { $$ = mk_node("ExprBinary", 3, mk_atom("BiShr"), $1, $3); }
-| expr '+' expr { $$ = mk_node("ExprBinary", 3, mk_atom("BiAdd"), $1, $3); }
-| expr '-' expr { $$ = mk_node("ExprBinary", 3, mk_atom("BiSub"), $1, $3); }
-| expr '*' expr { $$ = mk_node("ExprBinary", 3, mk_atom("BiMul"), $1, $3); }
-| expr '/' expr { $$ = mk_node("ExprBinary", 3, mk_atom("BiDiv"), $1, $3); }
-| expr '%' expr { $$ = mk_node("ExprBinary", 3, mk_atom("BiRem"), $1, $3); }
-| expr DOTDOT { $$ = mk_node("ExprRange", 2, $1, mk_none()); }
-| expr DOTDOT expr { $$ = mk_node("ExprRange", 2, $1, $3); }
-| DOTDOT expr { $$ = mk_node("ExprRange", 2, mk_none(), $2); }
-| DOTDOT { $$ = mk_node("ExprRange", 2, mk_none(), mk_none()); }
-| expr AS ty { $$ = mk_node("ExprCast", 2, $1, $3); }
-| expr ':' ty { $$ = mk_node("ExprTypeAscr", 2, $1, $3); }
-| BOX expr { $$ = mk_node("ExprBox", 1, $2); }
-| expr_qualified_path
-| block_expr
-| block
-| nonblock_prefix_expr
-;
-
-expr_nostruct
-: lit { $$ = mk_node("ExprLit", 1, $1); }
-| %prec IDENT
- path_expr { $$ = mk_node("ExprPath", 1, $1); }
-| SELF { $$ = mk_node("ExprPath", 1, mk_node("ident", 1, mk_atom("self"))); }
-| macro_expr { $$ = mk_node("ExprMac", 1, $1); }
-| expr_nostruct '?' { $$ = mk_node("ExprTry", 1, $1); }
-| expr_nostruct '.' path_generic_args_with_colons { $$ = mk_node("ExprField", 2, $1, $3); }
-| expr_nostruct '.' LIT_INTEGER { $$ = mk_node("ExprTupleIndex", 1, $1); }
-| expr_nostruct '[' maybe_expr ']' { $$ = mk_node("ExprIndex", 2, $1, $3); }
-| expr_nostruct '(' maybe_exprs ')' { $$ = mk_node("ExprCall", 2, $1, $3); }
-| '[' vec_expr ']' { $$ = mk_node("ExprVec", 1, $2); }
-| '(' maybe_exprs ')' { $$ = mk_node("ExprParen", 1, $2); }
-| CONTINUE { $$ = mk_node("ExprAgain", 0); }
-| CONTINUE ident { $$ = mk_node("ExprAgain", 1, $2); }
-| RETURN { $$ = mk_node("ExprRet", 0); }
-| RETURN expr { $$ = mk_node("ExprRet", 1, $2); }
-| BREAK { $$ = mk_node("ExprBreak", 0); }
-| BREAK ident { $$ = mk_node("ExprBreak", 1, $2); }
-| YIELD { $$ = mk_node("ExprYield", 0); }
-| YIELD expr { $$ = mk_node("ExprYield", 1, $2); }
-| expr_nostruct '=' expr_nostruct { $$ = mk_node("ExprAssign", 2, $1, $3); }
-| expr_nostruct SHLEQ expr_nostruct { $$ = mk_node("ExprAssignShl", 2, $1, $3); }
-| expr_nostruct SHREQ expr_nostruct { $$ = mk_node("ExprAssignShr", 2, $1, $3); }
-| expr_nostruct MINUSEQ expr_nostruct { $$ = mk_node("ExprAssignSub", 2, $1, $3); }
-| expr_nostruct ANDEQ expr_nostruct { $$ = mk_node("ExprAssignBitAnd", 2, $1, $3); }
-| expr_nostruct OREQ expr_nostruct { $$ = mk_node("ExprAssignBitOr", 2, $1, $3); }
-| expr_nostruct PLUSEQ expr_nostruct { $$ = mk_node("ExprAssignAdd", 2, $1, $3); }
-| expr_nostruct STAREQ expr_nostruct { $$ = mk_node("ExprAssignMul", 2, $1, $3); }
-| expr_nostruct SLASHEQ expr_nostruct { $$ = mk_node("ExprAssignDiv", 2, $1, $3); }
-| expr_nostruct CARETEQ expr_nostruct { $$ = mk_node("ExprAssignBitXor", 2, $1, $3); }
-| expr_nostruct PERCENTEQ expr_nostruct { $$ = mk_node("ExprAssignRem", 2, $1, $3); }
-| expr_nostruct OROR expr_nostruct { $$ = mk_node("ExprBinary", 3, mk_atom("BiOr"), $1, $3); }
-| expr_nostruct ANDAND expr_nostruct { $$ = mk_node("ExprBinary", 3, mk_atom("BiAnd"), $1, $3); }
-| expr_nostruct EQEQ expr_nostruct { $$ = mk_node("ExprBinary", 3, mk_atom("BiEq"), $1, $3); }
-| expr_nostruct NE expr_nostruct { $$ = mk_node("ExprBinary", 3, mk_atom("BiNe"), $1, $3); }
-| expr_nostruct '<' expr_nostruct { $$ = mk_node("ExprBinary", 3, mk_atom("BiLt"), $1, $3); }
-| expr_nostruct '>' expr_nostruct { $$ = mk_node("ExprBinary", 3, mk_atom("BiGt"), $1, $3); }
-| expr_nostruct LE expr_nostruct { $$ = mk_node("ExprBinary", 3, mk_atom("BiLe"), $1, $3); }
-| expr_nostruct GE expr_nostruct { $$ = mk_node("ExprBinary", 3, mk_atom("BiGe"), $1, $3); }
-| expr_nostruct '|' expr_nostruct { $$ = mk_node("ExprBinary", 3, mk_atom("BiBitOr"), $1, $3); }
-| expr_nostruct '^' expr_nostruct { $$ = mk_node("ExprBinary", 3, mk_atom("BiBitXor"), $1, $3); }
-| expr_nostruct '&' expr_nostruct { $$ = mk_node("ExprBinary", 3, mk_atom("BiBitAnd"), $1, $3); }
-| expr_nostruct SHL expr_nostruct { $$ = mk_node("ExprBinary", 3, mk_atom("BiShl"), $1, $3); }
-| expr_nostruct SHR expr_nostruct { $$ = mk_node("ExprBinary", 3, mk_atom("BiShr"), $1, $3); }
-| expr_nostruct '+' expr_nostruct { $$ = mk_node("ExprBinary", 3, mk_atom("BiAdd"), $1, $3); }
-| expr_nostruct '-' expr_nostruct { $$ = mk_node("ExprBinary", 3, mk_atom("BiSub"), $1, $3); }
-| expr_nostruct '*' expr_nostruct { $$ = mk_node("ExprBinary", 3, mk_atom("BiMul"), $1, $3); }
-| expr_nostruct '/' expr_nostruct { $$ = mk_node("ExprBinary", 3, mk_atom("BiDiv"), $1, $3); }
-| expr_nostruct '%' expr_nostruct { $$ = mk_node("ExprBinary", 3, mk_atom("BiRem"), $1, $3); }
-| expr_nostruct DOTDOT %prec RANGE { $$ = mk_node("ExprRange", 2, $1, mk_none()); }
-| expr_nostruct DOTDOT expr_nostruct { $$ = mk_node("ExprRange", 2, $1, $3); }
-| DOTDOT expr_nostruct { $$ = mk_node("ExprRange", 2, mk_none(), $2); }
-| DOTDOT { $$ = mk_node("ExprRange", 2, mk_none(), mk_none()); }
-| expr_nostruct AS ty { $$ = mk_node("ExprCast", 2, $1, $3); }
-| expr_nostruct ':' ty { $$ = mk_node("ExprTypeAscr", 2, $1, $3); }
-| BOX expr { $$ = mk_node("ExprBox", 1, $2); }
-| expr_qualified_path
-| block_expr
-| block
-| nonblock_prefix_expr_nostruct
-;
-
-nonblock_prefix_expr_nostruct
-: '-' expr_nostruct { $$ = mk_node("ExprUnary", 2, mk_atom("UnNeg"), $2); }
-| '!' expr_nostruct { $$ = mk_node("ExprUnary", 2, mk_atom("UnNot"), $2); }
-| '*' expr_nostruct { $$ = mk_node("ExprUnary", 2, mk_atom("UnDeref"), $2); }
-| '&' maybe_mut expr_nostruct { $$ = mk_node("ExprAddrOf", 2, $2, $3); }
-| ANDAND maybe_mut expr_nostruct { $$ = mk_node("ExprAddrOf", 1, mk_node("ExprAddrOf", 2, $2, $3)); }
-| lambda_expr_nostruct
-| MOVE lambda_expr_nostruct { $$ = $2; }
-;
-
-nonblock_prefix_expr
-: '-' expr { $$ = mk_node("ExprUnary", 2, mk_atom("UnNeg"), $2); }
-| '!' expr { $$ = mk_node("ExprUnary", 2, mk_atom("UnNot"), $2); }
-| '*' expr { $$ = mk_node("ExprUnary", 2, mk_atom("UnDeref"), $2); }
-| '&' maybe_mut expr { $$ = mk_node("ExprAddrOf", 2, $2, $3); }
-| ANDAND maybe_mut expr { $$ = mk_node("ExprAddrOf", 1, mk_node("ExprAddrOf", 2, $2, $3)); }
-| lambda_expr
-| MOVE lambda_expr { $$ = $2; }
-;
-
-expr_qualified_path
-: '<' ty_sum maybe_as_trait_ref '>' MOD_SEP ident maybe_qpath_params
-{
- $$ = mk_node("ExprQualifiedPath", 4, $2, $3, $6, $7);
-}
-| SHL ty_sum maybe_as_trait_ref '>' MOD_SEP ident maybe_as_trait_ref '>' MOD_SEP ident
-{
- $$ = mk_node("ExprQualifiedPath", 3, mk_node("ExprQualifiedPath", 3, $2, $3, $6), $7, $10);
-}
-| SHL ty_sum maybe_as_trait_ref '>' MOD_SEP ident generic_args maybe_as_trait_ref '>' MOD_SEP ident
-{
- $$ = mk_node("ExprQualifiedPath", 3, mk_node("ExprQualifiedPath", 4, $2, $3, $6, $7), $8, $11);
-}
-| SHL ty_sum maybe_as_trait_ref '>' MOD_SEP ident maybe_as_trait_ref '>' MOD_SEP ident generic_args
-{
- $$ = mk_node("ExprQualifiedPath", 4, mk_node("ExprQualifiedPath", 3, $2, $3, $6), $7, $10, $11);
-}
-| SHL ty_sum maybe_as_trait_ref '>' MOD_SEP ident generic_args maybe_as_trait_ref '>' MOD_SEP ident generic_args
-{
- $$ = mk_node("ExprQualifiedPath", 4, mk_node("ExprQualifiedPath", 4, $2, $3, $6, $7), $8, $11, $12);
-}
-
-maybe_qpath_params
-: MOD_SEP generic_args { $$ = $2; }
-| %empty { $$ = mk_none(); }
-;
-
-maybe_as_trait_ref
-: AS trait_ref { $$ = $2; }
-| %empty { $$ = mk_none(); }
-;
-
-lambda_expr
-: %prec LAMBDA
- OROR ret_ty expr { $$ = mk_node("ExprFnBlock", 3, mk_none(), $2, $3); }
-| %prec LAMBDA
- '|' '|' ret_ty expr { $$ = mk_node("ExprFnBlock", 3, mk_none(), $3, $4); }
-| %prec LAMBDA
- '|' inferrable_params '|' ret_ty expr { $$ = mk_node("ExprFnBlock", 3, $2, $4, $5); }
-| %prec LAMBDA
- '|' inferrable_params OROR lambda_expr_no_first_bar { $$ = mk_node("ExprFnBlock", 3, $2, mk_none(), $4); }
-;
-
-lambda_expr_no_first_bar
-: %prec LAMBDA
- '|' ret_ty expr { $$ = mk_node("ExprFnBlock", 3, mk_none(), $2, $3); }
-| %prec LAMBDA
- inferrable_params '|' ret_ty expr { $$ = mk_node("ExprFnBlock", 3, $1, $3, $4); }
-| %prec LAMBDA
- inferrable_params OROR lambda_expr_no_first_bar { $$ = mk_node("ExprFnBlock", 3, $1, mk_none(), $3); }
-;
-
-lambda_expr_nostruct
-: %prec LAMBDA
- OROR expr_nostruct { $$ = mk_node("ExprFnBlock", 2, mk_none(), $2); }
-| %prec LAMBDA
- '|' '|' ret_ty expr_nostruct { $$ = mk_node("ExprFnBlock", 3, mk_none(), $3, $4); }
-| %prec LAMBDA
- '|' inferrable_params '|' expr_nostruct { $$ = mk_node("ExprFnBlock", 2, $2, $4); }
-| %prec LAMBDA
- '|' inferrable_params OROR lambda_expr_nostruct_no_first_bar { $$ = mk_node("ExprFnBlock", 3, $2, mk_none(), $4); }
-;
-
-lambda_expr_nostruct_no_first_bar
-: %prec LAMBDA
- '|' ret_ty expr_nostruct { $$ = mk_node("ExprFnBlock", 3, mk_none(), $2, $3); }
-| %prec LAMBDA
- inferrable_params '|' ret_ty expr_nostruct { $$ = mk_node("ExprFnBlock", 3, $1, $3, $4); }
-| %prec LAMBDA
- inferrable_params OROR lambda_expr_nostruct_no_first_bar { $$ = mk_node("ExprFnBlock", 3, $1, mk_none(), $3); }
-;
-
-vec_expr
-: maybe_exprs
-| exprs ';' expr { $$ = mk_node("VecRepeat", 2, $1, $3); }
-;
-
-struct_expr_fields
-: field_inits
-| field_inits ','
-| maybe_field_inits default_field_init { $$ = ext_node($1, 1, $2); }
-| %empty { $$ = mk_none(); }
-;
-
-maybe_field_inits
-: field_inits
-| field_inits ','
-| %empty { $$ = mk_none(); }
-;
-
-field_inits
-: field_init { $$ = mk_node("FieldInits", 1, $1); }
-| field_inits ',' field_init { $$ = ext_node($1, 1, $3); }
-;
-
-field_init
-: ident { $$ = mk_node("FieldInit", 1, $1); }
-| ident ':' expr { $$ = mk_node("FieldInit", 2, $1, $3); }
-| LIT_INTEGER ':' expr { $$ = mk_node("FieldInit", 2, mk_atom(yytext), $3); }
-;
-
-default_field_init
-: DOTDOT expr { $$ = mk_node("DefaultFieldInit", 1, $2); }
-;
-
-block_expr
-: expr_match
-| expr_if
-| expr_if_let
-| expr_while
-| expr_while_let
-| expr_loop
-| expr_for
-| UNSAFE block { $$ = mk_node("UnsafeBlock", 1, $2); }
-| path_expr '!' maybe_ident braces_delimited_token_trees { $$ = mk_node("Macro", 3, $1, $3, $4); }
-;
-
-full_block_expr
-: block_expr
-| block_expr_dot
-;
-
-block_expr_dot
-: block_expr '.' path_generic_args_with_colons %prec IDENT { $$ = mk_node("ExprField", 2, $1, $3); }
-| block_expr_dot '.' path_generic_args_with_colons %prec IDENT { $$ = mk_node("ExprField", 2, $1, $3); }
-| block_expr '.' path_generic_args_with_colons '[' maybe_expr ']' { $$ = mk_node("ExprIndex", 3, $1, $3, $5); }
-| block_expr_dot '.' path_generic_args_with_colons '[' maybe_expr ']' { $$ = mk_node("ExprIndex", 3, $1, $3, $5); }
-| block_expr '.' path_generic_args_with_colons '(' maybe_exprs ')' { $$ = mk_node("ExprCall", 3, $1, $3, $5); }
-| block_expr_dot '.' path_generic_args_with_colons '(' maybe_exprs ')' { $$ = mk_node("ExprCall", 3, $1, $3, $5); }
-| block_expr '.' LIT_INTEGER { $$ = mk_node("ExprTupleIndex", 1, $1); }
-| block_expr_dot '.' LIT_INTEGER { $$ = mk_node("ExprTupleIndex", 1, $1); }
-;
-
-expr_match
-: MATCH expr_nostruct '{' '}' { $$ = mk_node("ExprMatch", 1, $2); }
-| MATCH expr_nostruct '{' match_clauses '}' { $$ = mk_node("ExprMatch", 2, $2, $4); }
-| MATCH expr_nostruct '{' match_clauses nonblock_match_clause '}' { $$ = mk_node("ExprMatch", 2, $2, ext_node($4, 1, $5)); }
-| MATCH expr_nostruct '{' nonblock_match_clause '}' { $$ = mk_node("ExprMatch", 2, $2, mk_node("Arms", 1, $4)); }
-;
-
-match_clauses
-: match_clause { $$ = mk_node("Arms", 1, $1); }
-| match_clauses match_clause { $$ = ext_node($1, 1, $2); }
-;
-
-match_clause
-: nonblock_match_clause ','
-| block_match_clause
-| block_match_clause ','
-;
-
-nonblock_match_clause
-: maybe_outer_attrs pats_or maybe_guard FAT_ARROW nonblock_expr { $$ = mk_node("ArmNonblock", 4, $1, $2, $3, $5); }
-| maybe_outer_attrs pats_or maybe_guard FAT_ARROW block_expr_dot { $$ = mk_node("ArmNonblock", 4, $1, $2, $3, $5); }
-;
-
-block_match_clause
-: maybe_outer_attrs pats_or maybe_guard FAT_ARROW block { $$ = mk_node("ArmBlock", 4, $1, $2, $3, $5); }
-| maybe_outer_attrs pats_or maybe_guard FAT_ARROW block_expr { $$ = mk_node("ArmBlock", 4, $1, $2, $3, $5); }
-;
-
-maybe_guard
-: IF expr_nostruct { $$ = $2; }
-| %empty { $$ = mk_none(); }
-;
-
-expr_if
-: IF expr_nostruct block { $$ = mk_node("ExprIf", 2, $2, $3); }
-| IF expr_nostruct block ELSE block_or_if { $$ = mk_node("ExprIf", 3, $2, $3, $5); }
-;
-
-expr_if_let
-: IF LET pat '=' expr_nostruct block { $$ = mk_node("ExprIfLet", 3, $3, $5, $6); }
-| IF LET pat '=' expr_nostruct block ELSE block_or_if { $$ = mk_node("ExprIfLet", 4, $3, $5, $6, $8); }
-;
-
-block_or_if
-: block
-| expr_if
-| expr_if_let
-;
-
-expr_while
-: maybe_label WHILE expr_nostruct block { $$ = mk_node("ExprWhile", 3, $1, $3, $4); }
-;
-
-expr_while_let
-: maybe_label WHILE LET pat '=' expr_nostruct block { $$ = mk_node("ExprWhileLet", 4, $1, $4, $6, $7); }
-;
-
-expr_loop
-: maybe_label LOOP block { $$ = mk_node("ExprLoop", 2, $1, $3); }
-;
-
-expr_for
-: maybe_label FOR pat IN expr_nostruct block { $$ = mk_node("ExprForLoop", 4, $1, $3, $5, $6); }
-;
-
-maybe_label
-: lifetime ':'
-| %empty { $$ = mk_none(); }
-;
-
-let
-: LET pat maybe_ty_ascription maybe_init_expr ';' { $$ = mk_node("DeclLocal", 3, $2, $3, $4); }
-;
-
-////////////////////////////////////////////////////////////////////////
-// Part 5: Macros and misc. rules
-////////////////////////////////////////////////////////////////////////
-
-lit
-: LIT_BYTE { $$ = mk_node("LitByte", 1, mk_atom(yytext)); }
-| LIT_CHAR { $$ = mk_node("LitChar", 1, mk_atom(yytext)); }
-| LIT_INTEGER { $$ = mk_node("LitInteger", 1, mk_atom(yytext)); }
-| LIT_FLOAT { $$ = mk_node("LitFloat", 1, mk_atom(yytext)); }
-| TRUE { $$ = mk_node("LitBool", 1, mk_atom(yytext)); }
-| FALSE { $$ = mk_node("LitBool", 1, mk_atom(yytext)); }
-| str
-;
-
-str
-: LIT_STR { $$ = mk_node("LitStr", 1, mk_atom(yytext), mk_atom("CookedStr")); }
-| LIT_STR_RAW { $$ = mk_node("LitStr", 1, mk_atom(yytext), mk_atom("RawStr")); }
-| LIT_BYTE_STR { $$ = mk_node("LitByteStr", 1, mk_atom(yytext), mk_atom("ByteStr")); }
-| LIT_BYTE_STR_RAW { $$ = mk_node("LitByteStr", 1, mk_atom(yytext), mk_atom("RawByteStr")); }
-;
-
-maybe_ident
-: %empty { $$ = mk_none(); }
-| ident
-;
-
-ident
-: IDENT { $$ = mk_node("ident", 1, mk_atom(yytext)); }
-// Weak keywords that can be used as identifiers
-| CATCH { $$ = mk_node("ident", 1, mk_atom(yytext)); }
-| DEFAULT { $$ = mk_node("ident", 1, mk_atom(yytext)); }
-| UNION { $$ = mk_node("ident", 1, mk_atom(yytext)); }
-;
-
-unpaired_token
-: SHL { $$ = mk_atom(yytext); }
-| SHR { $$ = mk_atom(yytext); }
-| LE { $$ = mk_atom(yytext); }
-| EQEQ { $$ = mk_atom(yytext); }
-| NE { $$ = mk_atom(yytext); }
-| GE { $$ = mk_atom(yytext); }
-| ANDAND { $$ = mk_atom(yytext); }
-| OROR { $$ = mk_atom(yytext); }
-| LARROW { $$ = mk_atom(yytext); }
-| SHLEQ { $$ = mk_atom(yytext); }
-| SHREQ { $$ = mk_atom(yytext); }
-| MINUSEQ { $$ = mk_atom(yytext); }
-| ANDEQ { $$ = mk_atom(yytext); }
-| OREQ { $$ = mk_atom(yytext); }
-| PLUSEQ { $$ = mk_atom(yytext); }
-| STAREQ { $$ = mk_atom(yytext); }
-| SLASHEQ { $$ = mk_atom(yytext); }
-| CARETEQ { $$ = mk_atom(yytext); }
-| PERCENTEQ { $$ = mk_atom(yytext); }
-| DOTDOT { $$ = mk_atom(yytext); }
-| DOTDOTDOT { $$ = mk_atom(yytext); }
-| MOD_SEP { $$ = mk_atom(yytext); }
-| RARROW { $$ = mk_atom(yytext); }
-| FAT_ARROW { $$ = mk_atom(yytext); }
-| LIT_BYTE { $$ = mk_atom(yytext); }
-| LIT_CHAR { $$ = mk_atom(yytext); }
-| LIT_INTEGER { $$ = mk_atom(yytext); }
-| LIT_FLOAT { $$ = mk_atom(yytext); }
-| LIT_STR { $$ = mk_atom(yytext); }
-| LIT_STR_RAW { $$ = mk_atom(yytext); }
-| LIT_BYTE_STR { $$ = mk_atom(yytext); }
-| LIT_BYTE_STR_RAW { $$ = mk_atom(yytext); }
-| IDENT { $$ = mk_atom(yytext); }
-| UNDERSCORE { $$ = mk_atom(yytext); }
-| LIFETIME { $$ = mk_atom(yytext); }
-| SELF { $$ = mk_atom(yytext); }
-| STATIC { $$ = mk_atom(yytext); }
-| ABSTRACT { $$ = mk_atom(yytext); }
-| ALIGNOF { $$ = mk_atom(yytext); }
-| AS { $$ = mk_atom(yytext); }
-| BECOME { $$ = mk_atom(yytext); }
-| BREAK { $$ = mk_atom(yytext); }
-| CATCH { $$ = mk_atom(yytext); }
-| CRATE { $$ = mk_atom(yytext); }
-| DEFAULT { $$ = mk_atom(yytext); }
-| DO { $$ = mk_atom(yytext); }
-| ELSE { $$ = mk_atom(yytext); }
-| ENUM { $$ = mk_atom(yytext); }
-| EXTERN { $$ = mk_atom(yytext); }
-| FALSE { $$ = mk_atom(yytext); }
-| FINAL { $$ = mk_atom(yytext); }
-| FN { $$ = mk_atom(yytext); }
-| FOR { $$ = mk_atom(yytext); }
-| IF { $$ = mk_atom(yytext); }
-| IMPL { $$ = mk_atom(yytext); }
-| IN { $$ = mk_atom(yytext); }
-| LET { $$ = mk_atom(yytext); }
-| LOOP { $$ = mk_atom(yytext); }
-| MACRO { $$ = mk_atom(yytext); }
-| MATCH { $$ = mk_atom(yytext); }
-| MOD { $$ = mk_atom(yytext); }
-| MOVE { $$ = mk_atom(yytext); }
-| MUT { $$ = mk_atom(yytext); }
-| OFFSETOF { $$ = mk_atom(yytext); }
-| OVERRIDE { $$ = mk_atom(yytext); }
-| PRIV { $$ = mk_atom(yytext); }
-| PUB { $$ = mk_atom(yytext); }
-| PURE { $$ = mk_atom(yytext); }
-| REF { $$ = mk_atom(yytext); }
-| RETURN { $$ = mk_atom(yytext); }
-| STRUCT { $$ = mk_atom(yytext); }
-| SIZEOF { $$ = mk_atom(yytext); }
-| SUPER { $$ = mk_atom(yytext); }
-| TRUE { $$ = mk_atom(yytext); }
-| TRAIT { $$ = mk_atom(yytext); }
-| TYPE { $$ = mk_atom(yytext); }
-| UNION { $$ = mk_atom(yytext); }
-| UNSAFE { $$ = mk_atom(yytext); }
-| UNSIZED { $$ = mk_atom(yytext); }
-| USE { $$ = mk_atom(yytext); }
-| VIRTUAL { $$ = mk_atom(yytext); }
-| WHILE { $$ = mk_atom(yytext); }
-| YIELD { $$ = mk_atom(yytext); }
-| CONTINUE { $$ = mk_atom(yytext); }
-| PROC { $$ = mk_atom(yytext); }
-| BOX { $$ = mk_atom(yytext); }
-| CONST { $$ = mk_atom(yytext); }
-| WHERE { $$ = mk_atom(yytext); }
-| TYPEOF { $$ = mk_atom(yytext); }
-| INNER_DOC_COMMENT { $$ = mk_atom(yytext); }
-| OUTER_DOC_COMMENT { $$ = mk_atom(yytext); }
-| SHEBANG { $$ = mk_atom(yytext); }
-| STATIC_LIFETIME { $$ = mk_atom(yytext); }
-| ';' { $$ = mk_atom(yytext); }
-| ',' { $$ = mk_atom(yytext); }
-| '.' { $$ = mk_atom(yytext); }
-| '@' { $$ = mk_atom(yytext); }
-| '#' { $$ = mk_atom(yytext); }
-| '~' { $$ = mk_atom(yytext); }
-| ':' { $$ = mk_atom(yytext); }
-| '$' { $$ = mk_atom(yytext); }
-| '=' { $$ = mk_atom(yytext); }
-| '?' { $$ = mk_atom(yytext); }
-| '!' { $$ = mk_atom(yytext); }
-| '<' { $$ = mk_atom(yytext); }
-| '>' { $$ = mk_atom(yytext); }
-| '-' { $$ = mk_atom(yytext); }
-| '&' { $$ = mk_atom(yytext); }
-| '|' { $$ = mk_atom(yytext); }
-| '+' { $$ = mk_atom(yytext); }
-| '*' { $$ = mk_atom(yytext); }
-| '/' { $$ = mk_atom(yytext); }
-| '^' { $$ = mk_atom(yytext); }
-| '%' { $$ = mk_atom(yytext); }
-;
-
-token_trees
-: %empty { $$ = mk_node("TokenTrees", 0); }
-| token_trees token_tree { $$ = ext_node($1, 1, $2); }
-;
-
-token_tree
-: delimited_token_trees
-| unpaired_token { $$ = mk_node("TTTok", 1, $1); }
-;
-
-delimited_token_trees
-: parens_delimited_token_trees
-| braces_delimited_token_trees
-| brackets_delimited_token_trees
-;
-
-parens_delimited_token_trees
-: '(' token_trees ')'
-{
- $$ = mk_node("TTDelim", 3,
- mk_node("TTTok", 1, mk_atom("(")),
- $2,
- mk_node("TTTok", 1, mk_atom(")")));
-}
-;
-
-braces_delimited_token_trees
-: '{' token_trees '}'
-{
- $$ = mk_node("TTDelim", 3,
- mk_node("TTTok", 1, mk_atom("{")),
- $2,
- mk_node("TTTok", 1, mk_atom("}")));
-}
-;
-
-brackets_delimited_token_trees
-: '[' token_trees ']'
-{
- $$ = mk_node("TTDelim", 3,
- mk_node("TTTok", 1, mk_atom("[")),
- $2,
- mk_node("TTTok", 1, mk_atom("]")));
-}
-;
diff --git a/src/grammar/raw-string-literal-ambiguity.md b/src/grammar/raw-string-literal-ambiguity.md
deleted file mode 100644
index c909f2333148a..0000000000000
--- a/src/grammar/raw-string-literal-ambiguity.md
+++ /dev/null
@@ -1,64 +0,0 @@
-Rust's lexical grammar is not context-free. Raw string literals are the source
-of the problem. Informally, a raw string literal is an `r`, followed by `N`
-hashes (where N can be zero), a quote, any characters, then a quote followed
-by `N` hashes. Critically, once inside the first pair of quotes,
-another quote cannot be followed by `N` consecutive hashes. e.g.
-`r###""###"###` is invalid.
-
-This grammar describes this as best possible:
-
- R -> 'r' S
- S -> '"' B '"'
- S -> '#' S '#'
- B -> . B
- B -> ε
-
-Where `.` represents any character, and `ε` the empty string. Consider the
-string `r#""#"#`. This string is not a valid raw string literal, but can be
-accepted as one by the above grammar, using the derivation:
-
- R : #""#"#
- S : ""#"
- S : "#
- B : #
- B : ε
-
-(Where `T : U` means the rule `T` is applied, and `U` is the remainder of the
-string.) The difficulty arises from the fact that it is fundamentally
-context-sensitive. In particular, the context needed is the number of hashes.
-
-To prove that Rust's string literals are not context-free, we will use
-the fact that context-free languages are closed under intersection with
-regular languages, and the
-[pumping lemma for context-free languages](https://en.wikipedia.org/wiki/Pumping_lemma_for_context-free_languages).
-
-Consider the regular language `R = r#+""#*"#+`. If Rust's raw string literals are
-context-free, then their intersection with `R`, `R'`, should also be context-free.
-Therefore, to prove that raw string literals are not context-free,
-it is sufficient to prove that `R'` is not context-free.
-
-The language `R'` is `{r#^n""#^m"#^n | m < n}`.
-
-Assume `R'` *is* context-free. Then `R'` has some pumping length `p > 0` for which
-the pumping lemma applies. Consider the following string `s` in `R'`:
-
-`r#^p""#^{p-1}"#^p`
-
-e.g. for `p = 2`: `s = r##""#"##`
-
-Then `s = uvwxy` for some choice of `uvwxy` such that `vx` is non-empty,
-`|vwx| < p+1`, and `uv^iwx^iy` is in `R'` for all `i >= 0`.
-
-Neither `v` nor `x` can contain a `"` or `r`, as the number of these characters
-in any string in `R'` is fixed. So `v` and `x` contain only hashes.
-Consequently, of the three sequences of hashes, `v` and `x` combined
-can only pump two of them.
-If we ever choose the central sequence of hashes, then one of the outer sequences
-will not grow when we pump, leading to an imbalance between the outer sequences.
-Therefore, we must pump both outer sequences of hashes. However,
-there are `p+2` characters between these two sequences of hashes, and `|vwx|` must
-be less than `p+1`. Therefore we have a contradiction, and `R'` must not be
-context-free.
-
-Since `R'` is not context-free, it follows that the Rust's raw string literals
-must not be context-free.
diff --git a/src/grammar/testparser.py b/src/grammar/testparser.py
deleted file mode 100755
index 4b5a7fb9e10b5..0000000000000
--- a/src/grammar/testparser.py
+++ /dev/null
@@ -1,66 +0,0 @@
-#!/usr/bin/env python
-
-# ignore-tidy-linelength
-
-import sys
-
-import os
-import subprocess
-import argparse
-
-# usage: testparser.py [-h] [-p PARSER [PARSER ...]] -s SOURCE_DIR
-
-# Parsers should read from stdin and return exit status 0 for a
-# successful parse, and nonzero for an unsuccessful parse
-
-parser = argparse.ArgumentParser()
-parser.add_argument('-p', '--parser', nargs='+')
-parser.add_argument('-s', '--source-dir', nargs=1, required=True)
-args = parser.parse_args(sys.argv[1:])
-
-total = 0
-ok = {}
-bad = {}
-for parser in args.parser:
- ok[parser] = 0
- bad[parser] = []
-devnull = open(os.devnull, 'w')
-print("\n")
-
-for base, dirs, files in os.walk(args.source_dir[0]):
- for f in filter(lambda p: p.endswith('.rs'), files):
- p = os.path.join(base, f)
- parse_fail = 'parse-fail' in p
- if sys.version_info.major == 3:
- lines = open(p, encoding='utf-8').readlines()
- else:
- lines = open(p).readlines()
- if any('ignore-test' in line or 'ignore-lexer-test' in line for line in lines):
- continue
- total += 1
- for parser in args.parser:
- if subprocess.call(parser, stdin=open(p), stderr=subprocess.STDOUT, stdout=devnull) == 0:
- if parse_fail:
- bad[parser].append(p)
- else:
- ok[parser] += 1
- else:
- if parse_fail:
- ok[parser] += 1
- else:
- bad[parser].append(p)
- parser_stats = ', '.join(['{}: {}'.format(parser, ok[parser]) for parser in args.parser])
- sys.stdout.write("\033[K\r total: {}, {}, scanned {}"
- .format(total, os.path.relpath(parser_stats), os.path.relpath(p)))
-
-devnull.close()
-
-print("\n")
-
-for parser in args.parser:
- filename = os.path.basename(parser) + '.bad'
- print("writing {} files that did not yield the correct result with {} to {}".format(len(bad[parser]), parser, filename))
- with open(filename, "w") as f:
- for p in bad[parser]:
- f.write(p)
- f.write("\n")
diff --git a/src/grammar/tokens.h b/src/grammar/tokens.h
deleted file mode 100644
index 297e3dc841e87..0000000000000
--- a/src/grammar/tokens.h
+++ /dev/null
@@ -1,99 +0,0 @@
-enum Token {
- SHL = 257, // Parser generators reserve 0-256 for char literals
- SHR,
- LE,
- EQEQ,
- NE,
- GE,
- ANDAND,
- OROR,
- SHLEQ,
- SHREQ,
- MINUSEQ,
- ANDEQ,
- OREQ,
- PLUSEQ,
- STAREQ,
- SLASHEQ,
- CARETEQ,
- PERCENTEQ,
- DOTDOT,
- DOTDOTDOT,
- MOD_SEP,
- LARROW,
- RARROW,
- FAT_ARROW,
- LIT_BYTE,
- LIT_CHAR,
- LIT_INTEGER,
- LIT_FLOAT,
- LIT_STR,
- LIT_STR_RAW,
- LIT_BYTE_STR,
- LIT_BYTE_STR_RAW,
- IDENT,
- UNDERSCORE,
- LIFETIME,
-
- // keywords
- SELF,
- STATIC,
- ABSTRACT,
- ALIGNOF,
- AS,
- BECOME,
- BREAK,
- CATCH,
- CRATE,
- DEFAULT,
- DO,
- ELSE,
- ENUM,
- EXTERN,
- FALSE,
- FINAL,
- FN,
- FOR,
- IF,
- IMPL,
- IN,
- LET,
- LOOP,
- MACRO,
- MATCH,
- MOD,
- MOVE,
- MUT,
- OFFSETOF,
- OVERRIDE,
- PRIV,
- PUB,
- PURE,
- REF,
- RETURN,
- SIZEOF,
- STRUCT,
- SUPER,
- UNION,
- TRUE,
- TRAIT,
- TYPE,
- UNSAFE,
- UNSIZED,
- USE,
- VIRTUAL,
- WHILE,
- YIELD,
- CONTINUE,
- PROC,
- BOX,
- CONST,
- WHERE,
- TYPEOF,
- INNER_DOC_COMMENT,
- OUTER_DOC_COMMENT,
-
- SHEBANG,
- SHEBANG_LINE,
- STATIC_LIFETIME
-};
diff --git a/src/librustc/hir/lowering/expr.rs b/src/librustc/hir/lowering/expr.rs
index 2f0a318d5363e..9dcecedd97cae 100644
--- a/src/librustc/hir/lowering/expr.rs
+++ b/src/librustc/hir/lowering/expr.rs
@@ -1037,10 +1037,9 @@ impl LoweringContext<'_> {
) -> hir::Expr {
// expand
let mut head = self.lower_expr(head);
- let head_sp = head.span;
let desugared_span = self.mark_span_with_reason(
DesugaringKind::ForLoop,
- head_sp,
+ head.span,
None,
);
head.span = desugared_span;
@@ -1086,21 +1085,21 @@ impl LoweringContext<'_> {
// `match ::std::iter::Iterator::next(&mut iter) { ... }`
let match_expr = {
- let iter = P(self.expr_ident(head_sp, iter, iter_pat_nid));
- let ref_mut_iter = self.expr_mut_addr_of(head_sp, iter);
+ let iter = P(self.expr_ident(desugared_span, iter, iter_pat_nid));
+ let ref_mut_iter = self.expr_mut_addr_of(desugared_span, iter);
let next_path = &[sym::iter, sym::Iterator, sym::next];
let next_expr = P(self.expr_call_std_path(
- head_sp,
+ desugared_span,
next_path,
hir_vec![ref_mut_iter],
));
let arms = hir_vec![pat_arm, break_arm];
- self.expr_match(head_sp, next_expr, arms, hir::MatchSource::ForLoopDesugar)
+ self.expr_match(desugared_span, next_expr, arms, hir::MatchSource::ForLoopDesugar)
};
- let match_stmt = self.stmt_expr(head_sp, match_expr);
+ let match_stmt = self.stmt_expr(desugared_span, match_expr);
- let next_expr = P(self.expr_ident(head_sp, next_ident, next_pat_hid));
+ let next_expr = P(self.expr_ident(desugared_span, next_ident, next_pat_hid));
// `let mut __next`
let next_let = self.stmt_let_pat(
@@ -1115,7 +1114,7 @@ impl LoweringContext<'_> {
let pat = self.lower_pat(pat);
let pat_let = self.stmt_let_pat(
ThinVec::new(),
- head_sp,
+ desugared_span,
Some(next_expr),
pat,
hir::LocalSource::ForLoopDesugar,
@@ -1152,14 +1151,14 @@ impl LoweringContext<'_> {
let into_iter_path =
&[sym::iter, sym::IntoIterator, sym::into_iter];
P(self.expr_call_std_path(
- head_sp,
+ desugared_span,
into_iter_path,
hir_vec![head],
))
};
let match_expr = P(self.expr_match(
- head_sp,
+ desugared_span,
into_iter_expr,
hir_vec![iter_arm],
hir::MatchSource::ForLoopDesugar,
@@ -1171,7 +1170,7 @@ impl LoweringContext<'_> {
// surrounding scope of the `match` since the `match` is not a terminating scope.
//
// Also, add the attributes to the outer returned expr node.
- self.expr_drop_temps(head_sp, match_expr, e.attrs.clone())
+ self.expr_drop_temps(desugared_span, match_expr, e.attrs.clone())
}
/// Desugar `ExprKind::Try` from: `?` into:
diff --git a/src/librustc/hir/map/mod.rs b/src/librustc/hir/map/mod.rs
index 42a4a9909f8a9..a1011697ef160 100644
--- a/src/librustc/hir/map/mod.rs
+++ b/src/librustc/hir/map/mod.rs
@@ -818,6 +818,32 @@ impl<'hir> Map<'hir> {
CRATE_HIR_ID
}
+ /// When on a match arm tail expression or on a match arm, give back the enclosing `match`
+ /// expression.
+ ///
+ /// Used by error reporting when there's a type error in a match arm caused by the `match`
+ /// expression needing to be unit.
+ pub fn get_match_if_cause(&self, hir_id: HirId) -> Option<&Expr> {
+ for (_, node) in ParentHirIterator::new(hir_id, &self) {
+ match node {
+ Node::Item(_) |
+ Node::ForeignItem(_) |
+ Node::TraitItem(_) |
+ Node::ImplItem(_) => break,
+ Node::Expr(expr) => match expr.kind {
+ ExprKind::Match(_, _, _) => return Some(expr),
+ _ => {}
+ },
+ Node::Stmt(stmt) => match stmt.kind {
+ StmtKind::Local(_) => break,
+ _ => {}
+ }
+ _ => {}
+ }
+ }
+ None
+ }
+
/// Returns the nearest enclosing scope. A scope is roughly an item or block.
pub fn get_enclosing_scope(&self, hir_id: HirId) -> Option {
for (hir_id, node) in ParentHirIterator::new(hir_id, &self) {
diff --git a/src/librustc/mir/interpret/mod.rs b/src/librustc/mir/interpret/mod.rs
index cd58396d95c62..e925d7429fff4 100644
--- a/src/librustc/mir/interpret/mod.rs
+++ b/src/librustc/mir/interpret/mod.rs
@@ -101,7 +101,7 @@ pub use self::error::{
InvalidProgramInfo, ResourceExhaustionInfo, UndefinedBehaviorInfo,
};
-pub use self::value::{Scalar, ScalarMaybeUndef, RawConst, ConstValue};
+pub use self::value::{Scalar, ScalarMaybeUndef, RawConst, ConstValue, get_slice_bytes};
pub use self::allocation::{Allocation, AllocationExtra, Relocations, UndefMask};
diff --git a/src/librustc/mir/interpret/value.rs b/src/librustc/mir/interpret/value.rs
index b8bc741419738..32f45cd9d4720 100644
--- a/src/librustc/mir/interpret/value.rs
+++ b/src/librustc/mir/interpret/value.rs
@@ -611,3 +611,18 @@ impl_stable_hash_for!(enum crate::mir::interpret::ScalarMaybeUndef {
Scalar(v),
Undef
});
+
+/// Gets the bytes of a constant slice value.
+pub fn get_slice_bytes<'tcx>(cx: &impl HasDataLayout, val: ConstValue<'tcx>) -> &'tcx [u8] {
+ if let ConstValue::Slice { data, start, end } = val {
+ let len = end - start;
+ data.get_bytes(
+ cx,
+ // invent a pointer, only the offset is relevant anyway
+ Pointer::new(AllocId(0), Size::from_bytes(start as u64)),
+ Size::from_bytes(len as u64),
+ ).unwrap_or_else(|err| bug!("const slice is invalid: {:?}", err))
+ } else {
+ bug!("expected const slice, but found another const value");
+ }
+}
diff --git a/src/librustc/ty/relate.rs b/src/librustc/ty/relate.rs
index 2af6963f7122a..3bd61e3455436 100644
--- a/src/librustc/ty/relate.rs
+++ b/src/librustc/ty/relate.rs
@@ -8,7 +8,7 @@ use crate::hir::def_id::DefId;
use crate::ty::subst::{GenericArg, GenericArgKind, SubstsRef};
use crate::ty::{self, Ty, TyCtxt, TypeFoldable};
use crate::ty::error::{ExpectedFound, TypeError};
-use crate::mir::interpret::{ConstValue, Scalar};
+use crate::mir::interpret::{ConstValue, get_slice_bytes, Scalar};
use std::rc::Rc;
use std::iter;
use rustc_target::spec::abi;
@@ -584,7 +584,20 @@ pub fn super_relate_consts>(
// FIXME(const_generics): we should either handle `Scalar::Ptr` or add a comment
// saying that we're not handling it intentionally.
- // FIXME(const_generics): handle `ConstValue::ByRef` and `ConstValue::Slice`.
+ (a_val @ ConstValue::Slice { .. }, b_val @ ConstValue::Slice { .. }) => {
+ let a_bytes = get_slice_bytes(&tcx, a_val);
+ let b_bytes = get_slice_bytes(&tcx, b_val);
+ if a_bytes == b_bytes {
+ Ok(tcx.mk_const(ty::Const {
+ val: a_val,
+ ty: a.ty,
+ }))
+ } else {
+ Err(TypeError::ConstMismatch(expected_found(relation, &a, &b)))
+ }
+ }
+
+ // FIXME(const_generics): handle `ConstValue::ByRef`.
// FIXME(const_generics): this is wrong, as it is a projection
(ConstValue::Unevaluated(a_def_id, a_substs),
diff --git a/src/librustc_mir/hair/pattern/mod.rs b/src/librustc_mir/hair/pattern/mod.rs
index 4d2fee3d160ed..fcdf2719ab627 100644
--- a/src/librustc_mir/hair/pattern/mod.rs
+++ b/src/librustc_mir/hair/pattern/mod.rs
@@ -13,12 +13,12 @@ use crate::hair::constant::*;
use rustc::lint;
use rustc::mir::{Field, BorrowKind, Mutability};
use rustc::mir::{UserTypeProjection};
-use rustc::mir::interpret::{GlobalId, ConstValue, sign_extend, AllocId, Pointer};
+use rustc::mir::interpret::{GlobalId, ConstValue, get_slice_bytes, sign_extend};
use rustc::traits::{ObligationCause, PredicateObligation};
use rustc::ty::{self, Region, TyCtxt, AdtDef, Ty, UserType, DefIdTree};
use rustc::ty::{CanonicalUserType, CanonicalUserTypeAnnotation, CanonicalUserTypeAnnotations};
use rustc::ty::subst::{SubstsRef, GenericArg};
-use rustc::ty::layout::{VariantIdx, Size};
+use rustc::ty::layout::VariantIdx;
use rustc::hir::{self, RangeEnd};
use rustc::hir::def::{CtorOf, Res, DefKind, CtorKind};
use rustc::hir::pat_util::EnumerateAndAdjustIterator;
@@ -1526,27 +1526,10 @@ pub fn compare_const_vals<'tcx>(
if let ty::Str = ty.kind {
match (a.val, b.val) {
- (
- ConstValue::Slice { data: alloc_a, start: offset_a, end: end_a },
- ConstValue::Slice { data: alloc_b, start: offset_b, end: end_b },
- ) => {
- let len_a = end_a - offset_a;
- let len_b = end_b - offset_b;
- let a = alloc_a.get_bytes(
- &tcx,
- // invent a pointer, only the offset is relevant anyway
- Pointer::new(AllocId(0), Size::from_bytes(offset_a as u64)),
- Size::from_bytes(len_a as u64),
- );
- let b = alloc_b.get_bytes(
- &tcx,
- // invent a pointer, only the offset is relevant anyway
- Pointer::new(AllocId(0), Size::from_bytes(offset_b as u64)),
- Size::from_bytes(len_b as u64),
- );
- if let (Ok(a), Ok(b)) = (a, b) {
- return from_bool(a == b);
- }
+ (ConstValue::Slice { .. }, ConstValue::Slice { .. }) => {
+ let a_bytes = get_slice_bytes(&tcx, a.val);
+ let b_bytes = get_slice_bytes(&tcx, b.val);
+ return from_bool(a_bytes == b_bytes);
}
_ => (),
}
diff --git a/src/librustc_resolve/late/diagnostics.rs b/src/librustc_resolve/late/diagnostics.rs
index 0d35cc53ac6f3..d3bf82b66ad1c 100644
--- a/src/librustc_resolve/late/diagnostics.rs
+++ b/src/librustc_resolve/late/diagnostics.rs
@@ -348,7 +348,7 @@ impl<'a> LateResolutionVisitor<'a, '_> {
_ => false,
};
- let mut bad_struct_syntax_suggestion = || {
+ let mut bad_struct_syntax_suggestion = |def_id: DefId| {
let (followed_by_brace, closing_brace) = self.followed_by_brace(span);
let mut suggested = false;
match source {
@@ -374,6 +374,9 @@ impl<'a> LateResolutionVisitor<'a, '_> {
_ => {}
}
if !suggested {
+ if let Some(span) = self.r.definitions.opt_span(def_id) {
+ err.span_label(span, &format!("`{}` defined here", path_str));
+ }
err.span_label(
span,
format!("did you mean `{} {{ /* fields */ }}`?", path_str),
@@ -437,18 +440,21 @@ impl<'a> LateResolutionVisitor<'a, '_> {
);
}
} else {
- bad_struct_syntax_suggestion();
+ bad_struct_syntax_suggestion(def_id);
}
}
- (Res::Def(DefKind::Union, _), _) |
- (Res::Def(DefKind::Variant, _), _) |
- (Res::Def(DefKind::Ctor(_, CtorKind::Fictive), _), _) if ns == ValueNS => {
- bad_struct_syntax_suggestion();
+ (Res::Def(DefKind::Union, def_id), _) |
+ (Res::Def(DefKind::Variant, def_id), _) |
+ (Res::Def(DefKind::Ctor(_, CtorKind::Fictive), def_id), _) if ns == ValueNS => {
+ bad_struct_syntax_suggestion(def_id);
}
- (Res::Def(DefKind::Ctor(_, CtorKind::Fn), _), _) if ns == ValueNS => {
+ (Res::Def(DefKind::Ctor(_, CtorKind::Fn), def_id), _) if ns == ValueNS => {
+ if let Some(span) = self.r.definitions.opt_span(def_id) {
+ err.span_label(span, &format!("`{}` defined here", path_str));
+ }
err.span_label(
span,
- format!("did you mean `{} ( /* fields */ )`?", path_str),
+ format!("did you mean `{}( /* fields */ )`?", path_str),
);
}
(Res::SelfTy(..), _) if ns == ValueNS => {
diff --git a/src/librustc_typeck/check/_match.rs b/src/librustc_typeck/check/_match.rs
index 13b6b1b8aa08d..a1daed005f302 100644
--- a/src/librustc_typeck/check/_match.rs
+++ b/src/librustc_typeck/check/_match.rs
@@ -36,7 +36,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
// 2. By expecting `bool` for `expr` we get nice diagnostics for e.g. `if x = y { .. }`.
//
// FIXME(60707): Consider removing hack with principled solution.
- self.check_expr_has_type_or_error(discrim, self.tcx.types.bool)
+ self.check_expr_has_type_or_error(discrim, self.tcx.types.bool, |_| {})
} else {
self.demand_discriminant_type(arms, discrim)
};
@@ -106,7 +106,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
if let Some(g) = &arm.guard {
self.diverges.set(pats_diverge);
match g {
- hir::Guard::If(e) => self.check_expr_has_type_or_error(e, tcx.types.bool),
+ hir::Guard::If(e) => {
+ self.check_expr_has_type_or_error(e, tcx.types.bool, |_| {})
+ }
};
}
@@ -442,7 +444,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
kind: TypeVariableOriginKind::TypeInference,
span: discrim.span,
});
- self.check_expr_has_type_or_error(discrim, discrim_ty);
+ self.check_expr_has_type_or_error(discrim, discrim_ty, |_| {});
discrim_ty
}
}
diff --git a/src/librustc_typeck/check/coercion.rs b/src/librustc_typeck/check/coercion.rs
index 564a0eac75539..56962d53a6450 100644
--- a/src/librustc_typeck/check/coercion.rs
+++ b/src/librustc_typeck/check/coercion.rs
@@ -1163,18 +1163,20 @@ impl<'tcx, 'exprs, E: AsCoercionSite> CoerceMany<'tcx, 'exprs, E> {
fcx.try_coerce(expression, expression_ty, self.expected_ty, AllowTwoPhase::No)
} else {
match self.expressions {
- Expressions::Dynamic(ref exprs) =>
- fcx.try_find_coercion_lub(cause,
- exprs,
- self.merged_ty(),
- expression,
- expression_ty),
- Expressions::UpFront(ref coercion_sites) =>
- fcx.try_find_coercion_lub(cause,
- &coercion_sites[0..self.pushed],
- self.merged_ty(),
- expression,
- expression_ty),
+ Expressions::Dynamic(ref exprs) => fcx.try_find_coercion_lub(
+ cause,
+ exprs,
+ self.merged_ty(),
+ expression,
+ expression_ty,
+ ),
+ Expressions::UpFront(ref coercion_sites) => fcx.try_find_coercion_lub(
+ cause,
+ &coercion_sites[0..self.pushed],
+ self.merged_ty(),
+ expression,
+ expression_ty,
+ ),
}
}
} else {
@@ -1216,7 +1218,7 @@ impl<'tcx, 'exprs, E: AsCoercionSite> CoerceMany<'tcx, 'exprs, E> {
self.pushed += 1;
}
}
- Err(err) => {
+ Err(coercion_error) => {
let (expected, found) = if label_expression_as_expected {
// In the case where this is a "forced unit", like
// `break`, we want to call the `()` "expected"
@@ -1232,41 +1234,42 @@ impl<'tcx, 'exprs, E: AsCoercionSite> CoerceMany<'tcx, 'exprs, E> {
(self.final_ty.unwrap_or(self.expected_ty), expression_ty)
};
- let mut db;
+ let mut err;
match cause.code {
ObligationCauseCode::ReturnNoExpression => {
- db = struct_span_err!(
+ err = struct_span_err!(
fcx.tcx.sess, cause.span, E0069,
"`return;` in a function whose return type is not `()`");
- db.span_label(cause.span, "return type is not `()`");
+ err.span_label(cause.span, "return type is not `()`");
}
ObligationCauseCode::BlockTailExpression(blk_id) => {
let parent_id = fcx.tcx.hir().get_parent_node(blk_id);
- db = self.report_return_mismatched_types(
+ err = self.report_return_mismatched_types(
cause,
expected,
found,
- err,
+ coercion_error,
fcx,
parent_id,
expression.map(|expr| (expr, blk_id)),
);
}
ObligationCauseCode::ReturnValue(id) => {
- db = self.report_return_mismatched_types(
- cause, expected, found, err, fcx, id, None);
+ err = self.report_return_mismatched_types(
+ cause, expected, found, coercion_error, fcx, id, None);
}
_ => {
- db = fcx.report_mismatched_types(cause, expected, found, err);
+ err = fcx.report_mismatched_types(cause, expected, found, coercion_error);
}
}
if let Some(augment_error) = augment_error {
- augment_error(&mut db);
+ augment_error(&mut err);
}
// Error possibly reported in `check_assign` so avoid emitting error again.
- db.emit_unless(expression.filter(|e| fcx.is_assign_to_bool(e, expected)).is_some());
+ err.emit_unless(expression.filter(|e| fcx.is_assign_to_bool(e, expected))
+ .is_some());
self.final_ty = Some(fcx.tcx.types.err);
}
@@ -1278,12 +1281,12 @@ impl<'tcx, 'exprs, E: AsCoercionSite> CoerceMany<'tcx, 'exprs, E> {
cause: &ObligationCause<'tcx>,
expected: Ty<'tcx>,
found: Ty<'tcx>,
- err: TypeError<'tcx>,
+ ty_err: TypeError<'tcx>,
fcx: &FnCtxt<'a, 'tcx>,
id: hir::HirId,
expression: Option<(&'tcx hir::Expr, hir::HirId)>,
) -> DiagnosticBuilder<'a> {
- let mut db = fcx.report_mismatched_types(cause, expected, found, err);
+ let mut err = fcx.report_mismatched_types(cause, expected, found, ty_err);
let mut pointing_at_return_type = false;
let mut return_sp = None;
@@ -1294,7 +1297,7 @@ impl<'tcx, 'exprs, E: AsCoercionSite> CoerceMany<'tcx, 'exprs, E> {
let parent_id = fcx.tcx.hir().get_parent_node(id);
let fn_decl = if let Some((expr, blk_id)) = expression {
pointing_at_return_type = fcx.suggest_mismatched_types_on_tail(
- &mut db,
+ &mut err,
expr,
expected,
found,
@@ -1302,6 +1305,16 @@ impl<'tcx, 'exprs, E: AsCoercionSite> CoerceMany<'tcx, 'exprs, E> {
blk_id,
);
let parent = fcx.tcx.hir().get(parent_id);
+ if let (Some(match_expr), true, false) = (
+ fcx.tcx.hir().get_match_if_cause(expr.hir_id),
+ expected.is_unit(),
+ pointing_at_return_type,
+ ) {
+ if match_expr.span.desugaring_kind().is_none() {
+ err.span_label(match_expr.span, "expected this to be `()`");
+ fcx.suggest_semicolon_at_end(match_expr.span, &mut err);
+ }
+ }
fcx.get_node_fn_decl(parent).map(|(fn_decl, _, is_main)| (fn_decl, is_main))
} else {
fcx.get_fn_decl(parent_id)
@@ -1310,20 +1323,20 @@ impl<'tcx, 'exprs, E: AsCoercionSite> CoerceMany<'tcx, 'exprs, E> {
if let (Some((fn_decl, can_suggest)), _) = (fn_decl, pointing_at_return_type) {
if expression.is_none() {
pointing_at_return_type |= fcx.suggest_missing_return_type(
- &mut db, &fn_decl, expected, found, can_suggest);
+ &mut err, &fn_decl, expected, found, can_suggest);
}
if !pointing_at_return_type {
return_sp = Some(fn_decl.output.span()); // `impl Trait` return type
}
}
if let (Some(sp), Some(return_sp)) = (fcx.ret_coercion_span.borrow().as_ref(), return_sp) {
- db.span_label(return_sp, "expected because this return type...");
- db.span_label( *sp, format!(
+ err.span_label(return_sp, "expected because this return type...");
+ err.span_label( *sp, format!(
"...is found to be `{}` here",
fcx.resolve_type_vars_with_obligations(expected),
));
}
- db
+ err
}
pub fn complete<'a>(self, fcx: &FnCtxt<'a, 'tcx>) -> Ty<'tcx> {
diff --git a/src/librustc_typeck/check/expr.rs b/src/librustc_typeck/check/expr.rs
index 6bed321d27f82..04c8536de8dfe 100644
--- a/src/librustc_typeck/check/expr.rs
+++ b/src/librustc_typeck/check/expr.rs
@@ -53,14 +53,16 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
&self,
expr: &'tcx hir::Expr,
expected: Ty<'tcx>,
+ extend_err: impl Fn(&mut DiagnosticBuilder<'_>),
) -> Ty<'tcx> {
- self.check_expr_meets_expectation_or_error(expr, ExpectHasType(expected))
+ self.check_expr_meets_expectation_or_error(expr, ExpectHasType(expected), extend_err)
}
fn check_expr_meets_expectation_or_error(
&self,
expr: &'tcx hir::Expr,
expected: Expectation<'tcx>,
+ extend_err: impl Fn(&mut DiagnosticBuilder<'_>),
) -> Ty<'tcx> {
let expected_ty = expected.to_option(&self).unwrap_or(self.tcx.types.bool);
let mut ty = self.check_expr_with_expectation(expr, expected);
@@ -88,6 +90,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
ExprKind::DropTemps(expr) => expr,
_ => expr,
};
+ extend_err(&mut err);
// Error possibly reported in `check_assign` so avoid emitting error again.
err.emit_unless(self.is_assign_to_bool(expr, expected_ty));
}
@@ -971,7 +974,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
kind: TypeVariableOriginKind::MiscVariable,
span: element.span,
});
- let element_ty = self.check_expr_has_type_or_error(&element, ty);
+ let element_ty = self.check_expr_has_type_or_error(&element, ty, |_| {});
(element_ty, ty)
}
};
@@ -1058,7 +1061,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
// the fields with the base_expr. This could cause us to hit errors later
// when certain fields are assumed to exist that in fact do not.
if !error_happened {
- self.check_expr_has_type_or_error(base_expr, adt_ty);
+ self.check_expr_has_type_or_error(base_expr, adt_ty, |_| {});
match adt_ty.kind {
ty::Adt(adt, substs) if adt.is_struct() => {
let fru_field_types = adt.non_enum_variant().fields.iter().map(|f| {
diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs
index a7832b8c2cf17..092ab0936c0f4 100644
--- a/src/librustc_typeck/check/mod.rs
+++ b/src/librustc_typeck/check/mod.rs
@@ -3879,6 +3879,15 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
}
}
+ fn suggest_semicolon_at_end(&self, span: Span, err: &mut DiagnosticBuilder<'_>) {
+ err.span_suggestion_short(
+ span.shrink_to_hi(),
+ "consider using a semicolon here",
+ ";".to_string(),
+ Applicability::MachineApplicable,
+ );
+ }
+
pub fn check_stmt(&self, stmt: &'tcx hir::Stmt) {
// Don't do all the complex logic below for `DeclItem`.
match stmt.kind {
@@ -3902,7 +3911,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
hir::StmtKind::Item(_) => {}
hir::StmtKind::Expr(ref expr) => {
// Check with expected type of `()`.
- self.check_expr_has_type_or_error(&expr, self.tcx.mk_unit());
+
+ self.check_expr_has_type_or_error(&expr, self.tcx.mk_unit(), |err| {
+ self.suggest_semicolon_at_end(expr.span, err);
+ });
}
hir::StmtKind::Semi(ref expr) => {
self.check_expr(&expr);
diff --git a/src/librustc_typeck/error_codes.rs b/src/librustc_typeck/error_codes.rs
index e11dcfafb8f8b..3a07171b12fb8 100644
--- a/src/librustc_typeck/error_codes.rs
+++ b/src/librustc_typeck/error_codes.rs
@@ -3610,6 +3610,43 @@ match r {
```
"##,
+E0533: r##"
+An item which isn't a unit struct, a variant, nor a constant has been used as a
+match pattern.
+
+Erroneous code example:
+
+```compile_fail,E0533
+struct Tortoise;
+
+impl Tortoise {
+ fn turtle(&self) -> u32 { 0 }
+}
+
+match 0u32 {
+ Tortoise::turtle => {} // Error!
+ _ => {}
+}
+if let Tortoise::turtle = 0u32 {} // Same error!
+```
+
+If you want to match against a value returned by a method, you need to bind the
+value first:
+
+```
+struct Tortoise;
+
+impl Tortoise {
+ fn turtle(&self) -> u32 { 0 }
+}
+
+match 0u32 {
+ x if x == Tortoise.turtle() => {} // Bound into `x` then we compare it!
+ _ => {}
+}
+```
+"##,
+
E0534: r##"
The `inline` attribute was malformed.
@@ -4935,7 +4972,6 @@ and the pin is required to keep it in the same place in memory.
E0377, // the trait `CoerceUnsized` may only be implemented for a coercion
// between structures with the same definition
// E0558, // replaced with a generic attribute input check
- E0533, // `{}` does not name a unit variant, unit struct or a constant
// E0563, // cannot determine a type for this `impl Trait` removed in 6383de15
E0564, // only named lifetimes are allowed in `impl Trait`,
// but `{}` was found in the type `{}`
diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs
index f22fd5ad703d9..2fb6f197dad7c 100644
--- a/src/libsyntax/parse/parser.rs
+++ b/src/libsyntax/parse/parser.rs
@@ -974,15 +974,22 @@ impl<'a> Parser<'a> {
/// This version of parse param doesn't necessarily require identifier names.
fn parse_param_general(
&mut self,
+ is_self_allowed: bool,
is_trait_item: bool,
allow_c_variadic: bool,
is_name_required: impl Fn(&token::Token) -> bool,
) -> PResult<'a, Param> {
let lo = self.token.span;
let attrs = self.parse_outer_attributes()?;
+
+ // Possibly parse `self`. Recover if we parsed it and it wasn't allowed here.
if let Some(mut param) = self.parse_self_param()? {
param.attrs = attrs.into();
- return self.recover_bad_self_param(param, is_trait_item);
+ return if is_self_allowed {
+ Ok(param)
+ } else {
+ self.recover_bad_self_param(param, is_trait_item)
+ };
}
let is_name_required = is_name_required(&self.token);
@@ -1207,6 +1214,7 @@ impl<'a> Parser<'a> {
}
};
match p.parse_param_general(
+ false,
false,
allow_c_variadic,
do_not_enforce_named_arguments_for_c_variadic
@@ -1361,60 +1369,25 @@ impl<'a> Parser<'a> {
Ok(Some(Param::from_self(ThinVec::default(), eself, eself_ident)))
}
- /// Returns the parsed optional self parameter with attributes and whether a self
- /// shortcut was used.
- fn parse_self_parameter_with_attrs(&mut self) -> PResult<'a, Option> {
- let attrs = self.parse_outer_attributes()?;
- let param_opt = self.parse_self_param()?;
- Ok(param_opt.map(|mut param| {
- param.attrs = attrs.into();
- param
- }))
- }
-
/// Parses the parameter list and result type of a function that may have a `self` parameter.
- fn parse_fn_decl_with_self(&mut self, parse_param_fn: F) -> PResult<'a, P>
- where F: FnMut(&mut Parser<'a>) -> PResult<'a, Param>,
- {
- self.expect(&token::OpenDelim(token::Paren))?;
-
- // Parse optional self argument.
- let self_param = self.parse_self_parameter_with_attrs()?;
-
- // Parse the rest of the function parameter list.
- let sep = SeqSep::trailing_allowed(token::Comma);
- let (mut fn_inputs, recovered) = if let Some(self_param) = self_param {
- if self.check(&token::CloseDelim(token::Paren)) {
- (vec![self_param], false)
- } else if self.eat(&token::Comma) {
- let mut fn_inputs = vec![self_param];
- let (mut input, _, recovered) = self.parse_seq_to_before_end(
- &token::CloseDelim(token::Paren), sep, parse_param_fn)?;
- fn_inputs.append(&mut input);
- (fn_inputs, recovered)
- } else {
- match self.expect_one_of(&[], &[]) {
- Err(err) => return Err(err),
- Ok(recovered) => (vec![self_param], recovered),
- }
- }
- } else {
- let (input, _, recovered) =
- self.parse_seq_to_before_end(&token::CloseDelim(token::Paren),
- sep,
- parse_param_fn)?;
- (input, recovered)
- };
+ fn parse_fn_decl_with_self(
+ &mut self,
+ is_name_required: impl Copy + Fn(&token::Token) -> bool,
+ ) -> PResult<'a, P> {
+ // Parse the arguments, starting out with `self` being allowed...
+ let mut is_self_allowed = true;
+ let (mut inputs, _): (Vec<_>, _) = self.parse_paren_comma_seq(|p| {
+ let res = p.parse_param_general(is_self_allowed, true, false, is_name_required);
+ // ...but now that we've parsed the first argument, `self` is no longer allowed.
+ is_self_allowed = false;
+ res
+ })?;
- if !recovered {
- // Parse closing paren and return type.
- self.expect(&token::CloseDelim(token::Paren))?;
- }
// Replace duplicated recovered params with `_` pattern to avoid unecessary errors.
- self.deduplicate_recovered_params_names(&mut fn_inputs);
+ self.deduplicate_recovered_params_names(&mut inputs);
Ok(P(FnDecl {
- inputs: fn_inputs,
+ inputs,
output: self.parse_ret_ty(true)?,
}))
}
diff --git a/src/libsyntax/parse/parser/item.rs b/src/libsyntax/parse/parser/item.rs
index 92b19b73e5719..64c494416ff34 100644
--- a/src/libsyntax/parse/parser/item.rs
+++ b/src/libsyntax/parse/parser/item.rs
@@ -424,13 +424,7 @@ impl<'a> Parser<'a> {
} else if self.look_ahead(1, |t| *t == token::OpenDelim(token::Paren)) {
let ident = self.parse_ident().unwrap();
self.bump(); // `(`
- let kw_name = if let Ok(Some(_)) = self.parse_self_parameter_with_attrs()
- .map_err(|mut e| e.cancel())
- {
- "method"
- } else {
- "function"
- };
+ let kw_name = self.recover_first_param();
self.consume_block(token::Paren);
let (kw, kw_name, ambiguous) = if self.check(&token::RArrow) {
self.eat_to_tokens(&[&token::OpenDelim(token::Brace)]);
@@ -477,13 +471,7 @@ impl<'a> Parser<'a> {
self.eat_to_tokens(&[&token::Gt]);
self.bump(); // `>`
let (kw, kw_name, ambiguous) = if self.eat(&token::OpenDelim(token::Paren)) {
- if let Ok(Some(_)) = self.parse_self_parameter_with_attrs()
- .map_err(|mut e| e.cancel())
- {
- ("fn", "method", false)
- } else {
- ("fn", "function", false)
- }
+ ("fn", self.recover_first_param(), false)
} else if self.check(&token::OpenDelim(token::Brace)) {
("struct", "struct", false)
} else {
@@ -505,6 +493,16 @@ impl<'a> Parser<'a> {
self.parse_macro_use_or_failure(attrs, macros_allowed, attributes_allowed, lo, visibility)
}
+ fn recover_first_param(&mut self) -> &'static str {
+ match self.parse_outer_attributes()
+ .and_then(|_| self.parse_self_param())
+ .map_err(|mut e| e.cancel())
+ {
+ Ok(Some(_)) => "method",
+ _ => "function",
+ }
+ }
+
/// This is the fall-through for parsing items.
fn parse_macro_use_or_failure(
&mut self,
@@ -861,9 +859,7 @@ impl<'a> Parser<'a> {
let (constness, unsafety, asyncness, abi) = self.parse_fn_front_matter()?;
let ident = self.parse_ident()?;
let mut generics = self.parse_generics()?;
- let decl = self.parse_fn_decl_with_self(|p| {
- p.parse_param_general(true, false, |_| true)
- })?;
+ let decl = self.parse_fn_decl_with_self(|_| true)?;
generics.where_clause = self.parse_where_clause()?;
*at_end = true;
let (inner_attrs, body) = self.parse_inner_attrs_and_block()?;
@@ -1034,15 +1030,11 @@ impl<'a> Parser<'a> {
let ident = self.parse_ident()?;
let mut generics = self.parse_generics()?;
- let decl = self.parse_fn_decl_with_self(|p: &mut Parser<'a>| {
- // This is somewhat dubious; We don't want to allow
- // argument names to be left off if there is a
- // definition...
-
- // We don't allow argument names to be left off in edition 2018.
- let is_name_required = p.token.span.rust_2018();
- p.parse_param_general(true, false, |_| is_name_required)
- })?;
+ // This is somewhat dubious; We don't want to allow
+ // argument names to be left off if there is a definition...
+ //
+ // We don't allow argument names to be left off in edition 2018.
+ let decl = self.parse_fn_decl_with_self(|t| t.span.rust_2018())?;
generics.where_clause = self.parse_where_clause()?;
let sig = ast::MethodSig {
diff --git a/src/test/ui/const-generics/slice-const-param-mismatch.rs b/src/test/ui/const-generics/slice-const-param-mismatch.rs
new file mode 100644
index 0000000000000..73c75ae666805
--- /dev/null
+++ b/src/test/ui/const-generics/slice-const-param-mismatch.rs
@@ -0,0 +1,14 @@
+#![feature(const_generics)]
+//~^ WARN the feature `const_generics` is incomplete and may cause the compiler to crash
+
+struct ConstString;
+struct ConstBytes;
+
+pub fn main() {
+ let _: ConstString<"Hello"> = ConstString::<"Hello">;
+ let _: ConstString<"Hello"> = ConstString::<"World">; //~ ERROR mismatched types
+ let _: ConstString<"ℇ㇈↦"> = ConstString::<"ℇ㇈↦">;
+ let _: ConstString<"ℇ㇈↦"> = ConstString::<"ℇ㇈↥">; //~ ERROR mismatched types
+ let _: ConstBytes = ConstBytes::<{&[0x41, 0x41, 0x41]}>;
+ let _: ConstBytes = ConstBytes::; //~ ERROR mismatched types
+}
diff --git a/src/test/ui/const-generics/slice-const-param-mismatch.stderr b/src/test/ui/const-generics/slice-const-param-mismatch.stderr
new file mode 100644
index 0000000000000..72369ab24ebfc
--- /dev/null
+++ b/src/test/ui/const-generics/slice-const-param-mismatch.stderr
@@ -0,0 +1,38 @@
+warning: the feature `const_generics` is incomplete and may cause the compiler to crash
+ --> $DIR/slice-const-param-mismatch.rs:1:12
+ |
+LL | #![feature(const_generics)]
+ | ^^^^^^^^^^^^^^
+ |
+ = note: `#[warn(incomplete_features)]` on by default
+
+error[E0308]: mismatched types
+ --> $DIR/slice-const-param-mismatch.rs:9:35
+ |
+LL | let _: ConstString<"Hello"> = ConstString::<"World">;
+ | ^^^^^^^^^^^^^^^^^^^^^^ expected `"Hello"`, found `"World"`
+ |
+ = note: expected type `ConstString<>`
+ found type `ConstString<>`
+
+error[E0308]: mismatched types
+ --> $DIR/slice-const-param-mismatch.rs:11:33
+ |
+LL | let _: ConstString<"ℇ㇈↦"> = ConstString::<"ℇ㇈↥">;
+ | ^^^^^^^^^^^^^^^^^^^^^ expected `"ℇ㇈↦"`, found `"ℇ㇈↥"`
+ |
+ = note: expected type `ConstString<>`
+ found type `ConstString<>`
+
+error[E0308]: mismatched types
+ --> $DIR/slice-const-param-mismatch.rs:13:33
+ |
+LL | let _: ConstBytes = ConstBytes::;
+ | ^^^^^^^^^^^^^^^^^^^^ expected `b"AAA"`, found `b"BBB"`
+ |
+ = note: expected type `ConstBytes<>`
+ found type `ConstBytes<>`
+
+error: aborting due to 3 previous errors
+
+For more information about this error, try `rustc --explain E0308`.
diff --git a/src/test/ui/const-generics/slice-const-param.rs b/src/test/ui/const-generics/slice-const-param.rs
new file mode 100644
index 0000000000000..2629caa392106
--- /dev/null
+++ b/src/test/ui/const-generics/slice-const-param.rs
@@ -0,0 +1,19 @@
+// run-pass
+
+#![feature(const_generics)]
+//~^ WARN the feature `const_generics` is incomplete and may cause the compiler to crash
+
+pub fn function_with_str() -> &'static str {
+ STRING
+}
+
+pub fn function_with_bytes() -> &'static [u8] {
+ BYTES
+}
+
+pub fn main() {
+ assert_eq!(function_with_str::<"Rust">(), "Rust");
+ assert_eq!(function_with_str::<"ℇ㇈↦">(), "ℇ㇈↦");
+ assert_eq!(function_with_bytes::(), &[0x41, 0x41, 0x41, 0x41]);
+ assert_eq!(function_with_bytes::<{&[0x41, 0x41, 0x41, 0x41]}>(), b"AAAA");
+}
diff --git a/src/test/ui/const-generics/slice-const-param.stderr b/src/test/ui/const-generics/slice-const-param.stderr
new file mode 100644
index 0000000000000..79214a34fdba0
--- /dev/null
+++ b/src/test/ui/const-generics/slice-const-param.stderr
@@ -0,0 +1,8 @@
+warning: the feature `const_generics` is incomplete and may cause the compiler to crash
+ --> $DIR/slice-const-param.rs:3:12
+ |
+LL | #![feature(const_generics)]
+ | ^^^^^^^^^^^^^^
+ |
+ = note: `#[warn(incomplete_features)]` on by default
+
diff --git a/src/test/ui/empty/empty-struct-braces-expr.stderr b/src/test/ui/empty/empty-struct-braces-expr.stderr
index b9681db87b67e..9712157552716 100644
--- a/src/test/ui/empty/empty-struct-braces-expr.stderr
+++ b/src/test/ui/empty/empty-struct-braces-expr.stderr
@@ -1,6 +1,9 @@
error[E0423]: expected value, found struct `Empty1`
--> $DIR/empty-struct-braces-expr.rs:15:14
|
+LL | struct Empty1 {}
+ | ---------------- `Empty1` defined here
+...
LL | let e1 = Empty1;
| ^^^^^^
| |
@@ -10,6 +13,9 @@ LL | let e1 = Empty1;
error[E0423]: expected function, found struct `Empty1`
--> $DIR/empty-struct-braces-expr.rs:16:14
|
+LL | struct Empty1 {}
+ | ---------------- `Empty1` defined here
+...
LL | let e1 = Empty1();
| ^^^^^^
| |
@@ -19,12 +25,18 @@ LL | let e1 = Empty1();
error[E0423]: expected value, found struct variant `E::Empty3`
--> $DIR/empty-struct-braces-expr.rs:17:14
|
+LL | Empty3 {}
+ | --------- `E::Empty3` defined here
+...
LL | let e3 = E::Empty3;
| ^^^^^^^^^ did you mean `E::Empty3 { /* fields */ }`?
error[E0423]: expected function, found struct variant `E::Empty3`
--> $DIR/empty-struct-braces-expr.rs:18:14
|
+LL | Empty3 {}
+ | --------- `E::Empty3` defined here
+...
LL | let e3 = E::Empty3();
| ^^^^^^^^^ did you mean `E::Empty3 { /* fields */ }`?
diff --git a/src/test/ui/empty/empty-struct-braces-pat-1.stderr b/src/test/ui/empty/empty-struct-braces-pat-1.stderr
index 6c361c703440c..271e811a2fd65 100644
--- a/src/test/ui/empty/empty-struct-braces-pat-1.stderr
+++ b/src/test/ui/empty/empty-struct-braces-pat-1.stderr
@@ -1,6 +1,9 @@
error[E0532]: expected unit struct/variant or constant, found struct variant `E::Empty3`
--> $DIR/empty-struct-braces-pat-1.rs:24:9
|
+LL | Empty3 {}
+ | --------- `E::Empty3` defined here
+...
LL | E::Empty3 => ()
| ^^^^^^^^^ did you mean `E::Empty3 { /* fields */ }`?
diff --git a/src/test/ui/empty/empty-struct-braces-pat-2.stderr b/src/test/ui/empty/empty-struct-braces-pat-2.stderr
index 12047b5880c3e..3352473788894 100644
--- a/src/test/ui/empty/empty-struct-braces-pat-2.stderr
+++ b/src/test/ui/empty/empty-struct-braces-pat-2.stderr
@@ -1,6 +1,9 @@
error[E0532]: expected tuple struct/variant, found struct `Empty1`
--> $DIR/empty-struct-braces-pat-2.rs:15:9
|
+LL | struct Empty1 {}
+ | ---------------- `Empty1` defined here
+...
LL | Empty1() => ()
| ^^^^^^
| |
@@ -19,6 +22,9 @@ LL | XEmpty1() => ()
error[E0532]: expected tuple struct/variant, found struct `Empty1`
--> $DIR/empty-struct-braces-pat-2.rs:21:9
|
+LL | struct Empty1 {}
+ | ---------------- `Empty1` defined here
+...
LL | Empty1(..) => ()
| ^^^^^^
| |
diff --git a/src/test/ui/empty/empty-struct-braces-pat-3.stderr b/src/test/ui/empty/empty-struct-braces-pat-3.stderr
index af8731b5f0596..aefdd772b1bfd 100644
--- a/src/test/ui/empty/empty-struct-braces-pat-3.stderr
+++ b/src/test/ui/empty/empty-struct-braces-pat-3.stderr
@@ -1,6 +1,9 @@
error[E0532]: expected tuple struct/variant, found struct variant `E::Empty3`
--> $DIR/empty-struct-braces-pat-3.rs:17:9
|
+LL | Empty3 {}
+ | --------- `E::Empty3` defined here
+...
LL | E::Empty3() => ()
| ^^^^^^^^^ did you mean `E::Empty3 { /* fields */ }`?
@@ -16,6 +19,9 @@ LL | XE::XEmpty3() => ()
error[E0532]: expected tuple struct/variant, found struct variant `E::Empty3`
--> $DIR/empty-struct-braces-pat-3.rs:25:9
|
+LL | Empty3 {}
+ | --------- `E::Empty3` defined here
+...
LL | E::Empty3(..) => ()
| ^^^^^^^^^ did you mean `E::Empty3 { /* fields */ }`?
diff --git a/src/test/ui/empty/empty-struct-tuple-pat.stderr b/src/test/ui/empty/empty-struct-tuple-pat.stderr
index 6c15e7bf282ce..4b828c0d942e3 100644
--- a/src/test/ui/empty/empty-struct-tuple-pat.stderr
+++ b/src/test/ui/empty/empty-struct-tuple-pat.stderr
@@ -19,8 +19,11 @@ LL | XEmpty6 => ()
error[E0532]: expected unit struct/variant or constant, found tuple variant `E::Empty4`
--> $DIR/empty-struct-tuple-pat.rs:29:9
|
+LL | Empty4()
+ | -------- `E::Empty4` defined here
+...
LL | E::Empty4 => ()
- | ^^^^^^^^^ did you mean `E::Empty4 ( /* fields */ )`?
+ | ^^^^^^^^^ did you mean `E::Empty4( /* fields */ )`?
error[E0532]: expected unit struct/variant or constant, found tuple variant `XE::XEmpty5`
--> $DIR/empty-struct-tuple-pat.rs:33:9
@@ -29,7 +32,7 @@ LL | XE::XEmpty5 => (),
| ^^^^-------
| | |
| | help: a unit variant with a similar name exists: `XEmpty4`
- | did you mean `XE::XEmpty5 ( /* fields */ )`?
+ | did you mean `XE::XEmpty5( /* fields */ )`?
error: aborting due to 4 previous errors
diff --git a/src/test/ui/error-codes/E0423.stderr b/src/test/ui/error-codes/E0423.stderr
index ec240003f9182..ce631ca4bf786 100644
--- a/src/test/ui/error-codes/E0423.stderr
+++ b/src/test/ui/error-codes/E0423.stderr
@@ -27,6 +27,9 @@ LL | for _ in (std::ops::Range { start: 0, end: 10 }) {}
error[E0423]: expected function, found struct `Foo`
--> $DIR/E0423.rs:4:13
|
+LL | struct Foo { a: bool };
+ | ---------------------- `Foo` defined here
+LL |
LL | let f = Foo();
| ^^^
| |
diff --git a/src/test/ui/issues/issue-19086.stderr b/src/test/ui/issues/issue-19086.stderr
index d2b9b90890e3c..e2229cbc20922 100644
--- a/src/test/ui/issues/issue-19086.stderr
+++ b/src/test/ui/issues/issue-19086.stderr
@@ -1,6 +1,9 @@
error[E0532]: expected tuple struct/variant, found struct variant `FooB`
--> $DIR/issue-19086.rs:10:9
|
+LL | FooB { x: i32, y: i32 }
+ | ----------------------- `FooB` defined here
+...
LL | FooB(a, b) => println!("{} {}", a, b),
| ^^^^ did you mean `FooB { /* fields */ }`?
diff --git a/src/test/ui/issues/issue-32004.stderr b/src/test/ui/issues/issue-32004.stderr
index b56fa949acb7e..e9a5e217392a6 100644
--- a/src/test/ui/issues/issue-32004.stderr
+++ b/src/test/ui/issues/issue-32004.stderr
@@ -1,11 +1,14 @@
error[E0532]: expected unit struct/variant or constant, found tuple variant `Foo::Bar`
--> $DIR/issue-32004.rs:10:9
|
+LL | Bar(i32),
+ | -------- `Foo::Bar` defined here
+...
LL | Foo::Bar => {}
| ^^^^^---
| | |
| | help: a unit variant with a similar name exists: `Baz`
- | did you mean `Foo::Bar ( /* fields */ )`?
+ | did you mean `Foo::Bar( /* fields */ )`?
error[E0532]: expected tuple struct/variant, found unit struct `S`
--> $DIR/issue-32004.rs:16:9
diff --git a/src/test/ui/issues/issue-63983.stderr b/src/test/ui/issues/issue-63983.stderr
index 67acd1d57c27a..8949c475b6f72 100644
--- a/src/test/ui/issues/issue-63983.stderr
+++ b/src/test/ui/issues/issue-63983.stderr
@@ -1,12 +1,18 @@
error[E0532]: expected unit struct/variant or constant, found tuple variant `MyEnum::Tuple`
--> $DIR/issue-63983.rs:8:9
|
+LL | Tuple(i32),
+ | ---------- `MyEnum::Tuple` defined here
+...
LL | MyEnum::Tuple => "",
- | ^^^^^^^^^^^^^ did you mean `MyEnum::Tuple ( /* fields */ )`?
+ | ^^^^^^^^^^^^^ did you mean `MyEnum::Tuple( /* fields */ )`?
error[E0532]: expected unit struct/variant or constant, found struct variant `MyEnum::Struct`
--> $DIR/issue-63983.rs:10:9
|
+LL | Struct{ s: i32 },
+ | ---------------- `MyEnum::Struct` defined here
+...
LL | MyEnum::Struct => "",
| ^^^^^^^^^^^^^^ did you mean `MyEnum::Struct { /* fields */ }`?
diff --git a/src/test/ui/lint/lint-unused-variables.rs b/src/test/ui/lint/lint-unused-variables.rs
index 1a6b5183f0fae..6850e999242ea 100644
--- a/src/test/ui/lint/lint-unused-variables.rs
+++ b/src/test/ui/lint/lint-unused-variables.rs
@@ -29,6 +29,11 @@ impl RefStruct {
b: i32,
//~^ ERROR unused variable: `b`
) {}
+ fn issue_64682_associated_fn(
+ #[allow(unused_variables)] a: i32,
+ b: i32,
+ //~^ ERROR unused variable: `b`
+ ) {}
}
trait RefTrait {
fn bar(
@@ -37,6 +42,11 @@ trait RefTrait {
b: i32,
//~^ ERROR unused variable: `b`
) {}
+ fn issue_64682_associated_fn(
+ #[allow(unused_variables)] a: i32,
+ b: i32,
+ //~^ ERROR unused variable: `b`
+ ) {}
}
impl RefTrait for RefStruct {
fn bar(
@@ -45,6 +55,11 @@ impl RefTrait for RefStruct {
b: i32,
//~^ ERROR unused variable: `b`
) {}
+ fn issue_64682_associated_fn(
+ #[allow(unused_variables)] a: i32,
+ b: i32,
+ //~^ ERROR unused variable: `b`
+ ) {}
}
fn main() {
diff --git a/src/test/ui/lint/lint-unused-variables.stderr b/src/test/ui/lint/lint-unused-variables.stderr
index 7ed5669e33c24..f8419bf506660 100644
--- a/src/test/ui/lint/lint-unused-variables.stderr
+++ b/src/test/ui/lint/lint-unused-variables.stderr
@@ -17,19 +17,25 @@ LL | b: i32,
| ^ help: consider prefixing with an underscore: `_b`
error: unused variable: `a`
- --> $DIR/lint-unused-variables.rs:53:9
+ --> $DIR/lint-unused-variables.rs:68:9
|
LL | a: i32,
| ^ help: consider prefixing with an underscore: `_a`
error: unused variable: `b`
- --> $DIR/lint-unused-variables.rs:59:9
+ --> $DIR/lint-unused-variables.rs:74:9
|
LL | b: i32,
| ^ help: consider prefixing with an underscore: `_b`
error: unused variable: `b`
- --> $DIR/lint-unused-variables.rs:37:9
+ --> $DIR/lint-unused-variables.rs:42:9
+ |
+LL | b: i32,
+ | ^ help: consider prefixing with an underscore: `_b`
+
+error: unused variable: `b`
+ --> $DIR/lint-unused-variables.rs:47:9
|
LL | b: i32,
| ^ help: consider prefixing with an underscore: `_b`
@@ -47,10 +53,22 @@ LL | b: i32,
| ^ help: consider prefixing with an underscore: `_b`
error: unused variable: `b`
- --> $DIR/lint-unused-variables.rs:45:9
+ --> $DIR/lint-unused-variables.rs:34:9
+ |
+LL | b: i32,
+ | ^ help: consider prefixing with an underscore: `_b`
+
+error: unused variable: `b`
+ --> $DIR/lint-unused-variables.rs:55:9
+ |
+LL | b: i32,
+ | ^ help: consider prefixing with an underscore: `_b`
+
+error: unused variable: `b`
+ --> $DIR/lint-unused-variables.rs:60:9
|
LL | b: i32,
| ^ help: consider prefixing with an underscore: `_b`
-error: aborting due to 8 previous errors
+error: aborting due to 11 previous errors
diff --git a/src/test/ui/methods/method-path-in-pattern.rs b/src/test/ui/methods/method-path-in-pattern.rs
index fb1cf7f71e70a..21a91f3f32b24 100644
--- a/src/test/ui/methods/method-path-in-pattern.rs
+++ b/src/test/ui/methods/method-path-in-pattern.rs
@@ -23,4 +23,10 @@ fn main() {
::trait_bar => {}
//~^ ERROR expected unit struct/variant or constant, found method `::trait_bar`
}
+ if let Foo::bar = 0u32 {}
+ //~^ ERROR expected unit struct/variant or constant, found method `::bar`
+ if let ::bar = 0u32 {}
+ //~^ ERROR expected unit struct/variant or constant, found method `::bar`
+ if let Foo::trait_bar = 0u32 {}
+ //~^ ERROR expected unit struct/variant or constant, found method `::trait_bar`
}
diff --git a/src/test/ui/methods/method-path-in-pattern.stderr b/src/test/ui/methods/method-path-in-pattern.stderr
index 3f53ad768825b..257fff4c37dc0 100644
--- a/src/test/ui/methods/method-path-in-pattern.stderr
+++ b/src/test/ui/methods/method-path-in-pattern.stderr
@@ -16,5 +16,24 @@ error[E0533]: expected unit struct/variant or constant, found method `::tra
LL | ::trait_bar => {}
| ^^^^^^^^^^^^^^^^
-error: aborting due to 3 previous errors
+error[E0533]: expected unit struct/variant or constant, found method `::bar`
+ --> $DIR/method-path-in-pattern.rs:26:12
+ |
+LL | if let Foo::bar = 0u32 {}
+ | ^^^^^^^^
+
+error[E0533]: expected unit struct/variant or constant, found method `::bar`
+ --> $DIR/method-path-in-pattern.rs:28:12
+ |
+LL | if let ::bar = 0u32 {}
+ | ^^^^^^^^^^
+
+error[E0533]: expected unit struct/variant or constant, found method `::trait_bar`
+ --> $DIR/method-path-in-pattern.rs:30:12
+ |
+LL | if let Foo::trait_bar = 0u32 {}
+ | ^^^^^^^^^^^^^^
+
+error: aborting due to 6 previous errors
+For more information about this error, try `rustc --explain E0533`.
diff --git a/src/test/ui/namespace/namespace-mix.stderr b/src/test/ui/namespace/namespace-mix.stderr
index aa21928aaeff2..77da07f40d536 100644
--- a/src/test/ui/namespace/namespace-mix.stderr
+++ b/src/test/ui/namespace/namespace-mix.stderr
@@ -37,6 +37,9 @@ LL | use namespace_mix::xm2::S;
error[E0423]: expected value, found struct variant `m7::V`
--> $DIR/namespace-mix.rs:100:11
|
+LL | V {},
+ | ---- `m7::V` defined here
+...
LL | check(m7::V);
| ^^^^^ did you mean `m7::V { /* fields */ }`?
help: a tuple variant with a similar name exists
diff --git a/src/test/ui/parser/recover-from-bad-variant.stderr b/src/test/ui/parser/recover-from-bad-variant.stderr
index b46d3ca9c233c..32bb88d31c4c7 100644
--- a/src/test/ui/parser/recover-from-bad-variant.stderr
+++ b/src/test/ui/parser/recover-from-bad-variant.stderr
@@ -12,6 +12,9 @@ LL | let x = Enum::Foo(a: 3, b: 4);
error[E0532]: expected tuple struct/variant, found struct variant `Enum::Foo`
--> $DIR/recover-from-bad-variant.rs:10:9
|
+LL | Foo { a: usize, b: usize },
+ | -------------------------- `Enum::Foo` defined here
+...
LL | Enum::Foo(a, b) => {}
| ^^^^^^^^^ did you mean `Enum::Foo { /* fields */ }`?
diff --git a/src/test/ui/qualified/qualified-path-params.stderr b/src/test/ui/qualified/qualified-path-params.stderr
index b8d3b744e837c..3e8fcdc7ca3e2 100644
--- a/src/test/ui/qualified/qualified-path-params.stderr
+++ b/src/test/ui/qualified/qualified-path-params.stderr
@@ -15,4 +15,5 @@ LL | 0 ..= ::A::f:: => {}
error: aborting due to 2 previous errors
-For more information about this error, try `rustc --explain E0029`.
+Some errors have detailed explanations: E0029, E0533.
+For more information about an error, try `rustc --explain E0029`.
diff --git a/src/test/ui/resolve/issue-18252.stderr b/src/test/ui/resolve/issue-18252.stderr
index 293f290f82fd9..c76e5ef8b3617 100644
--- a/src/test/ui/resolve/issue-18252.stderr
+++ b/src/test/ui/resolve/issue-18252.stderr
@@ -1,6 +1,9 @@
error[E0423]: expected function, found struct variant `Foo::Variant`
--> $DIR/issue-18252.rs:6:13
|
+LL | Variant { x: usize }
+ | -------------------- `Foo::Variant` defined here
+...
LL | let f = Foo::Variant(42);
| ^^^^^^^^^^^^ did you mean `Foo::Variant { /* fields */ }`?
diff --git a/src/test/ui/resolve/issue-19452.stderr b/src/test/ui/resolve/issue-19452.stderr
index 56a0e397b854c..4d20f1580264c 100644
--- a/src/test/ui/resolve/issue-19452.stderr
+++ b/src/test/ui/resolve/issue-19452.stderr
@@ -1,6 +1,9 @@
error[E0423]: expected value, found struct variant `Homura::Madoka`
--> $DIR/issue-19452.rs:10:18
|
+LL | Madoka { age: u32 }
+ | ------------------- `Homura::Madoka` defined here
+...
LL | let homura = Homura::Madoka;
| ^^^^^^^^^^^^^^ did you mean `Homura::Madoka { /* fields */ }`?
diff --git a/src/test/ui/resolve/issue-39226.stderr b/src/test/ui/resolve/issue-39226.stderr
index c97fb4db6be6b..d9a28e63dce8b 100644
--- a/src/test/ui/resolve/issue-39226.stderr
+++ b/src/test/ui/resolve/issue-39226.stderr
@@ -1,6 +1,9 @@
error[E0423]: expected value, found struct `Handle`
--> $DIR/issue-39226.rs:11:17
|
+LL | struct Handle {}
+ | ---------------- `Handle` defined here
+...
LL | handle: Handle
| ^^^^^^
| |
diff --git a/src/test/ui/resolve/issue-6702.stderr b/src/test/ui/resolve/issue-6702.stderr
index 9a46f0d774262..3fdc7acb274e5 100644
--- a/src/test/ui/resolve/issue-6702.stderr
+++ b/src/test/ui/resolve/issue-6702.stderr
@@ -1,8 +1,13 @@
error[E0423]: expected function, found struct `Monster`
--> $DIR/issue-6702.rs:7:14
|
-LL | let _m = Monster();
- | ^^^^^^^ did you mean `Monster { /* fields */ }`?
+LL | / struct Monster {
+LL | | damage: isize
+LL | | }
+ | |_- `Monster` defined here
+...
+LL | let _m = Monster();
+ | ^^^^^^^ did you mean `Monster { /* fields */ }`?
error: aborting due to previous error
diff --git a/src/test/ui/resolve/privacy-enum-ctor.stderr b/src/test/ui/resolve/privacy-enum-ctor.stderr
index 2538bbbf8067f..7d8d1d0abfc21 100644
--- a/src/test/ui/resolve/privacy-enum-ctor.stderr
+++ b/src/test/ui/resolve/privacy-enum-ctor.stderr
@@ -33,8 +33,13 @@ LL | m::Z::Unit;
error[E0423]: expected value, found struct variant `Z::Struct`
--> $DIR/privacy-enum-ctor.rs:29:20
|
-LL | let _: Z = Z::Struct;
- | ^^^^^^^^^ did you mean `Z::Struct { /* fields */ }`?
+LL | / Struct {
+LL | | s: u8,
+LL | | },
+ | |_____________- `Z::Struct` defined here
+...
+LL | let _: Z = Z::Struct;
+ | ^^^^^^^^^ did you mean `Z::Struct { /* fields */ }`?
error[E0423]: expected value, found enum `m::E`
--> $DIR/privacy-enum-ctor.rs:41:16
@@ -63,8 +68,13 @@ LL | use std::f64::consts::E;
error[E0423]: expected value, found struct variant `m::E::Struct`
--> $DIR/privacy-enum-ctor.rs:45:16
|
-LL | let _: E = m::E::Struct;
- | ^^^^^^^^^^^^ did you mean `m::E::Struct { /* fields */ }`?
+LL | / Struct {
+LL | | s: u8,
+LL | | },
+ | |_________- `m::E::Struct` defined here
+...
+LL | let _: E = m::E::Struct;
+ | ^^^^^^^^^^^^ did you mean `m::E::Struct { /* fields */ }`?
error[E0423]: expected value, found enum `E`
--> $DIR/privacy-enum-ctor.rs:49:16
@@ -89,8 +99,13 @@ LL | use std::f64::consts::E;
error[E0423]: expected value, found struct variant `E::Struct`
--> $DIR/privacy-enum-ctor.rs:53:16
|
-LL | let _: E = E::Struct;
- | ^^^^^^^^^ did you mean `E::Struct { /* fields */ }`?
+LL | / Struct {
+LL | | s: u8,
+LL | | },
+ | |_________- `E::Struct` defined here
+...
+LL | let _: E = E::Struct;
+ | ^^^^^^^^^ did you mean `E::Struct { /* fields */ }`?
error[E0412]: cannot find type `Z` in this scope
--> $DIR/privacy-enum-ctor.rs:57:12
@@ -151,8 +166,13 @@ LL | use m::n::Z;
error[E0423]: expected value, found struct variant `m::n::Z::Struct`
--> $DIR/privacy-enum-ctor.rs:64:16
|
-LL | let _: Z = m::n::Z::Struct;
- | ^^^^^^^^^^^^^^^ did you mean `m::n::Z::Struct { /* fields */ }`?
+LL | / Struct {
+LL | | s: u8,
+LL | | },
+ | |_____________- `m::n::Z::Struct` defined here
+...
+LL | let _: Z = m::n::Z::Struct;
+ | ^^^^^^^^^^^^^^^ did you mean `m::n::Z::Struct { /* fields */ }`?
error[E0412]: cannot find type `Z` in this scope
--> $DIR/privacy-enum-ctor.rs:68:12
diff --git a/src/test/ui/resolve/privacy-struct-ctor.stderr b/src/test/ui/resolve/privacy-struct-ctor.stderr
index 72d62fe45ce74..979367bc623fd 100644
--- a/src/test/ui/resolve/privacy-struct-ctor.stderr
+++ b/src/test/ui/resolve/privacy-struct-ctor.stderr
@@ -16,8 +16,13 @@ LL | S;
error[E0423]: expected value, found struct `S2`
--> $DIR/privacy-struct-ctor.rs:38:5
|
-LL | S2;
- | ^^ did you mean `S2 { /* fields */ }`?
+LL | / pub struct S2 {
+LL | | s: u8
+LL | | }
+ | |_____- `S2` defined here
+...
+LL | S2;
+ | ^^ did you mean `S2 { /* fields */ }`?
error[E0423]: expected value, found struct `xcrate::S`
--> $DIR/privacy-struct-ctor.rs:43:5
diff --git a/src/test/ui/rfc-2565-param-attrs/attr-without-param.rs b/src/test/ui/rfc-2565-param-attrs/attr-without-param.rs
new file mode 100644
index 0000000000000..eeb2191bab462
--- /dev/null
+++ b/src/test/ui/rfc-2565-param-attrs/attr-without-param.rs
@@ -0,0 +1,16 @@
+#[cfg(FALSE)]
+impl S {
+ fn f(#[attr]) {} //~ ERROR expected parameter name, found `)`
+}
+
+#[cfg(FALSE)]
+impl T for S {
+ fn f(#[attr]) {} //~ ERROR expected parameter name, found `)`
+}
+
+#[cfg(FALSE)]
+trait T {
+ fn f(#[attr]); //~ ERROR expected argument name, found `)`
+}
+
+fn main() {}
diff --git a/src/test/ui/rfc-2565-param-attrs/attr-without-param.stderr b/src/test/ui/rfc-2565-param-attrs/attr-without-param.stderr
new file mode 100644
index 0000000000000..26dff4d4b30bf
--- /dev/null
+++ b/src/test/ui/rfc-2565-param-attrs/attr-without-param.stderr
@@ -0,0 +1,20 @@
+error: expected parameter name, found `)`
+ --> $DIR/attr-without-param.rs:3:17
+ |
+LL | fn f(#[attr]) {}
+ | ^ expected parameter name
+
+error: expected parameter name, found `)`
+ --> $DIR/attr-without-param.rs:8:17
+ |
+LL | fn f(#[attr]) {}
+ | ^ expected parameter name
+
+error: expected argument name, found `)`
+ --> $DIR/attr-without-param.rs:13:17
+ |
+LL | fn f(#[attr]);
+ | ^ expected argument name
+
+error: aborting due to 3 previous errors
+
diff --git a/src/test/ui/rfc-2565-param-attrs/auxiliary/param-attrs.rs b/src/test/ui/rfc-2565-param-attrs/auxiliary/param-attrs.rs
index 71815e3c08974..c537c1034b5a6 100644
--- a/src/test/ui/rfc-2565-param-attrs/auxiliary/param-attrs.rs
+++ b/src/test/ui/rfc-2565-param-attrs/auxiliary/param-attrs.rs
@@ -11,7 +11,6 @@ macro_rules! checker {
($attr_name:ident, $expected:literal) => {
#[proc_macro_attribute]
pub fn $attr_name(attr: TokenStream, input: TokenStream) -> TokenStream {
- assert!(attr.to_string().is_empty());
assert_eq!(input.to_string(), $expected);
TokenStream::new()
}
@@ -28,7 +27,18 @@ checker!(attr_inherent_1, "fn inherent1(#[a1] self, #[a2] arg1: u8) { }");
checker!(attr_inherent_2, "fn inherent2(#[a1] &self, #[a2] arg1: u8) { }");
checker!(attr_inherent_3, "fn inherent3<'a>(#[a1] &'a mut self, #[a2] arg1: u8) { }");
checker!(attr_inherent_4, "fn inherent4<'a>(#[a1] self: Box, #[a2] arg1: u8) { }");
+checker!(attr_inherent_issue_64682, "fn inherent5(#[a1] #[a2] arg1: u8, #[a3] arg2: u8) { }");
checker!(attr_trait_1, "fn trait1(#[a1] self, #[a2] arg1: u8);");
checker!(attr_trait_2, "fn trait2(#[a1] &self, #[a2] arg1: u8);");
checker!(attr_trait_3, "fn trait3<'a>(#[a1] &'a mut self, #[a2] arg1: u8);");
checker!(attr_trait_4, "fn trait4<'a>(#[a1] self: Box, #[a2] arg1: u8, #[a3] Vec);");
+checker!(attr_trait_issue_64682, "fn trait5(#[a1] #[a2] arg1: u8, #[a3] arg2: u8);");
+checker!(rename_params, r#"impl Foo {
+ fn hello(#[angery(true)] a: i32, #[a2] b: i32, #[what = "how"] c: u32) { }
+ fn hello2(#[a1] #[a2] a: i32, #[what = "how"] b: i32,
+ #[angery(true)] c: u32) {
+ }
+ fn hello_self(#[a1] #[a2] &self, #[a1] #[a2] a: i32,
+ #[what = "how"] b: i32, #[angery(true)] c: u32) {
+ }
+}"#);
diff --git a/src/test/ui/rfc-2565-param-attrs/issue-64682-dropping-first-attrs-in-impl-fns.rs b/src/test/ui/rfc-2565-param-attrs/issue-64682-dropping-first-attrs-in-impl-fns.rs
new file mode 100644
index 0000000000000..670303906d24c
--- /dev/null
+++ b/src/test/ui/rfc-2565-param-attrs/issue-64682-dropping-first-attrs-in-impl-fns.rs
@@ -0,0 +1,21 @@
+// aux-build:param-attrs.rs
+
+// check-pass
+
+extern crate param_attrs;
+
+use param_attrs::rename_params;
+
+#[rename_params(send_help)]
+impl Foo {
+ fn hello(#[angery(true)] a: i32, #[a2] b: i32, #[what = "how"] c: u32) {}
+ fn hello2(#[a1] #[a2] a: i32, #[what = "how"] b: i32, #[angery(true)] c: u32) {}
+ fn hello_self(
+ #[a1] #[a2] &self,
+ #[a1] #[a2] a: i32,
+ #[what = "how"] b: i32,
+ #[angery(true)] c: u32
+ ) {}
+}
+
+fn main() {}
diff --git a/src/test/ui/rfc-2565-param-attrs/param-attrs-builtin-attrs.rs b/src/test/ui/rfc-2565-param-attrs/param-attrs-builtin-attrs.rs
index c4684a3fa82b0..bf09171c9a12a 100644
--- a/src/test/ui/rfc-2565-param-attrs/param-attrs-builtin-attrs.rs
+++ b/src/test/ui/rfc-2565-param-attrs/param-attrs-builtin-attrs.rs
@@ -64,6 +64,21 @@ impl SelfStruct {
#[no_mangle] b: i32,
//~^ ERROR allow, cfg, cfg_attr, deny, forbid, and warn are the only allowed built-in
) {}
+
+ fn issue_64682_associated_fn(
+ /// Foo
+ //~^ ERROR documentation comments cannot be applied to function
+ #[test] a: i32,
+ //~^ ERROR expected an inert attribute, found an attribute macro
+ /// Baz
+ //~^ ERROR documentation comments cannot be applied to function
+ #[must_use]
+ //~^ ERROR allow, cfg, cfg_attr, deny, forbid, and warn are the only allowed built-in
+ /// Qux
+ //~^ ERROR documentation comments cannot be applied to function
+ #[no_mangle] b: i32,
+ //~^ ERROR allow, cfg, cfg_attr, deny, forbid, and warn are the only allowed built-in
+ ) {}
}
struct RefStruct {}
@@ -104,7 +119,23 @@ trait RefTrait {
#[no_mangle] b: i32,
//~^ ERROR allow, cfg, cfg_attr, deny, forbid, and warn are the only allowed built-in
) {}
+
+ fn issue_64682_associated_fn(
+ /// Foo
+ //~^ ERROR documentation comments cannot be applied to function
+ #[test] a: i32,
+ //~^ ERROR expected an inert attribute, found an attribute macro
+ /// Baz
+ //~^ ERROR documentation comments cannot be applied to function
+ #[must_use]
+ //~^ ERROR allow, cfg, cfg_attr, deny, forbid, and warn are the only allowed built-in
+ /// Qux
+ //~^ ERROR documentation comments cannot be applied to function
+ #[no_mangle] b: i32,
+ //~^ ERROR allow, cfg, cfg_attr, deny, forbid, and warn are the only allowed built-in
+ ) {}
}
+
impl RefTrait for RefStruct {
fn foo(
/// Foo
diff --git a/src/test/ui/rfc-2565-param-attrs/param-attrs-builtin-attrs.stderr b/src/test/ui/rfc-2565-param-attrs/param-attrs-builtin-attrs.stderr
index 0fc6ca2f7f37a..4d0349e8765f0 100644
--- a/src/test/ui/rfc-2565-param-attrs/param-attrs-builtin-attrs.stderr
+++ b/src/test/ui/rfc-2565-param-attrs/param-attrs-builtin-attrs.stderr
@@ -23,25 +23,37 @@ LL | #[test] a: i32,
| ^^^^^^^
error: expected an inert attribute, found an attribute macro
- --> $DIR/param-attrs-builtin-attrs.rs:77:9
+ --> $DIR/param-attrs-builtin-attrs.rs:71:9
|
LL | #[test] a: i32,
| ^^^^^^^
error: expected an inert attribute, found an attribute macro
- --> $DIR/param-attrs-builtin-attrs.rs:96:9
+ --> $DIR/param-attrs-builtin-attrs.rs:92:9
|
LL | #[test] a: i32,
| ^^^^^^^
error: expected an inert attribute, found an attribute macro
- --> $DIR/param-attrs-builtin-attrs.rs:115:9
+ --> $DIR/param-attrs-builtin-attrs.rs:111:9
|
LL | #[test] a: i32,
| ^^^^^^^
error: expected an inert attribute, found an attribute macro
- --> $DIR/param-attrs-builtin-attrs.rs:132:9
+ --> $DIR/param-attrs-builtin-attrs.rs:126:9
+ |
+LL | #[test] a: i32,
+ | ^^^^^^^
+
+error: expected an inert attribute, found an attribute macro
+ --> $DIR/param-attrs-builtin-attrs.rs:146:9
+ |
+LL | #[test] a: i32,
+ | ^^^^^^^
+
+error: expected an inert attribute, found an attribute macro
+ --> $DIR/param-attrs-builtin-attrs.rs:163:9
|
LL | #[test] a: u32,
| ^^^^^^^
@@ -173,142 +185,202 @@ LL | #[no_mangle] b: i32,
| ^^^^^^^^^^^^
error: documentation comments cannot be applied to function parameters
- --> $DIR/param-attrs-builtin-attrs.rs:72:9
+ --> $DIR/param-attrs-builtin-attrs.rs:69:9
|
LL | /// Foo
| ^^^^^^^ doc comments are not allowed here
error: documentation comments cannot be applied to function parameters
+ --> $DIR/param-attrs-builtin-attrs.rs:73:9
+ |
+LL | /// Baz
+ | ^^^^^^^ doc comments are not allowed here
+
+error: allow, cfg, cfg_attr, deny, forbid, and warn are the only allowed built-in attributes in function parameters
--> $DIR/param-attrs-builtin-attrs.rs:75:9
|
+LL | #[must_use]
+ | ^^^^^^^^^^^
+
+error: documentation comments cannot be applied to function parameters
+ --> $DIR/param-attrs-builtin-attrs.rs:77:9
+ |
+LL | /// Qux
+ | ^^^^^^^ doc comments are not allowed here
+
+error: allow, cfg, cfg_attr, deny, forbid, and warn are the only allowed built-in attributes in function parameters
+ --> $DIR/param-attrs-builtin-attrs.rs:79:9
+ |
+LL | #[no_mangle] b: i32,
+ | ^^^^^^^^^^^^
+
+error: documentation comments cannot be applied to function parameters
+ --> $DIR/param-attrs-builtin-attrs.rs:87:9
+ |
+LL | /// Foo
+ | ^^^^^^^ doc comments are not allowed here
+
+error: documentation comments cannot be applied to function parameters
+ --> $DIR/param-attrs-builtin-attrs.rs:90:9
+ |
LL | /// Bar
| ^^^^^^^ doc comments are not allowed here
error: documentation comments cannot be applied to function parameters
- --> $DIR/param-attrs-builtin-attrs.rs:79:9
+ --> $DIR/param-attrs-builtin-attrs.rs:94:9
|
LL | /// Baz
| ^^^^^^^ doc comments are not allowed here
error: allow, cfg, cfg_attr, deny, forbid, and warn are the only allowed built-in attributes in function parameters
- --> $DIR/param-attrs-builtin-attrs.rs:81:9
+ --> $DIR/param-attrs-builtin-attrs.rs:96:9
|
LL | #[must_use]
| ^^^^^^^^^^^
error: documentation comments cannot be applied to function parameters
- --> $DIR/param-attrs-builtin-attrs.rs:83:9
+ --> $DIR/param-attrs-builtin-attrs.rs:98:9
|
LL | /// Qux
| ^^^^^^^ doc comments are not allowed here
error: allow, cfg, cfg_attr, deny, forbid, and warn are the only allowed built-in attributes in function parameters
- --> $DIR/param-attrs-builtin-attrs.rs:85:9
+ --> $DIR/param-attrs-builtin-attrs.rs:100:9
|
LL | #[no_mangle] b: i32,
| ^^^^^^^^^^^^
error: documentation comments cannot be applied to function parameters
- --> $DIR/param-attrs-builtin-attrs.rs:91:9
+ --> $DIR/param-attrs-builtin-attrs.rs:106:9
|
LL | /// Foo
| ^^^^^^^ doc comments are not allowed here
error: documentation comments cannot be applied to function parameters
- --> $DIR/param-attrs-builtin-attrs.rs:94:9
+ --> $DIR/param-attrs-builtin-attrs.rs:109:9
|
LL | /// Bar
| ^^^^^^^ doc comments are not allowed here
error: documentation comments cannot be applied to function parameters
- --> $DIR/param-attrs-builtin-attrs.rs:98:9
+ --> $DIR/param-attrs-builtin-attrs.rs:113:9
|
LL | /// Baz
| ^^^^^^^ doc comments are not allowed here
error: allow, cfg, cfg_attr, deny, forbid, and warn are the only allowed built-in attributes in function parameters
- --> $DIR/param-attrs-builtin-attrs.rs:100:9
+ --> $DIR/param-attrs-builtin-attrs.rs:115:9
|
LL | #[must_use]
| ^^^^^^^^^^^
error: documentation comments cannot be applied to function parameters
- --> $DIR/param-attrs-builtin-attrs.rs:102:9
+ --> $DIR/param-attrs-builtin-attrs.rs:117:9
|
LL | /// Qux
| ^^^^^^^ doc comments are not allowed here
error: allow, cfg, cfg_attr, deny, forbid, and warn are the only allowed built-in attributes in function parameters
- --> $DIR/param-attrs-builtin-attrs.rs:104:9
+ --> $DIR/param-attrs-builtin-attrs.rs:119:9
|
LL | #[no_mangle] b: i32,
| ^^^^^^^^^^^^
error: documentation comments cannot be applied to function parameters
- --> $DIR/param-attrs-builtin-attrs.rs:110:9
+ --> $DIR/param-attrs-builtin-attrs.rs:124:9
|
LL | /// Foo
| ^^^^^^^ doc comments are not allowed here
error: documentation comments cannot be applied to function parameters
- --> $DIR/param-attrs-builtin-attrs.rs:113:9
+ --> $DIR/param-attrs-builtin-attrs.rs:128:9
+ |
+LL | /// Baz
+ | ^^^^^^^ doc comments are not allowed here
+
+error: allow, cfg, cfg_attr, deny, forbid, and warn are the only allowed built-in attributes in function parameters
+ --> $DIR/param-attrs-builtin-attrs.rs:130:9
+ |
+LL | #[must_use]
+ | ^^^^^^^^^^^
+
+error: documentation comments cannot be applied to function parameters
+ --> $DIR/param-attrs-builtin-attrs.rs:132:9
+ |
+LL | /// Qux
+ | ^^^^^^^ doc comments are not allowed here
+
+error: allow, cfg, cfg_attr, deny, forbid, and warn are the only allowed built-in attributes in function parameters
+ --> $DIR/param-attrs-builtin-attrs.rs:134:9
+ |
+LL | #[no_mangle] b: i32,
+ | ^^^^^^^^^^^^
+
+error: documentation comments cannot be applied to function parameters
+ --> $DIR/param-attrs-builtin-attrs.rs:141:9
+ |
+LL | /// Foo
+ | ^^^^^^^ doc comments are not allowed here
+
+error: documentation comments cannot be applied to function parameters
+ --> $DIR/param-attrs-builtin-attrs.rs:144:9
|
LL | /// Bar
| ^^^^^^^ doc comments are not allowed here
error: documentation comments cannot be applied to function parameters
- --> $DIR/param-attrs-builtin-attrs.rs:117:9
+ --> $DIR/param-attrs-builtin-attrs.rs:148:9
|
LL | /// Baz
| ^^^^^^^ doc comments are not allowed here
error: allow, cfg, cfg_attr, deny, forbid, and warn are the only allowed built-in attributes in function parameters
- --> $DIR/param-attrs-builtin-attrs.rs:119:9
+ --> $DIR/param-attrs-builtin-attrs.rs:150:9
|
LL | #[must_use]
| ^^^^^^^^^^^
error: documentation comments cannot be applied to function parameters
- --> $DIR/param-attrs-builtin-attrs.rs:121:9
+ --> $DIR/param-attrs-builtin-attrs.rs:152:9
|
LL | /// Qux
| ^^^^^^^ doc comments are not allowed here
error: allow, cfg, cfg_attr, deny, forbid, and warn are the only allowed built-in attributes in function parameters
- --> $DIR/param-attrs-builtin-attrs.rs:123:9
+ --> $DIR/param-attrs-builtin-attrs.rs:154:9
|
LL | #[no_mangle] b: i32,
| ^^^^^^^^^^^^
error: documentation comments cannot be applied to function parameters
- --> $DIR/param-attrs-builtin-attrs.rs:130:9
+ --> $DIR/param-attrs-builtin-attrs.rs:161:9
|
LL | /// Foo
| ^^^^^^^ doc comments are not allowed here
error: documentation comments cannot be applied to function parameters
- --> $DIR/param-attrs-builtin-attrs.rs:134:9
+ --> $DIR/param-attrs-builtin-attrs.rs:165:9
|
LL | /// Bar
| ^^^^^^^ doc comments are not allowed here
error: allow, cfg, cfg_attr, deny, forbid, and warn are the only allowed built-in attributes in function parameters
- --> $DIR/param-attrs-builtin-attrs.rs:136:9
+ --> $DIR/param-attrs-builtin-attrs.rs:167:9
|
LL | #[must_use]
| ^^^^^^^^^^^
error: documentation comments cannot be applied to function parameters
- --> $DIR/param-attrs-builtin-attrs.rs:138:9
+ --> $DIR/param-attrs-builtin-attrs.rs:169:9
|
LL | /// Baz
| ^^^^^^^ doc comments are not allowed here
error: allow, cfg, cfg_attr, deny, forbid, and warn are the only allowed built-in attributes in function parameters
- --> $DIR/param-attrs-builtin-attrs.rs:140:9
+ --> $DIR/param-attrs-builtin-attrs.rs:171:9
|
LL | #[no_mangle] b: i32
| ^^^^^^^^^^^^
-error: aborting due to 52 previous errors
+error: aborting due to 64 previous errors
diff --git a/src/test/ui/rfc-2565-param-attrs/param-attrs-cfg.rs b/src/test/ui/rfc-2565-param-attrs/param-attrs-cfg.rs
index d44ff14e99247..a4d9d32b514ac 100644
--- a/src/test/ui/rfc-2565-param-attrs/param-attrs-cfg.rs
+++ b/src/test/ui/rfc-2565-param-attrs/param-attrs-cfg.rs
@@ -51,6 +51,14 @@ impl RefStruct {
//~^ ERROR unused variable: `c`
#[cfg_attr(something, cfg(nothing))] d: i32,
) {}
+ fn issue_64682_associated_fn(
+ #[cfg(nothing)] a: i32,
+ #[cfg(something)] b: i32,
+ //~^ ERROR unused variable: `b`
+ #[cfg_attr(nothing, cfg(nothing))] c: i32,
+ //~^ ERROR unused variable: `c`
+ #[cfg_attr(something, cfg(nothing))] d: i32,
+ ) {}
}
trait RefTrait {
fn bar(
@@ -62,6 +70,14 @@ trait RefTrait {
//~^ ERROR unused variable: `c`
#[cfg_attr(something, cfg(nothing))] d: i32,
) {}
+ fn issue_64682_associated_fn(
+ #[cfg(nothing)] a: i32,
+ #[cfg(something)] b: i32,
+ //~^ ERROR unused variable: `b`
+ #[cfg_attr(nothing, cfg(nothing))] c: i32,
+ //~^ ERROR unused variable: `c`
+ #[cfg_attr(something, cfg(nothing))] d: i32,
+ ) {}
}
impl RefTrait for RefStruct {
fn bar(
@@ -73,6 +89,14 @@ impl RefTrait for RefStruct {
//~^ ERROR unused variable: `c`
#[cfg_attr(something, cfg(nothing))] d: i32,
) {}
+ fn issue_64682_associated_fn(
+ #[cfg(nothing)] a: i32,
+ #[cfg(something)] b: i32,
+ //~^ ERROR unused variable: `b`
+ #[cfg_attr(nothing, cfg(nothing))] c: i32,
+ //~^ ERROR unused variable: `c`
+ #[cfg_attr(something, cfg(nothing))] d: i32,
+ ) {}
}
fn main() {
diff --git a/src/test/ui/rfc-2565-param-attrs/param-attrs-cfg.stderr b/src/test/ui/rfc-2565-param-attrs/param-attrs-cfg.stderr
index 3232e2a0411a2..8d9571d09a856 100644
--- a/src/test/ui/rfc-2565-param-attrs/param-attrs-cfg.stderr
+++ b/src/test/ui/rfc-2565-param-attrs/param-attrs-cfg.stderr
@@ -23,31 +23,43 @@ LL | #[cfg_attr(nothing, cfg(nothing))] c: i32,
| ^ help: consider prefixing with an underscore: `_c`
error: unused variable: `a`
- --> $DIR/param-attrs-cfg.rs:83:27
+ --> $DIR/param-attrs-cfg.rs:107:27
|
LL | #[cfg(something)] a: i32,
| ^ help: consider prefixing with an underscore: `_a`
error: unused variable: `b`
- --> $DIR/param-attrs-cfg.rs:89:27
+ --> $DIR/param-attrs-cfg.rs:113:27
|
LL | #[cfg(something)] b: i32,
| ^ help: consider prefixing with an underscore: `_b`
error: unused variable: `c`
- --> $DIR/param-attrs-cfg.rs:91:44
+ --> $DIR/param-attrs-cfg.rs:115:44
|
LL | #[cfg_attr(nothing, cfg(nothing))] c: i32,
| ^ help: consider prefixing with an underscore: `_c`
error: unused variable: `b`
- --> $DIR/param-attrs-cfg.rs:59:27
+ --> $DIR/param-attrs-cfg.rs:67:27
|
LL | #[cfg(something)] b: i32,
| ^ help: consider prefixing with an underscore: `_b`
error: unused variable: `c`
- --> $DIR/param-attrs-cfg.rs:61:44
+ --> $DIR/param-attrs-cfg.rs:69:44
+ |
+LL | #[cfg_attr(nothing, cfg(nothing))] c: i32,
+ | ^ help: consider prefixing with an underscore: `_c`
+
+error: unused variable: `b`
+ --> $DIR/param-attrs-cfg.rs:75:27
+ |
+LL | #[cfg(something)] b: i32,
+ | ^ help: consider prefixing with an underscore: `_b`
+
+error: unused variable: `c`
+ --> $DIR/param-attrs-cfg.rs:77:44
|
LL | #[cfg_attr(nothing, cfg(nothing))] c: i32,
| ^ help: consider prefixing with an underscore: `_c`
@@ -71,16 +83,40 @@ LL | #[cfg_attr(nothing, cfg(nothing))] c: i32,
| ^ help: consider prefixing with an underscore: `_c`
error: unused variable: `b`
- --> $DIR/param-attrs-cfg.rs:70:27
+ --> $DIR/param-attrs-cfg.rs:56:27
+ |
+LL | #[cfg(something)] b: i32,
+ | ^ help: consider prefixing with an underscore: `_b`
+
+error: unused variable: `c`
+ --> $DIR/param-attrs-cfg.rs:58:44
+ |
+LL | #[cfg_attr(nothing, cfg(nothing))] c: i32,
+ | ^ help: consider prefixing with an underscore: `_c`
+
+error: unused variable: `b`
+ --> $DIR/param-attrs-cfg.rs:86:27
+ |
+LL | #[cfg(something)] b: i32,
+ | ^ help: consider prefixing with an underscore: `_b`
+
+error: unused variable: `c`
+ --> $DIR/param-attrs-cfg.rs:88:44
+ |
+LL | #[cfg_attr(nothing, cfg(nothing))] c: i32,
+ | ^ help: consider prefixing with an underscore: `_c`
+
+error: unused variable: `b`
+ --> $DIR/param-attrs-cfg.rs:94:27
|
LL | #[cfg(something)] b: i32,
| ^ help: consider prefixing with an underscore: `_b`
error: unused variable: `c`
- --> $DIR/param-attrs-cfg.rs:72:44
+ --> $DIR/param-attrs-cfg.rs:96:44
|
LL | #[cfg_attr(nothing, cfg(nothing))] c: i32,
| ^ help: consider prefixing with an underscore: `_c`
-error: aborting due to 13 previous errors
+error: aborting due to 19 previous errors
diff --git a/src/test/ui/rfc-2565-param-attrs/param-attrs-pretty.rs b/src/test/ui/rfc-2565-param-attrs/param-attrs-pretty.rs
index fb86020d992e9..1183ac65b9a7f 100644
--- a/src/test/ui/rfc-2565-param-attrs/param-attrs-pretty.rs
+++ b/src/test/ui/rfc-2565-param-attrs/param-attrs-pretty.rs
@@ -36,6 +36,9 @@ impl W {
#[attr_inherent_4]
fn inherent4<'a>(#[a1] self: Box, #[a2] arg1: u8) {}
+
+ #[attr_inherent_issue_64682]
+ fn inherent5(#[a1] #[a2] arg1: u8, #[a3] arg2: u8) {}
}
trait A {
@@ -50,6 +53,9 @@ trait A {
#[attr_trait_4]
fn trait4<'a>(#[a1] self: Box, #[a2] arg1: u8, #[a3] Vec);
+
+ #[attr_trait_issue_64682]
+ fn trait5(#[a1] #[a2] arg1: u8, #[a3] arg2: u8);
}
fn main() {}
diff --git a/src/test/ui/rfc-2565-param-attrs/proc-macro-cannot-be-used.rs b/src/test/ui/rfc-2565-param-attrs/proc-macro-cannot-be-used.rs
index e2680446f851a..be9085d5878cb 100644
--- a/src/test/ui/rfc-2565-param-attrs/proc-macro-cannot-be-used.rs
+++ b/src/test/ui/rfc-2565-param-attrs/proc-macro-cannot-be-used.rs
@@ -38,6 +38,9 @@ impl W {
fn inherent4<'a>(#[id] self: Box, #[id] arg1: u8) {}
//~^ ERROR expected an inert attribute, found an attribute macro
//~| ERROR expected an inert attribute, found an attribute macro
+ fn issue_64682_associated_fn<'a>(#[id] arg1: u8, #[id] arg2: u8) {}
+ //~^ ERROR expected an inert attribute, found an attribute macro
+ //~| ERROR expected an inert attribute, found an attribute macro
}
trait A {
@@ -54,6 +57,9 @@ trait A {
//~^ ERROR expected an inert attribute, found an attribute macro
//~| ERROR expected an inert attribute, found an attribute macro
//~| ERROR expected an inert attribute, found an attribute macro
+ fn issue_64682_associated_fn<'a>(#[id] arg1: u8, #[id] arg2: u8);
+ //~^ ERROR expected an inert attribute, found an attribute macro
+ //~| ERROR expected an inert attribute, found an attribute macro
}
fn main() {}
diff --git a/src/test/ui/rfc-2565-param-attrs/proc-macro-cannot-be-used.stderr b/src/test/ui/rfc-2565-param-attrs/proc-macro-cannot-be-used.stderr
index 4654dc1b496f2..1cc3c3d82281b 100644
--- a/src/test/ui/rfc-2565-param-attrs/proc-macro-cannot-be-used.stderr
+++ b/src/test/ui/rfc-2565-param-attrs/proc-macro-cannot-be-used.stderr
@@ -95,58 +95,82 @@ LL | fn inherent4<'a>(#[id] self: Box, #[id] arg1: u8) {}
| ^^^^^
error: expected an inert attribute, found an attribute macro
- --> $DIR/proc-macro-cannot-be-used.rs:44:15
+ --> $DIR/proc-macro-cannot-be-used.rs:41:38
+ |
+LL | fn issue_64682_associated_fn<'a>(#[id] arg1: u8, #[id] arg2: u8) {}
+ | ^^^^^
+
+error: expected an inert attribute, found an attribute macro
+ --> $DIR/proc-macro-cannot-be-used.rs:41:54
+ |
+LL | fn issue_64682_associated_fn<'a>(#[id] arg1: u8, #[id] arg2: u8) {}
+ | ^^^^^
+
+error: expected an inert attribute, found an attribute macro
+ --> $DIR/proc-macro-cannot-be-used.rs:47:15
|
LL | fn trait1(#[id] self, #[id] arg1: u8);
| ^^^^^
error: expected an inert attribute, found an attribute macro
- --> $DIR/proc-macro-cannot-be-used.rs:44:27
+ --> $DIR/proc-macro-cannot-be-used.rs:47:27
|
LL | fn trait1(#[id] self, #[id] arg1: u8);
| ^^^^^
error: expected an inert attribute, found an attribute macro
- --> $DIR/proc-macro-cannot-be-used.rs:47:15
+ --> $DIR/proc-macro-cannot-be-used.rs:50:15
|
LL | fn trait2(#[id] &self, #[id] arg1: u8);
| ^^^^^
error: expected an inert attribute, found an attribute macro
- --> $DIR/proc-macro-cannot-be-used.rs:47:28
+ --> $DIR/proc-macro-cannot-be-used.rs:50:28
|
LL | fn trait2(#[id] &self, #[id] arg1: u8);
| ^^^^^
error: expected an inert attribute, found an attribute macro
- --> $DIR/proc-macro-cannot-be-used.rs:50:19
+ --> $DIR/proc-macro-cannot-be-used.rs:53:19
|
LL | fn trait3<'a>(#[id] &'a mut self, #[id] arg1: u8);
| ^^^^^
error: expected an inert attribute, found an attribute macro
- --> $DIR/proc-macro-cannot-be-used.rs:50:39
+ --> $DIR/proc-macro-cannot-be-used.rs:53:39
|
LL | fn trait3<'a>(#[id] &'a mut self, #[id] arg1: u8);
| ^^^^^
error: expected an inert attribute, found an attribute macro
- --> $DIR/proc-macro-cannot-be-used.rs:53:19
+ --> $DIR/proc-macro-cannot-be-used.rs:56:19
|
LL | fn trait4<'a>(#[id] self: Box, #[id] arg1: u8, #[id] Vec);
| ^^^^^
error: expected an inert attribute, found an attribute macro
- --> $DIR/proc-macro-cannot-be-used.rs:53:42
+ --> $DIR/proc-macro-cannot-be-used.rs:56:42
|
LL | fn trait4<'a>(#[id] self: Box, #[id] arg1: u8, #[id] Vec);
| ^^^^^
error: expected an inert attribute, found an attribute macro
- --> $DIR/proc-macro-cannot-be-used.rs:53:58
+ --> $DIR/proc-macro-cannot-be-used.rs:56:58
|
LL | fn trait4<'a>(#[id] self: Box, #[id] arg1: u8, #[id] Vec);
| ^^^^^
-error: aborting due to 25 previous errors
+error: expected an inert attribute, found an attribute macro
+ --> $DIR/proc-macro-cannot-be-used.rs:60:38
+ |
+LL | fn issue_64682_associated_fn<'a>(#[id] arg1: u8, #[id] arg2: u8);
+ | ^^^^^
+
+error: expected an inert attribute, found an attribute macro
+ --> $DIR/proc-macro-cannot-be-used.rs:60:54
+ |
+LL | fn issue_64682_associated_fn<'a>(#[id] arg1: u8, #[id] arg2: u8);
+ | ^^^^^
+
+error: aborting due to 29 previous errors
diff --git a/src/test/ui/struct-literal-variant-in-if.stderr b/src/test/ui/struct-literal-variant-in-if.stderr
index 85cbc787bc2db..a52ec6dc53938 100644
--- a/src/test/ui/struct-literal-variant-in-if.stderr
+++ b/src/test/ui/struct-literal-variant-in-if.stderr
@@ -50,7 +50,10 @@ error[E0308]: mismatched types
--> $DIR/struct-literal-variant-in-if.rs:10:20
|
LL | if x == E::V { field } {}
- | ^^^^^ expected (), found bool
+ | ---------------^^^^^--- help: consider using a semicolon here
+ | | |
+ | | expected (), found bool
+ | expected this to be `()`
|
= note: expected type `()`
found type `bool`
diff --git a/src/test/ui/suggestions/fn-or-tuple-struct-without-args.stderr b/src/test/ui/suggestions/fn-or-tuple-struct-without-args.stderr
index 28b331bdbdcbc..1af0f7a191e80 100644
--- a/src/test/ui/suggestions/fn-or-tuple-struct-without-args.stderr
+++ b/src/test/ui/suggestions/fn-or-tuple-struct-without-args.stderr
@@ -1,6 +1,9 @@
error[E0423]: expected value, found struct variant `E::B`
--> $DIR/fn-or-tuple-struct-without-args.rs:36:16
|
+LL | B { a: usize },
+ | -------------- `E::B` defined here
+...
LL | let _: E = E::B;
| ^^^-
| | |
diff --git a/src/test/ui/suggestions/issue-61226.stderr b/src/test/ui/suggestions/issue-61226.stderr
index 6d7d98ac6a16b..fbcfba6653f27 100644
--- a/src/test/ui/suggestions/issue-61226.stderr
+++ b/src/test/ui/suggestions/issue-61226.stderr
@@ -1,6 +1,9 @@
error[E0423]: expected value, found struct `X`
--> $DIR/issue-61226.rs:3:10
|
+LL | struct X {}
+ | ----------- `X` defined here
+LL | fn main() {
LL | vec![X]; //…
| ^ did you mean `X { /* fields */ }`?
diff --git a/src/test/ui/suggestions/match-needing-semi.fixed b/src/test/ui/suggestions/match-needing-semi.fixed
new file mode 100644
index 0000000000000..03cbed1376ea3
--- /dev/null
+++ b/src/test/ui/suggestions/match-needing-semi.fixed
@@ -0,0 +1,18 @@
+// check-only
+// run-rustfix
+
+fn main() {
+ match 3 {
+ 4 => 1,
+ 3 => {
+ 2 //~ ERROR mismatched types
+ }
+ _ => 2
+ };
+ match 3 { //~ ERROR mismatched types
+ 4 => 1,
+ 3 => 2,
+ _ => 2
+ };
+ let _ = ();
+}
diff --git a/src/test/ui/suggestions/match-needing-semi.rs b/src/test/ui/suggestions/match-needing-semi.rs
new file mode 100644
index 0000000000000..f34071ac75886
--- /dev/null
+++ b/src/test/ui/suggestions/match-needing-semi.rs
@@ -0,0 +1,18 @@
+// check-only
+// run-rustfix
+
+fn main() {
+ match 3 {
+ 4 => 1,
+ 3 => {
+ 2 //~ ERROR mismatched types
+ }
+ _ => 2
+ }
+ match 3 { //~ ERROR mismatched types
+ 4 => 1,
+ 3 => 2,
+ _ => 2
+ }
+ let _ = ();
+}
diff --git a/src/test/ui/suggestions/match-needing-semi.stderr b/src/test/ui/suggestions/match-needing-semi.stderr
new file mode 100644
index 0000000000000..988945817c2ee
--- /dev/null
+++ b/src/test/ui/suggestions/match-needing-semi.stderr
@@ -0,0 +1,36 @@
+error[E0308]: mismatched types
+ --> $DIR/match-needing-semi.rs:8:13
+ |
+LL | / match 3 {
+LL | | 4 => 1,
+LL | | 3 => {
+LL | | 2
+ | | ^ expected (), found integer
+LL | | }
+LL | | _ => 2
+LL | | }
+ | | -- help: consider using a semicolon here
+ | |_____|
+ | expected this to be `()`
+ |
+ = note: expected type `()`
+ found type `{integer}`
+
+error[E0308]: mismatched types
+ --> $DIR/match-needing-semi.rs:12:5
+ |
+LL | / match 3 {
+LL | | 4 => 1,
+LL | | 3 => 2,
+LL | | _ => 2
+LL | | }
+ | | ^- help: consider using a semicolon here
+ | |_____|
+ | expected (), found integer
+ |
+ = note: expected type `()`
+ found type `{integer}`
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0308`.
diff --git a/src/test/ui/type-alias-enum-variants/incorrect-variant-form-through-Self-issue-58006.stderr b/src/test/ui/type-alias-enum-variants/incorrect-variant-form-through-Self-issue-58006.stderr
index 128a85e15634c..357b33de51b84 100644
--- a/src/test/ui/type-alias-enum-variants/incorrect-variant-form-through-Self-issue-58006.stderr
+++ b/src/test/ui/type-alias-enum-variants/incorrect-variant-form-through-Self-issue-58006.stderr
@@ -6,3 +6,4 @@ LL | Self::A => (),
error: aborting due to previous error
+For more information about this error, try `rustc --explain E0533`.
diff --git a/src/test/ui/type-alias-enum-variants/incorrect-variant-form-through-alias-caught.stderr b/src/test/ui/type-alias-enum-variants/incorrect-variant-form-through-alias-caught.stderr
index c1ea816b7facf..c6528e417d8ae 100644
--- a/src/test/ui/type-alias-enum-variants/incorrect-variant-form-through-alias-caught.stderr
+++ b/src/test/ui/type-alias-enum-variants/incorrect-variant-form-through-alias-caught.stderr
@@ -39,5 +39,5 @@ LL | let Alias::Unit() = panic!();
error: aborting due to 5 previous errors
-Some errors have detailed explanations: E0164, E0618.
+Some errors have detailed explanations: E0164, E0533, E0618.
For more information about an error, try `rustc --explain E0164`.