@@ -65,10 +65,13 @@ type crate_ctxt = rec(mutable obj_info[] obj_infos, ty::ctxt tcx);
65
65
type fn_ctxt =
66
66
rec( ty:: t ret_ty ,
67
67
ast:: purity purity,
68
+ // var_bindings, locals, local_names, and next_var_id are shared
69
+ // with any nested functions that capture the environment
70
+ // (and with any functions whose environment is being captured).
68
71
@ty:: unify:: var_bindings var_bindings,
69
72
hashmap[ ast:: node_id, int] locals ,
70
73
hashmap[ ast:: node_id, ast:: ident] local_names ,
71
- mutable int next_var_id ,
74
+ @ mutable int next_var_id ,
72
75
mutable ast:: node_id[ ] fixups,
73
76
@crate_ctxt ccx) ;
74
77
@@ -237,6 +240,18 @@ fn structure_of(&@fn_ctxt fcx, &span sp, ty::t typ) -> ty::sty {
237
240
ret ty:: struct ( fcx. ccx . tcx , structurally_resolved_type ( fcx, sp, typ) ) ;
238
241
}
239
242
243
+ // Returns the one-level-deep structure of the given type or none if it
244
+ // is not known yet.
245
+ fn structure_of_maybe ( & @fn_ctxt fcx , & span sp, ty:: t typ )
246
+ -> option:: t [ ty:: sty ] {
247
+ auto r =
248
+ ty:: unify:: resolve_type_structure ( fcx. ccx . tcx , fcx. var_bindings , typ) ;
249
+ ret alt ( r) {
250
+ case ( fix_ok ( ?typ_s) ) { some ( ty:: struct ( fcx. ccx . tcx , typ_s) ) }
251
+ case ( fix_err ( _) ) { none }
252
+ }
253
+ }
254
+
240
255
fn type_is_integral ( & @fn_ctxt fcx , & span sp, ty:: t typ ) -> bool {
241
256
auto typ_s = structurally_resolved_type ( fcx, sp, typ) ;
242
257
ret ty:: type_is_integral ( fcx. ccx . tcx , typ_s) ;
@@ -470,6 +485,15 @@ mod write {
470
485
}
471
486
}
472
487
488
+ // Determine the proto for a fn type given the proto for its associated
489
+ // code. This is needed because fn and lambda have fn type while iter
490
+ // has iter type and block has block type. This may end up changing.
491
+ fn proto_to_ty_proto( & ast:: proto proto) -> ast:: proto {
492
+ ret alt ( proto) {
493
+ ast:: proto_iter | ast:: proto_block { proto }
494
+ _ { ast:: proto_fn }
495
+ } ;
496
+ }
473
497
474
498
// Item collection - a pair of bootstrap passes:
475
499
//
@@ -511,8 +535,8 @@ mod collect {
511
535
out_constrs += ~[ ty:: ast_constr_to_constr ( cx. tcx , constr) ] ;
512
536
}
513
537
auto t_fn =
514
- ty:: mk_fn ( cx. tcx , proto, input_tys, output_ty , decl . cf ,
515
- out_constrs) ;
538
+ ty:: mk_fn ( cx. tcx , proto_to_ty_proto ( proto) , input_tys,
539
+ output_ty , decl . cf , out_constrs) ;
516
540
auto ty_param_count = ivec:: len[ ast:: ty_param] ( ty_params) ;
517
541
auto tpt = rec ( count=ty_param_count, ty=t_fn) ;
518
542
alt ( def_id) {
@@ -590,9 +614,9 @@ mod collect {
590
614
for ( @ast:: constr constr in m. node. meth. decl. constraints) {
591
615
out_constrs += ~[ ty:: ast_constr_to_constr ( cx. tcx , constr) ] ;
592
616
}
593
- ret rec( proto=m. node . meth . proto , ident=m . node . ident ,
594
- inputs=inputs, output=output, cf=m . node . meth . decl . cf ,
595
- constrs=out_constrs) ;
617
+ ret rec( proto=proto_to_ty_proto ( m. node . meth . proto ) ,
618
+ ident=m . node . ident , inputs=inputs, output=output,
619
+ cf=m . node . meth . decl . cf , constrs=out_constrs) ;
596
620
}
597
621
fn ty_of_obj ( @ctxt cx , & ast:: ident id, & ast:: _obj ob,
598
622
& ast:: ty_param[ ] ty_params) -> ty:: ty_param_count_and_ty {
@@ -872,7 +896,7 @@ mod unify {
872
896
}
873
897
}
874
898
875
- tag autoderef_kind { AUTODEREF_OK ; NO_AUTODEREF ; }
899
+ tag autoderef_kind { AUTODEREF_OK ; NO_AUTODEREF ; AUTODEREF_BLOCK_COERCE ; }
876
900
877
901
// FIXME This is almost a duplicate of ty::type_autoderef, with structure_of
878
902
// instead of ty::struct.
@@ -917,6 +941,29 @@ fn count_boxes(&@fn_ctxt fcx, &span sp, &ty::t t) -> uint {
917
941
fail;
918
942
}
919
943
944
+ fn do_fn_block_coerce( & @fn_ctxt fcx, & span sp,
945
+ & ty:: t actual, & ty:: t expected) -> ty:: t {
946
+ // fns can be silently coerced to blocks when being used as
947
+ // function call or bind arguments, but not the reverse.
948
+ // If our actual type is a fn and our expected type is a block,
949
+ // build up a new expected type that is identical to the old one
950
+ // except for its proto. If we don't know the expected or actual
951
+ // types, that's fine, but we can't do the coercion.
952
+ ret alt ( structure_of_maybe( fcx, sp, actual) ) {
953
+ some( ty:: ty_fn( ast:: proto_fn, ?args, ?ret_ty, ?cf, ?constrs) ) {
954
+ alt ( structure_of_maybe( fcx, sp, expected) ) {
955
+ some( ty:: ty_fn( ast:: proto_block, _, _, _, _) ) {
956
+ ty:: mk_fn( fcx. ccx. tcx,
957
+ ast:: proto_block, args, ret_ty, cf, constrs)
958
+ }
959
+ _ { actual }
960
+ }
961
+ }
962
+ _ { actual }
963
+ }
964
+ }
965
+
966
+
920
967
fn resolve_type_vars_if_possible( & @fn_ctxt fcx, ty:: t typ) -> ty:: t {
921
968
alt ( ty:: unify:: fixup_vars( fcx. ccx. tcx, fcx. var_bindings, typ) ) {
922
969
case ( fix_ok( ?new_type) ) { ret new_type; }
@@ -951,6 +998,8 @@ mod demand {
951
998
expected_1 = do_autoderef( fcx, sp, expected_1) ;
952
999
actual_1 = do_autoderef( fcx, sp, actual_1) ;
953
1000
implicit_boxes = count_boxes( fcx, sp, actual) ;
1001
+ } else if ( adk == AUTODEREF_BLOCK_COERCE ) {
1002
+ actual_1 = do_fn_block_coerce( fcx, sp, actual, expected) ;
954
1003
}
955
1004
let ty:: t[ mutable] ty_param_substs = ~[ mutable] ;
956
1005
let int[ ] ty_param_subst_var_ids = ~[ ] ;
@@ -1175,11 +1224,12 @@ type gather_result =
1175
1224
rec( @ty:: unify:: var_bindings var_bindings,
1176
1225
hashmap[ ast:: node_id, int] locals,
1177
1226
hashmap[ ast:: node_id, ast:: ident] local_names,
1178
- int next_var_id) ;
1227
+ @mutable int next_var_id) ;
1179
1228
1180
1229
// Used only as a helper for check_fn.
1181
1230
fn gather_locals( & @crate_ctxt ccx, & ast:: _fn f,
1182
- & ast:: node_id id) -> gather_result {
1231
+ & ast:: node_id id, & option:: t[ @fn_ctxt] old_fcx)
1232
+ -> gather_result {
1183
1233
fn next_var_id( @mutable int nvi) -> int {
1184
1234
auto rv = * nvi;
1185
1235
* nvi += 1 ;
@@ -1201,10 +1251,22 @@ fn gather_locals(&@crate_ctxt ccx, &ast::_fn f,
1201
1251
}
1202
1252
}
1203
1253
}
1204
- auto vb = ty:: unify:: mk_var_bindings( ) ;
1205
- auto locals = new_int_hash[ int] ( ) ;
1206
- auto local_names = new_int_hash[ ast:: ident] ( ) ;
1207
- auto nvi = @mutable 0 ;
1254
+
1255
+ auto vb; auto locals; auto local_names; auto nvi;
1256
+ alt ( old_fcx) {
1257
+ none {
1258
+ vb = ty:: unify:: mk_var_bindings( ) ;
1259
+ locals = new_int_hash[ int] ( ) ;
1260
+ local_names = new_int_hash[ ast:: ident] ( ) ;
1261
+ nvi = @mutable 0 ;
1262
+ }
1263
+ some( ?fcx) {
1264
+ vb = fcx. var_bindings;
1265
+ locals = fcx. locals;
1266
+ local_names = fcx. local_names;
1267
+ nvi = fcx. next_var_id;
1268
+ }
1269
+ }
1208
1270
1209
1271
// Add object fields, if any.
1210
1272
auto obj_fields = ~[ ] ;
@@ -1288,7 +1350,7 @@ fn gather_locals(&@crate_ctxt ccx, &ast::_fn f,
1288
1350
ret rec( var_bindings=vb,
1289
1351
locals=locals,
1290
1352
local_names=local_names,
1291
- next_var_id=* nvi) ;
1353
+ next_var_id=nvi) ;
1292
1354
}
1293
1355
1294
1356
// AST fragment checking
@@ -1555,8 +1617,9 @@ fn check_expr(&@fn_ctxt fcx, &@ast::expr expr) {
1555
1617
alt ( a_opt) {
1556
1618
case ( some( ?a) ) {
1557
1619
check_expr( fcx, a) ;
1558
- demand:: simple( fcx, a. span, arg_tys. ( i) . ty,
1559
- expr_ty( fcx. ccx. tcx, a) ) ;
1620
+ demand:: full( fcx, a. span, arg_tys. ( i) . ty,
1621
+ expr_ty( fcx. ccx. tcx, a) , ~[ ] ,
1622
+ AUTODEREF_BLOCK_COERCE ) ;
1560
1623
}
1561
1624
case ( none) {
1562
1625
check_ty_vars = true;
@@ -2013,7 +2076,7 @@ fn check_expr(&@fn_ctxt fcx, &@ast::expr expr) {
2013
2076
collect:: ty_of_fn_decl( cx, convert, ty_of_arg, f. decl,
2014
2077
f. proto, ~[ ] , none) . ty;
2015
2078
write:: ty_only_fixup( fcx, id, fty) ;
2016
- check_fn( fcx. ccx, f, id) ;
2079
+ check_fn( fcx. ccx, f, id, some ( fcx ) ) ;
2017
2080
}
2018
2081
case ( ast:: expr_block( ?b) ) {
2019
2082
check_block( fcx, b) ;
@@ -2487,8 +2550,8 @@ fn check_expr(&@fn_ctxt fcx, &@ast::expr expr) {
2487
2550
}
2488
2551
2489
2552
fn next_ty_var_id( @fn_ctxt fcx) -> int {
2490
- auto id = fcx. next_var_id ;
2491
- fcx. next_var_id += 1 ;
2553
+ auto id = * fcx. next_var_id ;
2554
+ * fcx. next_var_id = fcx . next_var_id + 1 ;
2492
2555
ret id;
2493
2556
}
2494
2557
@@ -2586,24 +2649,25 @@ fn check_const(&@crate_ctxt ccx, &span sp, &@ast::expr e, &ast::node_id id) {
2586
2649
var_bindings=ty:: unify:: mk_var_bindings ( ) ,
2587
2650
locals=new_int_hash[ int] ( ) ,
2588
2651
local_names=new_int_hash[ ast:: ident] ( ) ,
2589
- mutable next_var_id=0 ,
2652
+ next_var_id=@mutable 0 ,
2590
2653
mutable fixups=fixups,
2591
2654
ccx=ccx) ;
2592
2655
check_expr ( fcx, e) ;
2593
2656
}
2594
2657
2595
- fn check_fn ( & @crate_ctxt ccx , & ast:: _fn f, & ast:: node_id id) {
2658
+ fn check_fn ( & @crate_ctxt ccx , & ast:: _fn f, & ast:: node_id id,
2659
+ & option:: t[ @fn_ctxt] old_fcx ) {
2596
2660
auto decl = f. decl ;
2597
2661
auto body = f. body ;
2598
- auto gather_result = gather_locals ( ccx, f, id) ;
2662
+ auto gather_result = gather_locals ( ccx, f, id, old_fcx ) ;
2599
2663
let ast:: node_id[ ] fixups = ~[ ] ;
2600
2664
let @fn_ctxt fcx =
2601
2665
@rec ( ret_ty=ast_ty_to_ty_crate ( ccx, decl. output ) ,
2602
2666
purity=decl. purity ,
2603
2667
var_bindings=gather_result. var_bindings ,
2604
2668
locals=gather_result. locals ,
2605
2669
local_names=gather_result. local_names ,
2606
- mutable next_var_id=gather_result. next_var_id ,
2670
+ next_var_id=gather_result. next_var_id ,
2607
2671
mutable fixups=fixups,
2608
2672
ccx=ccx) ;
2609
2673
@@ -2636,7 +2700,7 @@ fn check_fn(&@crate_ctxt ccx, &ast::_fn f, &ast::node_id id) {
2636
2700
}
2637
2701
2638
2702
fn check_method ( & @crate_ctxt ccx , & @ast:: method method) {
2639
- check_fn ( ccx, method. node . meth , method. node . id ) ;
2703
+ check_fn ( ccx, method. node . meth , method. node . id , none ) ;
2640
2704
}
2641
2705
2642
2706
fn check_item ( @crate_ctxt ccx , & @ast:: item it) {
@@ -2645,10 +2709,10 @@ fn check_item(@crate_ctxt ccx, &@ast::item it) {
2645
2709
check_const ( ccx, it. span , e, it. id ) ;
2646
2710
}
2647
2711
case ( ast:: item_fn ( ?f, _) ) {
2648
- check_fn ( ccx, f, it. id ) ;
2712
+ check_fn ( ccx, f, it. id , none ) ;
2649
2713
}
2650
2714
case ( ast:: item_res ( ?f, ?dtor_id, _, _) ) {
2651
- check_fn ( ccx, f, dtor_id) ;
2715
+ check_fn ( ccx, f, dtor_id, none ) ;
2652
2716
}
2653
2717
case ( ast:: item_obj ( ?ob, _, _) ) {
2654
2718
// We're entering an object, so gather up the info we need.
0 commit comments