From 9e95e8efb68077e4479c2860839faecea2b4e240 Mon Sep 17 00:00:00 2001 From: Gaith Hallak Date: Fri, 18 Nov 2022 16:59:42 +0300 Subject: [PATCH 1/5] Ban calling contracts functions as functions namespaces --- src/aeso_ast_infer_types.erl | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/aeso_ast_infer_types.erl b/src/aeso_ast_infer_types.erl index 7b2a399..5113950 100644 --- a/src/aeso_ast_infer_types.erl +++ b/src/aeso_ast_infer_types.erl @@ -229,7 +229,7 @@ force_bind_fun(X, Type, Env = #env{ what = What }) -> NoCode = get_option(no_code, false), Entry = if X == "init", What == contract, not NoCode -> {reserved_init, Ann, Type}; - What == contract_interface -> {contract_fun, Ann, Type}; + What == contract orelse What == contract_interface -> {contract_fun, Ann, Type}; true -> {Ann, Type} end, on_current_scope(Env, fun(Scope = #scope{ funs = Funs }) -> @@ -426,6 +426,7 @@ lookup_env(Env, Kind, Ann, Name) -> lookup_env1(#env{ namespace = Current, used_namespaces = UsedNamespaces, scopes = Scopes }, Kind, Ann, QName) -> Qual = lists:droplast(QName), Name = lists:last(QName), + QNameIsEvent = lists:suffix(["Chain", "event"], QName), AllowPrivate = lists:prefix(Qual, Current), %% Get the scope case maps:get(Qual, Scopes, false) of @@ -441,6 +442,8 @@ lookup_env1(#env{ namespace = Current, used_namespaces = UsedNamespaces, scopes {reserved_init, Ann1, Type} -> type_error({cannot_call_init_function, Ann}), {QName, {Ann1, Type}}; %% Return the type to avoid an extra not-in-scope error + {contract_fun, Ann1, Type} when AllowPrivate orelse QNameIsEvent -> + {QName, {Ann1, Type}}; {contract_fun, Ann1, Type} -> type_error({contract_treated_as_namespace, Ann, QName}), {QName, {Ann1, Type}}; -- 2.30.2 From 3b7f08381738a4369479e70c2cbb266159fc1f98 Mon Sep 17 00:00:00 2001 From: Gaith Hallak Date: Fri, 18 Nov 2022 16:59:57 +0300 Subject: [PATCH 2/5] Ban using contracts as namespaces --- src/aeso_ast_infer_types.erl | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/aeso_ast_infer_types.erl b/src/aeso_ast_infer_types.erl index 5113950..539b2ac 100644 --- a/src/aeso_ast_infer_types.erl +++ b/src/aeso_ast_infer_types.erl @@ -1257,6 +1257,10 @@ check_usings(Env = #env{ used_namespaces = UsedNamespaces }, [{using, Ann, Con, create_type_errors(), type_error({using_undefined_namespace, Ann, qname(Con)}), destroy_and_report_type_errors(Env); + #scope{kind = contract} -> + create_type_errors(), + type_error({using_undefined_namespace, Ann, qname(Con)}), + destroy_and_report_type_errors(Env); Scope -> Nsp = case Parts of none -> -- 2.30.2 From 6499823e5fd18fa4e533e1ec52685ecced0127a8 Mon Sep 17 00:00:00 2001 From: Gaith Hallak Date: Fri, 18 Nov 2022 17:11:12 +0300 Subject: [PATCH 3/5] Add tests --- test/aeso_compiler_tests.erl | 7 +++++++ test/contracts/calling_child_contract_entrypoint.aes | 5 +++++ test/contracts/using_contract_as_namespace.aes | 7 +++++++ 3 files changed, 19 insertions(+) create mode 100644 test/contracts/calling_child_contract_entrypoint.aes create mode 100644 test/contracts/using_contract_as_namespace.aes diff --git a/test/aeso_compiler_tests.erl b/test/aeso_compiler_tests.erl index 81f2cef..1c724a5 100644 --- a/test/aeso_compiler_tests.erl +++ b/test/aeso_compiler_tests.erl @@ -1175,6 +1175,13 @@ failing_contracts() -> [<> ]) + , ?TYPE_ERROR(calling_child_contract_entrypoint, + [<>]) + , ?TYPE_ERROR(using_contract_as_namespace, + [<>]) ]. validation_test_() -> diff --git a/test/contracts/calling_child_contract_entrypoint.aes b/test/contracts/calling_child_contract_entrypoint.aes new file mode 100644 index 0000000..3e9f4c0 --- /dev/null +++ b/test/contracts/calling_child_contract_entrypoint.aes @@ -0,0 +1,5 @@ +contract F = + entrypoint g() = 1 + +main contract C = + entrypoint f() = F.g() diff --git a/test/contracts/using_contract_as_namespace.aes b/test/contracts/using_contract_as_namespace.aes new file mode 100644 index 0000000..61c1390 --- /dev/null +++ b/test/contracts/using_contract_as_namespace.aes @@ -0,0 +1,7 @@ +contract F = + entrypoint g() = 1 + +main contract C = + using F for [g] + + entrypoint f() = g() \ No newline at end of file -- 2.30.2 From f2c4ba42c0a342881e0e80f23f08bc28224788fe Mon Sep 17 00:00:00 2001 From: Gaith Hallak Date: Fri, 18 Nov 2022 17:13:32 +0300 Subject: [PATCH 4/5] Update CHANGELOG --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9f929b6..a926a1e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -17,6 +17,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Changed - Type definitions serialised to ACI as `typedefs` field instead of `type_defs` to increase compatibility. - Check contracts and entrypoints modifiers when implementing interfaces. +- Contracts can no longer be used as namespaces. ### Removed ### Fixed - Typechecker crashes if Chain.create or Chain.clone are used without arguments. -- 2.30.2 From 3838a47694c2db10663ff79b7f54d4667e3fb9e1 Mon Sep 17 00:00:00 2001 From: Gaith Hallak Date: Mon, 21 Nov 2022 13:15:12 +0300 Subject: [PATCH 5/5] Separate guards with a semicolon --- src/aeso_ast_infer_types.erl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/aeso_ast_infer_types.erl b/src/aeso_ast_infer_types.erl index 539b2ac..db8e4e3 100644 --- a/src/aeso_ast_infer_types.erl +++ b/src/aeso_ast_infer_types.erl @@ -229,7 +229,7 @@ force_bind_fun(X, Type, Env = #env{ what = What }) -> NoCode = get_option(no_code, false), Entry = if X == "init", What == contract, not NoCode -> {reserved_init, Ann, Type}; - What == contract orelse What == contract_interface -> {contract_fun, Ann, Type}; + What == contract; What == contract_interface -> {contract_fun, Ann, Type}; true -> {Ann, Type} end, on_current_scope(Env, fun(Scope = #scope{ funs = Funs }) -> -- 2.30.2