diff --git a/src/aeso_ast_infer_types.erl b/src/aeso_ast_infer_types.erl index 61b26ab..0c319f4 100644 --- a/src/aeso_ast_infer_types.erl +++ b/src/aeso_ast_infer_types.erl @@ -1013,6 +1013,9 @@ infer_contract(Env0, What, Defs0, Options) -> contract -> bind_state(Env1) %% bind state and put end, {ProtoSigs, Decls} = lists:unzip([ check_fundecl(Env1, Decl) || Decl <- Get(prototype, Defs) ]), + [ type_error({missing_definition, Id}) || {fun_decl, _, Id, _} <- Decls, + What =:= contract, + get_option(no_code, false) =:= false ], Env3 = bind_funs(ProtoSigs, Env2), Functions = Get(function, Defs), %% Check for duplicates in Functions (we turn it into a map below) @@ -3484,6 +3487,9 @@ mk_error({unimplemented_interface_function, ConId, InterfaceName, FunName}) -> mk_error({referencing_undefined_interface, InterfaceId}) -> Msg = io_lib:format("Trying to implement or extend an undefined interface `~s`", [pp(InterfaceId)]), mk_t_err(pos(InterfaceId), Msg); +mk_error({missing_definition, Id}) -> + Msg = io_lib:format("Missing definition of function `~s`", [name(Id)]), + mk_t_err(pos(Id), Msg); mk_error(Err) -> Msg = io_lib:format("Unknown error: ~p", [Err]), mk_t_err(pos(0, 0), Msg). diff --git a/src/aeso_ast_to_fcode.erl b/src/aeso_ast_to_fcode.erl index d0328c9..bf6e648 100644 --- a/src/aeso_ast_to_fcode.erl +++ b/src/aeso_ast_to_fcode.erl @@ -377,11 +377,6 @@ decls_to_fcode(Env, Decls) -> end, Env1, Decls). -spec decl_to_fcode(env(), aeso_syntax:decl()) -> env(). -decl_to_fcode(Env = #{context := {contract_def, _}}, {fun_decl, _, Id, _}) -> - case is_no_code(Env) of - false -> fcode_error({missing_definition, Id}); - true -> Env - end; decl_to_fcode(Env, {fun_decl, _, _, _}) -> Env; decl_to_fcode(Env, {type_def, _Ann, Name, Args, Def}) -> typedef_to_fcode(Env, Name, Args, Def); diff --git a/src/aeso_code_errors.erl b/src/aeso_code_errors.erl index 269d8d7..ea36803 100644 --- a/src/aeso_code_errors.erl +++ b/src/aeso_code_errors.erl @@ -18,9 +18,6 @@ format({missing_init_function, Con}) -> Msg = io_lib:format("Missing init function for the contract '~s'.", [pp_expr(Con)]), Cxt = "The 'init' function can only be omitted if the state type is 'unit'.", mk_err(pos(Con), Msg, Cxt); -format({missing_definition, Id}) -> - Msg = io_lib:format("Missing definition of function '~s'.", [pp_expr(Id)]), - mk_err(pos(Id), Msg); format({parameterized_state, Decl}) -> Msg = "The state type cannot be parameterized.", mk_err(pos(Decl), Msg); diff --git a/test/aeso_aci_tests.erl b/test/aeso_aci_tests.erl index 43ac0c3..70b1600 100644 --- a/test/aeso_aci_tests.erl +++ b/test/aeso_aci_tests.erl @@ -127,7 +127,7 @@ check_stub(Stub, Options) -> Ast -> try %% io:format("AST: ~120p\n", [Ast]), - aeso_ast_infer_types:infer(Ast, []) + aeso_ast_infer_types:infer(Ast, [no_code]) catch throw:{type_errors, TE} -> io:format("Type error:\n~s\n", [TE]), error(TE); diff --git a/test/aeso_calldata_tests.erl b/test/aeso_calldata_tests.erl index 2fb7a36..88d7bae 100644 --- a/test/aeso_calldata_tests.erl +++ b/test/aeso_calldata_tests.erl @@ -29,7 +29,7 @@ calldata_aci_test_() -> [ {"Testing " ++ ContractName ++ " contract calling " ++ Fun, fun() -> ContractString = aeso_test_utils:read_contract(ContractName), - {ok, ContractACIBin} = aeso_aci:contract_interface(string, ContractString), + {ok, ContractACIBin} = aeso_aci:contract_interface(string, ContractString, [no_code]), ContractACI = binary_to_list(ContractACIBin), io:format("ACI:\n~s\n", [ContractACIBin]), FateExprs = ast_exprs(ContractACI, Fun, Args), diff --git a/test/aeso_compiler_tests.erl b/test/aeso_compiler_tests.erl index fe53c95..9be8d9c 100644 --- a/test/aeso_compiler_tests.erl +++ b/test/aeso_compiler_tests.erl @@ -289,34 +289,26 @@ failing_contracts() -> %% Type errors , ?TYPE_ERROR(name_clash, - [<>, + <>, - <>, + <>, - <>, - <>, - <>, - <>, - <>, + <>]) + " - line 10, column 3">>]) , ?TYPE_ERROR(type_errors, [<>, @@ -1025,6 +1017,12 @@ failing_contracts() -> <>]) + , ?TYPE_ERROR(missing_definition, + [<>]) + , ?TYPE_ERROR(child_with_decls, + [<>]) ]. -define(Path(File), "code_errors/" ??File). @@ -1033,9 +1031,7 @@ failing_contracts() -> -define(FATE_ERR(File, Line, Col, Err), {?Path(File), ?Msg(File, Line, Col, Err)}). failing_code_gen_contracts() -> - [ ?FATE_ERR(missing_definition, 2, 14, - "Missing definition of function 'foo'.") - , ?FATE_ERR(higher_order_entrypoint, 2, 20, + [ ?FATE_ERR(higher_order_entrypoint, 2, 20, "The argument\n" " f : (int) => int\n" "of entrypoint 'apply' has a higher-order (contains function types) type.") @@ -1074,8 +1070,6 @@ failing_code_gen_contracts() -> "Invalid oracle type\n" " oracle(string, (int) => int)\n" "The response type must not be higher-order (contain function types).") - , ?FATE_ERR(child_with_decls, 2, 14, - "Missing definition of function 'f'.") ]. validation_test_() -> diff --git a/test/contracts/code_errors/child_with_decls.aes b/test/contracts/child_with_decls.aes similarity index 100% rename from test/contracts/code_errors/child_with_decls.aes rename to test/contracts/child_with_decls.aes diff --git a/test/contracts/code_errors/missing_definition.aes b/test/contracts/missing_definition.aes similarity index 100% rename from test/contracts/code_errors/missing_definition.aes rename to test/contracts/missing_definition.aes diff --git a/test/contracts/name_clash.aes b/test/contracts/name_clash.aes index 1e8d8e2..2154b80 100644 --- a/test/contracts/name_clash.aes +++ b/test/contracts/name_clash.aes @@ -1,12 +1,5 @@ - contract NameClash = - entrypoint double_proto : () => int - entrypoint double_proto : () => int - - entrypoint proto_and_def : int => int - entrypoint proto_and_def(n) = n + 1 - entrypoint double_def(x) = x entrypoint double_def(y) = 0 @@ -14,4 +7,4 @@ contract NameClash = entrypoint abort() : int = 0 entrypoint require(b, err) = if(b) abort(err) entrypoint put(x) = x - entrypoint state(x, y) = x + y + entrypoint state(x, y) = x + y \ No newline at end of file