@@ -76,10 +76,13 @@ fn type_of(cx: @crate_ctxt, t: ty::t) -> TypeRef {
76
76
// this then, e.g. `option<{myfield: bool}>` would be a different
77
77
// type than `option<myrec>`.
78
78
let t_norm = ty:: normalize_ty ( cx. tcx , t) ;
79
- let llty = if t != t_norm {
80
- type_of ( cx, t_norm)
79
+
80
+ let mut llty;
81
+ if t != t_norm {
82
+ llty = type_of ( cx, t_norm) ;
83
+ cx. lltypes . insert ( t, llty) ;
81
84
} else {
82
- alt ty:: get ( t) . struct {
85
+ llty = alt ty:: get ( t) . struct {
83
86
ty:: ty_nil | ty:: ty_bot { T_nil ( ) }
84
87
ty:: ty_bool { T_bool ( ) }
85
88
ty:: ty_int ( t) { T_int_ty ( cx, t) }
@@ -149,30 +152,46 @@ fn type_of(cx: @crate_ctxt, t: ty::t) -> TypeRef {
149
152
}
150
153
ty:: ty_opaque_closure_ptr ( _) { T_opaque_box_ptr ( cx) }
151
154
ty:: ty_constr ( subt, _) { type_of ( cx, subt) }
155
+ ty:: ty_class ( * ) {
156
+ // Only create the named struct, but don't fill it in. We fill it
157
+ // in *after* placing it into the type cache. This prevents
158
+ // infinite recursion with recursive class types.
159
+
160
+ common:: T_named_struct ( llvm_type_name ( cx, t) )
161
+ }
162
+ ty:: ty_self { cx. tcx . sess . unimpl ( "type_of: ty_self" ) ; }
163
+ ty:: ty_var( _) { cx. tcx . sess . bug ( "type_of shouldn't see a ty_var" ) ; }
164
+ ty:: ty_param ( * ) { cx. tcx . sess . bug ( "type_of with ty_param" ) ; }
165
+ ty:: ty_var_integral ( _) {
166
+ cx. tcx . sess . bug ( "type_of shouldn't see a ty_var_integral" ) ;
167
+ }
168
+ } ;
169
+
170
+ cx. lltypes . insert ( t, llty) ;
171
+
172
+ // If this was a class, fill in the type now.
173
+ alt ty:: get ( t) . struct {
152
174
ty:: ty_class ( did, ts) {
153
- // only instance vars are record fields at runtime
175
+ // Only instance vars are record fields at runtime.
154
176
let fields = lookup_class_fields ( cx. tcx , did) ;
155
- let tys = vec:: map ( fields) { |f|
177
+ let mut tys = vec:: map ( fields) { |f|
156
178
let t = ty:: lookup_field_type ( cx. tcx , did, f. id , ts) ;
157
179
type_of ( cx, t)
158
180
} ;
159
- if ty:: ty_dtor ( cx. tcx , did) == none {
160
- T_struct ( tys)
161
- }
162
- else {
181
+
182
+ if ty:: ty_dtor ( cx. tcx , did) != none {
163
183
// resource type
164
- T_struct ( [ T_i8 ( ) , T_struct ( tys) ] )
184
+ tys = [ T_i8 ( ) , T_struct ( tys) ] ;
165
185
}
186
+
187
+ common:: set_struct_body ( llty, tys) ;
166
188
}
167
- ty:: ty_self { cx. tcx . sess . unimpl ( "type_of: ty_self" ) ; }
168
- ty:: ty_var ( _) { cx. tcx . sess . bug ( "type_of shouldn't see a ty_var" ) ; }
169
- ty:: ty_param ( * ) { cx. tcx . sess . bug ( "type_of with ty_param" ) ; }
170
- ty:: ty_var_integral ( _) {
171
- cx. tcx . sess . bug ( "type_of shouldn't see a ty_var_integral" ) ;
189
+ _ {
190
+ // Nothing more to do.
172
191
}
173
192
}
174
193
} ;
175
- cx . lltypes . insert ( t , llty ) ;
194
+
176
195
ret llty;
177
196
}
178
197
@@ -214,6 +233,9 @@ fn llvm_type_name(cx: @crate_ctxt, t: ty::t) -> str {
214
233
ty:: ty_enum ( did, substs) {
215
234
( "enum" , did, substs. tps )
216
235
}
236
+ ty:: ty_class ( did, substs) {
237
+ ( "class" , did, substs. tps )
238
+ }
217
239
} ;
218
240
ret #fmt(
219
241
"%s %s[#%d]" ,
0 commit comments