@@ -92,7 +92,14 @@ fn type_of(cx: @crate_ctxt, t: ty::t) -> TypeRef {
92
92
ty:: ty_estr( ty:: vstore_uniq) => {
93
93
T_unique_ptr ( T_unique ( cx, T_vec ( cx, T_i8 ( ) ) ) )
94
94
}
95
- ty:: ty_enum( did, _) => type_of_enum ( cx, did, t) ,
95
+ ty:: ty_enum( did, _) => {
96
+ // Only create the named struct, but don't fill it in. We
97
+ // fill it in *after* placing it into the type cache. This
98
+ // avoids creating more than one copy of the enum when one
99
+ // of the enum's variants refers to the enum itself.
100
+
101
+ common:: T_named_struct ( llvm_type_name ( cx, t) )
102
+ }
96
103
ty:: ty_estr( ty:: vstore_box) => {
97
104
T_box_ptr ( T_box ( cx, T_vec ( cx, T_i8 ( ) ) ) )
98
105
}
@@ -165,8 +172,11 @@ fn type_of(cx: @crate_ctxt, t: ty::t) -> TypeRef {
165
172
166
173
cx. lltypes. insert ( t, llty) ;
167
174
168
- // If this was a class, fill in the type now.
175
+ // If this was an enum or class, fill in the type now.
169
176
match ty:: get ( t) . struct {
177
+ ty:: ty_enum( did, _) => {
178
+ fill_type_of_enum ( cx, did, t, llty) ;
179
+ }
170
180
ty:: ty_class( did, ts) => {
171
181
// Only instance vars are record fields at runtime.
172
182
let fields = ty:: lookup_class_fields ( cx. tcx , did) ;
@@ -191,21 +201,11 @@ fn type_of(cx: @crate_ctxt, t: ty::t) -> TypeRef {
191
201
return llty;
192
202
}
193
203
194
- // This should only be called from type_of, above, because it
195
- // creates new llvm named struct types lazily that are then
196
- // cached by type_of
197
- fn type_of_enum ( cx : @crate_ctxt , did : ast:: def_id , t : ty:: t )
198
- -> TypeRef {
204
+ fn fill_type_of_enum ( cx : @crate_ctxt , did : ast:: def_id , t : ty:: t ,
205
+ llty : TypeRef ) {
199
206
200
207
debug ! { "type_of_enum %?: %?" , t, ty:: get( t) } ;
201
208
202
- // Every enum type has a unique name. When we find our roots
203
- // for GC and unwinding we will use this name to rediscover
204
- // the Rust type
205
- let name = llvm_type_name ( cx, t) ;
206
-
207
- let named_llty = common:: T_named_struct ( name) ;
208
-
209
209
let lltys = {
210
210
let degen = ( * ty:: enum_variants ( cx. tcx , did) ) . len ( ) == 1 u;
211
211
let size = shape:: static_size_of_enum ( cx, t) ;
@@ -220,8 +220,7 @@ fn type_of_enum(cx: @crate_ctxt, did: ast::def_id, t: ty::t)
220
220
}
221
221
} ;
222
222
223
- common:: set_struct_body ( named_llty, lltys) ;
224
- return named_llty;
223
+ common:: set_struct_body ( llty, lltys) ;
225
224
}
226
225
227
226
fn llvm_type_name ( cx : @crate_ctxt , t : ty:: t ) -> ~str {
0 commit comments