Skip to content

Commit 0fdad30

Browse files
committed
Fix ret/put mis-identification in typechecker. Closes #87.
1 parent 777002c commit 0fdad30

File tree

2 files changed

+48
-6
lines changed

2 files changed

+48
-6
lines changed

src/boot/me/type.ml

+40-6
Original file line numberDiff line numberDiff line change
@@ -216,6 +216,20 @@ let process_crate (cx:ctxt) (crate:Ast.crate) : unit =
216216
in
217217

218218
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+
219233
let push_retval_tv tv =
220234
Stack.push tv retval_tvs
221235
in
@@ -1215,13 +1229,27 @@ let process_crate (cx:ctxt) (crate:Ast.crate) : unit =
12151229
| Ast.STMT_if { Ast.if_test = if_test } ->
12161230
unify_expr rval_ctx if_test (ty Ast.TY_bool);
12171231

1218-
| Ast.STMT_ret atom_opt
1219-
| Ast.STMT_put atom_opt ->
1232+
| Ast.STMT_ret atom_opt ->
12201233
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
12211248
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())
12231250
| Some atom -> unify_atom arg_pass_ctx atom (retval_tv())
1224-
end
1251+
else
1252+
err None "Non-iter function with 'put'"
12251253

12261254
| Ast.STMT_be (callee, args) ->
12271255
check_callable (retval_tv()) callee args
@@ -1344,19 +1372,25 @@ let process_crate (cx:ctxt) (crate:Ast.crate) : unit =
13441372
in
13451373

13461374
let enter_fn fn retspec =
1375+
push_fn fn;
13471376
let out = fn.Ast.fn_output_slot in
13481377
push_retval_tv (ref retspec);
13491378
unify_slot arg_pass_ctx out.node (Some out.id) (retval_tv())
13501379
in
13511380

1381+
let leave_fn _ =
1382+
pop_retval_tv ();
1383+
pop_fn ();
1384+
in
1385+
13521386
let visit_obj_fn_pre obj ident fn =
13531387
enter_fn fn.node TYSPEC_all;
13541388
inner.Walk.visit_obj_fn_pre obj ident fn
13551389
in
13561390

13571391
let visit_obj_fn_post obj ident fn =
13581392
inner.Walk.visit_obj_fn_post obj ident fn;
1359-
pop_retval_tv ();
1393+
leave_fn ();
13601394
in
13611395

13621396
let visit_mod_item_pre n p mod_item =
@@ -1382,7 +1416,7 @@ let process_crate (cx:ctxt) (crate:Ast.crate) : unit =
13821416
match mod_item.node.Ast.decl_item with
13831417

13841418
| Ast.MOD_ITEM_fn _ ->
1385-
pop_retval_tv ();
1419+
leave_fn ();
13861420
if (Some (path_name())) = cx.ctxt_main_name
13871421
then
13881422
begin

src/test/compile-fail/put-in-fn.rs

+8
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
// error-pattern: Non-iter function
2+
3+
fn f() -> int {
4+
put 10;
5+
}
6+
7+
fn main() {
8+
}

0 commit comments

Comments
 (0)