From 038c6a3ab17f0359254f1fb4f47e531272cf3849 Mon Sep 17 00:00:00 2001 From: moony Date: Tue, 20 Sep 2022 14:39:28 -0500 Subject: [PATCH 1/4] Diagnostics for arithmetic right and left shift operators. --- .../locales/en-US/parser.ftl | 4 +++ .../rustc_parse/src/parser/diagnostics.rs | 18 ++++++++++ compiler/rustc_parse/src/parser/expr.rs | 34 +++++++++++++++++-- .../arithmetic-left-shift.rs | 4 +++ .../arithmetic-left-shift.stderr | 8 +++++ .../arithmetic-right-shift.rs | 4 +++ .../arithmetic-right-shift.stderr | 8 +++++ 7 files changed, 78 insertions(+), 2 deletions(-) create mode 100644 src/test/ui/operator-recovery/arithmetic-left-shift.rs create mode 100644 src/test/ui/operator-recovery/arithmetic-left-shift.stderr create mode 100644 src/test/ui/operator-recovery/arithmetic-right-shift.rs create mode 100644 src/test/ui/operator-recovery/arithmetic-right-shift.stderr diff --git a/compiler/rustc_error_messages/locales/en-US/parser.ftl b/compiler/rustc_error_messages/locales/en-US/parser.ftl index f74df3d9746ae..44677476d43e0 100644 --- a/compiler/rustc_error_messages/locales/en-US/parser.ftl +++ b/compiler/rustc_error_messages/locales/en-US/parser.ftl @@ -46,6 +46,10 @@ parser_invalid_comparison_operator = invalid comparison operator `{$invalid}` .use_instead = `{$invalid}` is not a valid comparison operator, use `{$correct}` .spaceship_operator_invalid = `<=>` is not a valid comparison operator, use `std::cmp::Ordering` +parser_invalid_shift_operator = invalid shift operator `{$invalid}` + .arithmetic_left_shift_operator_invalid = `<<<` is not a valid left shift operator, consider shifting normally and fixing the sign as needed. + .arithmetic_right_shift_operator_invalid = `>>>` is not a valid right shift operator, consider casting to a signed integer and right shifting normally. + parser_invalid_logical_operator = `{$incorrect}` is not a logical operator .note = unlike in e.g., python and PHP, `&&` and `||` are used for logical operators .use_amp_amp_for_conjunction = use `&&` to perform logical conjunction diff --git a/compiler/rustc_parse/src/parser/diagnostics.rs b/compiler/rustc_parse/src/parser/diagnostics.rs index be524db785bc0..2ba7dc195683f 100644 --- a/compiler/rustc_parse/src/parser/diagnostics.rs +++ b/compiler/rustc_parse/src/parser/diagnostics.rs @@ -389,6 +389,24 @@ pub(crate) enum InvalidComparisonOperatorSub { Spaceship(#[primary_span] Span), } +#[derive(SessionDiagnostic)] +#[diag(parser::invalid_shift_operator)] +pub(crate) struct InvalidShiftOperator { + #[primary_span] + pub span: Span, + pub invalid: String, + #[subdiagnostic] + pub sub: InvalidShiftOperatorSub, +} + +#[derive(SessionSubdiagnostic)] +pub(crate) enum InvalidShiftOperatorSub { + #[label(parser::arithmetic_left_shift_operator_invalid)] + ArithmeticLeftShift(#[primary_span] Span), + #[label(parser::arithmetic_right_shift_operator_invalid)] + ArithmeticRightShift(#[primary_span] Span), +} + #[derive(SessionDiagnostic)] #[diag(parser::invalid_logical_operator)] #[note] diff --git a/compiler/rustc_parse/src/parser/expr.rs b/compiler/rustc_parse/src/parser/expr.rs index ed37ede65d514..30935bf170611 100644 --- a/compiler/rustc_parse/src/parser/expr.rs +++ b/compiler/rustc_parse/src/parser/expr.rs @@ -4,8 +4,9 @@ use super::diagnostics::{ FloatLiteralRequiresIntegerPart, IfExpressionMissingCondition, IfExpressionMissingThenBlock, IfExpressionMissingThenBlockSub, InvalidBlockMacroSegment, InvalidComparisonOperator, InvalidComparisonOperatorSub, InvalidLogicalOperator, InvalidLogicalOperatorSub, - LeftArrowOperator, LifetimeInBorrowExpression, MacroInvocationWithQualifiedPath, - MalformedLoopLabel, MissingInInForLoop, MissingInInForLoopSub, MissingSemicolonBeforeArray, + InvalidShiftOperator, InvalidShiftOperatorSub, LeftArrowOperator, + LifetimeInBorrowExpression, MacroInvocationWithQualifiedPath, MalformedLoopLabel, + MissingInInForLoop, MissingInInForLoopSub, MissingSemicolonBeforeArray, NotAsNegationOperator, OuterAttributeNotAllowedOnIfElse, RequireColonAfterLabeledExpression, SnapshotParser, TildeAsUnaryOperator, UnexpectedTokenAfterLabel, }; @@ -279,6 +280,35 @@ impl<'a> Parser<'a> { self.bump(); } + // Look for the arithmetic right shift operator (`>>>`) and recover. + if op.node == AssocOp::ShiftRight + && self.token.kind == token::Gt + && self.prev_token.span.hi() == self.token.span.lo() + { + let sp = op.span.to(self.token.span); + self.sess.emit_err(InvalidShiftOperator { + span: sp, + invalid: ">>>".into(), + sub: InvalidShiftOperatorSub::ArithmeticRightShift(sp), + }); + self.bump(); + } + + // Look for the arithmetic left shift operator (`<<<`) and recover. + // Yea nobody uses this but it's worth being thorough. + if op.node == AssocOp::ShiftLeft + && self.token.kind == token::Lt + && self.prev_token.span.hi() == self.token.span.lo() + { + let sp = op.span.to(self.token.span); + self.sess.emit_err(InvalidShiftOperator { + span: sp, + invalid: "<<<".into(), + sub: InvalidShiftOperatorSub::ArithmeticLeftShift(sp), + }); + self.bump(); + } + if self.prev_token == token::BinOp(token::Plus) && self.token == token::BinOp(token::Plus) && self.prev_token.span.between(self.token.span).is_empty() diff --git a/src/test/ui/operator-recovery/arithmetic-left-shift.rs b/src/test/ui/operator-recovery/arithmetic-left-shift.rs new file mode 100644 index 0000000000000..3045105690931 --- /dev/null +++ b/src/test/ui/operator-recovery/arithmetic-left-shift.rs @@ -0,0 +1,4 @@ +fn main() { + println!("{}", 1 <<< 2); + //~^ERROR invalid shift operator `<<<` +} diff --git a/src/test/ui/operator-recovery/arithmetic-left-shift.stderr b/src/test/ui/operator-recovery/arithmetic-left-shift.stderr new file mode 100644 index 0000000000000..04fe36dcc918a --- /dev/null +++ b/src/test/ui/operator-recovery/arithmetic-left-shift.stderr @@ -0,0 +1,8 @@ +error: invalid shift operator `<<<` + --> $DIR/arithmetic-left-shift.rs:2:22 + | +LL | println!("{}", 1 <<< 2); + | ^^^ `<<<` is not a valid left shift operator, consider shifting normally and fixing the sign as needed. + +error: aborting due to previous error + diff --git a/src/test/ui/operator-recovery/arithmetic-right-shift.rs b/src/test/ui/operator-recovery/arithmetic-right-shift.rs new file mode 100644 index 0000000000000..18353d9428ae1 --- /dev/null +++ b/src/test/ui/operator-recovery/arithmetic-right-shift.rs @@ -0,0 +1,4 @@ +fn main() { + println!("{}", 1 >>> 2); + //~^ERROR invalid shift operator `>>>` +} diff --git a/src/test/ui/operator-recovery/arithmetic-right-shift.stderr b/src/test/ui/operator-recovery/arithmetic-right-shift.stderr new file mode 100644 index 0000000000000..f66d160ccc6e2 --- /dev/null +++ b/src/test/ui/operator-recovery/arithmetic-right-shift.stderr @@ -0,0 +1,8 @@ +error: invalid shift operator `>>>` + --> $DIR/arithmetic-right-shift.rs:2:22 + | +LL | println!("{}", 1 >>> 2); + | ^^^ `>>>` is not a valid right shift operator, consider casting to a signed integer and right shifting normally. + +error: aborting due to previous error + From 3d07f184dff8451523e2fe4cccb0c46e7481de21 Mon Sep 17 00:00:00 2001 From: moony Date: Tue, 20 Sep 2022 14:41:26 -0500 Subject: [PATCH 2/4] thanks formatter i forgot about you --- compiler/rustc_parse/src/parser/expr.rs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/compiler/rustc_parse/src/parser/expr.rs b/compiler/rustc_parse/src/parser/expr.rs index 30935bf170611..b60d12ae3f987 100644 --- a/compiler/rustc_parse/src/parser/expr.rs +++ b/compiler/rustc_parse/src/parser/expr.rs @@ -4,11 +4,11 @@ use super::diagnostics::{ FloatLiteralRequiresIntegerPart, IfExpressionMissingCondition, IfExpressionMissingThenBlock, IfExpressionMissingThenBlockSub, InvalidBlockMacroSegment, InvalidComparisonOperator, InvalidComparisonOperatorSub, InvalidLogicalOperator, InvalidLogicalOperatorSub, - InvalidShiftOperator, InvalidShiftOperatorSub, LeftArrowOperator, - LifetimeInBorrowExpression, MacroInvocationWithQualifiedPath, MalformedLoopLabel, - MissingInInForLoop, MissingInInForLoopSub, MissingSemicolonBeforeArray, - NotAsNegationOperator, OuterAttributeNotAllowedOnIfElse, RequireColonAfterLabeledExpression, - SnapshotParser, TildeAsUnaryOperator, UnexpectedTokenAfterLabel, + InvalidShiftOperator, InvalidShiftOperatorSub, LeftArrowOperator, LifetimeInBorrowExpression, + MacroInvocationWithQualifiedPath, MalformedLoopLabel, MissingInInForLoop, + MissingInInForLoopSub, MissingSemicolonBeforeArray, NotAsNegationOperator, + OuterAttributeNotAllowedOnIfElse, RequireColonAfterLabeledExpression, SnapshotParser, + TildeAsUnaryOperator, UnexpectedTokenAfterLabel, }; use super::pat::{CommaRecoveryMode, RecoverColon, RecoverComma, PARAM_EXPECTED}; use super::ty::{AllowPlus, RecoverQPath, RecoverReturnSign}; From f76812e10a90a034dfb10dbdc4f16f78d27299d8 Mon Sep 17 00:00:00 2001 From: moony Date: Tue, 20 Sep 2022 19:34:28 -0500 Subject: [PATCH 3/4] fixe --- compiler/rustc_error_messages/locales/en-US/parser.ftl | 4 ++-- compiler/rustc_parse/src/parser/diagnostics.rs | 8 ++++---- compiler/rustc_parse/src/parser/expr.rs | 8 ++++---- .../{arithmetic-left-shift.rs => logical-left-shift.rs} | 0 ...hmetic-left-shift.stderr => logical-left-shift.stderr} | 2 +- .../{arithmetic-right-shift.rs => logical-right-shift.rs} | 0 ...etic-right-shift.stderr => logical-right-shift.stderr} | 4 ++-- 7 files changed, 13 insertions(+), 13 deletions(-) rename src/test/ui/operator-recovery/{arithmetic-left-shift.rs => logical-left-shift.rs} (100%) rename src/test/ui/operator-recovery/{arithmetic-left-shift.stderr => logical-left-shift.stderr} (85%) rename src/test/ui/operator-recovery/{arithmetic-right-shift.rs => logical-right-shift.rs} (100%) rename src/test/ui/operator-recovery/{arithmetic-right-shift.stderr => logical-right-shift.stderr} (60%) diff --git a/compiler/rustc_error_messages/locales/en-US/parser.ftl b/compiler/rustc_error_messages/locales/en-US/parser.ftl index 44677476d43e0..f1cdcc99c45b9 100644 --- a/compiler/rustc_error_messages/locales/en-US/parser.ftl +++ b/compiler/rustc_error_messages/locales/en-US/parser.ftl @@ -47,8 +47,8 @@ parser_invalid_comparison_operator = invalid comparison operator `{$invalid}` .spaceship_operator_invalid = `<=>` is not a valid comparison operator, use `std::cmp::Ordering` parser_invalid_shift_operator = invalid shift operator `{$invalid}` - .arithmetic_left_shift_operator_invalid = `<<<` is not a valid left shift operator, consider shifting normally and fixing the sign as needed. - .arithmetic_right_shift_operator_invalid = `>>>` is not a valid right shift operator, consider casting to a signed integer and right shifting normally. + .logical_left_shift_operator_invalid = `<<<` is not a valid left shift operator, consider shifting normally and fixing the sign as needed. + .logical_right_shift_operator_invalid = `>>>` is not a valid right shift operator, consider casting to an unsigned integer and right shifting normally. parser_invalid_logical_operator = `{$incorrect}` is not a logical operator .note = unlike in e.g., python and PHP, `&&` and `||` are used for logical operators diff --git a/compiler/rustc_parse/src/parser/diagnostics.rs b/compiler/rustc_parse/src/parser/diagnostics.rs index 2ba7dc195683f..75863ccdb893a 100644 --- a/compiler/rustc_parse/src/parser/diagnostics.rs +++ b/compiler/rustc_parse/src/parser/diagnostics.rs @@ -401,10 +401,10 @@ pub(crate) struct InvalidShiftOperator { #[derive(SessionSubdiagnostic)] pub(crate) enum InvalidShiftOperatorSub { - #[label(parser::arithmetic_left_shift_operator_invalid)] - ArithmeticLeftShift(#[primary_span] Span), - #[label(parser::arithmetic_right_shift_operator_invalid)] - ArithmeticRightShift(#[primary_span] Span), + #[label(parser::logical_left_shift_operator_invalid)] + LogicalLeftShift(#[primary_span] Span), + #[label(parser::logical_right_shift_operator_invalid)] + LogicalRightShift(#[primary_span] Span), } #[derive(SessionDiagnostic)] diff --git a/compiler/rustc_parse/src/parser/expr.rs b/compiler/rustc_parse/src/parser/expr.rs index b60d12ae3f987..d47de2311e151 100644 --- a/compiler/rustc_parse/src/parser/expr.rs +++ b/compiler/rustc_parse/src/parser/expr.rs @@ -280,7 +280,7 @@ impl<'a> Parser<'a> { self.bump(); } - // Look for the arithmetic right shift operator (`>>>`) and recover. + // Look for the logical right shift operator (`>>>`) and recover. if op.node == AssocOp::ShiftRight && self.token.kind == token::Gt && self.prev_token.span.hi() == self.token.span.lo() @@ -289,12 +289,12 @@ impl<'a> Parser<'a> { self.sess.emit_err(InvalidShiftOperator { span: sp, invalid: ">>>".into(), - sub: InvalidShiftOperatorSub::ArithmeticRightShift(sp), + sub: InvalidShiftOperatorSub::LogicalRightShift(sp), }); self.bump(); } - // Look for the arithmetic left shift operator (`<<<`) and recover. + // Look for the logical left shift operator (`<<<`) and recover. // Yea nobody uses this but it's worth being thorough. if op.node == AssocOp::ShiftLeft && self.token.kind == token::Lt @@ -304,7 +304,7 @@ impl<'a> Parser<'a> { self.sess.emit_err(InvalidShiftOperator { span: sp, invalid: "<<<".into(), - sub: InvalidShiftOperatorSub::ArithmeticLeftShift(sp), + sub: InvalidShiftOperatorSub::LogicalLeftShift(sp), }); self.bump(); } diff --git a/src/test/ui/operator-recovery/arithmetic-left-shift.rs b/src/test/ui/operator-recovery/logical-left-shift.rs similarity index 100% rename from src/test/ui/operator-recovery/arithmetic-left-shift.rs rename to src/test/ui/operator-recovery/logical-left-shift.rs diff --git a/src/test/ui/operator-recovery/arithmetic-left-shift.stderr b/src/test/ui/operator-recovery/logical-left-shift.stderr similarity index 85% rename from src/test/ui/operator-recovery/arithmetic-left-shift.stderr rename to src/test/ui/operator-recovery/logical-left-shift.stderr index 04fe36dcc918a..124981d4b266a 100644 --- a/src/test/ui/operator-recovery/arithmetic-left-shift.stderr +++ b/src/test/ui/operator-recovery/logical-left-shift.stderr @@ -1,5 +1,5 @@ error: invalid shift operator `<<<` - --> $DIR/arithmetic-left-shift.rs:2:22 + --> $DIR/logical-left-shift.rs:2:22 | LL | println!("{}", 1 <<< 2); | ^^^ `<<<` is not a valid left shift operator, consider shifting normally and fixing the sign as needed. diff --git a/src/test/ui/operator-recovery/arithmetic-right-shift.rs b/src/test/ui/operator-recovery/logical-right-shift.rs similarity index 100% rename from src/test/ui/operator-recovery/arithmetic-right-shift.rs rename to src/test/ui/operator-recovery/logical-right-shift.rs diff --git a/src/test/ui/operator-recovery/arithmetic-right-shift.stderr b/src/test/ui/operator-recovery/logical-right-shift.stderr similarity index 60% rename from src/test/ui/operator-recovery/arithmetic-right-shift.stderr rename to src/test/ui/operator-recovery/logical-right-shift.stderr index f66d160ccc6e2..d8b4c7de84019 100644 --- a/src/test/ui/operator-recovery/arithmetic-right-shift.stderr +++ b/src/test/ui/operator-recovery/logical-right-shift.stderr @@ -1,8 +1,8 @@ error: invalid shift operator `>>>` - --> $DIR/arithmetic-right-shift.rs:2:22 + --> $DIR/logical-right-shift.rs:2:22 | LL | println!("{}", 1 >>> 2); - | ^^^ `>>>` is not a valid right shift operator, consider casting to a signed integer and right shifting normally. + | ^^^ `>>>` is not a valid right shift operator, consider casting to an unsigned integer and right shifting normally. error: aborting due to previous error From 130721cafa07054c7c50282436fa220ecf1ea057 Mon Sep 17 00:00:00 2001 From: moony Date: Wed, 21 Sep 2022 12:52:30 -0500 Subject: [PATCH 4/4] caps --- compiler/rustc_error_messages/locales/en-US/parser.ftl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/compiler/rustc_error_messages/locales/en-US/parser.ftl b/compiler/rustc_error_messages/locales/en-US/parser.ftl index f1cdcc99c45b9..5a1a8ad556808 100644 --- a/compiler/rustc_error_messages/locales/en-US/parser.ftl +++ b/compiler/rustc_error_messages/locales/en-US/parser.ftl @@ -47,8 +47,8 @@ parser_invalid_comparison_operator = invalid comparison operator `{$invalid}` .spaceship_operator_invalid = `<=>` is not a valid comparison operator, use `std::cmp::Ordering` parser_invalid_shift_operator = invalid shift operator `{$invalid}` - .logical_left_shift_operator_invalid = `<<<` is not a valid left shift operator, consider shifting normally and fixing the sign as needed. - .logical_right_shift_operator_invalid = `>>>` is not a valid right shift operator, consider casting to an unsigned integer and right shifting normally. + .logical_left_shift_operator_invalid = `<<<` is not a valid left shift operator, consider shifting normally and fixing the sign as needed + .logical_right_shift_operator_invalid = `>>>` is not a valid right shift operator, consider casting to an unsigned integer and right shifting normally parser_invalid_logical_operator = `{$incorrect}` is not a logical operator .note = unlike in e.g., python and PHP, `&&` and `||` are used for logical operators