From 2e888d0341e81de1744b257c25b012c2c148f0ba Mon Sep 17 00:00:00 2001 From: Huon Wilson Date: Tue, 13 Jan 2015 14:24:37 +1100 Subject: [PATCH 1/2] Add the span of the operator itself to ast::BinOp. --- src/librustc/lint/builtin.rs | 14 +++++++------- src/librustc/middle/cfg/construct.rs | 2 +- src/librustc/middle/const_eval.rs | 12 ++++++------ src/librustc/middle/expr_use_visitor.rs | 2 +- src/librustc/middle/liveness.rs | 4 ++-- src/librustc/middle/region.rs | 6 +++--- src/librustc/middle/ty.rs | 2 +- src/librustc_back/svh.rs | 8 ++++---- src/librustc_trans/trans/base.rs | 10 +++++----- src/librustc_trans/trans/consts.rs | 2 +- src/librustc_trans/trans/expr.rs | 8 ++++---- src/librustc_typeck/check/mod.rs | 18 +++++++++--------- src/librustc_typeck/check/regionck.rs | 2 +- src/libsyntax/ast.rs | 6 ++++-- src/libsyntax/ast_util.rs | 12 ++++++------ src/libsyntax/ext/build.rs | 6 +++--- src/libsyntax/ext/deriving/generic/mod.rs | 2 +- src/libsyntax/parse/parser.rs | 12 +++++++----- src/libsyntax/parse/token.rs | 2 +- src/libsyntax/print/pprust.rs | 4 ++-- 20 files changed, 69 insertions(+), 65 deletions(-) diff --git a/src/librustc/lint/builtin.rs b/src/librustc/lint/builtin.rs index fef1017b78285..9a7b7e0eb942a 100644 --- a/src/librustc/lint/builtin.rs +++ b/src/librustc/lint/builtin.rs @@ -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(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 diff --git a/src/librustc/middle/cfg/construct.rs b/src/librustc/middle/cfg/construct.rs index 1a2162b3076ec..6162f61fde1c7 100644 --- a/src/librustc/middle/cfg/construct.rs +++ b/src/librustc/middle/cfg/construct.rs @@ -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] // | diff --git a/src/librustc/middle/const_eval.rs b/src/librustc/middle/const_eval.rs index 05dd47f5a367f..c2533c1a9c688 100644 --- a/src/librustc/middle/const_eval.rs +++ b/src/librustc/middle/const_eval.rs @@ -400,7 +400,7 @@ pub fn eval_const_expr_partial(tcx: &ty::ctxt, e: &Expr) -> Result { - 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 { - 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 { - 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 { - 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, diff --git a/src/librustc/middle/expr_use_visitor.rs b/src/librustc/middle/expr_use_visitor.rs index a5f2dc398e9e2..d9ab86deb3b7c 100644 --- a/src/librustc/middle/expr_use_visitor.rs +++ b/src/librustc/middle/expr_use_visitor.rs @@ -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 diff --git a/src/librustc/middle/liveness.rs b/src/librustc/middle/liveness.rs index 43989d0aadc8a..c08af95f13996 100644 --- a/src/librustc/middle/liveness.rs +++ b/src/librustc/middle/liveness.rs @@ -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); diff --git a/src/librustc/middle/region.rs b/src/librustc/middle/region.rs index b4b2e1b63e80c..67c0e52d6649a 100644 --- a/src/librustc/middle/region.rs +++ b/src/librustc/middle/region.rs @@ -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); diff --git a/src/librustc/middle/ty.rs b/src/librustc/middle/ty.rs index 83bbdf14e4a74..bae41b78c08a4 100644 --- a/src/librustc/middle/ty.rs +++ b/src/librustc/middle/ty.rs @@ -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, diff --git a/src/librustc_back/svh.rs b/src/librustc_back/svh.rs index ebeaf3e6e22d7..65a7fbf60a5d8 100644 --- a/src/librustc_back/svh.rs +++ b/src/librustc_back/svh.rs @@ -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, diff --git a/src/librustc_trans/trans/base.rs b/src/librustc_trans/trans/base.rs index 572dfd165eeda..4c1fdc6140ec0 100644 --- a/src/librustc_trans/trans/base.rs +++ b/src/librustc_trans/trans/base.rs @@ -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(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 { diff --git a/src/librustc_trans/trans/consts.rs b/src/librustc_trans/trans/consts.rs index 29cf9f72ef8e8..ba3af53a9160a 100644 --- a/src/librustc_trans/trans/consts.rs +++ b/src/librustc_trans/trans/consts.rs @@ -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) } diff --git a/src/librustc_trans/trans/expr.rs b/src/librustc_trans/trans/expr.rs index 4ebaf91d11173..f0b491bdea848 100644 --- a/src/librustc_trans/trans/expr.rs +++ b/src/librustc_trans/trans/expr.rs @@ -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) } diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index 5f8ae09b5bd6f..a9f81d3a26632 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -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) -> 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>, diff --git a/src/librustc_typeck/check/regionck.rs b/src/librustc_typeck/check/regionck.rs index 56b700663d419..af5250805b7c6 100644 --- a/src/librustc_typeck/check/regionck.rs +++ b/src/librustc_typeck/check/regionck.rs @@ -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 diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs index 7111fe3af1fa9..25a30b5e8e2ee 100644 --- a/src/libsyntax/ast.rs +++ b/src/libsyntax/ast.rs @@ -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; + #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Show, Copy)] pub enum UnOp { UnUniq, diff --git a/src/libsyntax/ast_util.rs b/src/libsyntax/ast_util.rs index cf0aac5bf4ab5..5aeea47ac60dc 100644 --- a/src/libsyntax/ast_util.rs +++ b/src/libsyntax/ast_util.rs @@ -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, diff --git a/src/libsyntax/ext/build.rs b/src/libsyntax/ext/build.rs index 92619cf42e4d1..2b3a72126831e 100644 --- a/src/libsyntax/ext/build.rs +++ b/src/libsyntax/ext/build.rs @@ -106,7 +106,7 @@ pub trait AstBuilder { fn expr_ident(&self, span: Span, id: ast::Ident) -> P; fn expr_self(&self, span: Span) -> P; - fn expr_binary(&self, sp: Span, op: ast::BinOp, + fn expr_binary(&self, sp: Span, op: ast::BinOp_, lhs: P, rhs: P) -> P; fn expr_deref(&self, sp: Span, e: P) -> P; fn expr_unary(&self, sp: Span, op: ast::UnOp, e: P) -> P; @@ -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, rhs: P) -> P { - 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) -> P { diff --git a/src/libsyntax/ext/deriving/generic/mod.rs b/src/libsyntax/ext/deriving/generic/mod.rs index 272b046401011..f8812f4d28dc7 100644 --- a/src/libsyntax/ext/deriving/generic/mod.rs +++ b/src/libsyntax/ext/deriving/generic/mod.rs @@ -1449,7 +1449,7 @@ pub fn cs_same_method_fold(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, +pub fn cs_binop(binop: ast::BinOp_, base: P, enum_nonmatch_f: EnumNonMatchCollapsedFunc, cx: &mut ExtCtxt, trait_span: Span, substructure: &Substructure) -> P { diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index e59dbe52b769f..15254988ce026 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -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) -> P { 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..`. diff --git a/src/libsyntax/parse/token.rs b/src/libsyntax/parse/token.rs index a129fd19d9405..ac694afac6bf7 100644 --- a/src/libsyntax/parse/token.rs +++ b/src/libsyntax/parse/token.rs @@ -249,7 +249,7 @@ impl Token { } /// Maps a token to its corresponding binary operator. - pub fn to_binop(&self) -> Option { + pub fn to_binop(&self) -> Option { match *self { BinOp(Star) => Some(ast::BiMul), BinOp(Slash) => Some(ast::BiDiv), diff --git a/src/libsyntax/print/pprust.rs b/src/libsyntax/print/pprust.rs index 42f156d6a112d..1026f4cb3235d 100644 --- a/src/libsyntax/print/pprust.rs +++ b/src/libsyntax/print/pprust.rs @@ -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)); } From ec790d6fcc426e13431cbb7510c62864515a3ef8 Mon Sep 17 00:00:00 2001 From: Huon Wilson Date: Tue, 13 Jan 2015 15:18:55 +1100 Subject: [PATCH 2/2] Tweak chained comparison errors. Lower case and give a more precise span: from operator to operator, not just the last one. --- src/libsyntax/parse/parser.rs | 7 ++++--- .../compile-fail/require-parens-for-chained-comparison.rs | 8 ++++---- src/test/compile-fail/unsized2.rs | 4 ++-- 3 files changed, 10 insertions(+), 9 deletions(-) diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index 15254988ce026..759e5e8229a0e 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -2882,12 +2882,13 @@ impl<'a> Parser<'a> { debug_assert!(ast_util::is_comparison_binop(outer_op)); match lhs.node { ExprBinary(op, _, _) if ast_util::is_comparison_binop(op.node) => { - let op_span = self.span; + // respan to include both operators + let op_span = mk_sp(op.span.lo, self.span.hi); self.span_err(op_span, - "Chained comparison operators require parentheses"); + "chained comparison operators require parentheses"); if op.node == BiLt && outer_op == BiGt { self.span_help(op_span, - "use ::< instead of < if you meant to specify type arguments"); + "use `::<...>` instead of `<...>` if you meant to specify type arguments"); } } _ => {} diff --git a/src/test/compile-fail/require-parens-for-chained-comparison.rs b/src/test/compile-fail/require-parens-for-chained-comparison.rs index f5d8c5748147a..f2705f58331b4 100644 --- a/src/test/compile-fail/require-parens-for-chained-comparison.rs +++ b/src/test/compile-fail/require-parens-for-chained-comparison.rs @@ -12,12 +12,12 @@ fn f() {} fn main() { false == false == false; - //~^ ERROR: Chained comparison operators require parentheses + //~^ ERROR: chained comparison operators require parentheses false == 0 < 2; - //~^ ERROR: Chained comparison operators require parentheses + //~^ ERROR: chained comparison operators require parentheses f(); - //~^ ERROR: Chained comparison operators require parentheses - //~^^ HELP: use ::< instead of < if you meant to specify type arguments + //~^ ERROR: chained comparison operators require parentheses + //~^^ HELP: use `::<...>` instead of `<...>` } diff --git a/src/test/compile-fail/unsized2.rs b/src/test/compile-fail/unsized2.rs index a47d81e38ccba..b2eb2064aeb09 100644 --- a/src/test/compile-fail/unsized2.rs +++ b/src/test/compile-fail/unsized2.rs @@ -15,6 +15,6 @@ fn f() {} pub fn main() { f(); //~^ ERROR expected identifier, found keyword `type` - //~^^ ERROR: Chained comparison operators require parentheses - //~^^^ HELP: use ::< instead of < if you meant to specify type arguments + //~^^ ERROR: chained comparison + //~^^^ HELP: use `::< }