[m-rev.] for review: improve check for invalid invalid declarations
Peter Ross
pro at missioncriticalit.com
Tue Oct 2 14:32:30 AEST 2007
On Fri, Sep 28, 2007 at 06:32:28PM +1000, Mark Brown wrote:
> On 28-Sep-2007, Peter Ross <pro at missioncriticalit.com> wrote:
> > On 9/28/07, Mark Brown <mark at csse.unimelb.edu.au> wrote:
> > > On 28-Sep-2007, Peter Ross <pro at missioncriticalit.com> wrote:
> > > >
> > > > For juliensf or pwa to review.
> > > >
> > > > ===================================================================
> > > >
> > > >
> > > > Estimated hours taken: 4
> > > > Branches: main
> > > >
> > > > Improve check for invalid instance declarations.
> > > >
> > > > compiler/check_typeclass.m:
> > > > Check that each type in the instance declaration is a type with
> > > > no arguments of a polymorphic type whose arguments are all distinct
> > > > type variables.
> > >
> > > Hmm, there is already code to check this in parse_underived_instance_2
> > > in prog_io_typeclass.m. I'm a bit puzzled why it apparently isn't working.
> > > Any clue?
> > >
> > because at that point it doesn't know anything about equivalence types.
>
> Ah, right. I knew its error messages weren't that good, but I didn't
> know it was also missing some cases. You should remove the check during
> parsing, and update any further test cases.
>
> >
> > > In any case, putting the check in the front end pass is a good idea, and
> > > is better than checking during parsing, IMHO.
>
Here is the updated diff.
I've removed the checking during parsing, and updated the error
messages.
===================================================================
Estimated hours taken: 8
Branches: main
Improve the detection of invalid instance declarations by doing the check
during hlds checking rather than parsing, as we have more information then.
compiler/check_typeclass.m:
Add check_instance_declaration_types/4, where we check that each type
the instance declaration must be either a type with no arguments, a
polymorphic type whose arguments are all distinct type variables.
compiler/error_util.m:
Add nth_fixed to format_component which returns "first", "second",
"third", "4th" depending on the given integer.
compiler/prog_io_typeclass.m:
Remove the invalid instance check during parsing.
compiler/type_util.m:
Fix a spelling mistake.
tests/hard_coded/typeclasses/fundeps_1.m:
tests/hard_coded/typeclasses/fundeps_2.m:
tests/invalid/ambiguous_method.m:
tests/invalid/ambiguous_method_2.m:
Fix invalid instance declarations.
tests/invalid/bad_instance.err_exp:
tests/invalid/instance_dup_var.err_exp:
Update to the new error messages.
tests/invalid/Mmakefile:
tests/invalid/invalid_instance_declarations.err_exp:
tests/invalid/invalid_instance_declarations.m:
Add a check where we use equivalence types to
hide invalid typeclass declarations.
Index: compiler/check_typeclass.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/check_typeclass.m,v
retrieving revision 1.113
diff -u -r1.113 check_typeclass.m
--- compiler/check_typeclass.m 25 Sep 2007 04:56:37 -0000 1.113
+++ compiler/check_typeclass.m 2 Oct 2007 04:11:32 -0000
@@ -70,6 +70,10 @@
% generated, we should add the concrete definitions before this pass to
% ensure that they get checked.
%
+% Fifth, in check_instance_declaration_types/4, we check that each type
+% in the instance declaration must be either a type with no arguments,
+% or a polymorphic type whose arguments are all distinct type variables.
+%
% Last, in check_typeclass_constraints/4, we check typeclass constraints on
% predicate and function declarations and on existentially typed data
% constructors for ambiguity, taking into consideration the information
@@ -101,6 +105,7 @@
:- implementation.
:- import_module check_hlds.typeclasses.
+:- import_module check_hlds.type_util.
:- import_module hlds.hlds_code_util.
:- import_module hlds.hlds_data.
:- import_module hlds.hlds_error_util.
@@ -122,6 +127,7 @@
:- import_module parse_tree.prog_util.
:- import_module bool.
+:- import_module int.
:- import_module map.
:- import_module maybe.
:- import_module multi_map.
@@ -165,8 +171,14 @@
check_functional_dependencies(!ModuleInfo, !Specs),
trace [io(!IO5)] (
- maybe_write_string(Verbose, "% Checking typeclass constraints...\n",
- !IO5)
+ maybe_write_string(Verbose,
+ "% Checking instance declaration types...\n", !IO5)
+ ),
+ check_instance_declaration_types(!ModuleInfo, !Specs),
+
+ trace [io(!IO6)] (
+ maybe_write_string(Verbose, "% Checking typeclass constraints...\n",
+ !IO6)
),
check_typeclass_constraints(!ModuleInfo, !Specs).
@@ -1214,6 +1226,189 @@
;
true
).
+
+%---------------------------------------------------------------------------%
+
+ % In check_instance_declaration_types/4, we check that each type
+ % in the instance declaration must be either a type with no arguments,
+ % or a polymorphic type whose arguments are all distinct type variables.
+ %
+:- pred check_instance_declaration_types(module_info::in, module_info::out,
+ list(error_spec)::in, list(error_spec)::out) is det.
+
+check_instance_declaration_types(!ModuleInfo, !Specs) :-
+ module_info_get_instance_table(!.ModuleInfo, InstanceTable),
+ map.foldl(check_instance_declaration_types(!.ModuleInfo),
+ InstanceTable, !Specs).
+
+:- pred check_instance_declaration_types(module_info::in,
+ class_id::in, list(hlds_instance_defn)::in,
+ list(error_spec)::in, list(error_spec)::out) is det.
+
+check_instance_declaration_types(MI, ClassId, InstanceDefns, !Specs) :-
+ list.foldl(check_one_instance_declaration_types(MI, ClassId),
+ InstanceDefns, !Specs).
+
+:- pred check_one_instance_declaration_types(module_info::in,
+ class_id::in, hlds_instance_defn::in,
+ list(error_spec)::in, list(error_spec)::out) is det.
+
+check_one_instance_declaration_types(MI, ClassId, InstanceDefn, !Specs) :-
+ Types = InstanceDefn ^ instance_types,
+ list.foldl3(is_valid_instance_type(MI, ClassId, InstanceDefn),
+ Types, 1, _, set.init, _, !Specs).
+
+ %
+ % Each of these types in the instance declaration must be either a
+ % type with no arguments, or a polymorphic type whose arguments are
+ % all distinct type variables.
+ %
+:- pred is_valid_instance_type(module_info::in,
+ class_id::in, hlds_instance_defn::in, mer_type::in,
+ int::in, int::out, set(mer_type)::in, set(mer_type)::out,
+ list(error_spec)::in, list(error_spec)::out) is det.
+
+is_valid_instance_type(_MI, _ClassId, _InstanceDefn,
+ builtin_type(_), N, N+1, !SeenTypes, !Specs).
+is_valid_instance_type(_MI, ClassId, InstanceDefn,
+ higher_order_type(_, _, _, _), N, N+1, !SeenTypes, !Specs) :-
+ Err = [words("is a higher order type")],
+ Spec = error_message_2(ClassId, InstanceDefn, N, Err),
+ !:Specs = [Spec | !.Specs].
+is_valid_instance_type(_MI, ClassId, InstanceDefn,
+ tuple_type(Args, _), N, N+1, !SeenTypes, !Specs) :-
+ each_arg_is_a_distinct_type_variable(!.SeenTypes, Args, 1, Result),
+ (
+ Result = no_error,
+ svset.insert_list(Args, !SeenTypes)
+ ;
+ ( Result = local_non_distinct
+ ; Result = global_non_distinct
+ ; Result = arg_not_type_variable(_)
+ ),
+ Spec = error_message(ClassId, InstanceDefn, N, Result),
+ !:Specs = [Spec | !.Specs]
+ ).
+is_valid_instance_type(_MI, ClassId, InstanceDefn,
+ apply_n_type(_, _, _), N, N+1, !SeenTypes, !Specs) :-
+ Err = [words("is a apply/N type")],
+ Spec = error_message_2(ClassId, InstanceDefn, N, Err),
+ !:Specs = [Spec | !.Specs].
+is_valid_instance_type(_MI, _ClassId, _InstanceDefn,
+ kinded_type(_, _), N, N+1, !SeenTypes, !Specs) :-
+ unexpected("check_typeclass", "kinded_type").
+is_valid_instance_type(_MI, ClassId, InstanceDefn,
+ type_variable(_, _), N, N+1, !SeenTypes, !Specs) :-
+ Err = [words("is a type variable")],
+ Spec = error_message_2(ClassId, InstanceDefn, N, Err),
+ !:Specs = [Spec | !.Specs].
+is_valid_instance_type(MI, ClassId, InstanceDefn,
+ Type @ defined_type(_, Args, _), N, N+1, !SeenTypes, !Specs) :-
+ each_arg_is_a_distinct_type_variable(!.SeenTypes, Args, 1, Result),
+ (
+ Result = no_error,
+ svset.insert_list(Args, !SeenTypes),
+ (
+ type_to_type_defn(MI, Type, TypeDefn),
+ get_type_defn_body(TypeDefn, TypeBody),
+ TypeBody = hlds_eqv_type(EqvType)
+ ->
+ is_valid_instance_type(MI,
+ ClassId, InstanceDefn, EqvType, N, _, !SeenTypes, !Specs)
+ ;
+ true
+ )
+ ;
+ ( Result = local_non_distinct
+ ; Result = global_non_distinct
+ ; Result = arg_not_type_variable(_)
+ ),
+ Spec = error_message(ClassId, InstanceDefn, N, Result),
+ !:Specs = [Spec | !.Specs]
+ ).
+
+
+:- type instance_arg_result
+ ---> no_error
+ ; local_non_distinct
+ ; global_non_distinct
+ ; arg_not_type_variable(int)
+ .
+
+:- inst instance_arg_result_error
+ ---> local_non_distinct
+ ; global_non_distinct
+ ; arg_not_type_variable(ground)
+ .
+
+
+:- pred each_arg_is_a_distinct_type_variable(set(mer_type)::in,
+ list(mer_type)::in, int::in, instance_arg_result::out) is det.
+
+each_arg_is_a_distinct_type_variable(_, [], _, no_error).
+each_arg_is_a_distinct_type_variable(SeenTypes, [Type | Types], N, Result) :-
+ ( Type = type_variable(_, _) ->
+ ( Type `list.member` Types ->
+ Result = local_non_distinct
+ ; Type `set.member` SeenTypes ->
+ Result = global_non_distinct
+ ;
+ each_arg_is_a_distinct_type_variable(SeenTypes, Types, N+1, Result)
+ )
+ ;
+ Result = arg_not_type_variable(N)
+ ).
+
+:- func error_message(class_id::in, hlds_instance_defn::in, int::in,
+ instance_arg_result::in(instance_arg_result_error))
+ = (error_spec::out) is det.
+
+error_message(ClassId, InstanceDefn, N, Error) = Spec :-
+ (
+ Error = local_non_distinct,
+ Err =
+ [words("is not a type whose arguments are distinct type variables")]
+ ;
+ Error = global_non_distinct,
+ Err = [words("contains a type variable which is used in another arg")]
+ ;
+ Error = arg_not_type_variable(ArgNum),
+ Err = [
+ words("is a type whose"), nth_fixed(ArgNum),
+ words("arg is not a variable")]
+ ),
+ Spec = error_message_2(ClassId, InstanceDefn, N, Err).
+
+:- func error_message_2(
+ class_id, hlds_instance_defn, int, format_components) = error_spec.
+
+error_message_2(ClassId, InstanceDefn, N, Pieces) = Spec :-
+ ClassId = class_id(ClassName, _),
+ ClassNameString = sym_name_to_string(ClassName),
+
+ InstanceVarSet = InstanceDefn ^ instance_tvarset,
+ InstanceTypes = InstanceDefn ^ instance_types,
+ InstanceContext = InstanceDefn ^ instance_context,
+ InstanceTypesString = mercury_type_list_to_string(InstanceVarSet,
+ InstanceTypes),
+
+ HeaderPieces =
+ [words("In instance declaration for"),
+ words("`" ++ ClassNameString ++
+ "(" ++ InstanceTypesString ++ ")':")
+ ],
+
+ VerbosePieces =
+ [words("types in instance declarations must be functors " ++
+ "with distinct variables as arguments")],
+
+ ArgNumPieces = [words("the"), nth_fixed(N), words("arg") | Pieces],
+
+ HeadingMsg = simple_msg(InstanceContext,
+ [always(HeaderPieces), always(ArgNumPieces),
+ verbose_only(VerbosePieces)]),
+ Spec = error_spec(severity_error, phase_type_check, [HeadingMsg]).
+
%---------------------------------------------------------------------------%
% Look for pred or func declarations for which the type variables in
Index: compiler/error_util.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/error_util.m,v
retrieving revision 1.64
diff -u -r1.64 error_util.m
--- compiler/error_util.m 31 Jul 2007 03:53:30 -0000 1.64
+++ compiler/error_util.m 2 Oct 2007 04:11:32 -0000
@@ -265,6 +265,11 @@
; int_fixed(int) % Convert the integer to a string, then treat
% as fixed.
+ ; nth_fixed(int) % Convert the integer to a string, such as
+ % "first", "second", "third", "4th", "5th" and
+ % then treat as fixed.
+ %
+
; prefix(string) % This string should appear in the output
% in one piece, as it is, inserted directly
% before the next format_component, without
@@ -958,6 +963,9 @@
Component = int_fixed(Int),
Str = join_string_and_tail(int_to_string(Int), Components, TailStr)
;
+ Component = nth_fixed(Int),
+ Str = join_string_and_tail(nth_fixed_str(Int), Components, TailStr)
+ ;
Component = prefix(Word),
Str = Word ++ TailStr
;
@@ -1004,6 +1012,19 @@
Str = "\n\n" ++ TailStr
).
+:- func nth_fixed_str(int) = string.
+
+nth_fixed_str(N) =
+ ( N = 1 ->
+ "first"
+ ; N = 2 ->
+ "second"
+ ; N = 3 ->
+ "third"
+ ;
+ int_to_string(N) ++ "th"
+ ).
+
:- func join_string_and_tail(string, list(format_component), string) = string.
join_string_and_tail(Word, Components, TailStr) = Str :-
@@ -1056,6 +1077,9 @@
Component = int_fixed(Int),
RevWords1 = [plain_word(int_to_string(Int)) | RevWords0]
;
+ Component = nth_fixed(Int),
+ RevWords1 = [plain_word(nth_fixed_str(Int)) | RevWords0]
+ ;
Component = prefix(Word),
RevWords1 = [prefix_word(Word) | RevWords0]
;
Index: compiler/prog_io_typeclass.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/prog_io_typeclass.m,v
retrieving revision 1.59
diff -u -r1.59 prog_io_typeclass.m
--- compiler/prog_io_typeclass.m 19 Jan 2007 07:04:28 -0000 1.59
+++ compiler/prog_io_typeclass.m 2 Oct 2007 04:11:32 -0000
@@ -598,67 +598,10 @@
maybe1(item)::out) is det.
parse_underived_instance_2(_, _, error1(Errors), _, _, error1(Errors)).
-parse_underived_instance_2(ErrorTerm, ClassName, ok1(Types), TVarSet,
+parse_underived_instance_2(_, ClassName, ok1(Types), TVarSet,
ModuleName, Result) :-
- (
- % Check that each type in the arguments of the instance decl
- % is a functor with vars as args...
- all [Type] (
- list.member(Type, Types)
- =>
- type_is_functor_and_vars(Type)
- ),
- % ...and that the vars are distinct across the entire arg list.
- type_vars_are_distinct(Types)
- ->
- Result = ok1(item_instance([], ClassName, Types,
- instance_body_abstract, TVarSet, ModuleName))
- ;
- Msg = "types in instance declarations must be functors " ++
- "with distinct variables as arguments",
- Result = error1([Msg - ErrorTerm])
- ).
-
-:- pred type_is_functor_and_vars(mer_type::in) is semidet.
-
-type_is_functor_and_vars(defined_type(_, Args, _)) :-
- functor_args_are_variables(Args).
-type_is_functor_and_vars(builtin_type(_)).
-type_is_functor_and_vars(higher_order_type(Args, MaybeRet, Purity,
- EvalMethod)) :-
- % XXX We currently allow pred types to be instance arguments, but not
- % func types. Even then, the pred type must be pure and have a
- % lambda_eval_method of normal. We keep this behaviour basically
- % for backwards compatibility -- there is little point fixing this
- % now without fixing the more general problem of having these
- % restrictions in the first place.
- MaybeRet = no,
- Purity = purity_pure,
- EvalMethod = lambda_normal,
- functor_args_are_variables(Args).
-type_is_functor_and_vars(tuple_type(Args, _)) :-
- functor_args_are_variables(Args).
-type_is_functor_and_vars(kinded_type(Type, _)) :-
- type_is_functor_and_vars(Type).
-
-:- pred functor_args_are_variables(list(mer_type)::in) is semidet.
-
-functor_args_are_variables(Args) :-
- all [Arg] (
- list.member(Arg, Args)
- =>
- type_is_var(Arg)
- ).
-
-:- pred type_vars_are_distinct(list(mer_type)::in) is semidet.
-
-type_vars_are_distinct(Types) :-
- promise_equivalent_solutions [NumVars, VarsWithoutDups] (
- solutions.unsorted_solutions(type_list_contains_var(Types), Vars),
- list.length(Vars, NumVars),
- list.sort_and_remove_dups(Vars, VarsWithoutDups)
- ),
- list.length(VarsWithoutDups, NumVars).
+ Result = ok1(item_instance([], ClassName, Types,
+ instance_body_abstract, TVarSet, ModuleName)).
:- pred parse_non_empty_instance(module_name::in, term::in, term::in,
varset::in, tvarset::in, maybe1(item)::out) is det.
Index: compiler/type_util.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/type_util.m,v
retrieving revision 1.183
diff -u -r1.183 type_util.m
--- compiler/type_util.m 25 Sep 2007 04:56:43 -0000 1.183
+++ compiler/type_util.m 2 Oct 2007 04:11:40 -0000
@@ -187,7 +187,7 @@
:- pred get_cons_id_non_existential_arg_types(module_info::in,
mer_type::in, cons_id::in, list(mer_type)::out) is semidet.
- % The same as gget_cons_id_arg_types except that the cons_id is output
+ % The same as get_cons_id_arg_types except that the cons_id is output
% non-deterministically. The cons_id is not module-qualified.
%
:- pred cons_id_arg_types(module_info::in, mer_type::in,
Index: tests/hard_coded/typeclasses/fundeps_1.m
===================================================================
RCS file: /home/mercury1/repository/tests/hard_coded/typeclasses/fundeps_1.m,v
retrieving revision 1.1
diff -u -r1.1 fundeps_1.m
--- tests/hard_coded/typeclasses/fundeps_1.m 20 Apr 2005 12:57:36 -0000 1.1
+++ tests/hard_coded/typeclasses/fundeps_1.m 2 Oct 2007 04:11:43 -0000
@@ -7,7 +7,7 @@
main(!S) :-
(
- test([0], 1)
+ test(intcoll([0]), 1)
->
write_string("yes\n", !S)
;
@@ -20,13 +20,13 @@
pred m(E::in, C::in) is semidet
].
-:- type intcoll == list(int).
+:- type intcoll ---> intcoll(list(int)).
:- instance coll(intcoll, int) where [
- (e = []),
- (i(Ns, N) = [N | Ns]),
- m(N, [N | _]),
- m(N, [_ | Ns]) :- m(N, Ns)
+ (e = intcoll([])),
+ (i(intcoll(Ns), N) = intcoll([N | Ns])),
+ m(N, intcoll([N | _])),
+ m(N, intcoll([_ | Ns])) :- m(N, intcoll(Ns))
].
:- pred test(C, E) <= coll(C, E).
Index: tests/hard_coded/typeclasses/fundeps_2.m
===================================================================
RCS file: /home/mercury1/repository/tests/hard_coded/typeclasses/fundeps_2.m,v
retrieving revision 1.1
diff -u -r1.1 fundeps_2.m
--- tests/hard_coded/typeclasses/fundeps_2.m 20 Apr 2005 12:57:36 -0000 1.1
+++ tests/hard_coded/typeclasses/fundeps_2.m 2 Oct 2007 04:11:43 -0000
@@ -7,14 +7,14 @@
main(!S) :-
(
- test([0], 1)
+ test(intcoll([0]), 1)
->
write_string("yes\n", !S)
;
write_string("no\n", !S)
),
(
- e = [1]
+ e = intcoll([1])
->
write_string("yes\n", !S)
;
@@ -30,13 +30,13 @@
pred m(E::in, C::in) is semidet
].
-:- type intcoll == list(int).
+:- type intcoll ---> intcoll(list(int)).
:- instance coll(intcoll, int) where [
- (e = []),
- (i(Ns, N) = [N | Ns]),
- m(N, [N | _]),
- m(N, [_ | Ns]) :- m(N, Ns)
+ (e = intcoll([])),
+ (i(intcoll(Ns), N) = intcoll([N | Ns])),
+ m(N, intcoll([N | _])),
+ m(N, intcoll([_ | Ns])) :- m(N, intcoll(Ns))
].
:- pred test(C, E) <= coll(C, E).
Index: tests/invalid/Mmakefile
===================================================================
RCS file: /home/mercury1/repository/tests/invalid/Mmakefile,v
retrieving revision 1.221
diff -u -r1.221 Mmakefile
--- tests/invalid/Mmakefile 3 Sep 2007 11:44:07 -0000 1.221
+++ tests/invalid/Mmakefile 2 Oct 2007 04:11:43 -0000
@@ -114,6 +114,7 @@
invalid_event \
invalid_export_detism \
invalid_import_detism \
+ invalid_instance_declarations \
invalid_main \
invalid_mllibs \
invalid_new \
Index: tests/invalid/ambiguous_method.m
===================================================================
RCS file: /home/mercury1/repository/tests/invalid/ambiguous_method.m,v
retrieving revision 1.1
diff -u -r1.1 ambiguous_method.m
--- tests/invalid/ambiguous_method.m 20 Apr 2005 12:57:44 -0000 1.1
+++ tests/invalid/ambiguous_method.m 2 Oct 2007 04:11:43 -0000
@@ -7,7 +7,7 @@
main(!S) :-
(
- test([0], 1)
+ test(intcoll([0]), 1)
->
write_string("yes\n", !S)
;
@@ -20,13 +20,13 @@
pred m(E::in, C::in) is semidet
].
-:- type intcoll == list(int).
+:- type intcoll ---> intcoll(list(int)).
:- instance coll(intcoll, int) where [
- (e = []),
- (i(Ns, N) = [N | Ns]),
- m(N, [N | _]),
- m(N, [_ | Ns]) :- m(N, Ns)
+ (e = intcoll([])),
+ (i(intcoll(Ns), N) = intcoll([N | Ns])),
+ m(N, intcoll([N | _])),
+ m(N, intcoll([_ | Ns])) :- m(N, intcoll(Ns))
].
:- pred test(C, E) <= coll(C, E).
Index: tests/invalid/ambiguous_method_2.m
===================================================================
RCS file: /home/mercury1/repository/tests/invalid/ambiguous_method_2.m,v
retrieving revision 1.1
diff -u -r1.1 ambiguous_method_2.m
--- tests/invalid/ambiguous_method_2.m 20 Apr 2005 12:57:44 -0000 1.1
+++ tests/invalid/ambiguous_method_2.m 2 Oct 2007 04:11:43 -0000
@@ -7,14 +7,14 @@
main(!S) :-
(
- test([0], 1)
+ test(intcoll([0]), 1)
->
write_string("yes\n", !S)
;
write_string("no\n", !S)
),
(
- e = [1]
+ e = intcoll([1])
->
write_string("yes\n", !S)
;
@@ -30,13 +30,13 @@
pred m(E::in, C::in) is semidet
].
-:- type intcoll == list(int).
+:- type intcoll ---> intcoll(list(int)).
:- instance coll(intcoll, int) where [
- (e = []),
- (i(Ns, N) = [N | Ns]),
- m(N, [N | _]),
- m(N, [_ | Ns]) :- m(N, Ns)
+ (e = intcoll([])),
+ (i(intcoll(Ns), N) = intcoll([N | Ns])),
+ m(N, intcoll([N | _])),
+ m(N, intcoll([_ | Ns])) :- m(N, intcoll(Ns))
].
:- pred test(C, E) <= coll(C, E).
Index: tests/invalid/bad_instance.err_exp
===================================================================
RCS file: /home/mercury1/repository/tests/invalid/bad_instance.err_exp,v
retrieving revision 1.2
diff -u -r1.2 bad_instance.err_exp
--- tests/invalid/bad_instance.err_exp 14 Sep 2005 05:26:42 -0000 1.2
+++ tests/invalid/bad_instance.err_exp 2 Oct 2007 04:11:43 -0000
@@ -1,2 +1,10 @@
-bad_instance.m:005: Error: types in instance declarations must be functors with distinct variables as arguments: foo(bar(_1), _2).
-bad_instance.m:011: Error: types in instance declarations must be functors with distinct variables as arguments: foo(bar(_1), _1).
+bad_instance.m:005: Error: abstract instance declaration for
+bad_instance.m:005: `bad_instance.foo((bad_instance.bar(T)), U)' has no
+bad_instance.m:005: corresponding concrete instance in the implementation.
+bad_instance.m:005: In instance declaration for
+bad_instance.m:005: `bad_instance.foo((bad_instance.bar(T)), U)':
+bad_instance.m:005: the second arg is a type variable
+bad_instance.m:011: In instance declaration for
+bad_instance.m:011: `bad_instance.foo((bad_instance.bar(T)), T)':
+bad_instance.m:011: the second arg is a type variable
+For more information, recompile with `-E'.
Index: tests/invalid/instance_dup_var.err_exp
===================================================================
RCS file: /home/mercury1/repository/tests/invalid/instance_dup_var.err_exp,v
retrieving revision 1.1
diff -u -r1.1 instance_dup_var.err_exp
--- tests/invalid/instance_dup_var.err_exp 19 Oct 2006 07:29:54 -0000 1.1
+++ tests/invalid/instance_dup_var.err_exp 2 Oct 2007 04:11:43 -0000
@@ -1,2 +1,11 @@
-instance_dup_var.m:012: Error: types in instance declarations must be functors with distinct variables as arguments: baz(foo(_1, _1), bar).
-instance_dup_var.m:015: Error: types in instance declarations must be functors with distinct variables as arguments: baz(foo(_1, _2), foo(_3, _1)).
+instance_dup_var.m:012: In instance declaration for
+instance_dup_var.m:012: `instance_dup_var.baz((instance_dup_var.foo(T, T)),
+instance_dup_var.m:012: (instance_dup_var.bar))':
+instance_dup_var.m:012: the first arg is not a type whose arguments are
+instance_dup_var.m:012: distinct type variables
+instance_dup_var.m:015: In instance declaration for
+instance_dup_var.m:015: `instance_dup_var.baz((instance_dup_var.foo(A, B)),
+instance_dup_var.m:015: (instance_dup_var.foo(C, A)))':
+instance_dup_var.m:015: the second arg contains a type variable which is used
+instance_dup_var.m:015: in another arg
+For more information, recompile with `-E'.
Index: tests/invalid/invalid_instance_declarations.err_exp
===================================================================
RCS file: tests/invalid/invalid_instance_declarations.err_exp
diff -N tests/invalid/invalid_instance_declarations.err_exp
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ tests/invalid/invalid_instance_declarations.err_exp 2 Oct 2007 04:11:43 -0000
@@ -0,0 +1,19 @@
+invalid_instance_declarations.m:015: In instance declaration for
+invalid_instance_declarations.m:015: `invalid_instance_declarations.tc((invalid_instance_declarations.t(T,
+invalid_instance_declarations.m:015: T)))':
+invalid_instance_declarations.m:015: the first arg is not a type whose
+invalid_instance_declarations.m:015: arguments are distinct type variables
+invalid_instance_declarations.m:016: In instance declaration for
+invalid_instance_declarations.m:016: `invalid_instance_declarations.tc(((func)
+invalid_instance_declarations.m:016: = T))':
+invalid_instance_declarations.m:016: the first arg is a higher order type
+invalid_instance_declarations.m:017: In instance declaration for
+invalid_instance_declarations.m:017: `invalid_instance_declarations.tc({T,
+invalid_instance_declarations.m:017: T})':
+invalid_instance_declarations.m:017: the first arg is not a type whose
+invalid_instance_declarations.m:017: arguments are distinct type variables
+invalid_instance_declarations.m:018: In instance declaration for
+invalid_instance_declarations.m:018: `invalid_instance_declarations.tc((invalid_instance_declarations.t(int)))':
+invalid_instance_declarations.m:018: the first arg is a type whose first arg
+invalid_instance_declarations.m:018: is not a variable
+For more information, recompile with `-E'.
Index: tests/invalid/invalid_instance_declarations.m
===================================================================
RCS file: tests/invalid/invalid_instance_declarations.m
diff -N tests/invalid/invalid_instance_declarations.m
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ tests/invalid/invalid_instance_declarations.m 2 Oct 2007 04:11:43 -0000
@@ -0,0 +1,18 @@
+:- module invalid_instance_declarations.
+:- interface.
+
+:- type t(T) ---> f(T).
+:- type t(T, U) ---> f(T, U).
+
+:- typeclass tc(T) where [].
+
+:- type e(T) == t(T, T).
+:- type f(T) == ((func) = T).
+:- type g(T) == {T, T}.
+:- type h == t(int).
+
+:- implementation.
+:- instance tc(e(T)) where [].
+:- instance tc(f(T)) where [].
+:- instance tc(g(T)) where [].
+:- instance tc(h) where [].
--------------------------------------------------------------------------
mercury-reviews mailing list
Post messages to: mercury-reviews at csse.unimelb.edu.au
Administrative Queries: owner-mercury-reviews at csse.unimelb.edu.au
Subscriptions: mercury-reviews-request at csse.unimelb.edu.au
--------------------------------------------------------------------------
More information about the reviews
mailing list