[m-rev.] diff: fix bugs in smart recompilation

Simon Taylor stayl at cs.mu.OZ.AU
Tue Jul 24 20:47:57 AEST 2001


Estimated hours taken: 4
Branches: main

Fix bugs in smart recompilation.

compiler/recompilation_version.m:
	Avoid problems where splitting of combined predicate type
	and mode declarations resulted in different varsets when
	declarations were read back in from `.int' files for comparison
	with the new declarations. The symptom was that the interface
	file would change (due to changing timestamps) even if the
	source module was just touched.

	Pragmas can apply to typeclass methods, so consider a typeclass
	to be changed if any pragmas which could apply to any of its
	methods are changed.
	
compiler/hlds_out.m:
	Export mode_to_term for use by recompilation_version.m in
	testing whether two modes are identical with variable renaming.

tests/recompilation/change_type_nr*:
tests/recompilation/combined_type_mode_nr*:
tests/recompilation/typeclass_method_pragma_r*:
	Test cases.


Index: compiler/hlds_out.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/hlds_out.m,v
retrieving revision 1.264
diff -u -u -r1.264 hlds_out.m
--- compiler/hlds_out.m	2001/07/20 14:13:26	1.264
+++ compiler/hlds_out.m	2001/07/23 06:44:10
@@ -33,7 +33,7 @@
 :- interface.
 
 % Parse tree modules
-:- import_module prog_data.
+:- import_module prog_data, (inst).
 % HLDS modules
 :- import_module hlds_module, hlds_pred, hlds_goal, hlds_data, instmap.
 
@@ -241,6 +241,10 @@
 	--->	yes(tvarset, vartypes)
 	;	no.
 
+	% Convert a mode or inst to a term representation.
+:- func mode_to_term(mode) = prog_term.
+:- func inst_to_term(inst) = prog_term.
+
 %-----------------------------------------------------------------------------%
 %-----------------------------------------------------------------------------%
 
@@ -3255,6 +3259,8 @@
 		[HeadTerm, mode_to_term(Context, Mode)],
 		Context, AnnotatedTerm).
 
+mode_to_term(Mode) = mode_to_term(term__context_init, Mode).
+
 :- func mode_to_term(term__context, mode) = prog_term.
 mode_to_term(Context, (InstA -> InstB)) = Term :-
 	( 
@@ -3283,6 +3289,8 @@
 
 :- func map_inst_to_term(prog_context, inst) = prog_term.
 map_inst_to_term(Context, Inst) = inst_to_term(Inst, Context).
+
+inst_to_term(Inst) = inst_to_term(Inst, term__context_init).
 
 :- func inst_to_term(inst, prog_context) = prog_term.
 inst_to_term(any(Uniq), Context) =
Index: compiler/recompilation_version.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/recompilation_version.m,v
retrieving revision 1.2
diff -u -u -r1.2 recompilation_version.m
--- compiler/recompilation_version.m	2001/07/11 15:44:21	1.2
+++ compiler/recompilation_version.m	2001/07/24 10:45:20
@@ -33,11 +33,13 @@
 %-----------------------------------------------------------------------------%
 :- implementation.
 
-:- import_module mercury_to_mercury, prog_io, prog_util.
-:- import_module assoc_list, bool, list, map, require, string.
+:- import_module mercury_to_mercury, mode_util, prog_io, prog_util, type_util.
+:- import_module hlds_out, (inst).
+:- import_module assoc_list, bool, list, map, require, string, varset.
 
 recompilation_version__compute_version_numbers(SourceFileTime, Items,
-		MaybeOldItems, version_numbers(ItemVersionNumbers, InstanceVersionNumbers)) :-
+		MaybeOldItems,
+		version_numbers(ItemVersionNumbers, InstanceVersionNumbers)) :-
 	recompilation_version__gather_items(Items,
 		GatheredItems, InstanceItems),
 	(
@@ -161,7 +163,7 @@
 		recompilation_version__add_gathered_item(Item,
 			item_id(ItemType, SymName - Arity),
 			ItemContext, AddIfNotExisting,
-			GatheredItems0, GatheredItems)
+			GatheredItems0, GatheredItems2)
 	;
 		MaybePredOrFunc = no,
 
@@ -174,9 +176,35 @@
 		recompilation_version__add_gathered_item(Item,
 			item_id(function, SymName - FuncArity),
 			ItemContext, AddIfNotExisting,
-			GatheredItems1, GatheredItems)
-	).
+			GatheredItems1, GatheredItems2)
+	),
 
+	% Pragmas can apply to typeclass methods.
+	map__map_values(
+	    (pred(_::in, ClassItems0::in, ClassItems::out) is det :-
+		( 
+			% Does this pragma match any of the methods
+			% of this class.
+			list__member(ClassItem, ClassItems0),
+			ClassItem = typeclass(_, _, _, Interface, _) - _,
+			Interface = concrete(Methods),
+			list__member(Method, Methods),
+			Method = pred_or_func(_, _, _, MethodPredOrFunc,
+				SymName, TypesAndModes, _, _, _, _, _),
+			( MaybePredOrFunc = yes(MethodPredOrFunc)
+			; MaybePredOrFunc = no
+			),
+			adjust_func_arity(MethodPredOrFunc,
+				Arity, list__length(TypesAndModes))
+		->
+			% XXX O(N^2), but shouldn't happen too often.
+			ClassItems = ClassItems0 ++ [ItemAndContext]
+		;
+			ClassItems = ClassItems0
+		)
+	    ), extract_ids(GatheredItems2, typeclass), GatheredTypeClasses),
+	GatheredItems = update_ids(GatheredItems2, typeclass,
+				GatheredTypeClasses).
 
 :- type gathered_item_info
 	--->	gathered_item_info(
@@ -305,16 +333,15 @@
 		Item = pred_or_func(TVarSet, InstVarSet, ExistQVars,
 			PredOrFunc, PredName, TypesAndModes, Det,
 			Cond, Purity, ClassContext),
-		split_types_and_modes(TypesAndModes,
-			Types, MaybeModes),
+		split_types_and_modes(TypesAndModes, Types, MaybeModes),
 		MaybeModes = yes(Modes)
 	->
 		TypesWithoutModes = list__map(
 			(func(Type) = type_only(Type)), Types),
-		PredOrFuncItem = pred_or_func(TVarSet, InstVarSet,
-			ExistQVars, PredOrFunc, PredName,
-			TypesWithoutModes, no, Cond, Purity,
-			ClassContext),
+		varset__init(EmptyInstVarSet),
+		PredOrFuncItem = pred_or_func(TVarSet, EmptyInstVarSet,
+			ExistQVars, PredOrFunc, PredName, TypesWithoutModes,
+			no, Cond, Purity, ClassContext),
 		PredOrFuncModeItem = pred_or_func_mode(InstVarSet,
 			PredOrFunc, PredName, Modes, Det, Cond),
 		MatchingItems =
@@ -361,7 +388,8 @@
 		TypesWithoutModes = TypesAndModes,
 		PredOrFuncModeItems = []
 	),
-	PredOrFuncItem = pred_or_func(TVarSet, InstVarSet,
+	varset__init(EmptyInstVarSet),
+	PredOrFuncItem = pred_or_func(TVarSet, EmptyInstVarSet,
 		ExistQVars, PredOrFunc, SymName,
 		TypesWithoutModes, no, Cond, Purity,
 		ClassContext, term__context_init),
@@ -407,9 +435,10 @@
 item_to_item_id_2(Item, yes(item_id((typeclass), ClassName - ClassArity))) :-
 	Item = typeclass(_, ClassName, ClassVars, _, _),
 	list__length(ClassVars, ClassArity).	
-item_to_item_id_2(Item, yes(item_id((typeclass), ClassName - ClassArity))) :-
-	Item = instance(_, ClassName, ClassArgs, _, _, _),
-	list__length(ClassArgs, ClassArity).	
+	% Instances are handled separately (unlike other items, the module
+	% qualifier on an instance declaration is the module containing
+	% the class, not the module containing the instance).
+item_to_item_id_2(instance(_, _, _, _, _, _), no).
 item_to_item_id_2(nothing(_), no).
 
 :- type maybe_pred_or_func_id ==
@@ -466,8 +495,229 @@
 :- pred items_are_unchanged(item_list::in, item_list::in) is semidet.
 
 items_are_unchanged([], []).
-items_are_unchanged([Item - _ | Items1], [Item - _ | Items2]) :-
+items_are_unchanged([Item1 - _ | Items1], [Item2 - _ | Items2]) :-
+	yes = item_is_unchanged(Item1, Item2),
 	items_are_unchanged(Items1, Items2).
+
+:- func item_is_unchanged(item, item) = bool.
+
+	% We don't need to compare the varsets. What matters is that
+	% the variable numbers in the arguments and body are the same,
+	% the names are irrelevant.
+	%
+	% It's important not to compare the varsets for type and instance
+	% declarations because the declarations we get here may be abstract
+	% declarations produced from concrete declarations for use in an
+	% interface file. The varsets may contain variables from the
+	% discarded bodies which will not be present in the items read
+	% in from the interface files for comparison. 
+	%
+	% This code assumes that the variables in the head of a
+	% type or instance declaration are added to the varset before
+	% those from the body, so that the variable numbers in the head of
+	% the declaration match those from an abstract declaration read
+	% from an interface file.
+item_is_unchanged(type_defn(_VarSet, Name, Args, Defn, Cond), Item2) =
+		( Item2 = type_defn(_, Name, Args, Defn, Cond) -> yes ; no ).
+item_is_unchanged(mode_defn(_VarSet, Name, Args, Defn, Cond), Item2) =
+		( Item2 = mode_defn(_, Name, Args, Defn, Cond) -> yes ; no ).
+item_is_unchanged(inst_defn(_VarSet, Name, Args, Defn, Cond), Item2) =
+		( Item2 = inst_defn(_, Name, Args, Defn, Cond) -> yes ; no ).
+item_is_unchanged(module_defn(_VarSet, Defn), Item2) =
+		( Item2 = module_defn(_, Defn) -> yes ; no ).
+item_is_unchanged(instance(Constraints, Name, Types, Body, _VarSet, Module),
+		Item2) =
+	( Item2 = instance(Constraints, Name, Types, Body, _, Module) ->
+		yes
+	;
+		no
+	).
+
+	% XXX Need to compare the goals properly in clauses and assertions.
+	% That's not necessary at the moment because smart recompilation
+	% doesn't work with inter-module optimization yet.
+item_is_unchanged(clause(_VarSet, PorF, SymName, Args, Goal), Item2) =
+		( Item2 = clause(_, PorF, SymName, Args, Goal) -> yes ; no ).
+item_is_unchanged(assertion(Goal, _VarSet), Item2) =
+		( Item2 = assertion(Goal, _) -> yes ; no ).
+
+item_is_unchanged(pragma(PragmaType), Item2) =
+		( Item2 = pragma(PragmaType) -> yes ; no ).
+item_is_unchanged(nothing(A), Item2) =
+		( Item2 = nothing(A) -> yes ; no ).
+
+item_is_unchanged(Item1, Item2) = Result :-
+	Item1 = pred_or_func(TVarSet1, _, ExistQVars1, PredOrFunc,
+		Name, TypesAndModes1, Detism, Cond, Purity, Constraints1),
+	(
+		Item2 = pred_or_func(TVarSet2, _, ExistQVars2,
+			PredOrFunc, Name, TypesAndModes2, Detism, Cond, Purity,
+			Constraints2),
+		pred_or_func_type_is_unchanged(TVarSet1, ExistQVars1,
+			TypesAndModes1, Constraints1, TVarSet2,
+			ExistQVars2, TypesAndModes2, Constraints2)
+	->
+		Result = yes
+	;
+		Result = no
+	).
+
+item_is_unchanged(Item1, Item2) = Result :-
+	Item1 = pred_or_func_mode(InstVarSet1, PredOrFunc, Name, Modes1,
+			Det, Cond),
+	(
+		Item2 = pred_or_func_mode(InstVarSet2, PredOrFunc,
+			Name, Modes2, Det, Cond),
+		pred_or_func_mode_is_unchanged(InstVarSet1, Modes1,
+			InstVarSet2, Modes2)
+	->
+		Result = yes
+	;
+		Result = no
+	).
+
+
+item_is_unchanged(Item1, Item2) = Result :-
+	Item1 = typeclass(Constraints, Name, Vars, Interface1, _VarSet),
+	(
+		Item2 = typeclass(Constraints, Name, Vars, Interface2, _),
+		class_interface_is_unchanged(Interface1, Interface2)
+	->
+		Result = yes
+	;
+		Result = no
+	).
+
+	%
+	% Apply a substitution to the existq_tvars, types_and_modes, and
+	% class_constraints so that the type variables from both declarations
+	% being checked are contained in the same tvarset, then check that
+	% they are identical.
+	%
+	% We can't just assume that the varsets will be identical for
+	% identical declarations because mercury_to_mercury.m splits
+	% combined type and mode declarations into separate declarations.
+	% When they are read back in the variable numbers will be different
+	% because parser stores the type and inst variables for a combined
+	% declaration in a single varset (it doesn't know which are which).
+	%
+:- pred pred_or_func_type_is_unchanged(tvarset::in, existq_tvars::in,
+		list(type_and_mode)::in, class_constraints::in,
+		tvarset::in, existq_tvars::in, list(type_and_mode)::in,
+		class_constraints::in) is semidet. 
+
+pred_or_func_type_is_unchanged(TVarSet1, ExistQVars1, TypesAndModes1,
+		Constraints1, TVarSet2, ExistQVars2,
+		TypesAndModes2, Constraints2) :-
+
+	varset__merge_subst(TVarSet1, TVarSet2, _, Subst),
+
+	GetArgTypes =
+		(func(TypeAndMode0) = Type :-
+			(
+				TypeAndMode0 = type_only(Type)
+			;
+				% This should have been split out into a
+				% separate mode declaration by gather_items.
+				TypeAndMode0 = type_and_mode(_, _),
+				error(
+			"pred_or_func_type_matches: type_and_mode")
+			)
+		),
+	Types1 = list__map(GetArgTypes, TypesAndModes1),
+	Types2 = list__map(GetArgTypes, TypesAndModes2),
+	term__apply_substitution_to_list(Types2, Subst, SubstTypes2),
+
+	%
+	% Check that the types are equivalent
+	%
+	type_list_subsumes(SubstTypes2, Types1, Types2ToTypes1Subst),
+	type_list_subsumes(Types1, SubstTypes2, _),
+
+	%
+	% Check that the existentially quantified variables are equivalent.
+	%
+	SubstExistQVars2 =
+		term_list_to_var_list(
+			term__apply_rec_substitution_to_list(
+				apply_substitution_to_list(
+					var_list_to_term_list(ExistQVars2),
+					Subst),
+				Types2ToTypes1Subst)),
+	ExistQVars1 = SubstExistQVars2,
+
+	%
+	% Check that the class constraints are identical.
+	%
+	apply_subst_to_constraints(Subst, Constraints2, RenamedConstraints2),
+	apply_rec_subst_to_constraints(Types2ToTypes1Subst,
+		RenamedConstraints2, SubstConstraints2),
+	Constraints1 = SubstConstraints2.
+
+:- pred pred_or_func_mode_is_unchanged(inst_varset::in, list(mode)::in,
+		inst_varset::in, list(mode)::in) is semidet.
+
+pred_or_func_mode_is_unchanged(InstVarSet1, Modes1, InstVarSet2, Modes2) :-
+	varset__coerce(InstVarSet1, VarSet1),
+	varset__coerce(InstVarSet2, VarSet2),
+
+	%
+	% Apply the substitution to the modes so that the inst variables
+	% from both declarations being checked are contained in the same
+	% inst_varset, then check that they are identical.
+	%
+	varset__merge_subst(VarSet1, VarSet2, _, InstSubst),
+
+	%
+	% Treat modes as types here to use type_list_subsumes, which
+	% does just what we want here. (XXX shouldn't type_list_subsumes
+	% be in term.m and apply to generic terms anyway?).
+	%
+	ModeToTerm = (func(Mode) = term__coerce(mode_to_term(Mode))),
+	ModeTerms1 = list__map(ModeToTerm, Modes1),
+	ModeTerms2 = list__map(ModeToTerm, Modes2),
+	term__apply_substitution_to_list(ModeTerms2,
+		InstSubst, SubstModeTerms2),
+	type_list_subsumes(ModeTerms1, SubstModeTerms2, _),
+	type_list_subsumes(SubstModeTerms2, ModeTerms1, _).
+
+	%
+	% Combined typeclass method type and mode declarations are split
+	% as for ordinary predicate declarations, so the varsets won't
+	% necessarily match up if a typeclass declration is read back
+	% from an interface file.
+	%
+:- pred class_interface_is_unchanged(class_interface::in,
+		class_interface::in) is semidet.
+
+class_interface_is_unchanged(abstract, abstract).
+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.
+
+class_methods_are_unchanged([], []).
+class_methods_are_unchanged([Method1 | Methods1], [Method2 | Methods2]) :-
+	(
+		Method1 = pred_or_func(TVarSet1, _, ExistQVars1, PredOrFunc,
+			Name, TypesAndModes1, Detism, Cond, Purity,
+			Constraints1, _),
+		Method2 = pred_or_func(TVarSet2, _, ExistQVars2, PredOrFunc,
+			Name, TypesAndModes2, Detism, Cond, Purity,
+			Constraints2, _),
+		pred_or_func_type_is_unchanged(TVarSet1, ExistQVars1,
+			TypesAndModes1, Constraints1, TVarSet2, ExistQVars2,
+			TypesAndModes2, Constraints2)
+	;
+		Method1 = pred_or_func_mode(InstVarSet1, PredOrFunc, Name,
+			Modes1, Det, Cond, _),
+		Method2 = pred_or_func_mode(InstVarSet2, PredOrFunc, Name,
+			Modes2, Det, Cond, _),
+		pred_or_func_mode_is_unchanged(InstVarSet1, Modes1,
+			InstVarSet2, Modes2)
+	),
+	class_methods_are_unchanged(Methods1, Methods2).
 
 %-----------------------------------------------------------------------------%
 
Index: tests/recompilation/Mmakefile
===================================================================
RCS file: /home/mercury1/repository/tests/recompilation/Mmakefile,v
retrieving revision 1.4
diff -u -u -r1.4 Mmakefile
--- tests/recompilation/Mmakefile	2001/07/12 07:55:11	1.4
+++ tests/recompilation/Mmakefile	2001/07/24 07:45:03
@@ -19,6 +19,10 @@
 should_run_recompilation_tests:
 	@echo $(RUN_RECOMPILATION_TESTS)
 
+	# typeclass_method_pragma_r calls a predicate with a
+	# `:- pragma obsolete' declaration.
+MCFLAGS-typeclass_method_pragma_r = --no-halt-at-warn
+
 # Smart recompilation doesn't yet work with --intermodule-optimization.
 # The `override' is needed because otherwise make ignores the assignment if
 # EXTRA_MCFLAGS is set on the command line, as it is for the nightly tests.
Index: tests/recompilation/TESTS
===================================================================
RCS file: /home/mercury1/repository/tests/recompilation/TESTS,v
retrieving revision 1.2
diff -u -u -r1.2 TESTS
--- tests/recompilation/TESTS	2001/07/12 07:55:11	1.2
+++ tests/recompilation/TESTS	2001/07/24 09:50:35
@@ -10,6 +10,8 @@
 	change_class_r \
 	change_instance_r \
 	change_mode_r \
+	change_type_nr \
+	combined_type_mode_nr \
 	field_r \
 	func_overloading_nr \
 	func_overloading_r \
@@ -17,7 +19,8 @@
 	no_version_numbers_r \
 	pragma_type_spec_r \
 	pred_ctor_ambiguity_r \
-	pred_overloading_r"
+	pred_overloading_r \
+	typeclass_method_pragma_r"
 
 # Parallel mmake with nested sub-modules is broken.
 # The commands to create `.c' files from the `.m' file containing the
@@ -32,4 +35,4 @@
 	remove_type_re \
 	type_qual_re"
 
-ALL_TESTS=$TESTS_SHOULD_SUCCEED $NO_PARALLEL_MAKE_TESTS $TESTS_SHOULD_FAIL
+ALL_TESTS="$TESTS_SHOULD_SUCCEED $NO_PARALLEL_MAKE_TESTS $TESTS_SHOULD_FAIL"
Index: tests/recompilation/change_type_nr.err_exp.2
===================================================================
RCS file: change_type_nr.err_exp.2
diff -N change_type_nr.err_exp.2
--- /dev/null	Mon Apr 16 11:57:05 2001
+++ change_type_nr.err_exp.2	Tue Jul 24 19:59:27 2001
@@ -0,0 +1 @@
+Not recompiling module change_type_nr.
Index: tests/recompilation/change_type_nr.exp.1
===================================================================
RCS file: change_type_nr.exp.1
diff -N change_type_nr.exp.1
--- /dev/null	Mon Apr 16 11:57:05 2001
+++ change_type_nr.exp.1	Tue Jul 24 19:51:40 2001
@@ -0,0 +1 @@
+a
Index: tests/recompilation/change_type_nr.exp.2
===================================================================
RCS file: change_type_nr.exp.2
diff -N change_type_nr.exp.2
--- /dev/null	Mon Apr 16 11:57:05 2001
+++ change_type_nr.exp.2	Tue Jul 24 19:51:44 2001
@@ -0,0 +1 @@
+a
Index: tests/recompilation/change_type_nr.m.1
===================================================================
RCS file: change_type_nr.m.1
diff -N change_type_nr.m.1
--- /dev/null	Mon Apr 16 11:57:05 2001
+++ change_type_nr.m.1	Tue Jul 24 19:47:09 2001
@@ -0,0 +1,16 @@
+:- module change_type_nr.
+
+:- interface.
+
+:- import_module io.
+
+:- pred main(io__state::di, io__state::uo) is det.
+
+:- implementation.
+
+:- import_module change_type_nr_3.
+
+main -->
+	io__write(a `with_type` foo),
+	io__nl.
+
Index: tests/recompilation/change_type_nr_2.err_exp.2
===================================================================
RCS file: change_type_nr_2.err_exp.2
diff -N change_type_nr_2.err_exp.2
--- /dev/null	Mon Apr 16 11:57:05 2001
+++ change_type_nr_2.err_exp.2	Tue Jul 24 19:51:44 2001
@@ -0,0 +1,2 @@
+Recompiling module `change_type_nr_2':
+  file `change_type_nr_2.m' has changed.
Index: tests/recompilation/change_type_nr_2.m.1
===================================================================
RCS file: change_type_nr_2.m.1
diff -N change_type_nr_2.m.1
--- /dev/null	Mon Apr 16 11:57:05 2001
+++ change_type_nr_2.m.1	Tue Jul 24 19:50:13 2001
@@ -0,0 +1,16 @@
+% This module is indirectly imported from change_type_nr.m
+% (via change_type_nr_3.m).
+% 
+% The update for this module does not change the file, only its timestamp.
+% This checks that the extra type variable in the body of foo2 does not
+% cause problems with the code in recompilation_version.m to check whether
+% an item has changed.
+:- module change_type_nr_2.
+
+:- interface.
+
+:- type foo2
+	--->	c
+	;	some [T] d(T)
+	.
+
Index: tests/recompilation/change_type_nr_2.m.2
===================================================================
RCS file: change_type_nr_2.m.2
diff -N change_type_nr_2.m.2
--- /dev/null	Mon Apr 16 11:57:05 2001
+++ change_type_nr_2.m.2	Tue Jul 24 19:58:18 2001
@@ -0,0 +1,17 @@
+% This module is indirectly imported from change_type_nr.m
+% (via change_type_nr_3.m) so that change_type_nr.m uses the
+% abstract declaration of foo2 from change_type_nr_2.int2.
+% 
+% This test checks that the extra type variable in the body of foo2 does not
+% cause problems with the code in recompilation_version.m to check whether
+% an item has changed.
+:- module change_type_nr_2.
+
+:- interface.
+
+:- type foo2
+	--->	c
+	;	some [T] d(T)
+	.
+
+:- type t == int.
Index: tests/recompilation/change_type_nr_3.m
===================================================================
RCS file: change_type_nr_3.m
diff -N change_type_nr_3.m
--- /dev/null	Mon Apr 16 11:57:05 2001
+++ change_type_nr_3.m	Tue Jul 24 19:46:58 2001
@@ -0,0 +1,16 @@
+:- module change_type_nr_3.
+
+:- interface.
+
+:- import_module change_type_nr_2.
+
+:- type foo
+	--->	a
+	;	b(foo2).
+
+:- pred init(foo::out) is det.
+
+:- implementation.
+
+init(a).
+
Index: tests/recompilation/combined_type_mode_nr.err_exp.2
===================================================================
RCS file: combined_type_mode_nr.err_exp.2
diff -N combined_type_mode_nr.err_exp.2
--- /dev/null	Mon Apr 16 11:57:05 2001
+++ combined_type_mode_nr.err_exp.2	Tue Jul 24 17:06:48 2001
@@ -0,0 +1 @@
+Not recompiling module combined_type_mode_nr.
Index: tests/recompilation/combined_type_mode_nr.exp.1
===================================================================
RCS file: combined_type_mode_nr.exp.1
diff -N combined_type_mode_nr.exp.1
--- /dev/null	Mon Apr 16 11:57:05 2001
+++ combined_type_mode_nr.exp.1	Tue Jul 24 17:04:26 2001
@@ -0,0 +1 @@
+1
Index: tests/recompilation/combined_type_mode_nr.exp.2
===================================================================
RCS file: combined_type_mode_nr.exp.2
diff -N combined_type_mode_nr.exp.2
--- /dev/null	Mon Apr 16 11:57:05 2001
+++ combined_type_mode_nr.exp.2	Tue Jul 24 17:04:30 2001
@@ -0,0 +1 @@
+1
Index: tests/recompilation/combined_type_mode_nr.m.1
===================================================================
RCS file: combined_type_mode_nr.m.1
diff -N combined_type_mode_nr.m.1
--- /dev/null	Mon Apr 16 11:57:05 2001
+++ combined_type_mode_nr.m.1	Tue Jul 24 19:33:25 2001
@@ -0,0 +1,16 @@
+:- module combined_type_mode_nr.
+
+:- interface.
+
+:- import_module io.
+
+:- pred main(io__state::di, io__state::uo) is det.
+
+:- implementation.
+
+:- import_module combined_type_mode_nr_2.
+
+main -->
+	{ p(1, Result) },
+	output(Result, _, Result),
+	io__nl.
Index: tests/recompilation/combined_type_mode_nr_2.err_exp.2
===================================================================
RCS file: combined_type_mode_nr_2.err_exp.2
diff -N combined_type_mode_nr_2.err_exp.2
--- /dev/null	Mon Apr 16 11:57:05 2001
+++ combined_type_mode_nr_2.err_exp.2	Tue Jul 24 17:04:30 2001
@@ -0,0 +1,2 @@
+Recompiling module `combined_type_mode_nr_2':
+  file `combined_type_mode_nr_2.m' has changed.
Index: tests/recompilation/combined_type_mode_nr_2.m.1
===================================================================
RCS file: combined_type_mode_nr_2.m.1
diff -N combined_type_mode_nr_2.m.1
--- /dev/null	Mon Apr 16 11:57:05 2001
+++ combined_type_mode_nr_2.m.1	Tue Jul 24 19:23:26 2001
@@ -0,0 +1,22 @@
+:- module combined_type_mode_nr_2.
+
+:- interface.
+
+:- import_module io.
+
+:- pred p(T::in(I), T::out(I)) is det.
+
+:- typeclass io(T) where [
+	pred id(T::in(I), T::out(I)) is det,
+	some [U] pred output(T::in(I), U::out(I), T::in,
+			io__state::di, io__state::uo) is det
+].
+
+:- instance io(int) where [
+	id(T, T),
+	(output(U, U, T) --> io__write(T))
+].
+
+:- implementation.
+
+p(T, T).
Index: tests/recompilation/combined_type_mode_nr_2.m.2
===================================================================
RCS file: combined_type_mode_nr_2.m.2
diff -N combined_type_mode_nr_2.m.2
--- /dev/null	Mon Apr 16 11:57:05 2001
+++ combined_type_mode_nr_2.m.2	Tue Jul 24 19:23:55 2001
@@ -0,0 +1,24 @@
+:- module combined_type_mode_nr_2.
+
+:- interface.
+
+:- import_module io.
+
+:- pred p(T::in(I), T::out(I)) is det.
+
+:- typeclass io(T) where [
+	pred id(T::in(I), T::out(I)) is det,
+	some [U] pred output(T::in(I), U::out(I), T::in,
+			io__state::di, io__state::uo) is det
+].
+
+:- instance io(int) where [
+	id(T, T),
+	(output(U, U, T) --> io__write(T))
+].
+
+:- type t == int.
+
+:- implementation.
+
+p(T, T).
Index: tests/recompilation/typeclass_method_pragma_r.err_exp.2
===================================================================
RCS file: typeclass_method_pragma_r.err_exp.2
diff -N typeclass_method_pragma_r.err_exp.2
--- /dev/null	Mon Apr 16 11:57:05 2001
+++ typeclass_method_pragma_r.err_exp.2	Tue Jul 24 17:42:24 2001
@@ -0,0 +1,3 @@
+Recompiling module `typeclass_method_pragma_r':
+  typeclass `typeclass_method_pragma_r_2:io/1' was modified.
+typeclass_method_pragma_r.m:015: Warning: call to obsolete predicate `typeclass_method_pragma_r_2:output/3'.
Index: tests/recompilation/typeclass_method_pragma_r.exp.1
===================================================================
RCS file: typeclass_method_pragma_r.exp.1
diff -N typeclass_method_pragma_r.exp.1
--- /dev/null	Mon Apr 16 11:57:05 2001
+++ typeclass_method_pragma_r.exp.1	Tue Jul 24 17:40:34 2001
@@ -0,0 +1 @@
+a
Index: tests/recompilation/typeclass_method_pragma_r.exp.2
===================================================================
RCS file: typeclass_method_pragma_r.exp.2
diff -N typeclass_method_pragma_r.exp.2
--- /dev/null	Mon Apr 16 11:57:05 2001
+++ typeclass_method_pragma_r.exp.2	Tue Jul 24 17:40:37 2001
@@ -0,0 +1 @@
+a
Index: tests/recompilation/typeclass_method_pragma_r.m.1
===================================================================
RCS file: typeclass_method_pragma_r.m.1
diff -N typeclass_method_pragma_r.m.1
--- /dev/null	Mon Apr 16 11:57:05 2001
+++ typeclass_method_pragma_r.m.1	Tue Jul 24 17:40:27 2001
@@ -0,0 +1,17 @@
+:- module typeclass_method_pragma_r.
+
+:- interface.
+
+:- import_module io.
+
+:- pred main(io__state::di, io__state::uo) is det.
+
+:- implementation.
+
+:- import_module typeclass_method_pragma_r_2.
+
+main -->
+	{ init_foo(X) },
+	output(X),
+	io__nl.
+
Index: tests/recompilation/typeclass_method_pragma_r_2.err_exp.2
===================================================================
RCS file: typeclass_method_pragma_r_2.err_exp.2
diff -N typeclass_method_pragma_r_2.err_exp.2
--- /dev/null	Mon Apr 16 11:57:05 2001
+++ typeclass_method_pragma_r_2.err_exp.2	Tue Jul 24 17:46:25 2001
@@ -0,0 +1,2 @@
+Recompiling module `typeclass_method_pragma_r_2':
+  file `typeclass_method_pragma_r_2.m' has changed.
Index: tests/recompilation/typeclass_method_pragma_r_2.m.1
===================================================================
RCS file: typeclass_method_pragma_r_2.m.1
diff -N typeclass_method_pragma_r_2.m.1
--- /dev/null	Mon Apr 16 11:57:05 2001
+++ typeclass_method_pragma_r_2.m.1	Tue Jul 24 17:38:44 2001
@@ -0,0 +1,24 @@
+:- module typeclass_method_pragma_r_2.
+
+:- interface.
+
+:- import_module io.
+
+:- type foo
+	--->	a
+	;	b(int).
+
+:- pred init_foo(foo::out) is det.
+
+:- typeclass io(T) where [
+	pred output(T::in, io__state::di, io__state::uo) is det
+].
+
+:- instance io(foo) where [
+	pred(output/3) is io__write
+].
+
+:- implementation.
+
+init_foo(a).
+
Index: tests/recompilation/typeclass_method_pragma_r_2.m.2
===================================================================
RCS file: typeclass_method_pragma_r_2.m.2
diff -N typeclass_method_pragma_r_2.m.2
--- /dev/null	Mon Apr 16 11:57:05 2001
+++ typeclass_method_pragma_r_2.m.2	Tue Jul 24 17:41:55 2001
@@ -0,0 +1,25 @@
+:- module typeclass_method_pragma_r_2.
+
+:- interface.
+
+:- import_module io.
+
+:- type foo
+	--->	a
+	;	b(int).
+
+:- pred init_foo(foo::out) is det.
+
+:- typeclass io(T) where [
+	pred output(T::in, io__state::di, io__state::uo) is det
+].
+:- pragma obsolete(output/3).
+
+:- instance io(foo) where [
+	pred(output/3) is io__write
+].
+
+:- implementation.
+
+init_foo(a).
+
--------------------------------------------------------------------------
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