Skip to content

Commit f64c23f

Browse files
committed
Descend into ty_boxes in type_use
type_use was failing to look into ty_boxes, which caused monomorphize to coalesce instances that shouldn't have been coalesced (because they should actually use different type glue) Closes #2734
1 parent 328fd30 commit f64c23f

File tree

2 files changed

+46
-25
lines changed

2 files changed

+46
-25
lines changed

src/rustc/middle/trans/base.rs

+26-22
Original file line numberDiff line numberDiff line change
@@ -242,7 +242,7 @@ fn trans_free(cx: block, v: ValueRef) -> block {
242242
}
243243

244244
fn trans_unique_free(cx: block, v: ValueRef) -> block {
245-
let _icx = cx.insn_ctxt("trans_shared_free");
245+
let _icx = cx.insn_ctxt("trans_unique_free");
246246
Call(cx, cx.ccx().upcalls.exchange_free,
247247
~[PointerCast(cx, v, T_ptr(T_i8()))]);
248248
ret cx;
@@ -422,12 +422,12 @@ fn get_tydesc(ccx: @crate_ctxt, t: ty::t,
422422

423423
fn get_static_tydesc(ccx: @crate_ctxt, t: ty::t) -> @tydesc_info {
424424
alt ccx.tydescs.find(t) {
425-
some(inf) { ret inf; }
426-
none {
425+
some(inf) { inf }
426+
_ {
427427
ccx.stats.n_static_tydescs += 1u;
428428
let inf = declare_tydesc(ccx, t);
429429
ccx.tydescs.insert(t, inf);
430-
ret inf;
430+
inf
431431
}
432432
}
433433
}
@@ -490,16 +490,15 @@ fn note_unique_llvm_symbol(ccx: @crate_ctxt, sym: str) {
490490
// Generates the declaration for (but doesn't emit) a type descriptor.
491491
fn declare_tydesc(ccx: @crate_ctxt, t: ty::t) -> @tydesc_info {
492492
let _icx = ccx.insn_ctxt("declare_tydesc");
493-
log(debug, "+++ declare_tydesc " + ty_to_str(ccx.tcx, t));
494493
let llty = type_of(ccx, t);
495494
let llsize = llsize_of(ccx, llty);
496495
let llalign = llalign_of(ccx, llty);
497-
let mut name;
498496
//XXX this triggers duplicate LLVM symbols
499-
if false /*ccx.sess.opts.debuginfo*/ {
500-
name = mangle_internal_name_by_type_only(ccx, t, @"tydesc");
501-
} else { name = mangle_internal_name_by_seq(ccx, @"tydesc"); }
497+
let name = if false /*ccx.sess.opts.debuginfo*/ {
498+
mangle_internal_name_by_type_only(ccx, t, @"tydesc")
499+
} else { mangle_internal_name_by_seq(ccx, @"tydesc") };
502500
note_unique_llvm_symbol(ccx, name);
501+
log(debug, #fmt("+++ declare_tydesc %s %s", ty_to_str(ccx.tcx, t), name));
503502
let gvar = str::as_c_str(name, {|buf|
504503
llvm::LLVMAddGlobal(ccx.llmod, ccx.tydesc_type, buf)
505504
});
@@ -613,14 +612,14 @@ fn emit_tydescs(ccx: @crate_ctxt) {
613612
drop_glue, // drop_glue
614613
free_glue, // free_glue
615614
visit_glue, // visit_glue
616-
C_int(ccx, 0), // ununsed
617-
C_int(ccx, 0), // ununsed
618-
C_int(ccx, 0), // ununsed
619-
C_int(ccx, 0), // ununsed
615+
C_int(ccx, 0), // unused
616+
C_int(ccx, 0), // unused
617+
C_int(ccx, 0), // unused
618+
C_int(ccx, 0), // unused
620619
C_shape(ccx, shape), // shape
621620
shape_tables, // shape_tables
622-
C_int(ccx, 0), // ununsed
623-
C_int(ccx, 0)]); // unused
621+
C_int(ccx, 0), // unused
622+
C_int(ccx, 0)]/~); // unused
624623

625624
let gvar = ti.tydesc;
626625
llvm::LLVMSetInitializer(gvar, tydesc);
@@ -704,8 +703,10 @@ fn make_free_glue(bcx: block, v: ValueRef, t: ty::t) {
704703
}
705704
ty::ty_opaque_box {
706705
let v = PointerCast(bcx, v, type_of(ccx, t));
707-
let td = Load(bcx, GEPi(bcx, v, ~[0u, abi::box_field_tydesc]));
708-
let valptr = GEPi(bcx, v, ~[0u, abi::box_field_body]);
706+
let td = Load(bcx, GEPi(bcx, v, [0u, abi::box_field_tydesc]/~));
707+
let valptr = GEPi(bcx, v, [0u, abi::box_field_body]/~);
708+
// Generate code that, dynamically, indexes into the
709+
// tydesc and calls the drop glue that got set dynamically
709710
call_tydesc_glue_full(bcx, valptr, td, abi::tydesc_field_drop_glue,
710711
none);
711712
trans_free(bcx, v)
@@ -1194,6 +1195,7 @@ fn call_tydesc_glue_full(++cx: block, v: ValueRef, tydesc: ValueRef,
11941195
let llfn = {
11951196
alt static_glue_fn {
11961197
none {
1198+
// Select out the glue function to call from the tydesc
11971199
let llfnptr = GEPi(cx, tydesc, ~[0u, field]);
11981200
Load(cx, llfnptr)
11991201
}
@@ -2136,11 +2138,6 @@ fn monomorphic_fn(ccx: @crate_ctxt, fn_id: ast::def_id,
21362138
}
21372139
});
21382140

2139-
#debug["monomorphic_fn(fn_id=%? (%s), real_substs=%?, substs=%?",
2140-
fn_id, ty::item_path_str(ccx.tcx, fn_id),
2141-
real_substs.map({|s| ty_to_str(ccx.tcx, s)}),
2142-
substs.map({|s| ty_to_str(ccx.tcx, s)})];
2143-
21442141
for real_substs.each() {|s| assert !ty::type_has_params(s); };
21452142
for substs.each() {|s| assert !ty::type_has_params(s); };
21462143

@@ -2150,6 +2147,13 @@ fn monomorphic_fn(ccx: @crate_ctxt, fn_id: ast::def_id,
21502147
{|p| alt p { mono_precise(_, _) { false } _ { true } } }) {
21512148
must_cast = true;
21522149
}
2150+
2151+
#debug["monomorphic_fn(fn_id=%? (%s), real_substs=%?, substs=%?, \
2152+
hash_id = %?",
2153+
fn_id, ty::item_path_str(ccx.tcx, fn_id),
2154+
real_substs.map({|s| ty_to_str(ccx.tcx, s)}),
2155+
substs.map({|s| ty_to_str(ccx.tcx, s)}), hash_id];
2156+
21532157
alt ccx.monomorphized.find(hash_id) {
21542158
some(val) {
21552159
ret {val: val, must_cast: must_cast};

src/rustc/middle/trans/type_use.rs

+20-3
Original file line numberDiff line numberDiff line change
@@ -117,8 +117,14 @@ fn type_needs_inner(cx: ctx, use: uint, ty: ty::t,
117117
ty::maybe_walk_ty(ty) {|ty|
118118
if ty::type_has_params(ty) {
119119
alt ty::get(ty).struct {
120-
ty::ty_fn(_) | ty::ty_ptr(_) | ty::ty_rptr(_, _) |
121-
ty::ty_box(_) | ty::ty_iface(_, _) { false }
120+
/*
121+
This previously included ty_box -- that was wrong
122+
because if we cast an @T to an iface (for example) and return
123+
it, we depend on the drop glue for T (we have to write the
124+
right tydesc into the result)
125+
*/
126+
ty::ty_fn(_) | ty::ty_ptr(_) | ty::ty_rptr(_, _)
127+
| ty::ty_iface(_, _) { false }
122128
ty::ty_enum(did, substs) {
123129
if option::is_none(list::find(enums_seen, {|id| id == did})) {
124130
let seen = @cons(did, enums_seen);
@@ -151,10 +157,21 @@ fn mark_for_expr(cx: ctx, e: @expr) {
151157
expr_vec(_, _) |
152158
expr_rec(_, _) | expr_tup(_) |
153159
expr_unary(box(_), _) | expr_unary(uniq(_), _) |
154-
expr_cast(_, _) | expr_binary(add, _, _) |
160+
expr_binary(add, _, _) |
155161
expr_copy(_) | expr_move(_, _) {
156162
node_type_needs(cx, use_repr, e.id);
157163
}
164+
expr_cast(base, _) {
165+
let result_t = ty::node_id_to_type(cx.ccx.tcx, e.id);
166+
alt ty::get(result_t).struct {
167+
ty::ty_iface(*) {
168+
// When we're casting to an iface, we need the
169+
// tydesc for the expr that's being cast.
170+
node_type_needs(cx, use_tydesc, base.id);
171+
}
172+
_ {}
173+
}
174+
}
158175
expr_binary(op, lhs, _) {
159176
alt op {
160177
eq | lt | le | ne | ge | gt {

0 commit comments

Comments
 (0)