Allow typed ids to be used for constants

This commit is contained in:
Gaith Hallak 2022-12-19 14:05:17 +03:00
parent 51935f8388
commit d34760b990
4 changed files with 21 additions and 11 deletions

View File

@ -534,8 +534,11 @@ qname({qid, _, Xs}) -> Xs;
qname({con, _, X}) -> [X]; qname({con, _, X}) -> [X];
qname({qcon, _, Xs}) -> Xs. qname({qcon, _, Xs}) -> Xs.
-spec name(aeso_syntax:id() | aeso_syntax:con()) -> name(). -spec name(Named | {typed, _, Named, _}) -> name() when
name({_, _, X}) -> X. 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(). -spec qid(aeso_syntax:ann(), qname()) -> aeso_syntax:id() | aeso_syntax:qid().
qid(Ann, [X]) -> {id, Ann, X}; 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()]}. -spec check_constants(env(), [aeso_syntax:decl()]) -> {env(), [aeso_syntax:decl()]}.
check_constants(Env = #env{ what = What }, Consts) -> check_constants(Env = #env{ what = What }, Consts) ->
HasValidId = fun({letval, _, {id, _, _}, _}) -> true; HasValidId = fun({letval, _, {id, _, _}, _}) -> true;
(_) -> false ({letval, _, {typed, _, {id, _, _}, _}, _}) -> true;
(_) -> false
end, end,
{Valid, Invalid} = lists:partition(HasValidId, Consts), {Valid, Invalid} = lists:partition(HasValidId, Consts),
[ type_error({invalid_const_id, aeso_syntax:get_ann(Pat)}) || {letval, _, Pat, _} <- Invalid ], [ 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), when_warning(warn_unused_return_value, fun() -> potential_unused_return_value(NewE) end),
[NewE|infer_block(Env, Attrs, Rest, BlockType)]. [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}) -> infer_const(Env, {letval, Ann, Id = {id, AnnId, _}, Expr}) ->
create_constraints(), create_constraints(),
NewExpr = {typed, _, _, Type} = infer_expr(Env#env{ current_const = Id }, Expr), NewExpr = {typed, _, _, Type} = infer_expr(Env#env{ current_const = Id }, Expr),
@ -3926,7 +3933,7 @@ mk_error({mutually_recursive_constants, Consts}) ->
[{letval, Ann, _, _} | _] = Consts, [{letval, Ann, _, _} | _] = Consts,
mk_t_err(pos(Ann), Msg); mk_t_err(pos(Ann), Msg);
mk_error({invalid_const_id, Ann}) -> 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_t_err(pos(Ann), Msg);
mk_error({invalid_const_expr, ConstId}) -> mk_error({invalid_const_expr, ConstId}) ->
Msg = io_lib:format("Invalid expression in the definition of the constant `~s`", [name(ConstId)]), Msg = io_lib:format("Invalid expression in the definition of the constant `~s`", [name(ConstId)]),

View File

@ -1222,7 +1222,7 @@ failing_contracts() ->
]) ])
, ?TYPE_ERROR(toplevel_constants_in_interface, , ?TYPE_ERROR(toplevel_constants_in_interface,
[<<?Pos(2,10) [<<?Pos(2,10)
"The name of the compile-time constant cannot have pattern matching nor type">>, "The name of the compile-time constant cannot have pattern matching">>,
<<?Pos(3,5) <<?Pos(3,5)
"Cannot define toplevel constants inside a contract interface">>, "Cannot define toplevel constants inside a contract interface">>,
<<?Pos(4,5) <<?Pos(4,5)
@ -1252,11 +1252,12 @@ failing_contracts() ->
]) ])
, ?TYPE_ERROR(toplevel_constants_invalid_id, , ?TYPE_ERROR(toplevel_constants_invalid_id,
[<<?Pos(2,9) [<<?Pos(2,9)
"The name of the compile-time constant cannot have pattern matching nor type">>, "The name of the compile-time constant cannot have pattern matching">>,
<<?Pos(3,9) <<?Pos(3,9)
"The name of the compile-time constant cannot have pattern matching nor type">>, "The name of the compile-time constant cannot have pattern matching">>,
<<?Pos(4,9) <<?Pos(4,20)
"The name of the compile-time constant cannot have pattern matching nor type">> "Cannot unify `string` and `bool`\n"
"when checking the type of the expression `\"str\" : string` against the expected type `bool`">>
]) ])
]. ].

View File

@ -34,6 +34,7 @@ contract C =
let c22 = N.nsconst let c22 = N.nsconst
let c23 = c01 let c23 = c01
let c24 = c11.name let c24 = c11.name
let c25 : int = 1
entrypoint f01() = c01 entrypoint f01() = c01
entrypoint f02() = c02 entrypoint f02() = c02
@ -59,4 +60,5 @@ contract C =
entrypoint f22() = c22 entrypoint f22() = c22
entrypoint f23() = c23 entrypoint f23() = c23
entrypoint f24() = c24 entrypoint f24() = c24
entrypoint f25() = c25
entrypoint fqual() = C.c01 entrypoint fqual() = C.c01

View File

@ -1,4 +1,4 @@
contract C = contract C =
let x::_ = [1,2,3,4] let x::_ = [1,2,3,4]
let y::(p = z::_) = [1,2,3,4] let y::(p = z::_) = [1,2,3,4]
let t : int = 1 let q : bool = "str"