Add test for unknown tvar constraints
This commit is contained in:
parent
fc08fe09a5
commit
2d17ce3ee2
@ -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).
|
||||||
|
@ -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,
|
||||||
|
@ -7,12 +7,12 @@ main contract C =
|
|||||||
|
|
||||||
// pass
|
// pass
|
||||||
function
|
function
|
||||||
passing_ord: 'a is ord ; ('a, 'a) => bool
|
passing_ord : 'a is ord ; ('a, 'a) => bool
|
||||||
passing_ord(x, y) = x >= y
|
passing_ord(x, y) = x >= y
|
||||||
|
|
||||||
// pass
|
// pass
|
||||||
function
|
function
|
||||||
passing_eq: 'a is eq ; ('a, 'a) => bool
|
passing_eq : 'a is eq ; ('a, 'a) => bool
|
||||||
passing_eq(x, y) = x == y
|
passing_eq(x, y) = x == y
|
||||||
|
|
||||||
// fail because eq is not specified for 'a
|
// fail because eq is not specified for 'a
|
||||||
@ -22,9 +22,13 @@ main contract C =
|
|||||||
|
|
||||||
// fail because 'b is not used
|
// fail because 'b is not used
|
||||||
function
|
function
|
||||||
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
|
||||||
|
Loading…
x
Reference in New Issue
Block a user