Skip to content

Recover mut $pat and other improvements #63945

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 5 commits into from
Aug 29, 2019
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions src/libsyntax/parse/literal.rs
Original file line number Diff line number Diff line change
@@ -104,7 +104,7 @@ impl LitKind {

Ok(match kind {
token::Bool => {
assert!(symbol == kw::True || symbol == kw::False);
assert!(symbol.is_bool_lit());
LitKind::Bool(symbol == kw::True)
}
token::Byte => return unescape_byte(&symbol.as_str())
@@ -261,7 +261,7 @@ impl Lit {
/// Converts arbitrary token into an AST literal.
crate fn from_token(token: &Token) -> Result<Lit, LitError> {
let lit = match token.kind {
token::Ident(name, false) if name == kw::True || name == kw::False =>
token::Ident(name, false) if name.is_bool_lit() =>
token::Lit::new(token::Bool, name, None),
token::Literal(lit) =>
lit,
155 changes: 126 additions & 29 deletions src/libsyntax/parse/parser/pat.rs
Original file line number Diff line number Diff line change
@@ -4,6 +4,7 @@ use crate::{maybe_recover_from_interpolated_ty_qpath, maybe_whole};
use crate::ptr::P;
use crate::ast::{self, Attribute, Pat, PatKind, FieldPat, RangeEnd, RangeSyntax, Mac};
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::print::pprust;
use crate::source_map::{respan, Span, Spanned};
@@ -273,21 +274,20 @@ impl<'a> Parser<'a> {
// Parse _
PatKind::Wild
} 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) {
// Parse ref ident @ pat / ref mut ident @ pat
let mutbl = self.parse_mutability();
self.parse_pat_ident(BindingMode::ByRef(mutbl))?
} else if self.eat_keyword(kw::Box) {
// Parse `box pat`
PatKind::Box(self.parse_pat_with_range_pat(false, None)?)
} else if self.token.is_ident() && !self.token.is_reserved_ident() &&
self.parse_as_ident() {
} else if self.can_be_ident_pat() {
// Parse `ident @ pat`
// This can give false positives and parse nullary enums,
// they are dealt with later in resolve.
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
let (qself, path) = if self.eat_lt() {
// Parse a qualified path
@@ -384,24 +384,108 @@ impl<'a> Parser<'a> {
})
}

/// Parse a mutable binding with the `mut` token already eaten.
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();

// Make sure we don't allow e.g. `let mut $p;` where `$p:pat`.
if let token::Interpolated(ref nt) = self.token.kind {
if let token::NtPat(_) = **nt {
self.expected_ident_found().emit();
}
}

// Parse the pattern we hope to be an identifier.
let mut pat = self.parse_pat(Some("identifier"))?;

// Add `mut` to any binding in the parsed pattern.
let changed_any_binding = Self::make_all_value_bindings_mutable(&mut pat);

// Unwrap; If we don't have `mut $ident`, error.
let pat = pat.into_inner();
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We could avoid this allocation by extracting a new function fn parse_pat_with_range_pat_kind. This would also avoid the need for the NtPat logic above but it would also not recover on let mut $p where $p:pat.

match &pat.node {
PatKind::Ident(..) => {}
_ => self.ban_mut_general_pat(mut_span, &pat, changed_any_binding),
}

Ok(pat.node)
}

/// Recover on `mut ref? ident @ pat` and suggest
/// that the order of `mut` and `ref` is incorrect.
fn recover_pat_ident_mut_first(&mut self) -> PResult<'a, PatKind> {
let mutref_span = self.prev_span.to(self.token.span);
let binding_mode = if self.eat_keyword(kw::Ref) {
self.struct_span_err(mutref_span, "the order of `mut` and `ref` is incorrect")
.span_suggestion(
mutref_span,
"try switching the order",
"ref mut".into(),
Applicability::MachineApplicable
)
.emit();
BindingMode::ByRef(Mutability::Mutable)
fn recover_mut_ref_ident(&mut self, lo: Span) -> PResult<'a, PatKind> {
let mutref_span = lo.to(self.prev_span);
self.struct_span_err(mutref_span, "the order of `mut` and `ref` is incorrect")
.span_suggestion(
mutref_span,
"try switching the order",
"ref mut".into(),
Applicability::MachineApplicable
)
.emit();

self.parse_pat_ident(BindingMode::ByRef(Mutability::Mutable))
}

/// Turn all by-value immutable bindings in a pattern into mutable bindings.
/// Returns `true` if any change was made.
fn make_all_value_bindings_mutable(pat: &mut P<Pat>) -> bool {
struct AddMut(bool);
impl MutVisitor for AddMut {
fn visit_pat(&mut self, pat: &mut P<Pat>) {
if let PatKind::Ident(BindingMode::ByValue(ref mut m @ Mutability::Immutable), ..)
= pat.node
{
*m = Mutability::Mutable;
self.0 = true;
}
noop_visit_pat(pat, self);
}
}

let mut add_mut = AddMut(false);
add_mut.visit_pat(pat);
add_mut.0
}

/// Error on `mut $pat` where `$pat` is not an ident.
fn ban_mut_general_pat(&self, lo: Span, pat: &Pat, changed_any_binding: bool) {
let span = lo.to(pat.span);
let fix = pprust::pat_to_string(&pat);
let (problem, suggestion) = if changed_any_binding {
("`mut` must be attached to each individual binding", "add `mut` to each binding")
} else {
BindingMode::ByValue(Mutability::Mutable)
("`mut` must be followed by a named binding", "remove the `mut` prefix")
};
self.parse_pat_ident(binding_mode)
self.struct_span_err(span, problem)
.span_suggestion(span, suggestion, fix, Applicability::MachineApplicable)
.note("`mut` may be followed by `variable` and `variable @ pattern`")
.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
@@ -479,17 +563,6 @@ impl<'a> Parser<'a> {
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?
fn is_pat_range_end_start(&self) -> bool {
self.token.is_path_start() // e.g. `MY_CONST`;
@@ -563,6 +636,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)
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looking at this made me realize that we should have some check for "expected Fn() -> _, found bool and expr is foo\n|| bar" to detect a missing ; on the first pattern and returning a closure was intended 😬

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What would be a concrete example of a pitfall here? I'd like to avoid complicating things until someone reports a an issue.


/// 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`.
/// Used by the copy foo and ref foo patterns to give a good
/// error message when parsing mistakes like `ref foo(a, b)`.
2 changes: 1 addition & 1 deletion src/libsyntax/parse/parser/path.rs
Original file line number Diff line number Diff line change
@@ -423,7 +423,7 @@ impl<'a> Parser<'a> {
// FIXME(const_generics): to distinguish between idents for types and consts,
// we should introduce a GenericArg::Ident in the AST and distinguish when
// lowering to the HIR. For now, idents for const args are not permitted.
if self.token.is_keyword(kw::True) || self.token.is_keyword(kw::False) {
if self.token.is_bool_lit() {
self.parse_literal_maybe_minus()?
} else {
return Err(
43 changes: 20 additions & 23 deletions src/libsyntax/parse/token.rs
Original file line number Diff line number Diff line change
@@ -409,18 +409,16 @@ impl Token {
crate fn expect_lit(&self) -> Lit {
match self.kind {
Literal(lit) => lit,
_=> panic!("`expect_lit` called on non-literal"),
_ => panic!("`expect_lit` called on non-literal"),
}
}

/// Returns `true` if the token is any literal, a minus (which can prefix a literal,
/// for example a '-42', or one of the boolean idents).
crate fn can_begin_literal_or_bool(&self) -> bool {
match self.kind {
Literal(..) => true,
BinOp(Minus) => true,
Ident(name, false) if name == kw::True => true,
Ident(name, false) if name == kw::False => true,
Literal(..) | BinOp(Minus) => true,
Ident(name, false) if name.is_bool_lit() => true,
Interpolated(ref nt) => match **nt {
NtLiteral(..) => true,
_ => false,
@@ -457,6 +455,7 @@ impl Token {
pub fn is_ident(&self) -> bool {
self.ident().is_some()
}

/// Returns `true` if the token is a lifetime.
crate fn is_lifetime(&self) -> bool {
self.lifetime().is_some()
@@ -508,45 +507,43 @@ impl Token {

/// Returns `true` if the token is a given keyword, `kw`.
pub fn is_keyword(&self, kw: Symbol) -> bool {
self.ident().map(|(id, is_raw)| id.name == kw && !is_raw).unwrap_or(false)
self.is_non_raw_ident_where(|id| id.name == kw)
}

crate fn is_path_segment_keyword(&self) -> bool {
match self.ident() {
Some((id, false)) => id.is_path_segment_keyword(),
_ => false,
}
self.is_non_raw_ident_where(ast::Ident::is_path_segment_keyword)
}

// Returns true for reserved identifiers used internally for elided lifetimes,
// unnamed method parameters, crate root module, error recovery etc.
crate fn is_special_ident(&self) -> bool {
match self.ident() {
Some((id, false)) => id.is_special(),
_ => false,
}
self.is_non_raw_ident_where(ast::Ident::is_special)
}

/// Returns `true` if the token is a keyword used in the language.
crate fn is_used_keyword(&self) -> bool {
match self.ident() {
Some((id, false)) => id.is_used_keyword(),
_ => false,
}
self.is_non_raw_ident_where(ast::Ident::is_used_keyword)
}

/// Returns `true` if the token is a keyword reserved for possible future use.
crate fn is_unused_keyword(&self) -> bool {
match self.ident() {
Some((id, false)) => id.is_unused_keyword(),
_ => false,
}
self.is_non_raw_ident_where(ast::Ident::is_unused_keyword)
}

/// Returns `true` if the token is either a special identifier or a keyword.
pub fn is_reserved_ident(&self) -> bool {
self.is_non_raw_ident_where(ast::Ident::is_reserved)
}

/// Returns `true` if the token is the identifier `true` or `false`.
crate fn is_bool_lit(&self) -> bool {
self.is_non_raw_ident_where(|id| id.name.is_bool_lit())
}

/// Returns `true` if the token is a non-raw identifier for which `pred` holds.
fn is_non_raw_ident_where(&self, pred: impl FnOnce(ast::Ident) -> bool) -> bool {
match self.ident() {
Some((id, false)) => id.is_reserved(),
Some((id, false)) => pred(id),
_ => false,
}
}
5 changes: 5 additions & 0 deletions src/libsyntax_pos/symbol.rs
Original file line number Diff line number Diff line change
@@ -1063,6 +1063,11 @@ impl Symbol {
self == kw::DollarCrate
}

/// Returns `true` if the symbol is `true` or `false`.
pub fn is_bool_lit(self) -> bool {
self == kw::True || self == kw::False
}

/// This symbol can be a raw identifier.
pub fn can_be_raw(self) -> bool {
self != kw::Invalid && self != kw::Underscore && !self.is_path_segment_keyword()
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
fn main() {
let extern = 0; //~ ERROR expected pattern, found keyword `extern`
let extern = 0; //~ ERROR expected identifier, found keyword `extern`
}
Original file line number Diff line number Diff line change
@@ -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
|
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

3 changes: 2 additions & 1 deletion src/test/ui/parser/issue-32501.rs
Original file line number Diff line number Diff line change
@@ -4,5 +4,6 @@ fn main() {
let _ = 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 followed by a named binding
}
8 changes: 5 additions & 3 deletions src/test/ui/parser/issue-32501.stderr
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
error: expected identifier, found reserved identifier `_`
--> $DIR/issue-32501.rs:7:13
error: `mut` must be followed by a named binding
--> $DIR/issue-32501.rs:7:9
|
LL | let mut _ = 0;
| ^ expected identifier, found reserved identifier
| ^^^^^ help: remove the `mut` prefix: `_`
|
= note: `mut` may be followed by `variable` and `variable @ pattern`

error: aborting due to previous error

2 changes: 1 addition & 1 deletion src/test/ui/parser/keyword-abstract.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
fn main() {
let abstract = (); //~ ERROR expected pattern, found reserved keyword `abstract`
let abstract = (); //~ ERROR expected identifier, found reserved keyword `abstract`
}
8 changes: 6 additions & 2 deletions src/test/ui/parser/keyword-abstract.stderr
Original file line number Diff line number Diff line change
@@ -1,8 +1,12 @@
error: expected pattern, found reserved keyword `abstract`
error: expected identifier, found reserved keyword `abstract`
--> $DIR/keyword-abstract.rs:2:9
|
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

2 changes: 1 addition & 1 deletion src/test/ui/parser/keyword-as-as-identifier.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// This file was auto-generated using 'src/etc/generate-keyword-tests.py as'

fn main() {
let as = "foo"; //~ error: expected pattern, found keyword `as`
let as = "foo"; //~ error: expected identifier, found keyword `as`
}
8 changes: 6 additions & 2 deletions src/test/ui/parser/keyword-as-as-identifier.stderr
Original file line number Diff line number Diff line change
@@ -1,8 +1,12 @@
error: expected pattern, found keyword `as`
error: expected identifier, found keyword `as`
--> $DIR/keyword-as-as-identifier.rs:4:9
|
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

2 changes: 1 addition & 1 deletion src/test/ui/parser/keyword-break-as-identifier.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// This file was auto-generated using 'src/etc/generate-keyword-tests.py break'

fn main() {
let break = "foo"; //~ error: expected pattern, found keyword `break`
let break = "foo"; //~ error: expected identifier, found keyword `break`
}
8 changes: 6 additions & 2 deletions src/test/ui/parser/keyword-break-as-identifier.stderr
Original file line number Diff line number Diff line change
@@ -1,8 +1,12 @@
error: expected pattern, found keyword `break`
error: expected identifier, found keyword `break`
--> $DIR/keyword-break-as-identifier.rs:4:9
|
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

2 changes: 1 addition & 1 deletion src/test/ui/parser/keyword-const-as-identifier.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// This file was auto-generated using 'src/etc/generate-keyword-tests.py const'

fn main() {
let const = "foo"; //~ error: expected pattern, found keyword `const`
let const = "foo"; //~ error: expected identifier, found keyword `const`
}
8 changes: 6 additions & 2 deletions src/test/ui/parser/keyword-const-as-identifier.stderr
Original file line number Diff line number Diff line change
@@ -1,8 +1,12 @@
error: expected pattern, found keyword `const`
error: expected identifier, found keyword `const`
--> $DIR/keyword-const-as-identifier.rs:4:9
|
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

2 changes: 1 addition & 1 deletion src/test/ui/parser/keyword-continue-as-identifier.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// This file was auto-generated using 'src/etc/generate-keyword-tests.py continue'

fn main() {
let continue = "foo"; //~ error: expected pattern, found keyword `continue`
let continue = "foo"; //~ error: expected identifier, found keyword `continue`
}
8 changes: 6 additions & 2 deletions src/test/ui/parser/keyword-continue-as-identifier.stderr
Original file line number Diff line number Diff line change
@@ -1,8 +1,12 @@
error: expected pattern, found keyword `continue`
error: expected identifier, found keyword `continue`
--> $DIR/keyword-continue-as-identifier.rs:4:9
|
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

2 changes: 1 addition & 1 deletion src/test/ui/parser/keyword-else-as-identifier.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// This file was auto-generated using 'src/etc/generate-keyword-tests.py else'

fn main() {
let else = "foo"; //~ error: expected pattern, found keyword `else`
let else = "foo"; //~ error: expected identifier, found keyword `else`
}
8 changes: 6 additions & 2 deletions src/test/ui/parser/keyword-else-as-identifier.stderr
Original file line number Diff line number Diff line change
@@ -1,8 +1,12 @@
error: expected pattern, found keyword `else`
error: expected identifier, found keyword `else`
--> $DIR/keyword-else-as-identifier.rs:4:9
|
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

2 changes: 1 addition & 1 deletion src/test/ui/parser/keyword-enum-as-identifier.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// This file was auto-generated using 'src/etc/generate-keyword-tests.py enum'

fn main() {
let enum = "foo"; //~ error: expected pattern, found keyword `enum`
let enum = "foo"; //~ error: expected identifier, found keyword `enum`
}
8 changes: 6 additions & 2 deletions src/test/ui/parser/keyword-enum-as-identifier.stderr
Original file line number Diff line number Diff line change
@@ -1,8 +1,12 @@
error: expected pattern, found keyword `enum`
error: expected identifier, found keyword `enum`
--> $DIR/keyword-enum-as-identifier.rs:4:9
|
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

2 changes: 1 addition & 1 deletion src/test/ui/parser/keyword-final.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
fn main() {
let final = (); //~ ERROR expected pattern, found reserved keyword `final`
let final = (); //~ ERROR expected identifier, found reserved keyword `final`
}
8 changes: 6 additions & 2 deletions src/test/ui/parser/keyword-final.stderr
Original file line number Diff line number Diff line change
@@ -1,8 +1,12 @@
error: expected pattern, found reserved keyword `final`
error: expected identifier, found reserved keyword `final`
--> $DIR/keyword-final.rs:2:9
|
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

2 changes: 1 addition & 1 deletion src/test/ui/parser/keyword-fn-as-identifier.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// This file was auto-generated using 'src/etc/generate-keyword-tests.py fn'

fn main() {
let fn = "foo"; //~ error: expected pattern, found keyword `fn`
let fn = "foo"; //~ error: expected identifier, found keyword `fn`
}
8 changes: 6 additions & 2 deletions src/test/ui/parser/keyword-fn-as-identifier.stderr
Original file line number Diff line number Diff line change
@@ -1,8 +1,12 @@
error: expected pattern, found keyword `fn`
error: expected identifier, found keyword `fn`
--> $DIR/keyword-fn-as-identifier.rs:4:9
|
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

2 changes: 1 addition & 1 deletion src/test/ui/parser/keyword-for-as-identifier.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// This file was auto-generated using 'src/etc/generate-keyword-tests.py for'

fn main() {
let for = "foo"; //~ error: expected pattern, found keyword `for`
let for = "foo"; //~ error: expected identifier, found keyword `for`
}
8 changes: 6 additions & 2 deletions src/test/ui/parser/keyword-for-as-identifier.stderr
Original file line number Diff line number Diff line change
@@ -1,8 +1,12 @@
error: expected pattern, found keyword `for`
error: expected identifier, found keyword `for`
--> $DIR/keyword-for-as-identifier.rs:4:9
|
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

2 changes: 1 addition & 1 deletion src/test/ui/parser/keyword-if-as-identifier.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// This file was auto-generated using 'src/etc/generate-keyword-tests.py if'

fn main() {
let if = "foo"; //~ error: expected pattern, found keyword `if`
let if = "foo"; //~ error: expected identifier, found keyword `if`
}
8 changes: 6 additions & 2 deletions src/test/ui/parser/keyword-if-as-identifier.stderr
Original file line number Diff line number Diff line change
@@ -1,8 +1,12 @@
error: expected pattern, found keyword `if`
error: expected identifier, found keyword `if`
--> $DIR/keyword-if-as-identifier.rs:4:9
|
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

2 changes: 1 addition & 1 deletion src/test/ui/parser/keyword-impl-as-identifier.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// This file was auto-generated using 'src/etc/generate-keyword-tests.py impl'

fn main() {
let impl = "foo"; //~ error: expected pattern, found keyword `impl`
let impl = "foo"; //~ error: expected identifier, found keyword `impl`
}
8 changes: 6 additions & 2 deletions src/test/ui/parser/keyword-impl-as-identifier.stderr
Original file line number Diff line number Diff line change
@@ -1,8 +1,12 @@
error: expected pattern, found keyword `impl`
error: expected identifier, found keyword `impl`
--> $DIR/keyword-impl-as-identifier.rs:4:9
|
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

2 changes: 1 addition & 1 deletion src/test/ui/parser/keyword-let-as-identifier.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// This file was auto-generated using 'src/etc/generate-keyword-tests.py let'

fn main() {
let let = "foo"; //~ error: expected pattern, found keyword `let`
let let = "foo"; //~ error: expected identifier, found keyword `let`
}
8 changes: 6 additions & 2 deletions src/test/ui/parser/keyword-let-as-identifier.stderr
Original file line number Diff line number Diff line change
@@ -1,8 +1,12 @@
error: expected pattern, found keyword `let`
error: expected identifier, found keyword `let`
--> $DIR/keyword-let-as-identifier.rs:4:9
|
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

2 changes: 1 addition & 1 deletion src/test/ui/parser/keyword-loop-as-identifier.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// This file was auto-generated using 'src/etc/generate-keyword-tests.py loop'

fn main() {
let loop = "foo"; //~ error: expected pattern, found keyword `loop`
let loop = "foo"; //~ error: expected identifier, found keyword `loop`
}
8 changes: 6 additions & 2 deletions src/test/ui/parser/keyword-loop-as-identifier.stderr
Original file line number Diff line number Diff line change
@@ -1,8 +1,12 @@
error: expected pattern, found keyword `loop`
error: expected identifier, found keyword `loop`
--> $DIR/keyword-loop-as-identifier.rs:4:9
|
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

2 changes: 1 addition & 1 deletion src/test/ui/parser/keyword-match-as-identifier.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// This file was auto-generated using 'src/etc/generate-keyword-tests.py match'

fn main() {
let match = "foo"; //~ error: expected pattern, found keyword `match`
let match = "foo"; //~ error: expected identifier, found keyword `match`
}
8 changes: 6 additions & 2 deletions src/test/ui/parser/keyword-match-as-identifier.stderr
Original file line number Diff line number Diff line change
@@ -1,8 +1,12 @@
error: expected pattern, found keyword `match`
error: expected identifier, found keyword `match`
--> $DIR/keyword-match-as-identifier.rs:4:9
|
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

2 changes: 1 addition & 1 deletion src/test/ui/parser/keyword-mod-as-identifier.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// This file was auto-generated using 'src/etc/generate-keyword-tests.py mod'

fn main() {
let mod = "foo"; //~ error: expected pattern, found keyword `mod`
let mod = "foo"; //~ error: expected identifier, found keyword `mod`
}
8 changes: 6 additions & 2 deletions src/test/ui/parser/keyword-mod-as-identifier.stderr
Original file line number Diff line number Diff line change
@@ -1,8 +1,12 @@
error: expected pattern, found keyword `mod`
error: expected identifier, found keyword `mod`
--> $DIR/keyword-mod-as-identifier.rs:4:9
|
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

2 changes: 1 addition & 1 deletion src/test/ui/parser/keyword-move-as-identifier.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// This file was auto-generated using 'src/etc/generate-keyword-tests.py move'

fn main() {
let move = "foo"; //~ error: expected pattern, found keyword `move`
let move = "foo"; //~ error: expected identifier, found keyword `move`
}
8 changes: 6 additions & 2 deletions src/test/ui/parser/keyword-move-as-identifier.stderr
Original file line number Diff line number Diff line change
@@ -1,8 +1,12 @@
error: expected pattern, found keyword `move`
error: expected identifier, found keyword `move`
--> $DIR/keyword-move-as-identifier.rs:4:9
|
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

2 changes: 1 addition & 1 deletion src/test/ui/parser/keyword-override.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
fn main() {
let override = (); //~ ERROR expected pattern, found reserved keyword `override`
let override = (); //~ ERROR expected identifier, found reserved keyword `override`
}
8 changes: 6 additions & 2 deletions src/test/ui/parser/keyword-override.stderr
Original file line number Diff line number Diff line change
@@ -1,8 +1,12 @@
error: expected pattern, found reserved keyword `override`
error: expected identifier, found reserved keyword `override`
--> $DIR/keyword-override.rs:2:9
|
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

2 changes: 1 addition & 1 deletion src/test/ui/parser/keyword-pub-as-identifier.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// This file was auto-generated using 'src/etc/generate-keyword-tests.py pub'

fn main() {
let pub = "foo"; //~ error: expected pattern, found keyword `pub`
let pub = "foo"; //~ error: expected identifier, found keyword `pub`
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think all of these tests could be one file, don't you think? (not to be addressed in this PR necessarily)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Want to file a follow up issue?

}
8 changes: 6 additions & 2 deletions src/test/ui/parser/keyword-pub-as-identifier.stderr
Original file line number Diff line number Diff line change
@@ -1,8 +1,12 @@
error: expected pattern, found keyword `pub`
error: expected identifier, found keyword `pub`
--> $DIR/keyword-pub-as-identifier.rs:4:9
|
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

2 changes: 1 addition & 1 deletion src/test/ui/parser/keyword-return-as-identifier.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// This file was auto-generated using 'src/etc/generate-keyword-tests.py return'

fn main() {
let return = "foo"; //~ error: expected pattern, found keyword `return`
let return = "foo"; //~ error: expected identifier, found keyword `return`
}
8 changes: 6 additions & 2 deletions src/test/ui/parser/keyword-return-as-identifier.stderr
Original file line number Diff line number Diff line change
@@ -1,8 +1,12 @@
error: expected pattern, found keyword `return`
error: expected identifier, found keyword `return`
--> $DIR/keyword-return-as-identifier.rs:4:9
|
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

2 changes: 1 addition & 1 deletion src/test/ui/parser/keyword-static-as-identifier.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// This file was auto-generated using 'src/etc/generate-keyword-tests.py static'

fn main() {
let static = "foo"; //~ error: expected pattern, found keyword `static`
let static = "foo"; //~ error: expected identifier, found keyword `static`
}
8 changes: 6 additions & 2 deletions src/test/ui/parser/keyword-static-as-identifier.stderr
Original file line number Diff line number Diff line change
@@ -1,8 +1,12 @@
error: expected pattern, found keyword `static`
error: expected identifier, found keyword `static`
--> $DIR/keyword-static-as-identifier.rs:4:9
|
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

2 changes: 1 addition & 1 deletion src/test/ui/parser/keyword-struct-as-identifier.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// This file was auto-generated using 'src/etc/generate-keyword-tests.py struct'

fn main() {
let struct = "foo"; //~ error: expected pattern, found keyword `struct`
let struct = "foo"; //~ error: expected identifier, found keyword `struct`
}
8 changes: 6 additions & 2 deletions src/test/ui/parser/keyword-struct-as-identifier.stderr
Original file line number Diff line number Diff line change
@@ -1,8 +1,12 @@
error: expected pattern, found keyword `struct`
error: expected identifier, found keyword `struct`
--> $DIR/keyword-struct-as-identifier.rs:4:9
|
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

2 changes: 1 addition & 1 deletion src/test/ui/parser/keyword-trait-as-identifier.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// This file was auto-generated using 'src/etc/generate-keyword-tests.py trait'

fn main() {
let trait = "foo"; //~ error: expected pattern, found keyword `trait`
let trait = "foo"; //~ error: expected identifier, found keyword `trait`
}
8 changes: 6 additions & 2 deletions src/test/ui/parser/keyword-trait-as-identifier.stderr
Original file line number Diff line number Diff line change
@@ -1,8 +1,12 @@
error: expected pattern, found keyword `trait`
error: expected identifier, found keyword `trait`
--> $DIR/keyword-trait-as-identifier.rs:4:9
|
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

Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// compile-flags: --edition 2018

fn main() {
let try = "foo"; //~ error: expected pattern, found reserved keyword `try`
let try = "foo"; //~ error: expected identifier, found reserved keyword `try`
}
Original file line number Diff line number Diff line change
@@ -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
|
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

2 changes: 1 addition & 1 deletion src/test/ui/parser/keyword-type-as-identifier.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// This file was auto-generated using 'src/etc/generate-keyword-tests.py type'

fn main() {
let type = "foo"; //~ error: expected pattern, found keyword `type`
let type = "foo"; //~ error: expected identifier, found keyword `type`
}
8 changes: 6 additions & 2 deletions src/test/ui/parser/keyword-type-as-identifier.stderr
Original file line number Diff line number Diff line change
@@ -1,8 +1,12 @@
error: expected pattern, found keyword `type`
error: expected identifier, found keyword `type`
--> $DIR/keyword-type-as-identifier.rs:4:9
|
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

2 changes: 1 addition & 1 deletion src/test/ui/parser/keyword-typeof.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
fn main() {
let typeof = (); //~ ERROR expected pattern, found reserved keyword `typeof`
let typeof = (); //~ ERROR expected identifier, found reserved keyword `typeof`
}
8 changes: 6 additions & 2 deletions src/test/ui/parser/keyword-typeof.stderr
Original file line number Diff line number Diff line change
@@ -1,8 +1,12 @@
error: expected pattern, found reserved keyword `typeof`
error: expected identifier, found reserved keyword `typeof`
--> $DIR/keyword-typeof.rs:2:9
|
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

2 changes: 1 addition & 1 deletion src/test/ui/parser/keyword-unsafe-as-identifier.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// This file was auto-generated using 'src/etc/generate-keyword-tests.py unsafe'

fn main() {
let unsafe = "foo"; //~ error: expected pattern, found keyword `unsafe`
let unsafe = "foo"; //~ error: expected identifier, found keyword `unsafe`
}
8 changes: 6 additions & 2 deletions src/test/ui/parser/keyword-unsafe-as-identifier.stderr
Original file line number Diff line number Diff line change
@@ -1,8 +1,12 @@
error: expected pattern, found keyword `unsafe`
error: expected identifier, found keyword `unsafe`
--> $DIR/keyword-unsafe-as-identifier.rs:4:9
|
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

2 changes: 1 addition & 1 deletion src/test/ui/parser/keyword-use-as-identifier.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// This file was auto-generated using 'src/etc/generate-keyword-tests.py use'

fn main() {
let use = "foo"; //~ error: expected pattern, found keyword `use`
let use = "foo"; //~ error: expected identifier, found keyword `use`
}
8 changes: 6 additions & 2 deletions src/test/ui/parser/keyword-use-as-identifier.stderr
Original file line number Diff line number Diff line change
@@ -1,8 +1,12 @@
error: expected pattern, found keyword `use`
error: expected identifier, found keyword `use`
--> $DIR/keyword-use-as-identifier.rs:4:9
|
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

2 changes: 1 addition & 1 deletion src/test/ui/parser/keyword-where-as-identifier.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// This file was auto-generated using 'src/etc/generate-keyword-tests.py where'

fn main() {
let where = "foo"; //~ error: expected pattern, found keyword `where`
let where = "foo"; //~ error: expected identifier, found keyword `where`
}
8 changes: 6 additions & 2 deletions src/test/ui/parser/keyword-where-as-identifier.stderr
Original file line number Diff line number Diff line change
@@ -1,8 +1,12 @@
error: expected pattern, found keyword `where`
error: expected identifier, found keyword `where`
--> $DIR/keyword-where-as-identifier.rs:4:9
|
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

2 changes: 1 addition & 1 deletion src/test/ui/parser/keyword-while-as-identifier.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// This file was auto-generated using 'src/etc/generate-keyword-tests.py while'

fn main() {
let while = "foo"; //~ error: expected pattern, found keyword `while`
let while = "foo"; //~ error: expected identifier, found keyword `while`
}
8 changes: 6 additions & 2 deletions src/test/ui/parser/keyword-while-as-identifier.stderr
Original file line number Diff line number Diff line change
@@ -1,8 +1,12 @@
error: expected pattern, found keyword `while`
error: expected identifier, found keyword `while`
--> $DIR/keyword-while-as-identifier.rs:4:9
|
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

41 changes: 40 additions & 1 deletion src/test/ui/parser/mut-patterns.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,46 @@
// Can't put mut in non-ident pattern

// edition:2018

#![feature(box_patterns)]
#![allow(warnings)]

pub fn main() {
let mut _ = 0; //~ ERROR `mut` must be followed by a named binding
let mut (_, _) = (0, 0); //~ ERROR `mut` must be followed by a named binding

let mut mut x = 0;
//~^ ERROR `mut` on a binding may not be repeated
//~| remove the additional `mut`s

struct Foo { x: isize }
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) }))));

// Make sure we don't accidentally allow `mut $p` where `$p:pat`.
macro_rules! foo {
($p:pat) => {
let mut $p = 0; //~ ERROR expected identifier, found `x`
}
}
foo!(x);
}
101 changes: 97 additions & 4 deletions src/test/ui/parser/mut-patterns.stderr
Original file line number Diff line number Diff line change
@@ -1,8 +1,101 @@
error: expected one of `:`, `;`, `=`, `@`, or `|`, found `{`
--> $DIR/mut-patterns.rs:5:17
error: `mut` must be followed by a named binding
--> $DIR/mut-patterns.rs:9:9
|
LL | let mut _ = 0;
| ^^^^^ help: remove the `mut` prefix: `_`
|
= note: `mut` may be followed by `variable` and `variable @ pattern`

error: `mut` must be followed by a named binding
--> $DIR/mut-patterns.rs:10:9
|
LL | let mut (_, _) = (0, 0);
| ^^^^^^^^^^ help: remove the `mut` prefix: `(_, _)`
|
= note: `mut` may be followed by `variable` and `variable @ pattern`

error: `mut` on a binding may not be repeated
--> $DIR/mut-patterns.rs:12: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:17:9
|
LL | let mut Foo { x: x } = Foo { x: 3 };
| ^ expected one of `:`, `;`, `=`, `@`, or `|` here
| ^^^^^^^^^^^^^^^^ help: add `mut` to each binding: `Foo { x: mut x }`
|
= note: `mut` may be followed by `variable` and `variable @ pattern`

error: `mut` must be attached to each individual binding
--> $DIR/mut-patterns.rs:21:9
|
LL | let mut Foo { x } = Foo { x: 3 };
| ^^^^^^^^^^^^^ help: add `mut` to each binding: `Foo { mut x }`
|
= note: `mut` may be followed by `variable` and `variable @ pattern`

error: `mut` on a binding may not be repeated
--> $DIR/mut-patterns.rs:26: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:26: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:26: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:26: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:26: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)`
|
= note: `mut` may be followed by `variable` and `variable @ pattern`

error: `mut` must be attached to each individual binding
--> $DIR/mut-patterns.rs:35: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 }))))`
|
= note: `mut` may be followed by `variable` and `variable @ pattern`

error: expected identifier, found `x`
--> $DIR/mut-patterns.rs:42:21
|
LL | let mut $p = 0;
| ^^ expected identifier
...
LL | foo!(x);
| -------- in this macro invocation

error: aborting due to previous error
error: aborting due to 12 previous errors

2 changes: 1 addition & 1 deletion src/test/ui/reserved/reserved-become.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
fn main() {
let become = 0;
//~^ ERROR expected pattern, found reserved keyword `become`
//~^ ERROR expected identifier, found reserved keyword `become`
}
8 changes: 6 additions & 2 deletions src/test/ui/reserved/reserved-become.stderr
Original file line number Diff line number Diff line change
@@ -1,8 +1,12 @@
error: expected pattern, found reserved keyword `become`
error: expected identifier, found reserved keyword `become`
--> $DIR/reserved-become.rs:2:9
|
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

3 changes: 2 additions & 1 deletion src/test/ui/self/self_type_keyword.rs
Original file line number Diff line number Diff line change
@@ -14,7 +14,8 @@ pub fn main() {
ref Self => (),
//~^ ERROR expected identifier, found keyword `Self`
mut Self => (),
//~^ ERROR expected identifier, found keyword `Self`
//~^ ERROR `mut` must be followed by a named binding
//~| ERROR cannot find unit struct/variant or constant `Self`
ref mut Self => (),
//~^ ERROR expected identifier, found keyword `Self`
Self!() => (),
32 changes: 22 additions & 10 deletions src/test/ui/self/self_type_keyword.stderr
Original file line number Diff line number Diff line change
@@ -10,38 +10,40 @@ error: expected identifier, found keyword `Self`
LL | ref Self => (),
| ^^^^ expected identifier, found keyword

error: expected identifier, found keyword `Self`
--> $DIR/self_type_keyword.rs:16:13
error: `mut` must be followed by a named binding
--> $DIR/self_type_keyword.rs:16:9
|
LL | mut Self => (),
| ^^^^ expected identifier, found keyword
| ^^^^^^^^ help: remove the `mut` prefix: `Self`
|
= note: `mut` may be followed by `variable` and `variable @ pattern`

error: expected identifier, found keyword `Self`
--> $DIR/self_type_keyword.rs:18:17
--> $DIR/self_type_keyword.rs:19:17
|
LL | ref mut Self => (),
| ^^^^ expected identifier, found keyword

error: expected identifier, found keyword `Self`
--> $DIR/self_type_keyword.rs:22:15
--> $DIR/self_type_keyword.rs:23:15
|
LL | Foo { Self } => (),
| ^^^^ expected identifier, found keyword

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;
| ^^^^ expected identifier, found keyword

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;
| ^^^^ expected identifier, found keyword

error: expected identifier, found keyword `Self`
--> $DIR/self_type_keyword.rs:38:11
--> $DIR/self_type_keyword.rs:39:11
|
LL | trait Self {}
| ^^^^ expected identifier, found keyword
@@ -53,11 +55,21 @@ LL | struct Bar<'Self>;
| ^^^^^

error: cannot find macro `Self!` in this scope
--> $DIR/self_type_keyword.rs:20:9
--> $DIR/self_type_keyword.rs:21:9
|
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
--> $DIR/self_type_keyword.rs:6:12
|
@@ -66,6 +78,6 @@ LL | struct Bar<'Self>;
|
= 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`.