|
18 | 18 | // invasive.)
|
19 | 19 |
|
20 | 20 | import std::map::hashmap;
|
| 21 | +import std::list; |
21 | 22 | import driver::session::session;
|
22 | 23 | import metadata::csearch;
|
23 | 24 | import syntax::ast::*, syntax::ast_util, syntax::visit;
|
@@ -91,21 +92,25 @@ fn type_needs(cx: ctx, use: uint, ty: ty::t) {
|
91 | 92 | let mut done = true;
|
92 | 93 | // Optimization -- don't descend type if all params already have this use
|
93 | 94 | for vec::each(cx.uses) {|u| if u & use != use { done = false } }
|
94 |
| - if !done { type_needs_inner(cx, use, ty); } |
| 95 | + if !done { type_needs_inner(cx, use, ty, list::nil); } |
95 | 96 | }
|
96 | 97 |
|
97 |
| -fn type_needs_inner(cx: ctx, use: uint, ty: ty::t) { |
| 98 | +fn type_needs_inner(cx: ctx, use: uint, ty: ty::t, |
| 99 | + enums_seen: list::list<def_id>) { |
98 | 100 | ty::maybe_walk_ty(ty) {|ty|
|
99 | 101 | if ty::type_has_params(ty) {
|
100 | 102 | alt ty::get(ty).struct {
|
101 | 103 | ty::ty_fn(_) | ty::ty_ptr(_) | ty::ty_rptr(_, _) |
|
102 | 104 | ty::ty_box(_) | ty::ty_iface(_, _) { false }
|
103 | 105 | ty::ty_enum(did, tps) {
|
104 |
| - for vec::each(*ty::enum_variants(cx.ccx.tcx, did)) {|v| |
105 |
| - for vec::each(v.args) {|aty| |
106 |
| - let t = ty::substitute_type_params(cx.ccx.tcx, tps, |
107 |
| - aty); |
108 |
| - type_needs_inner(cx, use, t); |
| 106 | + if option::is_none(list::find(enums_seen, {|id| id == did})) { |
| 107 | + let seen = list::cons(did, @enums_seen); |
| 108 | + for vec::each(*ty::enum_variants(cx.ccx.tcx, did)) {|v| |
| 109 | + for vec::each(v.args) {|aty| |
| 110 | + let t = ty::substitute_type_params(cx.ccx.tcx, |
| 111 | + tps, aty); |
| 112 | + type_needs_inner(cx, use, t, seen); |
| 113 | + } |
109 | 114 | }
|
110 | 115 | }
|
111 | 116 | false
|
|
0 commit comments