From 2194fc957a2a7daaf35703603553649dfc23e34d Mon Sep 17 00:00:00 2001 From: yukang Date: Thu, 15 Sep 2022 17:33:28 +0800 Subject: [PATCH 1/3] fix 101793, fix the wording of help msg for bitwise not --- compiler/rustc_error_messages/locales/en-US/parser.ftl | 2 +- .../issue-41679-tilde-bitwise-negation-attempt.fixed | 1 + .../issue-41679-tilde-bitwise-negation-attempt.rs | 1 + .../issue-41679-tilde-bitwise-negation-attempt.stderr | 10 +++++++++- ...sue-46836-identifier-not-instead-of-negation.stderr | 10 +++++----- 5 files changed, 17 insertions(+), 7 deletions(-) diff --git a/compiler/rustc_error_messages/locales/en-US/parser.ftl b/compiler/rustc_error_messages/locales/en-US/parser.ftl index f74df3d9746ae..b4636eee256ef 100644 --- a/compiler/rustc_error_messages/locales/en-US/parser.ftl +++ b/compiler/rustc_error_messages/locales/en-US/parser.ftl @@ -55,7 +55,7 @@ parser_tilde_is_not_unary_operator = `~` cannot be used as a unary operator .suggestion = use `!` to perform bitwise not parser_unexpected_token_after_not = unexpected {$negated_desc} after identifier - .suggestion = use `!` to perform logical negation + .suggestion = use `!` to perform bitwise not parser_malformed_loop_label = malformed loop label .suggestion = use the correct loop label format diff --git a/src/test/ui/did_you_mean/issue-41679-tilde-bitwise-negation-attempt.fixed b/src/test/ui/did_you_mean/issue-41679-tilde-bitwise-negation-attempt.fixed index 87debfeceaaf3..1244b8827edac 100644 --- a/src/test/ui/did_you_mean/issue-41679-tilde-bitwise-negation-attempt.fixed +++ b/src/test/ui/did_you_mean/issue-41679-tilde-bitwise-negation-attempt.fixed @@ -2,4 +2,5 @@ fn main() { let _x = !1; //~ ERROR cannot be used as a unary operator + let _y = !1; //~ ERROR unexpected `1` after identifier } diff --git a/src/test/ui/did_you_mean/issue-41679-tilde-bitwise-negation-attempt.rs b/src/test/ui/did_you_mean/issue-41679-tilde-bitwise-negation-attempt.rs index 015a8edcea355..51cfaaa0ec1ce 100644 --- a/src/test/ui/did_you_mean/issue-41679-tilde-bitwise-negation-attempt.rs +++ b/src/test/ui/did_you_mean/issue-41679-tilde-bitwise-negation-attempt.rs @@ -2,4 +2,5 @@ fn main() { let _x = ~1; //~ ERROR cannot be used as a unary operator + let _y = not 1; //~ ERROR unexpected `1` after identifier } diff --git a/src/test/ui/did_you_mean/issue-41679-tilde-bitwise-negation-attempt.stderr b/src/test/ui/did_you_mean/issue-41679-tilde-bitwise-negation-attempt.stderr index 84b81d561e909..36a6adfa27a1a 100644 --- a/src/test/ui/did_you_mean/issue-41679-tilde-bitwise-negation-attempt.stderr +++ b/src/test/ui/did_you_mean/issue-41679-tilde-bitwise-negation-attempt.stderr @@ -4,5 +4,13 @@ error: `~` cannot be used as a unary operator LL | let _x = ~1; | ^ help: use `!` to perform bitwise not -error: aborting due to previous error +error: unexpected `1` after identifier + --> $DIR/issue-41679-tilde-bitwise-negation-attempt.rs:5:18 + | +LL | let _y = not 1; + | ----^ + | | + | help: use `!` to perform bitwise not + +error: aborting due to 2 previous errors diff --git a/src/test/ui/did_you_mean/issue-46836-identifier-not-instead-of-negation.stderr b/src/test/ui/did_you_mean/issue-46836-identifier-not-instead-of-negation.stderr index 3ccc14bba5422..6657d824cd7eb 100644 --- a/src/test/ui/did_you_mean/issue-46836-identifier-not-instead-of-negation.stderr +++ b/src/test/ui/did_you_mean/issue-46836-identifier-not-instead-of-negation.stderr @@ -4,7 +4,7 @@ error: unexpected `for_you` after identifier LL | if not for_you { | ----^^^^^^^ | | - | help: use `!` to perform logical negation + | help: use `!` to perform bitwise not error: unexpected `the_worst` after identifier --> $DIR/issue-46836-identifier-not-instead-of-negation.rs:11:15 @@ -12,13 +12,13 @@ error: unexpected `the_worst` after identifier LL | while not the_worst { | ----^^^^^^^^^ | | - | help: use `!` to perform logical negation + | help: use `!` to perform bitwise not error: unexpected `println` after identifier --> $DIR/issue-46836-identifier-not-instead-of-negation.rs:20:9 | LL | if not // lack of braces is [sic] - | ----- help: use `!` to perform logical negation + | ----- help: use `!` to perform bitwise not LL | println!("Then when?"); | ^^^^^^^ @@ -42,7 +42,7 @@ error: unexpected `2` after identifier LL | let resource = not 2; | ----^ | | - | help: use `!` to perform logical negation + | help: use `!` to perform bitwise not error: unexpected `be_smothered_out_before` after identifier --> $DIR/issue-46836-identifier-not-instead-of-negation.rs:32:27 @@ -50,7 +50,7 @@ error: unexpected `be_smothered_out_before` after identifier LL | let young_souls = not be_smothered_out_before; | ----^^^^^^^^^^^^^^^^^^^^^^^ | | - | help: use `!` to perform logical negation + | help: use `!` to perform bitwise not error: aborting due to 6 previous errors From f43562b95bb80d91cd3f880e1d63b129a65a9b44 Mon Sep 17 00:00:00 2001 From: yukang Date: Thu, 15 Sep 2022 22:39:16 +0800 Subject: [PATCH 2/3] more tweak on diagnostic messages --- .../locales/en-US/parser.ftl | 4 +-- .../rustc_parse/src/parser/diagnostics.rs | 1 + compiler/rustc_parse/src/parser/expr.rs | 9 +++++++ ...41679-tilde-bitwise-negation-attempt.fixed | 4 +++ ...ue-41679-tilde-bitwise-negation-attempt.rs | 4 +++ ...1679-tilde-bitwise-negation-attempt.stderr | 26 ++++++++++++++++++- ...-identifier-not-instead-of-negation.stderr | 8 +++--- ...sue-54109-and_instead_of_ampersands.stderr | 16 ++++++------ .../issue-54109-without-witness.stderr | 16 ++++++------ 9 files changed, 65 insertions(+), 23 deletions(-) diff --git a/compiler/rustc_error_messages/locales/en-US/parser.ftl b/compiler/rustc_error_messages/locales/en-US/parser.ftl index b4636eee256ef..7d56da70ff5af 100644 --- a/compiler/rustc_error_messages/locales/en-US/parser.ftl +++ b/compiler/rustc_error_messages/locales/en-US/parser.ftl @@ -47,7 +47,7 @@ parser_invalid_comparison_operator = invalid comparison operator `{$invalid}` .spaceship_operator_invalid = `<=>` is not a valid comparison operator, use `std::cmp::Ordering` parser_invalid_logical_operator = `{$incorrect}` is not a logical operator - .note = unlike in e.g., python and PHP, `&&` and `||` are used for logical operators + .note = unlike in e.g., Python and PHP, `&&` and `||` are used for logical operators .use_amp_amp_for_conjunction = use `&&` to perform logical conjunction .use_pipe_pipe_for_disjunction = use `||` to perform logical disjunction @@ -55,7 +55,7 @@ parser_tilde_is_not_unary_operator = `~` cannot be used as a unary operator .suggestion = use `!` to perform bitwise not parser_unexpected_token_after_not = unexpected {$negated_desc} after identifier - .suggestion = use `!` to perform bitwise not + .suggestion = use `!` to perform {$negated_msg} parser_malformed_loop_label = malformed loop label .suggestion = use the correct loop label format diff --git a/compiler/rustc_parse/src/parser/diagnostics.rs b/compiler/rustc_parse/src/parser/diagnostics.rs index be524db785bc0..d2a8daa150cd2 100644 --- a/compiler/rustc_parse/src/parser/diagnostics.rs +++ b/compiler/rustc_parse/src/parser/diagnostics.rs @@ -430,6 +430,7 @@ pub(crate) struct NotAsNegationOperator { #[primary_span] pub negated: Span, pub negated_desc: String, + pub negated_msg: String, #[suggestion_short(applicability = "machine-applicable", code = "!")] pub not: Span, } diff --git a/compiler/rustc_parse/src/parser/expr.rs b/compiler/rustc_parse/src/parser/expr.rs index ed37ede65d514..1fdd312572aa1 100644 --- a/compiler/rustc_parse/src/parser/expr.rs +++ b/compiler/rustc_parse/src/parser/expr.rs @@ -660,9 +660,18 @@ impl<'a> Parser<'a> { fn recover_not_expr(&mut self, lo: Span) -> PResult<'a, (Span, ExprKind)> { // Emit the error... let negated_token = self.look_ahead(1, |t| t.clone()); + let negtated_msg = if negated_token.is_numeric_lit() { + "bitwise not" + } else if negated_token.is_bool_lit() { + "logical negation" + } else { + "logical negation or bitwise not" + }; + self.sess.emit_err(NotAsNegationOperator { negated: negated_token.span, negated_desc: super::token_descr(&negated_token), + negated_msg: negtated_msg.to_string(), // Span the `not` plus trailing whitespace to avoid // trailing whitespace after the `!` in our suggestion not: self.sess.source_map().span_until_non_whitespace(lo.to(negated_token.span)), diff --git a/src/test/ui/did_you_mean/issue-41679-tilde-bitwise-negation-attempt.fixed b/src/test/ui/did_you_mean/issue-41679-tilde-bitwise-negation-attempt.fixed index 1244b8827edac..e566ed488c957 100644 --- a/src/test/ui/did_you_mean/issue-41679-tilde-bitwise-negation-attempt.fixed +++ b/src/test/ui/did_you_mean/issue-41679-tilde-bitwise-negation-attempt.fixed @@ -3,4 +3,8 @@ fn main() { let _x = !1; //~ ERROR cannot be used as a unary operator let _y = !1; //~ ERROR unexpected `1` after identifier + let _z = !false; //~ ERROR unexpected keyword `false` after identifier + let _a = !true; //~ ERROR unexpected keyword `true` after identifier + let v = 1 + 2; + let _v = !v; //~ ERROR unexpected `v` after identifier } diff --git a/src/test/ui/did_you_mean/issue-41679-tilde-bitwise-negation-attempt.rs b/src/test/ui/did_you_mean/issue-41679-tilde-bitwise-negation-attempt.rs index 51cfaaa0ec1ce..1708a80505dbd 100644 --- a/src/test/ui/did_you_mean/issue-41679-tilde-bitwise-negation-attempt.rs +++ b/src/test/ui/did_you_mean/issue-41679-tilde-bitwise-negation-attempt.rs @@ -3,4 +3,8 @@ fn main() { let _x = ~1; //~ ERROR cannot be used as a unary operator let _y = not 1; //~ ERROR unexpected `1` after identifier + let _z = not false; //~ ERROR unexpected keyword `false` after identifier + let _a = not true; //~ ERROR unexpected keyword `true` after identifier + let v = 1 + 2; + let _v = not v; //~ ERROR unexpected `v` after identifier } diff --git a/src/test/ui/did_you_mean/issue-41679-tilde-bitwise-negation-attempt.stderr b/src/test/ui/did_you_mean/issue-41679-tilde-bitwise-negation-attempt.stderr index 36a6adfa27a1a..2a3242abea49c 100644 --- a/src/test/ui/did_you_mean/issue-41679-tilde-bitwise-negation-attempt.stderr +++ b/src/test/ui/did_you_mean/issue-41679-tilde-bitwise-negation-attempt.stderr @@ -12,5 +12,29 @@ LL | let _y = not 1; | | | help: use `!` to perform bitwise not -error: aborting due to 2 previous errors +error: unexpected keyword `false` after identifier + --> $DIR/issue-41679-tilde-bitwise-negation-attempt.rs:6:18 + | +LL | let _z = not false; + | ----^^^^^ + | | + | help: use `!` to perform logical negation + +error: unexpected keyword `true` after identifier + --> $DIR/issue-41679-tilde-bitwise-negation-attempt.rs:7:18 + | +LL | let _a = not true; + | ----^^^^ + | | + | help: use `!` to perform logical negation + +error: unexpected `v` after identifier + --> $DIR/issue-41679-tilde-bitwise-negation-attempt.rs:9:18 + | +LL | let _v = not v; + | ----^ + | | + | help: use `!` to perform logical negation or bitwise not + +error: aborting due to 5 previous errors diff --git a/src/test/ui/did_you_mean/issue-46836-identifier-not-instead-of-negation.stderr b/src/test/ui/did_you_mean/issue-46836-identifier-not-instead-of-negation.stderr index 6657d824cd7eb..14918ba895325 100644 --- a/src/test/ui/did_you_mean/issue-46836-identifier-not-instead-of-negation.stderr +++ b/src/test/ui/did_you_mean/issue-46836-identifier-not-instead-of-negation.stderr @@ -4,7 +4,7 @@ error: unexpected `for_you` after identifier LL | if not for_you { | ----^^^^^^^ | | - | help: use `!` to perform bitwise not + | help: use `!` to perform logical negation or bitwise not error: unexpected `the_worst` after identifier --> $DIR/issue-46836-identifier-not-instead-of-negation.rs:11:15 @@ -12,13 +12,13 @@ error: unexpected `the_worst` after identifier LL | while not the_worst { | ----^^^^^^^^^ | | - | help: use `!` to perform bitwise not + | help: use `!` to perform logical negation or bitwise not error: unexpected `println` after identifier --> $DIR/issue-46836-identifier-not-instead-of-negation.rs:20:9 | LL | if not // lack of braces is [sic] - | ----- help: use `!` to perform bitwise not + | ----- help: use `!` to perform logical negation or bitwise not LL | println!("Then when?"); | ^^^^^^^ @@ -50,7 +50,7 @@ error: unexpected `be_smothered_out_before` after identifier LL | let young_souls = not be_smothered_out_before; | ----^^^^^^^^^^^^^^^^^^^^^^^ | | - | help: use `!` to perform bitwise not + | help: use `!` to perform logical negation or bitwise not error: aborting due to 6 previous errors 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 528c62f501e0d..cbe59e8e0af7e 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 @@ -4,7 +4,7 @@ error: `and` is not a logical operator LL | let _ = a and b; | ^^^ help: use `&&` to perform logical conjunction | - = note: unlike in e.g., python and PHP, `&&` and `||` are used for logical operators + = 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 @@ -12,7 +12,7 @@ error: `and` is not a logical operator LL | if a and b { | ^^^ help: use `&&` to perform logical conjunction | - = note: unlike in e.g., python and PHP, `&&` and `||` are used for logical operators + = 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 @@ -20,7 +20,7 @@ error: `or` is not a logical operator LL | let _ = a or b; | ^^ help: use `||` to perform logical disjunction | - = note: unlike in e.g., python and PHP, `&&` and `||` are used for logical operators + = 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 @@ -28,7 +28,7 @@ error: `or` is not a logical operator LL | if a or b { | ^^ help: use `||` to perform logical disjunction | - = note: unlike in e.g., python and PHP, `&&` and `||` are used for logical operators + = 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:30:11 @@ -36,7 +36,7 @@ error: `and` is not a logical operator LL | if (a and b) { | ^^^ help: use `&&` to perform logical conjunction | - = note: unlike in e.g., python and PHP, `&&` and `||` are used for logical operators + = 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:38:11 @@ -44,7 +44,7 @@ error: `or` is not a logical operator LL | if (a or b) { | ^^ help: use `||` to perform logical disjunction | - = note: unlike in e.g., python and PHP, `&&` and `||` are used for logical operators + = 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:46:13 @@ -52,7 +52,7 @@ error: `and` is not a logical operator LL | while a and b { | ^^^ help: use `&&` to perform logical conjunction | - = note: unlike in e.g., python and PHP, `&&` and `||` are used for logical operators + = 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:54:13 @@ -60,7 +60,7 @@ error: `or` is not a logical operator LL | while a or b { | ^^ help: use `||` to perform logical disjunction | - = note: unlike in e.g., python and PHP, `&&` and `||` are used for logical operators + = 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 diff --git a/src/test/ui/did_you_mean/issue-54109-without-witness.stderr b/src/test/ui/did_you_mean/issue-54109-without-witness.stderr index 0350890c1fde0..6455b0863f8f5 100644 --- a/src/test/ui/did_you_mean/issue-54109-without-witness.stderr +++ b/src/test/ui/did_you_mean/issue-54109-without-witness.stderr @@ -4,7 +4,7 @@ error: `and` is not a logical operator LL | let _ = a and b; | ^^^ help: use `&&` to perform logical conjunction | - = note: unlike in e.g., python and PHP, `&&` and `||` are used for logical operators + = note: unlike in e.g., Python and PHP, `&&` and `||` are used for logical operators error: `and` is not a logical operator --> $DIR/issue-54109-without-witness.rs:15:10 @@ -12,7 +12,7 @@ error: `and` is not a logical operator LL | if a and b { | ^^^ help: use `&&` to perform logical conjunction | - = note: unlike in e.g., python and PHP, `&&` and `||` are used for logical operators + = note: unlike in e.g., Python and PHP, `&&` and `||` are used for logical operators error: `or` is not a logical operator --> $DIR/issue-54109-without-witness.rs:24:15 @@ -20,7 +20,7 @@ error: `or` is not a logical operator LL | let _ = a or b; | ^^ help: use `||` to perform logical disjunction | - = note: unlike in e.g., python and PHP, `&&` and `||` are used for logical operators + = note: unlike in e.g., Python and PHP, `&&` and `||` are used for logical operators error: `or` is not a logical operator --> $DIR/issue-54109-without-witness.rs:26:10 @@ -28,7 +28,7 @@ error: `or` is not a logical operator LL | if a or b { | ^^ help: use `||` to perform logical disjunction | - = note: unlike in e.g., python and PHP, `&&` and `||` are used for logical operators + = note: unlike in e.g., Python and PHP, `&&` and `||` are used for logical operators error: `and` is not a logical operator --> $DIR/issue-54109-without-witness.rs:34:11 @@ -36,7 +36,7 @@ error: `and` is not a logical operator LL | if (a and b) { | ^^^ help: use `&&` to perform logical conjunction | - = note: unlike in e.g., python and PHP, `&&` and `||` are used for logical operators + = note: unlike in e.g., Python and PHP, `&&` and `||` are used for logical operators error: `or` is not a logical operator --> $DIR/issue-54109-without-witness.rs:42:11 @@ -44,7 +44,7 @@ error: `or` is not a logical operator LL | if (a or b) { | ^^ help: use `||` to perform logical disjunction | - = note: unlike in e.g., python and PHP, `&&` and `||` are used for logical operators + = note: unlike in e.g., Python and PHP, `&&` and `||` are used for logical operators error: `and` is not a logical operator --> $DIR/issue-54109-without-witness.rs:50:13 @@ -52,7 +52,7 @@ error: `and` is not a logical operator LL | while a and b { | ^^^ help: use `&&` to perform logical conjunction | - = note: unlike in e.g., python and PHP, `&&` and `||` are used for logical operators + = note: unlike in e.g., Python and PHP, `&&` and `||` are used for logical operators error: `or` is not a logical operator --> $DIR/issue-54109-without-witness.rs:58:13 @@ -60,7 +60,7 @@ error: `or` is not a logical operator LL | while a or b { | ^^ help: use `||` to perform logical disjunction | - = note: unlike in e.g., python and PHP, `&&` and `||` are used for logical operators + = note: unlike in e.g., Python and PHP, `&&` and `||` are used for logical operators error: aborting due to 8 previous errors From 484b612909fed94c21846ec54832b676174c9b57 Mon Sep 17 00:00:00 2001 From: yukang Date: Fri, 16 Sep 2022 14:41:42 +0800 Subject: [PATCH 3/3] use subdiagnostic for logical negation, bitwise not --- .../locales/en-US/parser.ftl | 4 ++- .../rustc_parse/src/parser/diagnostics.rs | 29 +++++++++++++++++-- compiler/rustc_parse/src/parser/expr.rs | 19 +++++++----- 3 files changed, 40 insertions(+), 12 deletions(-) diff --git a/compiler/rustc_error_messages/locales/en-US/parser.ftl b/compiler/rustc_error_messages/locales/en-US/parser.ftl index 7d56da70ff5af..9459cfebde936 100644 --- a/compiler/rustc_error_messages/locales/en-US/parser.ftl +++ b/compiler/rustc_error_messages/locales/en-US/parser.ftl @@ -55,7 +55,9 @@ parser_tilde_is_not_unary_operator = `~` cannot be used as a unary operator .suggestion = use `!` to perform bitwise not parser_unexpected_token_after_not = unexpected {$negated_desc} after identifier - .suggestion = use `!` to perform {$negated_msg} +parser_unexpected_token_after_not_bitwise = use `!` to perform bitwise not +parser_unexpected_token_after_not_logical = use `!` to perform logical negation +parser_unexpected_token_after_not_default = use `!` to perform logical negation or bitwise not parser_malformed_loop_label = malformed loop label .suggestion = use the correct loop label format diff --git a/compiler/rustc_parse/src/parser/diagnostics.rs b/compiler/rustc_parse/src/parser/diagnostics.rs index d2a8daa150cd2..a65f523a0f455 100644 --- a/compiler/rustc_parse/src/parser/diagnostics.rs +++ b/compiler/rustc_parse/src/parser/diagnostics.rs @@ -430,9 +430,32 @@ pub(crate) struct NotAsNegationOperator { #[primary_span] pub negated: Span, pub negated_desc: String, - pub negated_msg: String, - #[suggestion_short(applicability = "machine-applicable", code = "!")] - pub not: Span, + #[subdiagnostic] + pub sub: NotAsNegationOperatorSub, +} + +#[derive(SessionSubdiagnostic)] +pub enum NotAsNegationOperatorSub { + #[suggestion_short( + parser::unexpected_token_after_not_default, + applicability = "machine-applicable", + code = "!" + )] + SuggestNotDefault(#[primary_span] Span), + + #[suggestion_short( + parser::unexpected_token_after_not_bitwise, + applicability = "machine-applicable", + code = "!" + )] + SuggestNotBitwise(#[primary_span] Span), + + #[suggestion_short( + parser::unexpected_token_after_not_logical, + applicability = "machine-applicable", + code = "!" + )] + SuggestNotLogical(#[primary_span] Span), } #[derive(SessionDiagnostic)] diff --git a/compiler/rustc_parse/src/parser/expr.rs b/compiler/rustc_parse/src/parser/expr.rs index 1fdd312572aa1..f4f75f71e722c 100644 --- a/compiler/rustc_parse/src/parser/expr.rs +++ b/compiler/rustc_parse/src/parser/expr.rs @@ -6,8 +6,9 @@ use super::diagnostics::{ InvalidComparisonOperatorSub, InvalidLogicalOperator, InvalidLogicalOperatorSub, LeftArrowOperator, LifetimeInBorrowExpression, MacroInvocationWithQualifiedPath, MalformedLoopLabel, MissingInInForLoop, MissingInInForLoopSub, MissingSemicolonBeforeArray, - NotAsNegationOperator, OuterAttributeNotAllowedOnIfElse, RequireColonAfterLabeledExpression, - SnapshotParser, TildeAsUnaryOperator, UnexpectedTokenAfterLabel, + NotAsNegationOperator, NotAsNegationOperatorSub, OuterAttributeNotAllowedOnIfElse, + RequireColonAfterLabeledExpression, SnapshotParser, TildeAsUnaryOperator, + UnexpectedTokenAfterLabel, }; use super::pat::{CommaRecoveryMode, RecoverColon, RecoverComma, PARAM_EXPECTED}; use super::ty::{AllowPlus, RecoverQPath, RecoverReturnSign}; @@ -660,21 +661,23 @@ impl<'a> Parser<'a> { fn recover_not_expr(&mut self, lo: Span) -> PResult<'a, (Span, ExprKind)> { // Emit the error... let negated_token = self.look_ahead(1, |t| t.clone()); - let negtated_msg = if negated_token.is_numeric_lit() { - "bitwise not" + + let sub_diag = if negated_token.is_numeric_lit() { + NotAsNegationOperatorSub::SuggestNotBitwise } else if negated_token.is_bool_lit() { - "logical negation" + NotAsNegationOperatorSub::SuggestNotLogical } else { - "logical negation or bitwise not" + NotAsNegationOperatorSub::SuggestNotDefault }; self.sess.emit_err(NotAsNegationOperator { negated: negated_token.span, negated_desc: super::token_descr(&negated_token), - negated_msg: negtated_msg.to_string(), // Span the `not` plus trailing whitespace to avoid // trailing whitespace after the `!` in our suggestion - not: self.sess.source_map().span_until_non_whitespace(lo.to(negated_token.span)), + sub: sub_diag( + self.sess.source_map().span_until_non_whitespace(lo.to(negated_token.span)), + ), }); // ...and recover!