[m-rev.] for review: fix infinite loop for `:- inst x == x.'
Fergus Henderson
fjh at cs.mu.OZ.AU
Fri Nov 22 23:23:49 AEDT 2002
On 21-Nov-2002, Mark Brown <dougl at cs.mu.OZ.AU> wrote:
>
> An alternative solution to this problem may be to do a pass over all the
> inst equivalence declarations to check for circularities, before mode
> analysis even starts. One way that this may be better is that errors
> such as
>
> :- inst f == f.
>
> would be detected even if the inst is never used.
...
> It seems to me that the only way this can loop is if, when expanding a
> particular user defined inst f/N, the same inst constructor f/N is reached
> at the top level of the expanded inst. Perhaps I've overlooked something,
> but it should be sufficient for the Expansions argument to have type
> set(sym_name_and_arity), and only be checked/updated when the inst is of
> the form defined_inst(user_inst(_, _)). This approach would also solve the
> XXX in the log message.
These are all excellent suggestions.
However, rather than doing a separate pass, I've done the check as part
of make_hlds.m, when we add inst or mode definitions to the HLDS.
This required only a very minor change to the existing infrastructure
in make_hlds.m (threading an extra boolean return value through pass 1).
----------
Estimated hours taken: 18
Branches: main, release
Fix a bug where the compiler was going into an infinite loop for
insts and modes that are infinitely recursive at the top level,
e.g. `:- inst foo == foo.' or `:- mode foo == foo'.
compiler/make_hlds.m:
Check for circular insts and modes, and report an error if any occur.
Also, pass back a boolean from pass 1 indicating whether or not
any cyclic insts and modes. Rename the "UndefModes" argument
for parse_tree_to_hlds as "InvalidModes", and set it to yes
if there were any circular insts or modes, to ensure that
mercury_compile.m will not run mode analysis. This is needed
to avoid infinite loops in mode analysis when processing
circular
compiler/notes/compiler_design.html:
Mention that make_hlds.m checks for circular insts and modes.
Also mention that it expands state variable syntax.
compiler/mercury_compile.m:
Add a comment about circular insts and modes to the list of
reasons why we might need to stop before running mode analysis.
tests/invalid/circ_inst2.m:
Fix a misleading comment.
tests/invalid/Mmakefile:
tests/invalid/circ_inst.err_exp:
tests/invalid/circ_inst2.err_exp:
tests/invalid/circ_inst3.err_exp:
tests/invalid/circ_inst4.err_exp:
tests/invalid/circ_mode.err_exp:
tests/invalid/circ_mode2.err_exp:
tests/invalid/circ_mode3.err_exp:
tests/invalid/circ_mode4.err_exp:
Enable these test cases, and add expected output files for them.
tests/invalid/Mmakefile:
tests/invalid/circ_type3.m:
tests/invalid/circ_type3.err_exp:
Add another test for circular equivalence types.
Workspace: /home/mars/fjh/ws1/mercury
Index: compiler/make_hlds.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/make_hlds.m,v
retrieving revision 1.426
diff -u -d -r1.426 make_hlds.m
--- compiler/make_hlds.m 10 Nov 2002 15:57:52 -0000 1.426
+++ compiler/make_hlds.m 22 Nov 2002 11:28:57 -0000
@@ -30,12 +30,12 @@
:- import_module bool, list, io, std_util.
% parse_tree_to_hlds(ParseTree, MQInfo, EqvMap, HLDS, QualInfo,
-% UndefTypes, UndefModes):
+% InvalidTypes, InvalidModes):
% Given MQInfo (returned by module_qual.m) and EqvMap (returned by
% equiv_type.m), converts ParseTree to HLDS.
% Any errors found are recorded in the HLDS num_errors field.
-% Returns UndefTypes = yes if undefined types found.
-% Returns UndefModes = yes if undefined modes found.
+% Returns InvalidTypes = yes if undefined types found.
+% Returns InvalidModes = yes if undefined or cyclic insts or modes found.
% QualInfo is an abstract type that is then passed back to
% produce_instance_method_clauses (see below).
:- pred parse_tree_to_hlds(compilation_unit, mq_info, eqv_map, module_info,
@@ -121,12 +121,13 @@
:- import_module bag, term, varset, getopt, assoc_list, term_io.
parse_tree_to_hlds(module(Name, Items), MQInfo0, EqvMap, Module, QualInfo,
- UndefTypes, UndefModes) -->
+ InvalidTypes, InvalidModes) -->
globals__io_get_globals(Globals),
{ mq_info_get_partial_qualifier_info(MQInfo0, PQInfo) },
{ module_info_init(Name, Items, Globals, PQInfo, no, Module0) },
add_item_list_decls_pass_1(Items,
- item_status(local, may_be_unqualified), Module0, Module1),
+ item_status(local, may_be_unqualified), Module0, Module1,
+ no, InvalidModes0),
globals__io_lookup_bool_option(statistics, Statistics),
maybe_report_stats(Statistics),
add_item_list_decls_pass_2(Items,
@@ -145,8 +146,9 @@
add_item_list_clauses(Items, local, Module4, Module5,
QualInfo0, QualInfo),
{ qual_info_get_mq_info(QualInfo, MQInfo) },
- { mq_info_get_type_error_flag(MQInfo, UndefTypes) },
- { mq_info_get_mode_error_flag(MQInfo, UndefModes) },
+ { mq_info_get_type_error_flag(MQInfo, InvalidTypes) },
+ { mq_info_get_mode_error_flag(MQInfo, InvalidModes1) },
+ { InvalidModes = bool__or(InvalidModes0, InvalidModes1) },
{ mq_info_get_num_errors(MQInfo, MQ_NumErrors) },
{ module_info_num_errors(Module4, NumErrors0) },
{ NumErrors is NumErrors0 + MQ_NumErrors },
@@ -168,16 +170,22 @@
% Add the declarations one by one to the module,
% except for type definitions and pragmas.
+ % The `InvalidModes' bool records whether we detected
+ % any cyclic insts or modes.
+
:- pred add_item_list_decls_pass_1(item_list, item_status,
- module_info, module_info,
- io__state, io__state).
-:- mode add_item_list_decls_pass_1(in, in, in, out, di, uo) is det.
+ module_info, module_info, bool, bool, io__state, io__state).
+:- mode add_item_list_decls_pass_1(in, in, in, out, in, out, di, uo) is det.
-add_item_list_decls_pass_1([], _, Module, Module) --> [].
-add_item_list_decls_pass_1([Item - Context | Items], Status0, Module0, Module)
- -->
- add_item_decl_pass_1(Item, Context, Status0, Module0, Status1, Module1),
- add_item_list_decls_pass_1(Items, Status1, Module1, Module).
+add_item_list_decls_pass_1([], _, Module, Module, InvalidModes, InvalidModes)
+ --> [].
+add_item_list_decls_pass_1([Item - Context | Items], Status0, Module0, Module,
+ InvalidModes0, InvalidModes) -->
+ add_item_decl_pass_1(Item, Context, Status0, Module0,
+ Status1, Module1, InvalidModes1),
+ { InvalidModes2 = bool__or(InvalidModes0, InvalidModes1) },
+ add_item_list_decls_pass_1(Items, Status1, Module1, Module,
+ InvalidModes2, InvalidModes).
% pass 2:
% Add the type definitions and pragmas one by one to the module,
@@ -227,33 +235,36 @@
%-----------------------------------------------------------------------------%
- % dispatch on the different types of items
+ % The bool records whether any cyclic insts or modes were
+ % detected.
-:- pred add_item_decl_pass_1(item, prog_context, item_status,
- module_info, item_status, module_info, io__state, io__state).
-:- mode add_item_decl_pass_1(in, in, in, in, out, out, di, uo) is det.
+:- pred add_item_decl_pass_1(item, prog_context, item_status, module_info,
+ item_status, module_info, bool, io__state, io__state).
+:- mode add_item_decl_pass_1(in, in, in, in, out, out, out, di, uo) is det.
+
+ % Dispatch on the different types of items.
% skip clauses
-add_item_decl_pass_1(clause(_, _, _, _, _), _, Status, Module, Status, Module)
- --> [].
+add_item_decl_pass_1(clause(_, _, _, _, _), _, Status, Module,
+ Status, Module, no) --> [].
add_item_decl_pass_1(type_defn(_, _, _, _, _), _, Status, Module,
- Status, Module) --> [].
+ Status, Module, no) --> [].
add_item_decl_pass_1(inst_defn(VarSet, Name, Params, InstDefn, Cond), Context,
- Status, Module0, Status, Module) -->
+ Status, Module0, Status, Module, InvalidMode) -->
module_add_inst_defn(Module0, VarSet, Name, Params,
- InstDefn, Cond, Context, Status, Module).
+ InstDefn, Cond, Context, Status, Module, InvalidMode).
add_item_decl_pass_1(mode_defn(VarSet, Name, Params, ModeDefn, Cond), Context,
- Status, Module0, Status, Module) -->
+ Status, Module0, Status, Module, InvalidMode) -->
module_add_mode_defn(Module0, VarSet, Name, Params, ModeDefn,
- Cond, Context, Status, Module).
+ Cond, Context, Status, Module, InvalidMode).
add_item_decl_pass_1(pred_or_func(TypeVarSet, InstVarSet, ExistQVars,
PredOrFunc, PredName, TypesAndModes, _WithType, _WithInst,
MaybeDet, Cond, Purity, ClassContext),
- Context, Status, Module0, Status, Module) -->
+ Context, Status, Module0, Status, Module, no) -->
{ init_markers(Markers) },
module_add_pred_or_func(Module0, TypeVarSet, InstVarSet, ExistQVars,
PredOrFunc, PredName, TypesAndModes, MaybeDet, Cond,
@@ -262,7 +273,7 @@
add_item_decl_pass_1(
pred_or_func_mode(VarSet, MaybePredOrFunc, PredName,
Modes, _WithInst, MaybeDet, Cond),
- Context, Status, Module0, Status, Module) -->
+ Context, Status, Module0, Status, Module, no) -->
( { MaybePredOrFunc = yes(PredOrFunc) } ->
{ Status = item_status(ImportStatus, _) },
{ IsClassMethod = no },
@@ -276,13 +287,13 @@
"add_item_decl_pass_1: no pred_or_func on mode declaration") }
).
-add_item_decl_pass_1(pragma(_), _, Status, Module, Status, Module) --> [].
+add_item_decl_pass_1(pragma(_), _, Status, Module, Status, Module, no) --> [].
-add_item_decl_pass_1(promise(_, _, _, _), _, Status, Module, Status, Module)
- --> [].
+add_item_decl_pass_1(promise(_, _, _, _), _, Status, Module, Status, Module,
+ no) --> [].
add_item_decl_pass_1(module_defn(_VarSet, ModuleDefn), Context,
- Status0, Module0, Status, Module) -->
+ Status0, Module0, Status, Module, no) -->
( { module_defn_update_import_status(ModuleDefn, Status1) } ->
{ Status = Status1 },
{ Module = Module0 }
@@ -349,17 +360,17 @@
report_warning("Warning: declaration not yet implemented.\n")
).
-add_item_decl_pass_1(nothing(_), _, Status, Module, Status, Module) --> [].
+add_item_decl_pass_1(nothing(_), _, Status, Module, Status, Module, no) --> [].
add_item_decl_pass_1(typeclass(Constraints, Name, Vars, Interface, VarSet),
- Context, Status, Module0, Status, Module) -->
+ Context, Status, Module0, Status, Module, no) -->
module_add_class_defn(Module0, Constraints, Name, Vars, Interface,
VarSet, Context, Status, Module).
% We add instance declarations on the second pass so that we don't add
% an instance declaration before its class declaration.
add_item_decl_pass_1(instance(_, _, _, _, _,_), _, Status, Module, Status,
- Module) --> [].
+ Module, no) --> [].
%-----------------------------------------------------------------------------%
@@ -1803,18 +1814,28 @@
:- pred module_add_inst_defn(module_info, inst_varset, sym_name, list(inst_var),
inst_defn, condition, prog_context, item_status,
- module_info, io__state, io__state).
+ module_info, bool, io__state, io__state).
:- mode module_add_inst_defn(in, in, in, in, in, in, in, in,
- out, di, uo) is det.
+ out, out, di, uo) is det.
module_add_inst_defn(Module0, VarSet, Name, Args, InstDefn, Cond,
- Context, item_status(Status, _NeedQual), Module) -->
+ Context, item_status(Status, _NeedQual),
+ Module, InvalidMode) -->
+ %
+ % add the definition of this inst to the HLDS inst table
+ %
{ module_info_insts(Module0, InstTable0) },
{ inst_table_get_user_insts(InstTable0, Insts0) },
insts_add(Insts0, VarSet, Name, Args, InstDefn, Cond,
Context, Status, Insts),
{ inst_table_set_user_insts(InstTable0, Insts, InstTable) },
- { module_info_set_insts(Module0, InstTable, Module) }.
+ { module_info_set_insts(Module0, InstTable, Module) },
+ %
+ % check if the inst is infinitely recursive (at the top level)
+ %
+ { Arity = list__length(Args) },
+ { InstId = Name - Arity },
+ check_for_cyclic_inst(Insts, InstId, InstId, [], Context, InvalidMode).
:- pred insts_add(user_inst_table, inst_varset, sym_name, list(inst_var),
inst_defn, condition, prog_context, import_status,
@@ -1848,44 +1869,146 @@
Context, OrigContext, _)
).
+ %
+ % check if the inst is infinitely recursive (at the top level)
+ %
+:- pred check_for_cyclic_inst(user_inst_table, inst_id, inst_id, list(inst_id),
+ prog_context, bool, io__state, io__state).
+:- mode check_for_cyclic_inst(in, in, in, in, in, out, di, uo) is det.
+
+check_for_cyclic_inst(UserInstTable, OrigInstId, InstId0, Expansions0,
+ Context, InvalidMode) -->
+ ( { list__member(InstId0, Expansions0) } ->
+ report_circular_equiv_error("inst", OrigInstId, InstId0,
+ Expansions0, Context),
+ { InvalidMode = yes }
+ ;
+ { user_inst_table_get_inst_defns(UserInstTable, InstDefns) },
+ (
+ { map__search(InstDefns, InstId0, InstDefn) },
+ { InstDefn = hlds_inst_defn(_, _, Body, _, _, _) },
+ { Body = eqv_inst(EqvInst) },
+ { EqvInst = defined_inst(user_inst(Name, Args)) }
+ ->
+ { Arity = list__length(Args) },
+ { InstId = Name - Arity },
+ { Expansions = [InstId0 | Expansions0] },
+ check_for_cyclic_inst(UserInstTable, OrigInstId,
+ InstId, Expansions, Context, InvalidMode)
+ ;
+ { InvalidMode = no }
+ )
+ ).
+
%-----------------------------------------------------------------------------%
:- pred module_add_mode_defn(module_info, inst_varset, sym_name,
list(inst_var), mode_defn, condition, prog_context,
- item_status, module_info, io__state, io__state).
+ item_status, module_info, bool, io__state, io__state).
:- mode module_add_mode_defn(in, in, in, in, in, in, in,
- in, out, di, uo) is det.
+ in, out, out, di, uo) is det.
module_add_mode_defn(Module0, VarSet, Name, Params, ModeDefn, Cond,
- Context, item_status(Status, _NeedQual), Module) -->
+ Context, item_status(Status, _NeedQual),
+ Module, InvalidMode) -->
{ module_info_modes(Module0, Modes0) },
modes_add(Modes0, VarSet, Name, Params, ModeDefn,
- Cond, Context, Status, Modes),
+ Cond, Context, Status, Modes, InvalidMode),
{ module_info_set_modes(Module0, Modes, Module) }.
:- pred modes_add(mode_table, inst_varset, sym_name, list(inst_var),
mode_defn, condition, prog_context, import_status,
- mode_table, io__state, io__state).
-:- mode modes_add(in, in, in, in, in, in, in, in, out, di, uo) is det.
+ mode_table, bool, io__state, io__state).
+:- mode modes_add(in, in, in, in, in, in, in, in, out, out, di, uo) is det.
modes_add(Modes0, VarSet, Name, Args, eqv_mode(Body),
- Cond, Context, Status, Modes) -->
+ Cond, Context, Status, Modes, InvalidMode) -->
{ list__length(Args, Arity) },
+ { ModeId = Name - Arity },
(
{ I = hlds_mode_defn(VarSet, Args, eqv_mode(Body), Cond,
Context, Status) },
- { mode_table_insert(Modes0, Name - Arity, I, Modes1) }
+ { mode_table_insert(Modes0, ModeId, I, Modes1) }
->
{ Modes = Modes1 }
;
{ Modes = Modes0 },
{ mode_table_get_mode_defns(Modes, ModeDefns) },
- { map__lookup(ModeDefns, Name - Arity, OrigI) },
+ { map__lookup(ModeDefns, ModeId, OrigI) },
{ OrigI = hlds_mode_defn(_, _, _, _, OrigContext, _) },
% XXX we should record each error using
% module_info_incr_errors
multiple_def_error(Status, Name, Arity, "mode",
Context, OrigContext, _)
+ ),
+ check_for_cyclic_mode(Modes, ModeId, ModeId, [], Context,
+ InvalidMode).
+
+ %
+ % check if the mode is infinitely recursive at the top level
+ %
+:- pred check_for_cyclic_mode(mode_table, mode_id, mode_id, list(mode_id),
+ prog_context, bool, io__state, io__state).
+:- mode check_for_cyclic_mode(in, in, in, in, in, out, di, uo) is det.
+
+check_for_cyclic_mode(ModeTable, OrigModeId, ModeId0, Expansions0, Context,
+ InvalidMode) -->
+ ( { list__member(ModeId0, Expansions0) } ->
+ report_circular_equiv_error("mode", OrigModeId, ModeId0,
+ Expansions0, Context),
+ { InvalidMode = yes }
+ ;
+ { mode_table_get_mode_defns(ModeTable, ModeDefns) },
+ (
+ { map__search(ModeDefns, ModeId0, ModeDefn) },
+ { ModeDefn = hlds_mode_defn(_, _, Body, _, _, _) },
+ { Body = eqv_mode(EqvMode) },
+ { EqvMode = user_defined_mode(Name, Args) }
+ ->
+ { Arity = list__length(Args) },
+ { ModeId = Name - Arity },
+ { Expansions = [ModeId0 | Expansions0] },
+ check_for_cyclic_mode(ModeTable, OrigModeId, ModeId,
+ Expansions, Context, InvalidMode)
+ ;
+ { InvalidMode = no }
+ )
+ ).
+
+:- type id == pair(sym_name, arity).
+:- pred report_circular_equiv_error(string::in, id::in, id::in, list(id)::in,
+ prog_context::in, io__state::di, io__state::uo) is det.
+
+report_circular_equiv_error(Kind, OrigId, Id, Expansions, Context) -->
+ ( { Id = OrigId } ->
+ %
+ % Report an error message of the form
+ % Error: circular equivalence <kind> foo/0.
+ % or
+ % Error: circular equivalence <kind>s foo/0 and bar/1.
+ % or
+ % Error: circular equivalence <kind>s foo/0, bar/1,
+ % and baz/2.
+ % where <kind> is either "inst" or "mode".
+ %
+ { Kinds = (if Expansions = [_] then Kind else Kind ++ "s") },
+ { Pieces0 = list__map(
+ (func(SymName - Arity) =
+ error_util__describe_sym_name_and_arity(
+ SymName / Arity)),
+ Expansions) },
+ { error_util__list_to_pieces(Pieces0, Pieces1) },
+ { Pieces = append_punctuation(
+ [words("Error: circular equivalence"),
+ fixed(Kinds) | Pieces1], '.') },
+ error_util__write_error_pieces(Context, 0, Pieces),
+ io__set_exit_status(1)
+ ;
+ % We have an inst `OrigId' which is not itself circular,
+ % but which is defined in terms of `Id' which is circular.
+ % Don't bother reporting it now -- it have already been
+ % reported when we processed the definition of Id.
+ []
).
%-----------------------------------------------------------------------------%
Index: compiler/mercury_compile.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/mercury_compile.m,v
retrieving revision 1.267
diff -u -d -r1.267 mercury_compile.m
--- compiler/mercury_compile.m 31 Oct 2002 05:47:51 -0000 1.267
+++ compiler/mercury_compile.m 22 Nov 2002 11:00:38 -0000
@@ -1553,6 +1553,7 @@
% error, since propagate_types_into_proc_modes
% (in post_typecheck.m -- called by purity.m)
% and mode analysis would get internal errors.
+ % Also mode analysis can loop if there are cyclic insts/modes.
%
% We can't continue if the type inference iteration
% limit was exceeeded because the code to resolve
Index: compiler/notes/compiler_design.html
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/notes/compiler_design.html,v
retrieving revision 1.79
diff -u -d -r1.79 compiler_design.html
--- compiler/notes/compiler_design.html 31 Oct 2002 05:47:59 -0000 1.79
+++ compiler/notes/compiler_design.html 22 Nov 2002 12:17:33 -0000
@@ -276,9 +276,9 @@
<li> conversion to superhomogeneous form and into HLDS <br>
- make_hlds.m transforms the code into superhomogeneous form,
+ make_hlds.m transforms the clauses into superhomogeneous form,
and at the same time converts the parse tree into the HLDS.
- It expands away universal quantification
+ It expands away state variable syntax, universal quantification
(using `all [Vs] G' ===> `not (some [Vs] (not G))')
and implication (using `A => B' ===> `not(A, not B)').
It converts `pragma import', `pragma c_code' and `pragma fact_table'
@@ -291,6 +291,9 @@
make_hlds.m also calls make_tags.m which chooses the data
representation for each discriminated union type by
assigning tags to each functor.
+ make_hlds.m also performs a number of semantic checks,
+ such as checking for circular insts and modes
+ and warning about singleton variables.
</ul>
<p>
Index: tests/invalid/Mmakefile
===================================================================
RCS file: /home/mercury1/repository/tests/invalid/Mmakefile,v
retrieving revision 1.130
diff -u -d -r1.130 Mmakefile
--- tests/invalid/Mmakefile 22 Nov 2002 09:00:51 -0000 1.130
+++ tests/invalid/Mmakefile 22 Nov 2002 11:39:28 -0000
@@ -34,8 +34,17 @@
bind_var_errors \
builtin_int \
builtin_proc \
+ circ_inst \
+ circ_inst2 \
+ circ_inst3 \
+ circ_inst4 \
+ circ_mode \
+ circ_mode2 \
+ circ_mode3 \
+ circ_mode4 \
circ_type \
circ_type2 \
+ circ_type3 \
constrained_poly_insts \
constructor_warning \
det_errors \
@@ -161,10 +170,6 @@
# the type class name should be in quotes)
# typeclass_mode_{2,3,4} (compiler calls error/1)
# cyclic_typeclass (compiler goes into an infinite loop)
-# circ_inst{,2} (error is not detected)
-# circ_inst{3,4} (compiler goes into an infinite loop)
-# circ_mode{,2} (error is not detected)
-# circ_mode{3,4} (compiler goes into an infinite loop)
# 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/circ_inst.err_exp
===================================================================
RCS file: tests/invalid/circ_inst.err_exp
diff -N tests/invalid/circ_inst.err_exp
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ tests/invalid/circ_inst.err_exp 22 Nov 2002 11:42:51 -0000
@@ -0,0 +1,4 @@
+circ_inst.m:006: Error: circular equivalence inst `circ_inst:circ/0'.
+circ_inst.m:010: Error: circular equivalence insts `circ_inst:circ1/0' and
+circ_inst.m:010: `circ_inst:circ2/0'.
+For more information, try recompiling with `-E'.
Index: tests/invalid/circ_inst2.err_exp
===================================================================
RCS file: tests/invalid/circ_inst2.err_exp
diff -N tests/invalid/circ_inst2.err_exp
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ tests/invalid/circ_inst2.err_exp 22 Nov 2002 11:44:07 -0000
@@ -0,0 +1,6 @@
+circ_inst2.m:010: Error: circular equivalence inst `circ_inst2:circ1/1'.
+circ_inst2.m:011: Error: circular equivalence inst `circ_inst2:circ2/1'.
+circ_inst2.m:013: Error: circular equivalence inst `circ_inst2:circ4/1'.
+circ_inst2.m:016: Error: circular equivalence insts `circ_inst2:left/1' and
+circ_inst2.m:016: `circ_inst2:right/1'.
+For more information, try recompiling with `-E'.
Index: tests/invalid/circ_inst2.m
===================================================================
RCS file: /home/mercury1/repository/tests/invalid/circ_inst2.m,v
retrieving revision 1.2
diff -u -d -r1.2 circ_inst2.m
--- tests/invalid/circ_inst2.m 22 Nov 2002 09:00:52 -0000 1.2
+++ tests/invalid/circ_inst2.m 22 Nov 2002 11:43:32 -0000
@@ -10,7 +10,7 @@
:- inst circ1(I) == circ1(I). % error -- cyclic
:- inst circ2(I) == circ2(circ2(I)). % error -- cyclic
:- inst circ3(I) == list_skel(circ3(I)). % OK
-:- inst circ4(I) == circ4(list_skel(I)). % OK
+:- inst circ4(I) == circ4(list_skel(I)). % error -- cyclic
:- inst left(I) == right(I). % error -- cyclic
:- inst right(I) == left(I). % error -- cyclic
Index: tests/invalid/circ_inst3.err_exp
===================================================================
RCS file: tests/invalid/circ_inst3.err_exp
diff -N tests/invalid/circ_inst3.err_exp
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ tests/invalid/circ_inst3.err_exp 22 Nov 2002 10:47:08 -0000
@@ -0,0 +1,3 @@
+circ_inst3.m:009: Error: circular equivalence inst `circ_inst3:circ/0'.
+circ_inst3.m:013: Error: circular equivalence insts `circ_inst3:circ1/0' and
+circ_inst3.m:013: `circ_inst3:circ2/0'.
Index: tests/invalid/circ_inst4.err_exp
===================================================================
RCS file: tests/invalid/circ_inst4.err_exp
diff -N tests/invalid/circ_inst4.err_exp
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ tests/invalid/circ_inst4.err_exp 22 Nov 2002 11:44:58 -0000
@@ -0,0 +1,6 @@
+circ_inst4.m:010: Error: circular equivalence inst `circ_inst4:circ1/1'.
+circ_inst4.m:011: Error: circular equivalence inst `circ_inst4:circ2/1'.
+circ_inst4.m:013: Error: circular equivalence inst `circ_inst4:circ4/1'.
+circ_inst4.m:016: Error: circular equivalence insts `circ_inst4:left/1' and
+circ_inst4.m:016: `circ_inst4:right/1'.
+For more information, try recompiling with `-E'.
Index: tests/invalid/circ_mode.err_exp
===================================================================
RCS file: tests/invalid/circ_mode.err_exp
diff -N tests/invalid/circ_mode.err_exp
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ tests/invalid/circ_mode.err_exp 22 Nov 2002 11:45:06 -0000
@@ -0,0 +1,4 @@
+circ_mode.m:006: Error: circular equivalence mode `circ_mode:circ/0'.
+circ_mode.m:010: Error: circular equivalence modes `circ_mode:circ1/0' and
+circ_mode.m:010: `circ_mode:circ2/0'.
+For more information, try recompiling with `-E'.
Index: tests/invalid/circ_mode2.err_exp
===================================================================
RCS file: tests/invalid/circ_mode2.err_exp
diff -N tests/invalid/circ_mode2.err_exp
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ tests/invalid/circ_mode2.err_exp 22 Nov 2002 11:45:15 -0000
@@ -0,0 +1,5 @@
+circ_mode2.m:010: Error: circular equivalence mode `circ_mode2:circ1/1'.
+circ_mode2.m:011: Error: circular equivalence mode `circ_mode2:circ2/1'.
+circ_mode2.m:014: Error: circular equivalence modes `circ_mode2:left/1' and
+circ_mode2.m:014: `circ_mode2:right/1'.
+For more information, try recompiling with `-E'.
Index: tests/invalid/circ_mode3.err_exp
===================================================================
RCS file: tests/invalid/circ_mode3.err_exp
diff -N tests/invalid/circ_mode3.err_exp
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ tests/invalid/circ_mode3.err_exp 22 Nov 2002 11:45:29 -0000
@@ -0,0 +1,4 @@
+circ_mode3.m:009: Error: circular equivalence mode `circ_mode3:circ/0'.
+circ_mode3.m:013: Error: circular equivalence modes `circ_mode3:circ1/0' and
+circ_mode3.m:013: `circ_mode3:circ2/0'.
+For more information, try recompiling with `-E'.
Index: tests/invalid/circ_mode4.err_exp
===================================================================
RCS file: tests/invalid/circ_mode4.err_exp
diff -N tests/invalid/circ_mode4.err_exp
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ tests/invalid/circ_mode4.err_exp 22 Nov 2002 11:45:44 -0000
@@ -0,0 +1,5 @@
+circ_mode4.m:010: Error: circular equivalence mode `circ_mode4:circ1/1'.
+circ_mode4.m:011: Error: circular equivalence mode `circ_mode4:circ2/1'.
+circ_mode4.m:014: Error: circular equivalence modes `circ_mode4:left/1' and
+circ_mode4.m:014: `circ_mode4:right/1'.
+For more information, try recompiling with `-E'.
Index: tests/invalid/circ_type3.err_exp
===================================================================
RCS file: tests/invalid/circ_type3.err_exp
diff -N tests/invalid/circ_type3.err_exp
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ tests/invalid/circ_type3.err_exp 22 Nov 2002 10:37:29 -0000
@@ -0,0 +1,4 @@
+circ_type3.m:008: Error: circular equivalence type `circ_type3:circ/0'.
+circ_type3.m:010: Error: circular equivalence type `circ_type3:circ1/0'.
+circ_type3.m:012: Error: circular equivalence type `circ_type3:circ2/0'.
+For more information, try recompiling with `-E'.
Index: tests/invalid/circ_type3.m
===================================================================
RCS file: tests/invalid/circ_type3.m
diff -N tests/invalid/circ_type3.m
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ tests/invalid/circ_type3.m 22 Nov 2002 11:43:32 -0000
@@ -0,0 +1,18 @@
+% Test for circular equivalence types.
+% This is the same as circ_type.m, except that we also have
+% a predicate that uses the types.
+:- module circ_type3.
+
+:- interface.
+
+:- type circ == circ.
+
+:- type circ1 == circ2.
+
+:- type circ2 == circ1.
+
+:- pred p(circ, circ1, circ2).
+:- mode p(in, in, out) is det.
+
+:- implementation.
+p(_, X, X).
--
Fergus Henderson <fjh at cs.mu.oz.au> | "I have always known that the pursuit
The University of Melbourne | of excellence is a lethal habit"
WWW: <http://www.cs.mu.oz.au/~fjh> | -- the last words of T. S. Garp.
--------------------------------------------------------------------------
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