Fail on function definitions in contracts other than the main contract
This commit is contained in:
parent
482d22d46b
commit
2d6d506d63
@ -707,19 +707,33 @@ check_unexpected(Xs) ->
|
||||
|
||||
check_modifiers(Env, Contracts) ->
|
||||
create_type_errors(),
|
||||
[ case C of
|
||||
{contract, _, Con, Decls} ->
|
||||
check_modifiers_(Env, Contracts),
|
||||
destroy_and_report_type_errors(Env).
|
||||
|
||||
check_modifiers_(Env, [{contract, _, Con, Decls} | Rest]) ->
|
||||
IsMain = Rest == [],
|
||||
check_modifiers1(contract, Decls),
|
||||
case {lists:keymember(letfun, 1, Decls),
|
||||
[ D || D <- Decls, aeso_syntax:get_ann(entrypoint, D, false) ]} of
|
||||
{true, []} -> type_error({contract_has_no_entrypoints, Con});
|
||||
_ -> ok
|
||||
_ when not IsMain ->
|
||||
case [ {Ann, Id} || {letfun, Ann, Id, _, _, _} <- Decls ] of
|
||||
[{Ann, Id} | _] -> type_error({definition_in_non_main_contract, Ann, Id});
|
||||
[] -> ok
|
||||
end;
|
||||
{namespace, _, _, Decls} -> check_modifiers1(namespace, Decls);
|
||||
{pragma, Ann, Pragma} -> check_pragma(Env, Ann, Pragma);
|
||||
Decl -> type_error({bad_top_level_decl, Decl})
|
||||
end || C <- Contracts ],
|
||||
destroy_and_report_type_errors(Env).
|
||||
_ -> ok
|
||||
end,
|
||||
check_modifiers_(Env, Rest);
|
||||
check_modifiers_(Env, [{namespace, _, _, Decls} | Rest]) ->
|
||||
check_modifiers1(namespace, Decls),
|
||||
check_modifiers_(Env, Rest);
|
||||
check_modifiers_(Env, [{pragma, Ann, Pragma} | Rest]) ->
|
||||
check_pragma(Env, Ann, Pragma),
|
||||
check_modifiers_(Env, Rest);
|
||||
check_modifiers_(Env, [Decl | Rest]) ->
|
||||
type_error({bad_top_level_decl, Decl}),
|
||||
check_modifiers_(Env, Rest);
|
||||
check_modifiers_(_Env, []) -> ok.
|
||||
|
||||
-spec check_pragma(env(), aeso_syntax:ann(), aeso_syntax:pragma()) -> ok.
|
||||
check_pragma(_Env, Ann, {compiler, Op, Ver}) ->
|
||||
@ -2359,6 +2373,10 @@ mk_error({contract_has_no_entrypoints, Con}) ->
|
||||
"contract functions must be declared with the 'entrypoint' keyword instead of\n"
|
||||
"'function'.\n", [pp_expr("", Con), pp_loc(Con)]),
|
||||
mk_t_err(pos(Con), Msg);
|
||||
mk_error({definition_in_non_main_contract, Ann, {id, _, Id}}) ->
|
||||
Msg = "Only the main contract can contain defined functions or entrypoints.\n",
|
||||
Cxt = io_lib:format("Fix: replace the definition of '~s' by a type signature.\n", [Id]),
|
||||
mk_t_err(pos(Ann), Msg, Cxt);
|
||||
mk_error({unbound_type, Type}) ->
|
||||
Msg = io_lib:format("Unbound type ~s (at ~s).\n", [pp_type("", Type), pp_loc(Type)]),
|
||||
mk_t_err(pos(Type), Msg);
|
||||
|
@ -573,6 +573,10 @@ failing_contracts() ->
|
||||
<<?Pos(2, 1)
|
||||
"Cannot compile with this version of the compiler,\n"
|
||||
"because it does not satisfy the constraint ", Version/binary, " == 9.9.9">>])
|
||||
, ?TYPE_ERROR(multiple_contracts,
|
||||
[<<?Pos(2, 3)
|
||||
"Only the main contract can contain defined functions or entrypoints.\n"
|
||||
"Fix: replace the definition of 'foo' by a type signature.">>])
|
||||
].
|
||||
|
||||
-define(Path(File), "code_errors/" ??File).
|
||||
|
5
test/contracts/multiple_contracts.aes
Normal file
5
test/contracts/multiple_contracts.aes
Normal file
@ -0,0 +1,5 @@
|
||||
contract ContractOne =
|
||||
entrypoint foo() = "foo"
|
||||
|
||||
contract ContractTwo =
|
||||
entrypoint bar() = "bar"
|
Loading…
x
Reference in New Issue
Block a user