@@ -13,7 +13,8 @@ type ltype =
13
13
14
14
type fn_ctx = {
15
15
fnctx_return_type : Ast .ty ;
16
- fnctx_is_iter : bool
16
+ fnctx_is_iter : bool ;
17
+ mutable fnctx_just_saw_ret : bool
17
18
}
18
19
19
20
exception Type_error of string * Ast. ty
@@ -627,10 +628,19 @@ let check_stmt (cx:Semant.ctxt) : (fn_ctx -> Ast.stmt -> unit) =
627
628
(* Again as above, we explicitly curry [fn_ctx] to avoid threading it
628
629
* through these functions. *)
629
630
let check_stmt (fn_ctx :fn_ctx ) : (Ast.stmt -> unit) =
631
+ let check_ret (stmt :Ast.stmt ) : unit =
632
+ fn_ctx.fnctx_just_saw_ret < -
633
+ match stmt.Common. node with
634
+ Ast. STMT_ret _ | Ast. STMT_be _ | Ast. STMT_fail
635
+ | Ast. STMT_yield _ -> true
636
+ | _ -> false
637
+ in
638
+
630
639
let rec check_block (block :Ast.block ) : unit =
631
640
Array. iter check_stmt block.Common. node
632
641
633
642
and check_stmt (stmt :Ast.stmt ) : unit =
643
+ check_ret stmt;
634
644
match stmt.Common. node with
635
645
Ast. STMT_spawn (dst , _ , callee , args ) ->
636
646
infer_lval Ast. TY_task dst;
@@ -841,7 +851,11 @@ let process_crate (cx:Semant.ctxt) (crate:Ast.crate) : unit =
841
851
842
852
let visitor (cx :Semant.ctxt ) (inner :Walk.visitor ) : Walk.visitor =
843
853
let push_fn_ctx (ret_ty :Ast.ty ) (is_iter :bool ) =
844
- let fn_ctx = { fnctx_return_type = ret_ty; fnctx_is_iter = is_iter } in
854
+ let fn_ctx = {
855
+ fnctx_return_type = ret_ty;
856
+ fnctx_is_iter = is_iter;
857
+ fnctx_just_saw_ret = false
858
+ } in
845
859
Stack. push fn_ctx fn_ctx_stack
846
860
in
847
861
@@ -852,10 +866,19 @@ let process_crate (cx:Semant.ctxt) (crate:Ast.crate) : unit =
852
866
push_fn_ctx (Common. option_get ret_ty) is_iter
853
867
in
854
868
869
+ let finish_function (item_id :Common.node_id ) =
870
+ let fn_ctx = Stack. pop fn_ctx_stack in
871
+ if not fn_ctx.fnctx_just_saw_ret &&
872
+ fn_ctx.fnctx_return_type <> Ast. TY_nil &&
873
+ not fn_ctx.fnctx_is_iter then
874
+ Common. err (Some item_id) " this function must return a value"
875
+ in
876
+
855
877
let visit_mod_item_pre _ _ item =
856
878
let { Common. node = item; Common. id = item_id } = item in
857
879
match item.Ast. decl_item with
858
- Ast. MOD_ITEM_fn _ ->
880
+ Ast. MOD_ITEM_fn _ when
881
+ not (Hashtbl. mem cx.Semant. ctxt_required_items item_id) ->
859
882
let fn_ty = Hashtbl. find cx.Semant. ctxt_all_item_types item_id in
860
883
begin
861
884
match fn_ty with
@@ -867,9 +890,12 @@ let process_crate (cx:Semant.ctxt) (crate:Ast.crate) : unit =
867
890
| _ -> ()
868
891
in
869
892
let visit_mod_item_post _ _ item =
870
- verify_main item.Common. id;
893
+ let item_id = item.Common. id in
894
+ verify_main item_id;
871
895
match item.Common. node.Ast. decl_item with
872
- Ast. MOD_ITEM_fn _ -> ignore (Stack. pop fn_ctx_stack)
896
+ Ast. MOD_ITEM_fn _ when
897
+ not (Hashtbl. mem cx.Semant. ctxt_required_items item_id) ->
898
+ finish_function item_id
873
899
| _ -> ()
874
900
in
875
901
@@ -884,7 +910,7 @@ let process_crate (cx:Semant.ctxt) (crate:Ast.crate) : unit =
884
910
" Type.visit_obj_fn_pre: item doesn't have an object type (%a)"
885
911
Ast. sprintf_ty obj_ty
886
912
in
887
- let visit_obj_fn_post _ _ _ = ignore ( Stack. pop fn_ctx_stack ) in
913
+ let visit_obj_fn_post _ _ item = finish_function (item. Common. id ) in
888
914
889
915
let visit_obj_drop_pre _ _ = push_fn_ctx Ast. TY_nil false in
890
916
let visit_obj_drop_post _ _ = ignore (Stack. pop fn_ctx_stack) in
0 commit comments