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};
};
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
///
/// 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.
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;
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
//
+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");
}
}
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");
}
}
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");
}
}
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");
}
}
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() {
-}
-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: `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: 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: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[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 6 previous errors
+error: aborting due to 9 previous errors
+For more information about this error, try `rustc --explain E0308`.