Skip to content

Commit d649292

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 f55d03c commit d649292

File tree

10 files changed

+573
-472
lines changed

10 files changed

+573
-472
lines changed

src/librustc/middle/ty.rs

+10-74
Original file line numberDiff line numberDiff line change
@@ -3039,6 +3039,10 @@ pub fn mk_nil<'tcx>(cx: &ctxt<'tcx>) -> Ty<'tcx> {
30393039
mk_tup(cx, Vec::new())
30403040
}
30413041

3042+
pub fn mk_bool<'tcx>(cx: &ctxt<'tcx>) -> Ty<'tcx> {
3043+
mk_t(cx, ty_bool)
3044+
}
3045+
30423046
pub fn mk_bare_fn<'tcx>(cx: &ctxt<'tcx>,
30433047
opt_def_id: Option<ast::DefId>,
30443048
fty: &'tcx BareFnTy<'tcx>) -> Ty<'tcx> {
@@ -3406,8 +3410,12 @@ pub fn type_is_scalar(ty: Ty) -> bool {
34063410
/// Returns true if this type is a floating point type and false otherwise.
34073411
pub fn type_is_floating_point(ty: Ty) -> bool {
34083412
match ty.sty {
3409-
ty_float(_) => true,
3410-
_ => false,
3413+
ty_float(_) |
3414+
ty_infer(FloatVar(_)) =>
3415+
true,
3416+
3417+
_ =>
3418+
false,
34113419
}
34123420
}
34133421

@@ -5805,78 +5813,6 @@ pub fn closure_upvars<'tcx>(typer: &mc::Typer<'tcx>,
58055813
}
58065814
}
58075815

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

src/librustc_trans/trans/base.rs

+1-1
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

+11-1
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

+4-1
Original file line numberDiff line numberDiff line change
@@ -2384,6 +2384,7 @@ fn deref_once<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
23842384
}
23852385
}
23862386

2387+
#[derive(Debug)]
23872388
enum OverflowOp {
23882389
Add,
23892390
Sub,
@@ -2413,6 +2414,7 @@ enum OverflowCodegen {
24132414

24142415
enum OverflowOpViaInputCheck { Shl, Shr, }
24152416

2417+
#[derive(Debug)]
24162418
enum OverflowOpViaIntrinsic { Add, Sub, Mul, }
24172419

24182420
impl OverflowOpViaIntrinsic {
@@ -2437,7 +2439,8 @@ impl OverflowOpViaIntrinsic {
24372439
_ => panic!("unsupported target word size")
24382440
},
24392441
ref t @ ty_uint(_) | ref t @ ty_int(_) => t.clone(),
2440-
_ => panic!("tried to get overflow intrinsic for non-int type")
2442+
_ => panic!("tried to get overflow intrinsic for {:?} applied to non-int type",
2443+
*self)
24412444
};
24422445

24432446
match *self {

src/librustc_typeck/check/callee.rs

-4
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)