Properly handle type errors during desugar

This commit is contained in:
Hans Svensson 2021-01-25 21:24:08 +01:00
parent f1d95484a5
commit 22aaeceba8
3 changed files with 14 additions and 1 deletions

View File

@ -623,7 +623,9 @@ check_scope_name_clash(Env, Kind, Name) ->
-spec infer_contract_top(env(), main_contract | contract | namespace, [aeso_syntax:decl()], list(option())) -> -spec infer_contract_top(env(), main_contract | contract | namespace, [aeso_syntax:decl()], list(option())) ->
{env(), [aeso_syntax:decl()]}. {env(), [aeso_syntax:decl()]}.
infer_contract_top(Env, Kind, Defs0, Options) -> infer_contract_top(Env, Kind, Defs0, Options) ->
create_type_errors(),
Defs = desugar(Defs0), Defs = desugar(Defs0),
destroy_and_report_type_errors(Env),
infer_contract(Env, Kind, Defs, Options). infer_contract(Env, Kind, Defs, Options).
%% infer_contract takes a proplist mapping global names to types, and %% infer_contract takes a proplist mapping global names to types, and
@ -2586,6 +2588,9 @@ mk_error({mixed_record_and_map, Expr}) ->
Msg = io_lib:format("Mixed record fields and map keys in\n~s", Msg = io_lib:format("Mixed record fields and map keys in\n~s",
[pp_expr(" ", Expr)]), [pp_expr(" ", Expr)]),
mk_t_err(pos(Expr), Msg); mk_t_err(pos(Expr), Msg);
mk_error({conflicting_updates_for_field, Upd, Key}) ->
Msg = io_lib:format("Conflicting updates for field '~s'\n", [Key]),
mk_t_err(pos(Upd), Msg);
mk_error(Err) -> mk_error(Err) ->
Msg = io_lib:format("Unknown error: ~p\n", [Err]), Msg = io_lib:format("Unknown error: ~p\n", [Err]),
mk_t_err(pos(0, 0), Msg). mk_t_err(pos(0, 0), Msg).
@ -2808,7 +2813,7 @@ desugar_updates([Upd | Updates]) ->
{More, Updates1} = updates_key(Key, Updates), {More, Updates1} = updates_key(Key, Updates),
%% Check conflicts %% Check conflicts
case length([ [] || [] <- [Rest | More] ]) of case length([ [] || [] <- [Rest | More] ]) of
N when N > 1 -> error({conflicting_updates_for_field, Upd, Key}); N when N > 1 -> type_error({conflicting_updates_for_field, Upd, Key});
_ -> ok _ -> ok
end, end,
[MakeField(lists:append([Rest | More])) | desugar_updates(Updates1)]. [MakeField(lists:append([Rest | More])) | desugar_updates(Updates1)].

View File

@ -713,6 +713,9 @@ failing_contracts() ->
" g : (int, string) => 'c\nto arguments\n" " g : (int, string) => 'c\nto arguments\n"
" \"Litwo, ojczyzno moja\" : string">> " \"Litwo, ojczyzno moja\" : string">>
]) ])
, ?TYPE_ERROR(bad_state,
[<<?Pos(4, 16)
"Conflicting updates for field 'foo'">>])
]. ].
-define(Path(File), "code_errors/" ??File). -define(Path(File), "code_errors/" ??File).

View File

@ -0,0 +1,5 @@
contract C =
record state = { foo : int }
entrypoint init(i : int) =
state{ foo = i,
foo = 42 }