[m-rev.] diff: fix inter-module optimization bug

Simon Taylor stayl at cs.mu.OZ.AU
Mon Jul 15 01:13:03 AEST 2002


Estimated hours taken: 2
Branches: main

Fix a bug in inter-module optimization with sub-modules reported
by Michael Day <mikeday at bigpond.net.au>. The symptom was a compiler
abort due to an attempt to take the address of a predicate with
multiple modes. The predicate only had multiple mode declarations
because the declarations were read from both the `.int0' and `.opt'
files for the module.

compiler/post_typecheck.m:
compiler/purity.m:
	Remove duplicate modes and report other errors in type
	declarations for all predicates in a separate pass before 
	purity checking and overloading resolution.

tests/valid/Mmakefile:
tests/valid/intermod_nested_module_bug.m:
tests/valid/intermod_nested_module_bug2.m:
	Test case.

tests/valid/assoc_list.m:
tests/valid/assoc_list_bug.m:
	Rename the assoc_list test case -- it interfered with
	other test cases attempting to import the assoc_list
	library module.

Index: compiler/post_typecheck.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/post_typecheck.m,v
retrieving revision 1.39
diff -u -u -r1.39 post_typecheck.m
--- compiler/post_typecheck.m	30 Jun 2002 17:06:35 -0000	1.39
+++ compiler/post_typecheck.m	14 Jul 2002 14:47:33 -0000
@@ -34,7 +34,8 @@
 :- import_module hlds__hlds_pred, parse_tree__prog_data.
 :- import_module list, io, bool, std_util.
 
-	% check_type_bindings(PredId, PredInfo, ModuleInfo, ReportErrors):
+	% post_typecheck__finish_preds(PredIds, ReportTypeErrors,
+	%	NumErrors, FoundTypeError, Module0, Module)
 	%
 	% Check that all Aditi predicates have an `aditi__state' argument.
 	% Check that the all of the types which have been inferred
@@ -47,11 +48,37 @@
 	% 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
+	% should prevent further processing (e.g. polymorphism or
+	% mode analysis).
+	%
+:- pred post_typecheck__finish_preds(list(pred_id), bool,
+	int, bool, module_info, module_info, io__state, io__state).
+:- mode post_typecheck__finish_preds(in, in, out, out,
+	in, out, di, uo) is det.
+
+	% As above, but don't check for `aditi__state's and return
+	% the list of procedures containing unbound inst variables
+	% instead of reporting the errors directly.
 	%
-:- pred post_typecheck__check_type_bindings(pred_id, pred_info, module_info,
-		bool, pred_info, int, io__state, io__state).
-:- mode post_typecheck__check_type_bindings(in, in, in, in, out, out, di, uo)
-		is det.
+:- pred post_typecheck__finish_pred_no_io(module_info, list(proc_id),
+		pred_info, pred_info).
+:- mode post_typecheck__finish_pred_no_io(in, out, in, out) is det.
+
+:- pred post_typecheck__finish_imported_pred_no_io(module_info,
+		list(proc_id), pred_info, pred_info).
+:- mode post_typecheck__finish_imported_pred_no_io(in, out, in, out) is det.
+
+:- pred post_typecheck__finish_ill_typed_pred(module_info, pred_id,
+		pred_info, pred_info, io__state, io__state).
+:- mode post_typecheck__finish_ill_typed_pred(in, in, in, out, di, uo) is det.
+
+	% Now that the assertion has finished being typechecked,
+	% remove it from further processing and store it in the
+	% assertion_table.
+:- pred post_typecheck__finish_promise(promise_type, module_info, pred_id,
+		module_info, io__state, io__state) is det.
+:- mode post_typecheck__finish_promise(in, in, in, out, di, uo) is det.
 
 	% Handle any unresolved overloading for a predicate call.
 	%
@@ -89,43 +116,6 @@
 :- mode post_typecheck__resolve_unify_functor(in, in, in, in, in, in,
 		in, in, in, out, in, out, in, out, out) is det.
 
-	% Do the stuff needed to initialize the pred_infos and proc_infos
-	% so that a pred is ready for running polymorphism and then
-	% mode checking.
-	% Also check that all predicates with an `aditi' marker have
-	% an `aditi__state' argument.
-	%
-:- pred post_typecheck__finish_pred(module_info, pred_id, pred_info, pred_info,
-		io__state, io__state).
-:- mode post_typecheck__finish_pred(in, in, in, out, di, uo) is det.
-
-:- pred post_typecheck__finish_imported_pred(module_info, pred_id,
-		pred_info, pred_info, io__state, io__state).
-:- mode post_typecheck__finish_imported_pred(in, in, in, out, di, uo) is det.
-
-	% As above, but don't check for `aditi__state's and return
-	% the list of procedures containing unbound inst variables
-	% instead of reporting the errors directly.
-	%
-:- pred post_typecheck__finish_pred_no_io(module_info, list(proc_id),
-		pred_info, pred_info).
-:- mode post_typecheck__finish_pred_no_io(in, out, in, out) is det.
-
-:- pred post_typecheck__finish_imported_pred_no_io(module_info,
-		list(proc_id), pred_info, pred_info).
-:- mode post_typecheck__finish_imported_pred_no_io(in, out, in, out) is det.
-
-:- pred post_typecheck__finish_ill_typed_pred(module_info, pred_id,
-		pred_info, pred_info, io__state, io__state).
-:- mode post_typecheck__finish_ill_typed_pred(in, in, in, out, di, uo) is det.
-
-	% Now that the assertion has finished being typechecked,
-	% remove it from further processing and store it in the
-	% assertion_table.
-:- pred post_typecheck__finish_promise(promise_type, module_info, pred_id,
-		module_info, io__state, io__state) is det.
-:- mode post_typecheck__finish_promise(in, in, in, out, di, uo) is det.
-
 %-----------------------------------------------------------------------------%
 
 :- implementation.
@@ -144,6 +134,92 @@
 :- import_module string, varset.
 
 %-----------------------------------------------------------------------------%
+
+post_typecheck__finish_preds(PredIds, ReportTypeErrors, NumErrors,
+		FoundTypeError, ModuleInfo0, ModuleInfo) -->
+	post_typecheck__finish_preds(PredIds, ReportTypeErrors,
+		ModuleInfo0, ModuleInfo, 0, NumErrors, no, FoundTypeError).
+
+:- pred post_typecheck__finish_preds(list(pred_id), bool,
+	module_info, module_info, int, int, bool, bool, io__state, io__state).
+:- mode post_typecheck__finish_preds(in, in, in, out, in, out,
+	in, out, di, uo) is det.
+
+post_typecheck__finish_preds([], _, ModuleInfo, ModuleInfo,
+		NumErrors, NumErrors,
+		PostTypecheckError, PostTypecheckError) --> [].
+post_typecheck__finish_preds([PredId | PredIds], ReportTypeErrors,
+		ModuleInfo0, ModuleInfo, NumErrors0, NumErrors,
+		FoundTypeError0, FoundTypeError) -->
+	{ module_info_pred_info(ModuleInfo0, PredId, PredInfo0) },
+	(	
+		{ pred_info_is_imported(PredInfo0)
+		; pred_info_is_pseudo_imported(PredInfo0) }
+	->
+		post_typecheck__finish_imported_pred(ModuleInfo0, PredId,
+				PredInfo0, PredInfo),
+		{ NumErrors1 = NumErrors0 },
+		{ FoundTypeError1 = FoundTypeError0 }
+	;
+		%
+		% Only report error messages for unbound type variables
+		% if we didn't get any type errors already; this avoids
+		% a lot of spurious diagnostics.
+		%
+		post_typecheck__check_type_bindings(PredId, PredInfo0,
+				ModuleInfo0, ReportTypeErrors,
+				PredInfo1, UnboundTypeErrsInThisPred),
+
+		%
+		% if there were any unsatisfied type class constraints,
+		% then that can cause internal errors in polymorphism.m
+		% if we try to continue, so we need to halt compilation
+		% after this pass.
+		%
+		{ UnboundTypeErrsInThisPred \= 0 ->
+			FoundTypeError1 = yes
+		;
+			FoundTypeError1 = FoundTypeError0
+		},
+
+		{ post_typecheck__finish_pred_no_io(ModuleInfo0,
+			ErrorProcs, PredInfo1, PredInfo2) },
+		report_unbound_inst_vars(ModuleInfo0, PredId,
+			ErrorProcs, PredInfo2, PredInfo3),
+		check_for_indistinguishable_modes(ModuleInfo0, PredId,
+			PredInfo3, PredInfo),
+
+		%
+		% check that main/2 has the right type
+		%
+		( { ReportTypeErrors = yes } ->
+			check_type_of_main(PredInfo)
+		;
+			[]
+		),
+
+		%
+		% Check that all Aditi predicates have an `aditi__state'
+		% argument. This must be done after typechecking because
+		% of type inference -- the types of some Aditi predicates
+		% may not be known before.
+		%
+		{ pred_info_get_markers(PredInfo, Markers) },
+		( { ReportTypeErrors = yes, check_marker(Markers, aditi) } ->
+			check_aditi_state(ModuleInfo0, PredInfo)
+		;
+			[]
+		),
+	 
+		{ NumErrors1 is NumErrors0 + UnboundTypeErrsInThisPred }
+	),
+	{ module_info_set_pred_info(ModuleInfo0, PredId,
+		PredInfo, ModuleInfo1) },
+	post_typecheck__finish_preds(PredIds, ReportTypeErrors,
+		ModuleInfo1, ModuleInfo, NumErrors1, NumErrors,
+		FoundTypeError1, FoundTypeError).
+
+%-----------------------------------------------------------------------------%
 %			Check for unbound type variables
 %
 %  Check that the all of the types which have been inferred
@@ -151,6 +227,11 @@
 %  variables other than those that occur in the types of head
 %  variables, and that there are no unsatisfied type class constraints.
 
+:- pred post_typecheck__check_type_bindings(pred_id, pred_info, module_info,
+		bool, pred_info, int, io__state, io__state).
+:- mode post_typecheck__check_type_bindings(in, in, in, in, out, out, di, uo)
+		is det.
+
 post_typecheck__check_type_bindings(PredId, PredInfo0, ModuleInfo, ReportErrs,
 		PredInfo, NumErrors, IOState0, IOState) :-
 	(
@@ -179,16 +260,16 @@
 			[], Errs, Set0, Set),
 	( Errs = [] ->
 		PredInfo = PredInfo0,
-		IOState2 = IOState1
+		IOState = IOState1
 	;
 		( ReportErrs = yes ->
 			%
 			% report the warning
 			%
 			report_unresolved_type_warning(Errs, PredId, PredInfo0,
-				ModuleInfo, VarSet, IOState1, IOState2)
+				ModuleInfo, VarSet, IOState1, IOState)
 		;
-			IOState2 = IOState1
+			IOState = IOState1
 		),
 
 		%
@@ -201,27 +282,6 @@
 			ClausesInfo),
 		pred_info_set_clauses_info(PredInfo0, ClausesInfo, PredInfo1),
 		pred_info_set_constraint_proofs(PredInfo1, Proofs, PredInfo)
-	),
-
-	%
-	% check that main/2 has the right type
-	%
-	( ReportErrs = yes ->
-		check_type_of_main(PredInfo, IOState2, IOState3)
-	;
-		IOState3 = IOState2
-	),
-
-	%
-	% Check that all Aditi predicates have an `aditi__state' argument.
-	% This must be done after typechecking because of type inference --
-	% the types of some Aditi predicates may not be known before.
-	%
-	pred_info_get_markers(PredInfo, Markers),
-	( ReportErrs = yes, check_marker(Markers, aditi) ->
-		check_aditi_state(ModuleInfo, PredInfo, IOState3, IOState)
-	;
-		IOState = IOState3
 	).
 
 :- pred check_type_bindings_2(assoc_list(prog_var, (type)), list(tvar),
@@ -625,18 +685,6 @@
 
 %-----------------------------------------------------------------------------%
 
-	% 
-	% Ensure that all constructors occurring in predicate mode 
-	% declarations are module qualified.
-	% 
-post_typecheck__finish_pred(ModuleInfo, PredId, PredInfo0, PredInfo) -->
-	{ post_typecheck__finish_pred_no_io(ModuleInfo,
-			ErrorProcs, PredInfo0, PredInfo1) },
-	report_unbound_inst_vars(ModuleInfo, PredId,
-			ErrorProcs, PredInfo1, PredInfo2),
-	check_for_indistinguishable_modes(ModuleInfo, PredId,
-			PredInfo2, PredInfo).
-
 post_typecheck__finish_pred_no_io(ModuleInfo, ErrorProcs,
 		PredInfo0, PredInfo) :-
 	post_typecheck__propagate_types_into_modes(ModuleInfo,
@@ -661,6 +709,10 @@
 	% constructors occurring in predicate mode declarations are
 	% module qualified.
 	% 
+:- pred post_typecheck__finish_imported_pred(module_info, pred_id,
+		pred_info, pred_info, io__state, io__state).
+:- mode post_typecheck__finish_imported_pred(in, in, in, out, di, uo) is det.
+
 post_typecheck__finish_imported_pred(ModuleInfo, PredId,
 		PredInfo0, PredInfo) -->
 	{ pred_info_get_markers(PredInfo0, Markers) },
Index: compiler/purity.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/purity.m,v
retrieving revision 1.46
diff -u -u -r1.46 purity.m
--- compiler/purity.m	28 Mar 2002 03:43:34 -0000	1.46
+++ compiler/purity.m	14 Jul 2002 14:48:01 -0000
@@ -331,79 +331,55 @@
 check_preds_purity(FoundTypeError, ModuleInfo0,
 		PostTypecheckError, ModuleInfo) -->
 	{ module_info_predids(ModuleInfo0, PredIds) },
-	check_preds_purity_2(PredIds, FoundTypeError, ModuleInfo0,
-		ModuleInfo1, 0, NumErrors, no, PostTypecheckError),
-	{ module_info_num_errors(ModuleInfo1, Errs0) },
-	{ Errs is Errs0 + NumErrors },
-	{ module_info_set_num_errors(ModuleInfo1, Errs, ModuleInfo) }.
 
+	% Only report error messages for unbound type variables
+	% if we didn't get any type errors already; this avoids
+	% a lot of spurious diagnostics.
+	{ ReportTypeErrors = bool__not(FoundTypeError) },
+	post_typecheck__finish_preds(PredIds, ReportTypeErrors, NumErrors1,
+		PostTypecheckError, ModuleInfo0, ModuleInfo1),
+
+	check_preds_purity_2(PredIds, ModuleInfo1, ModuleInfo2,
+		NumErrors1, NumErrors),
+	{ module_info_num_errors(ModuleInfo2, Errs0) },
+	{ Errs is Errs0 + NumErrors },
+	{ module_info_set_num_errors(ModuleInfo2, Errs, ModuleInfo) }.
 
-:- pred check_preds_purity_2(list(pred_id), bool, module_info, module_info,
-			int, int, bool, bool, io__state, io__state).
-:- mode check_preds_purity_2(in, in, in, out, in, out, in, out, di, uo) is det.
+:- pred check_preds_purity_2(list(pred_id), module_info, module_info,
+			int, int, io__state, io__state).
+:- mode check_preds_purity_2(in, in, out, in, out, di, uo) is det.
 
-check_preds_purity_2([], _, ModuleInfo, ModuleInfo, NumErrors, NumErrors,
-		PostTypecheckError, PostTypecheckError) --> [].
-check_preds_purity_2([PredId | PredIds], FoundTypeError, ModuleInfo0,
-		ModuleInfo, NumErrors0, NumErrors,
-		PostTypecheckError0, PostTypecheckError) -->
-	{ module_info_preds(ModuleInfo0, Preds0) },
-	{ map__lookup(Preds0, PredId, PredInfo0) },
+check_preds_purity_2([], ModuleInfo, ModuleInfo, NumErrors, NumErrors) --> [].
+check_preds_purity_2([PredId | PredIds], ModuleInfo0, ModuleInfo,
+		NumErrors0, NumErrors) -->
+	{ module_info_pred_info(ModuleInfo0, PredId, PredInfo0) },
 	(	
 		{ pred_info_is_imported(PredInfo0)
 		; pred_info_is_pseudo_imported(PredInfo0) }
 	->
-		post_typecheck__finish_imported_pred(ModuleInfo0, PredId,
-				PredInfo0, PredInfo),
-		{ NumErrors1 = NumErrors0 },
-		{ PostTypecheckError1 = PostTypecheckError0 }
+		{ ModuleInfo1 = ModuleInfo0 },
+		{ PredInfo = PredInfo0 },
+		{ NumErrors1 = NumErrors0 }
 	;
 		write_pred_progress_message("% Purity-checking ", PredId,
 					    ModuleInfo0),
-		%
-		% Only report error messages for unbound type variables
-		% if we didn't get any type errors already; this avoids
-		% a lot of spurious diagnostics.
-		%
-		{ bool__not(FoundTypeError, ReportErrs) },
-		post_typecheck__check_type_bindings(PredId, PredInfo0,
-				ModuleInfo0, ReportErrs,
-				PredInfo1, UnboundTypeErrsInThisPred),
-		%
-		% if there were any unsatisfied type class constraints,
-		% then that can cause internal errors in polymorphism.m
-		% if we try to continue, so we need to halt compilation
-		% after this pass.
-		%
-		{ UnboundTypeErrsInThisPred \= 0 ->
-			PostTypecheckError1 = yes
-		;
-			PostTypecheckError1 = PostTypecheckError0
-		},
-		puritycheck_pred(PredId, PredInfo1, PredInfo2, ModuleInfo0,
+		puritycheck_pred(PredId, PredInfo0, PredInfo, ModuleInfo0,
 				PurityErrsInThisPred),
-		post_typecheck__finish_pred(ModuleInfo0, PredId, PredInfo2,
-				PredInfo),
-		{ NumErrors1 is NumErrors0 + UnboundTypeErrsInThisPred
-					   + PurityErrsInThisPred }
+		{ NumErrors1 = NumErrors0 + PurityErrsInThisPred },
+		{ module_info_set_pred_info(ModuleInfo0, PredId,
+				PredInfo, ModuleInfo1) }
 	),
-	{ map__det_update(Preds0, PredId, PredInfo, Preds) },
-	{ module_info_get_predicate_table(ModuleInfo0, PredTable0) },
-	{ predicate_table_set_preds(PredTable0, Preds, PredTable) },
-	{ module_info_set_predicate_table(ModuleInfo0, PredTable,
-					  ModuleInfo1) },
 
 		% finish processing of promise declarations
-	{ pred_info_get_goal_type(PredInfo0, GoalType) },
+	{ pred_info_get_goal_type(PredInfo, GoalType) },
 	( { GoalType = promise(PromiseType) } ->
 		post_typecheck__finish_promise(PromiseType, ModuleInfo1,
 				PredId, ModuleInfo2)
 	;
 		{ ModuleInfo2 = ModuleInfo1 }
 	),
-	check_preds_purity_2(PredIds, FoundTypeError, ModuleInfo2, ModuleInfo,
-				  NumErrors1, NumErrors,
-				  PostTypecheckError1, PostTypecheckError).
+	check_preds_purity_2(PredIds, ModuleInfo2, ModuleInfo,
+			  NumErrors1, NumErrors).
 
 	% Purity-check the code for single predicate, reporting any errors.
 
Index: tests/valid/Mmakefile
===================================================================
RCS file: /home/mercury1/repository/tests/valid/Mmakefile,v
retrieving revision 1.106
diff -u -u -r1.106 Mmakefile
--- tests/valid/Mmakefile	4 Jul 2002 23:25:49 -0000	1.106
+++ tests/valid/Mmakefile	13 Jul 2002 16:43:39 -0000
@@ -95,6 +95,7 @@
 	intermod_impure.m \
 	intermod_lambda.m \
 	intermod_nested_module.m \
+	intermod_nested_module_bug.m \
 	intermod_nested_uniq.m \
 	intermod_pragma_import.m \
 	intermod_quote.m \
@@ -177,7 +178,7 @@
 	zero_arity.m
 
 # XXX The mode system can't handle the following test cases yet:
-#	assoc_list.m
+#	assoc_list_bug.m
 #	determinism.m
 #	mode_merge_insts.m
 #	inst_perf_bug_2.m
@@ -289,6 +290,8 @@
 MCFLAGS-intermod_lambda2	= --intermodule-optimization
 MCFLAGS-intermod_nested_module	= --intermodule-optimization
 MCFLAGS-intermod_nested_module2	= --intermodule-optimization
+MCFLAGS-intermod_nested_module_bug = --intermodule-optimization
+MCFLAGS-intermod_nested_module_bug2 = --intermodule-optimization
 MCFLAGS-intermod_nested_uniq	= --intermodule-optimization
 MCFLAGS-intermod_nested_uniq2	= --intermodule-optimization
 MCFLAGS-intermod_pragma_import	= --intermodule-optimization
Index: tests/valid/assoc_list.m
===================================================================
RCS file: tests/valid/assoc_list.m
diff -N tests/valid/assoc_list.m
--- tests/valid/assoc_list.m	11 Dec 1996 00:01:35 -0000	1.2
+++ /dev/null	1 Jan 1970 00:00:00 -0000
@@ -1,11 +0,0 @@
-:- module assoc_list.
-:- interface.
-:- import_module list, std_util.
-
-:- pred assoc_list_member(pair(K,V), list(pair(K,V))).
-:- mode assoc_list_member(bound(free - ground) -> ground, in) is semidet.
-:- mode assoc_list_member(bound(free - free) -> ground, in) is nondet.
-
-assoc_list_member(X, [X|_]).
-assoc_list_member(X, [_|Xs]) :-
-	assoc_list_member(X, Xs).
Index: tests/valid/assoc_list_bug.m
===================================================================
RCS file: tests/valid/assoc_list_bug.m
diff -N tests/valid/assoc_list_bug.m
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ tests/valid/assoc_list_bug.m	11 Dec 1996 00:01:35 -0000
@@ -0,0 +1,11 @@
+:- module assoc_list.
+:- interface.
+:- import_module list, std_util.
+
+:- pred assoc_list_member(pair(K,V), list(pair(K,V))).
+:- mode assoc_list_member(bound(free - ground) -> ground, in) is semidet.
+:- mode assoc_list_member(bound(free - free) -> ground, in) is nondet.
+
+assoc_list_member(X, [X|_]).
+assoc_list_member(X, [_|Xs]) :-
+	assoc_list_member(X, Xs).
Index: tests/valid/intermod_nested_module_bug.m
===================================================================
RCS file: tests/valid/intermod_nested_module_bug.m
diff -N tests/valid/intermod_nested_module_bug.m
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ tests/valid/intermod_nested_module_bug.m	13 Jul 2002 16:47:08 -0000
@@ -0,0 +1,25 @@
+:- module intermod_nested_module_bug.
+
+:- interface.
+
+:- import_module io.
+
+:- pred main(io, io).
+:- mode main(di, uo) is det.
+
+:- implementation.
+
+:- import_module std_util.
+:- import_module intermod_nested_module_bug2, intermod_nested_module_bug2__sub.
+
+main -->
+    get_request(Res0),
+    (
+	{ Res0 = ok(CGI) },
+	read_post(CGI, Form),
+	write(Form), nl
+    ;
+	{ Res0 = error(Error) },
+	write_string(Error)
+    ).
+
Index: tests/valid/intermod_nested_module_bug2.m
===================================================================
RCS file: tests/valid/intermod_nested_module_bug2.m
diff -N tests/valid/intermod_nested_module_bug2.m
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ tests/valid/intermod_nested_module_bug2.m	13 Jul 2002 16:47:08 -0000
@@ -0,0 +1,23 @@
+:- module intermod_nested_module_bug2.
+
+:- interface.
+
+:- include_module intermod_nested_module_bug2__sub.
+:- import_module io, string, list, assoc_list, int, std_util.
+
+:- type cgi
+    --->    cgi(
+		content_length :: maybe(int)
+	    ).
+
+:- pred get_request(maybe_error(cgi), io, io).
+:- mode get_request(out, di, uo) is det.
+
+:- implementation.
+
+get_request(Res) --> { Res = promise_only_solution(get_request0) }.
+
+:- pred get_request0(maybe_error(cgi)).
+:- mode get_request0(out) is cc_multi.
+
+get_request0(error("foo")).
Index: tests/valid/intermod_nested_module_bug2.sub.m
===================================================================
RCS file: tests/valid/intermod_nested_module_bug2.sub.m
diff -N tests/valid/intermod_nested_module_bug2.sub.m
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ tests/valid/intermod_nested_module_bug2.sub.m	13 Jul 2002 16:47:45 -0000
@@ -0,0 +1,15 @@
+
+:- module intermod_nested_module_bug2__sub.
+
+:- interface.
+
+:- type post == assoc_list(string).
+
+:- pred read_post(cgi, maybe_error(post), io, io).
+:- mode read_post(in, out, di, uo) is det.
+
+:- implementation.
+
+read_post(_CGI, error("foo")) --> [].
+
+:- end_module intermod_nested_module_bug2__sub.
--------------------------------------------------------------------------
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