parent
9e4e524e0e
commit
1cc69c484e
4 changed files with 58 additions and 4 deletions
|
|
@ -85,6 +85,13 @@ pub fn is_shift_binop(b: BinOp) -> bool {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn is_comparison_binop(b: BinOp) -> bool {
|
||||
match b {
|
||||
BiEq | BiLt | BiLe | BiNe | BiGt | BiGe => true,
|
||||
_ => false
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns `true` if the binary operator takes its arguments by value
|
||||
pub fn is_by_value_binop(b: BinOp) -> bool {
|
||||
match b {
|
||||
|
|
@ -317,8 +324,7 @@ pub fn operator_prec(op: ast::BinOp) -> uint {
|
|||
BiBitAnd => 8u,
|
||||
BiBitXor => 7u,
|
||||
BiBitOr => 6u,
|
||||
BiLt | BiLe | BiGe | BiGt => 4u,
|
||||
BiEq | BiNe => 3u,
|
||||
BiLt | BiLe | BiGe | BiGt | BiEq | BiNe => 3u,
|
||||
BiAnd => 2u,
|
||||
BiOr => 1u
|
||||
}
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@ use ast::{AssociatedType, BareFnTy};
|
|||
use ast::{RegionTyParamBound, TraitTyParamBound, TraitBoundModifier};
|
||||
use ast::{ProvidedMethod, Public, Unsafety};
|
||||
use ast::{Mod, BiAdd, Arg, Arm, Attribute, BindByRef, BindByValue};
|
||||
use ast::{BiBitAnd, BiBitOr, BiBitXor, BiRem, Block};
|
||||
use ast::{BiBitAnd, BiBitOr, BiBitXor, BiRem, BiLt, BiGt, Block};
|
||||
use ast::{BlockCheckMode, CaptureByRef, CaptureByValue, CaptureClause};
|
||||
use ast::{Crate, CrateConfig, Decl, DeclItem};
|
||||
use ast::{DeclLocal, DefaultBlock, UnDeref, BiDiv, EMPTY_CTXT, EnumDef, ExplicitSelf};
|
||||
|
|
@ -2906,6 +2906,9 @@ impl<'a> Parser<'a> {
|
|||
let cur_opt = self.token.to_binop();
|
||||
match cur_opt {
|
||||
Some(cur_op) => {
|
||||
if ast_util::is_comparison_binop(cur_op) {
|
||||
self.check_no_chained_comparison(&*lhs, cur_op)
|
||||
}
|
||||
let cur_prec = operator_prec(cur_op);
|
||||
if cur_prec > min_prec {
|
||||
self.bump();
|
||||
|
|
@ -2934,6 +2937,25 @@ impl<'a> Parser<'a> {
|
|||
}
|
||||
}
|
||||
|
||||
/// Produce an error if comparison operators are chained (RFC #558).
|
||||
/// We only need to check lhs, not rhs, because all comparison ops
|
||||
/// have same precedence and are left-associative
|
||||
fn check_no_chained_comparison(&mut self, lhs: &Expr, outer_op: ast::BinOp) {
|
||||
debug_assert!(ast_util::is_comparison_binop(outer_op));
|
||||
match lhs.node {
|
||||
ExprBinary(op, _, _) if ast_util::is_comparison_binop(op) => {
|
||||
let op_span = self.span;
|
||||
self.span_err(op_span,
|
||||
"Chained comparison operators require parentheses");
|
||||
if op == BiLt && outer_op == BiGt {
|
||||
self.span_help(op_span,
|
||||
"Use ::< instead of < if you meant to specify type arguments.");
|
||||
}
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
|
||||
/// Parse an assignment expression....
|
||||
/// actually, this seems to be the main entry point for
|
||||
/// parsing an arbitrary expression.
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue