@@ -261,52 +261,114 @@ fn ty_to_str(&@t typ) -> str {
261
261
262
262
// Type folds
263
263
264
- type ty_fold = state obj {
265
- fn fold_simple_ty( @t ty) -> @t;
266
- } ;
264
+ type ty_walk = fn ( @t ) ;
265
+
266
+ fn walk_ty ( ty_walk walker, @t ty ) {
267
+ alt ( ty. struct ) {
268
+ case ( ty_nil) { /* no-op */ }
269
+ case ( ty_bool) { /* no-op */ }
270
+ case ( ty_int) { /* no-op */ }
271
+ case ( ty_uint) { /* no-op */ }
272
+ case ( ty_float) { /* no-op */ }
273
+ case ( ty_machine ( _) ) { /* no-op */ }
274
+ case ( ty_char) { /* no-op */ }
275
+ case ( ty_str) { /* no-op */ }
276
+ case ( ty_type) { /* no-op */ }
277
+ case ( ty_native) { /* no-op */ }
278
+ case ( ty_box ( ?tm) ) { walk_ty ( walker, tm. ty ) ; }
279
+ case ( ty_vec ( ?tm) ) { walk_ty ( walker, tm. ty ) ; }
280
+ case ( ty_port ( ?subty) ) { walk_ty ( walker, subty) ; }
281
+ case ( ty_chan ( ?subty) ) { walk_ty ( walker, subty) ; }
282
+ case ( ty_tag ( ?tid, ?subtys) ) {
283
+ for ( @t subty in subtys) {
284
+ walk_ty ( walker, subty) ;
285
+ }
286
+ }
287
+ case ( ty_tup ( ?mts) ) {
288
+ for ( mt tm in mts) {
289
+ walk_ty ( walker, tm. ty ) ;
290
+ }
291
+ }
292
+ case ( ty_rec ( ?fields) ) {
293
+ for ( field fl in fields) {
294
+ walk_ty ( walker, fl. mt . ty ) ;
295
+ }
296
+ }
297
+ case ( ty_fn ( ?proto, ?args, ?ret_ty) ) {
298
+ for ( arg a in args) {
299
+ walk_ty ( walker, a. ty ) ;
300
+ }
301
+ walk_ty ( walker, ret_ty) ;
302
+ }
303
+ case ( ty_native_fn ( ?abi, ?args, ?ret_ty) ) {
304
+ for ( arg a in args) {
305
+ walk_ty ( walker, a. ty ) ;
306
+ }
307
+ walk_ty ( walker, ret_ty) ;
308
+ }
309
+ case ( ty_obj ( ?methods) ) {
310
+ let vec[ method] new_methods = vec ( ) ;
311
+ for ( method m in methods) {
312
+ for ( arg a in m. inputs) {
313
+ walk_ty ( walker, a. ty ) ;
314
+ }
315
+ walk_ty ( walker, m. output ) ;
316
+ }
317
+ }
318
+ case ( ty_var ( _) ) { /* no-op */ }
319
+ case ( ty_local ( _) ) { /* no-op */ }
320
+ case ( ty_param ( _) ) { /* no-op */ }
321
+ case ( ty_bound_param ( _) ) { /* no-op */ }
322
+ }
267
323
268
- fn fold_ty( ty_fold fld, @t ty ) -> @t {
324
+ walker ( ty) ;
325
+ }
326
+
327
+ type ty_fold = fn ( @t ) -> @t ;
328
+
329
+ fn fold_ty ( ty_fold fld, @t ty_0 ) -> @t {
269
330
fn rewrap ( @t orig , & sty new) -> @t {
270
331
ret @rec( struct=new, cname=orig. cname ) ;
271
332
}
272
333
334
+ auto ty = ty_0;
273
335
alt ( ty. struct ) {
274
- case ( ty_nil) { ret fld . fold_simple_ty ( ty ) ; }
275
- case ( ty_bool) { ret fld . fold_simple_ty ( ty ) ; }
276
- case ( ty_int) { ret fld . fold_simple_ty ( ty ) ; }
277
- case ( ty_uint) { ret fld . fold_simple_ty ( ty ) ; }
278
- case ( ty_float) { ret fld . fold_simple_ty ( ty ) ; }
279
- case ( ty_machine ( _) ) { ret fld . fold_simple_ty ( ty ) ; }
280
- case ( ty_char) { ret fld . fold_simple_ty ( ty ) ; }
281
- case ( ty_str) { ret fld . fold_simple_ty ( ty ) ; }
282
- case ( ty_type) { ret fld . fold_simple_ty ( ty ) ; }
283
- case ( ty_native) { ret fld . fold_simple_ty ( ty ) ; }
336
+ case ( ty_nil) { /* no-op */ }
337
+ case ( ty_bool) { /* no-op */ }
338
+ case ( ty_int) { /* no-op */ }
339
+ case ( ty_uint) { /* no-op */ }
340
+ case ( ty_float) { /* no-op */ }
341
+ case ( ty_machine ( _) ) { /* no-op */ }
342
+ case ( ty_char) { /* no-op */ }
343
+ case ( ty_str) { /* no-op */ }
344
+ case ( ty_type) { /* no-op */ }
345
+ case ( ty_native) { /* no-op */ }
284
346
case ( ty_box ( ?tm) ) {
285
- ret rewrap ( ty, ty_box ( rec ( ty=fold_ty ( fld, tm. ty ) , mut=tm. mut ) ) ) ;
347
+ ty = rewrap ( ty, ty_box ( rec ( ty=fold_ty ( fld, tm. ty ) , mut=tm. mut ) ) ) ;
286
348
}
287
349
case ( ty_vec ( ?tm) ) {
288
- ret rewrap ( ty, ty_vec ( rec ( ty=fold_ty ( fld, tm. ty ) , mut=tm. mut ) ) ) ;
350
+ ty = rewrap ( ty, ty_vec ( rec ( ty=fold_ty ( fld, tm. ty ) , mut=tm. mut ) ) ) ;
289
351
}
290
352
case ( ty_port ( ?subty) ) {
291
- ret rewrap ( ty, ty_port ( fold_ty ( fld, subty) ) ) ;
353
+ ty = rewrap ( ty, ty_port ( fold_ty ( fld, subty) ) ) ;
292
354
}
293
355
case ( ty_chan ( ?subty) ) {
294
- ret rewrap ( ty, ty_chan ( fold_ty ( fld, subty) ) ) ;
356
+ ty = rewrap ( ty, ty_chan ( fold_ty ( fld, subty) ) ) ;
295
357
}
296
358
case ( ty_tag ( ?tid, ?subtys) ) {
297
359
let vec[ @t] new_subtys = vec ( ) ;
298
360
for ( @t subty in subtys) {
299
361
new_subtys += vec ( fold_ty ( fld, subty) ) ;
300
362
}
301
- ret rewrap( ty, ty_tag ( tid, new_subtys) ) ;
363
+ ty = rewrap ( ty, ty_tag ( tid, new_subtys) ) ;
302
364
}
303
365
case ( ty_tup ( ?mts) ) {
304
366
let vec[ mt] new_mts = vec ( ) ;
305
367
for ( mt tm in mts) {
306
368
auto new_subty = fold_ty( fld, tm. ty) ;
307
369
new_mts += vec( rec( ty=new_subty, mut =tm. mut ) ) ;
308
370
}
309
- ret rewrap( ty, ty_tup( new_mts) ) ;
371
+ ty = rewrap ( ty, ty_tup ( new_mts) ) ;
310
372
}
311
373
case ( ty_rec ( ?fields) ) {
312
374
let vec[ field] new_fields = vec ( ) ;
@@ -315,23 +377,24 @@ fn fold_ty(ty_fold fld, @t ty) -> @t {
315
377
auto new_mt = rec( ty=new_ty, mut =fl. mt. mut ) ;
316
378
new_fields += vec( rec( ident=fl. ident, mt=new_mt) ) ;
317
379
}
318
- ret rewrap( ty, ty_rec( new_fields) ) ;
380
+ ty = rewrap( ty, ty_rec( new_fields) ) ;
319
381
}
320
382
case ( ty_fn( ?proto, ?args, ?ret_ty) ) {
321
383
let vec[ arg] new_args = vec( ) ;
322
384
for ( arg a in args) {
323
385
auto new_ty = fold_ty( fld, a. ty) ;
324
386
new_args += vec( rec( mode=a. mode, ty=new_ty) ) ;
325
387
}
326
- ret rewrap( ty, ty_fn( proto, new_args, fold_ty( fld, ret_ty) ) ) ;
388
+ ty = rewrap( ty, ty_fn( proto, new_args, fold_ty( fld, ret_ty) ) ) ;
327
389
}
328
390
case ( ty_native_fn( ?abi, ?args, ?ret_ty) ) {
329
391
let vec[ arg] new_args = vec( ) ;
330
392
for ( arg a in args) {
331
393
auto new_ty = fold_ty( fld, a. ty) ;
332
394
new_args += vec( rec( mode=a. mode, ty=new_ty) ) ;
333
395
}
334
- ret rewrap( ty, ty_native_fn( abi, new_args, fold_ty( fld, ret_ty) ) ) ;
396
+ ty = rewrap( ty, ty_native_fn( abi, new_args,
397
+ fold_ty( fld, ret_ty) ) ) ;
335
398
}
336
399
case ( ty_obj( ?methods) ) {
337
400
let vec[ method] new_methods = vec( ) ;
@@ -344,15 +407,15 @@ fn fold_ty(ty_fold fld, @t ty) -> @t {
344
407
inputs=new_args,
345
408
output=fold_ty( fld, m. output) ) ) ;
346
409
}
347
- ret rewrap( ty, ty_obj( new_methods) ) ;
410
+ ty = rewrap( ty, ty_obj( new_methods) ) ;
348
411
}
349
- case ( ty_var( _) ) { ret fld . fold_simple_ty ( ty ) ; }
350
- case ( ty_local( _) ) { ret fld . fold_simple_ty ( ty ) ; }
351
- case ( ty_param( _) ) { ret fld . fold_simple_ty ( ty ) ; }
352
- case ( ty_bound_param( _) ) { ret fld . fold_simple_ty ( ty ) ; }
412
+ case ( ty_var( _) ) { /* no-op */ }
413
+ case ( ty_local( _) ) { /* no-op */ }
414
+ case ( ty_param( _) ) { /* no-op */ }
415
+ case ( ty_bound_param( _) ) { /* no-op */ }
353
416
}
354
417
355
- fail ;
418
+ ret fld ( ty ) ;
356
419
}
357
420
358
421
// Type utilities
@@ -655,45 +718,41 @@ fn triv_ann(@ty.t typ) -> ast.ann {
655
718
656
719
// Returns the number of distinct type parameters in the given type.
657
720
fn count_ty_params( @t ty) -> uint {
658
- state obj ty_param_counter( @mutable vec[ uint] param_indices) {
659
- fn fold_simple_ty( @t ty) -> @t {
660
- alt ( ty. struct ) {
661
- case ( ty_param( ?param_idx) ) {
662
- auto seen = false;
663
- for ( uint other_param_idx in * param_indices) {
664
- if ( param_idx == other_param_idx) {
665
- seen = true;
666
- }
667
- }
668
- if ( !seen) {
669
- * param_indices += vec( param_idx) ;
721
+ fn counter( @mutable vec[ uint] param_indices, @t ty) {
722
+ alt ( ty. struct ) {
723
+ case ( ty_param( ?param_idx) ) {
724
+ auto seen = false;
725
+ for ( uint other_param_idx in * param_indices) {
726
+ if ( param_idx == other_param_idx) {
727
+ seen = true;
670
728
}
671
729
}
672
- case ( _) { /* fall through */ }
730
+ if ( !seen) {
731
+ * param_indices += vec( param_idx) ;
732
+ }
673
733
}
674
- ret ty ;
734
+ case ( _ ) { /* fall through */ }
675
735
}
676
736
}
677
737
678
738
let vec[ uint] v = vec( ) ; // FIXME: typechecker botch
679
739
let @mutable vec[ uint] param_indices = @mutable v;
680
- fold_ty( ty_param_counter( param_indices) , ty) ;
740
+ auto f = bind counter( param_indices, _) ;
741
+ walk_ty( f, ty) ;
681
742
ret _vec. len[ uint] ( * param_indices) ;
682
743
}
683
744
684
745
fn type_contains_vars( @t typ) -> bool {
685
- state obj ty_var_counter( @mutable bool flag) {
686
- fn fold_simple_ty( @t typ) -> @t {
687
- alt ( typ. struct ) {
746
+ fn checker( @mutable bool flag, @t typ) {
747
+ alt ( typ. struct ) {
688
748
case ( ty_var( _) ) { * flag = true; }
689
749
case ( _) { /* fall through */ }
690
- }
691
- ret typ;
692
750
}
693
751
}
694
752
695
753
let @mutable bool flag = @mutable false;
696
- fold_ty( ty_var_counter( flag) , typ) ;
754
+ auto f = bind checker( flag, _) ;
755
+ walk_ty( f, typ) ;
697
756
ret * flag;
698
757
}
699
758
@@ -1684,26 +1743,23 @@ fn unify(@ty.t expected, @ty.t actual, &unify_handler handler)
1684
1743
1685
1744
// Performs type binding substitution.
1686
1745
fn substitute ( var_bindings bindings, vec[ @t] set_types , @t typ ) -> @t {
1687
- state obj folder( tup( var_bindings, vec[ @t] ) env) {
1688
- fn fold_simple_ty( @t typ) -> @t {
1689
- auto bindings = env. _0;
1690
- auto types = env. _1;
1691
- alt ( typ. struct ) {
1746
+ fn substituter ( var_bindings bindings, vec[ @t] types, @t typ ) -> @t {
1747
+ alt ( typ. struct ) {
1692
1748
case ( ty_var ( ?id) ) {
1693
1749
alt ( bindings. var_ids . find ( id) ) {
1694
- case ( some[ uint] ( ?n) ) {
1695
- auto root = UFind . find( bindings. sets, n) ;
1696
- ret types. ( root) ;
1697
- }
1698
- case ( none[ uint] ) { ret typ; }
1750
+ case ( some[ uint] ( ?n) ) {
1751
+ auto root = UFind . find ( bindings. sets , n) ;
1752
+ ret types. ( root) ;
1753
+ }
1754
+ case ( none[ uint] ) { ret typ; }
1699
1755
}
1700
1756
}
1701
1757
case ( _) { ret typ; }
1702
- }
1703
1758
}
1704
1759
}
1705
1760
1706
- ret ty. fold_ty( folder( tup( bindings, set_types) ) , typ) ;
1761
+ auto f = bind substituter ( bindings, set_types, _) ;
1762
+ ret fold_ty( f, typ) ;
1707
1763
}
1708
1764
1709
1765
fn unify_sets ( & var_bindings bindings) -> vec [ @t] {
@@ -1804,41 +1860,35 @@ fn type_err_to_str(&ty.type_err err) -> str {
1804
1860
// Performs bound type parameter replacement using the supplied mapping from
1805
1861
// parameter IDs to types.
1806
1862
fn substitute_type_params ( vec[ @t] bindings , @t typ ) -> @t {
1807
- state obj param_replacer( vec[ @t] bindings) {
1808
- fn fold_simple_ty( @t typ) -> @t {
1809
- alt ( typ. struct ) {
1810
- case ( ty_bound_param( ?param_index) ) {
1811
- ret bindings. ( param_index) ;
1812
- }
1813
- case ( _) { ret typ; }
1863
+ fn replacer ( vec[ @t] bindings , @t typ ) -> @t {
1864
+ alt ( typ. struct ) {
1865
+ case ( ty_bound_param ( ?param_index) ) {
1866
+ ret bindings. ( param_index) ;
1814
1867
}
1868
+ case ( _) { ret typ; }
1815
1869
}
1816
1870
}
1817
- auto replacer = param_replacer( bindings) ;
1818
- ret fold_ty( replacer, typ) ;
1871
+
1872
+ auto f = bind replacer ( bindings, _) ;
1873
+ ret fold_ty( f, typ) ;
1819
1874
}
1820
1875
1821
1876
// Converts type parameters in a type to bound type parameters.
1822
1877
fn bind_params_in_type ( @t typ ) -> @t {
1823
- state obj folder( ( ) env) {
1824
- fn fold_simple_ty( @t typ) -> @t {
1825
- alt ( typ. struct ) {
1826
- case ( ty_bound_param( ?index) ) {
1827
- log "bind_params_in_type( ) called on type that already " +
1828
- "has bound params in it";
1829
- fail;
1830
- }
1831
- case ( ty_param( ?index) ) {
1832
- ret plain_ty( ty_bound_param( index) ) ;
1833
- }
1834
- case ( _) {
1835
- ret typ;
1836
- }
1878
+ fn binder ( @t typ ) -> @t {
1879
+ alt ( typ. struct ) {
1880
+ case ( ty_bound_param ( ?index) ) {
1881
+ log "bind_params_in_type() called on type that already " +
1882
+ "has bound params in it" ;
1883
+ fail;
1837
1884
}
1885
+ case ( ty_param ( ?index) ) { ret plain_ty ( ty_bound_param ( index) ) ; }
1886
+ case ( _) { ret typ; }
1838
1887
}
1839
1888
}
1840
1889
1841
- ret fold_ty( folder( ( ) ) , typ) ;
1890
+ auto f = binder;
1891
+ ret fold_ty( f, typ) ;
1842
1892
}
1843
1893
1844
1894
0 commit comments