@@ -216,6 +216,20 @@ let process_crate (cx:ctxt) (crate:Ast.crate) : unit =
216
216
in
217
217
218
218
let retval_tvs = Stack. create () in
219
+ let fns = Stack. create () in
220
+
221
+ let push_fn fn =
222
+ Stack. push fn fns
223
+ in
224
+
225
+ let pop_fn _ =
226
+ ignore (Stack. pop fns)
227
+ in
228
+
229
+ let fn_is_iter() =
230
+ (Stack. top fns).Ast. fn_aux.Ast. fn_is_iter
231
+ in
232
+
219
233
let push_retval_tv tv =
220
234
Stack. push tv retval_tvs
221
235
in
@@ -1215,13 +1229,27 @@ let process_crate (cx:ctxt) (crate:Ast.crate) : unit =
1215
1229
| Ast. STMT_if { Ast. if_test = if_test } ->
1216
1230
unify_expr rval_ctx if_test (ty Ast. TY_bool );
1217
1231
1218
- | Ast. STMT_ret atom_opt
1219
- | Ast. STMT_put atom_opt ->
1232
+ | Ast. STMT_ret atom_opt ->
1220
1233
begin
1234
+ if fn_is_iter()
1235
+ then
1236
+ match atom_opt with
1237
+ | None -> ()
1238
+ | Some _ -> err None " Iter returning value"
1239
+ else
1240
+ match atom_opt with
1241
+ | None -> unify_ty arg_pass_ctx Ast. TY_nil (retval_tv() )
1242
+ | Some atom -> unify_atom arg_pass_ctx atom (retval_tv() )
1243
+ end
1244
+
1245
+ | Ast. STMT_put atom_opt ->
1246
+ if fn_is_iter()
1247
+ then
1221
1248
match atom_opt with
1222
- None -> unify_ty arg_pass_ctx Ast. TY_nil (retval_tv() )
1249
+ | None -> unify_ty arg_pass_ctx Ast. TY_nil (retval_tv() )
1223
1250
| Some atom -> unify_atom arg_pass_ctx atom (retval_tv() )
1224
- end
1251
+ else
1252
+ err None " Non-iter function with 'put'"
1225
1253
1226
1254
| Ast. STMT_be (callee , args ) ->
1227
1255
check_callable (retval_tv() ) callee args
@@ -1344,19 +1372,25 @@ let process_crate (cx:ctxt) (crate:Ast.crate) : unit =
1344
1372
in
1345
1373
1346
1374
let enter_fn fn retspec =
1375
+ push_fn fn;
1347
1376
let out = fn.Ast. fn_output_slot in
1348
1377
push_retval_tv (ref retspec);
1349
1378
unify_slot arg_pass_ctx out.node (Some out.id) (retval_tv() )
1350
1379
in
1351
1380
1381
+ let leave_fn _ =
1382
+ pop_retval_tv () ;
1383
+ pop_fn () ;
1384
+ in
1385
+
1352
1386
let visit_obj_fn_pre obj ident fn =
1353
1387
enter_fn fn.node TYSPEC_all ;
1354
1388
inner.Walk. visit_obj_fn_pre obj ident fn
1355
1389
in
1356
1390
1357
1391
let visit_obj_fn_post obj ident fn =
1358
1392
inner.Walk. visit_obj_fn_post obj ident fn;
1359
- pop_retval_tv () ;
1393
+ leave_fn () ;
1360
1394
in
1361
1395
1362
1396
let visit_mod_item_pre n p mod_item =
@@ -1382,7 +1416,7 @@ let process_crate (cx:ctxt) (crate:Ast.crate) : unit =
1382
1416
match mod_item.node.Ast. decl_item with
1383
1417
1384
1418
| Ast. MOD_ITEM_fn _ ->
1385
- pop_retval_tv () ;
1419
+ leave_fn () ;
1386
1420
if (Some (path_name() )) = cx.ctxt_main_name
1387
1421
then
1388
1422
begin
0 commit comments