Skip to content

Commit 4ba3158

Browse files
bogglegraydon
authored andcommitted
parse: typeck: enabling trivial casts of tail-call return values
introduces ctypes::m_* machine type aliases for int, uint, float depending on cfg(target_arch) that are used in tests
1 parent 29f7cdf commit 4ba3158

File tree

9 files changed

+124
-47
lines changed

9 files changed

+124
-47
lines changed

src/comp/middle/trans.rs

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4088,10 +4088,8 @@ fn trans_expr(bcx: @block_ctxt, e: @ast::expr, dest: dest) -> @block_ctxt {
40884088
}
40894089
ast::expr_cast(val, _) {
40904090
alt tcx.cast_map.find(e.id) {
4091-
option::none. { ret trans_cast(bcx, val, e.id, dest); }
4092-
some { alt option::get(some) {
4093-
ty::triv_cast. { ret trans_expr(bcx, val, dest); }
4094-
} }
4091+
some(ty::triv_cast.) { ret trans_expr(bcx, val, dest); }
4092+
_ { ret trans_cast(bcx, val, e.id, dest); }
40954093
}
40964094
}
40974095
ast::expr_anon_obj(anon_obj) {
@@ -4122,7 +4120,7 @@ fn trans_expr(bcx: @block_ctxt, e: @ast::expr, dest: dest) -> @block_ctxt {
41224120
// that is_call_expr(ex) -- but we don't support that
41234121
// yet
41244122
// FIXME
4125-
check (ast_util::is_call_expr(ex));
4123+
check (ast_util::is_tail_call_expr(ex));
41264124
ret trans_be(bcx, ex);
41274125
}
41284126
ast::expr_fail(expr) {
@@ -4455,7 +4453,8 @@ fn trans_ret(bcx: @block_ctxt, e: option::t<@ast::expr>) -> @block_ctxt {
44554453
fn build_return(bcx: @block_ctxt) { Br(bcx, bcx_fcx(bcx).llreturn); }
44564454

44574455
// fn trans_be(cx: &@block_ctxt, e: &@ast::expr) -> result {
4458-
fn trans_be(cx: @block_ctxt, e: @ast::expr) : ast_util::is_call_expr(e) ->
4456+
fn trans_be(cx: @block_ctxt, e: @ast::expr) :
4457+
ast_util::is_tail_call_expr(e) ->
44594458
@block_ctxt {
44604459
// FIXME: Turn this into a real tail call once
44614460
// calling convention issues are settled

src/comp/middle/ty.rs

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1501,7 +1501,7 @@ fn eq_ty(&&a: t, &&b: t) -> bool { ret a == b; }
15011501
// Convert type to machine type
15021502
// (i.e. replace uint, int, float with target architecture machine types)
15031503
//
1504-
// Somewhat expensive but casts that need this should be rare
1504+
// FIXME somewhat expensive but this should only be called rarely
15051505
fn ty_to_machine_ty(cx: ctxt, ty: t) -> t {
15061506
fn sub_fn(cx: ctxt, uint_ty: t, int_ty: t, float_ty: t, in: t) -> t {
15071507
alt struct(cx, in) {
@@ -1525,12 +1525,9 @@ fn ty_to_machine_ty(cx: ctxt, ty: t) -> t {
15251525
// equal or if they are equal after substituting all occurences of
15261526
// machine independent primitive types by their machine type equivalents
15271527
// for the current target architecture
1528-
//
1529-
// Somewhat expensive but casts that need this should be rare
15301528
fn triv_eq_ty(cx: ctxt, &&a: t, &&b: t) -> bool {
1531-
let mach_a = ty_to_machine_ty(cx, a);
1532-
let mach_b = ty_to_machine_ty(cx, b );
1533-
ret eq_ty(a, b) || eq_ty(mach_a, mach_b);
1529+
ret eq_ty(a, b)
1530+
|| eq_ty(ty_to_machine_ty(cx, a), ty_to_machine_ty(cx, b));
15341531
}
15351532

15361533
// Type lookups

src/comp/middle/typeck.rs

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1846,8 +1846,21 @@ fn check_expr_with_unifier(fcx: @fn_ctxt, expr: @ast::expr, unify: unifier,
18461846
}
18471847
ast::expr_be(e) {
18481848
// FIXME: prove instead of assert
1849-
assert (ast_util::is_call_expr(e));
1849+
assert (ast_util::is_tail_call_expr(e));
18501850
check_expr_with(fcx, e, fcx.ret_ty);
1851+
1852+
alt e.node {
1853+
ast::expr_cast(_, _) {
1854+
alt tcx.cast_map.find(e.id) {
1855+
option::some(ty::triv_cast.) { }
1856+
_ { tcx.sess.span_err(expr.span,
1857+
"non-trivial cast of tail-call return value");
1858+
}
1859+
}
1860+
}
1861+
_ { /* regular tail call */ }
1862+
}
1863+
18511864
bot = true;
18521865
write::nil_ty(tcx, id);
18531866
}
@@ -2112,8 +2125,10 @@ fn check_expr_with_unifier(fcx: @fn_ctxt, expr: @ast::expr, unify: unifier,
21122125
ty_to_str(tcx, t_1));
21132126
}
21142127

2128+
// mark as triv_cast for later dropping in trans
21152129
if ty::triv_eq_ty(tcx, t_1, t_e)
21162130
{ tcx.cast_map.insert(expr.id, ty::triv_cast); }
2131+
21172132
write::ty_only_fixup(fcx, id, t_1);
21182133
}
21192134
ast::expr_vec(args, mut) {

src/comp/syntax/ast_util.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -175,6 +175,14 @@ pure fn is_call_expr(e: @expr) -> bool {
175175
alt e.node { expr_call(_, _, _) { true } _ { false } }
176176
}
177177

178+
pure fn is_tail_call_expr(e: @expr) -> bool {
179+
alt e.node {
180+
expr_call(_, _, _) { true }
181+
expr_cast(inner_e, _) { is_call_expr(inner_e) }
182+
_ { false }
183+
}
184+
}
185+
178186
fn is_constraint_arg(e: @expr) -> bool {
179187
alt e.node {
180188
expr_lit(_) { ret true; }

src/comp/syntax/parse/parser.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -962,7 +962,7 @@ fn parse_bottom_expr(p: parser) -> @ast::expr {
962962
let e = parse_expr(p);
963963

964964
// FIXME: Is this the right place for this check?
965-
if /*check*/ast_util::is_call_expr(e) {
965+
if /*check*/ ast_util::is_tail_call_expr(e) {
966966
hi = e.span.hi;
967967
ex = ast::expr_be(e);
968968
} else { p.fatal("Non-call expression in tail call"); }

src/lib/ctypes.rs

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ Definitions useful for C interop
55
*/
66

77
type c_int = i32;
8+
type c_uint = u32;
89

910
type void = int; // Not really the same as C
1011
type long = int;
@@ -15,8 +16,20 @@ type intptr_t = uint;
1516
type uintptr_t = uint;
1617
type uint32_t = u32;
1718

18-
// This *must* match with "import c_float = fXX" in std::math per arch
19-
type c_float = f64;
19+
// machine type equivalents of rust int, uint, float
20+
21+
#[cfg(target_arch="x86")]
22+
type m_int = i32;
23+
#[cfg(target_arch="x86_64")]
24+
type m_int = i64;
25+
26+
#[cfg(target_arch="x86")]
27+
type m_uint = u32;
28+
#[cfg(target_arch="x86_64")]
29+
type m_uint = u64;
30+
31+
// This *must* match with "import m_float = fXX" in std::math per arch
32+
type m_float = f64;
2033

2134
type size_t = uint;
2235
type ssize_t = int;

0 commit comments

Comments
 (0)