@@ -228,10 +228,10 @@ fn check_fn(ccx: @crate_ctxt,
228
228
node_type_substs: map:: int_hash ( ) }
229
229
}
230
230
some( fcx) => {
231
- assert fn_ty. purity == ast:: impure_fn;
232
231
{ infcx: fcx. infcx ,
233
232
locals: fcx. locals ,
234
- purity: fcx. purity ,
233
+ purity: ty:: determine_inherited_purity ( fcx. purity , fn_ty. purity ,
234
+ fn_ty. proto ) ,
235
235
node_types: fcx. node_types ,
236
236
node_type_substs: fcx. node_type_substs }
237
237
}
@@ -1187,14 +1187,9 @@ fn check_expr_with_unifier(fcx: @fn_ctxt,
1187
1187
}
1188
1188
}
1189
1189
1190
- enum fn_or_ast_proto {
1191
- foap_fn_proto( ty:: fn_proto) ,
1192
- foap_ast_proto( ast:: proto)
1193
- }
1194
-
1195
1190
fn check_expr_fn( fcx: @fn_ctxt,
1196
1191
expr: @ast:: expr,
1197
- fn_or_ast_proto : fn_or_ast_proto ,
1192
+ ast_proto_opt : option<ast :: proto> ,
1198
1193
decl: ast:: fn_decl,
1199
1194
body: ast:: blk,
1200
1195
is_loop_body: bool ,
@@ -1205,44 +1200,48 @@ fn check_expr_with_unifier(fcx: @fn_ctxt,
1205
1200
// avoid capture of bound regions in the expected type. See
1206
1201
// def'n of br_cap_avoid() for a more lengthy explanation of
1207
1202
// what's going on here.
1208
- let expected_tys = do unpack_expected( fcx, expected) |sty| {
1209
- match sty {
1210
- ty:: ty_fn( ref fn_ty) => {
1203
+ // Also try to pick up inferred purity and proto, defaulting
1204
+ // to impure and block. Note that we only will use those for
1205
+ // block syntax lambdas; that is, lambdas without explicit
1206
+ // protos.
1207
+ let expected_sty = unpack_expected( fcx, expected, |x| some( x) ) ;
1208
+ let ( expected_tys, expected_purity, expected_proto) =
1209
+ match expected_sty {
1210
+ some( ty:: ty_fn( ref fn_ty) ) => {
1211
1211
let { fn_ty, _} =
1212
1212
replace_bound_regions_in_fn_ty(
1213
1213
tcx, @nil, none, fn_ty,
1214
1214
|br| ty:: re_bound( ty:: br_cap_avoid( expr. id, @br) ) ) ;
1215
- some( { inputs: fn_ty. inputs,
1216
- output: fn_ty. output} )
1215
+ ( some( { inputs: fn_ty. inputs,
1216
+ output: fn_ty. output} ) ,
1217
+ fn_ty. purity,
1218
+ fn_ty. proto)
1217
1219
}
1218
- _ => { none}
1219
- }
1220
- } ;
1220
+ _ => {
1221
+ ( none, ast:: impure_fn, ty:: proto_vstore( ty:: vstore_box) )
1222
+ }
1223
+ } ;
1221
1224
1222
- let ast_proto;
1223
- match fn_or_ast_proto {
1224
- foap_fn_proto( fn_proto) => {
1225
- // Generate a fake AST prototype. We'll fill in the type with
1226
- // the real one later.
1227
- // XXX: This is a hack.
1228
- ast_proto = ast:: proto_box;
1229
- }
1230
- foap_ast_proto( existing_ast_proto) => {
1231
- ast_proto = existing_ast_proto;
1232
- }
1233
- }
1234
1225
1235
- let purity = ast:: impure_fn;
1226
+ // Generate AST prototypes and purity.
1227
+ // If this is a block lambda (ast_proto == none), these values
1228
+ // are bogus. We'll fill in the type with the real one later.
1229
+ // XXX: This is a hack.
1230
+ let ast_proto = ast_proto_opt. get_default( ast:: proto_box) ;
1231
+ let ast_purity = ast:: impure_fn;
1236
1232
1237
1233
// construct the function type
1238
- let mut fn_ty = astconv:: ty_of_fn_decl( fcx, fcx, ast_proto , purity ,
1239
- @~[ ] ,
1234
+ let mut fn_ty = astconv:: ty_of_fn_decl( fcx, fcx,
1235
+ ast_proto , ast_purity , @~[ ] ,
1240
1236
decl, expected_tys, expr. span) ;
1241
1237
1242
1238
// Patch up the function declaration, if necessary.
1243
- match fn_or_ast_proto {
1244
- foap_fn_proto( fn_proto) => fn_ty. proto = fn_proto,
1245
- foap_ast_proto( _) => { }
1239
+ match ast_proto_opt {
1240
+ none => {
1241
+ fn_ty. purity = expected_purity;
1242
+ fn_ty. proto = expected_proto;
1243
+ }
1244
+ some( _) => { }
1246
1245
}
1247
1246
1248
1247
let fty = ty:: mk_fn( tcx, fn_ty) ;
@@ -1602,17 +1601,13 @@ fn check_expr_with_unifier(fcx: @fn_ctxt,
1602
1601
bot = alt::check_alt(fcx, expr, discrim, arms);
1603
1602
}
1604
1603
ast::expr_fn(proto, decl, body, cap_clause) => {
1605
- check_expr_fn(fcx, expr, foap_ast_proto (proto),
1604
+ check_expr_fn(fcx, expr, some (proto),
1606
1605
decl, body, false,
1607
1606
expected);
1608
1607
capture::check_capture_clause(tcx, expr.id, cap_clause);
1609
1608
}
1610
1609
ast::expr_fn_block(decl, body, cap_clause) => {
1611
- // Take the prototype from the expected type, but default to block:
1612
- let proto = do unpack_expected(fcx, expected) |sty| {
1613
- match sty { ty::ty_fn({proto, _}) => some(proto), _ => none }
1614
- }.get_default(ty::proto_vstore(ty::vstore_box));
1615
- check_expr_fn(fcx, expr, foap_fn_proto(proto),
1610
+ check_expr_fn(fcx, expr, none,
1616
1611
decl, body, false,
1617
1612
expected);
1618
1613
capture::check_capture_clause(tcx, expr.id, cap_clause);
@@ -1625,7 +1620,7 @@ fn check_expr_with_unifier(fcx: @fn_ctxt,
1625
1620
// 1. a closure that returns a bool is expected
1626
1621
// 2. the cloure that was given returns unit
1627
1622
let expected_sty = unpack_expected(fcx, expected, |x| some(x));
1628
- let ( inner_ty, proto) = match expected_sty {
1623
+ let inner_ty = match expected_sty {
1629
1624
some(ty::ty_fn(fty)) => {
1630
1625
match fcx.mk_subty(false, expr.span,
1631
1626
fty.output, ty::mk_bool(tcx)) {
@@ -1637,7 +1632,7 @@ fn check_expr_with_unifier(fcx: @fn_ctxt,
1637
1632
fcx. infcx. ty_to_str( fty. output) ) ) ;
1638
1633
}
1639
1634
}
1640
- ( ty:: mk_fn( tcx, { output: ty:: mk_nil( tcx) with fty} ) , fty . proto )
1635
+ ty:: mk_fn( tcx, { output: ty:: mk_nil( tcx) with fty} )
1641
1636
}
1642
1637
_ => {
1643
1638
tcx. sess. span_fatal( expr. span, ~"a `loop ` function' s last \
@@ -1647,7 +1642,7 @@ fn check_expr_with_unifier(fcx: @fn_ctxt,
1647
1642
};
1648
1643
match check b.node {
1649
1644
ast::expr_fn_block(decl, body, cap_clause) => {
1650
- check_expr_fn(fcx, b, foap_fn_proto(proto) ,
1645
+ check_expr_fn(fcx, b, none ,
1651
1646
decl, body, true,
1652
1647
some(inner_ty));
1653
1648
demand::suptype(fcx, b.span, inner_ty, fcx.expr_ty(b));
@@ -1665,9 +1660,9 @@ fn check_expr_with_unifier(fcx: @fn_ctxt,
1665
1660
}
1666
1661
ast::expr_do_body(b) => {
1667
1662
let expected_sty = unpack_expected(fcx, expected, |x| some(x));
1668
- let ( inner_ty, proto) = match expected_sty {
1663
+ let inner_ty = match expected_sty {
1669
1664
some(ty::ty_fn(fty)) => {
1670
- ( ty::mk_fn(tcx, fty), fty.proto )
1665
+ ty::mk_fn(tcx, fty)
1671
1666
}
1672
1667
_ => {
1673
1668
tcx.sess.span_fatal(expr.span, ~" Non -function passed to a `do` \
@@ -1677,7 +1672,7 @@ fn check_expr_with_unifier(fcx: @fn_ctxt,
1677
1672
};
1678
1673
match check b.node {
1679
1674
ast::expr_fn_block(decl, body, cap_clause) => {
1680
- check_expr_fn(fcx, b, foap_fn_proto(proto) ,
1675
+ check_expr_fn(fcx, b, none ,
1681
1676
decl, body, true,
1682
1677
some(inner_ty));
1683
1678
demand::suptype(fcx, b.span, inner_ty, fcx.expr_ty(b));
0 commit comments