Add test for unknown tvar constraints

This commit is contained in:
Gaith Hallak 2022-06-14 14:55:50 +04:00
parent fc08fe09a5
commit 2d17ce3ee2
3 changed files with 53 additions and 42 deletions

View File

@ -1241,6 +1241,8 @@ check_type(Env, {constrained_t, Ann, Constraints, Type}, Arity) ->
TVars = [ Name || {tvar, _, Name} <- extract_typevars(Type) ], TVars = [ Name || {tvar, _, Name} <- extract_typevars(Type) ],
[ type_error({unused_constraint, C}) || C = {constraint, _, {tvar, _, Name}, _} <- Constraints, [ type_error({unused_constraint, C}) || C = {constraint, _, {tvar, _, Name}, _} <- Constraints,
not lists:member(Name, TVars) ], not lists:member(Name, TVars) ],
[ type_error({unknown_tvar_constraint, C}) || C = {constraint, _, _, {id, _, Name}} <- Constraints,
not lists:member(Name, ["eq", "ord"]) ],
{constrained_t, Ann, Constraints, check_type(Env, Type, Arity)}; {constrained_t, Ann, Constraints, check_type(Env, Type, Arity)};
check_type(_Env, {args_t, Ann, Ts}, _) -> check_type(_Env, {args_t, Ann, Ts}, _) ->
@ -3422,6 +3424,9 @@ mk_error({type_not_ord, Ann, Type}) ->
mk_error({unused_constraint, {constraint, Ann, {tvar, _, Name}, _}}) -> mk_error({unused_constraint, {constraint, Ann, {tvar, _, Name}, _}}) ->
Msg = io_lib:format("The type variable `~s` is constrained but never used", [Name]), Msg = io_lib:format("The type variable `~s` is constrained but never used", [Name]),
mk_t_err(pos(Ann), Msg); mk_t_err(pos(Ann), Msg);
mk_error({unknown_tvar_constraint, {constraint, _, {tvar, _, TVar}, {id, Ann, C}}}) ->
Msg = io_lib:format("Unknown constraint `~s` used on the type variable `~s`", [C, TVar]),
mk_t_err(pos(Ann), Msg);
mk_error(Err) -> mk_error(Err) ->
Msg = io_lib:format("Unknown error: ~p", [Err]), Msg = io_lib:format("Unknown error: ~p", [Err]),
mk_t_err(pos(0, 0), Msg). mk_t_err(pos(0, 0), Msg).

View File

@ -810,83 +810,85 @@ failing_contracts() ->
, ?TYPE_ERROR(comparable_typevar_constraints, , ?TYPE_ERROR(comparable_typevar_constraints,
[<<?Pos(21,30) [<<?Pos(21,30)
"Values of type `'a` are not comparable by equality">>, "Values of type `'a` are not comparable by equality">>,
<<?Pos(25,37) <<?Pos(25,38)
"The type variable `'b` is constrained but never used">>, "The type variable `'b` is constrained but never used">>,
<<?Pos(56,56) <<?Pos(29,41)
"Unknown constraint `foo` used on the type variable `'a`">>,
<<?Pos(60,56)
"Values of type `address` are not comparable by inequality">>, "Values of type `address` are not comparable by inequality">>,
<<?Pos(59,58) <<?Pos(63,58)
"Values of type `Chain.ttl` are not comparable by inequality">>, "Values of type `Chain.ttl` are not comparable by inequality">>,
<<?Pos(62,45) <<?Pos(66,45)
"Values of type `A` are not comparable by inequality">>, "Values of type `A` are not comparable by inequality">>,
<<?Pos(69,47) <<?Pos(73,47)
"Values of type `(int, char) => bool` are not comparable by inequality">>, "Values of type `(int, char) => bool` are not comparable by inequality">>,
<<?Pos(70,47) <<?Pos(74,47)
"Values of type `(int, char) => bool` are not comparable by equality">>, "Values of type `(int, char) => bool` are not comparable by equality">>,
<<?Pos(85,71) <<?Pos(89,71)
"Values of type `list(address)` are not comparable by inequality">>, "Values of type `list(address)` are not comparable by inequality">>,
<<?Pos(88,77) <<?Pos(92,77)
"Values of type `option(address)` are not comparable by inequality">>, "Values of type `option(address)` are not comparable by inequality">>,
<<?Pos(91,76) <<?Pos(95,76)
"Values of type `(address * int)` are not comparable by inequality">>, "Values of type `(address * int)` are not comparable by inequality">>,
<<?Pos(92,76) <<?Pos(96,76)
"Values of type `(address * int)` are not comparable by equality">>, "Values of type `(address * int)` are not comparable by equality">>,
<<?Pos(96,68) <<?Pos(100,68)
"Values of type `list((int, char) => bool)` are not comparable by inequality">>, "Values of type `list((int, char) => bool)` are not comparable by inequality">>,
<<?Pos(97,68) <<?Pos(101,68)
"Values of type `list((int, char) => bool)` are not comparable by equality">>, "Values of type `list((int, char) => bool)` are not comparable by equality">>,
<<?Pos(99,74) <<?Pos(103,74)
"Values of type `option((int, char) => bool)` are not comparable by inequality">>, "Values of type `option((int, char) => bool)` are not comparable by inequality">>,
<<?Pos(100,74) <<?Pos(104,74)
"Values of type `option((int, char) => bool)` are not comparable by equality">>, "Values of type `option((int, char) => bool)` are not comparable by equality">>,
<<?Pos(102,73) <<?Pos(106,73)
"Values of type `((int, char) => bool * int)` are not comparable by inequality">>, "Values of type `((int, char) => bool * int)` are not comparable by inequality">>,
<<?Pos(103,73) <<?Pos(107,73)
"Values of type `((int, char) => bool * int)` are not comparable by equality">>, "Values of type `((int, char) => bool * int)` are not comparable by equality">>,
<<?Pos(107,71) <<?Pos(111,71)
"Values of type `map(int, int)` are not comparable by inequality">>, "Values of type `map(int, int)` are not comparable by inequality">>,
<<?Pos(110,80) <<?Pos(114,80)
"Values of type `oracle(int, int)` are not comparable by inequality">>, "Values of type `oracle(int, int)` are not comparable by inequality">>,
<<?Pos(113,98) <<?Pos(117,98)
"Values of type `oracle_query(int, int)` are not comparable by inequality">>, "Values of type `oracle_query(int, int)` are not comparable by inequality">>,
<<?Pos(116,90) <<?Pos(120,90)
"Values of type `custom_datatype(int)` are not comparable by inequality">>, "Values of type `custom_datatype(int)` are not comparable by inequality">>,
<<?Pos(119,84) <<?Pos(123,84)
"Values of type `custom_record(int)` are not comparable by inequality">>, "Values of type `custom_record(int)` are not comparable by inequality">>,
<<?Pos(124,86) <<?Pos(128,86)
"Values of type `map(address, address)` are not comparable by inequality">>, "Values of type `map(address, address)` are not comparable by inequality">>,
<<?Pos(127,95) <<?Pos(131,95)
"Values of type `oracle(address, address)` are not comparable by inequality">>, "Values of type `oracle(address, address)` are not comparable by inequality">>,
<<?Pos(130,113) <<?Pos(134,113)
"Values of type `oracle_query(address, address)` are not comparable by inequality">>, "Values of type `oracle_query(address, address)` are not comparable by inequality">>,
<<?Pos(133,97) <<?Pos(137,97)
"Values of type `custom_datatype(address)` are not comparable by inequality">>, "Values of type `custom_datatype(address)` are not comparable by inequality">>,
<<?Pos(136,91) <<?Pos(140,91)
"Values of type `custom_record(address)` are not comparable by inequality">>, "Values of type `custom_record(address)` are not comparable by inequality">>,
<<?Pos(141,75) <<?Pos(145,75)
"Values of type `map((int, char) => bool, (int, char) => bool)` are not comparable by inequality">>, "Values of type `map((int, char) => bool, (int, char) => bool)` are not comparable by inequality">>,
<<?Pos(142,75) <<?Pos(146,75)
"Values of type `map((int, char) => bool, (int, char) => bool)` are not comparable by equality">>, "Values of type `map((int, char) => bool, (int, char) => bool)` are not comparable by equality">>,
<<?Pos(144,84) <<?Pos(148,84)
"Values of type `oracle((int, char) => bool, (int, char) => bool)` are not comparable by inequality">>, "Values of type `oracle((int, char) => bool, (int, char) => bool)` are not comparable by inequality">>,
<<?Pos(145,84) <<?Pos(149,84)
"Values of type `oracle((int, char) => bool, (int, char) => bool)` are not comparable by equality">>, "Values of type `oracle((int, char) => bool, (int, char) => bool)` are not comparable by equality">>,
<<?Pos(147,102) <<?Pos(151,102)
"Values of type `oracle_query((int, char) => bool, (int, char) => bool)` are not comparable by inequality">>, "Values of type `oracle_query((int, char) => bool, (int, char) => bool)` are not comparable by inequality">>,
<<?Pos(148,102) <<?Pos(152,102)
"Values of type `oracle_query((int, char) => bool, (int, char) => bool)` are not comparable by equality">>, "Values of type `oracle_query((int, char) => bool, (int, char) => bool)` are not comparable by equality">>,
<<?Pos(150,94) <<?Pos(154,94)
"Values of type `custom_datatype((int, char) => bool)` are not comparable by inequality">>, "Values of type `custom_datatype((int, char) => bool)` are not comparable by inequality">>,
<<?Pos(151,94) <<?Pos(155,94)
"Values of type `custom_datatype((int, char) => bool)` are not comparable by equality">>, "Values of type `custom_datatype((int, char) => bool)` are not comparable by equality">>,
<<?Pos(153,88) <<?Pos(157,88)
"Values of type `custom_record((int, char) => bool)` are not comparable by inequality">>, "Values of type `custom_record((int, char) => bool)` are not comparable by inequality">>,
<<?Pos(154,88) <<?Pos(158,88)
"Values of type `custom_record((int, char) => bool)` are not comparable by equality">>, "Values of type `custom_record((int, char) => bool)` are not comparable by equality">>,
<<?Pos(158,35) <<?Pos(162,35)
"Values of type `map(int, int)` are not comparable by inequality">>, "Values of type `map(int, int)` are not comparable by inequality">>,
<<?Pos(159,35) <<?Pos(163,35)
"Values of type `('a) => 'a` are not comparable by inequality">>, "Values of type `('a) => 'a` are not comparable by inequality">>,
<<?Pos(163,34) <<?Pos(167,34)
"Values of type `('b) => 'b` are not comparable by equality">> "Values of type `('b) => 'b` are not comparable by equality">>
]) ])
, ?TYPE_ERROR(warnings, , ?TYPE_ERROR(warnings,

View File

@ -25,6 +25,10 @@ main contract C =
fail_unused_tvar : 'a is eq, 'b is eq ; ('a, 'a) => bool fail_unused_tvar : 'a is eq, 'b is eq ; ('a, 'a) => bool
fail_unused_tvar(x, y) = x == y fail_unused_tvar(x, y) = x == y
function
fail_unknown_constraint : 'a is foo ; ('a) => 'a
fail_unknown_constraint(x) = x
// Ord types // Ord types
function bool_ord(x : bool, y : bool) = x >= y // pass function bool_ord(x : bool, y : bool) = x >= y // pass