From f194c9b26af5d280ab2d0e01fd85e23b3c303771 Mon Sep 17 00:00:00 2001 From: r00ster91 Date: Mon, 6 Dec 2021 18:55:58 +0100 Subject: [PATCH] Recover on invalid operators <> and <=> --- compiler/rustc_parse/src/parser/expr.rs | 34 ++++++++++++++++++- .../less-than-greater-than.rs | 4 +++ .../less-than-greater-than.stderr | 8 +++++ src/test/ui/operator-recovery/spaceship.rs | 4 +++ .../ui/operator-recovery/spaceship.stderr | 8 +++++ 5 files changed, 57 insertions(+), 1 deletion(-) create mode 100644 src/test/ui/operator-recovery/less-than-greater-than.rs create mode 100644 src/test/ui/operator-recovery/less-than-greater-than.stderr create mode 100644 src/test/ui/operator-recovery/spaceship.rs create mode 100644 src/test/ui/operator-recovery/spaceship.stderr diff --git a/compiler/rustc_parse/src/parser/expr.rs b/compiler/rustc_parse/src/parser/expr.rs index 1dbd7bad0f0..1c31c84b8bf 100644 --- a/compiler/rustc_parse/src/parser/expr.rs +++ b/compiler/rustc_parse/src/parser/expr.rs @@ -213,11 +213,11 @@ pub(super) fn parse_assoc_expr_with( } } + // Look for JS' `===` and `!==` and recover if (op.node == AssocOp::Equal || op.node == AssocOp::NotEqual) && self.token.kind == token::Eq && self.prev_token.span.hi() == self.token.span.lo() { - // Look for JS' `===` and `!==` and recover 😇 let sp = op.span.to(self.token.span); let sugg = match op.node { AssocOp::Equal => "==", @@ -235,6 +235,38 @@ pub(super) fn parse_assoc_expr_with( self.bump(); } + // Look for PHP's `<>` and recover + if op.node == AssocOp::Less + && self.token.kind == token::Gt + && self.prev_token.span.hi() == self.token.span.lo() + { + let sp = op.span.to(self.token.span); + self.struct_span_err(sp, "invalid comparison operator `<>`") + .span_suggestion_short( + sp, + "`<>` is not a valid comparison operator, use `!=`", + "!=".to_string(), + Applicability::MachineApplicable, + ) + .emit(); + self.bump(); + } + + // Look for C++'s `<=>` and recover + if op.node == AssocOp::LessEqual + && self.token.kind == token::Gt + && self.prev_token.span.hi() == self.token.span.lo() + { + let sp = op.span.to(self.token.span); + self.struct_span_err(sp, "invalid comparison operator `<=>`") + .span_label( + sp, + "`<=>` is not a valid comparison operator, use `std::cmp::Ordering`", + ) + .emit(); + self.bump(); + } + let op = op.node; // Special cases: if op == AssocOp::As { diff --git a/src/test/ui/operator-recovery/less-than-greater-than.rs b/src/test/ui/operator-recovery/less-than-greater-than.rs new file mode 100644 index 00000000000..2beed528ff1 --- /dev/null +++ b/src/test/ui/operator-recovery/less-than-greater-than.rs @@ -0,0 +1,4 @@ +fn main() { + println!("{}", 1 <> 2); + //~^ERROR invalid comparison operator `<>` +} diff --git a/src/test/ui/operator-recovery/less-than-greater-than.stderr b/src/test/ui/operator-recovery/less-than-greater-than.stderr new file mode 100644 index 00000000000..80c921535bd --- /dev/null +++ b/src/test/ui/operator-recovery/less-than-greater-than.stderr @@ -0,0 +1,8 @@ +error: invalid comparison operator `<>` + --> $DIR/less-than-greater-than.rs:2:22 + | +LL | println!("{}", 1 <> 2); + | ^^ help: `<>` is not a valid comparison operator, use `!=` + +error: aborting due to previous error + diff --git a/src/test/ui/operator-recovery/spaceship.rs b/src/test/ui/operator-recovery/spaceship.rs new file mode 100644 index 00000000000..a65f9389625 --- /dev/null +++ b/src/test/ui/operator-recovery/spaceship.rs @@ -0,0 +1,4 @@ +fn main() { + println!("{}", 1 <=> 2); + //~^ERROR invalid comparison operator `<=>` +} diff --git a/src/test/ui/operator-recovery/spaceship.stderr b/src/test/ui/operator-recovery/spaceship.stderr new file mode 100644 index 00000000000..ed6bd74c9b9 --- /dev/null +++ b/src/test/ui/operator-recovery/spaceship.stderr @@ -0,0 +1,8 @@ +error: invalid comparison operator `<=>` + --> $DIR/spaceship.rs:2:22 + | +LL | println!("{}", 1 <=> 2); + | ^^^ `<=>` is not a valid comparison operator, use `std::cmp::Ordering` + +error: aborting due to previous error + -- 2.44.0