From d36642cbc1b1a85f35fb4ff88bac6c09b3dda0eb Mon Sep 17 00:00:00 2001 From: Gaith Hallak Date: Tue, 1 Nov 2022 11:55:48 +0300 Subject: [PATCH] Ban the unification of uvar and var_args function --- src/aeso_ast_infer_types.erl | 2 ++ src/aeso_pretty.erl | 14 +++++++++----- test/aeso_compiler_tests.erl | 13 +++++++++++++ test/contracts/var_args_unify_fun_call.aes | 7 +++++++ test/contracts/var_args_unify_let.aes | 4 ++++ 5 files changed, 35 insertions(+), 5 deletions(-) create mode 100644 test/contracts/var_args_unify_fun_call.aes create mode 100644 test/contracts/var_args_unify_let.aes diff --git a/src/aeso_ast_infer_types.erl b/src/aeso_ast_infer_types.erl index 2387779..9e9e615 100644 --- a/src/aeso_ast_infer_types.erl +++ b/src/aeso_ast_infer_types.erl @@ -2856,6 +2856,8 @@ unify0(Env, A, B, Variance, When) -> unify1(_Env, {uvar, _, R}, {uvar, _, R}, _Variance, _When) -> true; +unify1(_Env, {uvar, _, _}, {fun_t, _, _, var_args, _}, _Variance, When) -> + type_error({unify_varargs, When}); unify1(Env, {uvar, A, R}, T, _Variance, When) -> case occurs_check(R, T) of true -> diff --git a/src/aeso_pretty.erl b/src/aeso_pretty.erl index 32208c4..765534e 100644 --- a/src/aeso_pretty.erl +++ b/src/aeso_pretty.erl @@ -261,6 +261,8 @@ type(Type, Options) -> with_options(Options, fun() -> type(Type) end). -spec type(aeso_syntax:type()) -> doc(). +type(F = {fun_t, _, _, var_args, _}) -> + type(setelement(4, F, [var_args])); type({fun_t, _, Named, Args, Ret}) -> follow(hsep(args_type(Named ++ Args), text("=>")), type(Ret)); type({type_sig, _, Named, Args, Ret}) -> @@ -284,11 +286,13 @@ type({named_arg_t, _, Name, Type, _Default}) -> typed(name(Name), Type); type(R = {record_t, _}) -> typedef(R); -type(T = {id, _, _}) -> name(T); -type(T = {qid, _, _}) -> name(T); -type(T = {con, _, _}) -> name(T); -type(T = {qcon, _, _}) -> name(T); -type(T = {tvar, _, _}) -> name(T). +type(T = {id, _, _}) -> name(T); +type(T = {qid, _, _}) -> name(T); +type(T = {con, _, _}) -> name(T); +type(T = {qcon, _, _}) -> name(T); +type(T = {tvar, _, _}) -> name(T); + +type(var_args) -> text("var_args"). -spec args_type([aeso_syntax:type()]) -> doc(). args_type(Args) -> diff --git a/test/aeso_compiler_tests.erl b/test/aeso_compiler_tests.erl index 3652aad..4de0385 100644 --- a/test/aeso_compiler_tests.erl +++ b/test/aeso_compiler_tests.erl @@ -1139,6 +1139,19 @@ failing_contracts() -> " `oracle(string, (int) => int)`\n" "The response type must not be higher-order (contain function types)">> ]) + , ?TYPE_ERROR(var_args_unify_let, + [< 'b`">> + ]) + , ?TYPE_ERROR(var_args_unify_fun_call, + [< 'a) => 'a`\n" + "to arguments\n" + " `Chain.create : (value : int, var_args) => 'b`">> + ]) ]. validation_test_() -> diff --git a/test/contracts/var_args_unify_fun_call.aes b/test/contracts/var_args_unify_fun_call.aes new file mode 100644 index 0000000..28f0b8a --- /dev/null +++ b/test/contracts/var_args_unify_fun_call.aes @@ -0,0 +1,7 @@ +contract C = + stateful function g(h) = + h() + + stateful entrypoint f() = + g(Chain.create) + 123 diff --git a/test/contracts/var_args_unify_let.aes b/test/contracts/var_args_unify_let.aes new file mode 100644 index 0000000..18bfc0e --- /dev/null +++ b/test/contracts/var_args_unify_let.aes @@ -0,0 +1,4 @@ +main contract C = + stateful entrypoint f() = + let x = Chain.clone + 123