@@ -261,75 +261,26 @@ fn ty_to_str(&@ty typ) -> str {
261
261
262
262
// Replaces parameter types inside a type with type variables.
263
263
fn generalize_ty ( @crate_ctxt cx , @ty t ) -> @ty {
264
- fn rewrap ( @ty orig , & sty new) -> @ty {
265
- ret @rec ( struct =new, mut =orig. mut , cname =orig. cname) ;
266
- }
267
-
268
- fn recur( @crate_ctxt cx , @ty t ,
269
- & hashmap[ ast. def_id, @ty] ty_params_to_ty_vars) -> @ty {
270
- alt ( t. struct ) {
271
- case ( ty_box ( ?subty ) ) {
272
- auto new_subty = recur ( cx , subty , ty_params_to_ty_vars ) ;
273
- ret rewrap ( t, ty_box ( new_subty) ) ;
274
- }
275
- case ( ty_vec ( ?subty) ) {
276
- auto new_subty = recur ( cx, subty, ty_params_to_ty_vars) ;
277
- ret rewrap ( t, ty_vec ( new_subty) ) ;
278
- }
279
- case ( ty_tup ( ?subtys) ) {
280
- let vec[ @ty] new_subtys = vec ( ) ;
281
- for ( @ty subty in subtys) {
282
- new_subtys += vec ( recur ( cx, subty, ty_params_to_ty_vars) ) ;
283
- }
284
- ret rewrap( t, ty_tup ( new_subtys) ) ;
285
- }
286
- case ( ty_rec ( ?fields) ) {
287
- let vec[ field] new_fields = vec ( ) ;
288
- for ( field fld in fields) {
289
- auto new_ty = recur( cx, fld. ty, ty_params_to_ty_vars) ;
290
- new_fields += vec( rec( ident=fld. ident, ty=new_ty) ) ;
291
- }
292
- ret rewrap( t, ty_rec( new_fields) ) ;
293
- }
294
- case ( ty_fn( ?args, ?ret_ty) ) {
295
- let vec[ arg] new_args = vec( ) ;
296
- for ( arg a in args) {
297
- auto new_ty = recur( cx, a. ty, ty_params_to_ty_vars) ;
298
- new_args += vec( rec( mode=a. mode, ty=new_ty) ) ;
299
- }
300
- auto new_ret_ty = recur( cx, ret_ty, ty_params_to_ty_vars) ;
301
- ret rewrap( t, ty_fn( new_args, new_ret_ty) ) ;
302
- }
303
- case ( ty_obj( ?methods) ) {
304
- let vec[ method] new_methods = vec( ) ;
305
- for ( method m in methods) {
306
- let vec[ arg] new_args = vec( ) ;
307
- for ( arg a in m. inputs) {
308
- auto new_ty = recur( cx, a. ty, ty_params_to_ty_vars) ;
309
- new_args += vec( rec( mode=a. mode, ty=new_ty) ) ;
264
+ state obj ty_generalizer ( @crate_ctxt cx ,
265
+ @hashmap[ ast. def_id, @ty] ty_params_to_ty_vars) {
266
+ fn fold_simple_ty ( @ty t ) -> @ty {
267
+ alt ( t. struct ) {
268
+ case ( ty_param ( ?pid) ) {
269
+ if ( ty_params_to_ty_vars. contains_key ( pid) ) {
270
+ ret ty_params_to_ty_vars. get ( pid) ;
310
271
}
311
- auto new_rty = recur( cx, m. output, ty_params_to_ty_vars) ;
312
- new_methods += vec( rec( ident=m. ident, inputs=new_args,
313
- output=new_rty) ) ;
314
- }
315
- ret rewrap( t, ty_obj( new_methods) ) ;
316
- }
317
- case ( ty_param( ?pid) ) {
318
- if ( ty_params_to_ty_vars. contains_key( pid) ) {
319
- ret ty_params_to_ty_vars. get( pid) ;
272
+ auto var_ty = next_ty_var ( cx) ;
273
+ ty_params_to_ty_vars. insert ( pid, var_ty) ;
274
+ ret var_ty;
320
275
}
321
- auto var_ty = next_ty_var( cx) ;
322
- ty_params_to_ty_vars. insert( pid, var_ty) ;
323
- ret var_ty;
276
+ case ( _) { /* fall through */ }
324
277
}
325
- case ( _ ) { /* fall through */ }
278
+ ret t ;
326
279
}
327
-
328
- ret t;
329
280
}
330
281
331
- auto ty_params_to_ty_vars = common. new_def_hash[ @ty] ( ) ;
332
- ret recur ( cx , t, ty_params_to_ty_vars ) ;
282
+ auto generalizer = ty_generalizer ( cx , @ common. new_def_hash [ @ty] ( ) ) ;
283
+ ret fold_ty ( generalizer , t) ;
333
284
}
334
285
335
286
// Parses the programmer's textual representation of a type into our internal
@@ -779,6 +730,75 @@ fn is_lval(@ast.expr expr) -> bool {
779
730
}
780
731
}
781
732
733
+ // Type folds
734
+
735
+ type ty_fold = state obj {
736
+ fn fold_simple_ty( @ty ty) -> @ty;
737
+ } ;
738
+
739
+ fn fold_ty ( ty_fold fld, @ty t ) -> @ty {
740
+ fn rewrap ( @ty orig , & sty new) -> @ty {
741
+ ret @rec ( struct =new, mut =orig. mut , cname =orig. cname) ;
742
+ }
743
+
744
+ alt ( t. struct ) {
745
+ case ( ty_nil) { ret fld. fold_simple_ty ( t) ; }
746
+ case ( ty_bool) { ret fld. fold_simple_ty ( t) ; }
747
+ case ( ty_int) { ret fld. fold_simple_ty ( t) ; }
748
+ case ( ty_uint) { ret fld. fold_simple_ty ( t) ; }
749
+ case ( ty_machine ( _) ) { ret fld. fold_simple_ty ( t) ; }
750
+ case ( ty_char) { ret fld. fold_simple_ty ( t) ; }
751
+ case ( ty_str) { ret fld. fold_simple_ty ( t) ; }
752
+ case ( ty_tag ( _) ) { ret fld. fold_simple_ty ( t) ; }
753
+ case ( ty_box ( ?subty) ) {
754
+ ret rewrap ( t, ty_box ( fold_ty ( fld, subty) ) ) ;
755
+ }
756
+ case ( ty_vec ( ?subty) ) {
757
+ ret rewrap ( t, ty_vec ( fold_ty ( fld, subty) ) ) ;
758
+ }
759
+ case ( ty_tup ( ?subtys) ) {
760
+ let vec[ @ty] new_subtys = vec ( ) ;
761
+ for ( @ty subty in subtys) {
762
+ new_subtys += vec ( fold_ty ( fld, subty) ) ;
763
+ }
764
+ ret rewrap( t, ty_tup ( new_subtys) ) ;
765
+ }
766
+ case ( ty_rec ( ?fields) ) {
767
+ let vec[ field] new_fields = vec ( ) ;
768
+ for ( field fl in fields) {
769
+ auto new_ty = fold_ty( fld, fl. ty) ;
770
+ new_fields += vec( rec( ident=fl. ident, ty=new_ty) ) ;
771
+ }
772
+ ret rewrap( t, ty_rec( new_fields) ) ;
773
+ }
774
+ case ( ty_fn( ?args, ?ret_ty) ) {
775
+ let vec[ arg] new_args = vec( ) ;
776
+ for ( arg a in args) {
777
+ auto new_ty = fold_ty( fld, a. ty) ;
778
+ new_args += vec( rec( mode=a. mode, ty=new_ty) ) ;
779
+ }
780
+ ret rewrap( t, ty_fn( new_args, fold_ty( fld, ret_ty) ) ) ;
781
+ }
782
+ case ( ty_obj( ?methods) ) {
783
+ let vec[ method] new_methods = vec( ) ;
784
+ for ( method m in methods) {
785
+ let vec[ arg] new_args = vec( ) ;
786
+ for ( arg a in m. inputs) {
787
+ new_args += vec( rec( mode=a. mode, ty=fold_ty( fld, a. ty) ) ) ;
788
+ }
789
+ new_methods += vec( rec( ident=m. ident, inputs=new_args,
790
+ output=fold_ty( fld, m. output) ) ) ;
791
+ }
792
+ ret rewrap( t, ty_obj( new_methods) ) ;
793
+ }
794
+ case ( ty_var( _) ) { ret fld. fold_simple_ty( t) ; }
795
+ case ( ty_local( _) ) { ret fld. fold_simple_ty( t) ; }
796
+ case ( ty_param( _) ) { ret fld. fold_simple_ty( t) ; }
797
+ }
798
+
799
+ ret t;
800
+ }
801
+
782
802
// Type utilities
783
803
784
804
// FIXME: remove me when == works on these tags.
0 commit comments