From 90cf9e0d6ff9c7788939ee100db6de9faeff3734 Mon Sep 17 00:00:00 2001 From: Marijn Haverbeke Date: Wed, 28 Mar 2012 10:35:16 +0200 Subject: [PATCH] Make sure type_use.rs doesn't get lost in recursive enums Closes #2059 --- src/rustc/middle/trans/type_use.rs | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/src/rustc/middle/trans/type_use.rs b/src/rustc/middle/trans/type_use.rs index d407cb59e7f..2d3e07fbe06 100644 --- a/src/rustc/middle/trans/type_use.rs +++ b/src/rustc/middle/trans/type_use.rs @@ -18,6 +18,7 @@ // invasive.) import std::map::hashmap; +import std::list; import driver::session::session; import metadata::csearch; import syntax::ast::*, syntax::ast_util, syntax::visit; @@ -91,21 +92,25 @@ fn type_needs(cx: ctx, use: uint, ty: ty::t) { let mut done = true; // Optimization -- don't descend type if all params already have this use for vec::each(cx.uses) {|u| if u & use != use { done = false } } - if !done { type_needs_inner(cx, use, ty); } + if !done { type_needs_inner(cx, use, ty, list::nil); } } -fn type_needs_inner(cx: ctx, use: uint, ty: ty::t) { +fn type_needs_inner(cx: ctx, use: uint, ty: ty::t, + enums_seen: list::list) { ty::maybe_walk_ty(ty) {|ty| if ty::type_has_params(ty) { alt ty::get(ty).struct { ty::ty_fn(_) | ty::ty_ptr(_) | ty::ty_rptr(_, _) | ty::ty_box(_) | ty::ty_iface(_, _) { false } ty::ty_enum(did, tps) { - for vec::each(*ty::enum_variants(cx.ccx.tcx, did)) {|v| - for vec::each(v.args) {|aty| - let t = ty::substitute_type_params(cx.ccx.tcx, tps, - aty); - type_needs_inner(cx, use, t); + if option::is_none(list::find(enums_seen, {|id| id == did})) { + let seen = list::cons(did, @enums_seen); + for vec::each(*ty::enum_variants(cx.ccx.tcx, did)) {|v| + for vec::each(v.args) {|aty| + let t = ty::substitute_type_params(cx.ccx.tcx, + tps, aty); + type_needs_inner(cx, use, t, seen); + } } } false