Skip to content

Commit

Permalink
logical left, right shifts wip
Browse files Browse the repository at this point in the history
  • Loading branch information
Dylan-DPC committed Jun 28, 2023
1 parent 7452822 commit ffe219a
Show file tree
Hide file tree
Showing 7 changed files with 71 additions and 0 deletions.
5 changes: 5 additions & 0 deletions compiler/rustc_parse/messages.ftl
Original file line number Diff line number Diff line change
Expand Up @@ -397,6 +397,11 @@ parse_invalid_literal_suffix_on_tuple_index = suffixes on a tuple index are inva
.tuple_exception_line_2 = on proc macros, you'll want to use `syn::Index::from` or `proc_macro::Literal::*_unsuffixed` for code that will desugar to tuple field access
.tuple_exception_line_3 = see issue #60210 <https://github.com/rust-lang/rust/issues/60210> for more information
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
parse_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
Expand Down
19 changes: 19 additions & 0 deletions compiler/rustc_parse/src/errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,25 @@ pub(crate) enum InvalidComparisonOperatorSub {
Spaceship(#[primary_span] Span),
}

#[derive(Diagnostic)]
#[diag(parse_invalid_shift_operator)]
#[note]
pub(crate) struct InvalidShiftOperator {
#[primary_span]
pub Span: Span,
pub invalid: String,
#[subdiagnostic]
pub sub: InvalidShiftOperatorSub
}

#[derive(SessionSubdiagnostic)]
pub enum InvalidShiftOperatorSub {
#[label(parser_left_shift_operator_invalid)]
LogicalLeftShift(#[primary_span] Span),
#[label(parser_logical_right_shift_operator)]
LogicalRightShift(#[primary_span] Span),
}

#[derive(Diagnostic)]
#[diag(parse_invalid_logical_operator)]
#[note]
Expand Down
23 changes: 23 additions & 0 deletions compiler/rustc_parse/src/parser/expr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -271,6 +271,29 @@ impl<'a> Parser<'a> {
self.bump();
}

// 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() {
let sp = op.span.to(self.token.span);
self.sess.emit_err(errors::InvalidShiftOperator {
span: sp,
invalid: ">>>".into(),
sub: errors::InvalidShiftOperatorSub::LogicalRightShift(sp),
});
self.bump();
}

// Look for the logical left shift operator (`<<<`) and recover
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(errors::InvalidShiftOperator {
span: sp,
invalid: "<<<".into(),
sub: errors::InvalidShiftOperatorSub::LogicalLeftShift(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()
Expand Down
4 changes: 4 additions & 0 deletions src/test/ui/operator-recovery/logical-left-shift.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
fn main() {
println!("{}", 1 <<< 2);
//~^ERROR invalid shift operator `<<<`
}
8 changes: 8 additions & 0 deletions src/test/ui/operator-recovery/logical-left-shift.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
error: invalid shift operator `<<<`
--> $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.

error: aborting due to previous error

4 changes: 4 additions & 0 deletions src/test/ui/operator-recovery/logical-right-shift.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
fn main() {
println!("{}", 1 >>> 2);
//~^ERROR invalid shift operator `>>>`
}
8 changes: 8 additions & 0 deletions src/test/ui/operator-recovery/logical-right-shift.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
error: invalid shift operator `>>>`
--> $DIR/logical-right-shift.rs:2:22
|
LL | println!("{}", 1 >>> 2);
| ^^^ `>>>` is not a valid right shift operator, consider casting to an unsigned integer and right shifting normally.

error: aborting due to previous error

0 comments on commit ffe219a

Please sign in to comment.