Skip to content

Commit 46054fd

Browse files
committed
Implement new type-checking strategy for binary operators. Basically,
the plan is to treat all binary operators as if they were overloaded, relying on the fact that we have impls for all the builtin scalar operations (and no more). But then during writeback we clear the overload if the types correspond to a builtin op. This strategy allows us to avoid having to know the types of the operands ahead of time. It also avoids us overspecializing as we did in the past.
1 parent ed81038 commit 46054fd

File tree

10 files changed

+549
-472
lines changed

10 files changed

+549
-472
lines changed

src/librustc/middle/ty.rs

Lines changed: 10 additions & 74 deletions
Original file line numberDiff line numberDiff line change
@@ -3004,6 +3004,10 @@ pub fn mk_nil<'tcx>(cx: &ctxt<'tcx>) -> Ty<'tcx> {
30043004
mk_tup(cx, Vec::new())
30053005
}
30063006

3007+
pub fn mk_bool<'tcx>(cx: &ctxt<'tcx>) -> Ty<'tcx> {
3008+
mk_t(cx, ty_bool)
3009+
}
3010+
30073011
pub fn mk_bare_fn<'tcx>(cx: &ctxt<'tcx>,
30083012
opt_def_id: Option<ast::DefId>,
30093013
fty: &'tcx BareFnTy<'tcx>) -> Ty<'tcx> {
@@ -3371,8 +3375,12 @@ pub fn type_is_scalar(ty: Ty) -> bool {
33713375
/// Returns true if this type is a floating point type and false otherwise.
33723376
pub fn type_is_floating_point(ty: Ty) -> bool {
33733377
match ty.sty {
3374-
ty_float(_) => true,
3375-
_ => false,
3378+
ty_float(_) |
3379+
ty_infer(FloatVar(_)) =>
3380+
true,
3381+
3382+
_ =>
3383+
false,
33763384
}
33773385
}
33783386

@@ -5797,78 +5805,6 @@ pub fn closure_upvars<'tcx>(typer: &mc::Typer<'tcx>,
57975805
}
57985806
}
57995807

5800-
pub fn is_binopable<'tcx>(cx: &ctxt<'tcx>, ty: Ty<'tcx>, op: ast::BinOp) -> bool {
5801-
#![allow(non_upper_case_globals)]
5802-
const tycat_other: int = 0;
5803-
const tycat_bool: int = 1;
5804-
const tycat_char: int = 2;
5805-
const tycat_int: int = 3;
5806-
const tycat_float: int = 4;
5807-
const tycat_raw_ptr: int = 6;
5808-
5809-
const opcat_add: int = 0;
5810-
const opcat_sub: int = 1;
5811-
const opcat_mult: int = 2;
5812-
const opcat_shift: int = 3;
5813-
const opcat_rel: int = 4;
5814-
const opcat_eq: int = 5;
5815-
const opcat_bit: int = 6;
5816-
const opcat_logic: int = 7;
5817-
const opcat_mod: int = 8;
5818-
5819-
fn opcat(op: ast::BinOp) -> int {
5820-
match op.node {
5821-
ast::BiAdd => opcat_add,
5822-
ast::BiSub => opcat_sub,
5823-
ast::BiMul => opcat_mult,
5824-
ast::BiDiv => opcat_mult,
5825-
ast::BiRem => opcat_mod,
5826-
ast::BiAnd => opcat_logic,
5827-
ast::BiOr => opcat_logic,
5828-
ast::BiBitXor => opcat_bit,
5829-
ast::BiBitAnd => opcat_bit,
5830-
ast::BiBitOr => opcat_bit,
5831-
ast::BiShl => opcat_shift,
5832-
ast::BiShr => opcat_shift,
5833-
ast::BiEq => opcat_eq,
5834-
ast::BiNe => opcat_eq,
5835-
ast::BiLt => opcat_rel,
5836-
ast::BiLe => opcat_rel,
5837-
ast::BiGe => opcat_rel,
5838-
ast::BiGt => opcat_rel
5839-
}
5840-
}
5841-
5842-
fn tycat<'tcx>(cx: &ctxt<'tcx>, ty: Ty<'tcx>) -> int {
5843-
if type_is_simd(cx, ty) {
5844-
return tycat(cx, simd_type(cx, ty))
5845-
}
5846-
match ty.sty {
5847-
ty_char => tycat_char,
5848-
ty_bool => tycat_bool,
5849-
ty_int(_) | ty_uint(_) | ty_infer(IntVar(_)) => tycat_int,
5850-
ty_float(_) | ty_infer(FloatVar(_)) => tycat_float,
5851-
ty_ptr(_) => tycat_raw_ptr,
5852-
_ => tycat_other
5853-
}
5854-
}
5855-
5856-
const t: bool = true;
5857-
const f: bool = false;
5858-
5859-
let tbl = [
5860-
// +, -, *, shift, rel, ==, bit, logic, mod
5861-
/*other*/ [f, f, f, f, f, f, f, f, f],
5862-
/*bool*/ [f, f, f, f, t, t, t, t, f],
5863-
/*char*/ [f, f, f, f, t, t, f, f, f],
5864-
/*int*/ [t, t, t, t, t, t, t, f, t],
5865-
/*float*/ [t, t, t, f, t, t, f, f, f],
5866-
/*bot*/ [t, t, t, t, t, t, t, t, t],
5867-
/*raw ptr*/ [f, f, f, f, t, t, f, f, f]];
5868-
5869-
return tbl[tycat(cx, ty) as uint ][opcat(op) as uint];
5870-
}
5871-
58725808
// Returns the repeat count for a repeating vector expression.
58735809
pub fn eval_repeat_count(tcx: &ctxt, count_expr: &ast::Expr) -> uint {
58745810
match const_eval::eval_const_expr_partial(tcx, count_expr, Some(tcx.types.uint)) {

src/librustc_trans/trans/base.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -560,7 +560,7 @@ pub fn compare_scalar_types<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
560560
_ => bcx.sess().bug("compare_scalar_types: must be a comparison operator")
561561
}
562562
}
563-
ty::ty_bool | ty::ty_uint(_) | ty::ty_char => {
563+
ty::ty_bare_fn(..) | ty::ty_bool | ty::ty_uint(_) | ty::ty_char => {
564564
ICmp(bcx, bin_op_to_icmp_predicate(bcx.ccx(), op, false), lhs, rhs, debug_loc)
565565
}
566566
ty::ty_ptr(mt) if common::type_is_sized(bcx.tcx(), mt.ty) => {

src/librustc_trans/trans/consts.rs

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -351,7 +351,14 @@ pub fn const_expr<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
351351
fn const_expr_unadjusted<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
352352
e: &ast::Expr,
353353
ety: Ty<'tcx>,
354-
param_substs: &'tcx Substs<'tcx>) -> ValueRef {
354+
param_substs: &'tcx Substs<'tcx>)
355+
-> ValueRef
356+
{
357+
debug!("const_expr_unadjusted(e={}, ety={}, param_substs={})",
358+
e.repr(cx.tcx()),
359+
ety.repr(cx.tcx()),
360+
param_substs.repr(cx.tcx()));
361+
355362
let map_list = |exprs: &[P<ast::Expr>]| {
356363
exprs.iter().map(|e| const_expr(cx, &**e, param_substs).0)
357364
.fold(Vec::new(), |mut l, val| { l.push(val); l })
@@ -366,6 +373,9 @@ fn const_expr_unadjusted<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
366373
/* Neither type is bottom, and we expect them to be unified
367374
* already, so the following is safe. */
368375
let (te1, ty) = const_expr(cx, &**e1, param_substs);
376+
debug!("const_expr_unadjusted: te1={}, ty={}",
377+
cx.tn().val_to_string(te1),
378+
ty.repr(cx.tcx()));
369379
let is_simd = ty::type_is_simd(cx.tcx(), ty);
370380
let intype = if is_simd {
371381
ty::simd_type(cx.tcx(), ty)

src/librustc_trans/trans/expr.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2390,6 +2390,7 @@ fn deref_once<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
23902390
}
23912391
}
23922392

2393+
#[derive(Debug)]
23932394
enum OverflowOp {
23942395
Add,
23952396
Sub,
@@ -2419,6 +2420,7 @@ enum OverflowCodegen {
24192420

24202421
enum OverflowOpViaInputCheck { Shl, Shr, }
24212422

2423+
#[derive(Debug)]
24222424
enum OverflowOpViaIntrinsic { Add, Sub, Mul, }
24232425

24242426
impl OverflowOpViaIntrinsic {
@@ -2443,7 +2445,8 @@ impl OverflowOpViaIntrinsic {
24432445
_ => panic!("unsupported target word size")
24442446
},
24452447
ref t @ ty_uint(_) | ref t @ ty_int(_) => t.clone(),
2446-
_ => panic!("tried to get overflow intrinsic for non-int type")
2448+
_ => panic!("tried to get overflow intrinsic for {:?} applied to non-int type",
2449+
*self)
24472450
};
24482451

24492452
match *self {

src/librustc_typeck/check/callee.rs

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@
99
// except according to those terms.
1010

1111
use super::autoderef;
12-
use super::AutorefArgs;
1312
use super::check_argument_types;
1413
use super::check_expr;
1514
use super::check_method_argument_types;
@@ -258,7 +257,6 @@ fn confirm_builtin_call<'a,'tcx>(fcx: &FnCtxt<'a,'tcx>,
258257
&fn_sig.inputs,
259258
&expected_arg_tys[..],
260259
arg_exprs,
261-
AutorefArgs::No,
262260
fn_sig.variadic,
263261
TupleArgumentsFlag::DontTupleArguments);
264262

@@ -288,7 +286,6 @@ fn confirm_deferred_closure_call<'a,'tcx>(fcx: &FnCtxt<'a,'tcx>,
288286
&*fn_sig.inputs,
289287
&*expected_arg_tys,
290288
arg_exprs,
291-
AutorefArgs::No,
292289
fn_sig.variadic,
293290
TupleArgumentsFlag::TupleArguments);
294291

@@ -308,7 +305,6 @@ fn confirm_overloaded_call<'a,'tcx>(fcx: &FnCtxt<'a, 'tcx>,
308305
method_callee.ty,
309306
callee_expr,
310307
arg_exprs,
311-
AutorefArgs::No,
312308
TupleArgumentsFlag::TupleArguments,
313309
expected);
314310
write_call(fcx, call_expr, output_type);

0 commit comments

Comments
 (0)