From 22aaeceba8210fd4ca2268c867f523806b7c2689 Mon Sep 17 00:00:00 2001 From: Hans Svensson Date: Mon, 25 Jan 2021 21:24:08 +0100 Subject: [PATCH] Properly handle type errors during desugar --- src/aeso_ast_infer_types.erl | 7 ++++++- test/aeso_compiler_tests.erl | 3 +++ test/contracts/bad_state.aes | 5 +++++ 3 files changed, 14 insertions(+), 1 deletion(-) create mode 100644 test/contracts/bad_state.aes diff --git a/src/aeso_ast_infer_types.erl b/src/aeso_ast_infer_types.erl index e7f151e..86027bf 100644 --- a/src/aeso_ast_infer_types.erl +++ b/src/aeso_ast_infer_types.erl @@ -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())) -> {env(), [aeso_syntax:decl()]}. infer_contract_top(Env, Kind, Defs0, Options) -> + create_type_errors(), Defs = desugar(Defs0), + destroy_and_report_type_errors(Env), infer_contract(Env, Kind, Defs, Options). %% 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", [pp_expr(" ", Expr)]), 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) -> Msg = io_lib:format("Unknown error: ~p\n", [Err]), mk_t_err(pos(0, 0), Msg). @@ -2808,7 +2813,7 @@ desugar_updates([Upd | Updates]) -> {More, Updates1} = updates_key(Key, Updates), %% Check conflicts 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 end, [MakeField(lists:append([Rest | More])) | desugar_updates(Updates1)]. diff --git a/test/aeso_compiler_tests.erl b/test/aeso_compiler_tests.erl index a6c76a6..8fd6c53 100644 --- a/test/aeso_compiler_tests.erl +++ b/test/aeso_compiler_tests.erl @@ -713,6 +713,9 @@ failing_contracts() -> " g : (int, string) => 'c\nto arguments\n" " \"Litwo, ojczyzno moja\" : string">> ]) + , ?TYPE_ERROR(bad_state, + [<>]) ]. -define(Path(File), "code_errors/" ??File). diff --git a/test/contracts/bad_state.aes b/test/contracts/bad_state.aes new file mode 100644 index 0000000..e632a41 --- /dev/null +++ b/test/contracts/bad_state.aes @@ -0,0 +1,5 @@ +contract C = + record state = { foo : int } + entrypoint init(i : int) = + state{ foo = i, + foo = 42 }