From 636f518aac7430406dcb410cd7e46b4a217c265c Mon Sep 17 00:00:00 2001 From: Vitaly _Vi Shukela Date: Thu, 13 Sep 2018 15:54:12 +0300 Subject: [PATCH 1/5] Suggest && and || instead of 'and' and 'or' Closes #54109. --- src/libsyntax/parse/parser.rs | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index f57fca2cfcf60..a28157106ba7d 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -732,6 +732,12 @@ impl<'a> Parser<'a> { format!("expected {} here", expect))) }; let mut err = self.fatal(&msg_exp); + if self.token.is_ident_named("and") { + err.help("Use `&&` instead of `and` for the boolean operator"); + } + if self.token.is_ident_named("or") { + err.help("Use `||` instead of `or` for the boolean operator"); + } let sp = if self.token == token::Token::Eof { // This is EOF, don't want to point at the following char, but rather the last token self.prev_span @@ -4751,6 +4757,13 @@ impl<'a> Parser<'a> { e.span_label(sp, "expected `{`"); } + if self.token.is_ident_named("and") { + e.help("Use `&&` instead of `and` for the boolean operator"); + } + if self.token.is_ident_named("or") { + e.help("Use `||` instead of `or` for the boolean operator"); + } + // Check to see if the user has written something like // // if (cond) From 888b8c9451a41cccc8bdceee6423ee9d9e66bb43 Mon Sep 17 00:00:00 2001 From: Vitaly _Vi Shukela Date: Thu, 13 Sep 2018 15:54:25 +0300 Subject: [PATCH 2/5] Add tests for issue 54109 --- .../issue-54109-and_instead_of_ampersands.rs | 48 +++++++++++++++++++ ...sue-54109-and_instead_of_ampersands.stderr | 38 +++++++++++++++ 2 files changed, 86 insertions(+) create mode 100644 src/test/ui/did_you_mean/issue-54109-and_instead_of_ampersands.rs create mode 100644 src/test/ui/did_you_mean/issue-54109-and_instead_of_ampersands.stderr diff --git a/src/test/ui/did_you_mean/issue-54109-and_instead_of_ampersands.rs b/src/test/ui/did_you_mean/issue-54109-and_instead_of_ampersands.rs new file mode 100644 index 0000000000000..cb37845529407 --- /dev/null +++ b/src/test/ui/did_you_mean/issue-54109-and_instead_of_ampersands.rs @@ -0,0 +1,48 @@ +// Copyright 2018 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +fn test_and() { + let a = true; + let b = false; + if a and b { + //~^ ERROR expected `{`, found `and` + println!("both"); + } +} + +fn test_or() { + let a = true; + let b = false; + if a or b { + //~^ ERROR expected `{`, found `or` + 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` + 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` + println!("both"); + } +} + +fn main() { +} diff --git a/src/test/ui/did_you_mean/issue-54109-and_instead_of_ampersands.stderr b/src/test/ui/did_you_mean/issue-54109-and_instead_of_ampersands.stderr new file mode 100644 index 0000000000000..9d53cc237e291 --- /dev/null +++ b/src/test/ui/did_you_mean/issue-54109-and_instead_of_ampersands.stderr @@ -0,0 +1,38 @@ +error: expected `{`, found `and` + --> $DIR/issue-54109-and_instead_of_ampersands.rs:14:10 + | +LL | if a and b { + | -- ^^^ + | | + | this `if` statement has a condition, but no block + | + = help: Use `&&` instead of `and` for the boolean operator + +error: expected `{`, found `or` + --> $DIR/issue-54109-and_instead_of_ampersands.rs:23:10 + | +LL | if a or b { + | -- ^^ + | | + | this `if` statement has a condition, but no block + | + = help: Use `||` instead of `or` for the boolean operator + +error: expected one of `!`, `)`, `,`, `.`, `::`, `?`, `{`, or an operator, found `and` + --> $DIR/issue-54109-and_instead_of_ampersands.rs:32:11 + | +LL | if (a and b) { + | ^^^ expected one of 8 possible tokens here + | + = help: Use `&&` instead of `and` for the boolean operator + +error: expected one of `!`, `)`, `,`, `.`, `::`, `?`, `{`, or an operator, found `or` + --> $DIR/issue-54109-and_instead_of_ampersands.rs:41:11 + | +LL | if (a or b) { + | ^^ expected one of 8 possible tokens here + | + = help: Use `||` instead of `or` for the boolean operator + +error: aborting due to 4 previous errors + From acc44e40ccd860a3cae54c7b56956c3c1340182e Mon Sep 17 00:00:00 2001 From: Vitaly _Vi Shukela Date: Thu, 13 Sep 2018 20:40:39 +0300 Subject: [PATCH 3/5] Use span_suggestion_with_applicability for "and/or" hinter Advised by @estebank. --- src/libsyntax/parse/parser.rs | 28 ++++++++++++++++--- ...sue-54109-and_instead_of_ampersands.stderr | 23 +++++++-------- 2 files changed, 34 insertions(+), 17 deletions(-) diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index a28157106ba7d..429d1b6bf5e8f 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -733,10 +733,20 @@ impl<'a> Parser<'a> { }; let mut err = self.fatal(&msg_exp); if self.token.is_ident_named("and") { - err.help("Use `&&` instead of `and` for the boolean operator"); + err.span_suggestion_with_applicability( + self.span, + "use `&&` instead of `and` for the boolean operator", + "&&".to_string(), + Applicability::MaybeIncorrect, + ); } if self.token.is_ident_named("or") { - err.help("Use `||` instead of `or` for the boolean operator"); + err.span_suggestion_with_applicability( + self.span, + "use `||` instead of `or` for the boolean operator", + "||".to_string(), + Applicability::MaybeIncorrect, + ); } let sp = if self.token == token::Token::Eof { // This is EOF, don't want to point at the following char, but rather the last token @@ -4758,10 +4768,20 @@ impl<'a> Parser<'a> { } if self.token.is_ident_named("and") { - e.help("Use `&&` instead of `and` for the boolean operator"); + e.span_suggestion_with_applicability( + self.span, + "use `&&` instead of `and` for the boolean operator", + "&&".to_string(), + Applicability::MaybeIncorrect, + ); } if self.token.is_ident_named("or") { - e.help("Use `||` instead of `or` for the boolean operator"); + e.span_suggestion_with_applicability( + self.span, + "use `||` instead of `or` for the boolean operator", + "||".to_string(), + Applicability::MaybeIncorrect, + ); } // Check to see if the user has written something like diff --git a/src/test/ui/did_you_mean/issue-54109-and_instead_of_ampersands.stderr b/src/test/ui/did_you_mean/issue-54109-and_instead_of_ampersands.stderr index 9d53cc237e291..74ebb1e757c96 100644 --- a/src/test/ui/did_you_mean/issue-54109-and_instead_of_ampersands.stderr +++ b/src/test/ui/did_you_mean/issue-54109-and_instead_of_ampersands.stderr @@ -2,37 +2,34 @@ error: expected `{`, found `and` --> $DIR/issue-54109-and_instead_of_ampersands.rs:14:10 | LL | if a and b { - | -- ^^^ + | -- ^^^ help: use `&&` instead of `and` for the boolean operator: `&&` | | | this `if` statement has a condition, but no block - | - = help: Use `&&` instead of `and` for the boolean operator error: expected `{`, found `or` --> $DIR/issue-54109-and_instead_of_ampersands.rs:23:10 | LL | if a or b { - | -- ^^ + | -- ^^ help: use `||` instead of `or` for the boolean operator: `||` | | | this `if` statement has a condition, but no block - | - = help: Use `||` instead of `or` for the boolean operator error: expected one of `!`, `)`, `,`, `.`, `::`, `?`, `{`, or an operator, found `and` --> $DIR/issue-54109-and_instead_of_ampersands.rs:32:11 | LL | if (a and b) { - | ^^^ expected one of 8 possible tokens here - | - = help: Use `&&` instead of `and` for the boolean operator + | ^^^ + | | + | expected one of 8 possible tokens here + | help: use `&&` instead of `and` for the boolean operator: `&&` error: expected one of `!`, `)`, `,`, `.`, `::`, `?`, `{`, or an operator, found `or` --> $DIR/issue-54109-and_instead_of_ampersands.rs:41:11 | LL | if (a or b) { - | ^^ expected one of 8 possible tokens here - | - = help: Use `||` instead of `or` for the boolean operator + | ^^ + | | + | expected one of 8 possible tokens here + | help: use `||` instead of `or` for the boolean operator: `||` error: aborting due to 4 previous errors - From 79919a7ed672fc77d0c6b8e5836b33af4598e280 Mon Sep 17 00:00:00 2001 From: Vitaly _Vi Shukela Date: Thu, 13 Sep 2018 20:51:29 +0300 Subject: [PATCH 4/5] Add "while" tests for issue 54109 --- .../issue-54109-and_instead_of_ampersands.rs | 18 ++++++++++++++++ ...sue-54109-and_instead_of_ampersands.stderr | 21 ++++++++++++++++++- 2 files changed, 38 insertions(+), 1 deletion(-) diff --git a/src/test/ui/did_you_mean/issue-54109-and_instead_of_ampersands.rs b/src/test/ui/did_you_mean/issue-54109-and_instead_of_ampersands.rs index cb37845529407..d053b11772cd0 100644 --- a/src/test/ui/did_you_mean/issue-54109-and_instead_of_ampersands.rs +++ b/src/test/ui/did_you_mean/issue-54109-and_instead_of_ampersands.rs @@ -44,5 +44,23 @@ 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` + 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` + println!("both"); + } +} + fn main() { } diff --git a/src/test/ui/did_you_mean/issue-54109-and_instead_of_ampersands.stderr b/src/test/ui/did_you_mean/issue-54109-and_instead_of_ampersands.stderr index 74ebb1e757c96..552619dd4beec 100644 --- a/src/test/ui/did_you_mean/issue-54109-and_instead_of_ampersands.stderr +++ b/src/test/ui/did_you_mean/issue-54109-and_instead_of_ampersands.stderr @@ -32,4 +32,23 @@ LL | if (a or b) { | expected one of 8 possible tokens here | help: use `||` instead of `or` for the boolean operator: `||` -error: aborting due to 4 previous errors +error: expected one of `!`, `.`, `::`, `?`, `{`, or an operator, found `and` + --> $DIR/issue-54109-and_instead_of_ampersands.rs:50:13 + | +LL | while a and b { + | ^^^ + | | + | expected one of `!`, `.`, `::`, `?`, `{`, or an operator here + | help: use `&&` instead of `and` for the boolean operator: `&&` + +error: expected one of `!`, `.`, `::`, `?`, `{`, or an operator, found `or` + --> $DIR/issue-54109-and_instead_of_ampersands.rs:59:13 + | +LL | while a or b { + | ^^ + | | + | expected one of `!`, `.`, `::`, `?`, `{`, or an operator here + | help: use `||` instead of `or` for the boolean operator: `||` + +error: aborting due to 6 previous errors + From bc63a4a13a442e1844bb5577adcc464c2a6bfd21 Mon Sep 17 00:00:00 2001 From: Vitaly _Vi Shukela Date: Sat, 15 Sep 2018 02:05:32 +0300 Subject: [PATCH 5/5] issue 54109: use short suggestions --- src/libsyntax/parse/parser.rs | 8 ++++---- .../issue-54109-and_instead_of_ampersands.stderr | 12 ++++++------ 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index 429d1b6bf5e8f..48e034b117f18 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -733,7 +733,7 @@ impl<'a> Parser<'a> { }; let mut err = self.fatal(&msg_exp); if self.token.is_ident_named("and") { - err.span_suggestion_with_applicability( + err.span_suggestion_short_with_applicability( self.span, "use `&&` instead of `and` for the boolean operator", "&&".to_string(), @@ -741,7 +741,7 @@ impl<'a> Parser<'a> { ); } if self.token.is_ident_named("or") { - err.span_suggestion_with_applicability( + err.span_suggestion_short_with_applicability( self.span, "use `||` instead of `or` for the boolean operator", "||".to_string(), @@ -4768,7 +4768,7 @@ impl<'a> Parser<'a> { } if self.token.is_ident_named("and") { - e.span_suggestion_with_applicability( + e.span_suggestion_short_with_applicability( self.span, "use `&&` instead of `and` for the boolean operator", "&&".to_string(), @@ -4776,7 +4776,7 @@ impl<'a> Parser<'a> { ); } if self.token.is_ident_named("or") { - e.span_suggestion_with_applicability( + e.span_suggestion_short_with_applicability( self.span, "use `||` instead of `or` for the boolean operator", "||".to_string(), diff --git a/src/test/ui/did_you_mean/issue-54109-and_instead_of_ampersands.stderr b/src/test/ui/did_you_mean/issue-54109-and_instead_of_ampersands.stderr index 552619dd4beec..22845775aed13 100644 --- a/src/test/ui/did_you_mean/issue-54109-and_instead_of_ampersands.stderr +++ b/src/test/ui/did_you_mean/issue-54109-and_instead_of_ampersands.stderr @@ -2,7 +2,7 @@ error: expected `{`, found `and` --> $DIR/issue-54109-and_instead_of_ampersands.rs:14:10 | LL | if a and b { - | -- ^^^ help: use `&&` instead of `and` for the boolean operator: `&&` + | -- ^^^ help: use `&&` instead of `and` for the boolean operator | | | this `if` statement has a condition, but no block @@ -10,7 +10,7 @@ error: expected `{`, found `or` --> $DIR/issue-54109-and_instead_of_ampersands.rs:23:10 | LL | if a or b { - | -- ^^ help: use `||` instead of `or` for the boolean operator: `||` + | -- ^^ help: use `||` instead of `or` for the boolean operator | | | this `if` statement has a condition, but no block @@ -21,7 +21,7 @@ LL | if (a and b) { | ^^^ | | | expected one of 8 possible tokens here - | help: use `&&` instead of `and` for the boolean operator: `&&` + | help: use `&&` instead of `and` for the boolean operator error: expected one of `!`, `)`, `,`, `.`, `::`, `?`, `{`, or an operator, found `or` --> $DIR/issue-54109-and_instead_of_ampersands.rs:41:11 @@ -30,7 +30,7 @@ LL | if (a or b) { | ^^ | | | expected one of 8 possible tokens here - | help: use `||` instead of `or` for the boolean operator: `||` + | help: use `||` instead of `or` for the boolean operator error: expected one of `!`, `.`, `::`, `?`, `{`, or an operator, found `and` --> $DIR/issue-54109-and_instead_of_ampersands.rs:50:13 @@ -39,7 +39,7 @@ LL | while a and b { | ^^^ | | | expected one of `!`, `.`, `::`, `?`, `{`, or an operator here - | help: use `&&` instead of `and` for the boolean operator: `&&` + | help: use `&&` instead of `and` for the boolean operator error: expected one of `!`, `.`, `::`, `?`, `{`, or an operator, found `or` --> $DIR/issue-54109-and_instead_of_ampersands.rs:59:13 @@ -48,7 +48,7 @@ LL | while a or b { | ^^ | | | expected one of `!`, `.`, `::`, `?`, `{`, or an operator here - | help: use `||` instead of `or` for the boolean operator: `||` + | help: use `||` instead of `or` for the boolean operator error: aborting due to 6 previous errors