Better errors when using old tuple type syntax

This commit is contained in:
Ulf Norell 2019-08-27 15:08:56 +02:00
parent 3ff93c5c89
commit 3b2daf8cd6
3 changed files with 17 additions and 10 deletions

View File

@ -767,7 +767,9 @@ check_type(Env, Type = {fun_t, Ann, NamedArgs, Args, Ret}, Arity) ->
{fun_t, Ann, NamedArgs1, Args1, Ret1};
check_type(_Env, Type = {uvar, _, _}, Arity) ->
ensure_base_type(Type, Arity),
Type.
Type;
check_type(_Env, {args_t, Ann, Ts}, _) ->
type_error({new_tuple_syntax, Ann, Ts}).
ensure_base_type(Type, Arity) ->
[ type_error({wrong_type_arguments, Type, Arity, 0}) || Arity /= 0 ],
@ -2222,6 +2224,9 @@ pp_error({contract_has_no_entrypoints, Con}) ->
"'function'.\n", [pp_expr("", Con), pp_loc(Con)]);
pp_error({unbound_type, Type}) ->
io_lib:format("Unbound type ~s (at ~s).\n", [pp_type("", Type), pp_loc(Type)]);
pp_error({new_tuple_syntax, Ann, Ts}) ->
io_lib:format("Invalid type\n~s (at ~s)\nThe syntax of tuple types changed in Sophia version 4.0. Did you mean\n~s\n",
[pp_type(" ", {args_t, Ann, Ts}), pp_loc(Ann), pp_type(" ", {tuple_t, Ann, Ts})]);
pp_error(Err) ->
io_lib:format("Unknown error: ~p\n", [Err]).

View File

@ -150,7 +150,7 @@ type() -> ?LAZY_P(type100()).
type100() -> type200().
type200() ->
?RULE(many({fun_domain(), keyword('=>')}), type300(), fun_t(_1, _2)).
?RULE(many({type300(), keyword('=>')}), type300(), fun_t(_1, _2)).
type300() ->
?RULE(sep1(type400(), tok('*')), tuple_t(get_ann(lists:nth(1, _1)), _1)).
@ -169,16 +169,15 @@ type400() ->
typeAtom() ->
?LAZY_P(choice(
[ parens(type())
, args_t()
, id(), token(con), token(qcon), token(qid), tvar()
])).
fun_domain() -> ?LAZY_P(choice(
[ ?RULE(tok('('), tok(')'), [])
%% Note avoidance of ambiguity: `(int)` can be treated as:
%% - literally `int`
%% - list of arguments with just one element int. This approach is dropped.
, ?RULE(tok('('), type(), tok(','), sep1(type(), tok(',')), tok(')'), [_2|_4])
, ?RULE(type300(), [_1])
args_t() ->
?LAZY_P(choice(
[ ?RULE(tok('('), tok(')'), {args_t, get_ann(_1), []})
%% Singleton case handled separately
, ?RULE(tok('('), type(), tok(','), sep1(type(), tok(',')), tok(')'), {args_t, get_ann(_1), [_2|_4]})
])).
%% -- Statements -------------------------------------------------------------
@ -501,7 +500,8 @@ tuple_t(_Ann, [Type]) -> Type; %% Not a tuple
tuple_t(Ann, Types) -> {tuple_t, Ann, Types}.
fun_t(Domains, Type) ->
lists:foldr(fun({Dom, Ann}, T) -> {fun_t, Ann, [], Dom, T} end,
lists:foldr(fun({{args_t, _, Dom}, Ann}, T) -> {fun_t, Ann, [], Dom, T};
({Dom, Ann}, T) -> {fun_t, Ann, [], [Dom], T} end,
Type, Domains).
tuple_e(_Ann, [Expr]) -> Expr; %% Not a tuple

View File

@ -243,6 +243,8 @@ type({app_t, _, Type, Args}) ->
beside(type(Type), args_type(Args));
type({tuple_t, _, Args}) ->
tuple_type(Args);
type({args_t, _, Args}) ->
args_type(Args);
type({bytes_t, _, any}) -> text("bytes(_)");
type({bytes_t, _, Len}) ->
text(lists:concat(["bytes(", Len, ")"]));