From 37d86ad45bc0070cf4603d877a8b0b182e93d113 Mon Sep 17 00:00:00 2001 From: Gaith Hallak Date: Fri, 17 Dec 2021 13:00:49 +0200 Subject: [PATCH] Simplify error messages reported by the compiler Add raw error message for 2 errors The errors: `unnamed_map_update_with_default` and `unbound_variable`. Revert "Add raw error message for 2 errors" This reverts commit 0db6d16140d52e29cd8a12d8719ee57ca874d5f5. Remove trailing new lines and at POS from error messages Convert multiple line error messages into single line error messages Remove at POS from pp_why_record context Change error message with new line before code Fix tests for changed error messages Fix the rest of the error messages Add new line after error message Remove new line from the end of data error messages --- src/aeso_ast_infer_types.erl | 402 ++++++++++++------------- src/aeso_code_errors.erl | 46 +-- src/aeso_compiler.erl | 22 +- src/aeso_errors.erl | 6 +- test/aeso_abi_tests.erl | 8 +- test/aeso_compiler_tests.erl | 568 +++++++++++++++-------------------- 6 files changed, 485 insertions(+), 567 deletions(-) diff --git a/src/aeso_ast_infer_types.erl b/src/aeso_ast_infer_types.erl index 3a52b66..0e87869 100644 --- a/src/aeso_ast_infer_types.erl +++ b/src/aeso_ast_infer_types.erl @@ -378,7 +378,7 @@ lookup_env(Env, Kind, Ann, Name) -> when_warning(warn_unused_includes, fun() -> used_include(AnnR) end), Res; Many -> - type_error({ambiguous_name, [{qid, A, Q} || {Q, {A, _}} <- Many]}), + type_error({ambiguous_name, qid(Ann, Name), [{qid, A, Q} || {Q, {A, _}} <- Many]}), false end end. @@ -2936,35 +2936,35 @@ mk_t_err_from_warn(Warn) -> mk_error({no_decls, File}) -> Pos = aeso_errors:pos(File, 0, 0), - mk_t_err(Pos, "Empty contract\n"); + mk_t_err(Pos, "Empty contract"); mk_error({mismatched_decl_in_funblock, Name, Decl}) -> - Msg = io_lib:format("Mismatch in the function block. Expected implementation/type declaration of ~s function\n", [Name]), + Msg = io_lib:format("Mismatch in the function block. Expected implementation/type declaration of ~s function", [Name]), mk_t_err(pos(Decl), Msg); mk_error({higher_kinded_typevar, T}) -> - Msg = io_lib:format("Type ~s is a higher kinded type variable\n" - "(takes another type as an argument)\n", [pp(instantiate(T))] + Msg = io_lib:format("Type `~s` is a higher kinded type variable " + "(takes another type as an argument)", [pp(instantiate(T))] ), mk_t_err(pos(T), Msg); mk_error({wrong_type_arguments, X, ArityGiven, ArityReal}) -> - Msg = io_lib:format("Arity for ~s doesn't match. Expected ~p, got ~p\n" + Msg = io_lib:format("Arity for ~s doesn't match. Expected ~p, got ~p" , [pp(instantiate(X)), ArityReal, ArityGiven] ), mk_t_err(pos(X), Msg); mk_error({unnamed_map_update_with_default, Upd}) -> - Msg = "Invalid map update with default\n", + Msg = "Invalid map update with default", mk_t_err(pos(Upd), Msg); mk_error({fundecl_must_have_funtype, _Ann, Id, Type}) -> - Msg = io_lib:format("~s at ~s was declared with an invalid type ~s.\n" + Msg = io_lib:format("`~s` was declared with an invalid type `~s`. " "Entrypoints and functions must have functional types" - , [pp(Id), pp_loc(Id), pp(instantiate(Type))]), + , [pp(Id), pp(instantiate(Type))]), mk_t_err(pos(Id), Msg); mk_error({cannot_unify, A, B, When}) -> - Msg = io_lib:format("Cannot unify ~s\n and ~s\n", + Msg = io_lib:format("Cannot unify `~s` and `~s`", [pp(instantiate(A)), pp(instantiate(B))]), {Pos, Ctxt} = pp_when(When), mk_t_err(Pos, Msg, Ctxt); mk_error({unbound_variable, Id}) -> - Msg = io_lib:format("Unbound variable ~s at ~s\n", [pp(Id), pp_loc(Id)]), + Msg = io_lib:format("Unbound variable `~s`", [pp(Id)]), case Id of {qid, _, ["Chain", "event"]} -> Cxt = "Did you forget to define the event type?", @@ -2972,224 +2972,222 @@ mk_error({unbound_variable, Id}) -> _ -> mk_t_err(pos(Id), Msg) end; mk_error({undefined_field, Id}) -> - Msg = io_lib:format("Unbound field ~s at ~s\n", [pp(Id), pp_loc(Id)]), + Msg = io_lib:format("Unbound field ~s", [pp(Id)]), mk_t_err(pos(Id), Msg); mk_error({not_a_record_type, Type, Why}) -> - Msg = io_lib:format("~s\n", [pp_type("Not a record type: ", Type)]), + Msg = io_lib:format("Not a record type: `~s`", [pp_type(Type)]), {Pos, Ctxt} = pp_why_record(Why), mk_t_err(Pos, Msg, Ctxt); mk_error({not_a_contract_type, Type, Cxt}) -> Msg = case Type of {tvar, _, _} -> - "Unresolved contract type\n"; + "Unresolved contract type"; _ -> - io_lib:format("The type ~s is not a contract type\n", [pp_type("", Type)]) + io_lib:format("The type `~s` is not a contract type", [pp_type(Type)]) end, {Pos, Cxt1} = case Cxt of {var_args, Ann, Fun} -> {pos(Ann), - io_lib:format("when calling variadic function\n~s\n", [pp_expr(" ", Fun)])}; + io_lib:format("when calling variadic function `~s`", [pp_expr(Fun)])}; {contract_literal, Lit} -> {pos(Lit), - io_lib:format("when checking that the contract literal\n~s\n" - "has the type\n~s\n", - [pp_expr(" ", Lit), pp_type(" ", Type)])}; + io_lib:format("when checking that the contract literal `~s` has the type `~s`", + [pp_expr(Lit), pp_type(Type)])}; {address_to_contract, Ann} -> {pos(Ann), - io_lib:format("when checking that the call to\n Address.to_contract\n" - "has the type\n~s\n", - [pp_type(" ", Type)])} + io_lib:format("when checking that the call to `Address.to_contract` has the type `~s`", + [pp_type(Type)])} end, mk_t_err(Pos, Msg, Cxt1); mk_error({non_linear_pattern, Pattern, Nonlinear}) -> - Msg = io_lib:format("Repeated name~s ~s in pattern\n~s (at ~s)\n", - [plural("", "s", Nonlinear), string:join(Nonlinear, ", "), - pp_expr(" ", Pattern), pp_loc(Pattern)]), + Msg = io_lib:format("Repeated name~s ~s in the pattern `~s`", + [plural("", "s", Nonlinear), + string:join(lists:map(fun(F) -> "`" ++ F ++ "`" end, Nonlinear), ", "), + pp_expr(Pattern)]), mk_t_err(pos(Pattern), Msg); mk_error({ambiguous_record, Fields = [{_, First} | _], Candidates}) -> - Msg = io_lib:format("Ambiguous record type with field~s ~s (at ~s) could be one of\n~s", - [plural("", "s", Fields), string:join([ pp(F) || {_, F} <- Fields ], ", "), - pp_loc(First), [ [" - ", pp(C), " (at ", pp_loc(C), ")\n"] || C <- Candidates ]]), + Msg = io_lib:format("Ambiguous record type with field~s ~s could be one of~s", + [plural("", "s", Fields), + string:join([ "`" ++ pp(F) ++ "`" || {_, F} <- Fields ], ", "), + [ ["\n - ", "`" ++ pp(C) ++ "`", " (at ", pp_loc(C), ")"] || C <- Candidates ]]), mk_t_err(pos(First), Msg); mk_error({missing_field, Field, Rec}) -> - Msg = io_lib:format("Record type ~s does not have field ~s (at ~s)\n", - [pp(Rec), pp(Field), pp_loc(Field)]), + Msg = io_lib:format("Record type `~s` does not have field `~s`", + [pp(Rec), pp(Field)]), mk_t_err(pos(Field), Msg); mk_error({missing_fields, Ann, RecType, Fields}) -> - Msg = io_lib:format("The field~s ~s ~s missing when constructing an element of type ~s (at ~s)\n", - [plural("", "s", Fields), string:join(Fields, ", "), - plural("is", "are", Fields), pp(RecType), pp_loc(Ann)]), + Msg = io_lib:format("The field~s ~s ~s missing when constructing an element of type `~s`", + [plural("", "s", Fields), + string:join(lists:map(fun(F) -> "`" ++ F ++ "`" end, Fields), ", "), + plural("is", "are", Fields), pp(RecType)]), mk_t_err(pos(Ann), Msg); mk_error({no_records_with_all_fields, Fields = [{_, First} | _]}) -> - Msg = io_lib:format("No record type with field~s ~s (at ~s)\n", - [plural("", "s", Fields), string:join([ pp(F) || {_, F} <- Fields ], ", "), - pp_loc(First)]), + Msg = io_lib:format("No record type with field~s ~s", + [plural("", "s", Fields), + string:join([ "`" ++ pp(F) ++ "`" || {_, F} <- Fields ], ", ")]), mk_t_err(pos(First), Msg); mk_error({recursive_types_not_implemented, Types}) -> S = plural(" is", "s are mutually", Types), - Msg = io_lib:format("The following type~s recursive, which is not yet supported:\n~s", - [S, [io_lib:format(" - ~s (at ~s)\n", [pp(T), pp_loc(T)]) || T <- Types]]), + Msg = io_lib:format("The following type~s recursive, which is not yet supported:~s", + [S, [io_lib:format("\n - `~s` (at ~s)", [pp(T), pp_loc(T)]) || T <- Types]]), mk_t_err(pos(hd(Types)), Msg); mk_error({event_must_be_variant_type, Where}) -> - Msg = io_lib:format("The event type must be a variant type (at ~s)\n", [pp_loc(Where)]), + Msg = io_lib:format("The event type must be a variant type", []), mk_t_err(pos(Where), Msg); mk_error({indexed_type_must_be_word, Type, Type}) -> - Msg = io_lib:format("The indexed type ~s (at ~s) is not a word type\n", - [pp_type("", Type), pp_loc(Type)]), + Msg = io_lib:format("The indexed type `~s` is not a word type", + [pp_type(Type)]), mk_t_err(pos(Type), Msg); mk_error({indexed_type_must_be_word, Type, Type1}) -> - Msg = io_lib:format("The indexed type ~s (at ~s) equals ~s which is not a word type\n", - [pp_type("", Type), pp_loc(Type), pp_type("", Type1)]), + Msg = io_lib:format("The indexed type `~s` equals `~s` which is not a word type", + [pp_type(Type), pp_type(Type1)]), mk_t_err(pos(Type), Msg); mk_error({event_0_to_3_indexed_values, Constr}) -> - Msg = io_lib:format("The event constructor ~s (at ~s) has too many indexed values (max 3)\n", - [name(Constr), pp_loc(Constr)]), + Msg = io_lib:format("The event constructor `~s` has too many indexed values (max 3)", + [name(Constr)]), mk_t_err(pos(Constr), Msg); mk_error({event_0_to_1_string_values, Constr}) -> - Msg = io_lib:format("The event constructor ~s (at ~s) has too many non-indexed values (max 1)\n", - [name(Constr), pp_loc(Constr)]), + Msg = io_lib:format("The event constructor `~s` has too many non-indexed values (max 1)", + [name(Constr)]), mk_t_err(pos(Constr), Msg); mk_error({repeated_constructor, Cs}) -> - Msg = io_lib:format("Variant types must have distinct constructor names\n~s", - [[ io_lib:format("~s (at ~s)\n", [pp_typed(" - ", C, T), pp_loc(C)]) || {C, T} <- Cs ]]), + Msg = io_lib:format("Variant types must have distinct constructor names~s", + [[ io_lib:format("\n`~s` (at ~s)", [pp_typed(" - ", C, T), pp_loc(C)]) || {C, T} <- Cs ]]), mk_t_err(pos(element(1, hd(Cs))), Msg); mk_error({bad_named_argument, [], Name}) -> - Msg = io_lib:format("Named argument ~s (at ~s) supplied to function expecting no named arguments.\n", - [pp(Name), pp_loc(Name)]), + Msg = io_lib:format("Named argument ~s supplied to function expecting no named arguments.", + [pp(Name)]), mk_t_err(pos(Name), Msg); mk_error({bad_named_argument, Args, Name}) -> - Msg = io_lib:format("Named argument ~s (at ~s) is not one of the expected named arguments\n~s", - [pp(Name), pp_loc(Name), - [ io_lib:format("~s\n", [pp_typed(" - ", Arg, Type)]) + Msg = io_lib:format("Named argument `~s` is not one of the expected named arguments~s", + [pp(Name), + [ io_lib:format("\n - `~s`", [pp_typed("", Arg, Type)]) || {named_arg_t, _, Arg, Type, _} <- Args ]]), mk_t_err(pos(Name), Msg); mk_error({unsolved_named_argument_constraint, #named_argument_constraint{name = Name, type = Type}}) -> - Msg = io_lib:format("Named argument ~s (at ~s) supplied to function with unknown named arguments.\n", - [pp_typed("", Name, Type), pp_loc(Name)]), + Msg = io_lib:format("Named argument ~s supplied to function with unknown named arguments.", + [pp_typed("", Name, Type)]), mk_t_err(pos(Name), Msg); mk_error({reserved_entrypoint, Name, Def}) -> - Msg = io_lib:format("The name '~s' is reserved and cannot be used for a\n" - "top-level contract function (at ~s).\n", [Name, pp_loc(Def)]), + Msg = io_lib:format("The name '~s' is reserved and cannot be used for a " + "top-level contract function.", [Name]), mk_t_err(pos(Def), Msg); mk_error({duplicate_definition, Name, Locs}) -> - Msg = io_lib:format("Duplicate definitions of ~s at\n~s", - [Name, [ [" - ", pp_loc(L), "\n"] || L <- Locs ]]), + Msg = io_lib:format("Duplicate definitions of `~s` at~s", + [Name, [ ["\n - ", pp_loc(L)] || L <- Locs ]]), mk_t_err(pos(lists:last(Locs)), Msg); mk_error({duplicate_scope, Kind, Name, OtherKind, L}) -> - Msg = io_lib:format("The ~p ~s (at ~s) has the same name as a ~p at ~s\n", - [Kind, pp(Name), pp_loc(Name), OtherKind, pp_loc(L)]), + Msg = io_lib:format("The ~p `~s` has the same name as a ~p at ~s", + [Kind, pp(Name), OtherKind, pp_loc(L)]), mk_t_err(pos(Name), Msg); mk_error({include, _, {string, Pos, Name}}) -> - Msg = io_lib:format("Include of '~s' at ~s\nnot allowed, include only allowed at top level.\n", - [binary_to_list(Name), pp_loc(Pos)]), + Msg = io_lib:format("Include of `~s` is not allowed, include only allowed at top level.", + [binary_to_list(Name)]), mk_t_err(pos(Pos), Msg); mk_error({namespace, _Pos, {con, Pos, Name}, _Def}) -> - Msg = io_lib:format("Nested namespaces are not allowed\nNamespace '~s' at ~s not defined at top level.\n", - [Name, pp_loc(Pos)]), + Msg = io_lib:format("Nested namespaces are not allowed. Namespace `~s` is not defined at top level.", + [Name]), mk_t_err(pos(Pos), Msg); mk_error({Contract, _Pos, {con, Pos, Name}, _Def}) when ?IS_CONTRACT_HEAD(Contract) -> - Msg = io_lib:format("Nested contracts are not allowed\nContract '~s' at ~s not defined at top level.\n", - [Name, pp_loc(Pos)]), + Msg = io_lib:format("Nested contracts are not allowed. Contract `~s` is not defined at top level.", + [Name]), mk_t_err(pos(Pos), Msg); mk_error({type_decl, _, {id, Pos, Name}, _}) -> - Msg = io_lib:format("Empty type declarations are not supported\nType ~s at ~s lacks a definition\n", - [Name, pp_loc(Pos)]), + Msg = io_lib:format("Empty type declarations are not supported. Type `~s` lacks a definition", + [Name]), mk_t_err(pos(Pos), Msg); mk_error({letval, _Pos, {id, Pos, Name}, _Def}) -> - Msg = io_lib:format("Toplevel \"let\" definitions are not supported\nValue ~s at ~s could be replaced by 0-argument function\n", - [Name, pp_loc(Pos)]), + Msg = io_lib:format("Toplevel \"let\" definitions are not supported. Value `~s` could be replaced by 0-argument function.", + [Name]), mk_t_err(pos(Pos), Msg); mk_error({stateful_not_allowed, Id, Fun}) -> - Msg = io_lib:format("Cannot reference stateful function ~s (at ~s)\nin the definition of non-stateful function ~s.\n", - [pp(Id), pp_loc(Id), pp(Fun)]), + Msg = io_lib:format("Cannot reference stateful function `~s` in the definition of non-stateful function `~s`.", + [pp(Id), pp(Fun)]), mk_t_err(pos(Id), Msg); mk_error({stateful_not_allowed_in_guards, Id}) -> - Msg = io_lib:format("Cannot reference stateful function ~s (at ~s) in a pattern guard.\n", - [pp(Id), pp_loc(Id)]), + Msg = io_lib:format("Cannot reference stateful function `~s` in a pattern guard.", + [pp(Id)]), mk_t_err(pos(Id), Msg); mk_error({value_arg_not_allowed, Value, Fun}) -> - Msg = io_lib:format("Cannot pass non-zero value argument ~s (at ~s)\nin the definition of non-stateful function ~s.\n", - [pp_expr("", Value), pp_loc(Value), pp(Fun)]), + Msg = io_lib:format("Cannot pass non-zero value argument `~s` in the definition of non-stateful function `~s`.", + [pp_expr(Value), pp(Fun)]), mk_t_err(pos(Value), Msg); mk_error({init_depends_on_state, Which, [_Init | Chain]}) -> WhichCalls = fun("put") -> ""; ("state") -> ""; (_) -> ", which calls" end, - Msg = io_lib:format("The init function should return the initial state as its result and cannot ~s the state,\nbut it calls\n~s", + Msg = io_lib:format("The `init` function should return the initial state as its result and cannot ~s the state, but it calls~s", [if Which == put -> "write"; true -> "read" end, - [ io_lib:format(" - ~s (at ~s)~s\n", [Fun, pp_loc(Ann), WhichCalls(Fun)]) + [ io_lib:format("\n - `~s` (at ~s)~s", [Fun, pp_loc(Ann), WhichCalls(Fun)]) || {[_, Fun], Ann} <- Chain]]), mk_t_err(pos(element(2, hd(Chain))), Msg); mk_error({missing_body_for_let, Ann}) -> - Msg = io_lib:format("Let binding at ~s must be followed by an expression\n", [pp_loc(Ann)]), + Msg = io_lib:format("Let binding must be followed by an expression.", []), mk_t_err(pos(Ann), Msg); mk_error({public_modifier_in_contract, Decl}) -> Decl1 = mk_entrypoint(Decl), - Msg = io_lib:format("Use 'entrypoint' instead of 'function' for public function ~s (at ~s):\n~s\n", - [pp_expr("", element(3, Decl)), pp_loc(Decl), - prettypr:format(prettypr:nest(2, aeso_pretty:decl(Decl1)))]), + Msg = io_lib:format("Use `entrypoint` instead of `function` for public function `~s`: `~s`", + [pp_expr(element(3, Decl)), + prettypr:format(aeso_pretty:decl(Decl1))]), mk_t_err(pos(Decl), Msg); mk_error({init_must_be_an_entrypoint, Decl}) -> Decl1 = mk_entrypoint(Decl), - Msg = io_lib:format("The init function (at ~s) must be an entrypoint:\n~s\n", - [pp_loc(Decl), - prettypr:format(prettypr:nest(2, aeso_pretty:decl(Decl1)))]), + Msg = io_lib:format("The init function must be an entrypoint: ~s", + [prettypr:format(prettypr:nest(2, aeso_pretty:decl(Decl1)))]), mk_t_err(pos(Decl), Msg); mk_error({init_must_not_be_payable, Decl}) -> - Msg = io_lib:format("The init function (at ~s) cannot be payable.\n" - "You don't need the 'payable' annotation to be able to attach\n" + Msg = io_lib:format("The init function cannot be payable. " + "You don't need the 'payable' annotation to be able to attach " "funds to the create contract transaction.", - [pp_loc(Decl)]), + []), mk_t_err(pos(Decl), Msg); mk_error({proto_must_be_entrypoint, Decl}) -> Decl1 = mk_entrypoint(Decl), - Msg = io_lib:format("Use 'entrypoint' for declaration of ~s (at ~s):\n~s\n", - [pp_expr("", element(3, Decl)), pp_loc(Decl), - prettypr:format(prettypr:nest(2, aeso_pretty:decl(Decl1)))]), + Msg = io_lib:format("Use `entrypoint` for declaration of `~s`: `~s`", + [pp_expr(element(3, Decl)), + prettypr:format(aeso_pretty:decl(Decl1))]), mk_t_err(pos(Decl), Msg); mk_error({proto_in_namespace, Decl}) -> - Msg = io_lib:format("Namespaces cannot contain function prototypes (at ~s).\n", - [pp_loc(Decl)]), + Msg = io_lib:format("Namespaces cannot contain function prototypes.", []), mk_t_err(pos(Decl), Msg); mk_error({entrypoint_in_namespace, Decl}) -> - Msg = io_lib:format("Namespaces cannot contain entrypoints (at ~s). Use 'function' instead.\n", - [pp_loc(Decl)]), + Msg = io_lib:format("Namespaces cannot contain entrypoints. Use `function` instead.", []), mk_t_err(pos(Decl), Msg); mk_error({private_entrypoint, Decl}) -> - Msg = io_lib:format("The entrypoint ~s (at ~s) cannot be private. Use 'function' instead.\n", - [pp_expr("", element(3, Decl)), pp_loc(Decl)]), + Msg = io_lib:format("The entrypoint `~s` cannot be private. Use `function` instead.", + [pp_expr(element(3, Decl))]), mk_t_err(pos(Decl), Msg); mk_error({private_and_public, Decl}) -> - Msg = io_lib:format("The function ~s (at ~s) cannot be both public and private.\n", - [pp_expr("", element(3, Decl)), pp_loc(Decl)]), + Msg = io_lib:format("The function `~s` cannot be both public and private.", + [pp_expr(element(3, Decl))]), mk_t_err(pos(Decl), Msg); mk_error({contract_has_no_entrypoints, Con}) -> - Msg = io_lib:format("The contract ~s (at ~s) has no entrypoints. Since Sophia version 3.2, public\n" - "contract functions must be declared with the 'entrypoint' keyword instead of\n" - "'function'.\n", [pp_expr("", Con), pp_loc(Con)]), + Msg = io_lib:format("The contract `~s` has no entrypoints. Since Sophia version 3.2, public " + "contract functions must be declared with the `entrypoint` keyword instead of " + "`function`.", [pp_expr(Con)]), mk_t_err(pos(Con), Msg); mk_error({definition_in_contract_interface, Ann, {id, _, Id}}) -> - Msg = "Contract interfaces cannot contain defined functions or entrypoints.\n", - Cxt = io_lib:format("Fix: replace the definition of '~s' by a type signature.\n", [Id]), + Msg = "Contract interfaces cannot contain defined functions or entrypoints.", + Cxt = io_lib:format("Fix: replace the definition of `~s` by a type signature.", [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)]), + Msg = io_lib:format("Unbound type ~s.", [pp_type(Type)]), mk_t_err(pos(Type), Msg); mk_error({new_tuple_syntax, Ann, Ts}) -> - Msg = io_lib:format("Invalid type\n~s (at ~s)\nThe syntax of tuple types changed in Sophia version 4.0. Did you mean\n~s\n", - [pp_type(" ", {args_t, Ann, Ts}), pp_loc(Ann), pp_type(" ", {tuple_t, Ann, Ts})]), + Msg = io_lib:format("Invalid type `~s`. The syntax of tuple types changed in Sophia version 4.0. Did you mean `~s`", + [pp_type({args_t, Ann, Ts}), pp_type({tuple_t, Ann, Ts})]), mk_t_err(pos(Ann), Msg); mk_error({map_in_map_key, Ann, KeyType}) -> - Msg = io_lib:format("Invalid key type\n~s\n", [pp_type(" ", KeyType)]), - Cxt = "Map keys cannot contain other maps.\n", + Msg = io_lib:format("Invalid key type `~s`", [pp_type(KeyType)]), + Cxt = "Map keys cannot contain other maps.", mk_t_err(pos(Ann), Msg, Cxt); mk_error({cannot_call_init_function, Ann}) -> - Msg = "The 'init' function is called exclusively by the create contract transaction\n" - "and cannot be called from the contract code.\n", + Msg = "The 'init' function is called exclusively by the create contract transaction " + "and cannot be called from the contract code.", mk_t_err(pos(Ann), Msg); mk_error({contract_treated_as_namespace, Ann, [Con, Fun] = QName}) -> - Msg = io_lib:format("Invalid call to contract entrypoint '~s'.\n", [string:join(QName, ".")]), - Cxt = io_lib:format("It must be called as 'c.~s' for some c : ~s.\n", [Fun, Con]), + Msg = io_lib:format("Invalid call to contract entrypoint `~s`.", [string:join(QName, ".")]), + Cxt = io_lib:format("It must be called as `c.~s` for some `c : ~s`.", [Fun, Con]), mk_t_err(pos(Ann), Msg, Cxt); mk_error({bad_top_level_decl, Decl}) -> What = case element(1, Decl) of @@ -3197,74 +3195,75 @@ mk_error({bad_top_level_decl, Decl}) -> _ -> "contract or namespace" end, Id = element(3, Decl), - Msg = io_lib:format("The definition of '~s' must appear inside a ~s.\n", - [pp_expr("", Id), What]), + Msg = io_lib:format("The definition of '~s' must appear inside a ~s.", + [pp_expr(Id), What]), mk_t_err(pos(Decl), Msg); mk_error({unknown_byte_length, Type}) -> - Msg = io_lib:format("Cannot resolve length of byte array.\n", []), + Msg = io_lib:format("Cannot resolve length of byte array.", []), mk_t_err(pos(Type), Msg); mk_error({unsolved_bytes_constraint, Ann, concat, A, B, C}) -> Msg = io_lib:format("Failed to resolve byte array lengths in call to Bytes.concat with arguments of type\n" - "~s (at ~s)\n~s (at ~s)\nand result type\n~s (at ~s)\n", + "~s (at ~s)\n~s (at ~s)\nand result type\n~s (at ~s)", [pp_type(" - ", A), pp_loc(A), pp_type(" - ", B), pp_loc(B), pp_type(" - ", C), pp_loc(C)]), mk_t_err(pos(Ann), Msg); mk_error({unsolved_bytes_constraint, Ann, split, A, B, C}) -> Msg = io_lib:format("Failed to resolve byte array lengths in call to Bytes.split with argument of type\n" - "~s (at ~s)\nand result types\n~s (at ~s)\n~s (at ~s)\n", + "~s (at ~s)\nand result types\n~s (at ~s)\n~s (at ~s)", [ pp_type(" - ", C), pp_loc(C), pp_type(" - ", A), pp_loc(A), pp_type(" - ", B), pp_loc(B)]), mk_t_err(pos(Ann), Msg); mk_error({failed_to_get_compiler_version, Err}) -> - Msg = io_lib:format("Failed to get compiler version. Error:\n ~p\n", [Err]), + Msg = io_lib:format("Failed to get compiler version. Error: ~p", [Err]), mk_t_err(pos(0, 0), Msg); mk_error({compiler_version_mismatch, Ann, Version, Op, Bound}) -> PrintV = fun(V) -> string:join([integer_to_list(N) || N <- V], ".") end, - Msg = io_lib:format("Cannot compile with this version of the compiler,\n" + Msg = io_lib:format("Cannot compile with this version of the compiler, " "because it does not satisfy the constraint" - " ~s ~s ~s\n", [PrintV(Version), Op, PrintV(Bound)]), + " ~s ~s ~s", [PrintV(Version), Op, PrintV(Bound)]), mk_t_err(pos(Ann), Msg); mk_error({empty_record_or_map_update, Expr}) -> - Msg = io_lib:format("Empty record/map update\n~s", - [pp_expr(" ", Expr)]), + Msg = io_lib:format("Empty record/map update `~s`", [pp_expr(Expr)]), mk_t_err(pos(Expr), Msg); mk_error({mixed_record_and_map, Expr}) -> - Msg = io_lib:format("Mixed record fields and map keys in\n~s", - [pp_expr(" ", Expr)]), + Msg = io_lib:format("Mixed record fields and map keys in `~s`", [pp_expr(Expr)]), mk_t_err(pos(Expr), Msg); mk_error({named_argument_must_be_literal_bool, Name, Arg}) -> - Msg = io_lib:format("Invalid '~s' argument\n~s\nIt must be either 'true' or 'false'.", [Name, pp_expr(" ", instantiate(Arg))]), + Msg = io_lib:format("Invalid `~s` argument `~s`. " + "It must be either `true` or `false`.", + [Name, pp_expr(instantiate(Arg))]), mk_t_err(pos(Arg), Msg); mk_error({conflicting_updates_for_field, Upd, Key}) -> - Msg = io_lib:format("Conflicting updates for field '~s'\n", [Key]), + Msg = io_lib:format("Conflicting updates for field '~s'", [Key]), mk_t_err(pos(Upd), Msg); mk_error({ambiguous_main_contract, Ann}) -> Msg = "Could not deduce the main contract. You can point it out manually with the `main` keyword.", mk_t_err(pos(Ann), Msg); mk_error({main_contract_undefined, Ann}) -> - Msg = "No contract defined.\n", + Msg = "No contract defined.", mk_t_err(pos(Ann), Msg); mk_error({multiple_main_contracts, Ann}) -> - Msg = "Only one main contract can be defined.\n", + Msg = "Only one main contract can be defined.", mk_t_err(pos(Ann), Msg); mk_error({unify_varargs, When}) -> - Msg = "Cannot unify variable argument list.\n", + Msg = "Cannot unify variable argument list.", {Pos, Ctxt} = pp_when(When), mk_t_err(Pos, Msg, Ctxt); mk_error({clone_no_contract, Ann}) -> - Msg = "Chain.clone requires `ref` named argument of contract type.\n", + Msg = "Chain.clone requires `ref` named argument of contract type.", mk_t_err(pos(Ann), Msg); mk_error({contract_lacks_definition, Type, When}) -> Msg = io_lib:format( - "~s is not implemented.\n", + "~s is not implemented.", [pp_type(Type)] ), {Pos, Ctxt} = pp_when(When), mk_t_err(Pos, Msg, Ctxt); -mk_error({ambiguous_name, QIds = [{qid, Ann, _} | _]}) -> - Names = lists:map(fun(QId) -> io_lib:format("~s at ~s\n", [pp(QId), pp_loc(QId)]) end, QIds), - Msg = "Ambiguous name: " ++ lists:concat(Names), - mk_t_err(pos(Ann), Msg); +mk_error({ambiguous_name, Name, QIds}) -> + Msg = io_lib:format("Ambiguous name `~s` could be one of~s", + [pp(Name), + [io_lib:format("\n - `~s` (at ~s)", [pp(QId), pp_loc(QId)]) || QId <- QIds]]), + mk_t_err(pos(Name), Msg); mk_error({using_undefined_namespace, Ann, Namespace}) -> Msg = io_lib:format("Cannot use undefined namespace ~s", [Namespace]), mk_t_err(pos(Ann), Msg); @@ -3276,38 +3275,38 @@ mk_error({unknown_warning, Warning}) -> Msg = io_lib:format("Trying to report unknown warning: ~p", [Warning]), mk_t_err(pos(0, 0), Msg); mk_error(Err) -> - Msg = io_lib:format("Unknown error: ~p\n", [Err]), + Msg = io_lib:format("Unknown error: ~p", [Err]), mk_t_err(pos(0, 0), Msg). mk_warning({unused_include, FileName, SrcFile}) -> - Msg = io_lib:format("The file ~s is included but not used", [FileName]), + Msg = io_lib:format("The file `~s` is included but not used.", [FileName]), aeso_warnings:new(aeso_errors:pos(SrcFile, 0, 0), Msg); mk_warning({unused_stateful, Ann, FunName}) -> - Msg = io_lib:format("The function ~s is unnecessarily marked as stateful at ~s", [name(FunName), pp_loc(Ann)]), + Msg = io_lib:format("The function `~s` is unnecessarily marked as stateful.", [name(FunName)]), aeso_warnings:new(pos(Ann), Msg); mk_warning({unused_variable, Ann, _Namespace, _Fun, VarName}) -> - Msg = io_lib:format("The variable ~s is defined at ~s but never used", [VarName, pp_loc(Ann)]), + Msg = io_lib:format("The variable `~s` is defined but never used.", [VarName]), aeso_warnings:new(pos(Ann), Msg); mk_warning({unused_typedef, Ann, QName, _Arity}) -> - Msg = io_lib:format("The type ~s is defined at ~s but never used", [lists:last(QName), pp_loc(Ann)]), + Msg = io_lib:format("The type `~s` is defined but never used.", [lists:last(QName)]), aeso_warnings:new(pos(Ann), Msg); mk_warning({unused_return_value, Ann}) -> - Msg = io_lib:format("Unused return value at ~s", [pp_loc(Ann)]), + Msg = io_lib:format("Unused return value.", []), aeso_warnings:new(pos(Ann), Msg); mk_warning({unused_function, Ann, FunName}) -> - Msg = io_lib:format("The function ~s is defined at ~s but never used", [FunName, pp_loc(Ann)]), + Msg = io_lib:format("The function `~s` is defined but never used.", [FunName]), aeso_warnings:new(pos(Ann), Msg); mk_warning({shadowing, Ann, VarName, AnnOld}) -> - Msg = io_lib:format("The definition of ~s at ~s shadows an older definition at ~s", [VarName, pp_loc(Ann), pp_loc(AnnOld)]), + Msg = io_lib:format("The definition of `~s` shadows an older definition at ~s.", [VarName, pp_loc(AnnOld)]), aeso_warnings:new(pos(Ann), Msg); mk_warning({division_by_zero, Ann}) -> - Msg = io_lib:format("Division by zero at ~s", [pp_loc(Ann)]), + Msg = io_lib:format("Division by zero.", []), aeso_warnings:new(pos(Ann), Msg); mk_warning({negative_spend, Ann}) -> - Msg = io_lib:format("Negative spend at ~s", [pp_loc(Ann)]), + Msg = io_lib:format("Negative spend.", []), aeso_warnings:new(pos(Ann), Msg); mk_warning(Warn) -> - Msg = io_lib:format("Unknown warning: ~p\n", [Warn]), + Msg = io_lib:format("Unknown warning: ~p", [Warn]), aeso_warnings:new(Msg). mk_entrypoint(Decl) -> @@ -3316,25 +3315,24 @@ mk_entrypoint(Decl) -> aeso_syntax:get_ann(Decl))) -- [public, private]], aeso_syntax:set_ann(Ann, Decl). -pp_when({todo, What}) -> {pos(0, 0), io_lib:format("[TODO] ~p\n", [What])}; -pp_when({at, Ann}) -> {pos(Ann), io_lib:format("at ~s\n", [pp_loc(Ann)])}; +pp_when({todo, What}) -> {pos(0, 0), io_lib:format("[TODO] ~p", [What])}; +pp_when({at, Ann}) -> {pos(Ann), io_lib:format("at ~s", [pp_loc(Ann)])}; pp_when({check_typesig, Name, Inferred, Given}) -> {pos(Given), - io_lib:format("when checking the definition of ~s (at ~s)\n" - " inferred type: ~s\n" - " given type: ~s\n", - [Name, pp_loc(Given), pp(instantiate(Inferred)), pp(instantiate(Given))])}; + io_lib:format("when checking the definition of `~s`\n" + " inferred type: `~s`\n" + " given type: `~s`", + [Name, pp(instantiate(Inferred)), pp(instantiate(Given))])}; pp_when({infer_app, Fun, NamedArgs, Args, Inferred0, ArgTypes0}) -> Inferred = instantiate(Inferred0), ArgTypes = instantiate(ArgTypes0), {pos(Fun), - io_lib:format("when checking the application at ~s of\n" - "~s\n" - "to arguments\n~s", - [pp_loc(Fun), - pp_typed(" ", Fun, Inferred), - [ [pp_expr(" ", NamedArg), "\n"] || NamedArg <- NamedArgs ] ++ - [ [pp_typed(" ", Arg, ArgT), "\n"] + io_lib:format("when checking the application of\n" + " `~s`\n" + "to arguments~s", + [pp_typed("", Fun, Inferred), + [ ["\n ", "`" ++ pp_expr(NamedArg) ++ "`"] || NamedArg <- NamedArgs ] ++ + [ ["\n ", "`" ++ pp_typed("", Arg, ArgT) ++ "`"] || {Arg, ArgT} <- lists:zip(Args, ArgTypes) ] ])}; pp_when({field_constraint, FieldType0, InferredType0, Fld}) -> FieldType = instantiate(FieldType0), @@ -3348,20 +3346,17 @@ pp_when({field_constraint, FieldType0, InferredType0, Fld}) -> pp_type(" ", InferredType) ]); {field, _Ann, LV, Id, E} -> - io_lib:format("when checking the assignment of the field\n~s (at ~s)\nto the old value ~s and the new value\n~s\n", - [pp_typed(" ", {lvalue, [], LV}, FieldType), - pp_loc(Fld), + io_lib:format("when checking the assignment of the field `~s` to the old value `~s` and the new value `~s`", + [pp_typed("", {lvalue, [], LV}, FieldType), pp(Id), - pp_typed(" ", E, InferredType)]); + pp_typed("", E, InferredType)]); {field, _Ann, LV, E} -> - io_lib:format("when checking the assignment of the field\n~s (at ~s)\nto the value\n~s\n", - [pp_typed(" ", {lvalue, [], LV}, FieldType), - pp_loc(Fld), - pp_typed(" ", E, InferredType)]); + io_lib:format("when checking the assignment of the field `~s` to the value `~s`", + [pp_typed("", {lvalue, [], LV}, FieldType), + pp_typed("", E, InferredType)]); {proj, _Ann, _Rec, _Fld} -> - io_lib:format("when checking the record projection at ~s\n~s\nagainst the expected type\n~s\n", - [pp_loc(Fld), - pp_typed(" ", Fld, FieldType), + io_lib:format("when checking the record projection `~s` against the expected type `~s`", + [pp_typed(" ", Fld, FieldType), pp_type(" ", InferredType)]) end}; pp_when({record_constraint, RecType0, InferredType0, Fld}) -> @@ -3372,23 +3367,23 @@ pp_when({record_constraint, RecType0, InferredType0, Fld}) -> {var_args, _Ann, _Fun} -> {Pos, io_lib:format("when checking that contract construction of type\n~s\n~s\n" - "matches the expected type\n~s\n", + "matches the expected type\n~s", [pp_type(" ", RecType), WhyRec, pp_type(" ", InferredType)] ) }; {field, _Ann, _LV, _Id, _E} -> {Pos, io_lib:format("when checking that the record type\n~s\n~s\n" - "matches the expected type\n~s\n", + "matches the expected type\n~s", [pp_type(" ", RecType), WhyRec, pp_type(" ", InferredType)])}; {field, _Ann, _LV, _E} -> {Pos, io_lib:format("when checking that the record type\n~s\n~s\n" - "matches the expected type\n~s\n", + "matches the expected type\n~s", [pp_type(" ", RecType), WhyRec, pp_type(" ", InferredType)])}; {proj, _Ann, Rec, _FldName} -> {pos(Rec), - io_lib:format("when checking that the expression\n~s (at ~s)\nhas type\n~s\n~s\n", + io_lib:format("when checking that the expression\n~s (at ~s)\nhas type\n~s\n~s", [pp_typed(" ", Rec, InferredType), pp_loc(Rec), pp_type(" ", RecType), WhyRec])} end; @@ -3402,73 +3397,68 @@ pp_when({if_branches, Then, ThenType0, Else, ElseType0}) -> pp_when({case_pat, Pat, PatType0, ExprType0}) -> {PatType, ExprType} = instantiate({PatType0, ExprType0}), {pos(Pat), - io_lib:format("when checking the type of the pattern at ~s\n~s\n" - "against the expected type\n~s\n", - [pp_loc(Pat), pp_typed(" ", Pat, PatType), - pp_type(" ", ExprType)])}; + io_lib:format("when checking the type of the pattern `~s` against the expected type `~s`", + [pp_typed("", Pat, PatType), + pp_type(ExprType)])}; pp_when({check_expr, Expr, Inferred0, Expected0}) -> {Inferred, Expected} = instantiate({Inferred0, Expected0}), {pos(Expr), - io_lib:format("when checking the type of the expression at ~s\n~s\n" - "against the expected type\n~s\n", - [pp_loc(Expr), pp_typed(" ", Expr, Inferred), - pp_type(" ", Expected)])}; + io_lib:format("when checking the type of the expression `~s` against the expected type `~s`", + [pp_typed("", Expr, Inferred), pp_type(Expected)])}; pp_when({checking_init_type, Ann}) -> {pos(Ann), - io_lib:format("when checking that 'init' returns a value of type 'state' at ~s\n", - [pp_loc(Ann)])}; + io_lib:format("when checking that `init` returns a value of type `state`", [])}; pp_when({list_comp, BindExpr, Inferred0, Expected0}) -> {Inferred, Expected} = instantiate({Inferred0, Expected0}), {pos(BindExpr), - io_lib:format("when checking rvalue of list comprehension binding at ~s\n~s\n" - "against type \n~s\n", - [pp_loc(BindExpr), pp_typed(" ", BindExpr, Inferred), pp_type(" ", Expected)])}; + io_lib:format("when checking rvalue of list comprehension binding `~s` against type `~s`", + [pp_typed("", BindExpr, Inferred), pp_type(Expected)])}; pp_when({check_named_arg_constraint, C}) -> {id, _, Name} = Arg = C#named_argument_constraint.name, [Type | _] = [ Type || {named_arg_t, _, {id, _, Name1}, Type, _} <- C#named_argument_constraint.args, Name1 == Name ], - Err = io_lib:format("when checking named argument\n~s\nagainst inferred type\n~s", - [pp_typed(" ", Arg, Type), pp_type(" ", C#named_argument_constraint.type)]), + Err = io_lib:format("when checking named argument `~s` against inferred type `~s`", + [pp_typed("", Arg, Type), pp_type(C#named_argument_constraint.type)]), {pos(Arg), Err}; pp_when({checking_init_args, Ann, Con0, ArgTypes0}) -> Con = instantiate(Con0), ArgTypes = instantiate(ArgTypes0), {pos(Ann), - io_lib:format("when checking arguments of ~s's init entrypoint to match\n(~s)", + io_lib:format("when checking arguments of `~s`'s init entrypoint to match\n(~s)", [pp_type(Con), string:join([pp_type(A) || A <- ArgTypes], ", ")]) }; pp_when({return_contract, App, Con0}) -> Con = instantiate(Con0), {pos(App) - , io_lib:format("when checking that expression returns contract of type\n~s", [pp_type(" ", Con)]) + , io_lib:format("when checking that expression returns contract of type `~s`", [pp_type(Con)]) }; pp_when({arg_name, Id1, Id2, When}) -> {Pos, Ctx} = pp_when(When), {Pos - , io_lib:format("when unifying names of named arguments: ~s and ~s\n~s", [pp_expr(Id1), pp_expr(Id2), Ctx]) + , io_lib:format("when unifying names of named arguments: `~s` and `~s`\n~s", [pp_expr(Id1), pp_expr(Id2), Ctx]) }; pp_when({var_args, Ann, Fun}) -> {pos(Ann) - , io_lib:format("when resolving arguments of variadic function\n~s\n", [pp_expr(" ", Fun)]) + , io_lib:format("when resolving arguments of variadic function `~s`", [pp_expr(Fun)]) }; pp_when(unknown) -> {pos(0,0), ""}. -spec pp_why_record(why_record()) -> {pos(), iolist()}. pp_why_record({var_args, Ann, Fun}) -> {pos(Ann), - io_lib:format("arising from resolution of variadic function ~s (at ~s)", - [pp_expr(Fun), pp_loc(Fun)])}; + io_lib:format("arising from resolution of variadic function `~s`", + [pp_expr(Fun)])}; pp_why_record(Fld = {field, _Ann, LV, _E}) -> {pos(Fld), - io_lib:format("arising from an assignment of the field ~s (at ~s)", - [pp_expr({lvalue, [], LV}), pp_loc(Fld)])}; + io_lib:format("arising from an assignment of the field `~s`", + [pp_expr({lvalue, [], LV})])}; pp_why_record(Fld = {field, _Ann, LV, _Alias, _E}) -> {pos(Fld), - io_lib:format("arising from an assignment of the field ~s (at ~s)", - [pp_expr({lvalue, [], LV}), pp_loc(Fld)])}; + io_lib:format("arising from an assignment of the field `~s`", + [pp_expr({lvalue, [], LV})])}; pp_why_record({proj, _Ann, Rec, FldName}) -> {pos(Rec), - io_lib:format("arising from the projection of the field ~s (at ~s)", - [pp(FldName), pp_loc(Rec)])}. + io_lib:format("arising from the projection of the field `~s`", + [pp(FldName)])}. if_branches(If = {'if', Ann, _, Then, Else}) -> @@ -3487,12 +3477,12 @@ pp_typed(Label, Expr, Type) -> pp_expr(Expr) -> pp_expr("", Expr). pp_expr(Label, Expr) -> - prettypr:format(prettypr:beside(prettypr:text(Label), aeso_pretty:expr(Expr, [show_generated]))). + prettypr:format(prettypr:beside(prettypr:text(Label), aeso_pretty:expr(Expr, [show_generated])), 80, 80). pp_type(Type) -> pp_type("", Type). pp_type(Label, Type) -> - prettypr:format(prettypr:beside(prettypr:text(Label), aeso_pretty:type(Type, [show_generated]))). + prettypr:format(prettypr:beside(prettypr:text(Label), aeso_pretty:type(Type, [show_generated])), 80, 80). src_file(T) -> aeso_syntax:get_ann(file, T, no_file). line_number(T) -> aeso_syntax:get_ann(line, T, 0). diff --git a/src/aeso_code_errors.erl b/src/aeso_code_errors.erl index b3d1308..bc03256 100644 --- a/src/aeso_code_errors.erl +++ b/src/aeso_code_errors.erl @@ -11,21 +11,21 @@ -export([format/1, pos/1]). format({last_declaration_must_be_main_contract, Decl = {Kind, _, {con, _, C}, _}}) -> - Msg = io_lib:format("Expected a main contract as the last declaration instead of the ~p '~s'\n", + Msg = io_lib:format("Expected a main contract as the last declaration instead of the ~p '~s'", [Kind, C]), mk_err(pos(Decl), Msg); format({missing_init_function, Con}) -> - Msg = io_lib:format("Missing init function for the contract '~s'.\n", [pp_expr(Con)]), - Cxt = "The 'init' function can only be omitted if the state type is 'unit'.\n", + 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'.\n", [pp_expr(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.\n", + Msg = "The state type cannot be parameterized.", mk_err(pos(Decl), Msg); format({parameterized_event, Decl}) -> - Msg = "The event type cannot be parameterized.\n", + Msg = "The event type cannot be parameterized.", mk_err(pos(Decl), Msg); format({invalid_entrypoint, Why, Ann, {id, _, Name}, Thing}) -> What = case Why of higher_order -> "higher-order (contains function types)"; @@ -38,54 +38,54 @@ format({invalid_entrypoint, Why, Ann, {id, _, Name}, Thing}) -> {argument, _, _} -> io_lib:format("has a ~s type", [What]); {result, _} -> io_lib:format("is ~s", [What]) end, - Msg = io_lib:format("The ~sof entrypoint '~s' ~s.\n", + Msg = io_lib:format("The ~sof entrypoint '~s' ~s.", [ThingS, Name, Bad]), case Why of polymorphic -> mk_err(pos(Ann), Msg, "Use the FATE backend if you want polymorphic entrypoints.\n"); higher_order -> mk_err(pos(Ann), Msg) end; format({cant_compare_type_aevm, Ann, Op, Type}) -> - StringAndTuple = [ "- type string\n" - "- tuple or record of word type\n" || lists:member(Op, ['==', '!=']) ], + StringAndTuple = [ "\n- type string" + "\n- tuple or record of word type" || lists:member(Op, ['==', '!=']) ], Msg = io_lib:format("Cannot compare values of type\n" "~s\n" "The AEVM only supports '~s' on values of\n" - "- word type (int, bool, bits, address, oracle(_, _), etc)\n" + "- word type (int, bool, bits, address, oracle(_, _), etc)" "~s", [pp_type(2, Type), Op, StringAndTuple]), - Cxt = "Use FATE if you need to compare arbitrary types.\n", + Cxt = "Use FATE if you need to compare arbitrary types.", mk_err(pos(Ann), Msg, Cxt); format({invalid_aens_resolve_type, Ann, T}) -> Msg = io_lib:format("Invalid return type of AENS.resolve:\n" "~s\n" - "It must be a string or a pubkey type (address, oracle, etc).\n", + "It must be a string or a pubkey type (address, oracle, etc).", [pp_type(2, T)]), mk_err(pos(Ann), Msg); format({unapplied_contract_call, Contract}) -> Msg = io_lib:format("The AEVM does not support unapplied contract call to\n" - "~s\n", [pp_expr(2, Contract)]), - Cxt = "Use FATE if you need this.\n", + "~s", [pp_expr(2, Contract)]), + Cxt = "Use FATE if you need this.", mk_err(pos(Contract), Msg, Cxt); format({unapplied_builtin, Id}) -> - Msg = io_lib:format("The AEVM does not support unapplied use of ~s.\n", [pp_expr(0, Id)]), - Cxt = "Use FATE if you need this.\n", + Msg = io_lib:format("The AEVM does not support unapplied use of ~s.", [pp_expr(0, Id)]), + Cxt = "Use FATE if you need this.", mk_err(pos(Id), Msg, Cxt); format({invalid_map_key_type, Why, Ann, Type}) -> - Msg = io_lib:format("Invalid map key type\n~s\n", [pp_type(2, Type)]), + Msg = io_lib:format("Invalid map key type\n~s", [pp_type(2, Type)]), Cxt = case Why of - polymorphic -> "Map keys cannot be polymorphic in the AEVM. Use FATE if you need this.\n"; - function -> "Map keys cannot be higher-order.\n" + polymorphic -> "Map keys cannot be polymorphic in the AEVM. Use FATE if you need this."; + function -> "Map keys cannot be higher-order." end, mk_err(pos(Ann), Msg, Cxt); format({invalid_oracle_type, Why, What, Ann, Type}) -> WhyS = case Why of higher_order -> "higher-order (contain function types)"; polymorphic -> "polymorphic (contain type variables)" end, - Msg = io_lib:format("Invalid oracle type\n~s\n", [pp_type(2, Type)]), - Cxt = io_lib:format("The ~s type must not be ~s.\n", [What, WhyS]), + Msg = io_lib:format("Invalid oracle type\n~s", [pp_type(2, Type)]), + Cxt = io_lib:format("The ~s type must not be ~s.", [What, WhyS]), mk_err(pos(Ann), Msg, Cxt); format({higher_order_state, {type_def, Ann, _, _, State}}) -> - Msg = io_lib:format("Invalid state type\n~s\n", [pp_type(2, State)]), - Cxt = "The state cannot contain functions in the AEVM. Use FATE if you need this.\n", + Msg = io_lib:format("Invalid state type\n~s", [pp_type(2, State)]), + Cxt = "The state cannot contain functions in the AEVM. Use FATE if you need this.", mk_err(pos(Ann), Msg, Cxt); format({var_args_not_set, Expr}) -> mk_err( pos(Expr), "Could not deduce type of variable arguments list" diff --git a/src/aeso_compiler.erl b/src/aeso_compiler.erl index 567099f..348881a 100644 --- a/src/aeso_compiler.erl +++ b/src/aeso_compiler.erl @@ -325,14 +325,14 @@ to_sophia_value(_, _, revert, Data, Options) -> {ok, Err} -> {ok, {app, [], {id, [], "abort"}, [{string, [], Err}]}}; {error, _} -> - Msg = "Could not interpret the revert message\n", + Msg = "Could not interpret the revert message", {error, [aeso_errors:new(data_error, Msg)]} end; fate -> try aeb_fate_encoding:deserialize(Data) of Err -> {ok, {app, [], {id, [], "abort"}, [{string, [], Err}]}} catch _:_ -> - Msg = "Could not deserialize the revert message\n", + Msg = "Could not deserialize the revert message", {error, [aeso_errors:new(data_error, Msg)]} end end; @@ -354,12 +354,12 @@ to_sophia_value(ContractString, FunName, ok, Data, Options0) -> {ok, aeso_vm_decode:from_aevm(VmType, Type, VmValue)} catch throw:cannot_translate_to_sophia -> Type0Str = prettypr:format(aeso_pretty:type(Type0)), - Msg = io_lib:format("Cannot translate VM value ~p\n of type ~p\n to Sophia type ~s\n", + Msg = io_lib:format("Cannot translate VM value ~p\n of type ~p\n to Sophia type ~s", [Data, VmType, Type0Str]), {error, [aeso_errors:new(data_error, Msg)]} end; {error, _Err} -> - Msg = io_lib:format("Failed to decode binary as type ~p\n", [VmType]), + Msg = io_lib:format("Failed to decode binary as type ~p", [VmType]), {error, [aeso_errors:new(data_error, Msg)]} end; fate -> @@ -367,12 +367,12 @@ to_sophia_value(ContractString, FunName, ok, Data, Options0) -> {ok, aeso_vm_decode:from_fate(Type, aeb_fate_encoding:deserialize(Data))} catch throw:cannot_translate_to_sophia -> Type1 = prettypr:format(aeso_pretty:type(Type0)), - Msg = io_lib:format("Cannot translate FATE value ~p\n of Sophia type ~s\n", + Msg = io_lib:format("Cannot translate FATE value ~p\n of Sophia type ~s", [aeb_fate_encoding:deserialize(Data), Type1]), {error, [aeso_errors:new(data_error, Msg)]}; _:_ -> Type1 = prettypr:format(aeso_pretty:type(Type0)), - Msg = io_lib:format("Failed to decode binary as type ~s\n", [Type1]), + Msg = io_lib:format("Failed to decode binary as type ~s", [Type1]), {error, [aeso_errors:new(data_error, Msg)]} end end @@ -436,12 +436,12 @@ decode_calldata(ContractString, FunName, Calldata, Options0) -> {ok, ArgTypes, Values} catch throw:cannot_translate_to_sophia -> Type0Str = prettypr:format(aeso_pretty:type(Type0)), - Msg = io_lib:format("Cannot translate VM value ~p\n of type ~p\n to Sophia type ~s\n", + Msg = io_lib:format("Cannot translate VM value ~p\n of type ~p\n to Sophia type ~s", [VmValue, VmType, Type0Str]), {error, [aeso_errors:new(data_error, Msg)]} end; {error, _Err} -> - Msg = io_lib:format("Failed to decode calldata as type ~p\n", [VmType]), + Msg = io_lib:format("Failed to decode calldata as type ~p", [VmType]), {error, [aeso_errors:new(data_error, Msg)]} end; fate -> @@ -454,12 +454,12 @@ decode_calldata(ContractString, FunName, Calldata, Options0) -> {ok, ArgTypes, AstArgs} catch throw:cannot_translate_to_sophia -> Type0Str = prettypr:format(aeso_pretty:type(Type0)), - Msg = io_lib:format("Cannot translate FATE value ~p\n to Sophia type ~s\n", + Msg = io_lib:format("Cannot translate FATE value ~p\n to Sophia type ~s", [FateArgs, Type0Str]), {error, [aeso_errors:new(data_error, Msg)]} end; {error, _} -> - Msg = io_lib:format("Failed to decode calldata binary\n", []), + Msg = io_lib:format("Failed to decode calldata binary", []), {error, [aeso_errors:new(data_error, Msg)]} end end @@ -502,7 +502,7 @@ get_decode_type(FunName, [{Contract, Ann, _, Defs}]) when ?IS_CONTRACT_HEAD(Cont case FunName of "init" -> {ok, [], {tuple_t, [], []}}; _ -> - Msg = io_lib:format("Function '~s' is missing in contract\n", [FunName]), + Msg = io_lib:format("Function '~s' is missing in contract", [FunName]), Pos = aeso_code_errors:pos(Ann), aeso_errors:throw(aeso_errors:new(data_error, Pos, Msg)) end diff --git a/src/aeso_errors.erl b/src/aeso_errors.erl index 79d4a6b..3ea0937 100644 --- a/src/aeso_errors.erl +++ b/src/aeso_errors.erl @@ -66,10 +66,10 @@ throw(#err{} = Err) -> erlang:throw({error, [Err]}). msg(#err{ message = Msg, context = none }) -> Msg; -msg(#err{ message = Msg, context = Ctxt }) -> Msg ++ Ctxt. +msg(#err{ message = Msg, context = Ctxt }) -> Msg ++ "\n" ++ Ctxt. err_msg(#err{ pos = Pos } = Err) -> - lists:flatten(io_lib:format("~s~s", [str_pos(Pos), msg(Err)])). + lists:flatten(io_lib:format("~s~s\n", [str_pos(Pos), msg(Err)])). str_pos(#pos{file = no_file, line = L, col = C}) -> io_lib:format("~p:~p:", [L, C]); @@ -79,7 +79,7 @@ str_pos(#pos{file = F, line = L, col = C}) -> type(#err{ type = Type }) -> Type. pp(#err{ type = Kind, pos = Pos } = Err) -> - lists:flatten(io_lib:format("~s~s:\n~s", [pp_kind(Kind), pp_pos(Pos), msg(Err)])). + lists:flatten(io_lib:format("~s~s:\n~s\n", [pp_kind(Kind), pp_pos(Pos), msg(Err)])). pp_kind(type_error) -> "Type error"; pp_kind(parse_error) -> "Parse error"; diff --git a/test/aeso_abi_tests.erl b/test/aeso_abi_tests.erl index 9306657..30ec42c 100644 --- a/test/aeso_abi_tests.erl +++ b/test/aeso_abi_tests.erl @@ -91,9 +91,11 @@ encode_calldata_neg_test() -> Code = [ "contract Foo =\n" " entrypoint x(y : int) : string = \"hello\"\n" ], - ExpErr1 = "Type error at line 5, col 34:\nCannot unify int\n and bool\n" - "when checking the application at line 5, column 34 of\n" - " x : (int) => string\nto arguments\n true : bool\n", + ExpErr1 = "Type error at line 5, col 34:\nCannot unify `int` and `bool`\n" + "when checking the application of\n" + " `x : (int) => string`\n" + "to arguments\n" + " `true : bool`\n", {error, [Err1]} = aeso_compiler:create_calldata(Code, "x", ["true"]), ?assertEqual(ExpErr1, aeso_errors:pp(Err1)), {error, [Err2]} = aeso_compiler:create_calldata(Code, "x", ["true"], [{backend, fate}]), diff --git a/test/aeso_compiler_tests.erl b/test/aeso_compiler_tests.erl index 0b402e5..fe3a130 100644 --- a/test/aeso_compiler_tests.erl +++ b/test/aeso_compiler_tests.erl @@ -257,33 +257,33 @@ debug_mode_contracts() -> warnings() -> ?WARNING(warnings, [<>, + "The file `Triple.aes` is included but not used.">>, <>, + "The function `h` is defined but never used.">>, <>, + "The type `unused_type` is defined but never used.">>, <>, + "Negative spend.">>, <>, + "The definition of `x` shadows an older definition at line 26, column 9.">>, <>, + "Division by zero.">>, <>, + "The function `unused_stateful` is unnecessarily marked as stateful.">>, <>, + "The variable `unused_arg` is defined but never used.">>, <>, + "The variable `unused_var` is defined but never used.">>, <>, + "The function `unused_function` is defined but never used.">>, <>, + "The function `recursive_unused_function` is defined but never used.">>, <>, + "The function `called_unused_function1` is defined but never used.">>, <>, + "The function `called_unused_function2` is defined but never used.">>, <> + "Unused return value.">> ]). failing_contracts() -> @@ -301,365 +301,302 @@ failing_contracts() -> %% Type errors , ?TYPE_ERROR(name_clash, [<>, <>, <>, <>, <>, <>, <>]) , ?TYPE_ERROR(type_errors, [<>, + "Unbound variable `zz`">>, < list(int)\n" + "Cannot unify `int` and `list(int)`\n" + "when checking the application of\n" + " `(::) : (int, list(int)) => list(int)`\n" "to arguments\n" - " x : int\n" - " x : int">>, + " `x : int`\n" + " `x : int`">>, <>, + "Cannot unify `string` and `int`\n" + "when checking the assignment of the field `x : map(string, string)` " + "to the old value `__x` and the new value `__x {[\"foo\"] @ x = x + 1} : map(string, int)`">>, <>, + "Cannot unify `int` and `string`\n" + "when checking the type of the expression `1 : int` " + "against the expected type `string`">>, <>, + "Cannot unify `string` and `int`\n" + "when checking the type of the expression `\"bla\" : string` " + "against the expected type `int`">>, <>, + "Cannot unify `string` and `int`\n" + "when checking the type of the expression `\"x\" : string` " + "against the expected type `int`">>, <>, + "Cannot unify `string` and `int`\n" + "when checking the type of the expression `\"foo\" : string` " + "against the expected type `int`">>, <>, <>, + "Not a record type: `string`\n" + "arising from the projection of the field `y`">>, <>, + "Not a record type: `string`\n" + "arising from an assignment of the field `y`">>, <>, + "Not a record type: `string`\n" + "arising from an assignment of the field `y`">>, <>, + "Not a record type: `string`\n" + "arising from an assignment of the field `y`">>, <>, + "Ambiguous record type with field `y` could be one of\n" + " - `r` (at line 4, column 10)\n" + " - `r'` (at line 5, column 10)">>, <>, + "Repeated name `x` in the pattern `x :: x`">>, <>, + "Repeated names `x`, `y` in the pattern `(x : int, y, x : string, y : bool)`">>, <>, + "Cannot unify `int` and `string`\n" + "when checking the type of the expression `x : int` " + "against the expected type `string`">>, <>, + "Cannot unify `int` and `string`\n" + "when checking the type of the expression `x : int` " + "against the expected type `string`">>, <>, + "No record type with fields `y`, `z`">>, <>, + "The field `z` is missing when constructing an element of type `r2`">>, <>, + "Record type `r2` does not have field `y`">>, <>, + "Let binding must be followed by an expression.">>, <>, + "Let binding must be followed by an expression.">>, <>, + "Let binding must be followed by an expression.">>, <>, + "Let binding must be followed by an expression.">>, <>]) + "Cannot unify `int` and `bool`\n" + "when checking the type of the expression `id(n) : int` " + "against the expected type `bool`">>]) , ?TYPE_ERROR(init_type_error, [<>]) + "Cannot unify `string` and `map(int, int)`\n" + "when checking that `init` returns a value of type `state`">>]) , ?TYPE_ERROR(missing_state_type, [<>]) + "Cannot unify `string` and `unit`\n" + "when checking that `init` returns a value of type `state`">>]) , ?TYPE_ERROR(missing_fields_in_record_expression, [<>, + "The field `x` is missing when constructing an element of type `r('a)`">>, <>, + "The field `y` is missing when constructing an element of type `r(int)`">>, <>]) + "The fields `y`, `z` are missing when constructing an element of type `r('a)`">>]) , ?TYPE_ERROR(namespace_clash, [<>]) + "The contract `Call` has the same name as a namespace at (builtin location)">>]) , ?TYPE_ERROR(bad_events, [<>, + "The indexed type `string` is not a word type">>, <>]) + "The indexed type `alias_string` equals `string` which is not a word type">>]) , ?TYPE_ERROR(bad_events2, [<>, + "The event constructor `BadEvent1` has too many non-indexed values (max 1)">>, <>]) + "The event constructor `BadEvent2` has too many indexed values (max 3)">>]) , ?TYPE_ERROR(type_clash, [<>]) + "Cannot unify `int` and `string`\n" + "when checking the type of the expression `r.foo() : map(int, string)` " + "against the expected type `map(string, int)`">>]) , ?TYPE_ERROR(not_toplevel_include, [<>]) + "Include of `included.aes` is not allowed, include only allowed at top level.">>]) , ?TYPE_ERROR(not_toplevel_namespace, [<>]) + "Nested namespaces are not allowed. Namespace `Foo` is not defined at top level.">>]) , ?TYPE_ERROR(not_toplevel_contract, [<>]) + "Nested contracts are not allowed. Contract `Con` is not defined at top level.">>]) , ?TYPE_ERROR(bad_address_literals, [<>, + "Cannot unify `address` and `oracle(int, bool)`\n" + "when checking the type of the expression `ak_2gx9MEFxKvY9vMG5YnqnXWv1hCsX7rgnfvBLJS4aQurustR1rt : address` " + "against the expected type `oracle(int, bool)`">>, <>, + "Cannot unify `address` and `Remote`\n" + "when checking the type of the expression `ak_2gx9MEFxKvY9vMG5YnqnXWv1hCsX7rgnfvBLJS4aQurustR1rt : address` " + "against the expected type `Remote`">>, <>, + "Cannot unify `address` and `bytes(32)`\n" + "when checking the type of the expression `ak_2gx9MEFxKvY9vMG5YnqnXWv1hCsX7rgnfvBLJS4aQurustR1rt : address` " + "against the expected type `bytes(32)`">>, <>, + "Cannot unify `oracle('a, 'b)` and `oracle_query(int, bool)`\n" + "when checking the type of the expression " + "`ok_2YNyxd6TRJPNrTcEDCe9ra59SVUdp9FR9qWC5msKZWYD9bP9z5 : oracle('a, 'b)` " + "against the expected type `oracle_query(int, bool)`">>, <>, + "Cannot unify `oracle('c, 'd)` and `bytes(32)`\n" + "when checking the type of the expression " + "`ok_2YNyxd6TRJPNrTcEDCe9ra59SVUdp9FR9qWC5msKZWYD9bP9z5 : oracle('c, 'd)` " + "against the expected type `bytes(32)`">>, <>, + "Cannot unify `oracle('e, 'f)` and `Remote`\n" + "when checking the type of the expression " + "`ok_2YNyxd6TRJPNrTcEDCe9ra59SVUdp9FR9qWC5msKZWYD9bP9z5 : oracle('e, 'f)` " + "against the expected type `Remote`">>, <>, + "Cannot unify `oracle_query('g, 'h)` and `oracle(int, bool)`\n" + "when checking the type of the expression " + "`oq_2oRvyowJuJnEkxy58Ckkw77XfWJrmRgmGaLzhdqb67SKEL1gPY : oracle_query('g, 'h)` " + "against the expected type `oracle(int, bool)`">>, <>, + "Cannot unify `oracle_query('i, 'j)` and `bytes(32)`\n" + "when checking the type of the expression " + "`oq_2oRvyowJuJnEkxy58Ckkw77XfWJrmRgmGaLzhdqb67SKEL1gPY : oracle_query('i, 'j)` " + "against the expected type `bytes(32)`">>, <>, + "Cannot unify `oracle_query('k, 'l)` and `Remote`\n" + "when checking the type of the expression " + "`oq_2oRvyowJuJnEkxy58Ckkw77XfWJrmRgmGaLzhdqb67SKEL1gPY : oracle_query('k, 'l)` " + "against the expected type `Remote`">>, <>, + "The type `address` is not a contract type\n" + "when checking that the contract literal " + "`ct_Ez6MyeTMm17YnTnDdHTSrzMEBKmy7Uz2sXu347bTDPgVH2ifJ` " + "has the type `address`">>, <>, + "The type `oracle(int, bool)` is not a contract type\n" + "when checking that the contract literal " + "`ct_Ez6MyeTMm17YnTnDdHTSrzMEBKmy7Uz2sXu347bTDPgVH2ifJ` " + "has the type `oracle(int, bool)`">>, <>, + "The type `bytes(32)` is not a contract type\n" + "when checking that the contract literal " + "`ct_Ez6MyeTMm17YnTnDdHTSrzMEBKmy7Uz2sXu347bTDPgVH2ifJ` " + "has the type `bytes(32)`">>, <>]) + "The type `address` is not a contract type\n" + "when checking that the call to `Address.to_contract` " + "has the type `address`">>]) , ?TYPE_ERROR(stateful, [<>, + "Cannot reference stateful function `Chain.spend` in the definition of non-stateful function `fail1`.">>, <>, + "Cannot reference stateful function `local_spend` in the definition of non-stateful function `fail2`.">>, <>, + "Cannot reference stateful function `Chain.spend` in the definition of non-stateful function `fail3`.">>, <>, + "Cannot reference stateful function `Chain.spend` in the definition of non-stateful function `fail4`.">>, <>, + "Cannot reference stateful function `Chain.spend` in the definition of non-stateful function `fail5`.">>, <>, + "Cannot pass non-zero value argument `1000` in the definition of non-stateful function `fail6`.">>, <>, + "Cannot pass non-zero value argument `1000` in the definition of non-stateful function `fail7`.">>, <>]) + "Cannot pass non-zero value argument `1000` in the definition of non-stateful function `fail8`.">>]) , ?TYPE_ERROR(bad_init_state_access, [<>, + " - `set_state` (at line 11, column 5), which calls\n" + " - `roundabout` (at line 8, column 38), which calls\n" + " - `put` (at line 7, column 39)">>, <>, + " - `new_state` (at line 12, column 5), which calls\n" + " - `state` (at line 5, column 29)">>, <>]) + " - `state` (at line 13, column 13)">>]) , ?TYPE_ERROR(modifier_checks, [<>, + "The function `all_the_things` cannot be both public and private.">>, <>, + "Namespaces cannot contain entrypoints. Use `function` instead.">>, <>, + "The contract `Remote` has no entrypoints. Since Sophia version 3.2, " + "public contract functions must be declared with the `entrypoint` " + "keyword instead of `function`.">>, <>, + "The entrypoint `wha` cannot be private. Use `function` instead.">>, < unit">>, + "Use `entrypoint` for declaration of `foo`: `entrypoint foo : () => unit`">>, <>, + "Use `entrypoint` instead of `function` for public function `foo`: `entrypoint foo() = ()`">>, < unit">>]) + "Use `entrypoint` instead of `function` for public function `foo`: `entrypoint foo : () => unit`">>]) , ?TYPE_ERROR(list_comp_not_a_list, [<> + "Cannot unify `int` and `list('a)`\n" + "when checking rvalue of list comprehension binding `1 : int` against type `list('a)`">> ]) , ?TYPE_ERROR(list_comp_if_not_bool, [<> + "Cannot unify `int` and `bool`\n" + "when checking the type of the expression `3 : int` against the expected type `bool`">> ]) , ?TYPE_ERROR(list_comp_bad_shadow, [<> + "Cannot unify `int` and `string`\n" + "when checking the type of the pattern `x : int` against the expected type `string`">> ]) , ?TYPE_ERROR(map_as_map_key, [<>, <>, <>]) , ?TYPE_ERROR(calling_init_function, [<>]) , ?TYPE_ERROR(bad_top_level_decl, [<>]) , ?TYPE_ERROR(missing_event_type, [<>]) , ?TYPE_ERROR(bad_bytes_concat, [< "and result type\n" " - 'f (at line 13, column 14)">>, <>, + "Cannot unify `bytes(26)` and `bytes(25)`\n" + "when checking the type of the expression `Bytes.concat(x, y) : bytes(26)` " + "against the expected type `bytes(25)`">>, < " - 'a (at line 18, column 37)">>]) , ?TYPE_ERROR(wrong_compiler_version, [<>, <>]) , ?TYPE_ERROR(interface_with_defs, [<>]) + "Fix: replace the definition of `foo` by a type signature.">>]) , ?TYPE_ERROR(contract_as_namespace, [<>]) + "Invalid call to contract entrypoint `Foo.foo`.\n" + "It must be called as `c.foo` for some `c : Foo`.">>]) , ?TYPE_ERROR(toplevel_let, [<>]) + "Toplevel \"let\" definitions are not supported. " + "Value `this_is_illegal` could be replaced by 0-argument function.">>]) , ?TYPE_ERROR(empty_typedecl, [<>]) + "Empty type declarations are not supported. " + "Type `t` lacks a definition">>]) , ?TYPE_ERROR(higher_kinded_type, [<>]) , ?TYPE_ERROR(bad_arity, [<>, <>, + "Cannot unify `int` and `id`\n" + "when checking the type of the expression `123 : int` " + "against the expected type `id`">>, <>, <>]) + "Cannot unify `int` and `id(int, int)`\n" + "when checking the type of the expression `123 : int` " + "against the expected type `id(int, int)`">>]) , ?TYPE_ERROR(bad_unnamed_map_update_default, [<>]) , ?TYPE_ERROR(non_functional_entrypoint, [<>]) , ?TYPE_ERROR(bad_records, [<>, + "Mixed record fields and map keys in `{x = 0, [0] = 1}`">>, <>, + "Mixed record fields and map keys in `r {x = 0, [0] = 1}`">>, <> + "Empty record/map update `r {}`">> ]) , ?TYPE_ERROR(bad_protected_call, [<> + "Invalid `protected` argument `(0 : int) == (1 : int) : bool`. " + "It must be either `true` or `false`.">> ]) , ?TYPE_ERROR(bad_function_block, [< ]) , ?TYPE_ERROR(bad_number_of_args, [< unit\n" - " and (int) => 'a\n", - "when checking the application at line 3, column 39 of\n" - " f : () => unit\n" + "Cannot unify `() => unit` and `(int) => 'a`\n", + "when checking the application of\n" + " `f : () => unit`\n" "to arguments\n" - " 1 : int">>, + " `1 : int`">>, < 'e\n" - " and (int) => 'd\n" - "when checking the application at line 4, column 20 of\n" - " g : (int, string) => 'e\n" + "Cannot unify `(int, string) => 'e` and `(int) => 'd`\n" + "when checking the application of\n" + " `g : (int, string) => 'e`\n" "to arguments\n" - " 1 : int">>, + " `1 : int`">>, < 'c\n" - " and (string) => 'b\n" - "when checking the application at line 5, column 20 of\n" - " g : (int, string) => 'c\nto arguments\n" - " \"Litwo, ojczyzno moja\" : string">> + "Cannot unify `(int, string) => 'c` and `(string) => 'b`\n" + "when checking the application of\n" + " `g : (int, string) => 'c`\n" + "to arguments\n" + " `\"Litwo, ojczyzno moja\" : string`">> ]) , ?TYPE_ERROR(bad_state, [< [<>, < if(protected, option(void), void)\n and (gas : int, value : int, protected : bool, int, bool) => 'b\n" + "Cannot unify `(gas : int, value : int, protected : bool) => if(protected, option(void), void)` and `(gas : int, value : int, protected : bool, int, bool) => 'b`\n" "when checking contract construction of type\n (gas : int, value : int, protected : bool) =>\n if(protected, option(void), void) (at line 11, column 18)\nagainst the expected type\n (gas : int, value : int, protected : bool, int, bool) => 'b">>, <>, + "Cannot unify `int` and `bool`\n" + "when checking named argument `gas : int` against inferred type `bool`">>, <>, + "when resolving arguments of variadic function `Chain.create`">>, < if(protected, option(void), void)\n and (gas : int, value : int, protected : bool) => 'a\n" + "Cannot unify `(gas : int, value : int, protected : bool, int, bool) => if(protected, option(void), void)` and `(gas : int, value : int, protected : bool) => 'a`\n" "when checking contract construction of type\n (gas : int, value : int, protected : bool, int, bool) =>\n if(protected, option(void), void) (at line 18, column 18)\nagainst the expected type\n (gas : int, value : int, protected : bool) => 'a">>, <>, + "Named argument `protected` is not one of the expected named arguments\n - `value : int`">>, <> + "Cannot unify `int` and `bool`\n" + "when checking named argument `value : int` against inferred type `bool`">> ]) , ?TYPE_ERROR(ambiguous_main, [< "Only one main contract can be defined.">> ]) , ?TYPE_ERROR(using_namespace_ambiguous_name, - [ <> + [ <> , <> + "Unbound variable `A.f`">> ]) , ?TYPE_ERROR(using_namespace_wrong_scope, [ <> + "Unbound variable `f`">> , <> + "Unbound variable `f`">> ]) , ?TYPE_ERROR(using_namespace_undefined, [< ]) , ?TYPE_ERROR(using_namespace_hidden_parts, [<> + "Unbound variable `g`">> ]) , ?TYPE_ERROR(stateful_pattern_guard, [<> + "Cannot reference stateful function `g` in a pattern guard.">> ]) , ?TYPE_ERROR(non_boolean_pattern_guard, [<> + "Cannot unify `string` and `bool`\n" + "when checking the type of the expression `\"y\" : string` " + "against the expected type `bool`">> ]) , ?TYPE_ERROR(warnings, [<>, + "The file `Triple.aes` is included but not used.">>, <>, + "The function `h` is defined but never used.">>, <>, + "The type `unused_type` is defined but never used.">>, <>, + "Negative spend.">>, <>, + "The definition of `x` shadows an older definition at line 26, column 9.">>, <>, + "Division by zero.">>, <>, + "The function `unused_stateful` is unnecessarily marked as stateful.">>, <>, + "The variable `unused_arg` is defined but never used.">>, <>, + "The variable `unused_var` is defined but never used.">>, <>, + "The function `unused_function` is defined but never used.">>, <>, + "The function `recursive_unused_function` is defined but never used.">>, <>, + "The function `called_unused_function1` is defined but never used.">>, <>, + "The function `called_unused_function2` is defined but never used.">>, <> + "Unused return value.">> ]) ].