Check for repeated argument names to functions

(PT-159592825)
This commit is contained in:
Ulf Norell 2019-05-10 14:04:01 +02:00
parent 23cc8e1132
commit f347eaee90
3 changed files with 16 additions and 1 deletions

View File

@ -862,7 +862,8 @@ infer_letrec(Env, Defs) ->
[print_typesig(S) || S <- TypeSigs],
{TypeSigs, NewDefs}.
infer_letfun(Env, {letfun, Attrib, {id, NameAttrib, Name}, Args, What, Body}) ->
infer_letfun(Env, {letfun, Attrib, Fun = {id, NameAttrib, Name}, Args, What, Body}) ->
check_unique_arg_names(Fun, Args),
ArgTypes = [{ArgName, check_type(Env, arg_type(T))} || {arg, _, ArgName, T} <- Args],
ExpectedType = check_type(Env, arg_type(What)),
NewBody={typed, _, _, ResultType} = check_expr(bind_vars(ArgTypes, Env), Body, ExpectedType),
@ -873,6 +874,13 @@ infer_letfun(Env, {letfun, Attrib, {id, NameAttrib, Name}, Args, What, Body}) ->
{{Name, TypeSig},
{letfun, Attrib, {id, NameAttrib, Name}, NewArgs, ResultType, NewBody}}.
check_unique_arg_names(Fun, Args) ->
Name = fun({arg, _, {id, _, X}, _}) -> X end,
Names = lists:map(Name, Args),
Dups = lists:usort(Names -- lists:usort(Names)),
[ type_error({repeated_arg, Fun, Arg}) || Arg <- Dups ],
ok.
print_typesig({Name, TypeSig}) ->
?PRINT_TYPES("Inferred ~s : ~s\n", [Name, pp(TypeSig)]).
@ -1929,6 +1937,9 @@ pp_error({include, {string, Pos, Name}}) ->
pp_error({namespace, _Pos, {con, Pos, Name}, _Def}) ->
io_lib:format("Nested namespace not allowed\nNamespace '~s' at ~s not defined at top level.\n",
[Name, pp_loc(Pos)]);
pp_error({repeated_arg, Fun, Arg}) ->
io_lib:format("Repeated argument ~s to function ~s (at ~s).\n",
[Arg, pp(Fun), pp_loc(Fun)]);
pp_error(Err) ->
io_lib:format("Unknown error: ~p\n", [Err]).

View File

@ -191,6 +191,8 @@ failing_contracts() ->
" - r' (at line 5, column 10)">>,
<<"Repeated name x in pattern\n"
" x :: x (at line 26, column 7)">>,
<<"Repeated argument x 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)">>,
<<"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)">>]}

View File

@ -40,3 +40,5 @@ contract Test =
function type_error(r, x) =
set_x(set_x(x, r), x)
function repeated_arg(x : int, y, x : string, y : bool) : string = x