Skip to content

Commit 6f95c79

Browse files
committed
Traverse types in reachability
Issue 2526 showed a test case where a library exported only a type that was a synonym for a class. Because the class's destructor wasn't getting marked as reachable, its linkage was wrongly getting set to "internal". The solution is for reachability to traverse types. Closes rust-lang#2526.
1 parent cce7327 commit 6f95c79

File tree

3 files changed

+67
-1
lines changed

3 files changed

+67
-1
lines changed

src/rustc/middle/trans/reachable.rs

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -135,11 +135,37 @@ fn traverse_public_item(cx: ctx, item: @item) {
135135
}
136136
}
137137
}
138-
item_const(*) | item_ty(*) |
138+
item_ty(t, _, _) {
139+
traverse_ty(t, cx, mk_ty_visitor());
140+
}
141+
item_const(*) |
139142
item_enum(*) | item_iface(*) {}
140143
}
141144
}
142145

146+
fn mk_ty_visitor() -> visit::vt<ctx> {
147+
visit::mk_vt(@{visit_ty: traverse_ty with *visit::default_visitor()})
148+
}
149+
150+
fn traverse_ty(ty: @ty, cx: ctx, v: visit::vt<ctx>) {
151+
if cx.rmap.contains_key(ty.id) { ret; }
152+
cx.rmap.insert(ty.id, ());
153+
154+
alt ty.node {
155+
ty_path(p, p_id) {
156+
alt cx.tcx.def_map.find(p_id) {
157+
// Kind of a hack to check this here, but I'm not sure what else
158+
// to do
159+
some(def_prim_ty(_)) { /* do nothing */ }
160+
some(d) { traverse_def_id(cx, def_id_of_def(d)); }
161+
none { /* do nothing -- but should we fail here? */ }
162+
}
163+
for p.types.each {|t| v.visit_ty(t, cx, v); };
164+
}
165+
_ { visit::visit_ty(ty, cx, v); }
166+
}
167+
}
168+
143169
fn traverse_inline_body(cx: ctx, body: blk) {
144170
fn traverse_expr(e: @expr, cx: ctx, v: visit::vt<ctx>) {
145171
alt e.node {

src/test/auxiliary/issue-2526.rs

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
#[link(name = "zmq",
2+
vers = "0.2",
3+
uuid = "54cc1bc9-02b8-447c-a227-75ebc923bc29")];
4+
#[crate_type = "lib"];
5+
6+
use std;
7+
8+
export context;
9+
10+
resource arc_destruct<T: const>(_data: int) { }
11+
12+
fn arc<T: const>(_data: T) -> arc_destruct<T> {
13+
arc_destruct(0)
14+
}
15+
16+
fn init() -> arc_destruct<context_res> unsafe {
17+
arc(context_res())
18+
}
19+
20+
class context_res {
21+
let ctx : int;
22+
23+
new() { self.ctx = 0; }
24+
25+
drop { }
26+
}
27+
28+
type context = arc_destruct<context_res>;
29+
30+
impl context for context {
31+
fn socket() { }
32+
}

src/test/run-pass/issue-2526-a.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
// xfail-fast
2+
// aux-build:issue-2526.rs
3+
4+
use zmq;
5+
import zmq::*;
6+
7+
fn main() {}
8+

0 commit comments

Comments
 (0)