diff --git a/src/aeso_ast_infer_types.erl b/src/aeso_ast_infer_types.erl index d52144b..94a9542 100644 --- a/src/aeso_ast_infer_types.erl +++ b/src/aeso_ast_infer_types.erl @@ -1241,6 +1241,8 @@ check_type(Env, {constrained_t, Ann, Constraints, Type}, Arity) -> TVars = [ Name || {tvar, _, Name} <- extract_typevars(Type) ], [ type_error({unused_constraint, C}) || C = {constraint, _, {tvar, _, Name}, _} <- Constraints, 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)}; 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}, _}}) -> Msg = io_lib:format("The type variable `~s` is constrained but never used", [Name]), 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) -> Msg = io_lib:format("Unknown error: ~p", [Err]), mk_t_err(pos(0, 0), Msg). diff --git a/test/aeso_compiler_tests.erl b/test/aeso_compiler_tests.erl index a84eeaf..7d630ec 100644 --- a/test/aeso_compiler_tests.erl +++ b/test/aeso_compiler_tests.erl @@ -810,83 +810,85 @@ failing_contracts() -> , ?TYPE_ERROR(comparable_typevar_constraints, [<>, - <>, - <>, + <>, - <>, - <>, - < bool` are not comparable by inequality">>, - < bool` are not comparable by equality">>, - <>, - <>, - <>, - <>, - < bool)` are not comparable by inequality">>, - < bool)` are not comparable by equality">>, - < bool)` are not comparable by inequality">>, - < bool)` are not comparable by equality">>, - < bool * int)` are not comparable by inequality">>, - < bool * int)` are not comparable by equality">>, - <>, - <>, - <>, - <>, - <>, - <>, - <>, - <>, - <>, - <>, - < bool, (int, char) => bool)` are not comparable by inequality">>, - < bool, (int, char) => bool)` are not comparable by equality">>, - < bool, (int, char) => bool)` are not comparable by inequality">>, - < bool, (int, char) => bool)` are not comparable by equality">>, - < bool, (int, char) => bool)` are not comparable by inequality">>, - < bool, (int, char) => bool)` are not comparable by equality">>, - < bool)` are not comparable by inequality">>, - < bool)` are not comparable by equality">>, - < bool)` are not comparable by inequality">>, - < bool)` are not comparable by equality">>, - <>, - < 'a` are not comparable by inequality">>, - < 'b` are not comparable by equality">> ]) , ?TYPE_ERROR(warnings, diff --git a/test/contracts/comparable_typevar_constraints.aes b/test/contracts/comparable_typevar_constraints.aes index 11e98fb..852ab5a 100644 --- a/test/contracts/comparable_typevar_constraints.aes +++ b/test/contracts/comparable_typevar_constraints.aes @@ -7,12 +7,12 @@ main contract C = // pass function - passing_ord: 'a is ord ; ('a, 'a) => bool + passing_ord : 'a is ord ; ('a, 'a) => bool passing_ord(x, y) = x >= y // pass function - passing_eq: 'a is eq ; ('a, 'a) => bool + passing_eq : 'a is eq ; ('a, 'a) => bool passing_eq(x, y) = x == y // fail because eq is not specified for 'a @@ -22,9 +22,13 @@ main contract C = // fail because 'b is not used 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 + function + fail_unknown_constraint : 'a is foo ; ('a) => 'a + fail_unknown_constraint(x) = x + // Ord types function bool_ord(x : bool, y : bool) = x >= y // pass