[m-rev.] for review: improve error reporting for typeclass decls

Julien Fischer juliensf at cs.mu.OZ.AU
Fri Jan 6 16:06:17 AEDT 2006


For review by anyone.

Estimated hours taken: 10
Branches: main

Improve error reporting for type class declarations in the situation where a
mode declaration for a method has been provided but there is no function or
predicate declaration for that method.  Currently, this causes an internal
abort in the compiler.

Avoid another compiler abort in polymorphism.m when a type class method has two
duplicate mode declarations.

compiler/add_class.m:
	Change the order in which we add type class declarations to the HLDS
	so that we can detect and report situations where a type class method
	has a mode declaration but no corresponding predicate or function
	declaration.  All of the predicate/function method declarations for a
	particular typeclass need to be added before any mode declarations.
	We can then check that there is a corresponding predicate/function
	method declaration as each mode is added.

compiler/post_typecheck.m:
	Have the post-typechecking pass indicate that an error has occurred if
	we encounter indistinguishable mode declarations.  This prevents
	polymorphism being run if there are such mode declarations.  This
	avoids an internal abort in polymorphism.m when the mode declarations
	in question are type class methods.

	Unrelated change: s/io.state/io__state/ in an error message.

compiler/hlds_error_util.m:
	When formatting predicate names, specifically identify type class
	methods as such.  e.g. instead of `predicate foo/1' we now
	write them out as `type class predicate method foo/1'.

compiler/modecheck_call.m:
	Fix a typo: s/identical/indentical/

compiler/prog_item.m:
	Add the equivalence: class_methods == list(class_method).

compiler/equiv_type.m:
compiler/mercury_to_mercury.m:
compiler/module_qual.m:
compiler/prog_data.m:
compiler/prog_io_typeclass.m:
compiler/recompilation.version.m:
	Minor changes to conform to the above.

tests/README:
	Fix an line that exceeds 80 characters in length.

tests/invalid/Mmakefile:
	Enable the test cases typeclass_mode_{2,3,4} since we now pass those
	tests.

	Delete a comment about `--split-c-files'.  That option is no longer
	supported.

tests/invalid/typeclass_mode_{2,3,4}.err_exp:
	Add expected outputs for these test cases.

tests/invalid/invalid_main.err_exp:
	The module qualifier in the expected output is now '.'.

tests/invalid/qualified_cons_id2.err_exp:
	Delete the determinism error from the expected output.  It won't show
	up now as the above changes mean the compiler will abort before
	determinism checking in this case.

tests/invalid/typeclass_dup_method_mode.{m,err_exp}:
	Add a test case for the problem that causes an abort in the
	polymorphism pass when a type class method has duplicate mode
	declarations.

tests/invalid/typeclass_mode.err_exp:
	Update the expected output to conform with the above changes.  Also,
	we no longer emit the spurious error message about missing clauses.

Julien.

Index: compiler/add_class.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/add_class.m,v
retrieving revision 1.10
diff -u -r1.10 add_class.m
--- compiler/add_class.m	28 Nov 2005 04:11:36 -0000	1.10
+++ compiler/add_class.m	6 Jan 2006 03:28:56 -0000
@@ -255,27 +255,106 @@
 	OldFunDeps = FunDeps.

 :- pred module_add_class_interface(sym_name::in, list(tvar)::in,
-    list(class_method)::in, item_status::in,
+    class_methods::in, item_status::in,
     list(maybe(pair(pred_id, proc_id)))::out,
     module_info::in, module_info::out, io::di, io::uo) is det.

 module_add_class_interface(Name, Vars, Methods, Status, PredProcIds,
         !ModuleInfo, !IO) :-
-    module_add_class_interface_2(Name, Vars, Methods, Status, PredProcIds0,
-        !ModuleInfo, !IO),
-    check_method_modes(Methods, PredProcIds0, PredProcIds,
-        !ModuleInfo, !IO).
+    list.filter(is_class_method_mode_item, Methods, ModeMethods,
+        PredOrFuncMethods),
+    some [!PPIds] (
+        add_class_pred_or_func_methods(Name, Vars, PredOrFuncMethods, Status,
+            !:PPIds, !ModuleInfo, !IO),
+        %
+        % Add the pred_or_func_mode decls.  Since we have already added the
+        % predicate/function method decls there should already be an entry in
+        % the predicate table corresponding to the mode item we are about to
+        % add.  If not, report an error.
+        %
+        list.foldl3(add_class_pred_or_func_mode_method(Name, Vars, Status),
+            ModeMethods, !PPIds, !ModuleInfo, !IO),
+        check_method_modes(Methods, !.PPIds, PredProcIds, !ModuleInfo, !IO)
+    ).
+
+:- pred is_class_method_mode_item(class_method::in) is semidet.
+
+is_class_method_mode_item(Method) :-
+    Method = pred_or_func_mode(_, _, _, _, _, _, _, _).
+
+:- pred add_class_pred_or_func_mode_method(sym_name::in,
+    list(tvar)::in, item_status::in, class_method::in,
+    list(maybe(pair(pred_id, proc_id)))::in,
+    list(maybe(pair(pred_id, proc_id)))::out,
+    module_info::in, module_info::out, io::di, io::uo) is det.
+
+add_class_pred_or_func_mode_method(Name, Vars, Status, Method,
+        !PredProcIds, !ModuleInfo, !IO) :-
+    (
+        Method = pred_or_func(_, _, _, _, _, _, _, _, _, _, _, _, _),
+        unexpected(this_file, "add_class_pred_or_func_mode_method: " ++
+            "pred_or_func method item")
+    ;
+        Method = pred_or_func_mode(_VarSet, MaybePredOrFunc, PredName,
+            Modes, _WithInst, _MaybeDet, _Cond, Context)
+    ),
+    module_info_get_predicate_table(!.ModuleInfo, PredTable),
+    PredArity = list.length(Modes) : int,
+    (
+        % The only way this could have happened now is if a `with_inst`
+        % annotation was not expanded.
+        %
+        MaybePredOrFunc = no,
+        unexpected(this_file, "add_class_pred_or_func_mode_method: " ++
+            "unexpanded `with_inst` annotation")
+    ;
+        MaybePredOrFunc = yes(PredOrFunc)
+    ),
+    (
+        predicate_table_search_pf_sym_arity(PredTable, is_fully_qualified,
+            PredOrFunc, PredName, PredArity, Preds),
+        Preds \= []
+    ->
+        (
+            % This case should have been caught above.
+            Preds = [],
+            unexpected(this_file, "empty list")
+        ;
+            Preds = [PredId],
+            module_info_pred_info(!.ModuleInfo, PredId, PredInfo),
+            pred_info_get_markers(PredInfo, PredMarkers),
+            ( check_marker(PredMarkers, class_method) ->
+                module_add_class_method(Method, Name, Vars, Status,
+                    PredProcId, !ModuleInfo, !IO),
+                list.cons(PredProcId, !PredProcIds)
+            ;
+                % XXX It may also be worth reporting that although there
+                % wasn't a matching class method, there was a matching
+                % predicate/function.
+                missing_pred_or_func_method_error(PredName, PredArity,
+                    PredOrFunc, Context, !ModuleInfo, !IO)
+            )
+        ;
+            % This shouldn't happen.
+            Preds = [_, _ | _],
+            unexpected(this_file, "multiple preds matching method mode")
+        )
+    ;
+        missing_pred_or_func_method_error(PredName, PredArity,
+            PredOrFunc, Context, !ModuleInfo, !IO)
+    ).

-:- pred module_add_class_interface_2(sym_name::in, list(tvar)::in,
-    list(class_method)::in, item_status::in,
+:- pred add_class_pred_or_func_methods(sym_name::in, list(tvar)::in,
+    class_methods::in, item_status::in,
     list(maybe(pair(pred_id, proc_id)))::out,
     module_info::in, module_info::out, io::di, io::uo) is det.

-module_add_class_interface_2(_, _, [], _, [], !ModuleInfo, !IO).
-module_add_class_interface_2(Name, Vars, [M | Ms], Status, [P | Ps],
+add_class_pred_or_func_methods(_, _, [], _, [], !ModuleInfo, !IO).
+add_class_pred_or_func_methods(Name, Vars, [M | Ms], Status, [P | Ps],
         !ModuleInfo, !IO) :-
     module_add_class_method(M, Name, Vars, Status, P, !ModuleInfo, !IO),
-    module_add_class_interface_2(Name, Vars, Ms, Status, Ps, !ModuleInfo, !IO).
+    add_class_pred_or_func_methods(Name, Vars, Ms, Status, Ps, !ModuleInfo,
+        !IO).

 :- pred module_add_class_method(class_method::in, sym_name::in, list(tvar)::in,
     item_status::in, maybe(pair(pred_id, proc_id))::out,
@@ -345,7 +424,7 @@
     % - predicates without mode declarations: report an error
     % - mode declarations with no determinism: report an error
     %
-:- pred check_method_modes(list(class_method)::in,
+:- pred check_method_modes(class_methods::in,
     list(maybe(pair(pred_id, proc_id)))::in,
     list(maybe(pair(pred_id, proc_id)))::out,
     module_info::in, module_info::out, io::di, io::uo) is det.
@@ -560,7 +639,7 @@
     write_error_pieces(Context, 0, Pieces, !IO),
     io__set_exit_status(1, !IO).

-:- pred undefined_type_class_error(sym_name::in, int::in, prog_context::in,
+:- pred undefined_type_class_error(sym_name::in, arity::in, prog_context::in,
     string::in, io::di, io::uo) is det.

 undefined_type_class_error(ClassName, Arity, Context, Description, !IO) :-
@@ -570,6 +649,23 @@
     write_error_pieces(Context, 0, Pieces, !IO),
     io__set_exit_status(1, !IO).

+:- pred missing_pred_or_func_method_error(sym_name::in, arity::in,
+    pred_or_func::in, prog_context::in, module_info::in, module_info::out,
+    io::di, io::uo) is det.
+
+missing_pred_or_func_method_error(Name, Arity, PredOrFunc, Context,
+        !ModuleInfo, !IO) :-
+    NoPredOrFuncMsg = [
+        words("Error: mode declaration for type class method"),
+        sym_name_and_arity(Name / Arity),
+        words("without corresponding"),
+        pred_or_func(PredOrFunc),
+        words("method declaration.")
+    ],
+    write_error_pieces(Context, 0, NoPredOrFuncMsg, !IO),
+    io.set_exit_status(1, !IO),
+    module_info_incr_errors(!ModuleInfo).
+
 %-----------------------------------------------------------------------------%

 :- func this_file = string.
Index: compiler/equiv_type.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/equiv_type.m,v
retrieving revision 1.57
diff -u -r1.57 equiv_type.m
--- compiler/equiv_type.m	23 Nov 2005 05:11:39 -0000	1.57
+++ compiler/equiv_type.m	4 Jan 2006 06:44:25 -0000
@@ -482,8 +482,8 @@

 %-----------------------------------------------------------------------------%

-:- pred replace_in_class_interface(list(class_method)::in,
-    eqv_map::in, eqv_inst_map::in, list(class_method)::out,
+:- pred replace_in_class_interface(class_methods::in,
+    eqv_map::in, eqv_inst_map::in, class_methods::out,
     list(eqv_error)::in, list(eqv_error)::out,
     equiv_type_info::in, equiv_type_info::out) is det.

Index: compiler/hlds_error_util.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/hlds_error_util.m,v
retrieving revision 1.14
diff -u -r1.14 hlds_error_util.m
--- compiler/hlds_error_util.m	17 Nov 2005 15:57:15 -0000	1.14
+++ compiler/hlds_error_util.m	5 Jan 2006 07:20:44 -0000
@@ -96,7 +96,6 @@
     ModuleName = pred_info_module(PredInfo),
     Arity = pred_info_orig_arity(PredInfo),
     PredOrFunc = pred_info_is_pred_or_func(PredInfo),
-    PredOrFuncStr = pred_or_func_to_string(PredOrFunc),
     adjust_func_arity(PredOrFunc, OrigArity, Arity),
     pred_info_get_markers(PredInfo, Markers),
     pred_info_get_origin(PredInfo, Origin),
@@ -116,6 +115,15 @@
         Pieces = [words("`" ++ promise_to_string(PromiseType) ++ "'"),
             words("declaration")]
     ;
+        ( check_marker(Markers, class_method) ->
+            Prefix = [
+                        words("type class"),
+                        pred_or_func(PredOrFunc),
+                        words("method")
+                     ]
+        ;
+            Prefix = [pred_or_func(PredOrFunc)]
+        ),
         string__int_to_string(OrigArity, ArityPart),
         string__append_list([
             "`",
@@ -124,7 +132,7 @@
             "/",
             ArityPart,
             "'"], SpecStr),
-        Pieces = [words(PredOrFuncStr), fixed(SpecStr)]
+        Pieces = Prefix ++ [fixed(SpecStr)]
     ).

 describe_one_pred_name_mode(Module, ShouldModuleQualify, PredId, InstVarSet,
Index: compiler/mercury_to_mercury.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/mercury_to_mercury.m,v
retrieving revision 1.277
diff -u -r1.277 mercury_to_mercury.m
--- compiler/mercury_to_mercury.m	28 Nov 2005 04:11:46 -0000	1.277
+++ compiler/mercury_to_mercury.m	4 Jan 2006 06:44:42 -0000
@@ -807,7 +807,7 @@

 %-----------------------------------------------------------------------------%

-:- pred output_class_methods(list(class_method)::in, io::di, io::uo) is det.
+:- pred output_class_methods(class_methods::in, io::di, io::uo) is det.

 output_class_methods(Methods, !IO) :-
     io__write_list(Methods, ",\n", output_class_method, !IO).
Index: compiler/modecheck_call.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/modecheck_call.m,v
retrieving revision 1.65
diff -u -r1.65 modecheck_call.m
--- compiler/modecheck_call.m	14 Dec 2005 05:14:14 -0000	1.65
+++ compiler/modecheck_call.m	5 Jan 2006 05:38:51 -0000
@@ -541,7 +541,7 @@
     % do not count as distinguishable.
     %
     % The code for this is similar to the code for
-    % modes_are_indentical/4 and compare_proc/5 below.
+    % modes_are_identical/4 and compare_proc/5 below.
     %
 modes_are_indistinguishable(ProcId, OtherProcId, PredInfo, ModuleInfo) :-
     pred_info_procedures(PredInfo, Procs),
Index: compiler/module_qual.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/module_qual.m,v
retrieving revision 1.122
diff -u -r1.122 module_qual.m
--- compiler/module_qual.m	28 Nov 2005 04:11:49 -0000	1.122
+++ compiler/module_qual.m	4 Jan 2006 06:45:06 -0000
@@ -1178,8 +1178,8 @@
     mq_info_get_classes(!.Info, ClassIdSet),
     find_unique_match(Class0, Class, ClassIdSet, class_id, !Info, !IO).

-:- pred qualify_class_interface(list(class_method)::in,
-    list(class_method)::out, mq_info::in, mq_info::out,
+:- pred qualify_class_interface(class_methods::in,
+    class_methods::out, mq_info::in, mq_info::out,
     io::di, io::uo) is det.

 qualify_class_interface([], [], !Info, !IO).
Index: compiler/post_typecheck.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/post_typecheck.m,v
retrieving revision 1.91
diff -u -r1.91 post_typecheck.m
--- compiler/post_typecheck.m	28 Nov 2005 04:11:51 -0000	1.91
+++ compiler/post_typecheck.m	5 Jan 2006 07:08:23 -0000
@@ -50,8 +50,8 @@

 %-----------------------------------------------------------------------------%

-    % finish_preds(PredIds, ReportTypeErrors, NumErrors, FoundTypeError,
-    %   !Module):
+    % finish_preds(PredIds, ReportTypeErrors, NumErrors, FoundError,
+    %   !ModuleInfo):
     %
     % Check that all Aditi predicates have an `aditi__state' argument.
     % Check that the all of the types which have been inferred for the
@@ -62,7 +62,7 @@
     % Also bind any unbound type variables to the type `void'. Note that
     % when checking assertions we take the conservative approach of warning
     % about unbound type variables. There may be cases for which this doesn't
-    % make sense. FoundTypeError will be `yes' if there were errors which
+    % make sense. FoundError will be `yes' if there were errors which
     % should prevent further processing (e.g. polymorphism or mode analysis).
     %
 :- pred finish_preds(list(pred_id)::in, bool::in, int::out, bool::out,
@@ -162,11 +162,11 @@
 %-----------------------------------------------------------------------------%

 finish_preds(PredIds, ReportTypeErrors, NumErrors,
-        FoundTypeError, !ModuleInfo, !IO) :-
+        PostTypecheckError, !ModuleInfo, !IO) :-
     finish_preds(PredIds, ReportTypeErrors, !ModuleInfo,
-        0, NumErrors0, no, FoundTypeError0, !IO),
+        0, NumErrors0, no, PostTypecheckError0, !IO),
     check_for_missing_definitions(!.ModuleInfo, NumErrors0, NumErrors,
-        FoundTypeError0, FoundTypeError, !IO).
+        PostTypecheckError0, PostTypecheckError, !IO).

 :- pred finish_preds(list(pred_id)::in, bool::in,
     module_info::in, module_info::out, int::in, int::out,
@@ -174,7 +174,7 @@

 finish_preds([], _, !ModuleInfo, !NumErrors, !PostTypecheckError, !IO).
 finish_preds([PredId | PredIds], ReportTypeErrors, !ModuleInfo, !NumErrors,
-        !FoundTypeError, !IO) :-
+        !PostTypecheckError, !IO) :-
     some [!PredInfo] (
         module_info_pred_info(!.ModuleInfo, PredId, !:PredInfo),
         (
@@ -194,7 +194,7 @@
             % can cause internal errors in polymorphism.m if we try to
             % continue, so we need to halt compilation after this pass.
             ( UnboundTypeErrsInThisPred \= 0 ->
-                !:FoundTypeError = yes
+                !:PostTypecheckError = yes
             ;
                 true
             ),
@@ -203,7 +203,8 @@
             report_unbound_inst_vars(!.ModuleInfo, PredId, ErrorProcs,
                 !PredInfo, !IO),
             check_for_indistinguishable_modes(!.ModuleInfo, PredId,
-                !PredInfo, !IO),
+                FoundModeError, !PredInfo, !IO),
+            bool.or(FoundModeError, !PostTypecheckError),

             % Check that main/2 has the right type.
             (
@@ -230,7 +231,7 @@
         ),
         module_info_set_pred_info(PredId, !.PredInfo, !ModuleInfo),
         finish_preds(PredIds, ReportTypeErrors,
-            !ModuleInfo, !NumErrors, !FoundTypeError, !IO)
+            !ModuleInfo, !NumErrors, !PostTypecheckError, !IO)
     ).

 %-----------------------------------------------------------------------------%
@@ -658,7 +659,7 @@
 finish_ill_typed_pred(ModuleInfo, PredId, !PredInfo, !IO) :-
     propagate_types_into_modes(ModuleInfo, ErrorProcs, !PredInfo),
     report_unbound_inst_vars(ModuleInfo, PredId, ErrorProcs, !PredInfo, !IO),
-    check_for_indistinguishable_modes(ModuleInfo, PredId, !PredInfo, !IO).
+    check_for_indistinguishable_modes(ModuleInfo, PredId, _, !PredInfo, !IO).

     % For imported preds, we just need to ensure that all constructors
     % occurring in predicate mode declarations are module qualified.
@@ -681,7 +682,7 @@
     % finish_ill_typed_pred? [zs]
     finish_imported_pred_no_io(ModuleInfo, ErrorProcs, !PredInfo),
     report_unbound_inst_vars(ModuleInfo, PredId, ErrorProcs, !PredInfo, !IO),
-    check_for_indistinguishable_modes(ModuleInfo, PredId, !PredInfo, !IO).
+    check_for_indistinguishable_modes(ModuleInfo, PredId, _, !PredInfo, !IO).

 finish_imported_pred_no_io(ModuleInfo, Errors, !PredInfo) :-
     % Make sure the var-types field in the clauses_info is valid for imported
@@ -798,7 +799,7 @@
             pred_info_context(PredInfo, Context),
             error_util__write_error_pieces(Context, 0,
                 [words("Error: arguments of main/2"),
-                words("must have type `io__state'.")], !IO),
+                words("must have type `io.state'.")], !IO),
             io__set_exit_status(1, !IO)
         )
     ;
@@ -891,9 +892,10 @@
 %-----------------------------------------------------------------------------%

 :- pred check_for_indistinguishable_modes(module_info::in, pred_id::in,
-    pred_info::in, pred_info::out, io::di, io::uo) is det.
+    bool::out, pred_info::in, pred_info::out, io::di, io::uo) is det.

-check_for_indistinguishable_modes(ModuleInfo, PredId, !PredInfo, !IO) :-
+check_for_indistinguishable_modes(ModuleInfo, PredId, FoundError,
+        !PredInfo, !IO) :-
     (
         % Don't check for indistinguishable modes in unification predicates.
         % The default (in, in) mode must be semidet, but for single-value types
@@ -904,35 +906,36 @@
         pred_info_get_origin(!.PredInfo, Origin),
         Origin = special_pred(spec_pred_unify - _)
     ->
-        true
+        FoundError = no
     ;
         ProcIds = pred_info_procids(!.PredInfo),
         check_for_indistinguishable_modes(ModuleInfo, PredId,
-            ProcIds, [], !PredInfo, !IO)
+            ProcIds, [], no, FoundError, !PredInfo, !IO)
     ).

 :- pred check_for_indistinguishable_modes(module_info::in, pred_id::in,
-    list(proc_id)::in, list(proc_id)::in, pred_info::in, pred_info::out,
-    io::di, io::uo) is det.
+    list(proc_id)::in, list(proc_id)::in, bool::in, bool::out,
+    pred_info::in, pred_info::out, io::di, io::uo) is det.

-check_for_indistinguishable_modes(_, _, [], _, !PredInfo, !IO).
+check_for_indistinguishable_modes(_, _, [], _, !FoundError, !PredInfo, !IO).
 check_for_indistinguishable_modes(ModuleInfo, PredId, [ProcId | ProcIds],
-        PrevProcIds, !PredInfo, !IO) :-
+        PrevProcIds, !FoundError, !PredInfo, !IO) :-
     check_for_indistinguishable_mode(ModuleInfo, PredId, ProcId,
         PrevProcIds, Removed, !PredInfo, !IO),
     (
         Removed = yes,
+        !:FoundError = yes,
         PrevProcIds1 = PrevProcIds
     ;
         Removed = no,
         PrevProcIds1 = [ProcId | PrevProcIds]
     ),
     check_for_indistinguishable_modes(ModuleInfo, PredId, ProcIds,
-        PrevProcIds1, !PredInfo, !IO).
+        PrevProcIds1, !FoundError, !PredInfo, !IO).

 :- pred check_for_indistinguishable_mode(module_info::in, pred_id::in,
-    proc_id::in, list(proc_id)::in, bool::out,
-    pred_info::in, pred_info::out, io::di, io::uo) is det.
+    proc_id::in, list(proc_id)::in, bool::out, pred_info::in, pred_info::out,
+    io::di, io::uo) is det.

 check_for_indistinguishable_mode(_, _, _, [], no, !PredInfo, !IO).
 check_for_indistinguishable_mode(ModuleInfo, PredId, ProcId1,
@@ -1644,7 +1647,7 @@
         get_type_defn_body(TypeDefn, TypeBody),
         TypeBody = abstract_type(_)
     ->
-        % We expect builtin types character, float, int and
+        % We expect the builtin types character, float, int and
         % string to have abstract declarations with no
         % definitions.  The following types from the type_desc
         % module also only have abstract declarations:
Index: compiler/prog_data.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/prog_data.m,v
retrieving revision 1.150
diff -u -r1.150 prog_data.m
--- compiler/prog_data.m	23 Nov 2005 05:11:40 -0000	1.150
+++ compiler/prog_data.m	4 Jan 2006 06:45:17 -0000
@@ -515,7 +515,7 @@

 :- type class_interface
     --->    abstract
-    ;       concrete(list(class_method)).
+    ;       concrete(class_methods).

 :- type instance_method
     --->    instance_method(
Index: compiler/prog_io_typeclass.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/prog_io_typeclass.m,v
retrieving revision 1.47
diff -u -r1.47 prog_io_typeclass.m
--- compiler/prog_io_typeclass.m	28 Nov 2005 04:11:52 -0000	1.47
+++ compiler/prog_io_typeclass.m	4 Jan 2006 06:46:55 -0000
@@ -243,7 +243,7 @@
     ).

 :- pred parse_class_methods(module_name::in, term::in, varset::in,
-    maybe1(list(class_method))::out) is det.
+    maybe1(class_methods)::out) is det.

 parse_class_methods(ModuleName, Methods, VarSet, Result) :-
     (
Index: compiler/prog_item.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/prog_item.m,v
retrieving revision 1.1
diff -u -r1.1 prog_item.m
--- compiler/prog_item.m	23 Nov 2005 04:44:07 -0000	1.1
+++ compiler/prog_item.m	4 Jan 2006 06:43:09 -0000
@@ -290,6 +290,8 @@
                 prog_context        % the declaration's context
             ).

+:- type class_methods == list(class_method).
+
 %-----------------------------------------------------------------------------%
 %
 % Mutable variables
Index: compiler/recompilation.version.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/recompilation.version.m,v
retrieving revision 1.34
diff -u -r1.34 recompilation.version.m
--- compiler/recompilation.version.m	28 Nov 2005 04:11:53 -0000	1.34
+++ compiler/recompilation.version.m	4 Jan 2006 06:46:22 -0000
@@ -439,7 +439,7 @@
     map__set(IdMap0, NameArity, MatchingItems, IdMap),
     !:GatheredItems = update_ids(!.GatheredItems, ItemType, IdMap).

-:- func split_class_method_types_and_modes(class_method) = list(class_method).
+:- func split_class_method_types_and_modes(class_method) = class_methods.

 split_class_method_types_and_modes(Method0) = Items :-
     % Always strip the context from the item -- this is needed
@@ -950,8 +950,8 @@
 class_interface_is_unchanged(concrete(Methods1), concrete(Methods2)) :-
     class_methods_are_unchanged(Methods1, Methods2).

-:- pred class_methods_are_unchanged(list(class_method)::in,
-    list(class_method)::in) is semidet.
+:- pred class_methods_are_unchanged(class_methods::in,
+    class_methods::in) is semidet.

 class_methods_are_unchanged([], []).
 class_methods_are_unchanged([Method1 | Methods1], [Method2 | Methods2]) :-
Index: tests/README
===================================================================
RCS file: /home/mercury1/repository/tests/README,v
retrieving revision 1.8
diff -u -r1.8 README
--- tests/README	16 Oct 2004 15:08:55 -0000	1.8
+++ tests/README	6 Jan 2006 04:14:02 -0000
@@ -71,4 +71,5 @@
 	This directory tests the compiler's termination analyser.  These
 	tests work by comparing the contents of the .trans_opt file emitted
 	by the compiler with the hand-written `.trans_opt_exp' file.
-	This directory is also used for testing the compiler's exception analysis.
+	This directory is also used for testing the compiler's exception
+	analysis.
Index: tests/invalid/Mmakefile
===================================================================
RCS file: /home/mercury1/repository/tests/invalid/Mmakefile,v
retrieving revision 1.185
diff -u -r1.185 Mmakefile
--- tests/invalid/Mmakefile	21 Dec 2005 22:11:54 -0000	1.185
+++ tests/invalid/Mmakefile	5 Jan 2006 14:34:45 -0000
@@ -161,12 +161,16 @@
 	tricky_assert1 \
 	typeclass_bogus_method \
 	typeclass_constraint_extra_var \
+	typeclass_dup_method_mode \
 	typeclass_missing_det \
 	typeclass_missing_det_2 \
 	typeclass_missing_det_3 \
 	typeclass_missing_mode \
 	typeclass_missing_mode_2 \
 	typeclass_mode \
+	typeclass_mode_2 \
+	typeclass_mode_3 \
+	typeclass_mode_4 \
 	typeclass_test_1 \
 	typeclass_test_10 \
 	typeclass_test_11 \
@@ -226,10 +230,8 @@
 #		the pragma foreign_proc rather than the pragma foreign_type)
 #	duplicate_instance_3 (the error is only detected when doing
 #		normal static linking; the error goes undetected
-#		when doing dynamic linking, or when the library
-#		was built with `--split-c-files')
+#		when doing dynamic linking)
 #	parent.undeclared_child (just not yet implemented)
-#	typeclass_mode_{2,3,4} (compiler calls error/1)
 #	ho_default_func_4 (due to a bug in the mode-checker ---
 #			see XXX comment in inst_match:inst_matches_final_3)
 #	inst_matches_final_bug (due to same bug as ho_default_func_4)
Index: tests/invalid/invalid_main.err_exp
===================================================================
RCS file: /home/mercury1/repository/tests/invalid/invalid_main.err_exp,v
retrieving revision 1.2
diff -u -r1.2 invalid_main.err_exp
--- tests/invalid/invalid_main.err_exp	14 Sep 2005 05:26:47 -0000	1.2
+++ tests/invalid/invalid_main.err_exp	5 Jan 2006 14:37:40 -0000
@@ -1,4 +1,4 @@
-invalid_main.m:004: Error: arguments of main/2 must have type `io__state'.
+invalid_main.m:004: Error: arguments of main/2 must have type `io.state'.
 invalid_main.m:004: In `main(di, out)':
 invalid_main.m:004:   warning: determinism declaration could be tighter.
 invalid_main.m:004:   Declared `multi', inferred `det'.
Index: tests/invalid/qualified_cons_id2.err_exp
===================================================================
RCS file: /home/mercury1/repository/tests/invalid/qualified_cons_id2.err_exp,v
retrieving revision 1.7
diff -u -r1.7 qualified_cons_id2.err_exp
--- tests/invalid/qualified_cons_id2.err_exp	14 Sep 2005 05:26:50 -0000	1.7
+++ tests/invalid/qualified_cons_id2.err_exp	5 Jan 2006 14:40:44 -0000
@@ -2,7 +2,3 @@
 qualified_cons_id2.m:015:   `qualified_cons_id2.test/2':
 qualified_cons_id2.m:015:   error: duplicate mode declaration.
 qualified_cons_id2.m:016:   Here is the conflicting mode declaration.
-qualified_cons_id2.m:015: In `test(in(bound(qualified_cons_id2.yes(ground))),
-qualified_cons_id2.m:015:   out)':
-qualified_cons_id2.m:015:   error: determinism declaration not satisfied.
-qualified_cons_id2.m:015:   Declared `det', inferred `failure'.
Index: tests/invalid/typeclass_dup_method_mode.err_exp
===================================================================
RCS file: tests/invalid/typeclass_dup_method_mode.err_exp
diff -N tests/invalid/typeclass_dup_method_mode.err_exp
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ tests/invalid/typeclass_dup_method_mode.err_exp	5 Jan 2006 14:33:39 -0000
@@ -0,0 +1,4 @@
+typeclass_dup_method_mode.m:005: In mode declarations for type class predicate
+typeclass_dup_method_mode.m:005:   method `typeclass_dup_method_mode.p/1':
+typeclass_dup_method_mode.m:005:   error: duplicate mode declaration.
+typeclass_dup_method_mode.m:006:   Here is the conflicting mode declaration.
Index: tests/invalid/typeclass_dup_method_mode.m
===================================================================
RCS file: tests/invalid/typeclass_dup_method_mode.m
diff -N tests/invalid/typeclass_dup_method_mode.m
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ tests/invalid/typeclass_dup_method_mode.m	5 Jan 2006 14:33:03 -0000
@@ -0,0 +1,7 @@
+:- module typeclass_dup_method_mode.
+:- interface.
+
+:- typeclass c(T) where [
+	pred p(T::in) is det,
+	mode p(in) is semidet
+].
Index: tests/invalid/typeclass_mode.err_exp
===================================================================
RCS file: /home/mercury1/repository/tests/invalid/typeclass_mode.err_exp,v
retrieving revision 1.5
diff -u -r1.5 typeclass_mode.err_exp
--- tests/invalid/typeclass_mode.err_exp	14 Sep 2005 05:26:53 -0000	1.5
+++ tests/invalid/typeclass_mode.err_exp	6 Jan 2006 03:05:04 -0000
@@ -1,4 +1,3 @@
-typeclass_mode.m:005: Error: mode declaration for predicate
-typeclass_mode.m:005:   `typeclass_mode.p/1'
-typeclass_mode.m:005:   without preceding `pred' declaration.
-typeclass_mode.m:005: Error: no clauses for predicate `p/1'.
+typeclass_mode.m:005: Error: mode declaration for type class method
+typeclass_mode.m:005:   `typeclass_mode.p'/1 without corresponding predicate
+typeclass_mode.m:005:   method declaration.
Index: tests/invalid/typeclass_mode_2.err_exp
===================================================================
RCS file: tests/invalid/typeclass_mode_2.err_exp
diff -N tests/invalid/typeclass_mode_2.err_exp
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ tests/invalid/typeclass_mode_2.err_exp	6 Jan 2006 03:05:23 -0000
@@ -0,0 +1,8 @@
+typeclass_mode_2.m:005: Error: mode declaration for type class method
+typeclass_mode_2.m:005:   `typeclass_mode_2.p'/1 without corresponding
+typeclass_mode_2.m:005:   predicate method declaration.
+typeclass_mode_2.m:010: Error: clause for predicate `typeclass_mode_2.p/1'
+typeclass_mode_2.m:010:   without preceding `pred' declaration.
+typeclass_mode_2.m:010: Inferred :- pred p(T1).
+typeclass_mode_2.m:010: Error: no mode declaration for predicate
+typeclass_mode_2.m:010:   `typeclass_mode_2.p/1'.
Index: tests/invalid/typeclass_mode_3.err_exp
===================================================================
RCS file: tests/invalid/typeclass_mode_3.err_exp
diff -N tests/invalid/typeclass_mode_3.err_exp
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ tests/invalid/typeclass_mode_3.err_exp	6 Jan 2006 03:05:29 -0000
@@ -0,0 +1,5 @@
+typeclass_mode_3.m:007: Error: mode declaration for type class method
+typeclass_mode_3.m:007:   `typeclass_mode_3.p'/1 without corresponding
+typeclass_mode_3.m:007:   predicate method declaration.
+typeclass_mode_3.m:004: Error: no mode declaration for exported predicate
+typeclass_mode_3.m:004:   `typeclass_mode_3.p/1'.
Index: tests/invalid/typeclass_mode_4.err_exp
===================================================================
RCS file: tests/invalid/typeclass_mode_4.err_exp
diff -N tests/invalid/typeclass_mode_4.err_exp
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ tests/invalid/typeclass_mode_4.err_exp	6 Jan 2006 03:05:36 -0000
@@ -0,0 +1,5 @@
+typeclass_mode_4.m:007: Error: mode declaration for type class method
+typeclass_mode_4.m:007:   `typeclass_mode_4.p'/1 without corresponding
+typeclass_mode_4.m:007:   predicate method declaration.
+typeclass_mode_4.m:004: Error: no mode declaration for exported predicate
+typeclass_mode_4.m:004:   `typeclass_mode_4.p/1'.

--------------------------------------------------------------------------
mercury-reviews mailing list
post:  mercury-reviews at cs.mu.oz.au
administrative address: owner-mercury-reviews at cs.mu.oz.au
unsubscribe: Address: mercury-reviews-request at cs.mu.oz.au Message: unsubscribe
subscribe:   Address: mercury-reviews-request at cs.mu.oz.au Message: subscribe
--------------------------------------------------------------------------



More information about the reviews mailing list