diff --git a/compiler/rustc_parse/src/parser/expr.rs b/compiler/rustc_parse/src/parser/expr.rs index 1dbd7bad0f023..1c31c84b8bfec 100644 --- a/compiler/rustc_parse/src/parser/expr.rs +++ b/compiler/rustc_parse/src/parser/expr.rs @@ -213,11 +213,11 @@ impl<'a> Parser<'a> { } } + // 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 @@ impl<'a> Parser<'a> { 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 0000000000000..2beed528ff1c1 --- /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 0000000000000..80c921535bd08 --- /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 0000000000000..a65f9389625fc --- /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 0000000000000..ed6bd74c9b92e --- /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 +