Add the span of the operator itself to ast::BinOp.

This commit is contained in:
Huon Wilson 2015-01-13 14:24:37 +11:00
parent 4be79d6acd
commit 2e888d0341
20 changed files with 69 additions and 65 deletions

View File

@ -44,7 +44,7 @@ use std::{i8, i16, i32, i64, u8, u16, u32, u64, f32, f64};
use syntax::{abi, ast, ast_map};
use syntax::ast_util::is_shift_binop;
use syntax::attr::{self, AttrMetaMethods};
use syntax::codemap::{Span, DUMMY_SP};
use syntax::codemap::{self, Span, DUMMY_SP};
use syntax::parse::token;
use syntax::ast::{TyIs, TyUs, TyI8, TyU8, TyI16, TyU16, TyI32, TyU32, TyI64, TyU64};
use syntax::ast_util;
@ -185,7 +185,7 @@ impl LintPass for TypeLimits {
"comparison is useless due to type limits");
}
if is_shift_binop(binop) {
if is_shift_binop(binop.node) {
let opt_ty_bits = match ty::expr_ty(cx.tcx, &**l).sty {
ty::ty_int(t) => Some(int_ty_bits(t, cx.sess().target.int_type)),
ty::ty_uint(t) => Some(uint_ty_bits(t, cx.sess().target.uint_type)),
@ -272,7 +272,7 @@ impl LintPass for TypeLimits {
fn is_valid<T:cmp::PartialOrd>(binop: ast::BinOp, v: T,
min: T, max: T) -> bool {
match binop {
match binop.node {
ast::BiLt => v > min && v <= max,
ast::BiLe => v >= min && v < max,
ast::BiGt => v >= min && v < max,
@ -283,13 +283,13 @@ impl LintPass for TypeLimits {
}
fn rev_binop(binop: ast::BinOp) -> ast::BinOp {
match binop {
codemap::respan(binop.span, match binop.node {
ast::BiLt => ast::BiGt,
ast::BiLe => ast::BiGe,
ast::BiGt => ast::BiLt,
ast::BiGe => ast::BiLe,
_ => binop
}
_ => return binop
})
}
// for int & uint, be conservative with the warnings, so that the
@ -382,7 +382,7 @@ impl LintPass for TypeLimits {
}
fn is_comparison(binop: ast::BinOp) -> bool {
match binop {
match binop.node {
ast::BiEq | ast::BiLt | ast::BiLe |
ast::BiNe | ast::BiGe | ast::BiGt => true,
_ => false

View File

@ -372,7 +372,7 @@ impl<'a, 'tcx> CFGBuilder<'a, 'tcx> {
expr_exit
}
ast::ExprBinary(op, ref l, ref r) if ast_util::lazy_binop(op) => {
ast::ExprBinary(op, ref l, ref r) if ast_util::lazy_binop(op.node) => {
//
// [pred]
// |

View File

@ -400,7 +400,7 @@ pub fn eval_const_expr_partial(tcx: &ty::ctxt, e: &Expr) -> Result<const_val, St
match (eval_const_expr_partial(tcx, &**a),
eval_const_expr_partial(tcx, &**b)) {
(Ok(const_float(a)), Ok(const_float(b))) => {
match op {
match op.node {
ast::BiAdd => Ok(const_float(a + b)),
ast::BiSub => Ok(const_float(a - b)),
ast::BiMul => Ok(const_float(a * b)),
@ -416,7 +416,7 @@ pub fn eval_const_expr_partial(tcx: &ty::ctxt, e: &Expr) -> Result<const_val, St
}
}
(Ok(const_int(a)), Ok(const_int(b))) => {
match op {
match op.node {
ast::BiAdd => Ok(const_int(a + b)),
ast::BiSub => Ok(const_int(a - b)),
ast::BiMul => Ok(const_int(a * b)),
@ -443,7 +443,7 @@ pub fn eval_const_expr_partial(tcx: &ty::ctxt, e: &Expr) -> Result<const_val, St
}
}
(Ok(const_uint(a)), Ok(const_uint(b))) => {
match op {
match op.node {
ast::BiAdd => Ok(const_uint(a + b)),
ast::BiSub => Ok(const_uint(a - b)),
ast::BiMul => Ok(const_uint(a * b)),
@ -471,21 +471,21 @@ pub fn eval_const_expr_partial(tcx: &ty::ctxt, e: &Expr) -> Result<const_val, St
}
// shifts can have any integral type as their rhs
(Ok(const_int(a)), Ok(const_uint(b))) => {
match op {
match op.node {
ast::BiShl => Ok(const_int(a << b as uint)),
ast::BiShr => Ok(const_int(a >> b as uint)),
_ => Err("can't do this op on an int and uint".to_string())
}
}
(Ok(const_uint(a)), Ok(const_int(b))) => {
match op {
match op.node {
ast::BiShl => Ok(const_uint(a << b as uint)),
ast::BiShr => Ok(const_uint(a >> b as uint)),
_ => Err("can't do this op on a uint and int".to_string())
}
}
(Ok(const_bool(a)), Ok(const_bool(b))) => {
Ok(const_bool(match op {
Ok(const_bool(match op.node {
ast::BiAnd => a && b,
ast::BiOr => a || b,
ast::BiBitXor => a ^ b,

View File

@ -568,7 +568,7 @@ impl<'d,'t,'tcx,TYPER:mc::Typer<'tcx>> ExprUseVisitor<'d,'t,'tcx,TYPER> {
}
ast::ExprBinary(op, ref lhs, ref rhs) => {
let pass_args = if ast_util::is_by_value_binop(op) {
let pass_args = if ast_util::is_by_value_binop(op.node) {
PassArgs::ByValue
} else {
PassArgs::ByRef

View File

@ -504,7 +504,7 @@ fn visit_expr(ir: &mut IrMaps, expr: &Expr) {
ir.add_live_node_for_node(expr.id, ExprNode(expr.span));
visit::walk_expr(ir, expr);
}
ast::ExprBinary(op, _, _) if ast_util::lazy_binop(op) => {
ast::ExprBinary(op, _, _) if ast_util::lazy_binop(op.node) => {
ir.add_live_node_for_node(expr.id, ExprNode(expr.span));
visit::walk_expr(ir, expr);
}
@ -1177,7 +1177,7 @@ impl<'a, 'tcx> Liveness<'a, 'tcx> {
self.propagate_through_exprs(&exprs[], succ)
}
ast::ExprBinary(op, ref l, ref r) if ast_util::lazy_binop(op) => {
ast::ExprBinary(op, ref l, ref r) if ast_util::lazy_binop(op.node) => {
let r_succ = self.propagate_through_expr(&**r, succ);
let ln = self.live_node(expr.id, expr.span);

View File

@ -22,7 +22,7 @@ use util::nodemap::{FnvHashMap, FnvHashSet, NodeMap};
use util::common::can_reach;
use std::cell::RefCell;
use syntax::codemap::Span;
use syntax::codemap::{self, Span};
use syntax::{ast, visit};
use syntax::ast::{Block, Item, FnDecl, NodeId, Arm, Pat, Stmt, Expr, Local};
use syntax::ast_util::{stmt_id};
@ -496,8 +496,8 @@ fn resolve_expr(visitor: &mut RegionResolutionVisitor, expr: &ast::Expr) {
// scopes, meaning that temporaries cannot outlive them.
// This ensures fixed size stacks.
ast::ExprBinary(ast::BiAnd, _, ref r) |
ast::ExprBinary(ast::BiOr, _, ref r) => {
ast::ExprBinary(codemap::Spanned { node: ast::BiAnd, .. }, _, ref r) |
ast::ExprBinary(codemap::Spanned { node: ast::BiOr, .. }, _, ref r) => {
// For shortcircuiting operators, mark the RHS as a terminating
// scope since it only executes conditionally.
terminating(r.id);

View File

@ -5716,7 +5716,7 @@ pub fn is_binopable<'tcx>(cx: &ctxt<'tcx>, ty: Ty<'tcx>, op: ast::BinOp) -> bool
static opcat_mod: int = 8;
fn opcat(op: ast::BinOp) -> int {
match op {
match op.node {
ast::BiAdd => opcat_add,
ast::BiSub => opcat_sub,
ast::BiMul => opcat_mult,

View File

@ -231,7 +231,7 @@ mod svh_visitor {
SawExprCall,
SawExprMethodCall,
SawExprTup,
SawExprBinary(ast::BinOp),
SawExprBinary(ast::BinOp_),
SawExprUnary(ast::UnOp),
SawExprLit(ast::Lit_),
SawExprCast,
@ -241,7 +241,7 @@ mod svh_visitor {
SawExprClosure,
SawExprBlock,
SawExprAssign,
SawExprAssignOp(ast::BinOp),
SawExprAssignOp(ast::BinOp_),
SawExprIndex,
SawExprRange,
SawExprPath,
@ -262,7 +262,7 @@ mod svh_visitor {
ExprCall(..) => SawExprCall,
ExprMethodCall(..) => SawExprMethodCall,
ExprTup(..) => SawExprTup,
ExprBinary(op, _, _) => SawExprBinary(op),
ExprBinary(op, _, _) => SawExprBinary(op.node),
ExprUnary(op, _) => SawExprUnary(op),
ExprLit(ref lit) => SawExprLit(lit.node.clone()),
ExprCast(..) => SawExprCast,
@ -273,7 +273,7 @@ mod svh_visitor {
ExprClosure(..) => SawExprClosure,
ExprBlock(..) => SawExprBlock,
ExprAssign(..) => SawExprAssign,
ExprAssignOp(op, _, _) => SawExprAssignOp(op),
ExprAssignOp(op, _, _) => SawExprAssignOp(op.node),
ExprField(_, id) => SawExprField(content(id.node)),
ExprTupField(_, id) => SawExprTupField(id.node),
ExprIndex(..) => SawExprIndex,

View File

@ -540,7 +540,7 @@ pub fn compare_scalar_types<'blk, 'tcx>(cx: Block<'blk, 'tcx>,
lhs: ValueRef,
rhs: ValueRef,
t: Ty<'tcx>,
op: ast::BinOp)
op: ast::BinOp_)
-> Result<'blk, 'tcx> {
let f = |&: a| Result::new(cx, compare_scalar_values(cx, lhs, rhs, a, op));
@ -561,7 +561,7 @@ pub fn compare_scalar_values<'blk, 'tcx>(cx: Block<'blk, 'tcx>,
lhs: ValueRef,
rhs: ValueRef,
nt: scalar_type,
op: ast::BinOp)
op: ast::BinOp_)
-> ValueRef {
let _icx = push_ctxt("compare_scalar_values");
fn die(cx: Block) -> ! {
@ -635,7 +635,7 @@ pub fn compare_simd_types<'blk, 'tcx>(
not supported for floating point SIMD types")
},
ty::ty_uint(_) | ty::ty_int(_) => {
let cmp = match op {
let cmp = match op.node {
ast::BiEq => llvm::IntEQ,
ast::BiNe => llvm::IntNE,
ast::BiLt => llvm::IntSLT,
@ -823,7 +823,7 @@ pub fn cast_shift_rhs<F, G>(op: ast::BinOp,
G: FnOnce(ValueRef, Type) -> ValueRef,
{
// Shifts may have any size int on the rhs
if ast_util::is_shift_binop(op) {
if ast_util::is_shift_binop(op.node) {
let mut rhs_llty = val_ty(rhs);
let mut lhs_llty = val_ty(lhs);
if rhs_llty.kind() == Vector { rhs_llty = rhs_llty.element_type() }
@ -852,7 +852,7 @@ pub fn fail_if_zero_or_overflows<'blk, 'tcx>(
rhs: ValueRef,
rhs_t: Ty<'tcx>)
-> Block<'blk, 'tcx> {
let (zero_text, overflow_text) = if divrem == ast::BiDiv {
let (zero_text, overflow_text) = if divrem.node == ast::BiDiv {
("attempted to divide by zero",
"attempted to divide with overflow")
} else {

View File

@ -310,7 +310,7 @@ fn const_expr_unadjusted(cx: &CrateContext, e: &ast::Expr) -> ValueRef {
let ty = ty::expr_ty(cx.tcx(), &**e1);
let is_float = ty::type_is_fp(ty);
let signed = ty::type_is_signed(ty);
return match b {
return match b.node {
ast::BiAdd => {
if is_float { llvm::LLVMConstFAdd(te1, te2) }
else { llvm::LLVMConstAdd(te1, te2) }

View File

@ -1132,7 +1132,7 @@ fn trans_rvalue_dps_unadjusted<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
let rhs_datum = unpack_datum!(bcx, trans(bcx, &**rhs));
trans_overloaded_op(bcx, expr, MethodCall::expr(expr.id), lhs,
vec![(rhs_datum, rhs.id)], Some(dest),
!ast_util::is_by_value_binop(op)).bcx
!ast_util::is_by_value_binop(op.node)).bcx
}
ast::ExprUnary(op, ref subexpr) => {
// if not overloaded, would be RvalueDatumExpr
@ -1676,7 +1676,7 @@ fn trans_eager_binop<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
let binop_debug_loc = binop_expr.debug_loc();
let mut bcx = bcx;
let val = match op {
let val = match op.node {
ast::BiAdd => {
if is_float {
FAdd(bcx, lhs, rhs, binop_debug_loc)
@ -1739,7 +1739,7 @@ fn trans_eager_binop<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
}
ast::BiEq | ast::BiNe | ast::BiLt | ast::BiGe | ast::BiLe | ast::BiGt => {
if ty::type_is_scalar(rhs_t) {
unpack_result!(bcx, base::compare_scalar_types(bcx, lhs, rhs, rhs_t, op))
unpack_result!(bcx, base::compare_scalar_types(bcx, lhs, rhs, rhs_t, op.node))
} else if is_simd {
base::compare_simd_types(bcx, lhs, rhs, intype, ty::simd_size(tcx, lhs_t), op)
} else {
@ -1811,7 +1811,7 @@ fn trans_binary<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
// if overloaded, would be RvalueDpsExpr
assert!(!ccx.tcx().method_map.borrow().contains_key(&MethodCall::expr(expr.id)));
match op {
match op.node {
ast::BiAnd => {
trans_lazy_binop(bcx, expr, lazy_and, lhs, rhs)
}

View File

@ -2859,7 +2859,7 @@ fn check_expr_with_unifier<'a, 'tcx, F>(fcx: &FnCtxt<'a, 'tcx>,
let lhs_t = structurally_resolved_type(fcx, lhs.span,
fcx.expr_ty(&*lhs));
if ty::type_is_integral(lhs_t) && ast_util::is_shift_binop(op) {
if ty::type_is_integral(lhs_t) && ast_util::is_shift_binop(op.node) {
// Shift is a special case: rhs must be uint, no matter what lhs is
check_expr(fcx, &**rhs);
let rhs_ty = fcx.expr_ty(&**rhs);
@ -2887,7 +2887,7 @@ fn check_expr_with_unifier<'a, 'tcx, F>(fcx: &FnCtxt<'a, 'tcx>,
demand::suptype(fcx, expr.span, tvar, lhs_t);
check_expr_has_type(fcx, &**rhs, tvar);
let result_t = match op {
let result_t = match op.node {
ast::BiEq | ast::BiNe | ast::BiLt | ast::BiLe | ast::BiGe |
ast::BiGt => {
if ty::type_is_simd(tcx, lhs_t) {
@ -2898,7 +2898,7 @@ fn check_expr_with_unifier<'a, 'tcx, F>(fcx: &FnCtxt<'a, 'tcx>,
operation `{}` not \
supported for floating \
point SIMD vector `{}`",
ast_util::binop_to_string(op),
ast_util::binop_to_string(op.node),
actual)
},
lhs_t,
@ -2919,7 +2919,7 @@ fn check_expr_with_unifier<'a, 'tcx, F>(fcx: &FnCtxt<'a, 'tcx>,
return;
}
if op == ast::BiOr || op == ast::BiAnd {
if op.node == ast::BiOr || op.node == ast::BiAnd {
// This is an error; one of the operands must have the wrong
// type
fcx.write_error(expr.id);
@ -2928,7 +2928,7 @@ fn check_expr_with_unifier<'a, 'tcx, F>(fcx: &FnCtxt<'a, 'tcx>,
|actual| {
format!("binary operation `{}` cannot be applied \
to type `{}`",
ast_util::binop_to_string(op),
ast_util::binop_to_string(op.node),
actual)
},
lhs_t,
@ -2945,7 +2945,7 @@ fn check_expr_with_unifier<'a, 'tcx, F>(fcx: &FnCtxt<'a, 'tcx>,
operation `{}=` \
cannot be applied to \
type `{}`",
ast_util::binop_to_string(op),
ast_util::binop_to_string(op.node),
actual)
},
lhs_t,
@ -2968,7 +2968,7 @@ fn check_expr_with_unifier<'a, 'tcx, F>(fcx: &FnCtxt<'a, 'tcx>,
rhs: &P<ast::Expr>) -> Ty<'tcx> {
let tcx = fcx.ccx.tcx;
let lang = &tcx.lang_items;
let (name, trait_did) = match op {
let (name, trait_did) = match op.node {
ast::BiAdd => ("add", lang.add_trait()),
ast::BiSub => ("sub", lang.sub_trait()),
ast::BiMul => ("mul", lang.mul_trait()),
@ -2994,10 +2994,10 @@ fn check_expr_with_unifier<'a, 'tcx, F>(fcx: &FnCtxt<'a, 'tcx>,
trait_did, lhs_expr, Some(rhs), || {
fcx.type_error_message(ex.span, |actual| {
format!("binary operation `{}` cannot be applied to type `{}`",
ast_util::binop_to_string(op),
ast_util::binop_to_string(op.node),
actual)
}, lhs_resolved_t, None)
}, if ast_util::is_by_value_binop(op) { AutorefArgs::No } else { AutorefArgs::Yes })
}, if ast_util::is_by_value_binop(op.node) { AutorefArgs::No } else { AutorefArgs::Yes })
}
fn check_user_unop<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,

View File

@ -564,7 +564,7 @@ fn visit_expr(rcx: &mut Rcx, expr: &ast::Expr) {
},
ast::ExprBinary(op, ref lhs, ref rhs) if has_method_map => {
let implicitly_ref_args = !ast_util::is_by_value_binop(op);
let implicitly_ref_args = !ast_util::is_by_value_binop(op.node);
// As `expr_method_call`, but the call is via an
// overloaded op. Note that we (sadly) currently use an

View File

@ -13,7 +13,7 @@
pub use self::AsmDialect::*;
pub use self::AttrStyle::*;
pub use self::BindingMode::*;
pub use self::BinOp::*;
pub use self::BinOp_::*;
pub use self::BlockCheckMode::*;
pub use self::CaptureClause::*;
pub use self::Decl_::*;
@ -582,7 +582,7 @@ pub enum Mutability {
}
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Show, Copy)]
pub enum BinOp {
pub enum BinOp_ {
BiAdd,
BiSub,
BiMul,
@ -603,6 +603,8 @@ pub enum BinOp {
BiGt,
}
pub type BinOp = Spanned<BinOp_>;
#[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Show, Copy)]
pub enum UnOp {
UnUniq,

View File

@ -46,7 +46,7 @@ pub fn stmt_id(s: &Stmt) -> NodeId {
}
}
pub fn binop_to_string(op: BinOp) -> &'static str {
pub fn binop_to_string(op: BinOp_) -> &'static str {
match op {
BiAdd => "+",
BiSub => "-",
@ -69,7 +69,7 @@ pub fn binop_to_string(op: BinOp) -> &'static str {
}
}
pub fn lazy_binop(b: BinOp) -> bool {
pub fn lazy_binop(b: BinOp_) -> bool {
match b {
BiAnd => true,
BiOr => true,
@ -77,7 +77,7 @@ pub fn lazy_binop(b: BinOp) -> bool {
}
}
pub fn is_shift_binop(b: BinOp) -> bool {
pub fn is_shift_binop(b: BinOp_) -> bool {
match b {
BiShl => true,
BiShr => true,
@ -85,7 +85,7 @@ pub fn is_shift_binop(b: BinOp) -> bool {
}
}
pub fn is_comparison_binop(b: BinOp) -> bool {
pub fn is_comparison_binop(b: BinOp_) -> bool {
match b {
BiEq | BiLt | BiLe | BiNe | BiGt | BiGe => true,
_ => false
@ -93,7 +93,7 @@ pub fn is_comparison_binop(b: BinOp) -> bool {
}
/// Returns `true` if the binary operator takes its arguments by value
pub fn is_by_value_binop(b: BinOp) -> bool {
pub fn is_by_value_binop(b: BinOp_) -> bool {
match b {
BiAdd | BiSub | BiMul | BiDiv | BiRem | BiBitXor | BiBitAnd | BiBitOr | BiShl | BiShr => {
true
@ -319,7 +319,7 @@ pub fn struct_field_visibility(field: ast::StructField) -> Visibility {
}
/// Maps a binary operator to its precedence
pub fn operator_prec(op: ast::BinOp) -> usize {
pub fn operator_prec(op: ast::BinOp_) -> usize {
match op {
// 'as' sits here with 12
BiMul | BiDiv | BiRem => 11us,

View File

@ -106,7 +106,7 @@ pub trait AstBuilder {
fn expr_ident(&self, span: Span, id: ast::Ident) -> P<ast::Expr>;
fn expr_self(&self, span: Span) -> P<ast::Expr>;
fn expr_binary(&self, sp: Span, op: ast::BinOp,
fn expr_binary(&self, sp: Span, op: ast::BinOp_,
lhs: P<ast::Expr>, rhs: P<ast::Expr>) -> P<ast::Expr>;
fn expr_deref(&self, sp: Span, e: P<ast::Expr>) -> P<ast::Expr>;
fn expr_unary(&self, sp: Span, op: ast::UnOp, e: P<ast::Expr>) -> P<ast::Expr>;
@ -561,9 +561,9 @@ impl<'a> AstBuilder for ExtCtxt<'a> {
self.expr_ident(span, special_idents::self_)
}
fn expr_binary(&self, sp: Span, op: ast::BinOp,
fn expr_binary(&self, sp: Span, op: ast::BinOp_,
lhs: P<ast::Expr>, rhs: P<ast::Expr>) -> P<ast::Expr> {
self.expr(sp, ast::ExprBinary(op, lhs, rhs))
self.expr(sp, ast::ExprBinary(Spanned { node: op, span: sp }, lhs, rhs))
}
fn expr_deref(&self, sp: Span, e: P<ast::Expr>) -> P<ast::Expr> {

View File

@ -1449,7 +1449,7 @@ pub fn cs_same_method_fold<F>(use_foldl: bool,
/// Use a given binop to combine the result of calling the derived method
/// on all the fields.
#[inline]
pub fn cs_binop(binop: ast::BinOp, base: P<Expr>,
pub fn cs_binop(binop: ast::BinOp_, base: P<Expr>,
enum_nonmatch_f: EnumNonMatchCollapsedFunc,
cx: &mut ExtCtxt, trait_span: Span,
substructure: &Substructure) -> P<Expr> {

View File

@ -2840,6 +2840,7 @@ impl<'a> Parser<'a> {
self.expected_tokens.push(TokenType::Operator);
let cur_op_span = self.span;
let cur_opt = self.token.to_binop();
match cur_opt {
Some(cur_op) => {
@ -2853,7 +2854,7 @@ impl<'a> Parser<'a> {
let rhs = self.parse_more_binops(expr, cur_prec + 1);
let lhs_span = lhs.span;
let rhs_span = rhs.span;
let binary = self.mk_binary(cur_op, lhs, rhs);
let binary = self.mk_binary(codemap::respan(cur_op_span, cur_op), lhs, rhs);
let bin = self.mk_expr(lhs_span.lo, rhs_span.hi, binary);
self.parse_more_binops(bin, min_prec)
} else {
@ -2877,14 +2878,14 @@ 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) {
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) => {
ExprBinary(op, _, _) if ast_util::is_comparison_binop(op.node) => {
let op_span = self.span;
self.span_err(op_span,
"Chained comparison operators require parentheses");
if op == BiLt && outer_op == BiGt {
if op.node == BiLt && outer_op == BiGt {
self.span_help(op_span,
"use ::< instead of < if you meant to specify type arguments");
}
@ -2919,6 +2920,7 @@ impl<'a> Parser<'a> {
pub fn parse_assign_expr_with(&mut self, lhs: P<Expr>) -> P<Expr> {
let restrictions = self.restrictions & RESTRICTION_NO_STRUCT_LITERAL;
let op_span = self.span;
match self.token {
token::Eq => {
self.bump();
@ -2942,7 +2944,7 @@ impl<'a> Parser<'a> {
};
let rhs_span = rhs.span;
let span = lhs.span;
let assign_op = self.mk_assign_op(aop, lhs, rhs);
let assign_op = self.mk_assign_op(codemap::respan(op_span, aop), lhs, rhs);
self.mk_expr(span.lo, rhs_span.hi, assign_op)
}
// A range expression, either `expr..expr` or `expr..`.

View File

@ -249,7 +249,7 @@ impl Token {
}
/// Maps a token to its corresponding binary operator.
pub fn to_binop(&self) -> Option<ast::BinOp> {
pub fn to_binop(&self) -> Option<ast::BinOp_> {
match *self {
BinOp(Star) => Some(ast::BiMul),
BinOp(Slash) => Some(ast::BiDiv),

View File

@ -1618,7 +1618,7 @@ impl<'a> State<'a> {
rhs: &ast::Expr) -> IoResult<()> {
try!(self.print_expr(lhs));
try!(space(&mut self.s));
try!(self.word_space(ast_util::binop_to_string(op)));
try!(self.word_space(ast_util::binop_to_string(op.node)));
self.print_expr(rhs)
}
@ -1786,7 +1786,7 @@ impl<'a> State<'a> {
ast::ExprAssignOp(op, ref lhs, ref rhs) => {
try!(self.print_expr(&**lhs));
try!(space(&mut self.s));
try!(word(&mut self.s, ast_util::binop_to_string(op)));
try!(word(&mut self.s, ast_util::binop_to_string(op.node)));
try!(self.word_space("="));
try!(self.print_expr(&**rhs));
}