Eliminate match checks in trans and typeck
This commit is contained in:
2
src/llvm
2
src/llvm
Submodule src/llvm updated: b55be285d1...ab9efdacc2
@@ -189,7 +189,7 @@ impl session {
|
|||||||
}
|
}
|
||||||
// This exists to help with refactoring to eliminate impossible
|
// This exists to help with refactoring to eliminate impossible
|
||||||
// cases later on
|
// cases later on
|
||||||
fn impossible_case(sp: span, msg: ~str) -> ! {
|
fn impossible_case(sp: span, msg: &str) -> ! {
|
||||||
self.span_bug(sp, #fmt("Impossible case reached: %s", msg));
|
self.span_bug(sp, #fmt("Impossible case reached: %s", msg));
|
||||||
}
|
}
|
||||||
fn ppregions() -> bool { self.debugging_opt(ppregions) }
|
fn ppregions() -> bool { self.debugging_opt(ppregions) }
|
||||||
|
|||||||
@@ -305,10 +305,10 @@ fn extract_variant_args(bcx: block, pat_id: ast::node_id,
|
|||||||
{vals: ~[ValueRef], bcx: block} {
|
{vals: ~[ValueRef], bcx: block} {
|
||||||
let _icx = bcx.insn_ctxt("alt::extract_variant_args");
|
let _icx = bcx.insn_ctxt("alt::extract_variant_args");
|
||||||
let ccx = bcx.fcx.ccx;
|
let ccx = bcx.fcx.ccx;
|
||||||
let enum_ty_substs = match check ty::get(node_id_type(bcx, pat_id))
|
let enum_ty_substs = match ty::get(node_id_type(bcx, pat_id))
|
||||||
.struct {
|
.struct {
|
||||||
|
|
||||||
ty::ty_enum(id, substs) => { assert id == vdefs.enm; substs.tps }
|
ty::ty_enum(id, substs) => { assert id == vdefs.enm; substs.tps }
|
||||||
|
_ => bcx.sess().bug(~"extract_variant_args: pattern has non-enum type")
|
||||||
};
|
};
|
||||||
let mut blobptr = val;
|
let mut blobptr = val;
|
||||||
let variants = ty::enum_variants(ccx.tcx, vdefs.enm);
|
let variants = ty::enum_variants(ccx.tcx, vdefs.enm);
|
||||||
@@ -667,11 +667,13 @@ fn compile_submatch(bcx: block, m: match_, vals: ~[ValueRef],
|
|||||||
match kind {
|
match kind {
|
||||||
single => Br(bcx, opt_cx.llbb),
|
single => Br(bcx, opt_cx.llbb),
|
||||||
switch => {
|
switch => {
|
||||||
match check trans_opt(bcx, opt) {
|
match trans_opt(bcx, opt) {
|
||||||
single_result(r) => {
|
single_result(r) => {
|
||||||
llvm::LLVMAddCase(sw, r.val, opt_cx.llbb);
|
llvm::LLVMAddCase(sw, r.val, opt_cx.llbb);
|
||||||
bcx = r.bcx;
|
bcx = r.bcx;
|
||||||
}
|
}
|
||||||
|
_ => bcx.sess().bug(~"in compile_submatch, expected \
|
||||||
|
trans_opt to return a single_result")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
compare => {
|
compare => {
|
||||||
@@ -892,7 +894,8 @@ fn trans_alt_inner(scope_cx: block, expr: @ast::expr, arms: ~[ast::arm],
|
|||||||
let arm_dest = dup_for_join(dest);
|
let arm_dest = dup_for_join(dest);
|
||||||
vec::push(arm_dests, arm_dest);
|
vec::push(arm_dests, arm_dest);
|
||||||
let mut arm_cx = trans_block(body_cx, a.body, arm_dest);
|
let mut arm_cx = trans_block(body_cx, a.body, arm_dest);
|
||||||
arm_cx = trans_block_cleanups(arm_cx, body_cx);
|
arm_cx = trans_block_cleanups(arm_cx,
|
||||||
|
block_cleanups(body_cx));
|
||||||
vec::push(arm_cxs, arm_cx);
|
vec::push(arm_cxs, arm_cx);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1962,7 +1962,7 @@ fn trans_if(cx: block, cond: @ast::expr, thn: ast::blk,
|
|||||||
let else_cx = scope_block(bcx, els.info(), ~"else");
|
let else_cx = scope_block(bcx, els.info(), ~"else");
|
||||||
CondBr(bcx, cond_val, then_cx.llbb, else_cx.llbb);
|
CondBr(bcx, cond_val, then_cx.llbb, else_cx.llbb);
|
||||||
let then_bcx = trans_block(then_cx, thn, then_dest);
|
let then_bcx = trans_block(then_cx, thn, then_dest);
|
||||||
let then_bcx = trans_block_cleanups(then_bcx, then_cx);
|
let then_bcx = trans_block_cleanups(then_bcx, block_cleanups(then_cx));
|
||||||
// Calling trans_block directly instead of trans_expr
|
// Calling trans_block directly instead of trans_expr
|
||||||
// because trans_expr will create another scope block
|
// because trans_expr will create another scope block
|
||||||
// context for the block, but we've already got the
|
// context for the block, but we've already got the
|
||||||
@@ -1983,7 +1983,7 @@ fn trans_if(cx: block, cond: @ast::expr, thn: ast::blk,
|
|||||||
}
|
}
|
||||||
_ => else_cx
|
_ => else_cx
|
||||||
};
|
};
|
||||||
let else_bcx = trans_block_cleanups(else_bcx, else_cx);
|
let else_bcx = trans_block_cleanups(else_bcx, block_cleanups(else_cx));
|
||||||
return join_returns(cx,
|
return join_returns(cx,
|
||||||
~[then_bcx, else_bcx], ~[then_dest, else_dest], dest);
|
~[then_bcx, else_bcx], ~[then_dest, else_dest], dest);
|
||||||
}
|
}
|
||||||
@@ -1998,7 +1998,8 @@ fn trans_while(cx: block, cond: @ast::expr, body: ast::blk)
|
|||||||
Br(cx, loop_cx.llbb);
|
Br(cx, loop_cx.llbb);
|
||||||
Br(loop_cx, cond_cx.llbb);
|
Br(loop_cx, cond_cx.llbb);
|
||||||
let cond_res = trans_temp_expr(cond_cx, cond);
|
let cond_res = trans_temp_expr(cond_cx, cond);
|
||||||
let cond_bcx = trans_block_cleanups(cond_res.bcx, cond_cx);
|
let cond_bcx = trans_block_cleanups(cond_res.bcx,
|
||||||
|
block_cleanups(cond_cx));
|
||||||
CondBr(cond_bcx, cond_res.val, body_cx.llbb, next_cx.llbb);
|
CondBr(cond_bcx, cond_res.val, body_cx.llbb, next_cx.llbb);
|
||||||
let body_end = trans_block(body_cx, body, ignore);
|
let body_end = trans_block(body_cx, body, ignore);
|
||||||
cleanup_and_Br(body_end, body_cx, cond_cx.llbb);
|
cleanup_and_Br(body_end, body_cx, cond_cx.llbb);
|
||||||
@@ -2113,19 +2114,19 @@ fn make_mono_id(ccx: @crate_ctxt, item: ast::def_id, substs: ~[ty::t],
|
|||||||
_ => ()
|
_ => ()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
mono_precise(subst, if v.len() > 0u { some(v) } else { none })
|
(subst, if v.len() > 0u { some(v) } else { none })
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
none => {
|
none => {
|
||||||
vec::map(substs, |subst| mono_precise(subst, none))
|
vec::map(substs, |subst| (subst, none))
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
let param_ids = match param_uses {
|
let param_ids = match param_uses {
|
||||||
some(uses) => {
|
some(uses) => {
|
||||||
vec::map2(precise_param_ids, uses, |id, uses| {
|
vec::map2(precise_param_ids, uses, |id, uses| {
|
||||||
match check id {
|
match id {
|
||||||
mono_precise(_, some(_)) => id,
|
(a, b@some(_)) => mono_precise(a, b),
|
||||||
mono_precise(subst, none) => {
|
(subst, none) => {
|
||||||
if uses == 0u { mono_any }
|
if uses == 0u { mono_any }
|
||||||
else if uses == type_use::use_repr &&
|
else if uses == type_use::use_repr &&
|
||||||
!ty::type_needs_drop(ccx.tcx, subst) {
|
!ty::type_needs_drop(ccx.tcx, subst) {
|
||||||
@@ -2137,12 +2138,13 @@ fn make_mono_id(ccx: @crate_ctxt, item: ast::def_id, substs: ~[ty::t],
|
|||||||
if size == 1u && ty::type_is_nil(subst) {
|
if size == 1u && ty::type_is_nil(subst) {
|
||||||
mono_repr(0u, 0u)
|
mono_repr(0u, 0u)
|
||||||
} else { mono_repr(size, align) }
|
} else { mono_repr(size, align) }
|
||||||
} else { id }
|
} else { mono_precise(subst, none) }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
none => precise_param_ids
|
none => precise_param_ids.map(|x| { let (a, b) = x;
|
||||||
|
mono_precise(a, b) })
|
||||||
};
|
};
|
||||||
@{def: item, params: param_ids}
|
@{def: item, params: param_ids}
|
||||||
}
|
}
|
||||||
@@ -2367,7 +2369,7 @@ fn maybe_instantiate_inline(ccx: @crate_ctxt, fn_id: ast::def_id)
|
|||||||
csearch::found_parent(parent_id, ast::ii_item(item)) => {
|
csearch::found_parent(parent_id, ast::ii_item(item)) => {
|
||||||
ccx.external.insert(parent_id, some(item.id));
|
ccx.external.insert(parent_id, some(item.id));
|
||||||
let mut my_id = 0;
|
let mut my_id = 0;
|
||||||
match check item.node {
|
match item.node {
|
||||||
ast::item_enum(_, _) => {
|
ast::item_enum(_, _) => {
|
||||||
let vs_here = ty::enum_variants(ccx.tcx, local_def(item.id));
|
let vs_here = ty::enum_variants(ccx.tcx, local_def(item.id));
|
||||||
let vs_there = ty::enum_variants(ccx.tcx, parent_id);
|
let vs_there = ty::enum_variants(ccx.tcx, parent_id);
|
||||||
@@ -2376,6 +2378,8 @@ fn maybe_instantiate_inline(ccx: @crate_ctxt, fn_id: ast::def_id)
|
|||||||
ccx.external.insert(there.id, some(here.id.node));
|
ccx.external.insert(there.id, some(here.id.node));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
_ => ccx.sess.bug(~"maybe_instantiate_inline: item has a \
|
||||||
|
non-enum parent")
|
||||||
}
|
}
|
||||||
trans_item(ccx, *item);
|
trans_item(ccx, *item);
|
||||||
local_def(my_id)
|
local_def(my_id)
|
||||||
@@ -2756,7 +2760,7 @@ fn trans_lval(cx: block, e: @ast::expr) -> lval_result {
|
|||||||
let ccx = cx.ccx();
|
let ccx = cx.ccx();
|
||||||
let sub = trans_temp_expr(cx, base);
|
let sub = trans_temp_expr(cx, base);
|
||||||
let t = expr_ty(cx, base);
|
let t = expr_ty(cx, base);
|
||||||
let val = match check ty::get(t).struct {
|
let val = match ty::get(t).struct {
|
||||||
ty::ty_box(_) => {
|
ty::ty_box(_) => {
|
||||||
let non_gc_val = non_gc_box_cast(sub.bcx, sub.val);
|
let non_gc_val = non_gc_box_cast(sub.bcx, sub.val);
|
||||||
GEPi(sub.bcx, non_gc_val, ~[0u, abi::box_field_body])
|
GEPi(sub.bcx, non_gc_val, ~[0u, abi::box_field_body])
|
||||||
@@ -2770,7 +2774,9 @@ fn trans_lval(cx: block, e: @ast::expr) -> lval_result {
|
|||||||
let ellty = T_ptr(type_of(ccx, ety));
|
let ellty = T_ptr(type_of(ccx, ety));
|
||||||
PointerCast(sub.bcx, sub.val, ellty)
|
PointerCast(sub.bcx, sub.val, ellty)
|
||||||
}
|
}
|
||||||
ty::ty_ptr(_) | ty::ty_rptr(_,_) => sub.val
|
ty::ty_ptr(_) | ty::ty_rptr(_,_) => sub.val,
|
||||||
|
_ => cx.sess().impossible_case(e.span, #fmt("unary operand \
|
||||||
|
may not have type %s", cx.ty_to_str(t)))
|
||||||
};
|
};
|
||||||
return lval_owned(sub.bcx, val);
|
return lval_owned(sub.bcx, val);
|
||||||
}
|
}
|
||||||
@@ -2917,22 +2923,13 @@ fn trans_cast(cx: block, e: @ast::expr, id: ast::node_id,
|
|||||||
return store_in_dest(e_res.bcx, newval, dest);
|
return store_in_dest(e_res.bcx, newval, dest);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn trans_loop_body(bcx: block, e: @ast::expr, ret_flag: option<ValueRef>,
|
fn trans_loop_body(bcx: block, id: ast::node_id,
|
||||||
|
decl: ast::fn_decl, body: ast::blk,
|
||||||
|
proto: ty::fn_proto, cap: ast::capture_clause,
|
||||||
|
ret_flag: option<ValueRef>,
|
||||||
dest: dest) -> block {
|
dest: dest) -> block {
|
||||||
match check e.node {
|
closure::trans_expr_fn(bcx, proto, decl, body, id,
|
||||||
ast::expr_loop_body(b@@{
|
cap, some(ret_flag), dest)
|
||||||
node: ast::expr_fn_block(decl, body, cap),
|
|
||||||
_
|
|
||||||
}) => {
|
|
||||||
match check ty::get(expr_ty(bcx, e)).struct {
|
|
||||||
ty::ty_fn({proto, _}) => {
|
|
||||||
closure::trans_expr_fn(bcx, proto, decl, body, b.id,
|
|
||||||
cap, some(ret_flag),
|
|
||||||
dest)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// temp_cleanups: cleanups that should run only if failure occurs before the
|
// temp_cleanups: cleanups that should run only if failure occurs before the
|
||||||
@@ -2950,12 +2947,21 @@ fn trans_arg_expr(cx: block, arg: ty::arg, lldestty: TypeRef, e: @ast::expr,
|
|||||||
// translate the arg expr as an lvalue
|
// translate the arg expr as an lvalue
|
||||||
let lv = match ret_flag {
|
let lv = match ret_flag {
|
||||||
// If there is a ret_flag, this *must* be a loop body
|
// If there is a ret_flag, this *must* be a loop body
|
||||||
some(_) => match check e.node {
|
some(_) => match e.node {
|
||||||
ast::expr_loop_body(blk) => {
|
ast::expr_loop_body(blk@@{node:
|
||||||
|
ast::expr_fn_block(decl, body, cap),_}) => {
|
||||||
let scratch = alloc_ty(cx, expr_ty(cx, blk));
|
let scratch = alloc_ty(cx, expr_ty(cx, blk));
|
||||||
let bcx = trans_loop_body(cx, e, ret_flag, save_in(scratch));
|
let proto = match ty::get(expr_ty(cx, e)).struct {
|
||||||
|
ty::ty_fn({proto, _}) => proto,
|
||||||
|
_ => cx.sess().impossible_case(e.span, ~"Loop body has \
|
||||||
|
non-fn ty")
|
||||||
|
};
|
||||||
|
let bcx = trans_loop_body(cx, blk.id, decl, body, proto,
|
||||||
|
cap, ret_flag, save_in(scratch));
|
||||||
{bcx: bcx, val: scratch, kind: lv_temporary}
|
{bcx: bcx, val: scratch, kind: lv_temporary}
|
||||||
}
|
}
|
||||||
|
_ => cx.sess().impossible_case(e.span, ~"ret_flag with non-loop-\
|
||||||
|
body expr")
|
||||||
},
|
},
|
||||||
none => {
|
none => {
|
||||||
trans_temp_lval(cx, e)
|
trans_temp_lval(cx, e)
|
||||||
@@ -3462,21 +3468,25 @@ fn trans_tup(bcx: block, elts: ~[@ast::expr], dest: dest) -> block {
|
|||||||
|
|
||||||
fn trans_rec(bcx: block, fields: ~[ast::field],
|
fn trans_rec(bcx: block, fields: ~[ast::field],
|
||||||
base: option<@ast::expr>, id: ast::node_id,
|
base: option<@ast::expr>, id: ast::node_id,
|
||||||
dest: dest) -> block {
|
// none = ignore; some(x) = save_in(x)
|
||||||
|
dest: option<ValueRef>) -> block {
|
||||||
let _icx = bcx.insn_ctxt("trans_rec");
|
let _icx = bcx.insn_ctxt("trans_rec");
|
||||||
let t = node_id_type(bcx, id);
|
let t = node_id_type(bcx, id);
|
||||||
let mut bcx = bcx;
|
let mut bcx = bcx;
|
||||||
let addr = match check dest {
|
let addr = match dest {
|
||||||
ignore => {
|
none => {
|
||||||
for vec::each(fields) |fld| {
|
for vec::each(fields) |fld| {
|
||||||
bcx = trans_expr(bcx, fld.node.expr, ignore);
|
bcx = trans_expr(bcx, fld.node.expr, ignore);
|
||||||
}
|
}
|
||||||
return bcx;
|
return bcx;
|
||||||
}
|
}
|
||||||
save_in(pos) => pos
|
some(pos) => pos
|
||||||
};
|
};
|
||||||
|
|
||||||
let ty_fields = match check ty::get(t).struct { ty::ty_rec(f) => f };
|
let ty_fields = match ty::get(t).struct {
|
||||||
|
ty::ty_rec(f) => f,
|
||||||
|
_ => bcx.sess().bug(~"trans_rec: record has non-record type")
|
||||||
|
};
|
||||||
|
|
||||||
let mut temp_cleanups = ~[];
|
let mut temp_cleanups = ~[];
|
||||||
for fields.each |fld| {
|
for fields.each |fld| {
|
||||||
@@ -3797,7 +3807,13 @@ fn trans_expr(bcx: block, e: @ast::expr, dest: dest) -> block {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
ast::expr_rec(args, base) => {
|
ast::expr_rec(args, base) => {
|
||||||
return trans_rec(bcx, args, base, e.id, dest);
|
let d = match dest {
|
||||||
|
ignore => none,
|
||||||
|
save_in(p) => some(p),
|
||||||
|
_ => bcx.sess().impossible_case(e.span,
|
||||||
|
"trans_expr::unrooted: can't pass a record by val")
|
||||||
|
};
|
||||||
|
return trans_rec(bcx, args, base, e.id, d);
|
||||||
}
|
}
|
||||||
ast::expr_struct(_, fields, base) => {
|
ast::expr_struct(_, fields, base) => {
|
||||||
return trans_struct(bcx, e.span, fields, base, e.id, dest);
|
return trans_struct(bcx, e.span, fields, base, e.id, dest);
|
||||||
@@ -3849,7 +3865,7 @@ fn trans_expr(bcx: block, e: @ast::expr, dest: dest) -> block {
|
|||||||
dest);
|
dest);
|
||||||
}
|
}
|
||||||
ast::expr_fn_block(decl, body, cap_clause) => {
|
ast::expr_fn_block(decl, body, cap_clause) => {
|
||||||
match check ty::get(expr_ty(bcx, e)).struct {
|
match ty::get(expr_ty(bcx, e)).struct {
|
||||||
ty::ty_fn({proto, _}) => {
|
ty::ty_fn({proto, _}) => {
|
||||||
debug!("translating fn_block %s with type %s",
|
debug!("translating fn_block %s with type %s",
|
||||||
expr_to_str(e, tcx.sess.intr()),
|
expr_to_str(e, tcx.sess.intr()),
|
||||||
@@ -3857,10 +3873,25 @@ fn trans_expr(bcx: block, e: @ast::expr, dest: dest) -> block {
|
|||||||
return closure::trans_expr_fn(bcx, proto, decl, body,
|
return closure::trans_expr_fn(bcx, proto, decl, body,
|
||||||
e.id, cap_clause, none, dest);
|
e.id, cap_clause, none, dest);
|
||||||
}
|
}
|
||||||
|
_ => bcx.sess().impossible_case(e.span, "fn_block has \
|
||||||
|
body with a non-fn type")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ast::expr_loop_body(_) => {
|
ast::expr_loop_body(blk) => {
|
||||||
return trans_loop_body(bcx, e, none, dest);
|
match ty::get(expr_ty(bcx, e)).struct {
|
||||||
|
ty::ty_fn({proto, _}) => {
|
||||||
|
match blk.node {
|
||||||
|
ast::expr_fn_block(decl, body, cap) =>
|
||||||
|
return trans_loop_body(bcx, blk.id, decl, body,
|
||||||
|
proto, cap, none, dest),
|
||||||
|
_ => bcx.sess().impossible_case(e.span, "loop_body \
|
||||||
|
has the wrong kind of contents")
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
_ => bcx.sess().impossible_case(e.span, "loop_body has \
|
||||||
|
body with a non-fn type")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
ast::expr_do_body(blk) => {
|
ast::expr_do_body(blk) => {
|
||||||
return trans_expr(bcx, blk, dest);
|
return trans_expr(bcx, blk, dest);
|
||||||
@@ -4436,19 +4467,18 @@ fn raw_block(fcx: fn_ctxt, is_lpad: bool, llbb: BasicBlockRef) -> block {
|
|||||||
// need to make sure those variables go out of scope when the block ends. We
|
// need to make sure those variables go out of scope when the block ends. We
|
||||||
// do that by running a 'cleanup' function for each variable.
|
// do that by running a 'cleanup' function for each variable.
|
||||||
// trans_block_cleanups runs all the cleanup functions for the block.
|
// trans_block_cleanups runs all the cleanup functions for the block.
|
||||||
fn trans_block_cleanups(bcx: block, cleanup_cx: block) -> block {
|
fn trans_block_cleanups(bcx: block, +cleanups: ~[cleanup]) -> block {
|
||||||
trans_block_cleanups_(bcx, cleanup_cx, false)
|
trans_block_cleanups_(bcx, cleanups, false)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn trans_block_cleanups_(bcx: block, cleanup_cx: block, is_lpad: bool) ->
|
fn trans_block_cleanups_(bcx: block,
|
||||||
|
+cleanups: ~[cleanup],
|
||||||
|
/* cleanup_cx: block, */ is_lpad: bool) ->
|
||||||
block {
|
block {
|
||||||
let _icx = bcx.insn_ctxt("trans_block_cleanups");
|
let _icx = bcx.insn_ctxt("trans_block_cleanups");
|
||||||
if bcx.unreachable { return bcx; }
|
if bcx.unreachable { return bcx; }
|
||||||
let mut bcx = bcx;
|
let mut bcx = bcx;
|
||||||
match check cleanup_cx.kind {
|
do vec::riter(cleanups) |cu| {
|
||||||
block_scope({cleanups, _}) => {
|
|
||||||
let cleanups = copy cleanups;
|
|
||||||
do vec::riter(cleanups) |cu| {
|
|
||||||
match cu {
|
match cu {
|
||||||
clean(cfn, cleanup_type) | clean_temp(_, cfn, cleanup_type) => {
|
clean(cfn, cleanup_type) | clean_temp(_, cfn, cleanup_type) => {
|
||||||
// Some types don't need to be cleaned up during
|
// Some types don't need to be cleaned up during
|
||||||
@@ -4458,9 +4488,7 @@ fn trans_block_cleanups_(bcx: block, cleanup_cx: block, is_lpad: bool) ->
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
return bcx;
|
return bcx;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -4491,7 +4519,7 @@ fn cleanup_and_leave(bcx: block, upto: option<BasicBlockRef>,
|
|||||||
let sub_cx = sub_block(bcx, ~"cleanup");
|
let sub_cx = sub_block(bcx, ~"cleanup");
|
||||||
Br(bcx, sub_cx.llbb);
|
Br(bcx, sub_cx.llbb);
|
||||||
vec::push(inf.cleanup_paths, {target: leave, dest: sub_cx.llbb});
|
vec::push(inf.cleanup_paths, {target: leave, dest: sub_cx.llbb});
|
||||||
bcx = trans_block_cleanups_(sub_cx, cur, is_lpad);
|
bcx = trans_block_cleanups_(sub_cx, block_cleanups(cur), is_lpad);
|
||||||
}
|
}
|
||||||
_ => ()
|
_ => ()
|
||||||
}
|
}
|
||||||
@@ -4906,8 +4934,9 @@ fn trans_enum_variant(ccx: @crate_ctxt,
|
|||||||
// If this argument to this function is a enum, it'll have come in to
|
// If this argument to this function is a enum, it'll have come in to
|
||||||
// this function as an opaque blob due to the way that type_of()
|
// this function as an opaque blob due to the way that type_of()
|
||||||
// works. So we have to cast to the destination's view of the type.
|
// works. So we have to cast to the destination's view of the type.
|
||||||
let llarg = match check fcx.llargs.find(va.id) {
|
let llarg = match fcx.llargs.find(va.id) {
|
||||||
some(local_mem(x)) => x
|
some(local_mem(x)) => x,
|
||||||
|
_ => fail ~"trans_enum_variant: how do we know this works?",
|
||||||
};
|
};
|
||||||
let arg_ty = arg_tys[i].ty;
|
let arg_ty = arg_tys[i].ty;
|
||||||
memmove_ty(bcx, lldestptr, llarg, arg_ty);
|
memmove_ty(bcx, lldestptr, llarg, arg_ty);
|
||||||
@@ -5052,8 +5081,10 @@ fn trans_enum_def(ccx: @crate_ctxt, enum_definition: ast::enum_def,
|
|||||||
|
|
||||||
fn trans_item(ccx: @crate_ctxt, item: ast::item) {
|
fn trans_item(ccx: @crate_ctxt, item: ast::item) {
|
||||||
let _icx = ccx.insn_ctxt("trans_item");
|
let _icx = ccx.insn_ctxt("trans_item");
|
||||||
let path = match check ccx.tcx.items.get(item.id) {
|
let path = match ccx.tcx.items.get(item.id) {
|
||||||
ast_map::node_item(_, p) => p
|
ast_map::node_item(_, p) => p,
|
||||||
|
// tjc: ?
|
||||||
|
_ => fail ~"trans_item",
|
||||||
};
|
};
|
||||||
match item.node {
|
match item.node {
|
||||||
ast::item_fn(decl, purity, tps, body) => {
|
ast::item_fn(decl, purity, tps, body) => {
|
||||||
@@ -5288,8 +5319,10 @@ fn fill_fn_pair(bcx: block, pair: ValueRef, llfn: ValueRef,
|
|||||||
|
|
||||||
fn item_path(ccx: @crate_ctxt, i: @ast::item) -> path {
|
fn item_path(ccx: @crate_ctxt, i: @ast::item) -> path {
|
||||||
vec::append(
|
vec::append(
|
||||||
*match check ccx.tcx.items.get(i.id) {
|
*match ccx.tcx.items.get(i.id) {
|
||||||
ast_map::node_item(_, p) => p
|
ast_map::node_item(_, p) => p,
|
||||||
|
// separate map for paths?
|
||||||
|
_ => fail ~"item_path"
|
||||||
},
|
},
|
||||||
~[path_name(i.ident)])
|
~[path_name(i.ident)])
|
||||||
}
|
}
|
||||||
@@ -5340,7 +5373,7 @@ fn get_item_val(ccx: @crate_ctxt, id: ast::node_id) -> ValueRef {
|
|||||||
let val = match ccx.tcx.items.get(id) {
|
let val = match ccx.tcx.items.get(id) {
|
||||||
ast_map::node_item(i, pth) => {
|
ast_map::node_item(i, pth) => {
|
||||||
let my_path = vec::append(*pth, ~[path_name(i.ident)]);
|
let my_path = vec::append(*pth, ~[path_name(i.ident)]);
|
||||||
match check i.node {
|
match i.node {
|
||||||
ast::item_const(_, _) => {
|
ast::item_const(_, _) => {
|
||||||
let typ = ty::node_id_to_type(ccx.tcx, i.id);
|
let typ = ty::node_id_to_type(ccx.tcx, i.id);
|
||||||
let s = mangle_exported_name(ccx, my_path, typ);
|
let s = mangle_exported_name(ccx, my_path, typ);
|
||||||
@@ -5359,6 +5392,7 @@ fn get_item_val(ccx: @crate_ctxt, id: ast::node_id) -> ValueRef {
|
|||||||
set_inline_hint_if_appr(i.attrs, llfn);
|
set_inline_hint_if_appr(i.attrs, llfn);
|
||||||
llfn
|
llfn
|
||||||
}
|
}
|
||||||
|
_ => fail ~"get_item_val: weird result in table"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ast_map::node_trait_method(trait_method, _, pth) => {
|
ast_map::node_trait_method(trait_method, _, pth) => {
|
||||||
@@ -5417,10 +5451,11 @@ fn get_item_val(ccx: @crate_ctxt, id: ast::node_id) -> ValueRef {
|
|||||||
let pth = vec::append(*pth,
|
let pth = vec::append(*pth,
|
||||||
~[path_name(enm.ident),
|
~[path_name(enm.ident),
|
||||||
path_name(v.node.name)]);
|
path_name(v.node.name)]);
|
||||||
llfn = match check enm.node {
|
llfn = match enm.node {
|
||||||
ast::item_enum(_, _) => {
|
ast::item_enum(_, _) => {
|
||||||
register_fn(ccx, v.span, pth, id)
|
register_fn(ccx, v.span, pth, id)
|
||||||
}
|
}
|
||||||
|
_ => fail ~"node_variant, shouldn't happen"
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
ast::struct_variant_kind(_) => {
|
ast::struct_variant_kind(_) => {
|
||||||
@@ -5733,11 +5768,11 @@ fn crate_ctxt_to_encode_parms(cx: @crate_ctxt)
|
|||||||
for cx.exp_map.each |exp_id, defs| {
|
for cx.exp_map.each |exp_id, defs| {
|
||||||
for defs.each |def| {
|
for defs.each |def| {
|
||||||
if !def.reexp { again; }
|
if !def.reexp { again; }
|
||||||
let path = match check cx.tcx.items.get(exp_id) {
|
let path = match cx.tcx.items.get(exp_id) {
|
||||||
ast_map::node_export(_, path) => {
|
ast_map::node_export(_, path) => {
|
||||||
ast_map::path_to_str(*path,
|
ast_map::path_to_str(*path, cx.sess.parse_sess.interner)
|
||||||
cx.sess.parse_sess.interner)
|
}
|
||||||
}
|
_ => fail ~"reexports"
|
||||||
};
|
};
|
||||||
vec::push(reexports, (path, def.id));
|
vec::push(reexports, (path, def.id));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -368,6 +368,13 @@ fn revoke_clean(cx: block, val: ValueRef) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn block_cleanups(bcx: block) -> ~[cleanup] {
|
||||||
|
match bcx.kind {
|
||||||
|
block_non_scope => ~[],
|
||||||
|
block_scope(inf) => inf.cleanups
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
enum block_kind {
|
enum block_kind {
|
||||||
// A scope at the end of which temporary values created inside of it are
|
// A scope at the end of which temporary values created inside of it are
|
||||||
// cleaned up. May correspond to an actual block in the language, but also
|
// cleaned up. May correspond to an actual block in the language, but also
|
||||||
|
|||||||
@@ -399,7 +399,7 @@ fn create_record(cx: @crate_ctxt, t: ty::t, fields: ~[ast::ty_field],
|
|||||||
line_from_span(cx.sess.codemap,
|
line_from_span(cx.sess.codemap,
|
||||||
span) as int);
|
span) as int);
|
||||||
for fields.each |field| {
|
for fields.each |field| {
|
||||||
let field_t = ty::get_field(t, field.node.ident).mt.ty;
|
let field_t = ty::get_field(cx.tcx, t, field.node.ident).mt.ty;
|
||||||
let ty_md = create_ty(cx, field_t, field.node.mt.ty);
|
let ty_md = create_ty(cx, field_t, field.node.mt.ty);
|
||||||
let (size, align) = size_and_align_of(cx, field_t);
|
let (size, align) = size_and_align_of(cx, field_t);
|
||||||
add_member(scx, cx.sess.str_of(field.node.ident),
|
add_member(scx, cx.sess.str_of(field.node.ident),
|
||||||
|
|||||||
@@ -925,8 +925,9 @@ fn trans_intrinsic(ccx: @crate_ctxt, decl: ValueRef, item: @ast::foreign_item,
|
|||||||
let tp_sz = shape::llsize_of_real(ccx, lltp_ty),
|
let tp_sz = shape::llsize_of_real(ccx, lltp_ty),
|
||||||
out_sz = shape::llsize_of_real(ccx, llout_ty);
|
out_sz = shape::llsize_of_real(ccx, llout_ty);
|
||||||
if tp_sz != out_sz {
|
if tp_sz != out_sz {
|
||||||
let sp = match check ccx.tcx.items.get(option::get(ref_id)) {
|
let sp = match ccx.tcx.items.get(option::get(ref_id)) {
|
||||||
ast_map::node_expr(e) => e.span
|
ast_map::node_expr(e) => e.span,
|
||||||
|
_ => fail ~"reinterpret_cast or forget has non-expr arg"
|
||||||
};
|
};
|
||||||
ccx.sess.span_fatal(
|
ccx.sess.span_fatal(
|
||||||
sp, fmt!("reinterpret_cast called on types \
|
sp, fmt!("reinterpret_cast called on types \
|
||||||
@@ -981,6 +982,8 @@ fn trans_intrinsic(ccx: @crate_ctxt, decl: ValueRef, item: @ast::foreign_item,
|
|||||||
arg_vals(~[frameaddress_val]), ignore);
|
arg_vals(~[frameaddress_val]), ignore);
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
|
// Could we make this an enum rather than a string? does it get
|
||||||
|
// checked earlier?
|
||||||
ccx.sess.span_bug(item.span, ~"unknown intrinsic");
|
ccx.sess.span_bug(item.span, ~"unknown intrinsic");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1171,8 +1174,10 @@ fn register_foreign_fn(ccx: @crate_ctxt, sp: span,
|
|||||||
fn abi_of_foreign_fn(ccx: @crate_ctxt, i: @ast::foreign_item)
|
fn abi_of_foreign_fn(ccx: @crate_ctxt, i: @ast::foreign_item)
|
||||||
-> ast::foreign_abi {
|
-> ast::foreign_abi {
|
||||||
match attr::first_attr_value_str_by_name(i.attrs, ~"abi") {
|
match attr::first_attr_value_str_by_name(i.attrs, ~"abi") {
|
||||||
none => match check ccx.tcx.items.get(i.id) {
|
none => match ccx.tcx.items.get(i.id) {
|
||||||
ast_map::node_foreign_item(_, abi, _) => abi
|
ast_map::node_foreign_item(_, abi, _) => abi,
|
||||||
|
// ??
|
||||||
|
_ => fail ~"abi_of_foreign_fn: not foreign"
|
||||||
},
|
},
|
||||||
some(_) => match attr::foreign_abi(i.attrs) {
|
some(_) => match attr::foreign_abi(i.attrs) {
|
||||||
either::Right(abi) => abi,
|
either::Right(abi) => abi,
|
||||||
|
|||||||
@@ -125,12 +125,14 @@ fn trans_method_callee(bcx: block, callee_id: ast::node_id,
|
|||||||
}
|
}
|
||||||
typeck::method_param({trait_id:trait_id, method_num:off,
|
typeck::method_param({trait_id:trait_id, method_num:off,
|
||||||
param_num:p, bound_num:b}) => {
|
param_num:p, bound_num:b}) => {
|
||||||
match check bcx.fcx.param_substs {
|
match bcx.fcx.param_substs {
|
||||||
some(substs) => {
|
some(substs) => {
|
||||||
let vtbl = find_vtable_in_fn_ctxt(substs, p, b);
|
let vtbl = find_vtable_in_fn_ctxt(substs, p, b);
|
||||||
trans_monomorphized_callee(bcx, callee_id, self, mentry,
|
trans_monomorphized_callee(bcx, callee_id, self, mentry,
|
||||||
trait_id, off, vtbl)
|
trait_id, off, vtbl)
|
||||||
}
|
}
|
||||||
|
// how to get rid of this?
|
||||||
|
none => fail ~"trans_method_callee: missing param_substs"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
typeck::method_trait(_, off) => {
|
typeck::method_trait(_, off) => {
|
||||||
@@ -150,10 +152,11 @@ fn trans_static_method_callee(bcx: block, method_id: ast::def_id,
|
|||||||
let ccx = bcx.ccx();
|
let ccx = bcx.ccx();
|
||||||
|
|
||||||
let mname = if method_id.crate == ast::local_crate {
|
let mname = if method_id.crate == ast::local_crate {
|
||||||
match check bcx.tcx().items.get(method_id.node) {
|
match bcx.tcx().items.get(method_id.node) {
|
||||||
ast_map::node_trait_method(trait_method, _, _) => {
|
ast_map::node_trait_method(trait_method, _, _) => {
|
||||||
ast_util::trait_method_to_ty_method(*trait_method).ident
|
ast_util::trait_method_to_ty_method(*trait_method).ident
|
||||||
}
|
}
|
||||||
|
_ => fail ~"callee is not a trait method"
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
let path = csearch::get_item_path(bcx.tcx(), method_id);
|
let path = csearch::get_item_path(bcx.tcx(), method_id);
|
||||||
@@ -200,7 +203,7 @@ fn method_from_methods(ms: ~[@ast::method], name: ast::ident)
|
|||||||
fn method_with_name(ccx: @crate_ctxt, impl_id: ast::def_id,
|
fn method_with_name(ccx: @crate_ctxt, impl_id: ast::def_id,
|
||||||
name: ast::ident) -> ast::def_id {
|
name: ast::ident) -> ast::def_id {
|
||||||
if impl_id.crate == ast::local_crate {
|
if impl_id.crate == ast::local_crate {
|
||||||
match check ccx.tcx.items.get(impl_id.node) {
|
match ccx.tcx.items.get(impl_id.node) {
|
||||||
ast_map::node_item(@{node: ast::item_impl(_, _, _, ms), _}, _) => {
|
ast_map::node_item(@{node: ast::item_impl(_, _, _, ms), _}, _) => {
|
||||||
method_from_methods(ms, name)
|
method_from_methods(ms, name)
|
||||||
}
|
}
|
||||||
@@ -208,6 +211,7 @@ fn method_with_name(ccx: @crate_ctxt, impl_id: ast::def_id,
|
|||||||
ast::item_class(struct_def, _), _}, _) => {
|
ast::item_class(struct_def, _), _}, _) => {
|
||||||
method_from_methods(struct_def.methods, name)
|
method_from_methods(struct_def.methods, name)
|
||||||
}
|
}
|
||||||
|
_ => fail ~"method_with_name"
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
csearch::get_impl_method(ccx.sess.cstore, impl_id, name)
|
csearch::get_impl_method(ccx.sess.cstore, impl_id, name)
|
||||||
@@ -217,8 +221,9 @@ fn method_with_name(ccx: @crate_ctxt, impl_id: ast::def_id,
|
|||||||
fn method_ty_param_count(ccx: @crate_ctxt, m_id: ast::def_id,
|
fn method_ty_param_count(ccx: @crate_ctxt, m_id: ast::def_id,
|
||||||
i_id: ast::def_id) -> uint {
|
i_id: ast::def_id) -> uint {
|
||||||
if m_id.crate == ast::local_crate {
|
if m_id.crate == ast::local_crate {
|
||||||
match check ccx.tcx.items.get(m_id.node) {
|
match ccx.tcx.items.get(m_id.node) {
|
||||||
ast_map::node_method(m, _, _) => vec::len(m.tps),
|
ast_map::node_method(m, _, _) => vec::len(m.tps),
|
||||||
|
_ => fail ~"method_ty_param_count"
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
csearch::get_type_param_count(ccx.sess.cstore, m_id) -
|
csearch::get_type_param_count(ccx.sess.cstore, m_id) -
|
||||||
@@ -321,10 +326,11 @@ fn resolve_vtable_in_fn_ctxt(fcx: fn_ctxt, vt: typeck::vtable_origin)
|
|||||||
resolve_vtables_in_fn_ctxt(fcx, sub))
|
resolve_vtables_in_fn_ctxt(fcx, sub))
|
||||||
}
|
}
|
||||||
typeck::vtable_param(n_param, n_bound) => {
|
typeck::vtable_param(n_param, n_bound) => {
|
||||||
match check fcx.param_substs {
|
match fcx.param_substs {
|
||||||
some(substs) => {
|
some(substs) => {
|
||||||
find_vtable_in_fn_ctxt(substs, n_param, n_bound)
|
find_vtable_in_fn_ctxt(substs, n_param, n_bound)
|
||||||
}
|
}
|
||||||
|
_ => fail ~"resolve_vtable_in_fn_ctxt: no substs"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_ => vt
|
_ => vt
|
||||||
@@ -332,7 +338,7 @@ fn resolve_vtable_in_fn_ctxt(fcx: fn_ctxt, vt: typeck::vtable_origin)
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn vtable_id(ccx: @crate_ctxt, origin: typeck::vtable_origin) -> mono_id {
|
fn vtable_id(ccx: @crate_ctxt, origin: typeck::vtable_origin) -> mono_id {
|
||||||
match check origin {
|
match origin {
|
||||||
typeck::vtable_static(impl_id, substs, sub_vtables) => {
|
typeck::vtable_static(impl_id, substs, sub_vtables) => {
|
||||||
make_mono_id(ccx, impl_id, substs,
|
make_mono_id(ccx, impl_id, substs,
|
||||||
if (*sub_vtables).len() == 0u { none }
|
if (*sub_vtables).len() == 0u { none }
|
||||||
@@ -342,6 +348,8 @@ fn vtable_id(ccx: @crate_ctxt, origin: typeck::vtable_origin) -> mono_id {
|
|||||||
@{def: trait_id,
|
@{def: trait_id,
|
||||||
params: vec::map(substs, |t| mono_precise(t, none))}
|
params: vec::map(substs, |t| mono_precise(t, none))}
|
||||||
}
|
}
|
||||||
|
// can't this be checked at the callee?
|
||||||
|
_ => fail ~"vtable_id"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -350,10 +358,11 @@ fn get_vtable(ccx: @crate_ctxt, origin: typeck::vtable_origin)
|
|||||||
let hash_id = vtable_id(ccx, origin);
|
let hash_id = vtable_id(ccx, origin);
|
||||||
match ccx.vtables.find(hash_id) {
|
match ccx.vtables.find(hash_id) {
|
||||||
some(val) => val,
|
some(val) => val,
|
||||||
none => match check origin {
|
none => match origin {
|
||||||
typeck::vtable_static(id, substs, sub_vtables) => {
|
typeck::vtable_static(id, substs, sub_vtables) => {
|
||||||
make_impl_vtable(ccx, id, substs, sub_vtables)
|
make_impl_vtable(ccx, id, substs, sub_vtables)
|
||||||
}
|
}
|
||||||
|
_ => fail ~"get_vtable: expected a static origin"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -95,13 +95,13 @@ fn type_of(cx: @crate_ctxt, t: ty::t) -> TypeRef {
|
|||||||
ty::ty_estr(ty::vstore_uniq) => {
|
ty::ty_estr(ty::vstore_uniq) => {
|
||||||
T_unique_ptr(T_unique(cx, T_vec(cx, T_i8())))
|
T_unique_ptr(T_unique(cx, T_vec(cx, T_i8())))
|
||||||
}
|
}
|
||||||
ty::ty_enum(*) => {
|
ty::ty_enum(did, substs) => {
|
||||||
// Only create the named struct, but don't fill it in. We
|
// Only create the named struct, but don't fill it in. We
|
||||||
// fill it in *after* placing it into the type cache. This
|
// fill it in *after* placing it into the type cache. This
|
||||||
// avoids creating more than one copy of the enum when one
|
// avoids creating more than one copy of the enum when one
|
||||||
// of the enum's variants refers to the enum itself.
|
// of the enum's variants refers to the enum itself.
|
||||||
|
|
||||||
common::T_named_struct(llvm_type_name(cx, t))
|
common::T_named_struct(llvm_type_name(cx, an_enum, did, substs.tps))
|
||||||
}
|
}
|
||||||
ty::ty_estr(ty::vstore_box) => {
|
ty::ty_estr(ty::vstore_box) => {
|
||||||
T_box_ptr(T_box(cx, T_vec(cx, T_i8())))
|
T_box_ptr(T_box(cx, T_vec(cx, T_i8())))
|
||||||
@@ -158,12 +158,12 @@ fn type_of(cx: @crate_ctxt, t: ty::t) -> TypeRef {
|
|||||||
T_struct(tys)
|
T_struct(tys)
|
||||||
}
|
}
|
||||||
ty::ty_opaque_closure_ptr(_) => T_opaque_box_ptr(cx),
|
ty::ty_opaque_closure_ptr(_) => T_opaque_box_ptr(cx),
|
||||||
ty::ty_class(*) => {
|
ty::ty_class(did, substs) => {
|
||||||
// Only create the named struct, but don't fill it in. We fill it
|
// Only create the named struct, but don't fill it in. We fill it
|
||||||
// in *after* placing it into the type cache. This prevents
|
// in *after* placing it into the type cache. This prevents
|
||||||
// infinite recursion with recursive class types.
|
// infinite recursion with recursive class types.
|
||||||
|
|
||||||
common::T_named_struct(llvm_type_name(cx, t))
|
common::T_named_struct(llvm_type_name(cx, a_class, did, substs.tps))
|
||||||
}
|
}
|
||||||
ty::ty_self => cx.tcx.sess.unimpl(~"type_of: ty_self"),
|
ty::ty_self => cx.tcx.sess.unimpl(~"type_of: ty_self"),
|
||||||
ty::ty_var(_) => cx.tcx.sess.bug(~"type_of with ty_var"),
|
ty::ty_var(_) => cx.tcx.sess.bug(~"type_of with ty_var"),
|
||||||
@@ -223,14 +223,18 @@ fn fill_type_of_enum(cx: @crate_ctxt, did: ast::def_id, t: ty::t,
|
|||||||
common::set_struct_body(llty, lltys);
|
common::set_struct_body(llty, lltys);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn llvm_type_name(cx: @crate_ctxt, t: ty::t) -> ~str {
|
// Want refinements! (Or case classes, I guess
|
||||||
let (name, did, tps) = match check ty::get(t).struct {
|
enum named_ty { a_class, an_enum }
|
||||||
ty::ty_enum(did, substs) => (~"enum", did, substs.tps),
|
|
||||||
ty::ty_class(did, substs) => (~"class", did, substs.tps)
|
fn llvm_type_name(cx: @crate_ctxt,
|
||||||
};
|
what: named_ty,
|
||||||
|
did: ast::def_id,
|
||||||
|
tps: ~[ty::t]
|
||||||
|
) -> ~str {
|
||||||
|
let name = match what { a_class => { "~class" } an_enum => { "~enum" } };
|
||||||
return fmt!(
|
return fmt!(
|
||||||
"%s %s[#%d]",
|
"%s %s[#%d]",
|
||||||
name,
|
name,
|
||||||
util::ppaux::parameterized(
|
util::ppaux::parameterized(
|
||||||
cx.tcx,
|
cx.tcx,
|
||||||
ty::item_path_str(cx.tcx, did),
|
ty::item_path_str(cx.tcx, did),
|
||||||
|
|||||||
@@ -97,6 +97,7 @@ fn type_uses_for(ccx: @crate_ctxt, fn_id: def_id, n_tps: uint)
|
|||||||
~"visit_tydesc" | ~"forget" | ~"addr_of" => {
|
~"visit_tydesc" | ~"forget" | ~"addr_of" => {
|
||||||
0u
|
0u
|
||||||
}
|
}
|
||||||
|
// would be cool to make these an enum instead of strings!
|
||||||
_ => fail ~"unknown intrinsic in type_use"
|
_ => fail ~"unknown intrinsic in type_use"
|
||||||
};
|
};
|
||||||
for uint::range(0u, n_tps) |n| { cx.uses[n] |= flags;}
|
for uint::range(0u, n_tps) |n| { cx.uses[n] |= flags;}
|
||||||
@@ -255,8 +256,8 @@ fn mark_for_expr(cx: ctx, e: @expr) {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
expr_match(_, _, _) | expr_block(_) | expr_if(_, _, _) |
|
expr_match(*) | expr_block(_) | expr_if(*) |
|
||||||
expr_while(_, _) | expr_fail(_) | expr_break(_) | expr_again(_) |
|
expr_while(*) | expr_fail(_) | expr_break(_) | expr_again(_) |
|
||||||
expr_unary(_, _) | expr_lit(_) | expr_assert(_) |
|
expr_unary(_, _) | expr_lit(_) | expr_assert(_) |
|
||||||
expr_mac(_) | expr_addr_of(_, _) |
|
expr_mac(_) | expr_addr_of(_, _) |
|
||||||
expr_ret(_) | expr_loop(_, _) |
|
expr_ret(_) | expr_loop(_, _) |
|
||||||
|
|||||||
@@ -2503,15 +2503,20 @@ fn field_idx(id: ast::ident, fields: ~[field]) -> option<uint> {
|
|||||||
return none;
|
return none;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_field(rec_ty: t, id: ast::ident) -> field {
|
fn get_field(tcx: ctxt, rec_ty: t, id: ast::ident) -> field {
|
||||||
match check vec::find(get_fields(rec_ty), |f| f.ident == id) {
|
match vec::find(get_fields(rec_ty), |f| f.ident == id) {
|
||||||
some(f) => f
|
some(f) => f,
|
||||||
|
// Do we only call this when we know the field is legit?
|
||||||
|
none => fail (#fmt("get_field: ty doesn't have a field %s",
|
||||||
|
tcx.sess.str_of(id)))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_fields(rec_ty:t) -> ~[field] {
|
fn get_fields(rec_ty:t) -> ~[field] {
|
||||||
match check get(rec_ty).struct {
|
match get(rec_ty).struct {
|
||||||
ty_rec(fields) => fields
|
ty_rec(fields) => fields,
|
||||||
|
// Can we check at the caller?
|
||||||
|
_ => fail ~"get_fields: not a record type"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2805,6 +2810,9 @@ fn trait_methods(cx: ctxt, id: ast::def_id) -> @~[method] {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Could this return a list of (def_id, substs) pairs?
|
||||||
|
*/
|
||||||
fn impl_traits(cx: ctxt, id: ast::def_id) -> ~[t] {
|
fn impl_traits(cx: ctxt, id: ast::def_id) -> ~[t] {
|
||||||
if id.crate == ast::local_crate {
|
if id.crate == ast::local_crate {
|
||||||
debug!("(impl_traits) searching for trait impl %?", id);
|
debug!("(impl_traits) searching for trait impl %?", id);
|
||||||
|
|||||||
@@ -177,10 +177,12 @@ fn check_bare_fn(ccx: @crate_ctxt,
|
|||||||
id: ast::node_id,
|
id: ast::node_id,
|
||||||
self_info: option<self_info>) {
|
self_info: option<self_info>) {
|
||||||
let fty = ty::node_id_to_type(ccx.tcx, id);
|
let fty = ty::node_id_to_type(ccx.tcx, id);
|
||||||
match check ty::get(fty).struct {
|
match ty::get(fty).struct {
|
||||||
ty::ty_fn(ref fn_ty) => {
|
ty::ty_fn(ref fn_ty) => {
|
||||||
check_fn(ccx, self_info, fn_ty, decl, body, false, none)
|
check_fn(ccx, self_info, fn_ty, decl, body, false, none)
|
||||||
}
|
}
|
||||||
|
_ => ccx.tcx.sess.impossible_case(body.span,
|
||||||
|
"check_bare_fn: function type expected")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -803,7 +805,7 @@ fn impl_self_ty(fcx: @fn_ctxt,
|
|||||||
|
|
||||||
let {n_tps, region_param, raw_ty} = if did.crate == ast::local_crate {
|
let {n_tps, region_param, raw_ty} = if did.crate == ast::local_crate {
|
||||||
let region_param = fcx.tcx().region_paramd_items.find(did.node);
|
let region_param = fcx.tcx().region_paramd_items.find(did.node);
|
||||||
match check tcx.items.find(did.node) {
|
match tcx.items.find(did.node) {
|
||||||
some(ast_map::node_item(@{node: ast::item_impl(ts, _, st, _),
|
some(ast_map::node_item(@{node: ast::item_impl(ts, _, st, _),
|
||||||
_}, _)) => {
|
_}, _)) => {
|
||||||
{n_tps: ts.len(),
|
{n_tps: ts.len(),
|
||||||
@@ -1597,7 +1599,7 @@ fn check_expr_with_unifier(fcx: @fn_ctxt,
|
|||||||
fcx.write_ty(id, ty::mk_nil(tcx));
|
fcx.write_ty(id, ty::mk_nil(tcx));
|
||||||
bot = !may_break(body);
|
bot = !may_break(body);
|
||||||
}
|
}
|
||||||
ast::expr_match(discrim, arms, _) => {
|
ast::expr_match(discrim, arms, mode) => {
|
||||||
bot = alt::check_alt(fcx, expr, discrim, arms);
|
bot = alt::check_alt(fcx, expr, discrim, arms);
|
||||||
}
|
}
|
||||||
ast::expr_fn(proto, decl, body, cap_clause) => {
|
ast::expr_fn(proto, decl, body, cap_clause) => {
|
||||||
@@ -1640,7 +1642,7 @@ fn check_expr_with_unifier(fcx: @fn_ctxt,
|
|||||||
type");
|
type");
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
match check b.node {
|
match b.node {
|
||||||
ast::expr_fn_block(decl, body, cap_clause) => {
|
ast::expr_fn_block(decl, body, cap_clause) => {
|
||||||
check_expr_fn(fcx, b, none,
|
check_expr_fn(fcx, b, none,
|
||||||
decl, body, true,
|
decl, body, true,
|
||||||
@@ -1648,14 +1650,17 @@ fn check_expr_with_unifier(fcx: @fn_ctxt,
|
|||||||
demand::suptype(fcx, b.span, inner_ty, fcx.expr_ty(b));
|
demand::suptype(fcx, b.span, inner_ty, fcx.expr_ty(b));
|
||||||
capture::check_capture_clause(tcx, b.id, cap_clause);
|
capture::check_capture_clause(tcx, b.id, cap_clause);
|
||||||
}
|
}
|
||||||
|
// argh
|
||||||
|
_ => fail ~"expr_fn_block"
|
||||||
}
|
}
|
||||||
let block_ty = structurally_resolved_type(
|
let block_ty = structurally_resolved_type(
|
||||||
fcx, expr.span, fcx.node_ty(b.id));
|
fcx, expr.span, fcx.node_ty(b.id));
|
||||||
match check ty::get(block_ty).struct {
|
match ty::get(block_ty).struct {
|
||||||
ty::ty_fn(fty) => {
|
ty::ty_fn(fty) => {
|
||||||
fcx.write_ty(expr.id, ty::mk_fn(tcx, {output: ty::mk_bool(tcx)
|
fcx.write_ty(expr.id, ty::mk_fn(tcx, {output: ty::mk_bool(tcx)
|
||||||
with fty}));
|
with fty}));
|
||||||
}
|
}
|
||||||
|
_ => fail ~"expected fn type"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ast::expr_do_body(b) => {
|
ast::expr_do_body(b) => {
|
||||||
@@ -1670,7 +1675,7 @@ fn check_expr_with_unifier(fcx: @fn_ctxt,
|
|||||||
passed to a `do` function");
|
passed to a `do` function");
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
match check b.node {
|
match b.node {
|
||||||
ast::expr_fn_block(decl, body, cap_clause) => {
|
ast::expr_fn_block(decl, body, cap_clause) => {
|
||||||
check_expr_fn(fcx, b, none,
|
check_expr_fn(fcx, b, none,
|
||||||
decl, body, true,
|
decl, body, true,
|
||||||
@@ -1678,13 +1683,16 @@ fn check_expr_with_unifier(fcx: @fn_ctxt,
|
|||||||
demand::suptype(fcx, b.span, inner_ty, fcx.expr_ty(b));
|
demand::suptype(fcx, b.span, inner_ty, fcx.expr_ty(b));
|
||||||
capture::check_capture_clause(tcx, b.id, cap_clause);
|
capture::check_capture_clause(tcx, b.id, cap_clause);
|
||||||
}
|
}
|
||||||
|
// argh
|
||||||
|
_ => fail ~"expected fn ty"
|
||||||
}
|
}
|
||||||
let block_ty = structurally_resolved_type(
|
let block_ty = structurally_resolved_type(
|
||||||
fcx, expr.span, fcx.node_ty(b.id));
|
fcx, expr.span, fcx.node_ty(b.id));
|
||||||
match check ty::get(block_ty).struct {
|
match ty::get(block_ty).struct {
|
||||||
ty::ty_fn(fty) => {
|
ty::ty_fn(fty) => {
|
||||||
fcx.write_ty(expr.id, ty::mk_fn(tcx, fty));
|
fcx.write_ty(expr.id, ty::mk_fn(tcx, fty));
|
||||||
}
|
}
|
||||||
|
_ => fail ~"expected fn ty"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ast::expr_block(b) => {
|
ast::expr_block(b) => {
|
||||||
|
|||||||
@@ -222,8 +222,9 @@ struct lookup {
|
|||||||
|
|
||||||
fn report_static_candidate(idx: uint, did: ast::def_id) {
|
fn report_static_candidate(idx: uint, did: ast::def_id) {
|
||||||
let span = if did.crate == ast::local_crate {
|
let span = if did.crate == ast::local_crate {
|
||||||
match check self.tcx().items.get(did.node) {
|
match self.tcx().items.get(did.node) {
|
||||||
ast_map::node_method(m, _, _) => m.span,
|
ast_map::node_method(m, _, _) => m.span,
|
||||||
|
_ => fail ~"report_static_candidate: bad item"
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
self.expr.span
|
self.expr.span
|
||||||
@@ -297,8 +298,9 @@ struct lookup {
|
|||||||
again; /* ok */
|
again; /* ok */
|
||||||
}
|
}
|
||||||
ty::bound_trait(bound_t) => {
|
ty::bound_trait(bound_t) => {
|
||||||
match check ty::get(bound_t).struct {
|
match ty::get(bound_t).struct {
|
||||||
ty::ty_trait(i, substs, _) => (i, substs)
|
ty::ty_trait(i, substs, _) => (i, substs),
|
||||||
|
_ => fail ~"add_candidates_from_param: non-trait bound"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@@ -402,11 +404,12 @@ struct lookup {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn ty_from_did(did: ast::def_id) -> ty::t {
|
fn ty_from_did(did: ast::def_id) -> ty::t {
|
||||||
match check ty::get(ty::lookup_item_type(self.tcx(), did).ty).struct {
|
match ty::get(ty::lookup_item_type(self.tcx(), did).ty).struct {
|
||||||
ty::ty_fn(fty) => {
|
ty::ty_fn(fty) => {
|
||||||
ty::mk_fn(self.tcx(),
|
ty::mk_fn(self.tcx(),
|
||||||
{proto: ty::proto_vstore(ty::vstore_box) with fty})
|
{proto: ty::proto_vstore(ty::vstore_box) with fty})
|
||||||
}
|
}
|
||||||
|
_ => fail ~"ty_from_did: not function ty"
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
if did.crate == ast::local_crate {
|
if did.crate == ast::local_crate {
|
||||||
|
|||||||
@@ -15,9 +15,9 @@ fn replace_bound_regions_in_fn_ty(
|
|||||||
|
|
||||||
// Take self_info apart; the self_ty part is the only one we want
|
// Take self_info apart; the self_ty part is the only one we want
|
||||||
// to update here.
|
// to update here.
|
||||||
let self_ty = match self_info {
|
let (self_ty, rebuild_self_info) = match self_info {
|
||||||
some(s) => some(s.self_ty),
|
some(s) => (some(s.self_ty), |t| some({self_ty: t with s})),
|
||||||
none => none
|
none => (none, |_t| none)
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut all_tys = ty::tys_in_fn_ty(fn_ty);
|
let mut all_tys = ty::tys_in_fn_ty(fn_ty);
|
||||||
@@ -59,22 +59,15 @@ fn replace_bound_regions_in_fn_ty(
|
|||||||
|
|
||||||
|
|
||||||
// Glue updated self_ty back together with its original def_id.
|
// Glue updated self_ty back together with its original def_id.
|
||||||
let new_self_info = match self_info {
|
let new_self_info: option<self_info> = match t_self {
|
||||||
some(s) => {
|
none => none,
|
||||||
match t_self {
|
some(t) => rebuild_self_info(t)
|
||||||
some(t) => some({self_ty: t with s}),
|
|
||||||
none => {
|
|
||||||
tcx.sess.bug(~"unexpected t_self in \
|
|
||||||
replace_bound_regions_in_fn_ty()");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
none => none
|
|
||||||
};
|
};
|
||||||
|
|
||||||
return {isr: isr,
|
return {isr: isr,
|
||||||
self_info: new_self_info,
|
self_info: new_self_info,
|
||||||
fn_ty: match check ty::get(t_fn).struct { ty::ty_fn(o) => o }};
|
fn_ty: match ty::get(t_fn).struct { ty::ty_fn(o) => o,
|
||||||
|
_ => tcx.sess.bug(~"replace_bound_regions_in_fn_ty: impossible")}};
|
||||||
|
|
||||||
|
|
||||||
// Takes `isr`, a (possibly empty) mapping from in-scope region
|
// Takes `isr`, a (possibly empty) mapping from in-scope region
|
||||||
|
|||||||
@@ -59,8 +59,9 @@ fn fixup_substs(fcx: @fn_ctxt, expr: @ast::expr,
|
|||||||
// use a dummy type just to package up the substs that need fixing up
|
// use a dummy type just to package up the substs that need fixing up
|
||||||
let t = ty::mk_trait(tcx, id, substs, ty::vstore_slice(ty::re_static));
|
let t = ty::mk_trait(tcx, id, substs, ty::vstore_slice(ty::re_static));
|
||||||
do fixup_ty(fcx, expr, t, is_early).map |t_f| {
|
do fixup_ty(fcx, expr, t, is_early).map |t_f| {
|
||||||
match check ty::get(t_f).struct {
|
match ty::get(t_f).struct {
|
||||||
ty::ty_trait(_, substs_f, _) => substs_f,
|
ty::ty_trait(_, substs_f, _) => substs_f,
|
||||||
|
_ => fail ~"t_f should be a trait"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -88,8 +89,10 @@ fn lookup_vtable(fcx: @fn_ctxt,
|
|||||||
let _i = indenter();
|
let _i = indenter();
|
||||||
|
|
||||||
let tcx = fcx.ccx.tcx;
|
let tcx = fcx.ccx.tcx;
|
||||||
let (trait_id, trait_substs) = match check ty::get(trait_ty).struct {
|
let (trait_id, trait_substs) = match ty::get(trait_ty).struct {
|
||||||
ty::ty_trait(did, substs, _) => (did, substs)
|
ty::ty_trait(did, substs, _) => (did, substs),
|
||||||
|
_ => tcx.sess.impossible_case(expr.span, "lookup_vtable: \
|
||||||
|
don't know how to handle a non-trait ty")
|
||||||
};
|
};
|
||||||
let ty = match fixup_ty(fcx, expr, ty, is_early) {
|
let ty = match fixup_ty(fcx, expr, ty, is_early) {
|
||||||
some(ty) => ty,
|
some(ty) => ty,
|
||||||
@@ -105,7 +108,7 @@ fn lookup_vtable(fcx: @fn_ctxt,
|
|||||||
|
|
||||||
match ty::get(ty).struct {
|
match ty::get(ty).struct {
|
||||||
ty::ty_param({idx: n, def_id: did}) => {
|
ty::ty_param({idx: n, def_id: did}) => {
|
||||||
let mut n_bound = 0u;
|
let mut n_bound = 0;
|
||||||
for vec::each(*tcx.ty_param_bounds.get(did.node)) |bound| {
|
for vec::each(*tcx.ty_param_bounds.get(did.node)) |bound| {
|
||||||
match bound {
|
match bound {
|
||||||
ty::bound_send | ty::bound_copy | ty::bound_const |
|
ty::bound_send | ty::bound_copy | ty::bound_const |
|
||||||
@@ -113,7 +116,7 @@ fn lookup_vtable(fcx: @fn_ctxt,
|
|||||||
/* ignore */
|
/* ignore */
|
||||||
}
|
}
|
||||||
ty::bound_trait(ity) => {
|
ty::bound_trait(ity) => {
|
||||||
match check ty::get(ity).struct {
|
match ty::get(ity).struct {
|
||||||
ty::ty_trait(idid, substs, _) => {
|
ty::ty_trait(idid, substs, _) => {
|
||||||
if trait_id == idid {
|
if trait_id == idid {
|
||||||
debug!("(checking vtable) @0 relating ty to trait ty
|
debug!("(checking vtable) @0 relating ty to trait ty
|
||||||
@@ -122,6 +125,9 @@ fn lookup_vtable(fcx: @fn_ctxt,
|
|||||||
return vtable_param(n, n_bound);
|
return vtable_param(n, n_bound);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
_ => tcx.sess.impossible_case(expr.span,
|
||||||
|
"lookup_vtable: in loop, \
|
||||||
|
don't know how to handle a non-trait ity")
|
||||||
}
|
}
|
||||||
n_bound += 1u;
|
n_bound += 1u;
|
||||||
}
|
}
|
||||||
@@ -277,11 +283,13 @@ fn connect_trait_tps(fcx: @fn_ctxt, expr: @ast::expr, impl_tys: ~[ty::t],
|
|||||||
let trait_ty = ty::subst_tps(tcx, impl_tys, ity);
|
let trait_ty = ty::subst_tps(tcx, impl_tys, ity);
|
||||||
debug!("(connect trait tps) trait type is %?, impl did is %?",
|
debug!("(connect trait tps) trait type is %?, impl did is %?",
|
||||||
ty::get(trait_ty).struct, impl_did);
|
ty::get(trait_ty).struct, impl_did);
|
||||||
match check ty::get(trait_ty).struct {
|
match ty::get(trait_ty).struct {
|
||||||
ty::ty_trait(_, substs, _) => {
|
ty::ty_trait(_, substs, _) => {
|
||||||
vec::iter2(substs.tps, trait_tys,
|
vec::iter2(substs.tps, trait_tys,
|
||||||
|a, b| demand::suptype(fcx, expr.span, a, b));
|
|a, b| demand::suptype(fcx, expr.span, a, b));
|
||||||
}
|
}
|
||||||
|
_ => tcx.sess.impossible_case(expr.span, "connect_trait_tps: \
|
||||||
|
don't know how to handle a non-trait ty")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user