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

Simon Taylor stayl at cs.mu.OZ.AU
Wed Jul 25 03:32:04 AEST 2001


On 24-Jul-2001, Fergus Henderson <fjh at cs.mu.OZ.AU> wrote:
> On 24-Jul-2001, Simon Taylor <stayl at cs.mu.OZ.AU> wrote:
> > 
> > +:- 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.
> 
> Hmm, that looks wrong to me.  Maybe you're not aware of the following sentence
> from the Mercury language reference manual:
> 
>  | The scope of type variables in a predicate or function's type
>  | declaration extends over any explicit type qualifications in the
>  | clauses for that predicate or function, so explicit type qualifications
>  | can refer to those type variables.
> 
> So if, for example, you write
> 
> 	:- module example.
> 	:- interface.
> 	:- import_module io.
> 
> 	:- pred main(io__state::di, io__state::uo) is det.
> 
> 	:- implementation.
> 
> 	main --> foo(0, "").
> 
> 	:- pred foo(T1, T2, io__state, io__state).
> 	:- mode foo(in, in, di, uo) is det.
> 
> 	foo(_, _) -->
> 		io__read(R `with_type` io__read_result(T1)),
> 		io__print(R),
> 		io__nl.
> 
> and then you change the pred declaration for `foo' to
> 
> 	:- pred foo(T2, T1, io__state, io__state).
> 
> then the resulting program will behave differently.

But to do that you have to modify the `.m' file, which will cause
the module to be recompiled.

The only other place where the names of variables matters is in
`:- pragma type_spec' declarations. My change did break the
handling of those.

Simon.

Estimated hours taken: 1
Branches: main

Fix a bug in my last change.

compiler/recompilation_version.m:
	My last change assumed that the names of variables do not
	matter. That is incorrect in the case of explicit type
	qualification and `:- pragma type_spec' declarations.
	recompilation_version.m only deals with items in interface
	files, so explicit type qualification does not need to
	be considered. For `:- pragma type_spec' declarations to
	work we need to consider a predicate or function declaration
	changed if the names of the type variables in the predicate
	declaration change.

tests/recompilation/TESTS:
tests/recompilation/type_spec_rename_var_r*:
	Test case.

Index: compiler/recompilation_version.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/recompilation_version.m,v
retrieving revision 1.3
diff -u -u -r1.3 recompilation_version.m
--- compiler/recompilation_version.m	2001/07/24 10:47:16	1.3
+++ compiler/recompilation_version.m	2001/07/24 16:52:44
@@ -499,11 +499,20 @@
 	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.
+	% In most places here, 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 usually irrelevant.
+	%
+	% The only places where the names of variables affect the
+	% compilation of the program are in explicit type qualifications
+	% and `:- pragma type_spec' declarations. Explicit type
+	% qualifications do not need to be considered here. This module
+	% only deals with items in interface files (we don't yet write type
+	% qualifications to `.opt' files). Variables in type qualifications
+	% are only matched with the head type variables of the predicate
+	% by make_hlds.m. For `:- pragma type_spec' declarations to work
+	% we need to consider a predicate or function declaration to be
+	% changed if the names of any of the type variables are changed.
 	%
 	% It's important not to compare the varsets for type and instance
 	% declarations because the declarations we get here may be abstract
@@ -517,6 +526,8 @@
 	% 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.
+:- func item_is_unchanged(item, item) = bool.
+
 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) =
@@ -541,6 +552,10 @@
 item_is_unchanged(assertion(Goal, _VarSet), Item2) =
 		( Item2 = assertion(Goal, _) -> yes ; no ).
 
+	% We do need to compare the varset in `:- pragma type_spec'
+	% declarations because the names of the variables are used
+	% to find the corresponding variables in the predicate or
+	% function type declaration.
 item_is_unchanged(pragma(PragmaType), Item2) =
 		( Item2 = pragma(PragmaType) -> yes ; no ).
 item_is_unchanged(nothing(A), Item2) =
@@ -610,7 +625,7 @@
 		Constraints1, TVarSet2, ExistQVars2,
 		TypesAndModes2, Constraints2) :-
 
-	varset__merge_subst(TVarSet1, TVarSet2, _, Subst),
+	varset__merge_subst(TVarSet1, TVarSet2, TVarSet, Subst),
 
 	GetArgTypes =
 		(func(TypeAndMode0) = Type :-
@@ -633,6 +648,33 @@
 	%
 	type_list_subsumes(SubstTypes2, Types1, Types2ToTypes1Subst),
 	type_list_subsumes(Types1, SubstTypes2, _),
+
+	%
+	% Check that the corresponding variables have the same names.
+	% This is necessary because `:- pragma type_spec' declarations
+	% depend on the names of the variables, so for example if two
+	% variable names are swapped, the same `:- pragma type_spec'
+	% declaration will cause a different specialized version to be
+	% created.
+	%
+	( all [VarInItem1, VarInItem2]
+	    (
+		map__member(Types2ToTypes1Subst, VarInItem2, SubstTerm),
+		(
+			SubstTerm = term__variable(VarInItem1)
+		;
+			% The reverse subsumption test above should
+			% ensure that the substitutions are all var->var.
+			SubstTerm = term__functor(_, _, _),
+			error("pred_or_func_type_matches: invalid subst")
+		)
+	    )
+	=>
+	    (
+		varset__lookup_name(TVarSet, VarInItem1, VarName),
+		varset__lookup_name(TVarSet, VarInItem2, VarName)
+	    )
+	),
 
 	%
 	% Check that the existentially quantified variables are equivalent.
Index: tests/recompilation/TESTS
===================================================================
RCS file: /home/mercury1/repository/tests/recompilation/TESTS,v
retrieving revision 1.3
diff -u -u -r1.3 TESTS
--- tests/recompilation/TESTS	2001/07/24 10:47:21	1.3
+++ tests/recompilation/TESTS	2001/07/24 15:18:14
@@ -20,7 +20,8 @@
 	pragma_type_spec_r \
 	pred_ctor_ambiguity_r \
 	pred_overloading_r \
-	typeclass_method_pragma_r"
+	typeclass_method_pragma_r \
+	type_spec_rename_var_r"
 
 # Parallel mmake with nested sub-modules is broken.
 # The commands to create `.c' files from the `.m' file containing the
Index: tests/recompilation/type_spec_rename_var_r.err_exp.2
===================================================================
RCS file: type_spec_rename_var_r.err_exp.2
diff -N type_spec_rename_var_r.err_exp.2
--- /dev/null	Mon Apr 16 11:57:05 2001
+++ type_spec_rename_var_r.err_exp.2	Wed Jul 25 01:21:34 2001
@@ -0,0 +1,2 @@
+Recompiling module `type_spec_rename_var_r':
+  predicate `type_spec_rename_var_r_2:p/3' was modified.
Index: tests/recompilation/type_spec_rename_var_r.exp.1
===================================================================
RCS file: type_spec_rename_var_r.exp.1
diff -N type_spec_rename_var_r.exp.1
--- /dev/null	Mon Apr 16 11:57:05 2001
+++ type_spec_rename_var_r.exp.1	Wed Jul 25 01:21:30 2001
@@ -0,0 +1 @@
+1 - 2.00000000000000
Index: tests/recompilation/type_spec_rename_var_r.exp.2
===================================================================
RCS file: type_spec_rename_var_r.exp.2
diff -N type_spec_rename_var_r.exp.2
--- /dev/null	Mon Apr 16 11:57:05 2001
+++ type_spec_rename_var_r.exp.2	Wed Jul 25 01:21:34 2001
@@ -0,0 +1 @@
+1 - 2.00000000000000
Index: tests/recompilation/type_spec_rename_var_r.m.1
===================================================================
RCS file: type_spec_rename_var_r.m.1
diff -N type_spec_rename_var_r.m.1
--- /dev/null	Mon Apr 16 11:57:05 2001
+++ type_spec_rename_var_r.m.1	Wed Jul 25 01:19:48 2001
@@ -0,0 +1,16 @@
+:- module type_spec_rename_var_r.
+
+:- interface.
+
+:- import_module io.
+
+:- pred main(io__state::di, io__state::uo) is det.
+
+:- implementation.
+
+:- import_module type_spec_rename_var_r_2.
+
+main -->
+	{ p(1, 2.0, Result) },
+	io__write(Result),
+	io__nl.
Index: tests/recompilation/type_spec_rename_var_r_2.err_exp.2
===================================================================
RCS file: type_spec_rename_var_r_2.err_exp.2
diff -N type_spec_rename_var_r_2.err_exp.2
--- /dev/null	Mon Apr 16 11:57:05 2001
+++ type_spec_rename_var_r_2.err_exp.2	Wed Jul 25 01:21:34 2001
@@ -0,0 +1,2 @@
+Recompiling module `type_spec_rename_var_r_2':
+  file `type_spec_rename_var_r_2.m' has changed.
Index: tests/recompilation/type_spec_rename_var_r_2.m.1
===================================================================
RCS file: type_spec_rename_var_r_2.m.1
diff -N type_spec_rename_var_r_2.m.1
--- /dev/null	Mon Apr 16 11:57:05 2001
+++ type_spec_rename_var_r_2.m.1	Wed Jul 25 01:21:15 2001
@@ -0,0 +1,12 @@
+:- module type_spec_rename_var_r_2.
+
+:- interface.
+
+:- import_module std_util.
+
+:- pred p(T::in, U::in, pair(T, U)::out) is det.
+:- pragma type_spec(p/3, T = int).
+
+:- implementation.
+
+p(T, U, T - U).
Index: tests/recompilation/type_spec_rename_var_r_2.m.2
===================================================================
RCS file: type_spec_rename_var_r_2.m.2
diff -N type_spec_rename_var_r_2.m.2
--- /dev/null	Mon Apr 16 11:57:05 2001
+++ type_spec_rename_var_r_2.m.2	Wed Jul 25 01:21:23 2001
@@ -0,0 +1,12 @@
+:- module type_spec_rename_var_r_2.
+
+:- interface.
+
+:- import_module std_util.
+
+:- pred p(U::in, T::in, pair(U, T)::out) is det.
+:- pragma type_spec(p/3, T = int).
+
+:- implementation.
+
+p(T, U, T - U).
--------------------------------------------------------------------------
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