recover on 'mut ' and improve recovery for keywords.

This commit is contained in:
Mazdak Farrokhzad 2019-08-27 13:04:48 +02:00
parent e49b9581ba
commit f908aa9e80
71 changed files with 449 additions and 147 deletions

View File

@ -4,6 +4,7 @@ use crate::{maybe_recover_from_interpolated_ty_qpath, maybe_whole};
use crate::ptr::P; use crate::ptr::P;
use crate::ast::{self, Attribute, Pat, PatKind, FieldPat, RangeEnd, RangeSyntax, Mac}; use crate::ast::{self, Attribute, Pat, PatKind, FieldPat, RangeEnd, RangeSyntax, Mac};
use crate::ast::{BindingMode, Ident, Mutability, Path, QSelf, Expr, ExprKind}; use crate::ast::{BindingMode, Ident, Mutability, Path, QSelf, Expr, ExprKind};
use crate::mut_visit::{noop_visit_pat, MutVisitor};
use crate::parse::token::{self}; use crate::parse::token::{self};
use crate::print::pprust; use crate::print::pprust;
use crate::source_map::{respan, Span, Spanned}; use crate::source_map::{respan, Span, Spanned};
@ -273,7 +274,7 @@ impl<'a> Parser<'a> {
// Parse _ // Parse _
PatKind::Wild PatKind::Wild
} else if self.eat_keyword(kw::Mut) { } else if self.eat_keyword(kw::Mut) {
self.recover_pat_ident_mut_first()? self.parse_pat_ident_mut()?
} else if self.eat_keyword(kw::Ref) { } else if self.eat_keyword(kw::Ref) {
// Parse ref ident @ pat / ref mut ident @ pat // Parse ref ident @ pat / ref mut ident @ pat
let mutbl = self.parse_mutability(); let mutbl = self.parse_mutability();
@ -281,13 +282,12 @@ impl<'a> Parser<'a> {
} else if self.eat_keyword(kw::Box) { } else if self.eat_keyword(kw::Box) {
// Parse `box pat` // Parse `box pat`
PatKind::Box(self.parse_pat_with_range_pat(false, None)?) PatKind::Box(self.parse_pat_with_range_pat(false, None)?)
} else if self.token.is_ident() && !self.token.is_reserved_ident() && } else if self.can_be_ident_pat() {
self.parse_as_ident() {
// Parse `ident @ pat` // Parse `ident @ pat`
// This can give false positives and parse nullary enums, // This can give false positives and parse nullary enums,
// they are dealt with later in resolve. // they are dealt with later in resolve.
self.parse_pat_ident(BindingMode::ByValue(Mutability::Immutable))? self.parse_pat_ident(BindingMode::ByValue(Mutability::Immutable))?
} else if self.token.is_path_start() { } else if self.is_start_of_pat_with_path() {
// Parse pattern starting with a path // Parse pattern starting with a path
let (qself, path) = if self.eat_lt() { let (qself, path) = if self.eat_lt() {
// Parse a qualified path // Parse a qualified path
@ -384,24 +384,85 @@ impl<'a> Parser<'a> {
}) })
} }
fn parse_pat_ident_mut(&mut self) -> PResult<'a, PatKind> {
let mut_span = self.prev_span;
if self.eat_keyword(kw::Ref) {
return self.recover_mut_ref_ident(mut_span)
}
self.recover_additional_muts();
let mut pat = self.parse_pat(Some("identifier"))?;
// Add `mut` to any binding in the parsed pattern.
struct AddMut;
impl MutVisitor for AddMut {
fn visit_pat(&mut self, pat: &mut P<Pat>) {
if let PatKind::Ident(BindingMode::ByValue(ref mut m), ..) = pat.node {
*m = Mutability::Mutable;
}
noop_visit_pat(pat, self);
}
}
AddMut.visit_pat(&mut pat);
// Unwrap; If we don't have `mut $ident`, error.
let pat = pat.into_inner();
match &pat.node {
PatKind::Ident(..) => {}
_ => self.ban_mut_general_pat(mut_span, &pat),
}
Ok(pat.node)
}
/// Recover on `mut ref? ident @ pat` and suggest /// Recover on `mut ref? ident @ pat` and suggest
/// that the order of `mut` and `ref` is incorrect. /// that the order of `mut` and `ref` is incorrect.
fn recover_pat_ident_mut_first(&mut self) -> PResult<'a, PatKind> { fn recover_mut_ref_ident(&mut self, lo: Span) -> PResult<'a, PatKind> {
let mutref_span = self.prev_span.to(self.token.span); let mutref_span = lo.to(self.prev_span);
let binding_mode = if self.eat_keyword(kw::Ref) { self.struct_span_err(mutref_span, "the order of `mut` and `ref` is incorrect")
self.struct_span_err(mutref_span, "the order of `mut` and `ref` is incorrect") .span_suggestion(
.span_suggestion( mutref_span,
mutref_span, "try switching the order",
"try switching the order", "ref mut".into(),
"ref mut".into(), Applicability::MachineApplicable
Applicability::MachineApplicable )
) .emit();
.emit();
BindingMode::ByRef(Mutability::Mutable) self.parse_pat_ident(BindingMode::ByRef(Mutability::Mutable))
} else { }
BindingMode::ByValue(Mutability::Mutable)
}; /// Error on `mut $pat` where `$pat` is not an ident.
self.parse_pat_ident(binding_mode) fn ban_mut_general_pat(&self, lo: Span, pat: &Pat) {
let span = lo.to(pat.span);
self.struct_span_err(span, "`mut` must be attached to each individual binding")
.span_suggestion(
span,
"add `mut` to each binding",
pprust::pat_to_string(&pat),
Applicability::MachineApplicable,
)
.emit();
}
/// Eat any extraneous `mut`s and error + recover if we ate any.
fn recover_additional_muts(&mut self) {
let lo = self.token.span;
while self.eat_keyword(kw::Mut) {}
if lo == self.token.span {
return;
}
let span = lo.to(self.prev_span);
self.struct_span_err(span, "`mut` on a binding may not be repeated")
.span_suggestion(
span,
"remove the additional `mut`s",
String::new(),
Applicability::MachineApplicable,
)
.emit();
} }
/// Parse macro invocation /// Parse macro invocation
@ -479,17 +540,6 @@ impl<'a> Parser<'a> {
Err(err) Err(err)
} }
// Helper function to decide whether to parse as ident binding
// or to try to do something more complex like range patterns.
fn parse_as_ident(&mut self) -> bool {
self.look_ahead(1, |t| match t.kind {
token::OpenDelim(token::Paren) | token::OpenDelim(token::Brace) |
token::DotDotDot | token::DotDotEq | token::DotDot |
token::ModSep | token::Not => false,
_ => true,
})
}
/// Is the current token suitable as the start of a range patterns end? /// Is the current token suitable as the start of a range patterns end?
fn is_pat_range_end_start(&self) -> bool { fn is_pat_range_end_start(&self) -> bool {
self.token.is_path_start() // e.g. `MY_CONST`; self.token.is_path_start() // e.g. `MY_CONST`;
@ -563,6 +613,30 @@ impl<'a> Parser<'a> {
} }
} }
/// Is this the start of a pattern beginning with a path?
fn is_start_of_pat_with_path(&mut self) -> bool {
self.check_path()
// Just for recovery (see `can_be_ident`).
|| self.token.is_ident() && !self.token.is_bool_lit() && !self.token.is_keyword(kw::In)
}
/// Would `parse_pat_ident` be appropriate here?
fn can_be_ident_pat(&mut self) -> bool {
self.check_ident()
&& !self.token.is_bool_lit() // Avoid `true` or `false` as a binding as it is a literal.
&& !self.token.is_path_segment_keyword() // Avoid e.g. `Self` as it is a path.
// Avoid `in`. Due to recovery in the list parser this messes with `for ( $pat in $expr )`.
&& !self.token.is_keyword(kw::In)
&& self.look_ahead(1, |t| match t.kind { // Try to do something more complex?
token::OpenDelim(token::Paren) // A tuple struct pattern.
| token::OpenDelim(token::Brace) // A struct pattern.
| token::DotDotDot | token::DotDotEq | token::DotDot // A range pattern.
| token::ModSep // A tuple / struct variant pattern.
| token::Not => false, // A macro expanding to a pattern.
_ => true,
})
}
/// Parses `ident` or `ident @ pat`. /// Parses `ident` or `ident @ pat`.
/// Used by the copy foo and ref foo patterns to give a good /// Used by the copy foo and ref foo patterns to give a good
/// error message when parsing mistakes like `ref foo(a, b)`. /// error message when parsing mistakes like `ref foo(a, b)`.

View File

@ -1,3 +1,3 @@
fn main() { fn main() {
let extern = 0; //~ ERROR expected pattern, found keyword `extern` let extern = 0; //~ ERROR expected identifier, found keyword `extern`
} }

View File

@ -1,8 +1,12 @@
error: expected pattern, found keyword `extern` error: expected identifier, found keyword `extern`
--> $DIR/keyword-extern-as-identifier-pat.rs:2:9 --> $DIR/keyword-extern-as-identifier-pat.rs:2:9
| |
LL | let extern = 0; LL | let extern = 0;
| ^^^^^^ expected pattern | ^^^^^^ expected identifier, found keyword
help: you can escape reserved keywords to use them as identifiers
|
LL | let r#extern = 0;
| ^^^^^^^^
error: aborting due to previous error error: aborting due to previous error

View File

@ -4,5 +4,6 @@ fn main() {
let _ = 0; let _ = 0;
let mut b = 0; let mut b = 0;
let mut _b = 0; let mut _b = 0;
let mut _ = 0; //~ ERROR expected identifier, found reserved identifier `_` let mut _ = 0;
//~^ ERROR `mut` must be attached to each individual binding
} }

View File

@ -1,8 +1,8 @@
error: expected identifier, found reserved identifier `_` error: `mut` must be attached to each individual binding
--> $DIR/issue-32501.rs:7:13 --> $DIR/issue-32501.rs:7:9
| |
LL | let mut _ = 0; LL | let mut _ = 0;
| ^ expected identifier, found reserved identifier | ^^^^^ help: add `mut` to each binding: `_`
error: aborting due to previous error error: aborting due to previous error

View File

@ -1,3 +1,3 @@
fn main() { fn main() {
let abstract = (); //~ ERROR expected pattern, found reserved keyword `abstract` let abstract = (); //~ ERROR expected identifier, found reserved keyword `abstract`
} }

View File

@ -1,8 +1,12 @@
error: expected pattern, found reserved keyword `abstract` error: expected identifier, found reserved keyword `abstract`
--> $DIR/keyword-abstract.rs:2:9 --> $DIR/keyword-abstract.rs:2:9
| |
LL | let abstract = (); LL | let abstract = ();
| ^^^^^^^^ expected pattern | ^^^^^^^^ expected identifier, found reserved keyword
help: you can escape reserved keywords to use them as identifiers
|
LL | let r#abstract = ();
| ^^^^^^^^^^
error: aborting due to previous error error: aborting due to previous error

View File

@ -1,5 +1,5 @@
// This file was auto-generated using 'src/etc/generate-keyword-tests.py as' // This file was auto-generated using 'src/etc/generate-keyword-tests.py as'
fn main() { fn main() {
let as = "foo"; //~ error: expected pattern, found keyword `as` let as = "foo"; //~ error: expected identifier, found keyword `as`
} }

View File

@ -1,8 +1,12 @@
error: expected pattern, found keyword `as` error: expected identifier, found keyword `as`
--> $DIR/keyword-as-as-identifier.rs:4:9 --> $DIR/keyword-as-as-identifier.rs:4:9
| |
LL | let as = "foo"; LL | let as = "foo";
| ^^ expected pattern | ^^ expected identifier, found keyword
help: you can escape reserved keywords to use them as identifiers
|
LL | let r#as = "foo";
| ^^^^
error: aborting due to previous error error: aborting due to previous error

View File

@ -1,5 +1,5 @@
// This file was auto-generated using 'src/etc/generate-keyword-tests.py break' // This file was auto-generated using 'src/etc/generate-keyword-tests.py break'
fn main() { fn main() {
let break = "foo"; //~ error: expected pattern, found keyword `break` let break = "foo"; //~ error: expected identifier, found keyword `break`
} }

View File

@ -1,8 +1,12 @@
error: expected pattern, found keyword `break` error: expected identifier, found keyword `break`
--> $DIR/keyword-break-as-identifier.rs:4:9 --> $DIR/keyword-break-as-identifier.rs:4:9
| |
LL | let break = "foo"; LL | let break = "foo";
| ^^^^^ expected pattern | ^^^^^ expected identifier, found keyword
help: you can escape reserved keywords to use them as identifiers
|
LL | let r#break = "foo";
| ^^^^^^^
error: aborting due to previous error error: aborting due to previous error

View File

@ -1,5 +1,5 @@
// This file was auto-generated using 'src/etc/generate-keyword-tests.py const' // This file was auto-generated using 'src/etc/generate-keyword-tests.py const'
fn main() { fn main() {
let const = "foo"; //~ error: expected pattern, found keyword `const` let const = "foo"; //~ error: expected identifier, found keyword `const`
} }

View File

@ -1,8 +1,12 @@
error: expected pattern, found keyword `const` error: expected identifier, found keyword `const`
--> $DIR/keyword-const-as-identifier.rs:4:9 --> $DIR/keyword-const-as-identifier.rs:4:9
| |
LL | let const = "foo"; LL | let const = "foo";
| ^^^^^ expected pattern | ^^^^^ expected identifier, found keyword
help: you can escape reserved keywords to use them as identifiers
|
LL | let r#const = "foo";
| ^^^^^^^
error: aborting due to previous error error: aborting due to previous error

View File

@ -1,5 +1,5 @@
// This file was auto-generated using 'src/etc/generate-keyword-tests.py continue' // This file was auto-generated using 'src/etc/generate-keyword-tests.py continue'
fn main() { fn main() {
let continue = "foo"; //~ error: expected pattern, found keyword `continue` let continue = "foo"; //~ error: expected identifier, found keyword `continue`
} }

View File

@ -1,8 +1,12 @@
error: expected pattern, found keyword `continue` error: expected identifier, found keyword `continue`
--> $DIR/keyword-continue-as-identifier.rs:4:9 --> $DIR/keyword-continue-as-identifier.rs:4:9
| |
LL | let continue = "foo"; LL | let continue = "foo";
| ^^^^^^^^ expected pattern | ^^^^^^^^ expected identifier, found keyword
help: you can escape reserved keywords to use them as identifiers
|
LL | let r#continue = "foo";
| ^^^^^^^^^^
error: aborting due to previous error error: aborting due to previous error

View File

@ -1,5 +1,5 @@
// This file was auto-generated using 'src/etc/generate-keyword-tests.py else' // This file was auto-generated using 'src/etc/generate-keyword-tests.py else'
fn main() { fn main() {
let else = "foo"; //~ error: expected pattern, found keyword `else` let else = "foo"; //~ error: expected identifier, found keyword `else`
} }

View File

@ -1,8 +1,12 @@
error: expected pattern, found keyword `else` error: expected identifier, found keyword `else`
--> $DIR/keyword-else-as-identifier.rs:4:9 --> $DIR/keyword-else-as-identifier.rs:4:9
| |
LL | let else = "foo"; LL | let else = "foo";
| ^^^^ expected pattern | ^^^^ expected identifier, found keyword
help: you can escape reserved keywords to use them as identifiers
|
LL | let r#else = "foo";
| ^^^^^^
error: aborting due to previous error error: aborting due to previous error

View File

@ -1,5 +1,5 @@
// This file was auto-generated using 'src/etc/generate-keyword-tests.py enum' // This file was auto-generated using 'src/etc/generate-keyword-tests.py enum'
fn main() { fn main() {
let enum = "foo"; //~ error: expected pattern, found keyword `enum` let enum = "foo"; //~ error: expected identifier, found keyword `enum`
} }

View File

@ -1,8 +1,12 @@
error: expected pattern, found keyword `enum` error: expected identifier, found keyword `enum`
--> $DIR/keyword-enum-as-identifier.rs:4:9 --> $DIR/keyword-enum-as-identifier.rs:4:9
| |
LL | let enum = "foo"; LL | let enum = "foo";
| ^^^^ expected pattern | ^^^^ expected identifier, found keyword
help: you can escape reserved keywords to use them as identifiers
|
LL | let r#enum = "foo";
| ^^^^^^
error: aborting due to previous error error: aborting due to previous error

View File

@ -1,3 +1,3 @@
fn main() { fn main() {
let final = (); //~ ERROR expected pattern, found reserved keyword `final` let final = (); //~ ERROR expected identifier, found reserved keyword `final`
} }

View File

@ -1,8 +1,12 @@
error: expected pattern, found reserved keyword `final` error: expected identifier, found reserved keyword `final`
--> $DIR/keyword-final.rs:2:9 --> $DIR/keyword-final.rs:2:9
| |
LL | let final = (); LL | let final = ();
| ^^^^^ expected pattern | ^^^^^ expected identifier, found reserved keyword
help: you can escape reserved keywords to use them as identifiers
|
LL | let r#final = ();
| ^^^^^^^
error: aborting due to previous error error: aborting due to previous error

View File

@ -1,5 +1,5 @@
// This file was auto-generated using 'src/etc/generate-keyword-tests.py fn' // This file was auto-generated using 'src/etc/generate-keyword-tests.py fn'
fn main() { fn main() {
let fn = "foo"; //~ error: expected pattern, found keyword `fn` let fn = "foo"; //~ error: expected identifier, found keyword `fn`
} }

View File

@ -1,8 +1,12 @@
error: expected pattern, found keyword `fn` error: expected identifier, found keyword `fn`
--> $DIR/keyword-fn-as-identifier.rs:4:9 --> $DIR/keyword-fn-as-identifier.rs:4:9
| |
LL | let fn = "foo"; LL | let fn = "foo";
| ^^ expected pattern | ^^ expected identifier, found keyword
help: you can escape reserved keywords to use them as identifiers
|
LL | let r#fn = "foo";
| ^^^^
error: aborting due to previous error error: aborting due to previous error

View File

@ -1,5 +1,5 @@
// This file was auto-generated using 'src/etc/generate-keyword-tests.py for' // This file was auto-generated using 'src/etc/generate-keyword-tests.py for'
fn main() { fn main() {
let for = "foo"; //~ error: expected pattern, found keyword `for` let for = "foo"; //~ error: expected identifier, found keyword `for`
} }

View File

@ -1,8 +1,12 @@
error: expected pattern, found keyword `for` error: expected identifier, found keyword `for`
--> $DIR/keyword-for-as-identifier.rs:4:9 --> $DIR/keyword-for-as-identifier.rs:4:9
| |
LL | let for = "foo"; LL | let for = "foo";
| ^^^ expected pattern | ^^^ expected identifier, found keyword
help: you can escape reserved keywords to use them as identifiers
|
LL | let r#for = "foo";
| ^^^^^
error: aborting due to previous error error: aborting due to previous error

View File

@ -1,5 +1,5 @@
// This file was auto-generated using 'src/etc/generate-keyword-tests.py if' // This file was auto-generated using 'src/etc/generate-keyword-tests.py if'
fn main() { fn main() {
let if = "foo"; //~ error: expected pattern, found keyword `if` let if = "foo"; //~ error: expected identifier, found keyword `if`
} }

View File

@ -1,8 +1,12 @@
error: expected pattern, found keyword `if` error: expected identifier, found keyword `if`
--> $DIR/keyword-if-as-identifier.rs:4:9 --> $DIR/keyword-if-as-identifier.rs:4:9
| |
LL | let if = "foo"; LL | let if = "foo";
| ^^ expected pattern | ^^ expected identifier, found keyword
help: you can escape reserved keywords to use them as identifiers
|
LL | let r#if = "foo";
| ^^^^
error: aborting due to previous error error: aborting due to previous error

View File

@ -1,5 +1,5 @@
// This file was auto-generated using 'src/etc/generate-keyword-tests.py impl' // This file was auto-generated using 'src/etc/generate-keyword-tests.py impl'
fn main() { fn main() {
let impl = "foo"; //~ error: expected pattern, found keyword `impl` let impl = "foo"; //~ error: expected identifier, found keyword `impl`
} }

View File

@ -1,8 +1,12 @@
error: expected pattern, found keyword `impl` error: expected identifier, found keyword `impl`
--> $DIR/keyword-impl-as-identifier.rs:4:9 --> $DIR/keyword-impl-as-identifier.rs:4:9
| |
LL | let impl = "foo"; LL | let impl = "foo";
| ^^^^ expected pattern | ^^^^ expected identifier, found keyword
help: you can escape reserved keywords to use them as identifiers
|
LL | let r#impl = "foo";
| ^^^^^^
error: aborting due to previous error error: aborting due to previous error

View File

@ -1,5 +1,5 @@
// This file was auto-generated using 'src/etc/generate-keyword-tests.py let' // This file was auto-generated using 'src/etc/generate-keyword-tests.py let'
fn main() { fn main() {
let let = "foo"; //~ error: expected pattern, found keyword `let` let let = "foo"; //~ error: expected identifier, found keyword `let`
} }

View File

@ -1,8 +1,12 @@
error: expected pattern, found keyword `let` error: expected identifier, found keyword `let`
--> $DIR/keyword-let-as-identifier.rs:4:9 --> $DIR/keyword-let-as-identifier.rs:4:9
| |
LL | let let = "foo"; LL | let let = "foo";
| ^^^ expected pattern | ^^^ expected identifier, found keyword
help: you can escape reserved keywords to use them as identifiers
|
LL | let r#let = "foo";
| ^^^^^
error: aborting due to previous error error: aborting due to previous error

View File

@ -1,5 +1,5 @@
// This file was auto-generated using 'src/etc/generate-keyword-tests.py loop' // This file was auto-generated using 'src/etc/generate-keyword-tests.py loop'
fn main() { fn main() {
let loop = "foo"; //~ error: expected pattern, found keyword `loop` let loop = "foo"; //~ error: expected identifier, found keyword `loop`
} }

View File

@ -1,8 +1,12 @@
error: expected pattern, found keyword `loop` error: expected identifier, found keyword `loop`
--> $DIR/keyword-loop-as-identifier.rs:4:9 --> $DIR/keyword-loop-as-identifier.rs:4:9
| |
LL | let loop = "foo"; LL | let loop = "foo";
| ^^^^ expected pattern | ^^^^ expected identifier, found keyword
help: you can escape reserved keywords to use them as identifiers
|
LL | let r#loop = "foo";
| ^^^^^^
error: aborting due to previous error error: aborting due to previous error

View File

@ -1,5 +1,5 @@
// This file was auto-generated using 'src/etc/generate-keyword-tests.py match' // This file was auto-generated using 'src/etc/generate-keyword-tests.py match'
fn main() { fn main() {
let match = "foo"; //~ error: expected pattern, found keyword `match` let match = "foo"; //~ error: expected identifier, found keyword `match`
} }

View File

@ -1,8 +1,12 @@
error: expected pattern, found keyword `match` error: expected identifier, found keyword `match`
--> $DIR/keyword-match-as-identifier.rs:4:9 --> $DIR/keyword-match-as-identifier.rs:4:9
| |
LL | let match = "foo"; LL | let match = "foo";
| ^^^^^ expected pattern | ^^^^^ expected identifier, found keyword
help: you can escape reserved keywords to use them as identifiers
|
LL | let r#match = "foo";
| ^^^^^^^
error: aborting due to previous error error: aborting due to previous error

View File

@ -1,5 +1,5 @@
// This file was auto-generated using 'src/etc/generate-keyword-tests.py mod' // This file was auto-generated using 'src/etc/generate-keyword-tests.py mod'
fn main() { fn main() {
let mod = "foo"; //~ error: expected pattern, found keyword `mod` let mod = "foo"; //~ error: expected identifier, found keyword `mod`
} }

View File

@ -1,8 +1,12 @@
error: expected pattern, found keyword `mod` error: expected identifier, found keyword `mod`
--> $DIR/keyword-mod-as-identifier.rs:4:9 --> $DIR/keyword-mod-as-identifier.rs:4:9
| |
LL | let mod = "foo"; LL | let mod = "foo";
| ^^^ expected pattern | ^^^ expected identifier, found keyword
help: you can escape reserved keywords to use them as identifiers
|
LL | let r#mod = "foo";
| ^^^^^
error: aborting due to previous error error: aborting due to previous error

View File

@ -1,5 +1,5 @@
// This file was auto-generated using 'src/etc/generate-keyword-tests.py move' // This file was auto-generated using 'src/etc/generate-keyword-tests.py move'
fn main() { fn main() {
let move = "foo"; //~ error: expected pattern, found keyword `move` let move = "foo"; //~ error: expected identifier, found keyword `move`
} }

View File

@ -1,8 +1,12 @@
error: expected pattern, found keyword `move` error: expected identifier, found keyword `move`
--> $DIR/keyword-move-as-identifier.rs:4:9 --> $DIR/keyword-move-as-identifier.rs:4:9
| |
LL | let move = "foo"; LL | let move = "foo";
| ^^^^ expected pattern | ^^^^ expected identifier, found keyword
help: you can escape reserved keywords to use them as identifiers
|
LL | let r#move = "foo";
| ^^^^^^
error: aborting due to previous error error: aborting due to previous error

View File

@ -1,3 +1,3 @@
fn main() { fn main() {
let override = (); //~ ERROR expected pattern, found reserved keyword `override` let override = (); //~ ERROR expected identifier, found reserved keyword `override`
} }

View File

@ -1,8 +1,12 @@
error: expected pattern, found reserved keyword `override` error: expected identifier, found reserved keyword `override`
--> $DIR/keyword-override.rs:2:9 --> $DIR/keyword-override.rs:2:9
| |
LL | let override = (); LL | let override = ();
| ^^^^^^^^ expected pattern | ^^^^^^^^ expected identifier, found reserved keyword
help: you can escape reserved keywords to use them as identifiers
|
LL | let r#override = ();
| ^^^^^^^^^^
error: aborting due to previous error error: aborting due to previous error

View File

@ -1,5 +1,5 @@
// This file was auto-generated using 'src/etc/generate-keyword-tests.py pub' // This file was auto-generated using 'src/etc/generate-keyword-tests.py pub'
fn main() { fn main() {
let pub = "foo"; //~ error: expected pattern, found keyword `pub` let pub = "foo"; //~ error: expected identifier, found keyword `pub`
} }

View File

@ -1,8 +1,12 @@
error: expected pattern, found keyword `pub` error: expected identifier, found keyword `pub`
--> $DIR/keyword-pub-as-identifier.rs:4:9 --> $DIR/keyword-pub-as-identifier.rs:4:9
| |
LL | let pub = "foo"; LL | let pub = "foo";
| ^^^ expected pattern | ^^^ expected identifier, found keyword
help: you can escape reserved keywords to use them as identifiers
|
LL | let r#pub = "foo";
| ^^^^^
error: aborting due to previous error error: aborting due to previous error

View File

@ -1,5 +1,5 @@
// This file was auto-generated using 'src/etc/generate-keyword-tests.py return' // This file was auto-generated using 'src/etc/generate-keyword-tests.py return'
fn main() { fn main() {
let return = "foo"; //~ error: expected pattern, found keyword `return` let return = "foo"; //~ error: expected identifier, found keyword `return`
} }

View File

@ -1,8 +1,12 @@
error: expected pattern, found keyword `return` error: expected identifier, found keyword `return`
--> $DIR/keyword-return-as-identifier.rs:4:9 --> $DIR/keyword-return-as-identifier.rs:4:9
| |
LL | let return = "foo"; LL | let return = "foo";
| ^^^^^^ expected pattern | ^^^^^^ expected identifier, found keyword
help: you can escape reserved keywords to use them as identifiers
|
LL | let r#return = "foo";
| ^^^^^^^^
error: aborting due to previous error error: aborting due to previous error

View File

@ -1,5 +1,5 @@
// This file was auto-generated using 'src/etc/generate-keyword-tests.py static' // This file was auto-generated using 'src/etc/generate-keyword-tests.py static'
fn main() { fn main() {
let static = "foo"; //~ error: expected pattern, found keyword `static` let static = "foo"; //~ error: expected identifier, found keyword `static`
} }

View File

@ -1,8 +1,12 @@
error: expected pattern, found keyword `static` error: expected identifier, found keyword `static`
--> $DIR/keyword-static-as-identifier.rs:4:9 --> $DIR/keyword-static-as-identifier.rs:4:9
| |
LL | let static = "foo"; LL | let static = "foo";
| ^^^^^^ expected pattern | ^^^^^^ expected identifier, found keyword
help: you can escape reserved keywords to use them as identifiers
|
LL | let r#static = "foo";
| ^^^^^^^^
error: aborting due to previous error error: aborting due to previous error

View File

@ -1,5 +1,5 @@
// This file was auto-generated using 'src/etc/generate-keyword-tests.py struct' // This file was auto-generated using 'src/etc/generate-keyword-tests.py struct'
fn main() { fn main() {
let struct = "foo"; //~ error: expected pattern, found keyword `struct` let struct = "foo"; //~ error: expected identifier, found keyword `struct`
} }

View File

@ -1,8 +1,12 @@
error: expected pattern, found keyword `struct` error: expected identifier, found keyword `struct`
--> $DIR/keyword-struct-as-identifier.rs:4:9 --> $DIR/keyword-struct-as-identifier.rs:4:9
| |
LL | let struct = "foo"; LL | let struct = "foo";
| ^^^^^^ expected pattern | ^^^^^^ expected identifier, found keyword
help: you can escape reserved keywords to use them as identifiers
|
LL | let r#struct = "foo";
| ^^^^^^^^
error: aborting due to previous error error: aborting due to previous error

View File

@ -1,5 +1,5 @@
// This file was auto-generated using 'src/etc/generate-keyword-tests.py trait' // This file was auto-generated using 'src/etc/generate-keyword-tests.py trait'
fn main() { fn main() {
let trait = "foo"; //~ error: expected pattern, found keyword `trait` let trait = "foo"; //~ error: expected identifier, found keyword `trait`
} }

View File

@ -1,8 +1,12 @@
error: expected pattern, found keyword `trait` error: expected identifier, found keyword `trait`
--> $DIR/keyword-trait-as-identifier.rs:4:9 --> $DIR/keyword-trait-as-identifier.rs:4:9
| |
LL | let trait = "foo"; LL | let trait = "foo";
| ^^^^^ expected pattern | ^^^^^ expected identifier, found keyword
help: you can escape reserved keywords to use them as identifiers
|
LL | let r#trait = "foo";
| ^^^^^^^
error: aborting due to previous error error: aborting due to previous error

View File

@ -1,5 +1,5 @@
// compile-flags: --edition 2018 // compile-flags: --edition 2018
fn main() { fn main() {
let try = "foo"; //~ error: expected pattern, found reserved keyword `try` let try = "foo"; //~ error: expected identifier, found reserved keyword `try`
} }

View File

@ -1,8 +1,12 @@
error: expected pattern, found reserved keyword `try` error: expected identifier, found reserved keyword `try`
--> $DIR/keyword-try-as-identifier-edition2018.rs:4:9 --> $DIR/keyword-try-as-identifier-edition2018.rs:4:9
| |
LL | let try = "foo"; LL | let try = "foo";
| ^^^ expected pattern | ^^^ expected identifier, found reserved keyword
help: you can escape reserved keywords to use them as identifiers
|
LL | let r#try = "foo";
| ^^^^^
error: aborting due to previous error error: aborting due to previous error

View File

@ -1,5 +1,5 @@
// This file was auto-generated using 'src/etc/generate-keyword-tests.py type' // This file was auto-generated using 'src/etc/generate-keyword-tests.py type'
fn main() { fn main() {
let type = "foo"; //~ error: expected pattern, found keyword `type` let type = "foo"; //~ error: expected identifier, found keyword `type`
} }

View File

@ -1,8 +1,12 @@
error: expected pattern, found keyword `type` error: expected identifier, found keyword `type`
--> $DIR/keyword-type-as-identifier.rs:4:9 --> $DIR/keyword-type-as-identifier.rs:4:9
| |
LL | let type = "foo"; LL | let type = "foo";
| ^^^^ expected pattern | ^^^^ expected identifier, found keyword
help: you can escape reserved keywords to use them as identifiers
|
LL | let r#type = "foo";
| ^^^^^^
error: aborting due to previous error error: aborting due to previous error

View File

@ -1,3 +1,3 @@
fn main() { fn main() {
let typeof = (); //~ ERROR expected pattern, found reserved keyword `typeof` let typeof = (); //~ ERROR expected identifier, found reserved keyword `typeof`
} }

View File

@ -1,8 +1,12 @@
error: expected pattern, found reserved keyword `typeof` error: expected identifier, found reserved keyword `typeof`
--> $DIR/keyword-typeof.rs:2:9 --> $DIR/keyword-typeof.rs:2:9
| |
LL | let typeof = (); LL | let typeof = ();
| ^^^^^^ expected pattern | ^^^^^^ expected identifier, found reserved keyword
help: you can escape reserved keywords to use them as identifiers
|
LL | let r#typeof = ();
| ^^^^^^^^
error: aborting due to previous error error: aborting due to previous error

View File

@ -1,5 +1,5 @@
// This file was auto-generated using 'src/etc/generate-keyword-tests.py unsafe' // This file was auto-generated using 'src/etc/generate-keyword-tests.py unsafe'
fn main() { fn main() {
let unsafe = "foo"; //~ error: expected pattern, found keyword `unsafe` let unsafe = "foo"; //~ error: expected identifier, found keyword `unsafe`
} }

View File

@ -1,8 +1,12 @@
error: expected pattern, found keyword `unsafe` error: expected identifier, found keyword `unsafe`
--> $DIR/keyword-unsafe-as-identifier.rs:4:9 --> $DIR/keyword-unsafe-as-identifier.rs:4:9
| |
LL | let unsafe = "foo"; LL | let unsafe = "foo";
| ^^^^^^ expected pattern | ^^^^^^ expected identifier, found keyword
help: you can escape reserved keywords to use them as identifiers
|
LL | let r#unsafe = "foo";
| ^^^^^^^^
error: aborting due to previous error error: aborting due to previous error

View File

@ -1,5 +1,5 @@
// This file was auto-generated using 'src/etc/generate-keyword-tests.py use' // This file was auto-generated using 'src/etc/generate-keyword-tests.py use'
fn main() { fn main() {
let use = "foo"; //~ error: expected pattern, found keyword `use` let use = "foo"; //~ error: expected identifier, found keyword `use`
} }

View File

@ -1,8 +1,12 @@
error: expected pattern, found keyword `use` error: expected identifier, found keyword `use`
--> $DIR/keyword-use-as-identifier.rs:4:9 --> $DIR/keyword-use-as-identifier.rs:4:9
| |
LL | let use = "foo"; LL | let use = "foo";
| ^^^ expected pattern | ^^^ expected identifier, found keyword
help: you can escape reserved keywords to use them as identifiers
|
LL | let r#use = "foo";
| ^^^^^
error: aborting due to previous error error: aborting due to previous error

View File

@ -1,5 +1,5 @@
// This file was auto-generated using 'src/etc/generate-keyword-tests.py where' // This file was auto-generated using 'src/etc/generate-keyword-tests.py where'
fn main() { fn main() {
let where = "foo"; //~ error: expected pattern, found keyword `where` let where = "foo"; //~ error: expected identifier, found keyword `where`
} }

View File

@ -1,8 +1,12 @@
error: expected pattern, found keyword `where` error: expected identifier, found keyword `where`
--> $DIR/keyword-where-as-identifier.rs:4:9 --> $DIR/keyword-where-as-identifier.rs:4:9
| |
LL | let where = "foo"; LL | let where = "foo";
| ^^^^^ expected pattern | ^^^^^ expected identifier, found keyword
help: you can escape reserved keywords to use them as identifiers
|
LL | let r#where = "foo";
| ^^^^^^^
error: aborting due to previous error error: aborting due to previous error

View File

@ -1,5 +1,5 @@
// This file was auto-generated using 'src/etc/generate-keyword-tests.py while' // This file was auto-generated using 'src/etc/generate-keyword-tests.py while'
fn main() { fn main() {
let while = "foo"; //~ error: expected pattern, found keyword `while` let while = "foo"; //~ error: expected identifier, found keyword `while`
} }

View File

@ -1,8 +1,12 @@
error: expected pattern, found keyword `while` error: expected identifier, found keyword `while`
--> $DIR/keyword-while-as-identifier.rs:4:9 --> $DIR/keyword-while-as-identifier.rs:4:9
| |
LL | let while = "foo"; LL | let while = "foo";
| ^^^^^ expected pattern | ^^^^^ expected identifier, found keyword
help: you can escape reserved keywords to use them as identifiers
|
LL | let r#while = "foo";
| ^^^^^^^
error: aborting due to previous error error: aborting due to previous error

View File

@ -1,7 +1,35 @@
// Can't put mut in non-ident pattern // Can't put mut in non-ident pattern
// edition:2018
#![feature(box_patterns)]
#![allow(warnings)]
pub fn main() { pub fn main() {
let mut mut x = 0;
//~^ ERROR `mut` on a binding may not be repeated
//~| remove the additional `mut`s
struct Foo { x: isize } struct Foo { x: isize }
let mut Foo { x: x } = Foo { x: 3 }; let mut Foo { x: x } = Foo { x: 3 };
//~^ ERROR: expected one of `:`, `;`, `=`, `@`, or `|`, found `{` //~^ ERROR `mut` must be attached to each individual binding
//~| add `mut` to each binding
let mut Foo { x } = Foo { x: 3 };
//~^ ERROR `mut` must be attached to each individual binding
//~| add `mut` to each binding
struct r#yield(u8, u8);
let mut mut yield(become, await) = r#yield(0, 0);
//~^ ERROR `mut` on a binding may not be repeated
//~| ERROR `mut` must be attached to each individual binding
//~| ERROR expected identifier, found reserved keyword `yield`
//~| ERROR expected identifier, found reserved keyword `become`
//~| ERROR expected identifier, found reserved keyword `await`
struct W<T, U>(T, U);
struct B { f: Box<u8> }
let mut W(mut a, W(b, W(ref c, W(d, B { box f }))))
//~^ ERROR `mut` must be attached to each individual binding
= W(0, W(1, W(2, W(3, B { f: Box::new(4u8) }))));
} }

View File

@ -1,8 +1,68 @@
error: expected one of `:`, `;`, `=`, `@`, or `|`, found `{` error: `mut` on a binding may not be repeated
--> $DIR/mut-patterns.rs:5:17 --> $DIR/mut-patterns.rs:9:13
|
LL | let mut mut x = 0;
| ^^^ help: remove the additional `mut`s
error: `mut` must be attached to each individual binding
--> $DIR/mut-patterns.rs:14:9
| |
LL | let mut Foo { x: x } = Foo { x: 3 }; LL | let mut Foo { x: x } = Foo { x: 3 };
| ^ expected one of `:`, `;`, `=`, `@`, or `|` here | ^^^^^^^^^^^^^^^^ help: add `mut` to each binding: `Foo { x: mut x }`
error: aborting due to previous error error: `mut` must be attached to each individual binding
--> $DIR/mut-patterns.rs:18:9
|
LL | let mut Foo { x } = Foo { x: 3 };
| ^^^^^^^^^^^^^ help: add `mut` to each binding: `Foo { mut x }`
error: `mut` on a binding may not be repeated
--> $DIR/mut-patterns.rs:23:13
|
LL | let mut mut yield(become, await) = r#yield(0, 0);
| ^^^ help: remove the additional `mut`s
error: expected identifier, found reserved keyword `yield`
--> $DIR/mut-patterns.rs:23:17
|
LL | let mut mut yield(become, await) = r#yield(0, 0);
| ^^^^^ expected identifier, found reserved keyword
help: you can escape reserved keywords to use them as identifiers
|
LL | let mut mut r#yield(become, await) = r#yield(0, 0);
| ^^^^^^^
error: expected identifier, found reserved keyword `become`
--> $DIR/mut-patterns.rs:23:23
|
LL | let mut mut yield(become, await) = r#yield(0, 0);
| ^^^^^^ expected identifier, found reserved keyword
help: you can escape reserved keywords to use them as identifiers
|
LL | let mut mut yield(r#become, await) = r#yield(0, 0);
| ^^^^^^^^
error: expected identifier, found reserved keyword `await`
--> $DIR/mut-patterns.rs:23:31
|
LL | let mut mut yield(become, await) = r#yield(0, 0);
| ^^^^^ expected identifier, found reserved keyword
help: you can escape reserved keywords to use them as identifiers
|
LL | let mut mut yield(become, r#await) = r#yield(0, 0);
| ^^^^^^^
error: `mut` must be attached to each individual binding
--> $DIR/mut-patterns.rs:23:9
|
LL | let mut mut yield(become, await) = r#yield(0, 0);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: add `mut` to each binding: `r#yield(mut r#become, mut r#await)`
error: `mut` must be attached to each individual binding
--> $DIR/mut-patterns.rs:32:9
|
LL | let mut W(mut a, W(b, W(ref c, W(d, B { box f }))))
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: add `mut` to each binding: `W(mut a, W(mut b, W(ref c, W(mut d, B { box mut f }))))`
error: aborting due to 9 previous errors

View File

@ -1,4 +1,4 @@
fn main() { fn main() {
let become = 0; let become = 0;
//~^ ERROR expected pattern, found reserved keyword `become` //~^ ERROR expected identifier, found reserved keyword `become`
} }

View File

@ -1,8 +1,12 @@
error: expected pattern, found reserved keyword `become` error: expected identifier, found reserved keyword `become`
--> $DIR/reserved-become.rs:2:9 --> $DIR/reserved-become.rs:2:9
| |
LL | let become = 0; LL | let become = 0;
| ^^^^^^ expected pattern | ^^^^^^ expected identifier, found reserved keyword
help: you can escape reserved keywords to use them as identifiers
|
LL | let r#become = 0;
| ^^^^^^^^
error: aborting due to previous error error: aborting due to previous error

View File

@ -14,7 +14,8 @@ pub fn main() {
ref Self => (), ref Self => (),
//~^ ERROR expected identifier, found keyword `Self` //~^ ERROR expected identifier, found keyword `Self`
mut Self => (), mut Self => (),
//~^ ERROR expected identifier, found keyword `Self` //~^ ERROR `mut` must be attached to each individual binding
//~| ERROR cannot find unit struct/variant or constant `Self`
ref mut Self => (), ref mut Self => (),
//~^ ERROR expected identifier, found keyword `Self` //~^ ERROR expected identifier, found keyword `Self`
Self!() => (), Self!() => (),

View File

@ -10,38 +10,38 @@ error: expected identifier, found keyword `Self`
LL | ref Self => (), LL | ref Self => (),
| ^^^^ expected identifier, found keyword | ^^^^ expected identifier, found keyword
error: expected identifier, found keyword `Self` error: `mut` must be attached to each individual binding
--> $DIR/self_type_keyword.rs:16:13 --> $DIR/self_type_keyword.rs:16:9
| |
LL | mut Self => (), LL | mut Self => (),
| ^^^^ expected identifier, found keyword | ^^^^^^^^ help: add `mut` to each binding: `Self`
error: expected identifier, found keyword `Self` error: expected identifier, found keyword `Self`
--> $DIR/self_type_keyword.rs:18:17 --> $DIR/self_type_keyword.rs:19:17
| |
LL | ref mut Self => (), LL | ref mut Self => (),
| ^^^^ expected identifier, found keyword | ^^^^ expected identifier, found keyword
error: expected identifier, found keyword `Self` error: expected identifier, found keyword `Self`
--> $DIR/self_type_keyword.rs:22:15 --> $DIR/self_type_keyword.rs:23:15
| |
LL | Foo { Self } => (), LL | Foo { Self } => (),
| ^^^^ expected identifier, found keyword | ^^^^ expected identifier, found keyword
error: expected identifier, found keyword `Self` error: expected identifier, found keyword `Self`
--> $DIR/self_type_keyword.rs:28:26 --> $DIR/self_type_keyword.rs:29:26
| |
LL | extern crate core as Self; LL | extern crate core as Self;
| ^^^^ expected identifier, found keyword | ^^^^ expected identifier, found keyword
error: expected identifier, found keyword `Self` error: expected identifier, found keyword `Self`
--> $DIR/self_type_keyword.rs:33:32 --> $DIR/self_type_keyword.rs:34:32
| |
LL | use std::option::Option as Self; LL | use std::option::Option as Self;
| ^^^^ expected identifier, found keyword | ^^^^ expected identifier, found keyword
error: expected identifier, found keyword `Self` error: expected identifier, found keyword `Self`
--> $DIR/self_type_keyword.rs:38:11 --> $DIR/self_type_keyword.rs:39:11
| |
LL | trait Self {} LL | trait Self {}
| ^^^^ expected identifier, found keyword | ^^^^ expected identifier, found keyword
@ -53,11 +53,21 @@ LL | struct Bar<'Self>;
| ^^^^^ | ^^^^^
error: cannot find macro `Self!` in this scope error: cannot find macro `Self!` in this scope
--> $DIR/self_type_keyword.rs:20:9 --> $DIR/self_type_keyword.rs:21:9
| |
LL | Self!() => (), LL | Self!() => (),
| ^^^^ | ^^^^
error[E0531]: cannot find unit struct/variant or constant `Self` in this scope
--> $DIR/self_type_keyword.rs:16:13
|
LL | mut Self => (),
| ^^^^ not found in this scope
help: possible candidate is found in another module, you can import it into scope
|
LL | use foo::Self;
|
error[E0392]: parameter `'Self` is never used error[E0392]: parameter `'Self` is never used
--> $DIR/self_type_keyword.rs:6:12 --> $DIR/self_type_keyword.rs:6:12
| |
@ -66,6 +76,6 @@ LL | struct Bar<'Self>;
| |
= help: consider removing `'Self` or using a marker such as `std::marker::PhantomData` = help: consider removing `'Self` or using a marker such as `std::marker::PhantomData`
error: aborting due to 11 previous errors error: aborting due to 12 previous errors
For more information about this error, try `rustc --explain E0392`. For more information about this error, try `rustc --explain E0392`.