Polymorphism support (#357)

* Add polymorphism to syntax tree and parser

* Add polymorphism to infer types

* Fix pretty printing

* Add new tests and fix old tests

* Fix the comparison between unit and empty tuple

* Report undefined interface errors before checking implemented interfaces

* Add test for implementing multiple interfaces

* Add test for implementing two interfaces with entrypoints of same names and different types

* Add tests for interfaces implementing interfaces

* Draft: Add variance switching

* Revert "Draft: Add variance switching"

This reverts commit 92dc6ac169cfbff447ed59de04994f564876b3fb.

* Add variance switching

* Fix broken tests

* Fix broken abi tests

* Add tests for variance switching

* Fix tests after rebase

* Variance switching for custom datatypes

* Fix dialyzer warning

* Add testing for custom types variance switching

* Make opposite_variance a separate function

* Make is_subtype/4 a separate function

* Fix warning

* Mark tvars as invariant

* Add type_vars_uvar ets table to ets_tables()

* Don't destroy and recreate type errors table when not needed

* Fixes from the reviews

* Use is_list to check if a var is a list

* Compare named args in fun_t

* Test only for covariance and contravariance

* Remove arrows_in_type and use infer_type_vars_variance instead

* Add tests for option and type aliases

* Fix previous commit

* Rename check_implemented_interfaces_recursive to check_implemented_interfaces1

* Make interfaces declare functions from extended interfaces

* Restore test.aes

* Add test for variance switching in records

* Enable variance switching for record types

* Handle builtin types type variables separately

* Add tests for oracles and oracle queries

* Replace compare_types with non-throwing version of unify

* Add the context to unification error

* Test variance switching for bivariant records

* Give clear names to the records in records variance switching test

* Handle comments about polymorphism_variance_switching.aes

* Rename datatypes in custom types variance switching test for readability

* Change the variance of the oracle_query type vars

* Add test for accessing maps with the wrong type

* Default to invariant when the variance of the type vars is unknown

* Rename test files to have common prefix

* Rename functions in variance switching tests for readability

* Fix variance inference

* Eliminate redundant tests

* Test all cases for bivariant
This commit is contained in:
Gaith Hallak
2022-06-17 13:09:07 +04:00
committed by GitHub
parent b599d581ee
commit e46226a693
28 changed files with 891 additions and 81 deletions
+1 -1
View File
@@ -39,7 +39,7 @@ calldata_aci_test_() ->
end} || {ContractName, Fun, Args} <- compilable_contracts()].
parse_args(Fun, Args) ->
[{contract_main, _, _, [{letfun, _, _, _, _, [{guarded, _, [], {app, _, _, AST}}]}]}] =
[{contract_main, _, _, _, [{letfun, _, _, _, _, [{guarded, _, [], {app, _, _, AST}}]}]}] =
aeso_parser:string("main contract Temp = function foo() = " ++ Fun ++ "(" ++ string:join(Args, ", ") ++ ")"),
strip_ann(AST).
+189 -1
View File
@@ -202,6 +202,12 @@ compilable_contracts() ->
"assign_patterns",
"patterns_guards",
"pipe_operator",
"polymorphism_contract_implements_interface",
"polymorphism_contract_multi_interface",
"polymorphism_contract_interface_extends_interface",
"polymorphism_contract_interface_extensions",
"polymorphism_contract_interface_same_decl_multi_interface",
"polymorphism_contract_interface_same_name_same_type",
"test" % Custom general-purpose test file. Keep it last on the list.
].
@@ -564,7 +570,7 @@ failing_contracts() ->
])
, ?TYPE_ERROR(list_comp_bad_shadow,
[<<?Pos(2, 53)
"Cannot unify `int` and `string`\n"
"Cannot unify `string` and `int`\n"
"when checking the type of the pattern `x : int` against the expected type `string`">>
])
, ?TYPE_ERROR(map_as_map_key,
@@ -837,6 +843,188 @@ failing_contracts() ->
<<?Pos(60, 5)
"The function `dec` is defined but never used.">>
])
, ?TYPE_ERROR(polymorphism_contract_interface_recursive,
[<<?Pos(1,24)
"Trying to implement or extend an undefined interface `Z`">>
])
, ?TYPE_ERROR(polymorphism_contract_interface_same_name_different_type,
[<<?Pos(4,20)
"Unimplemented function `f` from the interface `I1` in the contract `I2`">>])
, ?TYPE_ERROR(polymorphism_contract_missing_implementation,
[<<?Pos(4,20)
"Unimplemented function `f` from the interface `I1` in the contract `I2`">>
])
, ?TYPE_ERROR(polymorphism_contract_same_decl_multi_interface,
[<<?Pos(7,10)
"Unimplemented function `f` from the interface `J` in the contract `C`">>
])
, ?TYPE_ERROR(polymorphism_contract_undefined_interface,
[<<?Pos(1,14)
"Trying to implement or extend an undefined interface `I`">>
])
, ?TYPE_ERROR(polymorphism_contract_same_name_different_type_multi_interface,
[<<?Pos(9,5)
"Duplicate definitions of `f` at\n"
" - line 8, column 5\n"
" - line 9, column 5">>
])
, ?TYPE_ERROR(polymorphism_contract_interface_undefined_interface,
[<<?Pos(1,24)
"Trying to implement or extend an undefined interface `H`">>
])
, ?TYPE_ERROR(polymorphism_variance_switching,
[<<?Pos(36,49)
"Cannot unify `Cat` and `Animal` in a contravariant context\n"
"when checking the application of\n"
" `g2 : (Cat) => Cat`\n"
"to arguments\n"
" `x : Animal`">>,
<<?Pos(39,43)
"Cannot unify `Animal` and `Cat` in a covariant context\n"
"when checking the type of the expression `g3(x) : Animal` against the expected type `Cat`">>,
<<?Pos(48,55)
"Cannot unify `Animal` and `Cat` in a covariant context\n"
"when checking the application of\n"
" `g5 : ((Animal) => Animal) => Cat`\n"
"to arguments\n"
" `x : (Cat) => Cat`">>,
<<?Pos(52,44)
"Cannot unify `Animal` and `Cat` in a covariant context\n"
"when checking the type of the expression `f6() : option(Animal)` against the expected type `option(Cat)`">>,
<<?Pos(73,43)
"Cannot unify `Animal` and `Cat` in a covariant context\n"
"when checking the type of the expression `some_animal : Animal` against the expected type `Cat`">>
])
, ?TYPE_ERROR(polymorphism_variance_switching_custom_types,
[<<?Pos(56,39)
"Cannot unify `Cat` and `Animal` in a contravariant context\n"
"when checking the type of the expression `DT_CONTRA(f_c_to_u) : dt_contra(Cat)` against the expected type `dt_contra(Animal)`">>,
<<?Pos(62,35)
"Cannot unify `Animal` and `Cat` in a covariant context\n"
"when checking the type of the expression `DT_CO(f_u_to_a) : dt_co(Animal)` against the expected type `dt_co(Cat)`">>,
<<?Pos(67,36)
"Cannot unify `Cat` and `Animal` in a contravariant context\n"
"when checking the application of\n `DT_INV : ((Cat) => Cat) => dt_inv(Cat)`\nto arguments\n `f_c_to_a : (Cat) => Animal`">>,
<<?Pos(68,36)
"Cannot unify `Cat` and `Animal` in a invariant context\n"
"when checking the type of the expression `DT_INV(f_c_to_c) : dt_inv(Cat)` against the expected type `dt_inv(Animal)`">>,
<<?Pos(69,36)
"Cannot unify `Animal` and `Cat` in a invariant context\n"
"when checking the type of the expression `DT_INV(f_a_to_a) : dt_inv(Animal)` against the expected type `dt_inv(Cat)`">>,
<<?Pos(70,36)
"Cannot unify `Animal` and `Cat` in a invariant context\n"
"when checking the type of the expression `DT_INV(f_a_to_c) : dt_inv(Animal)` against the expected type `dt_inv(Cat)`">>,
<<?Pos(71,36)
"Cannot unify `Cat` and `Animal` in a contravariant context\n"
"when checking the application of\n `DT_INV : ((Cat) => Cat) => dt_inv(Cat)`\nto arguments\n `f_c_to_a : (Cat) => Animal`">>,
<<?Pos(80,40)
"Cannot unify `Cat` and `Animal` in a invariant context\n"
"when checking the type of the expression `DT_INV_SEP_A(f_c_to_u) : dt_inv_sep(Cat)` against the expected type `dt_inv_sep(Animal)`">>,
<<?Pos(82,40)
"Cannot unify `Cat` and `Animal` in a invariant context\n"
"when checking the type of the expression `DT_INV_SEP_B(f_u_to_c) : dt_inv_sep(Cat)` against the expected type `dt_inv_sep(Animal)`">>,
<<?Pos(83,40)
"Cannot unify `Animal` and `Cat` in a invariant context\n"
"when checking the type of the expression `DT_INV_SEP_A(f_a_to_u) : dt_inv_sep(Animal)` against the expected type `dt_inv_sep(Cat)`">>,
<<?Pos(85,40)
"Cannot unify `Animal` and `Cat` in a invariant context\n"
"when checking the type of the expression `DT_INV_SEP_B(f_u_to_a) : dt_inv_sep(Animal)` against the expected type `dt_inv_sep(Cat)`">>,
<<?Pos(90,42)
"Cannot unify `Animal` and `Cat` in a covariant context\n"
"when checking the type of the expression `DT_CO_NEST_A(f_dt_contra_a_to_u) : dt_co_nest_a(Animal)` against the expected type `dt_co_nest_a(Cat)`">>,
<<?Pos(94,46)
"Cannot unify `Cat` and `Animal` in a contravariant context\n"
"when checking the type of the expression `DT_CONTRA_NEST_A(f_dt_co_c_to_u) : dt_contra_nest_a(Cat)` against the expected type `dt_contra_nest_a(Animal)`">>,
<<?Pos(99,46)
"Cannot unify `Cat` and `Animal` in a contravariant context\n"
"when checking the type of the expression `DT_CONTRA_NEST_B(f_u_to_dt_contra_c) : dt_contra_nest_b(Cat)` against the expected type `dt_contra_nest_b(Animal)`">>,
<<?Pos(105,42)
"Cannot unify `Animal` and `Cat` in a covariant context\n"
"when checking the type of the expression `DT_CO_NEST_B(f_u_to_dt_co_a) : dt_co_nest_b(Animal)` against the expected type `dt_co_nest_b(Cat)`">>,
<<?Pos(110,13)
"Cannot unify `Animal` and `Cat` in a covariant context\n"
"when checking the type of the pattern `vj3 : dt_co_twice(Cat)` against the expected type `dt_co_twice(Animal)`">>,
<<?Pos(114,59)
"Cannot unify `Cat` and `Animal` in a contravariant context\n"
"when checking the type of the expression `DT_A_CONTRA_B_CONTRA(f_a_to_c_to_u) : dt_a_contra_b_contra(Animal, Cat)` against the expected type `dt_a_contra_b_contra(Animal, Animal)`">>,
<<?Pos(115,59)
"Cannot unify `Cat` and `Animal` in a contravariant context\n"
"when checking the type of the expression `DT_A_CONTRA_B_CONTRA(f_c_to_a_to_u) : dt_a_contra_b_contra(Cat, Animal)` against the expected type `dt_a_contra_b_contra(Animal, Animal)`">>,
<<?Pos(116,59)
"Cannot unify `Cat` and `Animal` in a contravariant context\n"
"when checking the type of the expression `DT_A_CONTRA_B_CONTRA(f_c_to_c_to_u) : dt_a_contra_b_contra(Cat, Cat)` against the expected type `dt_a_contra_b_contra(Animal, Animal)`">>,
<<?Pos(119,59)
"Cannot unify `Cat` and `Animal` in a contravariant context\n"
"when checking the type of the expression `DT_A_CONTRA_B_CONTRA(f_c_to_a_to_u) : dt_a_contra_b_contra(Cat, Animal)` against the expected type `dt_a_contra_b_contra(Animal, Cat)`">>,
<<?Pos(120,59)
"Cannot unify `Cat` and `Animal` in a contravariant context\n"
"when checking the type of the expression `DT_A_CONTRA_B_CONTRA(f_c_to_c_to_u) : dt_a_contra_b_contra(Cat, Cat)` against the expected type `dt_a_contra_b_contra(Animal, Cat)`">>,
<<?Pos(122,59)
"Cannot unify `Cat` and `Animal` in a contravariant context\n"
"when checking the type of the expression `DT_A_CONTRA_B_CONTRA(f_a_to_c_to_u) : dt_a_contra_b_contra(Animal, Cat)` against the expected type `dt_a_contra_b_contra(Cat, Animal)`">>,
<<?Pos(124,59)
"Cannot unify `Cat` and `Animal` in a contravariant context\n"
"when checking the type of the expression `DT_A_CONTRA_B_CONTRA(f_c_to_c_to_u) : dt_a_contra_b_contra(Cat, Cat)` against the expected type `dt_a_contra_b_contra(Cat, Animal)`">>,
<<?Pos(131,13)
"Cannot unify `Cat` and `Animal` in a contravariant context\n"
"when checking the type of the pattern `vl2 : dt_contra_twice(Animal)` against the expected type `dt_contra_twice(Cat)`">>
])
, ?TYPE_ERROR(polymorphism_variance_switching_records,
[<<?Pos(27,13)
"Cannot unify `Animal` and `Cat` in a covariant context\n"
"when checking the type of the pattern `r03 : rec_co(Cat)` against the expected type `Main.rec_co(Animal)`">>,
<<?Pos(33,13)
"Cannot unify `Cat` and `Animal` in a contravariant context\n"
"when checking the type of the pattern `r06 : rec_contra(Animal)` against the expected type `Main.rec_contra(Cat)`">>,
<<?Pos(40,13)
"Cannot unify `Cat` and `Animal` in a invariant context\n"
"when checking the type of the pattern `r10 : rec_inv(Animal)` against the expected type `Main.rec_inv(Cat)`">>,
<<?Pos(41,13)
"Cannot unify `Animal` and `Cat` in a invariant context\n"
"when checking the type of the pattern `r11 : rec_inv(Cat)` against the expected type `Main.rec_inv(Animal)`">>])
, ?TYPE_ERROR(polymorphism_variance_switching_oracles,
[<<?Pos(15,13)
"Cannot unify `Cat` and `Animal` in a contravariant context\n"
"when checking the type of the pattern `o03 : oracle(Animal, Animal)` against the expected type `oracle(Cat, Animal)`">>,
<<?Pos(16,13)
"Cannot unify `Cat` and `Animal` in a contravariant context\n"
"when checking the type of the pattern `o04 : oracle(Animal, Animal)` against the expected type `oracle(Cat, Cat)`">>,
<<?Pos(17,13)
"Cannot unify `Animal` and `Cat` in a covariant context\n"
"when checking the type of the pattern `o05 : oracle(Animal, Cat)` against the expected type `oracle(Animal, Animal)`">>,
<<?Pos(19,13)
"Cannot unify `Cat` and `Animal` in a contravariant context\n"
"when checking the type of the pattern `o07 : oracle(Animal, Cat)` against the expected type `oracle(Cat, Animal)`">>,
<<?Pos(20,13)
"Cannot unify `Cat` and `Animal` in a contravariant context\n"
"when checking the type of the pattern `o08 : oracle(Animal, Cat)` against the expected type `oracle(Cat, Cat)`">>,
<<?Pos(25,13)
"Cannot unify `Animal` and `Cat` in a covariant context\n"
"when checking the type of the pattern `o13 : oracle(Cat, Cat)` against the expected type `oracle(Animal, Animal)`">>,
<<?Pos(27,13)
"Cannot unify `Animal` and `Cat` in a covariant context\n"
"when checking the type of the pattern `o15 : oracle(Cat, Cat)` against the expected type `oracle(Cat, Animal)`">>,
<<?Pos(34,13)
"Cannot unify `Animal` and `Cat` in a covariant context\n"
"when checking the type of the pattern `q05 : oracle_query(Animal, Cat)` against the expected type `oracle_query(Animal, Animal)`">>,
<<?Pos(36,13)
"Cannot unify `Animal` and `Cat` in a covariant context\n"
"when checking the type of the pattern `q07 : oracle_query(Animal, Cat)` against the expected type `oracle_query(Cat, Animal)`">>,
<<?Pos(38,13)
"Cannot unify `Animal` and `Cat` in a covariant context\n"
"when checking the type of the pattern `q09 : oracle_query(Cat, Animal)` against the expected type `oracle_query(Animal, Animal)`">>,
<<?Pos(39,13)
"Cannot unify `Animal` and `Cat` in a covariant context\n"
"when checking the type of the pattern `q10 : oracle_query(Cat, Animal)` against the expected type `oracle_query(Animal, Cat)`">>,
<<?Pos(42,13)
"Cannot unify `Animal` and `Cat` in a covariant context\n"
"when checking the type of the pattern `q13 : oracle_query(Cat, Cat)` against the expected type `oracle_query(Animal, Animal)`">>,
<<?Pos(43,13)
"Cannot unify `Animal` and `Cat` in a covariant context\n"
"when checking the type of the pattern `q14 : oracle_query(Cat, Cat)` against the expected type `oracle_query(Animal, Cat)`">>,
<<?Pos(44,13)
"Cannot unify `Animal` and `Cat` in a covariant context\n"
"when checking the type of the pattern `q15 : oracle_query(Cat, Cat)` against the expected type `oracle_query(Cat, Animal)`">>])
].
-define(Path(File), "code_errors/" ??File).
+1 -1
View File
@@ -15,7 +15,7 @@ simple_contracts_test_() ->
Text = "main contract Identity =\n"
" function id(x) = x\n",
?assertMatch(
[{contract_main, _, {con, _, "Identity"},
[{contract_main, _, {con, _, "Identity"}, _,
[{letfun, _, {id, _, "id"}, [{id, _, "x"}], {id, _, "_"},
[{guarded, _, [], {id, _, "x"}}]}]}], parse_string(Text)),
ok
@@ -0,0 +1,5 @@
contract interface Strokable =
entrypoint stroke : () => string
contract Cat : Strokable =
entrypoint stroke() = "Cat stroke"
@@ -0,0 +1,10 @@
contract interface II =
entrypoint f : () => unit
contract interface I : II =
entrypoint f : () => unit
entrypoint g : () => unit
contract C : I =
entrypoint f() = ()
entrypoint g() = ()
@@ -0,0 +1,9 @@
contract interface I0 =
entrypoint f : () => int
contract interface I1 : I0 =
entrypoint f : () => int
entrypoint something_else : () => int
main contract C =
entrypoint f(x : I1) = x.f() // Here we should know that x has f
@@ -0,0 +1,13 @@
contract interface X : Z =
entrypoint x : () => int
contract interface Y : X =
entrypoint y : () => int
contract interface Z : Y =
entrypoint z : () => int
contract C : Z =
entrypoint x() = 1
entrypoint y() = 1
entrypoint z() = 1
@@ -0,0 +1,8 @@
contract interface I =
entrypoint f : () => int
contract interface II : I =
entrypoint f : () => int
contract C : II =
entrypoint f() = 1
@@ -0,0 +1,9 @@
contract interface I1 =
entrypoint f : () => int
contract interface I2 : I1 =
entrypoint f : () => char
contract C : I2 =
entrypoint f() = 1
entrypoint f() = 'c'
@@ -0,0 +1,8 @@
contract interface I1 =
entrypoint f : () => int
contract interface I2 : I1 =
entrypoint f : () => int
contract C : I2 =
entrypoint f() = 1
@@ -0,0 +1,5 @@
contract interface I : H =
entrypoint f : () => unit
contract C =
entrypoint g() = ()
@@ -0,0 +1,8 @@
contract interface I1 =
entrypoint f : () => int
contract interface I2 : I1 =
entrypoint g : () => int
contract C : I2 =
entrypoint g() = 1
@@ -0,0 +1,9 @@
contract interface I =
entrypoint f : () => int
contract interface J =
entrypoint g : () => char
contract C : I, J =
entrypoint f() = 1
entrypoint g() = 'c'
@@ -0,0 +1,8 @@
contract interface I =
entrypoint f : () => int
contract interface J =
entrypoint f : () => int
contract C : I, J =
entrypoint f() = 1
@@ -0,0 +1,9 @@
contract interface I =
entrypoint f : () => int
contract interface J =
entrypoint f : () => char
contract C : I, J =
entrypoint f() = 1
entrypoint f() = 'c'
@@ -0,0 +1,2 @@
contract C : I =
entrypoint f() = ()
@@ -0,0 +1,75 @@
contract interface Creature =
entrypoint is_alive : () => bool
contract interface Animal : Creature =
entrypoint is_alive : () => bool
entrypoint sound : () => string
contract Cat : Animal =
entrypoint sound() = "meow"
entrypoint is_alive() = true
main contract Main =
entrypoint init() = ()
stateful function g0(_ : Creature) : Cat = Chain.create()
stateful function f0(x : Cat) : Creature = g0(x)
stateful function h0() =
let a : Animal = (Chain.create() : Cat)
let c : Creature = (Chain.create() : Cat)
let c1 : Creature = a
()
stateful function g1(x : Animal) : Cat = Chain.create()
stateful function f1(x : Cat) : Animal = g1(x)
stateful function g11(x : list(Animal)) : list(Cat) = [Chain.create()]
stateful function f11(x : list(Cat)) : list(Animal) = g11(x)
stateful function g12(x : Animal * Animal) : Cat * Cat = (Chain.create(), Chain.create())
stateful function f12(x : Cat * Cat) : Animal * Animal = g12(x)
stateful function g13() : map(Cat, Cat) = { [Chain.create()] = Chain.create() }
stateful function f13() : map(Animal, Animal) = g13()
stateful function g2(x : Cat) : Cat = Chain.create()
stateful function f2(x : Animal) : Animal = g2(x) // fail
stateful function g3(x : Cat) : Animal = f1(x)
stateful function f3(x : Cat) : Cat = g3(x) // fail
stateful function g4(x : (Cat => Animal)) : Cat = Chain.create()
stateful function f4(x : (Animal => Cat)) : Animal = g4(x)
stateful function g44(x : list(list(Cat) => list(Animal))) : Cat = Chain.create()
stateful function f44(x : list(list(Animal) => list(Cat))) : Animal = g44(x)
stateful function g5(x : (Animal => Animal)) : Cat = Chain.create()
stateful function f5(x : (Cat => Cat)) : Animal = g5(x) // fail
stateful function g6() : option(Cat) = Some(Chain.create())
stateful function f6() : option(Animal) = g6()
stateful function h6() : option(Cat) = f6() // fail
type cat_type = Cat
type animal_type = Animal
type cat_cat_map = map(cat_type, cat_type)
type animal_animal_map = map(animal_type, animal_type)
stateful function g71(x : animal_type) : cat_type = Chain.create()
stateful function f71(x : cat_type) : animal_type = g1(x)
stateful function g72() : cat_cat_map = { [Chain.create()] = Chain.create() }
stateful function f72() : animal_animal_map = g13()
stateful function g73() =
let some_cat : Cat = Chain.create()
let some_animal : Animal = some_cat
let some_cat_cat_map : map(Cat, Cat) = g13()
let some_animal_animal_map : map(Animal, Animal) = some_cat_cat_map
let x : Animal = some_animal_animal_map[some_cat] // success
let y : Cat = some_cat_cat_map[some_animal] // fail
()
@@ -0,0 +1,135 @@
contract interface Animal =
entrypoint sound : () => string
contract Cat : Animal =
entrypoint sound() = "meow"
main contract Main =
datatype dt_contra('a) = DT_CONTRA('a => unit)
datatype dt_co('a) = DT_CO(unit => 'a)
datatype dt_inv('a) = DT_INV('a => 'a)
datatype dt_biv('a) = DT_BIV(unit => unit)
datatype dt_inv_sep('a) = DT_INV_SEP_A('a => unit) | DT_INV_SEP_B(unit => 'a)
datatype dt_co_nest_a('a) = DT_CO_NEST_A(dt_contra('a) => unit)
datatype dt_contra_nest_a('a) = DT_CONTRA_NEST_A(dt_co('a) => unit)
datatype dt_contra_nest_b('a) = DT_CONTRA_NEST_B(unit => dt_contra('a))
datatype dt_co_nest_b('a) = DT_CO_NEST_B(unit => dt_co('a))
datatype dt_co_twice('a) = DT_CO_TWICE(('a => unit) => 'a)
datatype dt_contra_twice('a) = DT_CONTRA_TWICE('a => 'a => unit)
datatype dt_a_contra_b_contra('a, 'b) = DT_A_CONTRA_B_CONTRA('a => 'b => unit)
function f_a_to_a_to_u(_ : Animal) : (Animal => unit) = f_a_to_u
function f_a_to_c_to_u(_ : Animal) : (Cat => unit) = f_c_to_u
function f_c_to_a_to_u(_ : Cat) : (Animal => unit) = f_a_to_u
function f_c_to_c_to_u(_ : Cat) : (Cat => unit) = f_c_to_u
function f_u_to_u(_ : unit) : unit = ()
function f_a_to_u(_ : Animal) : unit = ()
function f_c_to_u(_ : Cat) : unit = ()
function f_dt_contra_a_to_u(_ : dt_contra(Animal)) : unit = ()
function f_dt_contra_c_to_u(_ : dt_contra(Cat)) : unit = ()
function f_dt_co_a_to_u(_ : dt_co(Animal)) : unit = ()
function f_dt_co_c_to_u(_ : dt_co(Cat)) : unit = ()
function f_u_to_dt_contra_a(_ : unit) : dt_contra(Animal) = DT_CONTRA(f_a_to_u)
function f_u_to_dt_contra_c(_ : unit) : dt_contra(Cat) = DT_CONTRA(f_c_to_u)
stateful function f_c() : Cat = Chain.create()
stateful function f_a() : Animal = f_c()
stateful function f_u_to_a(_ : unit) : Animal = f_a()
stateful function f_u_to_c(_ : unit) : Cat = f_c()
stateful function f_a_to_a(_ : Animal) : Animal = f_a()
stateful function f_a_to_c(_ : Animal) : Cat = f_c()
stateful function f_c_to_a(_ : Cat) : Animal = f_a()
stateful function f_c_to_c(_ : Cat) : Cat = f_c()
stateful function f_a_to_u_to_c(_ : (Animal => unit)) : Cat = f_c()
stateful function f_c_to_u_to_a(_ : (Cat => unit)) : Animal = f_a()
stateful function f_c_to_u_to_c(_ : (Cat => unit)) : Cat = f_c()
stateful function f_u_to_dt_co_a(_ : unit) : dt_co(Animal) = DT_CO(f_u_to_a)
stateful function f_u_to_dt_co_c(_ : unit) : dt_co(Cat) = DT_CO(f_u_to_c)
stateful entrypoint init() =
let va1 : dt_contra(Animal) = DT_CONTRA(f_a_to_u) // success
let va2 : dt_contra(Animal) = DT_CONTRA(f_c_to_u) // fail
let va3 : dt_contra(Cat) = DT_CONTRA(f_a_to_u) // success
let va4 : dt_contra(Cat) = DT_CONTRA(f_c_to_u) // success
let vb1 : dt_co(Animal) = DT_CO(f_u_to_a) // success
let vb2 : dt_co(Animal) = DT_CO(f_u_to_c) // success
let vb3 : dt_co(Cat) = DT_CO(f_u_to_a) // fail
let vb4 : dt_co(Cat) = DT_CO(f_u_to_c) // success
let vc1 : dt_inv(Animal) = DT_INV(f_a_to_a) // success
let vc2 : dt_inv(Animal) = DT_INV(f_a_to_c) // success
let vc3 : dt_inv(Animal) = DT_INV(f_c_to_a) // fail
let vc4 : dt_inv(Animal) = DT_INV(f_c_to_c) // fail
let vc5 : dt_inv(Cat) = DT_INV(f_a_to_a) // fail
let vc6 : dt_inv(Cat) = DT_INV(f_a_to_c) // fail
let vc7 : dt_inv(Cat) = DT_INV(f_c_to_a) // fail
let vc8 : dt_inv(Cat) = DT_INV(f_c_to_c) // success
let vd1 : dt_biv(Animal) = DT_BIV(f_u_to_u) : dt_biv(Animal) // success
let vd2 : dt_biv(Animal) = DT_BIV(f_u_to_u) : dt_biv(Cat) // success
let vd3 : dt_biv(Cat) = DT_BIV(f_u_to_u) : dt_biv(Animal) // success
let vd4 : dt_biv(Cat) = DT_BIV(f_u_to_u) : dt_biv(Cat) // success
let ve1 : dt_inv_sep(Animal) = DT_INV_SEP_A(f_a_to_u) // success
let ve2 : dt_inv_sep(Animal) = DT_INV_SEP_A(f_c_to_u) // fail
let ve3 : dt_inv_sep(Animal) = DT_INV_SEP_B(f_u_to_a) // success
let ve4 : dt_inv_sep(Animal) = DT_INV_SEP_B(f_u_to_c) // fail
let ve5 : dt_inv_sep(Cat) = DT_INV_SEP_A(f_a_to_u) // fail
let ve6 : dt_inv_sep(Cat) = DT_INV_SEP_A(f_c_to_u) // success
let ve7 : dt_inv_sep(Cat) = DT_INV_SEP_B(f_u_to_a) // fail
let ve8 : dt_inv_sep(Cat) = DT_INV_SEP_B(f_u_to_c) // success
let vf1 : dt_co_nest_a(Animal) = DT_CO_NEST_A(f_dt_contra_a_to_u) // success
let vf2 : dt_co_nest_a(Animal) = DT_CO_NEST_A(f_dt_contra_c_to_u) // success
let vf3 : dt_co_nest_a(Cat) = DT_CO_NEST_A(f_dt_contra_a_to_u) // fail
let vf4 : dt_co_nest_a(Cat) = DT_CO_NEST_A(f_dt_contra_c_to_u) // success
let vg1 : dt_contra_nest_a(Animal) = DT_CONTRA_NEST_A(f_dt_co_a_to_u) // success
let vg2 : dt_contra_nest_a(Animal) = DT_CONTRA_NEST_A(f_dt_co_c_to_u) // fail
let vg3 : dt_contra_nest_a(Cat) = DT_CONTRA_NEST_A(f_dt_co_a_to_u) // success
let vg4 : dt_contra_nest_a(Cat) = DT_CONTRA_NEST_A(f_dt_co_c_to_u) // success
let vh1 : dt_contra_nest_b(Animal) = DT_CONTRA_NEST_B(f_u_to_dt_contra_a) // success
let vh2 : dt_contra_nest_b(Animal) = DT_CONTRA_NEST_B(f_u_to_dt_contra_c) // fail
let vh3 : dt_contra_nest_b(Cat) = DT_CONTRA_NEST_B(f_u_to_dt_contra_a) // success
let vh4 : dt_contra_nest_b(Cat) = DT_CONTRA_NEST_B(f_u_to_dt_contra_c) // success
let vi1 : dt_co_nest_b(Animal) = DT_CO_NEST_B(f_u_to_dt_co_a) // success
let vi2 : dt_co_nest_b(Animal) = DT_CO_NEST_B(f_u_to_dt_co_c) // success
let vi3 : dt_co_nest_b(Cat) = DT_CO_NEST_B(f_u_to_dt_co_a) // fail
let vi4 : dt_co_nest_b(Cat) = DT_CO_NEST_B(f_u_to_dt_co_c) // success
let vj1 : dt_co_twice(Animal) = DT_CO_TWICE(f_a_to_u_to_c : (Animal => unit) => Animal) : dt_co_twice(Animal) // success
let vj2 : dt_co_twice(Animal) = DT_CO_TWICE(f_c_to_u_to_c : (Cat => unit) => Cat ) : dt_co_twice(Cat) // success
let vj3 : dt_co_twice(Cat) = DT_CO_TWICE(f_c_to_u_to_a : (Animal => unit) => Animal) : dt_co_twice(Animal) // fail
let vj4 : dt_co_twice(Cat) = DT_CO_TWICE(f_c_to_u_to_c : (Cat => unit) => Cat ) : dt_co_twice(Cat) // success
let vk01 : dt_a_contra_b_contra(Animal, Animal) = DT_A_CONTRA_B_CONTRA(f_a_to_a_to_u) // success
let vk02 : dt_a_contra_b_contra(Animal, Animal) = DT_A_CONTRA_B_CONTRA(f_a_to_c_to_u) // fail
let vk03 : dt_a_contra_b_contra(Animal, Animal) = DT_A_CONTRA_B_CONTRA(f_c_to_a_to_u) // fail
let vk04 : dt_a_contra_b_contra(Animal, Animal) = DT_A_CONTRA_B_CONTRA(f_c_to_c_to_u) // fail
let vk05 : dt_a_contra_b_contra(Animal, Cat) = DT_A_CONTRA_B_CONTRA(f_a_to_a_to_u) // success
let vk06 : dt_a_contra_b_contra(Animal, Cat) = DT_A_CONTRA_B_CONTRA(f_a_to_c_to_u) // success
let vk07 : dt_a_contra_b_contra(Animal, Cat) = DT_A_CONTRA_B_CONTRA(f_c_to_a_to_u) // fail
let vk08 : dt_a_contra_b_contra(Animal, Cat) = DT_A_CONTRA_B_CONTRA(f_c_to_c_to_u) // fail
let vk09 : dt_a_contra_b_contra(Cat, Animal) = DT_A_CONTRA_B_CONTRA(f_a_to_a_to_u) // success
let vk10 : dt_a_contra_b_contra(Cat, Animal) = DT_A_CONTRA_B_CONTRA(f_a_to_c_to_u) // fail
let vk11 : dt_a_contra_b_contra(Cat, Animal) = DT_A_CONTRA_B_CONTRA(f_c_to_a_to_u) // success
let vk12 : dt_a_contra_b_contra(Cat, Animal) = DT_A_CONTRA_B_CONTRA(f_c_to_c_to_u) // fail
let vk13 : dt_a_contra_b_contra(Cat, Cat) = DT_A_CONTRA_B_CONTRA(f_a_to_a_to_u) // success
let vk14 : dt_a_contra_b_contra(Cat, Cat) = DT_A_CONTRA_B_CONTRA(f_a_to_c_to_u) // success
let vk15 : dt_a_contra_b_contra(Cat, Cat) = DT_A_CONTRA_B_CONTRA(f_c_to_a_to_u) // success
let vk16 : dt_a_contra_b_contra(Cat, Cat) = DT_A_CONTRA_B_CONTRA(f_c_to_c_to_u) // success
let vl1 : dt_contra_twice(Animal) = DT_CONTRA_TWICE(f_a_to_a_to_u : Animal => Animal => unit) : dt_contra_twice(Animal) // success
let vl2 : dt_contra_twice(Animal) = DT_CONTRA_TWICE(f_a_to_c_to_u : Cat => Cat => unit) : dt_contra_twice(Cat) // fail
let vl3 : dt_contra_twice(Cat) = DT_CONTRA_TWICE(f_a_to_a_to_u : Animal => Animal => unit) : dt_contra_twice(Animal) // success
let vl4 : dt_contra_twice(Cat) = DT_CONTRA_TWICE(f_c_to_a_to_u : Cat => Cat => unit) : dt_contra_twice(Cat) // success
()
@@ -0,0 +1,47 @@
contract interface Animal =
entrypoint sound : () => string
contract Cat : Animal =
entrypoint sound() = "meow"
main contract Main =
entrypoint oracle() = ok_2YNyxd6TRJPNrTcEDCe9ra59SVUdp9FR9qWC5msKZWYD9bP9z5
entrypoint query() = oq_2oRvyowJuJnEkxy58Ckkw77XfWJrmRgmGaLzhdqb67SKEL1gPY
entrypoint init() =
let o01 : oracle(Animal, Animal) = oracle() : oracle(Animal, Animal) // success
let o02 : oracle(Animal, Animal) = oracle() : oracle(Animal, Cat) // success
let o03 : oracle(Animal, Animal) = oracle() : oracle(Cat, Animal) // fail
let o04 : oracle(Animal, Animal) = oracle() : oracle(Cat, Cat) // fail
let o05 : oracle(Animal, Cat) = oracle() : oracle(Animal, Animal) // fail
let o06 : oracle(Animal, Cat) = oracle() : oracle(Animal, Cat) // success
let o07 : oracle(Animal, Cat) = oracle() : oracle(Cat, Animal) // fail
let o08 : oracle(Animal, Cat) = oracle() : oracle(Cat, Cat) // fail
let o09 : oracle(Cat, Animal) = oracle() : oracle(Animal, Animal) // success
let o10 : oracle(Cat, Animal) = oracle() : oracle(Animal, Cat) // success
let o11 : oracle(Cat, Animal) = oracle() : oracle(Cat, Animal) // success
let o12 : oracle(Cat, Animal) = oracle() : oracle(Cat, Cat) // success
let o13 : oracle(Cat, Cat) = oracle() : oracle(Animal, Animal) // fail
let o14 : oracle(Cat, Cat) = oracle() : oracle(Animal, Cat) // success
let o15 : oracle(Cat, Cat) = oracle() : oracle(Cat, Animal) // fail
let o16 : oracle(Cat, Cat) = oracle() : oracle(Cat, Cat) // success
let q01 : oracle_query(Animal, Animal) = query() : oracle_query(Animal, Animal) // success
let q02 : oracle_query(Animal, Animal) = query() : oracle_query(Animal, Cat) // success
let q03 : oracle_query(Animal, Animal) = query() : oracle_query(Cat, Animal) // success
let q04 : oracle_query(Animal, Animal) = query() : oracle_query(Cat, Cat) // success
let q05 : oracle_query(Animal, Cat) = query() : oracle_query(Animal, Animal) // fail
let q06 : oracle_query(Animal, Cat) = query() : oracle_query(Animal, Cat) // success
let q07 : oracle_query(Animal, Cat) = query() : oracle_query(Cat, Animal) // fail
let q08 : oracle_query(Animal, Cat) = query() : oracle_query(Cat, Cat) // success
let q09 : oracle_query(Cat, Animal) = query() : oracle_query(Animal, Animal) // fail
let q10 : oracle_query(Cat, Animal) = query() : oracle_query(Animal, Cat) // fail
let q11 : oracle_query(Cat, Animal) = query() : oracle_query(Cat, Animal) // success
let q12 : oracle_query(Cat, Animal) = query() : oracle_query(Cat, Cat) // success
let q13 : oracle_query(Cat, Cat) = query() : oracle_query(Animal, Animal) // fail
let q14 : oracle_query(Cat, Cat) = query() : oracle_query(Animal, Cat) // fail
let q15 : oracle_query(Cat, Cat) = query() : oracle_query(Cat, Animal) // fail
let q16 : oracle_query(Cat, Cat) = query() : oracle_query(Cat, Cat) // success
()
@@ -0,0 +1,51 @@
contract interface Animal =
entrypoint sound : () => string
contract Cat : Animal =
entrypoint sound() = "meow"
main contract Main =
record rec_co('a) = { x : 'a ,
y : () => 'a }
record rec_contra('a) = { x : 'a => unit }
record rec_inv('a) = { x : 'a => unit,
y : () => 'a }
record rec_biv('a) = { x : int }
stateful entrypoint new_cat() : Cat = Chain.create()
stateful entrypoint new_animal() : Animal = new_cat()
stateful entrypoint animal_to_unit(_ : Animal) : unit = ()
stateful entrypoint cat_to_unit(_ : Cat) : unit = ()
stateful entrypoint unit_to_animal() : Animal = new_animal()
stateful entrypoint unit_to_cat() : Cat = new_cat()
stateful entrypoint init() =
let ra : rec_co(Animal) = { x = new_animal(), y = unit_to_animal }
let rc : rec_co(Cat) = { x = new_cat(), y = unit_to_cat }
let r01 : rec_co(Animal) = ra // success
let r02 : rec_co(Animal) = rc // success
let r03 : rec_co(Cat) = ra // fail
let r04 : rec_co(Cat) = rc // sucess
let ratu : rec_contra(Animal) = { x = animal_to_unit }
let rctu : rec_contra(Cat) = { x = cat_to_unit }
let r05 : rec_contra(Animal) = ratu // success
let r06 : rec_contra(Animal) = rctu // fail
let r07 : rec_contra(Cat) = ratu // success
let r08 : rec_contra(Cat) = rctu // success
let rxaya : rec_inv(Animal) = { x = animal_to_unit, y = unit_to_animal }
let rxcyc : rec_inv(Cat) = { x = cat_to_unit, y = unit_to_cat }
let r09 : rec_inv(Animal) = rxaya // success
let r10 : rec_inv(Animal) = rxcyc // fail
let r11 : rec_inv(Cat) = rxaya // fail
let r12 : rec_inv(Cat) = rxcyc // success
let rba : rec_biv(Animal) = { x = 1 }
let rbc : rec_biv(Cat) = { x = 1 }
let r13 : rec_biv(Animal) = rba // success
let r14 : rec_biv(Animal) = rbc // success
let r15 : rec_biv(Cat) = rba // success
let r16 : rec_biv(Cat) = rbc // success
()
+12 -4
View File
@@ -1,4 +1,12 @@
contract ShareTwo =
record state = {s1 : int, s2 : int}
entrypoint init() = {s1 = 0, s2 = 0}
stateful entrypoint buy() = ()
// This is a custom test file if you need to run a compiler without
// changing aeso_compiler_tests.erl
include "List.aes"
contract IntegerHolder =
type state = int
entrypoint init(x) = x
entrypoint get() = state
main contract Test =
stateful entrypoint f(c) = Chain.clone(ref=c, 123)