Move the missing_definition error to the type checker
This commit is contained in:
parent
7b8957b46a
commit
878c229ebd
@ -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).
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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),
|
||||
|
@ -289,34 +289,26 @@ failing_contracts() ->
|
||||
|
||||
%% Type errors
|
||||
, ?TYPE_ERROR(name_clash,
|
||||
[<<?Pos(14, 3)
|
||||
[<<?Pos(4, 3)
|
||||
"Duplicate definitions of `double_def` at\n"
|
||||
" - line 3, column 3\n"
|
||||
" - line 4, column 3">>,
|
||||
<<?Pos(7, 3)
|
||||
"Duplicate definitions of `abort` at\n"
|
||||
" - (builtin location)\n"
|
||||
" - line 14, column 3">>,
|
||||
<<?Pos(15, 3)
|
||||
" - line 7, column 3">>,
|
||||
<<?Pos(8, 3)
|
||||
"Duplicate definitions of `require` at\n"
|
||||
" - (builtin location)\n"
|
||||
" - line 15, column 3">>,
|
||||
<<?Pos(11, 3)
|
||||
"Duplicate definitions of `double_def` at\n"
|
||||
" - line 10, column 3\n"
|
||||
" - line 11, column 3">>,
|
||||
<<?Pos(5, 3)
|
||||
"Duplicate definitions of `double_proto` at\n"
|
||||
" - line 4, column 3\n"
|
||||
" - line 5, column 3">>,
|
||||
<<?Pos(8, 3)
|
||||
"Duplicate definitions of `proto_and_def` at\n"
|
||||
" - line 7, column 3\n"
|
||||
" - line 8, column 3">>,
|
||||
<<?Pos(16, 3)
|
||||
<<?Pos(9, 3)
|
||||
"Duplicate definitions of `put` at\n"
|
||||
" - (builtin location)\n"
|
||||
" - line 16, column 3">>,
|
||||
<<?Pos(17, 3)
|
||||
" - line 9, column 3">>,
|
||||
<<?Pos(10, 3)
|
||||
"Duplicate definitions of `state` at\n"
|
||||
" - (builtin location)\n"
|
||||
" - line 17, column 3">>])
|
||||
" - line 10, column 3">>])
|
||||
, ?TYPE_ERROR(type_errors,
|
||||
[<<?Pos(17, 23)
|
||||
"Unbound variable `zz`">>,
|
||||
@ -1025,6 +1017,12 @@ failing_contracts() ->
|
||||
<<?Pos(44,13)
|
||||
"Cannot unify `Animal` and `Cat` in a covariant context\n"
|
||||
"when checking the type of the pattern `q15 : oracle_query(Cat, Cat)` against the expected type `oracle_query(Cat, Animal)`">>])
|
||||
, ?TYPE_ERROR(missing_definition,
|
||||
[<<?Pos(2,14)
|
||||
"Missing definition of function `foo`">>])
|
||||
, ?TYPE_ERROR(child_with_decls,
|
||||
[<<?Pos(2,14)
|
||||
"Missing definition of function `f`">>])
|
||||
].
|
||||
|
||||
-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_() ->
|
||||
|
@ -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
|
Loading…
x
Reference in New Issue
Block a user