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

Simon Taylor stayl at cs.mu.OZ.AU
Wed Oct 24 15:57:07 AEST 2001


Estimated hours taken: 1
Branches: main

Fix bugs in the handling of nested sub-modules with --smart-recompilation.

compiler/recompilation_check.m:
	If an error occurs before the nested sub-modules of the top-level
	module are known, recompile all of the nested sub-modules.

	If there is a syntax error in a `.used' file, recompile all
	sub-modules. This makes the above change simpler, and is probably
	a good idea anyway -- all outputs from a compilation which produces
	output files containing syntax errors are suspect.

compiler/mercury_compile.m:
	When working out the list of sub-modules of the main module
	in a source file, use all the sub-modules, not just the ones
	that are being recompiled.

tests/recompilation/Mmakefile:
tests/recompilation/TESTS:
tests/recompilation/nested_module_2_r*:
	Test case.

Index: compiler/mercury_compile.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/mercury_compile.m,v
retrieving revision 1.220
diff -u -u -r1.220 mercury_compile.m
--- compiler/mercury_compile.m	2 Oct 2001 07:09:43 -0000	1.220
+++ compiler/mercury_compile.m	23 Oct 2001 08:25:31 -0000
@@ -721,11 +721,11 @@
 					list__member(SubModule,
 						ModulesToRecompile)
 				),
-				SubModuleList0, SubModuleList)
+				SubModuleList0, SubModuleListToCompile)
 		;
-				SubModuleList = SubModuleList0	
+				SubModuleListToCompile = SubModuleList0	
 		},
-		{ assoc_list__keys(SubModuleList, NestedSubModules0) },
+		{ assoc_list__keys(SubModuleList0, NestedSubModules0) },
 		{ list__delete_all(NestedSubModules0,
 			ModuleName, NestedSubModules) },
 
@@ -751,7 +751,7 @@
 			compile_all_submodules(FileName,
 				ModuleName - NestedSubModules,
 				MaybeTimestamp, ReadModules,
-				FindTimestampFiles, SubModuleList,
+				FindTimestampFiles, SubModuleListToCompile,
 				ModulesToLink),
 
 			globals__io_set_option(trace_stack_layout, bool(TSL)),
@@ -760,7 +760,7 @@
 			compile_all_submodules(FileName,
 				ModuleName - NestedSubModules,
 				MaybeTimestamp, ReadModules,
-				FindTimestampFiles, SubModuleList,
+				FindTimestampFiles, SubModuleListToCompile,
 				ModulesToLink)
 		)
 	).
Index: compiler/recompilation_check.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/recompilation_check.m,v
retrieving revision 1.4
diff -u -u -r1.4 recompilation_check.m
--- compiler/recompilation_check.m	16 Jul 2001 08:21:05 -0000	1.4
+++ compiler/recompilation_check.m	24 Oct 2001 05:32:01 -0000
@@ -131,7 +131,7 @@
 		io__set_input_stream(OldInputStream, VersionStream),
 		io__close_input(VersionStream),
 
-		( { (all) = Info1 ^ modules_to_recompile } ->
+		( { (all) = Info4 ^ modules_to_recompile } ->
 			{ Info = Info4 }
 		;
 			{ Info5 = Info4 ^ is_inline_sub_module := yes },
@@ -158,6 +158,15 @@
 
 recompilation_check__should_recompile_3(IsSubModule, FindTargetFiles,
 		Info0, Info) -->
+
+	%
+	% WARNING: any exceptions thrown before the sub_modules
+	% field is set in the recompilation_check_info must set
+	% the modules_to_recompile field to `all', or else
+	% the nested sub-modules will not be checked and necessary
+	% recompilations may be missed.
+	%
+
 	%
 	% Check that the format of the usage file is the current format.
 	%
@@ -179,11 +188,11 @@
 		[]
 	;
 		io__input_stream_name(UsageFileName),
-		{ throw(recompile_exception(
+		{ throw_syntax_error(
 			file_error(UsageFileName,
 				"invalid usage file version number in file `"
 				++ UsageFileName ++ "'."),
-			Info0)) }
+			Info0) }
 	), 
 
 	%
@@ -213,46 +222,27 @@
 		->
 			record_read_file(ModuleName,
 				ModuleTimestamp ^ timestamp := NewTimestamp,
-				Items, Error, FileName, Info0, ErrorInfo),
+				Items, Error, FileName, Info0, RecompileInfo0),
+			RecompileInfo =
+				RecompileInfo0 ^ modules_to_recompile := (all),
 			throw(recompile_exception(module_changed(FileName),
-					ErrorInfo))
+					RecompileInfo))
 		;
 			( Error \= no_module_errors
 			; MaybeNewTimestamp = no
 			)
 		->
-			throw(recompile_exception(
+			throw_syntax_error(
 				file_error(FileName,
 				    "error reading file `"
 				    ++ FileName ++ "'."),
-				Info0))
+				Info0)
 		;
 			true
 		}
 	),
 
 	%
-	% Check whether the output files are present and up-to-date.
-	%
-	FindTargetFiles(Info0 ^ module_name, TargetFiles),
-	list__foldl(
-	    (pred(TargetFile::in, di, uo) is det -->
-		io__file_modification_time(TargetFile, TargetModTimeResult),
-		(
-			{ TargetModTimeResult = ok(TargetModTime) },
-			{ compare(TargetModTimeCompare,
-				time_t_to_timestamp(TargetModTime),
-				RecordedTimestamp) },
-			{ TargetModTimeCompare = (>) }
-		->
-			[]
-		;
-			{ Reason1 = output_file_not_up_to_date(TargetFile) },
-			{ throw(recompile_exception(Reason1, Info0)) }
-		)
-	    ), TargetFiles),
-
-	%
 	% Find out whether this module has any inline sub-modules.
 	%
 	read_term_check_for_error_or_eof(Info0, "inline sub-modules",
@@ -268,12 +258,33 @@
 	->
 		Info1 = Info0 ^ sub_modules := SubModules
 	;
-		Reason2 = syntax_error(get_term_context(SubModulesTerm),
+		Reason1 = syntax_error(get_term_context(SubModulesTerm),
 				"error in sub_modules term"),
-		throw(recompile_exception(Reason2, Info0)) 
+		throw_syntax_error(Reason1, Info0)
 	},
 
 	%
+	% Check whether the output files are present and up-to-date.
+	%
+	FindTargetFiles(Info1 ^ module_name, TargetFiles),
+	list__foldl(
+	    (pred(TargetFile::in, di, uo) is det -->
+		io__file_modification_time(TargetFile, TargetModTimeResult),
+		(
+			{ TargetModTimeResult = ok(TargetModTime) },
+			{ compare(TargetModTimeCompare,
+				time_t_to_timestamp(TargetModTime),
+				RecordedTimestamp) },
+			{ TargetModTimeCompare = (>) }
+		->
+			[]
+		;
+			{ Reason2 = output_file_not_up_to_date(TargetFile) },
+			{ throw(recompile_exception(Reason2, Info1)) }
+		)
+	    ), TargetFiles),
+
+	%
 	% Read in the used items, used for checking for
 	% ambiguities with new items.
 	%
@@ -299,7 +310,7 @@
 	;
 		Reason3 = syntax_error(get_term_context(UsedClassesTerm),
 				"error in used_typeclasses term"),
-		throw(recompile_exception(Reason3, Info2))
+		throw_syntax_error(Reason3, Info2)
 	},
 	check_imported_modules(Info3, Info).
 
@@ -332,7 +343,7 @@
 	;	
 		Reason = syntax_error(get_term_context(Term),
 				"error in module timestamp"),
-		throw(recompile_exception(Reason, Info))
+		throw_syntax_error(Reason, Info)
 	).
 
 %-----------------------------------------------------------------------------%
@@ -348,7 +359,7 @@
 	;
 		Reason = syntax_error(get_term_context(Term),
 				"error in used items"),
-		throw(recompile_exception(Reason, Info))
+		throw_syntax_error(Reason, Info)
 	).
 
 :- pred parse_used_item_set(recompilation_check_info::in, term::in,
@@ -378,12 +389,12 @@
 				string__append(
 				    "error in used items: unknown item type :",
 				    ItemTypeStr)),
-			throw(recompile_exception(Reason, Info))
+			throw_syntax_error(Reason, Info)
 		)
 	;
 		Reason = syntax_error(get_term_context(Term),
 				"error in used items"),
-		throw(recompile_exception(Reason, Info))
+		throw_syntax_error(Reason, Info)
 	).
 
 :- pred parse_simple_item(recompilation_check_info::in, term::in,
@@ -403,7 +414,7 @@
 	;
 		Reason = syntax_error(get_term_context(Term),
 				"error in simple items"),
-		throw(recompile_exception(Reason, Info))
+		throw_syntax_error(Reason, Info)
 	).
 
 :- pred parse_simple_item_match(recompilation_check_info::in, term::in,
@@ -427,7 +438,7 @@
 	;
 		Reason = syntax_error(get_term_context(Term),
 				"error in simple item match"),
-		throw(recompile_exception(Reason, Info))
+		throw_syntax_error(Reason, Info)
 	).
 
 :- pred parse_pred_or_func_item(recompilation_check_info::in,
@@ -448,7 +459,7 @@
 	;
 		Reason = syntax_error(get_term_context(Term),
 				"error in pred or func match"),
-		throw(recompile_exception(Reason, Info))
+		throw_syntax_error(Reason, Info)
 	).
 
 :- pred parse_pred_or_func_item_match(recompilation_check_info::in, term::in,
@@ -479,7 +490,7 @@
 	;
 		Reason = syntax_error(get_term_context(Term),
 				"error in pred or func match"),
-		throw(recompile_exception(Reason, Info))
+		throw_syntax_error(Reason, Info)
 	).
 
 :- pred parse_functor_item(recompilation_check_info::in, term::in,
@@ -498,7 +509,7 @@
 	;
 		Reason = syntax_error(get_term_context(Term),
 				"error in functor matches"),
-		throw(recompile_exception(Reason, Info))
+		throw_syntax_error(Reason, Info)
 	).
 
 :- pred parse_functor_arity_matches(recompilation_check_info::in, term::in,
@@ -517,7 +528,7 @@
 	;
 		Reason = syntax_error(get_term_context(Term),
 				"error in functor match"),
-		throw(recompile_exception(Reason, Info))
+		throw_syntax_error(Reason, Info)
 	).
 
 :- pred parse_functor_matches(recompilation_check_info::in, term::in,
@@ -537,7 +548,7 @@
 	;
 		Reason = syntax_error(get_term_context(Term),
 				"error in functor match"),
-		throw(recompile_exception(Reason, Info))
+		throw_syntax_error(Reason, Info)
 	).
 
 :- pred parse_resolved_functor(recompilation_check_info::in, term::in,
@@ -571,7 +582,7 @@
 	;
 		Reason = syntax_error(get_term_context(Term),
 				"error in functor match"),
-		throw(recompile_exception(Reason, Info))
+		throw_syntax_error(Reason, Info)
 	).
 
 %-----------------------------------------------------------------------------%
@@ -600,7 +611,7 @@
 		io__input_stream_name(FileName),
 		{ Reason = syntax_error(term__context(FileName, Line),
 				Message) },
-		{ throw(recompile_exception(Reason, Info0)) }
+		{ throw_syntax_error(Reason, Info0) }
 	;
 		{ TermResult = eof },
 		%
@@ -613,7 +624,7 @@
 		io__get_line_number(Line),
 		{ Reason = syntax_error(term__context(FileName, Line),
 				"unexpected end of file") },
-		{ throw(recompile_exception(Reason, Info0)) }
+		{ throw_syntax_error(Reason, Info0) }
 	).
 	
 :- pred check_imported_module(term::in, recompilation_check_info::in,
@@ -661,7 +672,8 @@
 	),
 	{
 		MaybeNewTimestamp = yes(NewTimestamp),
-		NewTimestamp \= RecordedTimestamp
+		NewTimestamp \= RecordedTimestamp,
+		Error = no_module_errors
 	->
 		( Recorded = no ->
 			record_read_file(ImportedModuleName,
@@ -687,10 +699,10 @@
 	;
 		Error \= no_module_errors
 	->
-		throw(recompile_exception(
+		throw_syntax_error(
 			file_error(FileName,
 				"error reading file `" ++ FileName ++ "'."),
-			Info0))
+			Info0)
 	;
 		Info = Info0
 	}.
@@ -710,9 +722,8 @@
 		UsedItemsResult = ok(UsedVersionNumbers)
 	;
 		UsedItemsResult = error(Msg, ErrorTerm),
-		Reason = syntax_error(get_term_context(ErrorTerm),
-				Msg),
-		throw(recompile_exception(Reason, Info0))
+		Reason = syntax_error(get_term_context(ErrorTerm), Msg),
+		throw_syntax_error(Reason, Info0)
 	},
 
 	{ UsedVersionNumbers = version_numbers(UsedItemVersionNumbers,
@@ -1473,7 +1484,7 @@
 		io__input_stream_name(FileName),
 		{ Reason = syntax_error(term__context(FileName, Line),
 				Message) },
-		{ throw(recompile_exception(Reason, Info)) }
+		{ throw_syntax_error(Reason, Info) }
 	;
 		{ TermResult = eof },
 		io__input_stream_name(FileName),
@@ -1482,7 +1493,7 @@
 			string__append_list(
 				["unexpected end of file, expected ",
 				Item, "."])) },
-		{ throw(recompile_exception(Reason, Info)) }
+		{ throw_syntax_error(Reason, Info) }
 	).
 
 :- func get_term_context(term) = term__context.
@@ -1493,5 +1504,15 @@
 	;
 		term__context_init
 	).
+
+:- pred throw_syntax_error(recompile_reason::in,
+		recompilation_check_info::in) is erroneous.
+
+throw_syntax_error(Reason, Info) :-
+	% If there were syntax errors in a `.used' file written during
+	% a compilation, all outputs of that compilation are slightly
+	% suspect, so it's worth entirely redoing the compilation.
+	RecompileInfo = Info ^ modules_to_recompile := (all),
+	throw(recompile_exception(Reason, RecompileInfo)).
 
 %-----------------------------------------------------------------------------%
Index: tests/recompilation/Mmakefile
===================================================================
RCS file: /home/mercury1/repository/tests/recompilation/Mmakefile,v
retrieving revision 1.5
diff -u -u -r1.5 Mmakefile
--- tests/recompilation/Mmakefile	24 Jul 2001 10:47:20 -0000	1.5
+++ tests/recompilation/Mmakefile	23 Oct 2001 16:52:01 -0000
@@ -33,4 +33,7 @@
 # for which no version numbers have been computed.
 MCFLAGS-no_version_numbers_r_2 = --no-smart-recompilation
 
+$(ints_subdir)nested_module_2_r_2.date: \
+				$(int0s_subdir)nested_module_2_r_2.int0
+
 #-----------------------------------------------------------------------------#
Index: tests/recompilation/TESTS
===================================================================
RCS file: /home/mercury1/repository/tests/recompilation/TESTS,v
retrieving revision 1.4
diff -u -u -r1.4 TESTS
--- tests/recompilation/TESTS	24 Jul 2001 17:16:46 -0000	1.4
+++ tests/recompilation/TESTS	23 Oct 2001 15:46:32 -0000
@@ -28,8 +28,8 @@
 # nested sub-module are run twice, resulting in incorrect output in
 # the `.err' file.
 NO_PARALLEL_MAKE_TESTS="\
-	nested_module_r
-"
+	nested_module_r \
+	nested_module_2_r"
 
 TESTS_SHOULD_FAIL="\
 	add_type_re \
Index: tests/recompilation/nested_module_2_r.err_exp.2
===================================================================
RCS file: tests/recompilation/nested_module_2_r.err_exp.2
diff -N tests/recompilation/nested_module_2_r.err_exp.2
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ tests/recompilation/nested_module_2_r.err_exp.2	23 Oct 2001 16:10:26 -0000
@@ -0,0 +1,2 @@
+Recompiling module `nested_module_2_r':
+  file `nested_module_2_r.used' not found.
Index: tests/recompilation/nested_module_2_r.exp.1
===================================================================
RCS file: tests/recompilation/nested_module_2_r.exp.1
diff -N tests/recompilation/nested_module_2_r.exp.1
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ tests/recompilation/nested_module_2_r.exp.1	23 Oct 2001 16:10:21 -0000
@@ -0,0 +1 @@
+answer 1
Index: tests/recompilation/nested_module_2_r.exp.2
===================================================================
RCS file: tests/recompilation/nested_module_2_r.exp.2
diff -N tests/recompilation/nested_module_2_r.exp.2
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ tests/recompilation/nested_module_2_r.exp.2	23 Oct 2001 16:10:53 -0000
@@ -0,0 +1 @@
+answer 2
Index: tests/recompilation/nested_module_2_r.m.1
===================================================================
RCS file: tests/recompilation/nested_module_2_r.m.1
diff -N tests/recompilation/nested_module_2_r.m.1
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ tests/recompilation/nested_module_2_r.m.1	23 Oct 2001 13:58:53 -0000
@@ -0,0 +1,14 @@
+:- module nested_module_2_r.
+
+:- interface.
+
+:- import_module io.
+
+:- pred main(io__state::di, io__state::uo) is det.
+
+:- implementation.
+
+:- import_module nested_module_2_r_2.
+
+main -->
+	main_2.
Index: tests/recompilation/nested_module_2_r_2.err_exp.2
===================================================================
RCS file: tests/recompilation/nested_module_2_r_2.err_exp.2
diff -N tests/recompilation/nested_module_2_r_2.err_exp.2
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ tests/recompilation/nested_module_2_r_2.err_exp.2	23 Oct 2001 16:20:33 -0000
@@ -0,0 +1,2 @@
+Recompiling module `nested_module_2_r_2':
+  file `nested_module_2_r_2.m' has changed.
Index: tests/recompilation/nested_module_2_r_2.m.1
===================================================================
RCS file: tests/recompilation/nested_module_2_r_2.m.1
diff -N tests/recompilation/nested_module_2_r_2.m.1
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ tests/recompilation/nested_module_2_r_2.m.1	23 Oct 2001 16:17:13 -0000
@@ -0,0 +1,26 @@
+:- module nested_module_2_r_2.
+
+:- interface.
+
+:- import_module io.
+
+:- pred main_2(io__state::di, io__state::uo) is det.
+
+:- implementation.
+
+:- import_module nested_module_2_r_2__sub_module.
+
+main_2 --> main_3.
+
+:- module nested_module_2_r_2__sub_module.
+
+:- interface.
+
+:- import_module io.
+
+:- pred main_3(io__state::di, io__state::uo) is det.
+
+:- implementation.
+
+main_3 --> io__write_string("answer 1\n").
+
Index: tests/recompilation/nested_module_2_r_2.m.2
===================================================================
RCS file: tests/recompilation/nested_module_2_r_2.m.2
diff -N tests/recompilation/nested_module_2_r_2.m.2
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ tests/recompilation/nested_module_2_r_2.m.2	23 Oct 2001 16:17:19 -0000
@@ -0,0 +1,26 @@
+:- module nested_module_2_r_2.
+
+:- interface.
+
+:- import_module io.
+
+:- pred main_2(io__state::di, io__state::uo) is det.
+
+:- implementation.
+
+:- import_module nested_module_2_r_2__sub_module.
+
+main_2 --> main_3.
+
+:- module nested_module_2_r_2__sub_module.
+
+:- interface.
+
+:- import_module io.
+
+:- pred main_3(io__state::di, io__state::uo) is det.
+
+:- implementation.
+
+main_3 --> io__write_string("answer 2\n").
+
--------------------------------------------------------------------------
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