Merge pull request #93 from aeternity/PT-166788837-bytes
PT-166788837 bytes
This commit is contained in:
commit
2e0c44862c
@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
{erl_opts, [debug_info]}.
|
{erl_opts, [debug_info]}.
|
||||||
|
|
||||||
{deps, [ {aebytecode, {git, "https://github.com/aeternity/aebytecode.git", {ref,"f91c8fa"}}}
|
{deps, [ {aebytecode, {git, "https://github.com/aeternity/aebytecode.git", {ref,"59af12b"}}}
|
||||||
, {getopt, "1.0.1"}
|
, {getopt, "1.0.1"}
|
||||||
, {jsx, {git, "https://github.com/talentdeficit/jsx.git",
|
, {jsx, {git, "https://github.com/talentdeficit/jsx.git",
|
||||||
{tag, "2.8.0"}}}
|
{tag, "2.8.0"}}}
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
{"1.1.0",
|
{"1.1.0",
|
||||||
[{<<"aebytecode">>,
|
[{<<"aebytecode">>,
|
||||||
{git,"https://github.com/aeternity/aebytecode.git",
|
{git,"https://github.com/aeternity/aebytecode.git",
|
||||||
{ref,"f91c8fabdd01cf911fb194862a50f9635c96c0e5"}},
|
{ref,"59af12bf349edafcd470cd3ccefff09cacd2d010"}},
|
||||||
0},
|
0},
|
||||||
{<<"aeserialization">>,
|
{<<"aeserialization">>,
|
||||||
{git,"https://github.com/aeternity/aeserialization.git",
|
{git,"https://github.com/aeternity/aeserialization.git",
|
||||||
|
@ -1134,7 +1134,13 @@ infer_expr(Env, {lam, Attrs, Args, Body}) ->
|
|||||||
{'case', _, {typed, _, {tuple, _, NewArgPatterns}, _}, NewBody} =
|
{'case', _, {typed, _, {tuple, _, NewArgPatterns}, _}, NewBody} =
|
||||||
infer_case(Env, Attrs, {tuple, Attrs, ArgPatterns}, {tuple_t, Attrs, ArgTypes}, Body, ResultType),
|
infer_case(Env, Attrs, {tuple, Attrs, ArgPatterns}, {tuple_t, Attrs, ArgTypes}, Body, ResultType),
|
||||||
NewArgs = [{arg, As, NewPat, NewT} || {typed, As, NewPat, NewT} <- NewArgPatterns],
|
NewArgs = [{arg, As, NewPat, NewT} || {typed, As, NewPat, NewT} <- NewArgPatterns],
|
||||||
{typed, Attrs, {lam, Attrs, NewArgs, NewBody}, {fun_t, Attrs, [], ArgTypes, ResultType}}.
|
{typed, Attrs, {lam, Attrs, NewArgs, NewBody}, {fun_t, Attrs, [], ArgTypes, ResultType}};
|
||||||
|
infer_expr(Env, Let = {letval, Attrs, _, _, _}) ->
|
||||||
|
type_error({missing_body_for_let, Attrs}),
|
||||||
|
infer_expr(Env, {block, Attrs, [Let, abort_expr(Attrs, "missing body")]});
|
||||||
|
infer_expr(Env, Let = {letfun, Attrs, _, _, _, _}) ->
|
||||||
|
type_error({missing_body_for_let, Attrs}),
|
||||||
|
infer_expr(Env, {block, Attrs, [Let, abort_expr(Attrs, "missing body")]}).
|
||||||
|
|
||||||
infer_named_arg(Env, NamedArgs, {named_arg, Ann, Id, E}) ->
|
infer_named_arg(Env, NamedArgs, {named_arg, Ann, Id, E}) ->
|
||||||
CheckedExpr = {typed, _, _, ArgType} = infer_expr(Env, E),
|
CheckedExpr = {typed, _, _, ArgType} = infer_expr(Env, E),
|
||||||
@ -1208,6 +1214,8 @@ infer_case(Env, Attrs, Pattern, ExprType, Branch, SwitchType) ->
|
|||||||
%% NewStmts = infer_block(Env, Attrs, Stmts, BlockType)
|
%% NewStmts = infer_block(Env, Attrs, Stmts, BlockType)
|
||||||
infer_block(_Env, Attrs, [], BlockType) ->
|
infer_block(_Env, Attrs, [], BlockType) ->
|
||||||
error({impossible, empty_block, Attrs, BlockType});
|
error({impossible, empty_block, Attrs, BlockType});
|
||||||
|
infer_block(Env, _, [E], BlockType) ->
|
||||||
|
[check_expr(Env, E, BlockType)];
|
||||||
infer_block(Env, Attrs, [Def={letfun, Ann, _, _, _, _}|Rest], BlockType) ->
|
infer_block(Env, Attrs, [Def={letfun, Ann, _, _, _, _}|Rest], BlockType) ->
|
||||||
{{Name, TypeSig}, LetFun} = infer_letfun(Env, Def),
|
{{Name, TypeSig}, LetFun} = infer_letfun(Env, Def),
|
||||||
FunT = freshen_type(typesig_to_fun_t(TypeSig)),
|
FunT = freshen_type(typesig_to_fun_t(TypeSig)),
|
||||||
@ -1218,8 +1226,6 @@ infer_block(Env, _, [{letval, Attrs, Pattern, Type, E}|Rest], BlockType) ->
|
|||||||
{'case', _, NewPattern, {typed, _, {block, _, NewRest}, _}} =
|
{'case', _, NewPattern, {typed, _, {block, _, NewRest}, _}} =
|
||||||
infer_case(Env, Attrs, Pattern, PatType, {block, Attrs, Rest}, BlockType),
|
infer_case(Env, Attrs, Pattern, PatType, {block, Attrs, Rest}, BlockType),
|
||||||
[{letval, Attrs, NewPattern, Type, NewE}|NewRest];
|
[{letval, Attrs, NewPattern, Type, NewE}|NewRest];
|
||||||
infer_block(Env, _, [E], BlockType) ->
|
|
||||||
[check_expr(Env, E, BlockType)];
|
|
||||||
infer_block(Env, Attrs, [E|Rest], BlockType) ->
|
infer_block(Env, Attrs, [E|Rest], BlockType) ->
|
||||||
[infer_expr(Env, E)|infer_block(Env, Attrs, Rest, BlockType)].
|
[infer_expr(Env, E)|infer_block(Env, Attrs, Rest, BlockType)].
|
||||||
|
|
||||||
@ -1255,6 +1261,9 @@ infer_prefix({IntOp,As}) when IntOp =:= '-' ->
|
|||||||
Int = {id, As, "int"},
|
Int = {id, As, "int"},
|
||||||
{fun_t, As, [], [Int], Int}.
|
{fun_t, As, [], [Int], Int}.
|
||||||
|
|
||||||
|
abort_expr(Ann, Str) ->
|
||||||
|
{app, Ann, {id, Ann, "abort"}, [{string, Ann, Str}]}.
|
||||||
|
|
||||||
free_vars({int, _, _}) ->
|
free_vars({int, _, _}) ->
|
||||||
[];
|
[];
|
||||||
free_vars({char, _, _}) ->
|
free_vars({char, _, _}) ->
|
||||||
@ -1814,6 +1823,10 @@ occurs_check1(R, {tuple_t, _, Ts}) ->
|
|||||||
occurs_check(R, Ts);
|
occurs_check(R, Ts);
|
||||||
occurs_check1(R, {named_arg_t, _, _, T, _}) ->
|
occurs_check1(R, {named_arg_t, _, _, T, _}) ->
|
||||||
occurs_check(R, T);
|
occurs_check(R, T);
|
||||||
|
occurs_check1(R, {record_t, Fields}) ->
|
||||||
|
occurs_check(R, Fields);
|
||||||
|
occurs_check1(R, {field_t, _, _, T}) ->
|
||||||
|
occurs_check(R, T);
|
||||||
occurs_check1(R, [H | T]) ->
|
occurs_check1(R, [H | T]) ->
|
||||||
occurs_check(R, H) orelse occurs_check(R, T);
|
occurs_check(R, H) orelse occurs_check(R, T);
|
||||||
occurs_check1(_, []) -> false.
|
occurs_check1(_, []) -> false.
|
||||||
@ -2025,6 +2038,8 @@ pp_error({init_depends_on_state, Which, [_Init | Chain]}) ->
|
|||||||
[if Which == put -> "write"; true -> "read" end,
|
[if Which == put -> "write"; true -> "read" end,
|
||||||
[ io_lib:format(" - ~s (at ~s)~s\n", [Fun, pp_loc(Ann), WhichCalls(Fun)])
|
[ io_lib:format(" - ~s (at ~s)~s\n", [Fun, pp_loc(Ann), WhichCalls(Fun)])
|
||||||
|| {[_, Fun], Ann} <- Chain]]);
|
|| {[_, Fun], Ann} <- Chain]]);
|
||||||
|
pp_error({missing_body_for_let, Ann}) ->
|
||||||
|
io_lib:format("Let binding at ~s must be followed by an expression\n", [pp_loc(Ann)]);
|
||||||
pp_error(Err) ->
|
pp_error(Err) ->
|
||||||
io_lib:format("Unknown error: ~p\n", [Err]).
|
io_lib:format("Unknown error: ~p\n", [Err]).
|
||||||
|
|
||||||
|
@ -37,8 +37,7 @@
|
|||||||
|
|
||||||
-type flit() :: {int, integer()}
|
-type flit() :: {int, integer()}
|
||||||
| {string, binary()}
|
| {string, binary()}
|
||||||
| {hash, binary()}
|
| {bytes, binary()}
|
||||||
| {signature, binary()}
|
|
||||||
| {account_pubkey, binary()}
|
| {account_pubkey, binary()}
|
||||||
| {contract_pubkey, binary()}
|
| {contract_pubkey, binary()}
|
||||||
| {oracle_pubkey, binary()}
|
| {oracle_pubkey, binary()}
|
||||||
@ -90,8 +89,7 @@
|
|||||||
| {map, ftype(), ftype()}
|
| {map, ftype(), ftype()}
|
||||||
| {tuple, [ftype()]}
|
| {tuple, [ftype()]}
|
||||||
| address
|
| address
|
||||||
| hash
|
| {bytes, non_neg_integer()}
|
||||||
| signature
|
|
||||||
| contract
|
| contract
|
||||||
| {oracle, ftype(), ftype()} %% Query type, Response type
|
| {oracle, ftype(), ftype()} %% Query type, Response type
|
||||||
| oracle_query
|
| oracle_query
|
||||||
@ -320,10 +318,8 @@ type_to_fcode(Env, Sub, {tuple_t, _, Types}) ->
|
|||||||
type_to_fcode(Env, Sub, {record_t, Fields}) ->
|
type_to_fcode(Env, Sub, {record_t, Fields}) ->
|
||||||
FieldType = fun({field_t, _, _, Ty}) -> Ty end,
|
FieldType = fun({field_t, _, _, Ty}) -> Ty end,
|
||||||
type_to_fcode(Env, Sub, {tuple_t, [], lists:map(FieldType, Fields)});
|
type_to_fcode(Env, Sub, {tuple_t, [], lists:map(FieldType, Fields)});
|
||||||
type_to_fcode(_Env, _Sub, {bytes_t, _, 32}) -> hash;
|
type_to_fcode(_Env, _Sub, {bytes_t, _, N}) ->
|
||||||
type_to_fcode(_Env, _Sub, {bytes_t, _, 64}) -> signature;
|
{bytes, N};
|
||||||
type_to_fcode(_Env, _Sub, {bytes_t, _, _N}) ->
|
|
||||||
string; %% TODO: add bytes type to FATE
|
|
||||||
type_to_fcode(_Env, Sub, {tvar, _, X}) ->
|
type_to_fcode(_Env, Sub, {tvar, _, X}) ->
|
||||||
maps:get(X, Sub, {tvar, X});
|
maps:get(X, Sub, {tvar, X});
|
||||||
type_to_fcode(Env, Sub, {fun_t, _, Named, Args, Res}) ->
|
type_to_fcode(Env, Sub, {fun_t, _, Named, Args, Res}) ->
|
||||||
@ -367,10 +363,7 @@ expr_to_fcode(_Env, _Type, {account_pubkey, _, K}) -> {lit, {account_pubkey, K}
|
|||||||
expr_to_fcode(_Env, _Type, {contract_pubkey, _, K}) -> {lit, {contract_pubkey, K}};
|
expr_to_fcode(_Env, _Type, {contract_pubkey, _, K}) -> {lit, {contract_pubkey, K}};
|
||||||
expr_to_fcode(_Env, _Type, {oracle_pubkey, _, K}) -> {lit, {oracle_pubkey, K}};
|
expr_to_fcode(_Env, _Type, {oracle_pubkey, _, K}) -> {lit, {oracle_pubkey, K}};
|
||||||
expr_to_fcode(_Env, _Type, {oracle_query_id, _, K}) -> {lit, {oracle_query_id, K}};
|
expr_to_fcode(_Env, _Type, {oracle_query_id, _, K}) -> {lit, {oracle_query_id, K}};
|
||||||
|
expr_to_fcode(_Env, _Type, {bytes, _, B}) -> {lit, {bytes, B}};
|
||||||
expr_to_fcode(_Env, _Type, {bytes, _, Bin = <<_:32/binary>>}) -> {lit, {hash, Bin}};
|
|
||||||
expr_to_fcode(_Env, _Type, {bytes, _, Bin = <<_:64/binary>>}) -> {lit, {signature, Bin}};
|
|
||||||
expr_to_fcode(_Env, _Type, {bytes, _, Bin}) -> {lit, {string, Bin}};
|
|
||||||
|
|
||||||
%% Variables
|
%% Variables
|
||||||
expr_to_fcode(Env, _Type, {id, _, X}) -> resolve_var(Env, [X]);
|
expr_to_fcode(Env, _Type, {id, _, X}) -> resolve_var(Env, [X]);
|
||||||
|
@ -161,8 +161,7 @@ type_to_scode(integer) -> integer;
|
|||||||
type_to_scode(boolean) -> boolean;
|
type_to_scode(boolean) -> boolean;
|
||||||
type_to_scode(string) -> string;
|
type_to_scode(string) -> string;
|
||||||
type_to_scode(address) -> address;
|
type_to_scode(address) -> address;
|
||||||
type_to_scode(hash) -> hash;
|
type_to_scode({bytes, N}) -> {bytes, N};
|
||||||
type_to_scode(signature) -> signature;
|
|
||||||
type_to_scode(contract) -> contract;
|
type_to_scode(contract) -> contract;
|
||||||
type_to_scode({oracle, _, _}) -> oracle;
|
type_to_scode({oracle, _, _}) -> oracle;
|
||||||
type_to_scode(oracle_query) -> oracle_query;
|
type_to_scode(oracle_query) -> oracle_query;
|
||||||
@ -236,8 +235,7 @@ lit_to_fate(L) ->
|
|||||||
case L of
|
case L of
|
||||||
{int, N} -> aeb_fate_data:make_integer(N);
|
{int, N} -> aeb_fate_data:make_integer(N);
|
||||||
{string, S} -> aeb_fate_data:make_string(S);
|
{string, S} -> aeb_fate_data:make_string(S);
|
||||||
{hash, H} -> aeb_fate_data:make_hash(H);
|
{bytes, B} -> aeb_fate_data:make_bytes(B);
|
||||||
{signature, S} -> aeb_fate_data:make_signature(S);
|
|
||||||
{bool, B} -> aeb_fate_data:make_boolean(B);
|
{bool, B} -> aeb_fate_data:make_boolean(B);
|
||||||
{account_pubkey, K} -> aeb_fate_data:make_address(K);
|
{account_pubkey, K} -> aeb_fate_data:make_address(K);
|
||||||
{contract_pubkey, K} -> aeb_fate_data:make_contract(K);
|
{contract_pubkey, K} -> aeb_fate_data:make_contract(K);
|
||||||
|
@ -69,9 +69,7 @@ from_fate({id, _, "address"}, ?FATE_ADDRESS(Bin)) -> {account_pubkey, [], Bin};
|
|||||||
from_fate({app_t, _, {id, _, "oracle"}, _}, ?FATE_ORACLE(Bin)) -> {oracle_pubkey, [], Bin};
|
from_fate({app_t, _, {id, _, "oracle"}, _}, ?FATE_ORACLE(Bin)) -> {oracle_pubkey, [], Bin};
|
||||||
from_fate({app_t, _, {id, _, "oracle_query"}, _}, ?FATE_ORACLE_Q(Bin)) -> {oracle_query_id, [], Bin};
|
from_fate({app_t, _, {id, _, "oracle_query"}, _}, ?FATE_ORACLE_Q(Bin)) -> {oracle_query_id, [], Bin};
|
||||||
from_fate({con, _, _Name}, ?FATE_CONTRACT(Bin)) -> {contract_pubkey, [], Bin};
|
from_fate({con, _, _Name}, ?FATE_CONTRACT(Bin)) -> {contract_pubkey, [], Bin};
|
||||||
from_fate({bytes_t, _, 32}, ?FATE_HASH(Bin)) -> {bytes, [], Bin};
|
from_fate({bytes_t, _, N}, ?FATE_BYTES(Bin)) when byte_size(Bin) == N -> {bytes, [], Bin};
|
||||||
from_fate({bytes_t, _, 64}, ?FATE_SIGNATURE(Bin)) -> {bytes, [], Bin};
|
|
||||||
from_fate({bytes_t, _, N}, Bin) when size(Bin) == N -> {bytes, [], Bin};
|
|
||||||
from_fate({id, _, "bits"}, ?FATE_BITS(Bin)) -> error({todo, bits, Bin});
|
from_fate({id, _, "bits"}, ?FATE_BITS(Bin)) -> error({todo, bits, Bin});
|
||||||
from_fate({id, _, "int"}, N) when is_integer(N) -> {int, [], N};
|
from_fate({id, _, "int"}, N) when is_integer(N) -> {int, [], N};
|
||||||
from_fate({id, _, "bool"}, B) when is_boolean(B) -> {bool, [], B};
|
from_fate({id, _, "bool"}, B) when is_boolean(B) -> {bool, [], B};
|
||||||
|
@ -114,7 +114,8 @@ compilable_contracts() ->
|
|||||||
"bitcoin_auth",
|
"bitcoin_auth",
|
||||||
"address_literals",
|
"address_literals",
|
||||||
"bytes_equality",
|
"bytes_equality",
|
||||||
"address_chain"
|
"address_chain",
|
||||||
|
"namespace_bug"
|
||||||
].
|
].
|
||||||
|
|
||||||
not_yet_compilable(fate) ->
|
not_yet_compilable(fate) ->
|
||||||
@ -207,7 +208,11 @@ failing_contracts() ->
|
|||||||
<<"Repeated argument y to function repeated_arg (at line 44, column 12).">>,
|
<<"Repeated argument y to function repeated_arg (at line 44, column 12).">>,
|
||||||
<<"No record type with fields y, z (at line 14, column 22)">>,
|
<<"No record type with fields y, z (at line 14, column 22)">>,
|
||||||
<<"The field z is missing when constructing an element of type r2 (at line 15, column 24)">>,
|
<<"The field z is missing when constructing an element of type r2 (at line 15, column 24)">>,
|
||||||
<<"Record type r2 does not have field y (at line 15, column 22)">>]}
|
<<"Record type r2 does not have field y (at line 15, column 22)">>,
|
||||||
|
<<"Let binding at line 47, column 5 must be followed by an expression">>,
|
||||||
|
<<"Let binding at line 50, column 5 must be followed by an expression">>,
|
||||||
|
<<"Let binding at line 54, column 5 must be followed by an expression">>,
|
||||||
|
<<"Let binding at line 58, column 5 must be followed by an expression">>]}
|
||||||
, {"init_type_error",
|
, {"init_type_error",
|
||||||
[<<"Cannot unify string\n"
|
[<<"Cannot unify string\n"
|
||||||
" and map(int, int)\n"
|
" and map(int, int)\n"
|
||||||
|
12
test/contracts/namespace_bug.aes
Normal file
12
test/contracts/namespace_bug.aes
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
|
||||||
|
namespace Foo =
|
||||||
|
|
||||||
|
record bla = {x : int, y : bool}
|
||||||
|
|
||||||
|
function bar() : Foo.bla = {x = 17, y = true}
|
||||||
|
|
||||||
|
contract Bug =
|
||||||
|
|
||||||
|
// Crashed the type checker
|
||||||
|
function foo () = Foo.bar()
|
||||||
|
|
@ -42,3 +42,18 @@ contract Test =
|
|||||||
set_x(set_x(x, r), x)
|
set_x(set_x(x, r), x)
|
||||||
|
|
||||||
function repeated_arg(x : int, y, x : string, y : bool) : string = x
|
function repeated_arg(x : int, y, x : string, y : bool) : string = x
|
||||||
|
|
||||||
|
function missing1() =
|
||||||
|
let x = 0
|
||||||
|
|
||||||
|
function missing_fun1() =
|
||||||
|
let f(x) = x
|
||||||
|
|
||||||
|
function missing2() =
|
||||||
|
let x = 0
|
||||||
|
let y = 0
|
||||||
|
|
||||||
|
function missing_fun2() =
|
||||||
|
let f() = 0
|
||||||
|
let g() = f()
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user