From 6f95c79b95319a8d91de2a5e361eab8d71375d05 Mon Sep 17 00:00:00 2001 From: Tim Chevalier Date: Wed, 13 Jun 2012 11:20:21 -0700 Subject: [PATCH] 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 #2526. --- src/rustc/middle/trans/reachable.rs | 28 ++++++++++++++++++++++++- src/test/auxiliary/issue-2526.rs | 32 +++++++++++++++++++++++++++++ src/test/run-pass/issue-2526-a.rs | 8 ++++++++ 3 files changed, 67 insertions(+), 1 deletion(-) create mode 100644 src/test/auxiliary/issue-2526.rs create mode 100644 src/test/run-pass/issue-2526-a.rs diff --git a/src/rustc/middle/trans/reachable.rs b/src/rustc/middle/trans/reachable.rs index 2b708467874..55a4b865e90 100644 --- a/src/rustc/middle/trans/reachable.rs +++ b/src/rustc/middle/trans/reachable.rs @@ -135,11 +135,37 @@ fn traverse_public_item(cx: ctx, item: @item) { } } } - item_const(*) | item_ty(*) | + item_ty(t, _, _) { + traverse_ty(t, cx, mk_ty_visitor()); + } + item_const(*) | item_enum(*) | item_iface(*) {} } } +fn mk_ty_visitor() -> visit::vt { + visit::mk_vt(@{visit_ty: traverse_ty with *visit::default_visitor()}) +} + +fn traverse_ty(ty: @ty, cx: ctx, v: visit::vt) { + if cx.rmap.contains_key(ty.id) { ret; } + cx.rmap.insert(ty.id, ()); + + alt ty.node { + ty_path(p, p_id) { + alt cx.tcx.def_map.find(p_id) { + // Kind of a hack to check this here, but I'm not sure what else + // to do + some(def_prim_ty(_)) { /* do nothing */ } + some(d) { traverse_def_id(cx, def_id_of_def(d)); } + none { /* do nothing -- but should we fail here? */ } + } + for p.types.each {|t| v.visit_ty(t, cx, v); }; + } + _ { visit::visit_ty(ty, cx, v); } + } +} + fn traverse_inline_body(cx: ctx, body: blk) { fn traverse_expr(e: @expr, cx: ctx, v: visit::vt) { alt e.node { diff --git a/src/test/auxiliary/issue-2526.rs b/src/test/auxiliary/issue-2526.rs new file mode 100644 index 00000000000..9dd7d262731 --- /dev/null +++ b/src/test/auxiliary/issue-2526.rs @@ -0,0 +1,32 @@ +#[link(name = "zmq", + vers = "0.2", + uuid = "54cc1bc9-02b8-447c-a227-75ebc923bc29")]; +#[crate_type = "lib"]; + +use std; + +export context; + +resource arc_destruct(_data: int) { } + +fn arc(_data: T) -> arc_destruct { + arc_destruct(0) +} + +fn init() -> arc_destruct unsafe { + arc(context_res()) +} + +class context_res { + let ctx : int; + + new() { self.ctx = 0; } + + drop { } +} + +type context = arc_destruct; + +impl context for context { + fn socket() { } +} diff --git a/src/test/run-pass/issue-2526-a.rs b/src/test/run-pass/issue-2526-a.rs new file mode 100644 index 00000000000..fdbcc005ae2 --- /dev/null +++ b/src/test/run-pass/issue-2526-a.rs @@ -0,0 +1,8 @@ +// xfail-fast +// aux-build:issue-2526.rs + +use zmq; +import zmq::*; + +fn main() {} +