diff --git a/src/boot/me/type.ml b/src/boot/me/type.ml index 20f2443d79b14..62ae1f677beb3 100644 --- a/src/boot/me/type.ml +++ b/src/boot/me/type.ml @@ -13,7 +13,8 @@ type ltype = type fn_ctx = { fnctx_return_type: Ast.ty; - fnctx_is_iter: bool + fnctx_is_iter: bool; + mutable fnctx_just_saw_ret: bool } exception Type_error of string * Ast.ty @@ -627,10 +628,19 @@ let check_stmt (cx:Semant.ctxt) : (fn_ctx -> Ast.stmt -> unit) = (* Again as above, we explicitly curry [fn_ctx] to avoid threading it * through these functions. *) let check_stmt (fn_ctx:fn_ctx) : (Ast.stmt -> unit) = + let check_ret (stmt:Ast.stmt) : unit = + fn_ctx.fnctx_just_saw_ret <- + match stmt.Common.node with + Ast.STMT_ret _ | Ast.STMT_be _ | Ast.STMT_fail + | Ast.STMT_yield _ -> true + | _ -> false + in + let rec check_block (block:Ast.block) : unit = Array.iter check_stmt block.Common.node and check_stmt (stmt:Ast.stmt) : unit = + check_ret stmt; match stmt.Common.node with Ast.STMT_spawn (dst, _, callee, args) -> infer_lval Ast.TY_task dst; @@ -841,7 +851,11 @@ let process_crate (cx:Semant.ctxt) (crate:Ast.crate) : unit = let visitor (cx:Semant.ctxt) (inner:Walk.visitor) : Walk.visitor = let push_fn_ctx (ret_ty:Ast.ty) (is_iter:bool) = - let fn_ctx = { fnctx_return_type = ret_ty; fnctx_is_iter = is_iter } in + let fn_ctx = { + fnctx_return_type = ret_ty; + fnctx_is_iter = is_iter; + fnctx_just_saw_ret = false + } in Stack.push fn_ctx fn_ctx_stack in @@ -852,10 +866,19 @@ let process_crate (cx:Semant.ctxt) (crate:Ast.crate) : unit = push_fn_ctx (Common.option_get ret_ty) is_iter in + let finish_function (item_id:Common.node_id) = + let fn_ctx = Stack.pop fn_ctx_stack in + if not fn_ctx.fnctx_just_saw_ret && + fn_ctx.fnctx_return_type <> Ast.TY_nil && + not fn_ctx.fnctx_is_iter then + Common.err (Some item_id) "this function must return a value" + in + let visit_mod_item_pre _ _ item = let { Common.node = item; Common.id = item_id } = item in match item.Ast.decl_item with - Ast.MOD_ITEM_fn _ -> + Ast.MOD_ITEM_fn _ when + not (Hashtbl.mem cx.Semant.ctxt_required_items item_id) -> let fn_ty = Hashtbl.find cx.Semant.ctxt_all_item_types item_id in begin match fn_ty with @@ -867,9 +890,12 @@ let process_crate (cx:Semant.ctxt) (crate:Ast.crate) : unit = | _ -> () in let visit_mod_item_post _ _ item = - verify_main item.Common.id; + let item_id = item.Common.id in + verify_main item_id; match item.Common.node.Ast.decl_item with - Ast.MOD_ITEM_fn _ -> ignore (Stack.pop fn_ctx_stack) + Ast.MOD_ITEM_fn _ when + not (Hashtbl.mem cx.Semant.ctxt_required_items item_id) -> + finish_function item_id | _ -> () in @@ -884,7 +910,7 @@ let process_crate (cx:Semant.ctxt) (crate:Ast.crate) : unit = "Type.visit_obj_fn_pre: item doesn't have an object type (%a)" Ast.sprintf_ty obj_ty in - let visit_obj_fn_post _ _ _ = ignore (Stack.pop fn_ctx_stack) in + let visit_obj_fn_post _ _ item = finish_function (item.Common.id) in let visit_obj_drop_pre _ _ = push_fn_ctx Ast.TY_nil false in let visit_obj_drop_post _ _ = ignore (Stack.pop fn_ctx_stack) in diff --git a/src/lib/_io.rs b/src/lib/_io.rs index d41ab1327aa77..e171e617b945e 100644 --- a/src/lib/_io.rs +++ b/src/lib/_io.rs @@ -15,6 +15,7 @@ fn new_buf() -> vec[u8] { } // FIXME (issue #93): should be: // ret _vec.alloc[u8](default_bufsz()); + ret v; } fn new_buf_reader(str s) -> buf_reader { diff --git a/src/lib/_str.rs b/src/lib/_str.rs index 167b9f6775481..062d8bf146f21 100644 --- a/src/lib/_str.rs +++ b/src/lib/_str.rs @@ -9,6 +9,7 @@ native "rust" mod rustrt { } fn is_utf8(vec[u8] v) -> bool { + fail; // FIXME } fn alloc(uint n_bytes) -> str { diff --git a/src/test/compile-fail/impure-pred.rs b/src/test/compile-fail/impure-pred.rs index 811d595aade10..82d4cf6fa3c0b 100644 --- a/src/test/compile-fail/impure-pred.rs +++ b/src/test/compile-fail/impure-pred.rs @@ -9,6 +9,7 @@ io fn lt(int a, int b) -> bool { let port[int] p = port(); let chan[int] c = chan(p); c <| 10; + ret true; } fn main() { diff --git a/src/test/compile-fail/missing-return.rs b/src/test/compile-fail/missing-return.rs new file mode 100644 index 0000000000000..34fb4105b8e00 --- /dev/null +++ b/src/test/compile-fail/missing-return.rs @@ -0,0 +1,9 @@ +// error-pattern: return + +fn f() -> int { +} + +fn main() { + f(); +} + diff --git a/src/test/run-pass/complex.rs b/src/test/run-pass/complex.rs index 3a6c13f3136fc..3687de7a71507 100644 --- a/src/test/run-pass/complex.rs +++ b/src/test/run-pass/complex.rs @@ -21,6 +21,7 @@ fn foo(int x) -> int { let t z; z = 0x55; foo(z); + ret 0; } fn main() {