Skip to content

Commit cd6962f

Browse files
committed
rustc: Link to external tag discriminants. Un-XFAIL test/run-pass/lib-option.rs.
1 parent 2a894ca commit cd6962f

File tree

2 files changed

+53
-46
lines changed

2 files changed

+53
-46
lines changed

src/comp/middle/trans.rs

Lines changed: 52 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -3679,6 +3679,24 @@ fn lval_generic_fn(@block_ctxt cx,
36793679
ret lv;
36803680
}
36813681

3682+
fn lookup_discriminant(@crate_ctxt ccx, ast.def_id tid, ast.def_id vid)
3683+
-> ValueRef {
3684+
alt (ccx.discrims.find(vid)) {
3685+
case (none[ValueRef]) {
3686+
// It's an external discriminant that we haven't seen yet.
3687+
check (ccx.sess.get_targ_crate_num() != vid._0);
3688+
auto sym = creader.get_symbol(ccx.sess, vid);
3689+
auto gvar = llvm.LLVMAddGlobal(ccx.llmod, T_int(), _str.buf(sym));
3690+
llvm.LLVMSetLinkage(gvar,
3691+
lib.llvm.LLVMExternalLinkage as llvm.Linkage);
3692+
llvm.LLVMSetGlobalConstant(gvar, True);
3693+
ccx.discrims.insert(vid, gvar);
3694+
ret gvar;
3695+
}
3696+
case (some[ValueRef](?llval)) { ret llval; }
3697+
}
3698+
}
3699+
36823700
fn trans_path(@block_ctxt cx, &ast.path p, &option.t[ast.def] dopt,
36833701
&ast.ann ann) -> lval_result {
36843702
alt (dopt) {
@@ -3725,46 +3743,39 @@ fn trans_path(@block_ctxt cx, &ast.path p, &option.t[ast.def] dopt,
37253743
ret lval_generic_fn(cx, tyt, did, ann);
37263744
}
37273745
case (ast.def_variant(?tid, ?vid)) {
3728-
// TODO: externals
3729-
if (cx.fcx.ccx.fn_pairs.contains_key(vid)) {
3730-
check (cx.fcx.ccx.items.contains_key(tid));
3731-
auto tag_item = cx.fcx.ccx.items.get(tid);
3732-
auto params = ty.item_ty(tag_item)._0;
3733-
auto fty = plain_ty(ty.ty_nil);
3734-
alt (tag_item.node) {
3735-
case (ast.item_tag(_, ?variants, _, _, _)) {
3736-
for (ast.variant v in variants) {
3737-
if (v.node.id == vid) {
3738-
fty = node_ann_type(cx.fcx.ccx,
3739-
v.node.ann);
3740-
}
3741-
}
3742-
}
3743-
}
3744-
ret lval_generic_fn(cx, tup(params, fty), vid, ann);
3745-
} else {
3746-
// Nullary variant.
3747-
auto tag_ty = node_ann_type(cx.fcx.ccx, ann);
3748-
auto lldiscrim_gv = cx.fcx.ccx.discrims.get(vid);
3749-
auto lldiscrim = cx.build.Load(lldiscrim_gv);
3750-
3751-
auto alloc_result = alloc_ty(cx, tag_ty);
3752-
auto lltagblob = alloc_result.val;
3753-
3754-
auto lltagty;
3755-
if (ty.type_has_dynamic_size(tag_ty)) {
3756-
lltagty = T_opaque_tag(cx.fcx.ccx.tn);
3757-
} else {
3758-
lltagty = type_of(cx.fcx.ccx, tag_ty);
3746+
auto v_tyt = ty.lookup_generic_item_type(cx.fcx.ccx.sess,
3747+
cx.fcx.ccx.type_cache, vid);
3748+
alt (v_tyt._1.struct) {
3749+
case (ty.ty_fn(_, _, _)) {
3750+
// N-ary variant.
3751+
ret lval_generic_fn(cx, v_tyt, vid, ann);
37593752
}
3760-
auto lltagptr = alloc_result.bcx.build.PointerCast(
3761-
lltagblob, T_ptr(lltagty));
3753+
case (_) {
3754+
// Nullary variant.
3755+
auto tag_ty = node_ann_type(cx.fcx.ccx, ann);
3756+
auto lldiscrim_gv =
3757+
lookup_discriminant(cx.fcx.ccx, tid, vid);
3758+
auto lldiscrim = cx.build.Load(lldiscrim_gv);
3759+
3760+
auto alloc_result = alloc_ty(cx, tag_ty);
3761+
auto lltagblob = alloc_result.val;
3762+
3763+
auto lltagty;
3764+
if (ty.type_has_dynamic_size(tag_ty)) {
3765+
lltagty = T_opaque_tag(cx.fcx.ccx.tn);
3766+
} else {
3767+
lltagty = type_of(cx.fcx.ccx, tag_ty);
3768+
}
3769+
auto lltagptr = alloc_result.bcx.build.PointerCast(
3770+
lltagblob, T_ptr(lltagty));
37623771

3763-
auto lldiscrimptr = alloc_result.bcx.build.GEP(
3764-
lltagptr, vec(C_int(0), C_int(0)));
3765-
alloc_result.bcx.build.Store(lldiscrim, lldiscrimptr);
3772+
auto lldiscrimptr = alloc_result.bcx.build.GEP(
3773+
lltagptr, vec(C_int(0), C_int(0)));
3774+
alloc_result.bcx.build.Store(lldiscrim,
3775+
lldiscrimptr);
37663776

3767-
ret lval_val(alloc_result.bcx, lltagptr);
3777+
ret lval_val(alloc_result.bcx, lltagptr);
3778+
}
37683779
}
37693780
}
37703781
case (ast.def_const(?did)) {
@@ -6378,25 +6389,22 @@ fn collect_tag_ctors(@crate_ctxt cx, @ast.crate crate) {
63786389

63796390
fn trans_constant(&@crate_ctxt cx, @ast.item it) -> @crate_ctxt {
63806391
alt (it.node) {
6381-
case (ast.item_tag(_, ?variants, _, ?tag_id, _)) {
6392+
case (ast.item_tag(?ident, ?variants, _, ?tag_id, _)) {
63826393
auto i = 0u;
63836394
auto n_variants = _vec.len[ast.variant](variants);
63846395
while (i < n_variants) {
63856396
auto variant = variants.(i);
63866397

63876398
auto discrim_val = C_int(i as int);
63886399

6389-
// FIXME: better name.
6390-
auto s = cx.names.next("_rust_tag_discrim");
6400+
auto s = mangle_name_by_seq(cx,
6401+
#fmt("_rust_tag_discrim_%s_%u",
6402+
ident, i));
63916403
auto discrim_gvar = llvm.LLVMAddGlobal(cx.llmod, T_int(),
63926404
_str.buf(s));
63936405

6394-
// FIXME: Eventually we do want to export these, but we need
6395-
// to figure out what name they get first!
63966406
llvm.LLVMSetInitializer(discrim_gvar, discrim_val);
63976407
llvm.LLVMSetGlobalConstant(discrim_gvar, True);
6398-
llvm.LLVMSetLinkage(discrim_gvar, lib.llvm.LLVMInternalLinkage
6399-
as llvm.Linkage);
64006408

64016409
cx.discrims.insert(variant.node.id, discrim_gvar);
64026410
cx.discrim_symbols.insert(variant.node.id, s);

src/test/run-pass/lib-option.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
1-
// xfail-stage0
21
use std;
32

43
fn main() {
54
auto x = std.option.some[int](10);
6-
}
5+
}

0 commit comments

Comments
 (0)