|
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