From d34760b9907cc6787398eeacf9f97d4f401fc06a Mon Sep 17 00:00:00 2001 From: Gaith Hallak Date: Mon, 19 Dec 2022 14:05:17 +0300 Subject: [PATCH] Allow typed ids to be used for constants --- src/aeso_ast_infer_types.erl | 17 ++++++++++++----- test/aeso_compiler_tests.erl | 11 ++++++----- test/contracts/toplevel_constants.aes | 2 ++ .../contracts/toplevel_constants_invalid_id.aes | 2 +- 4 files changed, 21 insertions(+), 11 deletions(-) diff --git a/src/aeso_ast_infer_types.erl b/src/aeso_ast_infer_types.erl index 0762109..ce19668 100644 --- a/src/aeso_ast_infer_types.erl +++ b/src/aeso_ast_infer_types.erl @@ -534,8 +534,11 @@ qname({qid, _, Xs}) -> Xs; qname({con, _, X}) -> [X]; qname({qcon, _, Xs}) -> Xs. --spec name(aeso_syntax:id() | aeso_syntax:con()) -> name(). -name({_, _, X}) -> X. +-spec name(Named | {typed, _, Named, _}) -> name() when + Named :: aeso_syntax:id() | aeso_syntax:con(). +name({typed, _, X, _}) -> name(X); +name({id, _, X}) -> X; +name({con, _, X}) -> X. -spec qid(aeso_syntax:ann(), qname()) -> aeso_syntax:id() | aeso_syntax:qid(). qid(Ann, [X]) -> {id, Ann, X}; @@ -1295,8 +1298,9 @@ opposite_variance(bivariant) -> bivariant. -spec check_constants(env(), [aeso_syntax:decl()]) -> {env(), [aeso_syntax:decl()]}. check_constants(Env = #env{ what = What }, Consts) -> - HasValidId = fun({letval, _, {id, _, _}, _}) -> true; - (_) -> false + HasValidId = fun({letval, _, {id, _, _}, _}) -> true; + ({letval, _, {typed, _, {id, _, _}, _}, _}) -> true; + (_) -> false end, {Valid, Invalid} = lists:partition(HasValidId, Consts), [ type_error({invalid_const_id, aeso_syntax:get_ann(Pat)}) || {letval, _, Pat, _} <- Invalid ], @@ -2317,6 +2321,9 @@ infer_block(Env, Attrs, [E|Rest], BlockType) -> when_warning(warn_unused_return_value, fun() -> potential_unused_return_value(NewE) end), [NewE|infer_block(Env, Attrs, Rest, BlockType)]. +infer_const(Env, {letval, Ann, TypedId = {typed, _, Id = {id, _, _}, Type}, Expr}) -> + NewExpr = check_expr(Env#env{ current_const = Id }, Expr, Type), + {letval, Ann, TypedId, NewExpr}; infer_const(Env, {letval, Ann, Id = {id, AnnId, _}, Expr}) -> create_constraints(), NewExpr = {typed, _, _, Type} = infer_expr(Env#env{ current_const = Id }, Expr), @@ -3926,7 +3933,7 @@ mk_error({mutually_recursive_constants, Consts}) -> [{letval, Ann, _, _} | _] = Consts, mk_t_err(pos(Ann), Msg); mk_error({invalid_const_id, Ann}) -> - Msg = "The name of the compile-time constant cannot have pattern matching nor type", + Msg = "The name of the compile-time constant cannot have pattern matching", mk_t_err(pos(Ann), Msg); mk_error({invalid_const_expr, ConstId}) -> Msg = io_lib:format("Invalid expression in the definition of the constant `~s`", [name(ConstId)]), diff --git a/test/aeso_compiler_tests.erl b/test/aeso_compiler_tests.erl index 74bc2e8..d2953cd 100644 --- a/test/aeso_compiler_tests.erl +++ b/test/aeso_compiler_tests.erl @@ -1222,7 +1222,7 @@ failing_contracts() -> ]) , ?TYPE_ERROR(toplevel_constants_in_interface, [<>, + "The name of the compile-time constant cannot have pattern matching">>, <>, < ]) , ?TYPE_ERROR(toplevel_constants_invalid_id, [<>, + "The name of the compile-time constant cannot have pattern matching">>, <>, - <> + "The name of the compile-time constant cannot have pattern matching">>, + <> ]) ]. diff --git a/test/contracts/toplevel_constants.aes b/test/contracts/toplevel_constants.aes index 4e82342..86ac9be 100644 --- a/test/contracts/toplevel_constants.aes +++ b/test/contracts/toplevel_constants.aes @@ -34,6 +34,7 @@ contract C = let c22 = N.nsconst let c23 = c01 let c24 = c11.name + let c25 : int = 1 entrypoint f01() = c01 entrypoint f02() = c02 @@ -59,4 +60,5 @@ contract C = entrypoint f22() = c22 entrypoint f23() = c23 entrypoint f24() = c24 + entrypoint f25() = c25 entrypoint fqual() = C.c01 diff --git a/test/contracts/toplevel_constants_invalid_id.aes b/test/contracts/toplevel_constants_invalid_id.aes index 3799fbb..719a932 100644 --- a/test/contracts/toplevel_constants_invalid_id.aes +++ b/test/contracts/toplevel_constants_invalid_id.aes @@ -1,4 +1,4 @@ contract C = let x::_ = [1,2,3,4] let y::(p = z::_) = [1,2,3,4] - let t : int = 1 + let q : bool = "str"