mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-23 07:14:28 +00:00
implement recovery in check_assoc_op
This commit is contained in:
parent
903c9dfd18
commit
52acaa6974
@ -11,7 +11,7 @@ use syntax::ptr::P;
|
||||
use syntax::ThinVec;
|
||||
use syntax::util::parser::AssocOp;
|
||||
use syntax::struct_span_err;
|
||||
use syntax_pos::symbol::{kw, sym};
|
||||
use syntax_pos::symbol::kw;
|
||||
use syntax_pos::{Span, DUMMY_SP, MultiSpan, SpanSnippetError};
|
||||
|
||||
use log::{debug, trace};
|
||||
@ -312,22 +312,6 @@ impl<'a> Parser<'a> {
|
||||
};
|
||||
self.last_unexpected_token_span = Some(self.token.span);
|
||||
let mut err = self.fatal(&msg_exp);
|
||||
if self.token.is_ident_named(sym::and) {
|
||||
err.span_suggestion_short(
|
||||
self.token.span,
|
||||
"use `&&` instead of `and` for the boolean operator",
|
||||
"&&".to_string(),
|
||||
Applicability::MaybeIncorrect,
|
||||
);
|
||||
}
|
||||
if self.token.is_ident_named(sym::or) {
|
||||
err.span_suggestion_short(
|
||||
self.token.span,
|
||||
"use `||` instead of `or` for the boolean operator",
|
||||
"||".to_string(),
|
||||
Applicability::MaybeIncorrect,
|
||||
);
|
||||
}
|
||||
let sp = if self.token == token::Eof {
|
||||
// This is EOF; don't want to point at the following char, but rather the last token.
|
||||
self.prev_span
|
||||
|
@ -345,7 +345,31 @@ impl<'a> Parser<'a> {
|
||||
///
|
||||
/// Also performs recovery for `and` / `or` which are mistaken for `&&` and `||` respectively.
|
||||
fn check_assoc_op(&self) -> Option<AssocOp> {
|
||||
AssocOp::from_token(&self.token)
|
||||
match (AssocOp::from_token(&self.token), &self.token.kind) {
|
||||
(op @ Some(_), _) => op,
|
||||
(None, token::Ident(sym::and, false)) => {
|
||||
self.error_bad_logical_op("and", "&&", "conjunction");
|
||||
Some(AssocOp::LAnd)
|
||||
}
|
||||
(None, token::Ident(sym::or, false)) => {
|
||||
self.error_bad_logical_op("or", "||", "disjunction");
|
||||
Some(AssocOp::LOr)
|
||||
}
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
||||
/// Error on `and` and `or` suggesting `&&` and `||` respectively.
|
||||
fn error_bad_logical_op(&self, bad: &str, good: &str, english: &str) {
|
||||
self.struct_span_err(self.token.span, &format!("`{}` is not a logical operator", bad))
|
||||
.span_suggestion(
|
||||
self.token.span,
|
||||
&format!("instead of `{}`, use `{}` to perform logical {}", bad, good, english),
|
||||
good.to_string(),
|
||||
Applicability::MachineApplicable,
|
||||
)
|
||||
.note("unlike in e.g., python and PHP, `&&` and `||` are used for logical operators")
|
||||
.emit();
|
||||
}
|
||||
|
||||
/// Checks if this expression is a successfully parsed statement.
|
||||
|
@ -15,7 +15,7 @@ use syntax::ast::{Attribute, AttrStyle, VisibilityKind, MacStmtStyle, Mac};
|
||||
use syntax::util::classify;
|
||||
use syntax::token;
|
||||
use syntax_pos::source_map::{respan, Span};
|
||||
use syntax_pos::symbol::{kw, sym};
|
||||
use syntax_pos::symbol::kw;
|
||||
|
||||
use std::mem;
|
||||
|
||||
@ -301,25 +301,7 @@ impl<'a> Parser<'a> {
|
||||
let sp = self.token.span;
|
||||
let tok = self.this_token_descr();
|
||||
let mut e = self.span_fatal(sp, &format!("expected `{{`, found {}", tok));
|
||||
let do_not_suggest_help =
|
||||
self.token.is_keyword(kw::In) || self.token == token::Colon;
|
||||
|
||||
if self.token.is_ident_named(sym::and) {
|
||||
e.span_suggestion_short(
|
||||
self.token.span,
|
||||
"use `&&` instead of `and` for the boolean operator",
|
||||
"&&".to_string(),
|
||||
Applicability::MaybeIncorrect,
|
||||
);
|
||||
}
|
||||
if self.token.is_ident_named(sym::or) {
|
||||
e.span_suggestion_short(
|
||||
self.token.span,
|
||||
"use `||` instead of `or` for the boolean operator",
|
||||
"||".to_string(),
|
||||
Applicability::MaybeIncorrect,
|
||||
);
|
||||
}
|
||||
let do_not_suggest_help = self.token.is_keyword(kw::In) || self.token == token::Colon;
|
||||
|
||||
// Check to see if the user has written something like
|
||||
//
|
||||
|
@ -1,17 +1,25 @@
|
||||
fn main() {}
|
||||
|
||||
fn test_and() {
|
||||
let a = true;
|
||||
let b = false;
|
||||
if a and b {
|
||||
//~^ ERROR expected `{`, found `and`
|
||||
|
||||
let _ = a and b; //~ ERROR `and` is not a logical operator
|
||||
|
||||
if a and b { //~ ERROR `and` is not a logical operator
|
||||
println!("both");
|
||||
}
|
||||
|
||||
let _recovery_witness: () = 0; //~ ERROR mismatched types
|
||||
}
|
||||
|
||||
fn test_or() {
|
||||
let a = true;
|
||||
let b = false;
|
||||
if a or b {
|
||||
//~^ ERROR expected `{`, found `or`
|
||||
|
||||
let _ = a or b; //~ ERROR `or` is not a logical operator
|
||||
|
||||
if a or b { //~ ERROR `or` is not a logical operator
|
||||
println!("both");
|
||||
}
|
||||
}
|
||||
@ -19,8 +27,7 @@ fn test_or() {
|
||||
fn test_and_par() {
|
||||
let a = true;
|
||||
let b = false;
|
||||
if (a and b) {
|
||||
//~^ ERROR expected one of `!`, `)`, `,`, `.`, `::`, `?`, `{`, or an operator, found `and`
|
||||
if (a and b) { //~ ERROR `and` is not a logical operator
|
||||
println!("both");
|
||||
}
|
||||
}
|
||||
@ -28,8 +35,7 @@ fn test_and_par() {
|
||||
fn test_or_par() {
|
||||
let a = true;
|
||||
let b = false;
|
||||
if (a or b) {
|
||||
//~^ ERROR expected one of `!`, `)`, `,`, `.`, `::`, `?`, `{`, or an operator, found `or`
|
||||
if (a or b) { //~ ERROR `or` is not a logical operator
|
||||
println!("both");
|
||||
}
|
||||
}
|
||||
@ -37,8 +43,7 @@ fn test_or_par() {
|
||||
fn test_while_and() {
|
||||
let a = true;
|
||||
let b = false;
|
||||
while a and b {
|
||||
//~^ ERROR expected one of `!`, `.`, `::`, `?`, `{`, or an operator, found `and`
|
||||
while a and b { //~ ERROR `and` is not a logical operator
|
||||
println!("both");
|
||||
}
|
||||
}
|
||||
@ -46,11 +51,7 @@ fn test_while_and() {
|
||||
fn test_while_or() {
|
||||
let a = true;
|
||||
let b = false;
|
||||
while a or b {
|
||||
//~^ ERROR expected one of `!`, `.`, `::`, `?`, `{`, or an operator, found `or`
|
||||
while a or b { //~ ERROR `or` is not a logical operator
|
||||
println!("both");
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {
|
||||
}
|
||||
|
@ -1,58 +1,75 @@
|
||||
error: expected `{`, found `and`
|
||||
--> $DIR/issue-54109-and_instead_of_ampersands.rs:4:10
|
||||
error: `and` is not a logical operator
|
||||
--> $DIR/issue-54109-and_instead_of_ampersands.rs:7:15
|
||||
|
|
||||
LL | let _ = a and b;
|
||||
| ^^^ help: instead of `and`, use `&&` to perform logical conjunction: `&&`
|
||||
|
|
||||
= note: unlike in e.g., python and PHP, `&&` and `||` are used for logical operators
|
||||
|
||||
error: `and` is not a logical operator
|
||||
--> $DIR/issue-54109-and_instead_of_ampersands.rs:9:10
|
||||
|
|
||||
LL | if a and b {
|
||||
| -- ^^^
|
||||
| | |
|
||||
| | expected `{`
|
||||
| | help: use `&&` instead of `and` for the boolean operator
|
||||
| this `if` statement has a condition, but no block
|
||||
| ^^^ help: instead of `and`, use `&&` to perform logical conjunction: `&&`
|
||||
|
|
||||
= note: unlike in e.g., python and PHP, `&&` and `||` are used for logical operators
|
||||
|
||||
error: expected `{`, found `or`
|
||||
--> $DIR/issue-54109-and_instead_of_ampersands.rs:13:10
|
||||
error: `or` is not a logical operator
|
||||
--> $DIR/issue-54109-and_instead_of_ampersands.rs:20:15
|
||||
|
|
||||
LL | let _ = a or b;
|
||||
| ^^ help: instead of `or`, use `||` to perform logical disjunction: `||`
|
||||
|
|
||||
= note: unlike in e.g., python and PHP, `&&` and `||` are used for logical operators
|
||||
|
||||
error: `or` is not a logical operator
|
||||
--> $DIR/issue-54109-and_instead_of_ampersands.rs:22:10
|
||||
|
|
||||
LL | if a or b {
|
||||
| -- ^^
|
||||
| | |
|
||||
| | expected `{`
|
||||
| | help: use `||` instead of `or` for the boolean operator
|
||||
| this `if` statement has a condition, but no block
|
||||
| ^^ help: instead of `or`, use `||` to perform logical disjunction: `||`
|
||||
|
|
||||
= note: unlike in e.g., python and PHP, `&&` and `||` are used for logical operators
|
||||
|
||||
error: expected one of `!`, `)`, `,`, `.`, `::`, `?`, `{`, or an operator, found `and`
|
||||
--> $DIR/issue-54109-and_instead_of_ampersands.rs:22:11
|
||||
error: `and` is not a logical operator
|
||||
--> $DIR/issue-54109-and_instead_of_ampersands.rs:30:11
|
||||
|
|
||||
LL | if (a and b) {
|
||||
| ^^^
|
||||
| |
|
||||
| expected one of 8 possible tokens
|
||||
| help: use `&&` instead of `and` for the boolean operator
|
||||
| ^^^ help: instead of `and`, use `&&` to perform logical conjunction: `&&`
|
||||
|
|
||||
= note: unlike in e.g., python and PHP, `&&` and `||` are used for logical operators
|
||||
|
||||
error: expected one of `!`, `)`, `,`, `.`, `::`, `?`, `{`, or an operator, found `or`
|
||||
--> $DIR/issue-54109-and_instead_of_ampersands.rs:31:11
|
||||
error: `or` is not a logical operator
|
||||
--> $DIR/issue-54109-and_instead_of_ampersands.rs:38:11
|
||||
|
|
||||
LL | if (a or b) {
|
||||
| ^^
|
||||
| |
|
||||
| expected one of 8 possible tokens
|
||||
| help: use `||` instead of `or` for the boolean operator
|
||||
| ^^ help: instead of `or`, use `||` to perform logical disjunction: `||`
|
||||
|
|
||||
= note: unlike in e.g., python and PHP, `&&` and `||` are used for logical operators
|
||||
|
||||
error: expected one of `!`, `.`, `::`, `?`, `{`, or an operator, found `and`
|
||||
--> $DIR/issue-54109-and_instead_of_ampersands.rs:40:13
|
||||
error: `and` is not a logical operator
|
||||
--> $DIR/issue-54109-and_instead_of_ampersands.rs:46:13
|
||||
|
|
||||
LL | while a and b {
|
||||
| ^^^
|
||||
| |
|
||||
| expected one of `!`, `.`, `::`, `?`, `{`, or an operator
|
||||
| help: use `&&` instead of `and` for the boolean operator
|
||||
| ^^^ help: instead of `and`, use `&&` to perform logical conjunction: `&&`
|
||||
|
|
||||
= note: unlike in e.g., python and PHP, `&&` and `||` are used for logical operators
|
||||
|
||||
error: expected one of `!`, `.`, `::`, `?`, `{`, or an operator, found `or`
|
||||
--> $DIR/issue-54109-and_instead_of_ampersands.rs:49:13
|
||||
error: `or` is not a logical operator
|
||||
--> $DIR/issue-54109-and_instead_of_ampersands.rs:54:13
|
||||
|
|
||||
LL | while a or b {
|
||||
| ^^
|
||||
| |
|
||||
| expected one of `!`, `.`, `::`, `?`, `{`, or an operator
|
||||
| help: use `||` instead of `or` for the boolean operator
|
||||
| ^^ help: instead of `or`, use `||` to perform logical disjunction: `||`
|
||||
|
|
||||
= note: unlike in e.g., python and PHP, `&&` and `||` are used for logical operators
|
||||
|
||||
error: aborting due to 6 previous errors
|
||||
error[E0308]: mismatched types
|
||||
--> $DIR/issue-54109-and_instead_of_ampersands.rs:13:33
|
||||
|
|
||||
LL | let _recovery_witness: () = 0;
|
||||
| -- ^ expected `()`, found integer
|
||||
| |
|
||||
| expected due to this
|
||||
|
||||
error: aborting due to 9 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0308`.
|
||||
|
Loading…
Reference in New Issue
Block a user