Skip to content

Commit f31cf60

Browse files
committed
---
yaml --- r: 4651 b: refs/heads/master c: 0340f32 h: refs/heads/master i: 4649: 94512e9 4647: 796d03b v: v3
1 parent 0234bf0 commit f31cf60

File tree

4 files changed

+48
-105
lines changed

4 files changed

+48
-105
lines changed

[refs]

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
11
---
2-
refs/heads/master: e5271405480f53ab1ed05da11001858c25be8558
2+
refs/heads/master: 0340f32748ad434ae525be5a5d37797be0f67c0f

trunk/src/comp/middle/trans.rs

Lines changed: 17 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -2497,15 +2497,13 @@ fn trans_unary(cx: &@block_ctxt, op: ast::unop, e: &@ast::expr,
24972497
alt op {
24982498
ast::not. {
24992499
let sub = trans_expr(cx, e);
2500-
let dr = autoderef(sub.bcx, sub.val, ty::expr_ty(bcx_tcx(cx), e));
2501-
ret rslt(dr.bcx, dr.bcx.build.Not(dr.val));
2500+
ret rslt(sub.bcx, sub.bcx.build.Not(sub.val));
25022501
}
25032502
ast::neg. {
25042503
let sub = trans_expr(cx, e);
2505-
let dr = autoderef(sub.bcx, sub.val, ty::expr_ty(bcx_tcx(cx), e));
25062504
if ty::struct(bcx_tcx(cx), e_ty) == ty::ty_float {
2507-
ret rslt(dr.bcx, dr.bcx.build.FNeg(dr.val));
2508-
} else { ret rslt(dr.bcx, sub.bcx.build.Neg(dr.val)); }
2505+
ret rslt(sub.bcx, sub.bcx.build.FNeg(sub.val));
2506+
} else { ret rslt(sub.bcx, sub.bcx.build.Neg(sub.val)); }
25092507
}
25102508
ast::box(_) {
25112509
let lv = trans_lval(cx, e);
@@ -2532,28 +2530,18 @@ fn trans_unary(cx: &@block_ctxt, op: ast::unop, e: &@ast::expr,
25322530
}
25332531
}
25342532

2535-
fn trans_compare(cx0: &@block_ctxt, op: ast::binop,
2536-
lhs0: ValueRef, lhs_t: ty::t, rhs0: ValueRef,
2537-
rhs_t: ty::t) -> result {
2538-
// Autoderef both sides.
2539-
2540-
let cx = cx0;
2541-
let lhs_r = autoderef(cx, lhs0, lhs_t);
2542-
let lhs = lhs_r.val;
2543-
cx = lhs_r.bcx;
2544-
let rhs_r = autoderef(cx, rhs0, rhs_t);
2545-
let rhs = rhs_r.val;
2546-
cx = rhs_r.bcx;
2533+
fn trans_compare(cx: &@block_ctxt, op: ast::binop,
2534+
lhs: ValueRef, lhs_t: ty::t, rhs: ValueRef,
2535+
rhs_t: ty::t) -> result {
25472536
// Determine the operation we need.
2548-
25492537
let llop;
25502538
alt op {
25512539
ast::eq. | ast::ne. { llop = C_u8(abi::cmp_glue_op_eq); }
25522540
ast::lt. | ast::ge. { llop = C_u8(abi::cmp_glue_op_lt); }
25532541
ast::le. | ast::gt. { llop = C_u8(abi::cmp_glue_op_le); }
25542542
}
25552543

2556-
let rs = compare(cx, lhs, rhs, rhs_r.ty, llop);
2544+
let rs = compare(cx, lhs, rhs, rhs_t, llop);
25572545

25582546
// Invert the result if necessary.
25592547
alt op {
@@ -3320,15 +3308,10 @@ fn trans_binary(cx: &@block_ctxt, op: ast::binop, a: &@ast::expr,
33203308
alt op {
33213309
ast::and. {
33223310
// Lazy-eval and
3323-
let lhs_expr = trans_expr(cx, a);
3324-
let lhs_res =
3325-
autoderef(lhs_expr.bcx, lhs_expr.val,
3326-
ty::expr_ty(bcx_tcx(cx), a));
3311+
let lhs_res = trans_expr(cx, a);
33273312
let rhs_cx = new_scope_block_ctxt(cx, "rhs");
3328-
let rhs_expr = trans_expr(rhs_cx, b);
3329-
let rhs_res =
3330-
autoderef(rhs_expr.bcx, rhs_expr.val,
3331-
ty::expr_ty(bcx_tcx(cx), b));
3313+
let rhs_res = trans_expr(rhs_cx, b);
3314+
33323315
let lhs_false_cx = new_scope_block_ctxt(cx, "lhs false");
33333316
let lhs_false_res = rslt(lhs_false_cx, C_bool(false));
33343317

@@ -3343,15 +3326,9 @@ fn trans_binary(cx: &@block_ctxt, op: ast::binop, a: &@ast::expr,
33433326
}
33443327
ast::or. {
33453328
// Lazy-eval or
3346-
let lhs_expr = trans_expr(cx, a);
3347-
let lhs_res =
3348-
autoderef(lhs_expr.bcx, lhs_expr.val,
3349-
ty::expr_ty(bcx_tcx(cx), a));
3329+
let lhs_res = trans_expr(cx, a);
33503330
let rhs_cx = new_scope_block_ctxt(cx, "rhs");
3351-
let rhs_expr = trans_expr(rhs_cx, b);
3352-
let rhs_res =
3353-
autoderef(rhs_expr.bcx, rhs_expr.val,
3354-
ty::expr_ty(bcx_tcx(cx), b));
3331+
let rhs_res = trans_expr(rhs_cx, b);
33553332
let lhs_true_cx = new_scope_block_ctxt(cx, "lhs true");
33563333
let lhs_true_res = rslt(lhs_true_cx, C_bool(true));
33573334

@@ -3363,15 +3340,12 @@ fn trans_binary(cx: &@block_ctxt, op: ast::binop, a: &@ast::expr,
33633340
}
33643341
_ {
33653342
// Remaining cases are eager:
3343+
let lhs = trans_expr(cx, a);
3344+
let rhs = trans_expr(lhs.bcx, b);
33663345

3367-
let lhs_expr = trans_expr(cx, a);
3368-
let lhty = ty::expr_ty(bcx_tcx(cx), a);
3369-
let lhs = autoderef(lhs_expr.bcx, lhs_expr.val, lhty);
3370-
let rhs_expr = trans_expr(lhs.bcx, b);
3371-
let rhty = ty::expr_ty(bcx_tcx(cx), b);
3372-
let rhs = autoderef(rhs_expr.bcx, rhs_expr.val, rhty);
3373-
3374-
ret trans_eager_binop(rhs.bcx, op, lhs.val, lhs.ty, rhs.val, rhs.ty);
3346+
ret trans_eager_binop(rhs.bcx, op,
3347+
lhs.val, ty::expr_ty(bcx_tcx(cx), a),
3348+
rhs.val, ty::expr_ty(bcx_tcx(cx), b));
33753349
}
33763350
}
33773351
}

trunk/src/comp/middle/typeck.rs

Lines changed: 28 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -890,7 +890,6 @@ mod unify {
890890
}
891891
}
892892

893-
tag autoderef_kind { AUTODEREF_OK; NO_AUTODEREF; AUTODEREF_BLOCK_COERCE; }
894893

895894
// FIXME This is almost a duplicate of ty::type_autoderef, with structure_of
896895
// instead of ty::struct.
@@ -929,27 +928,8 @@ fn do_autoderef(fcx: &@fn_ctxt, sp: &span, t: &ty::t) -> ty::t {
929928
fail;
930929
}
931930

932-
fn add_boxes(ccx: &@crate_ctxt, n: uint, t: &ty::t) -> ty::t {
933-
let t1 = t;
934-
while n != 0u { t1 = ty::mk_imm_box(ccx.tcx, t1); n -= 1u; }
935-
ret t1;
936-
}
937-
938-
fn count_boxes(fcx: &@fn_ctxt, sp: &span, t: &ty::t) -> uint {
939-
let n = 0u;
940-
let t1 = t;
941-
while true {
942-
alt structure_of(fcx, sp, t1) {
943-
ty::ty_box(inner) { n += 1u; t1 = inner.ty; }
944-
_ { ret n; }
945-
}
946-
}
947-
fail;
948-
}
949-
950931
fn do_fn_block_coerce(fcx: &@fn_ctxt, sp: &span, actual: &ty::t,
951932
expected: &ty::t) -> ty::t {
952-
953933
// fns can be silently coerced to blocks when being used as
954934
// function call or bind arguments, but not the reverse.
955935
// If our actual type is a fn and our expected type is a block,
@@ -986,27 +966,26 @@ type ty_param_substs_and_ty = {substs: [ty::t], ty: ty::t};
986966
mod demand {
987967
fn simple(fcx: &@fn_ctxt, sp: &span, expected: &ty::t, actual: &ty::t) ->
988968
ty::t {
989-
ret full(fcx, sp, expected, actual, ~[], NO_AUTODEREF).ty;
969+
full(fcx, sp, expected, actual, ~[], false).ty
970+
}
971+
fn block_coerce(fcx: &@fn_ctxt, sp: &span,
972+
expected: &ty::t, actual: &ty::t) -> ty::t {
973+
full(fcx, sp, expected, actual, ~[], true).ty
990974
}
991-
fn autoderef(fcx: &@fn_ctxt, sp: &span, expected: &ty::t, actual: &ty::t,
992-
adk: autoderef_kind) -> ty::t {
993-
ret full(fcx, sp, expected, actual, ~[], adk).ty;
975+
976+
fn with_substs(fcx: &@fn_ctxt, sp: &span, expected: &ty::t,
977+
actual: &ty::t, ty_param_substs_0: &[ty::t]) ->
978+
ty_param_substs_and_ty {
979+
full(fcx, sp, expected, actual, ty_param_substs_0, false)
994980
}
995981

996982
// Requires that the two types unify, and prints an error message if they
997983
// don't. Returns the unified type and the type parameter substitutions.
998-
fn full(fcx: &@fn_ctxt, sp: &span, expected: &ty::t, actual: &ty::t,
999-
ty_param_substs_0: &[ty::t], adk: autoderef_kind) ->
984+
fn full(fcx: &@fn_ctxt, sp: &span, expected: ty::t, actual: ty::t,
985+
ty_param_substs_0: &[ty::t], do_block_coerece: bool) ->
1000986
ty_param_substs_and_ty {
1001-
let expected_1 = expected;
1002-
let actual_1 = actual;
1003-
let implicit_boxes = 0u;
1004-
if adk == AUTODEREF_OK {
1005-
expected_1 = do_autoderef(fcx, sp, expected_1);
1006-
actual_1 = do_autoderef(fcx, sp, actual_1);
1007-
implicit_boxes = count_boxes(fcx, sp, actual);
1008-
} else if (adk == AUTODEREF_BLOCK_COERCE) {
1009-
actual_1 = do_fn_block_coerce(fcx, sp, actual, expected);
987+
if do_block_coerece {
988+
actual = do_fn_block_coerce(fcx, sp, actual, expected);
1010989
}
1011990

1012991
let ty_param_substs: [mutable ty::t] = ~[mutable];
@@ -1021,33 +1000,31 @@ mod demand {
10211000
}
10221001

10231002
fn mk_result(fcx: &@fn_ctxt, result_ty: &ty::t,
1024-
ty_param_subst_var_ids: &[int], implicit_boxes: uint) ->
1003+
ty_param_subst_var_ids: &[int]) ->
10251004
ty_param_substs_and_ty {
10261005
let result_ty_param_substs: [ty::t] = ~[];
10271006
for var_id: int in ty_param_subst_var_ids {
10281007
let tp_subst = ty::mk_var(fcx.ccx.tcx, var_id);
10291008
result_ty_param_substs += ~[tp_subst];
10301009
}
1031-
ret {substs: result_ty_param_substs,
1032-
ty: add_boxes(fcx.ccx, implicit_boxes, result_ty)};
1010+
ret {substs: result_ty_param_substs, ty: result_ty};
10331011
}
10341012

10351013

1036-
alt unify::unify(fcx, expected_1, actual_1) {
1014+
alt unify::unify(fcx, expected, actual) {
10371015
ures_ok(t) {
1038-
ret mk_result(fcx, t, ty_param_subst_var_ids, implicit_boxes);
1016+
ret mk_result(fcx, t, ty_param_subst_var_ids);
10391017
}
10401018
ures_err(err) {
1041-
let e_err = resolve_type_vars_if_possible(fcx, expected_1);
1042-
let a_err = resolve_type_vars_if_possible(fcx, actual_1);
1019+
let e_err = resolve_type_vars_if_possible(fcx, expected);
1020+
let a_err = resolve_type_vars_if_possible(fcx, actual);
10431021
fcx.ccx.tcx.sess.span_err(sp,
10441022
"mismatched types: expected " +
10451023
ty_to_str(fcx.ccx.tcx, e_err) +
10461024
" but found " +
10471025
ty_to_str(fcx.ccx.tcx, a_err) + " ("
10481026
+ ty::type_err_to_str(err) + ")");
1049-
ret mk_result(fcx, expected_1, ty_param_subst_var_ids,
1050-
implicit_boxes);
1027+
ret mk_result(fcx, expected, ty_param_subst_var_ids);
10511028
}
10521029
}
10531030
}
@@ -1379,8 +1356,8 @@ fn check_pat(fcx: &@fn_ctxt, map: &ast::pat_id_map, pat: &@ast::pat,
13791356
path_tpot);
13801357

13811358
let path_tpt =
1382-
demand::full(fcx, pat.span, expected, ctor_ty, expected_tps,
1383-
NO_AUTODEREF);
1359+
demand::with_substs(fcx, pat.span, expected, ctor_ty,
1360+
expected_tps);
13841361
path_tpot =
13851362
{substs: some[[ty::t]](path_tpt.substs), ty: path_tpt.ty};
13861363

@@ -1604,13 +1581,11 @@ fn check_expr_with_unifier(fcx: &@fn_ctxt, expr: &@ast::expr,
16041581
}
16051582

16061583
// Check the arguments.
1607-
let unifier =
1608-
bind demand::autoderef(_, _, _, _, AUTODEREF_BLOCK_COERCE);
16091584
let i = 0u;
16101585
for a_opt: option::t[@ast::expr] in args {
16111586
alt a_opt {
16121587
some(a) {
1613-
bot |= check_expr_with_unifier(fcx, a, unifier,
1588+
bot |= check_expr_with_unifier(fcx, a, demand::block_coerce,
16141589
arg_tys.(i).ty);
16151590
}
16161591
none. { }
@@ -1776,12 +1751,10 @@ fn check_expr_with_unifier(fcx: &@fn_ctxt, expr: &@ast::expr,
17761751
let lhs_t = next_ty_var(fcx);
17771752
bot = check_expr_with(fcx, lhs, lhs_t);
17781753

1779-
let unifier = bind demand::autoderef(_, _, _, _, AUTODEREF_OK);
1780-
let rhs_bot = check_expr_with_unifier(fcx, rhs, unifier, lhs_t);
1754+
let rhs_bot = check_expr_with(fcx, rhs, lhs_t);
17811755
if !ast::lazy_binop(binop) { bot |= rhs_bot; }
17821756

1783-
let deref_t = do_autoderef(fcx, expr.span, lhs_t);
1784-
check_binop_type_compat(fcx, expr.span, deref_t, binop);
1757+
check_binop_type_compat(fcx, expr.span, lhs_t, binop);
17851758

17861759
let t =
17871760
alt binop {
@@ -1791,7 +1764,7 @@ fn check_expr_with_unifier(fcx: &@fn_ctxt, expr: &@ast::expr,
17911764
ast::ne. { ty::mk_bool(tcx) }
17921765
ast::ge. { ty::mk_bool(tcx) }
17931766
ast::gt. { ty::mk_bool(tcx) }
1794-
_ { deref_t }
1767+
_ { lhs_t }
17951768
};
17961769
write::ty_only_fixup(fcx, id, t);
17971770
}
@@ -1838,8 +1811,7 @@ fn check_expr_with_unifier(fcx: &@fn_ctxt, expr: &@ast::expr,
18381811
}
18391812
}
18401813
ast::neg. {
1841-
oper_t = structurally_resolved_type
1842-
(fcx, oper.span, do_autoderef(fcx, expr.span, oper_t));
1814+
oper_t = structurally_resolved_type(fcx, oper.span, oper_t);
18431815
if !(ty::type_is_integral(tcx, oper_t) ||
18441816
ty::type_is_fp(tcx, oper_t)) {
18451817
tcx.sess.span_fatal(expr.span, "applying unary minus to \

trunk/src/test/run-pass/autoderef-full-lval.rs renamed to trunk/src/test/compile-fail/autoderef-full-lval.rs

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,4 @@
1-
2-
3-
4-
// -*- rust -*-
1+
// error-pattern: binary operation + cannot be applied to type
52
type clam = {x: @int, y: @int};
63

74
type fish = {a: @int};
@@ -17,4 +14,4 @@ fn main() {
1714
let answer: int = forty.a + two.a;
1815
log answer;
1916
assert (answer == 42);
20-
}
17+
}

0 commit comments

Comments
 (0)