[m-rev.] for review: transparent sub-modules

Peter Ross peter.ross at miscrit.be
Tue Dec 4 01:27:16 AEDT 2001


On Tue, Dec 04, 2001 at 12:34:12AM +1100, Simon Taylor wrote:
> On 03-Dec-2001, Peter Ross <peter.ross at miscrit.be> wrote:
> > Peter wrote:
> > > We currently don't imply that transparent sub-modules always have to
> > be
> > > used.  The change is trivial to do.  I am waiting for someone to
> > provide
> > > feedback on the alternative suggestion that I provided.
> > >
> > Anyone going to review this change?
> 
> We don't have agreement on whether it should be allowed yet.
> 
Assuming that agreement is forthcoming here is the complete change
with the changes necessary so that all the transparent sub-modules are
imported with a use_module declaration.


===================================================================



Estimated hours taken: 16
Branches: main

Add support for transparent modules.

Transparent modules provide a mechanism for the designer of a sub-module
hierarchy to have certain sub-modules automatically imported when their
parent module is imported.

compiler/intermod.m:
compiler/make_hlds.m:
compiler/mercury_compile.m:
compiler/module_qual.m:
    Minor changes to handle the new pass.

compiler/mercury_to_mercury.m:
compiler/prog_io.m:
    Handle the new transparent module declarations.

compiler/modules.m:
    Recursively process transparent sub-modules when reading in
    interface files.
    When calculating the dependencies for a module add the dependencies
    implied by the transparent sub-modules.

compiler/prog_data.m:
    Add for each module, end_module and include_module declaration
    whether it refers to an opaque or transparent module.

doc/reference_manual.texi:
    Document the new declarations.

library/ops.m:
    Add the operators to the operator table.
    
tests/hard_coded/sub-modules/Mmakefile:
tests/hard_coded/sub-modules/auto_parent.m:
tests/hard_coded/sub-modules/auto_parent.separate.m:
tests/hard_coded/sub-modules/use_transparent.exp:
tests/hard_coded/sub-modules/use_transparent.m:
tests/invalid/Mmakefile:
    Test cases.

Index: compiler/intermod.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/intermod.m,v
retrieving revision 1.109
diff -u -r1.109 intermod.m
--- compiler/intermod.m	6 Nov 2001 15:20:44 -0000	1.109
+++ compiler/intermod.m	3 Dec 2001 14:16:26 -0000
@@ -2046,7 +2046,8 @@
 		% Read in the .opt files for imported and ancestor modules.
 		%
 	{ Module0 = module_imports(_, ModuleName, Ancestors0, InterfaceDeps0,
-				ImplementationDeps0, _, _, _, _, _, _, _, _) },
+				ImplementationDeps0,
+				_, _, _, _, _, _, _, _, _) },
 	{ list__condense([Ancestors0, InterfaceDeps0, ImplementationDeps0],
 		OptFiles) },
 	read_optimization_interfaces(OptFiles, [], OptItems, no, OptError),
Index: compiler/make_hlds.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/make_hlds.m,v
retrieving revision 1.391
diff -u -r1.391 make_hlds.m
--- compiler/make_hlds.m	12 Nov 2001 11:08:07 -0000	1.391
+++ compiler/make_hlds.m	3 Dec 2001 14:16:28 -0000
@@ -280,7 +280,7 @@
 			{ module_add_indirectly_imported_module_specifiers(
 				Specifiers, Module0, Module) }
 		)
-	; { ModuleDefn = include_module(_) } ->
+	; { ModuleDefn = include_module(_, _) } ->
 		{ Status = Status0 },
 		{ Module = Module0 }
 	; { ModuleDefn = external(External) } ->
@@ -297,11 +297,11 @@
 			report_warning("Warning: `external' declaration requires arity.\n"),
 			io__set_output_stream(OldStream, _)
 		)
-	; { ModuleDefn = module(_ModuleName) } ->
+	; { ModuleDefn = module(_ModuleName, _ModuleType) } ->
 		report_unexpected_decl("module", Context),
 		{ Status = Status0 },
 		{ Module = Module0 }
-	; { ModuleDefn = end_module(_ModuleName) } ->
+	; { ModuleDefn = end_module(_ModuleName, _ModuleType) } ->
 		report_unexpected_decl("end_module", Context),
 		{ Status = Status0 },
 		{ Module = Module0 }
Index: compiler/mercury_compile.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/mercury_compile.m,v
retrieving revision 1.227
diff -u -r1.227 mercury_compile.m
--- compiler/mercury_compile.m	27 Nov 2001 14:06:56 -0000	1.227
+++ compiler/mercury_compile.m	3 Dec 2001 14:16:30 -0000
@@ -1299,7 +1299,8 @@
 			% imported (or used), and for all ancestor modules.
 			{ Imports0 = module_imports(_File, _Module, Ancestors,
 				InterfaceImports, ImplementationImports,
-				_IndirectImports, _PublicChildren, _FactDeps,
+				_IndirectImports, _PublicChildren, 
+				_PublicTransparentChildren, _FactDeps,
 				_ForeignCode, _ForeignImports, _Items,
 				_Error, _Timestamps) },
 			{ list__condense([Ancestors, InterfaceImports,
Index: compiler/mercury_to_mercury.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/mercury_to_mercury.m,v
retrieving revision 1.198
diff -u -r1.198 mercury_to_mercury.m
--- compiler/mercury_to_mercury.m	8 Nov 2001 15:30:31 -0000	1.198
+++ compiler/mercury_to_mercury.m	3 Dec 2001 14:16:31 -0000
@@ -762,16 +762,28 @@
 		io__write_string(":- interface.\n")
 	; { ModuleDefn = implementation } ->
 		io__write_string(":- implementation.\n")
-	; { ModuleDefn = include_module(IncludedModules) } ->
-		io__write_string(":- include_module "),
+	; { ModuleDefn = include_module(ModuleType, IncludedModules) } ->
+		( { ModuleType = opaque },
+			io__write_string(":- include_module ")
+		; { ModuleType = transparent },
+			io__write_string(":- include_transparent_module ")
+		),
 		mercury_write_module_spec_list(IncludedModules),
 		io__write_string(".\n")
-	; { ModuleDefn = module(Module) } ->
-		io__write_string(":- module "),
+	; { ModuleDefn = module(Module, ModuleType) } ->
+		( { ModuleType = opaque },
+			io__write_string(":- module ")
+		; { ModuleType = transparent },
+			io__write_string(":- transparent_module ")
+		),
 		mercury_output_bracketed_sym_name(Module),
 		io__write_string(".\n")
-	; { ModuleDefn = end_module(Module) } ->
-		io__write_string(":- end_module "),
+	; { ModuleDefn = end_module(Module, ModuleType) } ->
+		( { ModuleType = opaque },
+			io__write_string(":- end_module ")
+		; { ModuleType = transparent },
+			io__write_string(":- end_transparent_module ")
+		),
 		mercury_output_bracketed_sym_name(Module),
 		io__write_string(".\n")
 	; { ModuleDefn = version_numbers(Module, VersionNumbers) } ->
Index: compiler/module_qual.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/module_qual.m,v
retrieving revision 1.70
diff -u -r1.70 module_qual.m
--- compiler/module_qual.m	6 Nov 2001 15:21:05 -0000	1.70
+++ compiler/module_qual.m	3 Dec 2001 14:16:31 -0000
@@ -309,9 +309,9 @@
 
 :- pred process_module_defn(module_defn::in, mq_info::in, mq_info::out) is det.
 
-process_module_defn(module(ModuleName), Info0, Info) :-
+process_module_defn(module(ModuleName, _ModuleType), Info0, Info) :-
 	add_module_defn(ModuleName, Info0, Info).
-process_module_defn(include_module(ModuleNameList), Info0, Info) :-
+process_module_defn(include_module(_ModuleType, ModuleNameList), Info0, Info) :-
 	list__foldl(add_module_defn, ModuleNameList, Info0, Info).
 process_module_defn(interface, Info0, Info) :-
 	mq_info_set_import_status(Info0, exported, Info).
@@ -331,7 +331,7 @@
 process_module_defn(transitively_imported, _, _) :-
 	error("process_module_defn: transitively_imported item").
 process_module_defn(external(_), Info, Info).
-process_module_defn(end_module(_), Info, Info).
+process_module_defn(end_module(_, _), Info, Info).
 process_module_defn(export(_), Info, Info).
 process_module_defn(import(Imports), Info0, Info) :-
 	add_imports(Imports, Info0, Info).
@@ -612,7 +612,7 @@
 
 update_import_status(opt_imported, Info, Info, no).
 update_import_status(transitively_imported, Info, Info, no).
-update_import_status(module(_), Info, Info, yes).
+update_import_status(module(_, _), Info, Info, yes).
 update_import_status(interface, Info0, Info, yes) :-
 	mq_info_set_import_status(Info0, exported, Info).
 update_import_status(implementation, Info0, Info, yes) :-
@@ -622,12 +622,12 @@
 update_import_status(imported(_), Info, Info, no).
 update_import_status(used(_), Info, Info, no).
 update_import_status(external(_), Info, Info, yes).
-update_import_status(end_module(_), Info, Info, yes).
+update_import_status(end_module(_, _), Info, Info, yes).
 update_import_status(export(_), Info, Info, yes).
 update_import_status(import(_), Info, Info, yes).
 update_import_status(use(_), Info, Info, yes).
 update_import_status(version_numbers(_, _), Info, Info, yes).
-update_import_status(include_module(_), Info0, Info, yes) :-
+update_import_status(include_module(_, _), Info0, Info, yes) :-
 	% The sub-module might make use of *any* of the imported modules.
 	% There's no way for us to tell which ones.
 	% So we conservatively assume that it uses all of them.
Index: compiler/modules.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/modules.m,v
retrieving revision 1.209
diff -u -r1.209 modules.m
--- compiler/modules.m	28 Nov 2001 14:46:33 -0000	1.209
+++ compiler/modules.m	3 Dec 2001 14:16:33 -0000
@@ -271,6 +271,9 @@
 				% The list of its public children,
 				% i.e. child modules that it includes
 				% in the interface section.
+		public_transparent_children	:: list(module_name),
+				% The list of its public children which
+				% are transparent children.
 		fact_table_deps :: list(string),  
 				% The list of filenames for fact tables
 				% in this module.
@@ -620,7 +623,7 @@
 :- implementation.
 :- import_module llds_out, passes_aux, prog_out, prog_util, mercury_to_mercury.
 :- import_module prog_io_util, options, module_qual, foreign.
-:- import_module recompilation_version.
+:- import_module error_util, recompilation_version.
 
 :- import_module string, map, term, varset, dir, library.
 :- import_module assoc_list, relation, char, require.
@@ -1200,7 +1203,7 @@
 	(
 		{ Item = nothing(_)
 		; Item = module_defn(_, ModuleDefn),
-		  ModuleDefn \= include_module(_)
+		  ModuleDefn \= include_module(_, _)
 		}
 	->
 		% nothing useful - keep searching
@@ -1384,7 +1387,9 @@
 
 	{ get_fact_table_dependencies(Items0, FactDeps) },
 	{ get_interface(Items0, InterfaceItems) },
-	{ get_children(InterfaceItems, PublicChildren) },
+	{ PublicChildren = get_children(opaque, InterfaceItems) },
+	{ PublicTransparentChildren = get_children(
+			transparent, InterfaceItems) },
 	{ MaybeTimestamp = yes(Timestamp) ->
 		MaybeTimestamps = yes(map__det_insert(map__init, ModuleName,
 			module_timestamp(".m", Timestamp, may_be_unqualified)))
@@ -1393,14 +1398,15 @@
 
 	},
 	{ init_module_imports(SourceFileName, ModuleName, Items0,
-		PublicChildren, FactDeps, MaybeTimestamps, Module0) },
+		PublicChildren, PublicTransparentChildren, FactDeps,
+		MaybeTimestamps, Module0) },
 
 		% If this module has any seperately-compiled sub-modules,
 		% then we need to make everything in this module
 		% exported_to_submodules.  We do that by splitting
 		% out the declarations and putting them in a special
 		% `:- private_interface' section.
-	{ get_children(Items0, Children) },
+	{ Children = get_all_children(Items0) },
 	{ Children = [] ->
 		Module1 = Module0
 	;
@@ -1483,7 +1489,7 @@
 		% Construct the initial module import structure,
 		% and append a `:- imported' decl to the items.
 		%
-	{ init_module_imports(SourceFileName, ModuleName, Items0, [], [],
+	{ init_module_imports(SourceFileName, ModuleName, Items0, [], [], [],
 		no, Module0) },
 	{ append_pseudo_decl(Module0, imported(interface), Module1) },
 
@@ -1554,15 +1560,16 @@
 	).
 
 :- pred init_module_imports(file_name, module_name, item_list,
-			list(module_name), list(string),
+			list(module_name), list(module_name), list(string),
 			maybe(module_timestamps), module_imports).
-:- mode init_module_imports(in, in, in, in, in, in, out) is det.
+:- mode init_module_imports(in, in, in, in, in, in, in, out) is det.
 
 init_module_imports(SourceFileName, ModuleName, Items, PublicChildren,
-			FactDeps, MaybeTimestamps, Module) :-
+			PublicTransparentChildren, FactDeps,
+			MaybeTimestamps, Module) :-
 	Module = module_imports(SourceFileName, ModuleName, [], [], [], [],
-		PublicChildren, FactDeps, unknown, [], Items, no_module_errors,
-		MaybeTimestamps).
+		PublicChildren, PublicTransparentChildren, FactDeps,
+		unknown, [], Items, no_module_errors, MaybeTimestamps).
 
 module_imports_get_source_file_name(Module, Module ^ source_file_name).
 module_imports_get_module_name(Module, Module ^ module_name).
@@ -1790,8 +1797,8 @@
 
 write_dependency_file(Module, AllDepsSet, MaybeTransOptDeps) -->
 	{ Module = module_imports(SourceFileName, ModuleName, ParentDeps,
-			IntDeps, ImplDeps, IndirectDeps, _InclDeps, FactDeps0,
-			ContainsForeignCode, ForeignImports0,
+			IntDeps, ImplDeps, IndirectDeps, _InclDeps, _TransDeps,
+			FactDeps0, ContainsForeignCode, ForeignImports0,
 			Items, _Error, _Timestamps) },
 	globals__io_lookup_bool_option(verbose, Verbose),
 	{ module_name_to_make_var_name(ModuleName, MakeVarName) },
@@ -2854,6 +2861,7 @@
 			ModuleImports ^ int_deps,
 			ModuleImports ^ impl_deps,
 			ModuleImports ^ public_children, % a.k.a. incl_deps
+			ModuleImports ^ public_transparent_children,
 			ForeignImportedModules,
 			Modules],
 			Modules1) }
@@ -2899,7 +2907,8 @@
 		ParentDeps = ModuleImports ^ parent_deps,
 		relation__add_element(IntRel0, ModuleName, IntModuleKey,
 			IntRel1),
-		add_int_deps(IntModuleKey, ModuleImports, IntRel1, IntRel2),
+		add_int_deps(DepsMap, IntModuleKey, ModuleImports,
+				IntRel1, IntRel2),
 		list__foldl(add_parent_impl_deps(DepsMap, IntModuleKey),
 				ParentDeps, IntRel2, IntRel3),
 
@@ -2914,8 +2923,9 @@
 		% only by its parents.
 		%
 		relation__add_element(ImplRel0, ModuleName, ImplModuleKey,
-			ImplRel1),
-		add_impl_deps(ImplModuleKey, ModuleImports, ImplRel1, ImplRel2),
+				ImplRel1),
+		add_impl_deps(DepsMap, ImplModuleKey, ModuleImports,
+				ImplRel1, ImplRel2),
 		list__foldl(add_parent_impl_deps(DepsMap, ImplModuleKey),
 				ParentDeps, ImplRel2, ImplRel3)
 	;
@@ -2927,28 +2937,34 @@
 
 % add interface dependencies to the interface deps relation
 %
-:- pred add_int_deps(relation_key, module_imports, deps_rel, deps_rel).
-:- mode add_int_deps(in, in, in, out) is det.
+:- pred add_int_deps(deps_map::in, relation_key::in, module_imports::in,
+		deps_rel::in, deps_rel::out) is det.
 
-add_int_deps(ModuleKey, ModuleImports, Rel0, Rel) :-
+add_int_deps(DepsMap, ModuleKey, ModuleImports, Rel0, Rel) :-
 	AddDep = add_dep(ModuleKey),
 	list__foldl(AddDep, ModuleImports ^ parent_deps, Rel0, Rel1),
 	list__foldl(AddDep, ModuleImports ^ int_deps, Rel1, Rel2),
-	list__foldl(AddDep, ModuleImports ^ public_children, Rel2, Rel).
+	list__foldl(AddDep, ModuleImports ^ public_children, Rel2, Rel3),
+	list__foldl(AddDep, ModuleImports ^ public_transparent_children,
+			Rel3, Rel4),
+	list__foldl(add_transparent_mod_deps(DepsMap, ModuleKey),
+			ModuleImports ^ int_deps, Rel4, Rel).
 
 % add direct implementation dependencies for a module to the
 % impl. deps relation
 %
-:- pred add_impl_deps(relation_key, module_imports, deps_rel, deps_rel).
-:- mode add_impl_deps(in, in, in, out) is det.
+:- pred add_impl_deps(deps_map::in, relation_key::in, module_imports::in,
+		deps_rel::in, deps_rel::out) is det.
 
-add_impl_deps(ModuleKey, ModuleImports, Rel0, Rel) :-
+add_impl_deps(DepsMap, ModuleKey, ModuleImports, Rel0, Rel) :-
 	% the implementation dependencies are a superset of the
 	% interface dependencies, so first we add the interface deps
-	add_int_deps(ModuleKey, ModuleImports, Rel0, Rel1),
+	add_int_deps(DepsMap, ModuleKey, ModuleImports, Rel0, Rel1),
 	% then we add the impl deps
 	module_imports_get_impl_deps(ModuleImports, ImplDeps),
-	list__foldl(add_dep(ModuleKey), ImplDeps, Rel1, Rel).
+	list__foldl(add_transparent_mod_deps(DepsMap, ModuleKey),
+			ImplDeps, Rel1, Rel2),
+	list__foldl(add_dep(ModuleKey), ImplDeps, Rel2, Rel).
 
 % add parent implementation dependencies for the given Parent module
 % to the impl. deps relation values for the given ModuleKey.
@@ -2959,7 +2975,19 @@
 
 add_parent_impl_deps(DepsMap, ModuleKey, Parent, Rel0, Rel) :-
 	map__lookup(DepsMap, Parent, deps(_, ParentModuleImports)),
-	add_impl_deps(ModuleKey, ParentModuleImports, Rel0, Rel).
+	add_impl_deps(DepsMap, ModuleKey, ParentModuleImports, Rel0, Rel).
+
+% add dependencies between the module specified by the module key and
+% and every public transparent sub-module starting from module_name.
+:- pred add_transparent_mod_deps(deps_map::in, relation_key::in, module_name::in,
+		deps_rel::in, deps_rel::out) is det.
+
+add_transparent_mod_deps(DepsMap, ModuleKey, SubModule, Rel0, Rel) :-
+	map__lookup(DepsMap, SubModule, deps(_, SubModuleImports)),
+	TransparentChildren = SubModuleImports ^ public_transparent_children,
+	list__foldl(add_dep(ModuleKey), TransparentChildren, Rel0, Rel1),
+	list__foldl(add_transparent_mod_deps(DepsMap, ModuleKey),
+			TransparentChildren, Rel1, Rel).
 
 % add a single dependency to a relation
 %
@@ -4382,7 +4410,8 @@
 	% we don't fill in the indirect dependencies yet
 	IndirectDeps = [],
 
-	get_children(InterfaceItems, IncludeDeps),
+	IncludeDeps = get_children(opaque, InterfaceItems),
+	PublicTransparentChildren = get_children(transparent, InterfaceItems),
 
 	get_fact_table_dependencies(Items, FactTableDeps),
 
@@ -4399,8 +4428,8 @@
 
 	ModuleImports = module_imports(FileName, ModuleName, ParentDeps,
 		InterfaceDeps, ImplementationDeps, IndirectDeps, IncludeDeps,
-		FactTableDeps, ContainsForeignCode, ForeignImports,
-		[], Error, no).
+		PublicTransparentChildren, FactTableDeps, ContainsForeignCode,
+		ForeignImports, [], Error, no).
 
 %-----------------------------------------------------------------------------%
 
@@ -4706,6 +4735,7 @@
 				ModItems0)
 		),
 		{ get_dependencies(Items, IndirectImports1, IndirectUses1) },
+		{ TransparentChildren = get_children(transparent, Items) },
 		{ list__append(IndirectImports0, IndirectImports1,
 			IndirectImports2) },
 		{ list__append(IndirectImports2, IndirectUses1,
@@ -4715,9 +4745,12 @@
 				      ^ items := ModItems)
 				      ^ error := ModError },
 
+		process_module_long_interfaces(ReadModules, must_be_qualified,
+			TransparentChildren, Ext,
+			IndirectImports3, IndirectImports4, Module2, Module3),
 		process_module_long_interfaces(ReadModules, NeedQualifier,
-			Imports, Ext, IndirectImports3, IndirectImports,
-			Module2, Module)
+			Imports, Ext, IndirectImports4, IndirectImports,
+			Module3, Module)
 	).
 
 :- pred check_module_accessibility(module_name, module_name, item_list,
@@ -4735,7 +4768,7 @@
 		% declaration that names it.
 		%
 		(
-			{ get_children(Items, AccessibleSubModules) },
+			{ AccessibleSubModules = get_all_children(Items) },
 			{ list__member(ImportedModule, AccessibleSubModules) }
 		->
 			[]
@@ -4889,14 +4922,18 @@
 
 		{ ModIndirectImports = [Import | ModIndirectImports0] },
 		{ get_dependencies(Items, Imports1, Uses1) },
+		{ TransparentChildren = get_children(transparent, Items) },
 		{ list__append(IndirectImports0, Imports1, IndirectImports1) },
 		{ list__append(IndirectImports1, Uses1, IndirectImports2) },
 		{ list__append(ModItems0, Items, ModItems) },
 		{ Module2 = ((Module1 ^ indirect_deps := ModIndirectImports)
 				      ^ items := ModItems)
 				      ^ error := ModError },
+		process_module_short_interfaces(ReadModules,
+			TransparentChildren, Ext,
+			IndirectImports2, IndirectImports3, Module2, Module3),
 		process_module_short_interfaces(ReadModules, Imports, Ext,
-			IndirectImports2, IndirectImports, Module2, Module)
+			IndirectImports3, IndirectImports, Module3, Module)
 	).
 
 strip_off_interface_decl(Items0, Items) :-
@@ -4950,29 +4987,36 @@
 
 %-----------------------------------------------------------------------------%
 
-	% get_children(Items, IncludeDeps):
+	% get_all_children(Items) = IncludeDeps
 	%	IncludeDeps is the list of sub-modules declared with
-	% 	`:- include_module' in Items.
+	% 	`:- include_module' or `:- include_transparent_module'
+	% 	in Items.
 	%
-:- pred get_children(item_list, list(module_name)).
-:- mode get_children(in, out) is det.
+:- func get_all_children(item_list) = list(module_name).
 
-get_children(Items, IncludeDeps) :-
-	get_children_2(Items, [], IncludeDeps).
+get_all_children(Items) =
+	get_children(opaque, Items) ++ get_children(transparent, Items).
 
-:- pred get_children_2(item_list, list(module_name), list(module_name)).
-:- mode get_children_2(in, in, out) is det.
+	% get_children(ModuleType, Items) = Children
+	%	Children is the list of sub-modules declared with
+	% 	`:- include_module' if ModuleType is opaque or
+	% 	':- include_transparent_module' if ModuleType is transparent.
+	%
+:- func get_children(module_type, item_list) = list(module_name).
 
-get_children_2([], IncludeDeps, IncludeDeps).
-get_children_2([Item - _Context | Items], IncludeDeps0, IncludeDeps) :-
-	( 
-		Item = module_defn(_VarSet, include_module(Modules))
-	->
-		list__append(IncludeDeps0, Modules, IncludeDeps1)
+get_children(ModuleType, Items) =
+	get_children_2(ModuleType, Items, []).
+
+:- func get_children_2(module_type, item_list,
+		list(module_name)) = list(module_name).
+
+get_children_2(_ModuleType, [], IncludeDeps) = IncludeDeps.
+get_children_2(ModuleType, [Item - _Context | Items], IncludeDeps0) =
+	( Item = module_defn(_VarSet, include_module(ModuleType, Modules)) ->
+		get_children_2(ModuleType, Items, Modules ++ IncludeDeps0)
 	;
-		IncludeDeps1 = IncludeDeps0
-	),
-	get_children_2(Items, IncludeDeps1, IncludeDeps).
+		get_children_2(ModuleType, Items, IncludeDeps0)
+	).
 
 %-----------------------------------------------------------------------------%
 
@@ -5134,61 +5178,91 @@
 split_into_submodules(ModuleName, Items0, ModuleList) -->
 	{ InParentInterface = no },
 	split_into_submodules_2(ModuleName, Items0, InParentInterface,
-		Items, ModuleList),
+			opaque, Items, ModuleList),
 	{ require(unify(Items, []), "modules.m: items after end_module") },
 	%
 	% check for modules declared as both nested and separate sub-modules
 	%
-	{ get_children(Items0, NestedSubmodules) },
+	{ NestedSubmodules = get_all_children(Items0) },
 	{ assoc_list__keys(ModuleList, SeparateSubModules) },
-	{ Duplicates = set__intersect(set__list_to_set(NestedSubmodules),
-				set__list_to_set(SeparateSubModules)) },
+	{ NestedSubmodulesSet = set__list_to_set(NestedSubmodules) },
+	{ SeparateSubModulesSet = set__list_to_set(SeparateSubModules) },
+	{ Duplicates = NestedSubmodulesSet `intersect` SeparateSubModulesSet },
 	( { set__empty(Duplicates) } ->
 		[]
 	;
 		report_duplicate_modules(Duplicates, Items0)
+	),
+
+	%
+	% Ensure that the automatic_include only refers to public
+	% sub-modules of the current module.
+	% seen by the current module.
+	%
+	( { ModuleList = [ _ - CurrentModuleItems | _ ] } ->
+		{ Transparent = list_to_set(get_children(transparent,
+				CurrentModuleItems)) },
+		{ Opaque = list_to_set(get_children(opaque,
+				CurrentModuleItems)) },
+
+		{ TransparentAndOpaqueModules = 
+				Transparent `intersect` Opaque },
+
+		( { empty(TransparentAndOpaqueModules) } ->
+			[]
+		;
+			{ ErrorIncludes = to_sorted_list(
+					TransparentAndOpaqueModules) },
+			list__foldl(report_transparent_and_opaque(
+					CurrentModuleItems), ErrorIncludes)
+		)
+	;
+		{ unexpected(this_file, "empty module list") }
 	).
 
-:- pred split_into_submodules_2(module_name, item_list, bool, item_list,
-				module_list, io__state, io__state).
-:- mode split_into_submodules_2(in, in, in, out, out, di, uo) is det.
+:- pred split_into_submodules_2(module_name, item_list, bool, module_type,
+		item_list, module_list, io__state, io__state).
+:- mode split_into_submodules_2(in, in, in, in, out, out, di, uo) is det.
 
-split_into_submodules_2(ModuleName, Items0, InParentInterface,
+split_into_submodules_2(ModuleName, Items0, InParentInterface, SubModuleType,
 		Items, ModuleList) -->
 	{ InInterface0 = no },
 	split_into_submodules_3(ModuleName, Items0,
-		InParentInterface, InInterface0,
+		InParentInterface, InInterface0, SubModuleType,
 		ThisModuleItems, Items, SubModules),
 	{ map__to_assoc_list(SubModules, SubModuleList) },
 	{ ModuleList = [ModuleName - ThisModuleItems | SubModuleList] }.
 
 :- pred split_into_submodules_3(module_name, item_list, bool, bool,
-			item_list, item_list, map(module_name, item_list),
-			io__state, io__state).
-:- mode split_into_submodules_3(in, in, in, in, out, out, out, di, uo) is det.
+		module_type, item_list, item_list,
+		map(module_name, item_list), io__state, io__state).
+:- mode split_into_submodules_3(in, in, in, in, in,
+		out, out, out, di, uo) is det.
 
-split_into_submodules_3(_ModuleName, [], _, _, [], [], SubModules) -->
+split_into_submodules_3(_ModuleName, [], _, _, _, [], [], SubModules) -->
 	{ map__init(SubModules) }.
 split_into_submodules_3(ModuleName, [Item | Items1],
-		InParentInterface, InInterface0, 
+		InParentInterface, InInterface0, SubModuleType,
 		ThisModuleItems, OtherItems, SubModules) -->
 	(
 		%
 		% check for a `module' declaration, which signals
 		% the start of a nested module
 		%
-		{ Item = module_defn(VarSet, module(SubModuleName)) - Context }
+		{ Item = module_defn(VarSet,
+			module(SubModuleName, NewSubModuleType)) - Context }
 	->
 		%
 		% parse in the items for the nested submodule
 		%
 		split_into_submodules_2(SubModuleName, Items1, InInterface0,
-			Items2, SubModules0),
+			NewSubModuleType, Items2, SubModules0),
 		%
 		% parse in the remaining items for this module
 		%
 		split_into_submodules_3(ModuleName, Items2, InParentInterface,
-			InInterface0, ThisModuleItems0, Items3, SubModules1),
+			InInterface0, SubModuleType, ThisModuleItems0,
+			Items3, SubModules1),
 
 		%
 		% combine the sub-module declarations from the previous two
@@ -5200,15 +5274,16 @@
 		% replace the nested submodule with an `include_module'
 		% declaration
 		%
-		{ IncludeSubMod = module_defn(VarSet,
-			include_module([SubModuleName])) - Context },
+		{ IncludeSubMod = module_defn(VarSet, include_module(
+				NewSubModuleType, [SubModuleName])) - Context },
 		{ ThisModuleItems = [IncludeSubMod | ThisModuleItems0] },
 		{ OtherItems = Items3 }
 	;
 		%
 		% check for a matching `end_module' declaration
 		%
-		{ Item = module_defn(_VarSet, end_module(ModuleName)) - _ }
+		{ Item = module_defn(_VarSet,
+				end_module(ModuleName, SubModuleType)) - _ }
 	->
 		%
 		% if so, thats the end of this module
@@ -5248,7 +5323,7 @@
 		% parse the remaining items for this module,
 		%
 		split_into_submodules_3(ModuleName, Items1,
-			InParentInterface, InInterface1,
+			InParentInterface, InInterface1, SubModuleType,
 			ThisModuleItems0, Items2, SubModules),
 		%
 		% put the current item back onto the
@@ -5317,8 +5392,8 @@
 	{ IsDuplicateError = (pred(SubModuleName - Context::out) is nondet :-
 		list__member(Item, Items),
 		Item = module_defn(_VarSet, ModuleDefn) - Context,
-		( ModuleDefn = module(SubModuleName)
-		; ModuleDefn = include_module(SubModuleNames),
+		( ModuleDefn = module(SubModuleName, _)
+		; ModuleDefn = include_module(_, SubModuleNames),
 		  list__member(SubModuleName, SubModuleNames)
 		),
 		set__member(SubModuleName, Duplicates)
@@ -5353,6 +5428,43 @@
 	io__write_string("  a separate sub-module and a nested sub-module.\n"),
 	io__set_exit_status(1).
 
+:- pred report_transparent_and_opaque(item_list::in, module_name::in,
+		io__state::di, io__state::uo) is det.
+
+report_transparent_and_opaque(Items, ModuleName) -->
+	{ FindTransparentContexts = (pred(Context::out) is nondet :-
+		list__member(Item, Items),
+		Item = module_defn(_VarSet, ModuleDefn) - Context,
+		ModuleDefn = include_module(transparent, Transparents),
+		list__member(ModuleName, Transparents)
+	  ) },
+	{ FindOpaqueContexts = (pred(Context::out) is nondet :-
+		list__member(Item, Items),
+		Item = module_defn(_VarSet, ModuleDefn) - Context,
+		ModuleDefn = include_module(opaque, Opaques),
+		list__member(ModuleName, Opaques)
+	  ) },
+	{ WriteHere = (pred(Context::in, di, uo) is det -->
+		error_util__write_error_pieces(Context, 4,
+				[words("location of conflicting"),
+				words("`:- module' declaration")])
+	) },
+	{ WriteError = (pred(Context::in, di, uo) is det -->
+		{ ModuleNameStr = describe_sym_name(ModuleName) },
+		error_util__write_error_pieces(Context, 0,
+				[words("error:"),
+				 words("The `:- transparent_module'"),
+				 words("declaration for the module"),
+				 words(ModuleNameStr),
+				 words("conflicts with the following"),
+				 words("declarations:")]),
+		{ solutions(FindOpaqueContexts, OpaqueContexts) },
+		list__foldl(WriteHere, OpaqueContexts)
+	) },
+	{ solutions(FindTransparentContexts, Contexts) },
+	list__foldl(WriteError, Contexts),
+	io__set_exit_status(1).
+
 	% Given a module (well, a list of items), extract the interface
 	% part of that module, i.e. all the items between `:- interface'
 	% and `:- implementation'.
@@ -5575,5 +5687,11 @@
 	;
 		[]
 	).
+
+%-----------------------------------------------------------------------------%
+
+:- func this_file = string.
+
+this_file = "modules.m".
 
 %-----------------------------------------------------------------------------%
Index: compiler/prog_data.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/prog_data.m,v
retrieving revision 1.72
diff -u -r1.72 prog_data.m
--- compiler/prog_data.m	20 Nov 2001 13:53:19 -0000	1.72
+++ compiler/prog_data.m	3 Dec 2001 14:16:34 -0000
@@ -866,8 +866,8 @@
 	% and exports) are represented.
 
 :- type module_defn	
-	--->	module(module_name)
-	;	end_module(module_name)
+	--->	module(module_name, module_type)
+	;	end_module(module_name, module_type)
 
 	;	interface
 	;	implementation
@@ -917,12 +917,16 @@
 	;	import(sym_list)
 	;	use(sym_list)
 
-	;	include_module(list(module_name))
+	;	include_module(module_type, list(module_name))
 
 		% This is used to represent the version numbers
 		% of items in an interface file for use in
 		% smart recompilation.
 	;	version_numbers(module_name, recompilation__version_numbers).
+
+:- type module_type
+	--->	opaque
+	;	transparent.
 
 :- type section
 	--->	implementation
Index: compiler/prog_io.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/prog_io.m,v
retrieving revision 1.197
diff -u -r1.197 prog_io.m
--- compiler/prog_io.m	16 Jul 2001 08:21:04 -0000	1.197
+++ compiler/prog_io.m	3 Dec 2001 14:16:35 -0000
@@ -341,7 +341,7 @@
 
 	% extract the final `:- end_module' declaration if any
 
-:- type module_end ---> no ; yes(module_name, prog_context).
+:- type module_end ---> no ; yes(module_name, module_type, prog_context).
 
 :- pred get_end_module(item_list, module_name, item_list, module_end).
 :- mode get_end_module(in, in, out, out) is det.
@@ -355,12 +355,13 @@
 		% we leave it alone.  If it is not for a nested module,
 		% the error will be caught by make_hlds.m.
 		%
-		RevItems0 = [
-			module_defn(_VarSet, end_module(ModuleName)) - Context
+		% XXX
+		RevItems0 = [module_defn(_VarSet,
+				end_module(ModuleName, ModuleType)) - Context
 			    | RevItems1]
 	->
 		RevItems = RevItems1,
-		EndModule = yes(ModuleName, Context)
+		EndModule = yes(ModuleName, ModuleType, Context)
 	;
 		RevItems = RevItems0,
 		EndModule = no
@@ -383,7 +384,8 @@
     % declaration, and remove it from the front of the item list
     %
     {
-        Items0 = [module_defn(_VarSet, module(ModuleName1)) - _Context1
+        Items0 = [module_defn(_VarSet,
+		module(ModuleName, ModuleType)) - _Context1
 		| Items1]
     ->
 	Items = Items1,
@@ -391,19 +393,35 @@
         % check that the end module declaration (if any)
         % matches the begin module declaration 
 	%
-        (
-            EndModule = yes(ModuleName2, Context2),
-            ModuleName1 \= ModuleName2
-        ->
-	    dummy_term_with_context(Context2, Term),
-            add_error(
-"`:- end_module' declaration doesn't match `:- module' declaration",
-			Term, Messages0, Messages),
-	    Error = some_module_errors
-        ;
+        ( EndModule = yes(EndModuleName, EndModuleType, EndContext) ->
+	    ( ModuleType = opaque,
+		ModuleStr = "`:- module'"
+	    ; ModuleType = transparent,
+		ModuleStr = "`:- transparent_module'"
+	    ),
+	    ( EndModuleType = opaque,
+		EndModuleStr = "`:- end_module'"
+	    ; EndModuleType = transparent,
+		EndModuleStr = "`:- end_transparent_module'"
+	    ),
+	    ErrorString = EndModuleStr ++ " declaration doesn't match " ++
+	   		 ModuleStr ++ " declaration",
+	    ( ModuleName \= EndModuleName ->
+		dummy_term_with_context(EndContext, Term),
+		add_error(ErrorString, Term, Messages0, Messages),
+		Error = some_module_errors
+	    ; ModuleType \= EndModuleType ->
+		dummy_term_with_context(EndContext, Term),
+		add_error(ErrorString, Term, Messages0, Messages),
+		Error = some_module_errors
+	    ;
+		Messages = Messages0,
+		Error = Error0
+	    )
+	;
 	    Messages = Messages0,
 	    Error = Error0
-        )
+	)
     ;
 	% if there's no `:- module' declaration at this point, it is
 	% an internal error -- read_first_item should have inserted one
@@ -521,7 +539,7 @@
 	    %
 	    { MaybeFirstItem = ok(FirstItem, FirstContext) },
 	    { FirstItem = module_defn(_VarSet, ModuleDefn) },
-	    { ModuleDefn = module(StartModuleName) }
+	    { ModuleDefn = module(StartModuleName, ModuleType) }
 	->
 	    
 	    %
@@ -553,7 +571,8 @@
 		% but now we use the declared one.
 		ModuleName = StartModuleName
 	    },
-	    { make_module_decl(ModuleName, FirstContext, FixedFirstItem) },
+	    { make_module_decl(ModuleName, ModuleType,
+	    		FirstContext, FixedFirstItem) },
 	    { Items0 = [FixedFirstItem] },
 	    { Error0 = no_module_errors },
 	    read_items_loop(ModuleName, SourceFileName,
@@ -579,7 +598,8 @@
 		Messages0 = []
 	    },
 	    { ModuleName = DefaultModuleName },
-	    { make_module_decl(ModuleName, FirstContext, FixedFirstItem) },
+	    { make_module_decl(ModuleName, opaque,
+	   		 FirstContext, FixedFirstItem) },
     
 	    %
 	    % reparse the first term, this time treating it as
@@ -597,12 +617,13 @@
 		Messages, Items, Error)
 	).
 
-:- pred make_module_decl(module_name, term__context, item_and_context).
-:- mode make_module_decl(in, in, out) is det.
+:- pred make_module_decl(module_name, module_type,
+		term__context, item_and_context).
+:- mode make_module_decl(in, in, in, out) is det.
 
-make_module_decl(ModuleName, Context, Item - Context) :-
+make_module_decl(ModuleName, ModuleType, Context, Item - Context) :-
 	varset__init(EmptyVarSet),
-	ModuleDefn = module(ModuleName),
+	ModuleDefn = module(ModuleName, ModuleType),
 	Item = module_defn(EmptyVarSet, ModuleDefn).
 
 :- pred maybe_add_warning(bool, read_term, term__context, string,
@@ -723,11 +744,11 @@
 		SourceFileName = NewSourceFileName,
 		ModuleName = ModuleName0,
 		Items1 = Items0
-	; Item = module_defn(_VarSet, module(NestedModuleName)) ->
+	; Item = module_defn(_VarSet, module(NestedModuleName, _)) ->
 		ModuleName = NestedModuleName,
 		SourceFileName = SourceFileName0,
 		Items1 = [Item - Context | Items0]
-	; Item = module_defn(_VarSet, end_module(NestedModuleName)) ->
+	; Item = module_defn(_VarSet, end_module(NestedModuleName, _)) ->
 		root_module_name(RootModuleName),
 		sym_name_get_module_name(NestedModuleName, RootModuleName,
 			ParentModuleName),
@@ -1071,7 +1092,21 @@
 	(	
 		Result0 = ok(ModuleNameSym), 
 		varset__coerce(VarSet0, VarSet),
-		Result1 = ok(module_defn(VarSet, module(ModuleNameSym)))
+		Result1 = ok(module_defn(VarSet, module(ModuleNameSym, opaque)))
+	;	
+		Result0 = error(A, B),
+		Result1 = error(A, B)
+	),
+	check_no_attributes(Result1, Attributes, Result).
+
+process_decl(DefaultModuleName, VarSet0, "transparent_module",
+		[ModuleName], Attributes, Result) :-
+	parse_module_name(DefaultModuleName, ModuleName, Result0),
+	(	
+		Result0 = ok(ModuleNameSym), 
+		varset__coerce(VarSet0, VarSet),
+		Result1 = ok(module_defn(VarSet,
+				module(ModuleNameSym, transparent)))
 	;	
 		Result0 = error(A, B),
 		Result1 = error(A, B)
@@ -1085,7 +1120,21 @@
 		Result0 = ok(ModuleNameSyms), 
 		varset__coerce(VarSet0, VarSet),
 		Result1 = ok(module_defn(VarSet,
-				include_module(ModuleNameSyms)))
+				include_module(opaque, ModuleNameSyms)))
+	;	
+		Result0 = error(A, B),
+		Result1 = error(A, B)
+	),
+	check_no_attributes(Result1, Attributes, Result).
+
+process_decl(DefaultModuleName, VarSet0, "include_transparent_module",
+		[ModuleNames], Attributes, Result) :-
+	parse_list(parse_module_name(DefaultModuleName), ModuleNames, Result0),
+	(	
+		Result0 = ok(ModuleNameSyms), 
+		varset__coerce(VarSet0, VarSet),
+		Result1 = ok(module_defn(VarSet,
+				include_module(transparent, ModuleNameSyms)))
 	;	
 		Result0 = error(A, B),
 		Result1 = error(A, B)
@@ -1106,7 +1155,31 @@
 	(	
 		Result0 = ok(ModuleNameSym), 
 		varset__coerce(VarSet0, VarSet),
-		Result1 = ok(module_defn(VarSet, end_module(ModuleNameSym)))
+		Result1 = ok(module_defn(VarSet,
+				end_module(ModuleNameSym, opaque)))
+	;	
+		Result0 = error(A, B),
+		Result1 = error(A, B)
+	),
+	check_no_attributes(Result1, Attributes, Result).
+
+process_decl(DefaultModuleName, VarSet0, "end_transparent_module", [ModuleName],
+		Attributes, Result) :-
+	%
+	% The name in an `end_transparent_module' declaration is not
+	% inside the scope of the module being ended, so the default
+	% module name here is the parent of the previous default module
+	% name.
+	%
+	root_module_name(RootModuleName),
+	sym_name_get_module_name(DefaultModuleName, RootModuleName,
+		ParentOfDefaultModuleName),
+	parse_module_name(ParentOfDefaultModuleName, ModuleName, Result0),
+	(	
+		Result0 = ok(ModuleNameSym), 
+		varset__coerce(VarSet0, VarSet),
+		Result1 = ok(module_defn(VarSet,
+				end_module(ModuleNameSym, transparent)))
 	;	
 		Result0 = error(A, B),
 		Result1 = error(A, B)
Index: doc/reference_manual.texi
===================================================================
RCS file: /home/mercury1/repository/mercury/doc/reference_manual.texi,v
retrieving revision 1.228
diff -u -r1.228 reference_manual.texi
--- doc/reference_manual.texi	22 Nov 2001 19:19:54 -0000	1.228
+++ doc/reference_manual.texi	3 Dec 2001 14:16:43 -0000
@@ -487,8 +487,10 @@
 --->              xfy       1179
 type              fx        1180
 end_module        fx        1199
+end_transparent_module fx        1199
 import_module     fx        1199
 include_module    fx        1199
+include_transparent_module fx        1199
 instance          fx        1199
 inst              fx        1199
 mode              fx        1199
@@ -497,6 +499,7 @@
 promise           fx        1199
 rule              fx        1199
 typeclass         fx        1199
+transparent_module fx        1199
 use_module        fx        1199
 -->               xfx       1200
 :-                xfx       1200
@@ -543,6 +546,9 @@
 :- use_module
 :- include_module
 :- end_module
+:- transparent_module
+:- include_transparent_module
+:- end_transparent_module
 @end example
 
 The @samp{type}, @samp{pred} and @samp{func} declarations are used for the
@@ -3650,10 +3656,23 @@
 @section Sub-modules
 
 As mentioned above, modules may contain sub-modules.
-There are two kinds of sub-modules, called nested sub-modules
-and separate sub-modules; the difference is that nested sub-modules
+A sub-module can be either nested or separate:
+the difference is that nested sub-modules
 are defined in the same source file as the containing module,
 whereas separate sub-modules are defined in separate source files.
+A sub-module is either transparent or opaque:
+the difference is that any interface transparent sub-modules
+are implicitly imported with a `:- use_module' declaration
+when the parent module is imported,
+whereas an opaque sub-module must always be explicitly imported.
+Most sub-modules should be opaque.
+Transparent sub-modules are a useful mechanism for entities which
+logically belong in the parent module but the entity needs an extra
+level of qualification.
+For example,
+transparent sub-modules can be used to avoid the restriction
+that two typeclasses in the same module can not have the same method name.
+
 Implementations should support separate compilation of separate sub-modules.
 
 A module may not contain more than one sub-module with the same name.
@@ -3668,13 +3687,17 @@
 @node Nested sub-modules
 @subsection Nested sub-modules
 
-Nested sub-modules within a module are delimited by
+Opaque nested sub-modules within a module are delimited by
 matching @samp{:- module} and @samp{:- end_module} declarations.
 (Note that @samp{:- end_module} for nested sub-modules 
 are mandatory, not optional, even if the nested sub-module
 is the last thing in the source file.
 Also note that the module name in a @samp{:- module} or @samp{:- end_module}
 declaration need not be fully-qualified.)
+Transparent nested sub-modules are delimited by
+ at samp{:- transparent_module} and @samp{:- end_transparent_module} declarations,
+but are otherwise syntactically identical to opaque sub-modules.
+
 The sequence of items thus delimited is known as a sub-module item sequence.
 
 The interface and implementation parts of a nested sub-module
@@ -3699,10 +3722,13 @@
 @node Separate sub-modules
 @subsection Separate sub-modules
 
-Separate sub-modules are declared using
+Opaque separate sub-modules are declared using
 @samp{:- include_module @var{Modules}} declarations.
-Each @samp{:- include_module} declaration specifies a comma-separated list
-of sub-modules.
+Transparent separate sub-modules are declared using
+ at samp{:- include_transparent_module @var{Modules}} declarations.
+Each @samp{:- include_module} or @samp{:- include_transparent_module}
+declaration specifies a comma-separated list of sub-modules.
+
 
 @example
 :- include_module @var{Module1}, @var{Module2}, @dots{}, @var{ModuleN}.
@@ -3787,7 +3813,8 @@
 is an error to import a module without importing all of its parent
 modules.
 
-Note that a sub-module for which the @samp{:- module} or
+Note that a sub-module for which the @samp{:- module},
+ at samp{transparent_module}, @samp{:- include_transparent_module} or
 @samp{:- include_module} declaration occurs only in the implementation
 section of the parent module may only be imported or used by its
 parent module or by sub-modules of its parent module.
Index: library/ops.m
===================================================================
RCS file: /home/mercury1/repository/mercury/library/ops.m,v
retrieving revision 1.37
diff -u -r1.37 ops.m
--- library/ops.m	12 Nov 2001 11:08:16 -0000	1.37
+++ library/ops.m	3 Dec 2001 14:16:44 -0000
@@ -313,10 +313,12 @@
 ops__op_table("div", after, yfx, 400).		% standard ISO Prolog
 ops__op_table("else", after, xfy, 1170).	% Mercury/NU-Prolog extension
 ops__op_table("end_module", before, fx, 1199).	% Mercury extension
+ops__op_table("end_transparent_module", before, fx, 1199). % Mercury extension
 ops__op_table("func", before, fx, 800).		% Mercury extension
 ops__op_table("if", before, fx, 1160).		% Mercury/NU-Prolog extension
 ops__op_table("import_module", before, fx, 1199). % Mercury extension
 ops__op_table("include_module", before, fx, 1199). % Mercury extension
+ops__op_table("include_transparent_module", before, fx, 1199). % Mercury extension
 ops__op_table("impure", before, fy, 800).	% Mercury extension
 ops__op_table("inst", before, fx, 1199).	% Mercury extension
 ops__op_table("instance", before, fx, 1199).	% Mercury extension
@@ -335,6 +337,7 @@
 ops__op_table("semipure", before, fy, 800).	% Mercury extension
 ops__op_table("some", before, fxy, 950).	% Mercury/NU-Prolog extension
 ops__op_table("then", after, xfx, 1150).	% Mercury/NU-Prolog extension
+ops__op_table("transparent_module", before, fx, 1199). % Mercury extension
 ops__op_table("type", before, fx, 1180).	% Mercury extension
 ops__op_table("typeclass", before, fx, 1199).	% Mercury extension
 ops__op_table("use_module", before, fx, 1199).	% Mercury extension
Index: tests/hard_coded/sub-modules/Mmakefile
===================================================================
RCS file: /home/mercury1/repository/tests/hard_coded/sub-modules/Mmakefile,v
retrieving revision 1.4
diff -u -r1.4 Mmakefile
--- tests/hard_coded/sub-modules/Mmakefile	15 Nov 2001 15:01:30 -0000	1.4
+++ tests/hard_coded/sub-modules/Mmakefile	3 Dec 2001 14:16:47 -0000
@@ -19,6 +19,7 @@
 
 PROGS=	\
 	use_submodule \
+	use_transparent \
 	parent \
 	parent2 \
 	nested \
Index: tests/hard_coded/sub-modules/auto_parent.m
===================================================================
RCS file: tests/hard_coded/sub-modules/auto_parent.m
diff -N tests/hard_coded/sub-modules/auto_parent.m
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ tests/hard_coded/sub-modules/auto_parent.m	3 Dec 2001 14:16:47 -0000
@@ -0,0 +1,44 @@
+% Test the auto_import statement.
+% Used by use_transparent.m
+
+:- module auto_parent.
+
+:- interface.
+
+:- import_module io.
+
+:- include_transparent_module separate.
+
+:- pred hello(io__state::di, io__state::uo) is det.
+
+  :- transparent_module auto_parent__nested.
+  :- interface.
+  :- pred hello(io__state::di, io__state::uo) is det.
+
+    :- transparent_module auto_parent__nested__nested.
+    :- interface.
+    :- pred hello(io__state::di, io__state::uo) is det.
+    :- end_transparent_module auto_parent__nested__nested.
+
+  :- end_transparent_module auto_parent__nested.
+
+:- implementation.
+
+hello -->
+	io__write_string("auto_parent: hello\n").
+
+:- transparent_module auto_parent__nested.
+:- implementation.
+
+hello -->
+	io__write_string("auto_parent__nested: hello\n").
+
+:- transparent_module auto_parent__nested__nested.
+:- implementation.
+
+hello -->
+	io__write_string("auto_parent__nested__nested: hello\n").
+
+:- end_transparent_module auto_parent__nested__nested.
+
+:- end_transparent_module auto_parent__nested.
Index: tests/hard_coded/sub-modules/auto_parent.separate.m
===================================================================
RCS file: tests/hard_coded/sub-modules/auto_parent.separate.m
diff -N tests/hard_coded/sub-modules/auto_parent.separate.m
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ tests/hard_coded/sub-modules/auto_parent.separate.m	3 Dec 2001 14:16:47 -0000
@@ -0,0 +1,14 @@
+% Used by use_transparent.m
+
+:- module auto_parent__separate.
+
+:- interface.
+
+% The parent module autos io.
+
+:- pred hello(io__state::di, io__state::uo) is det.
+
+:- implementation.
+
+hello -->
+	io__write_string("auto_parent__separate: hello\n").
Index: tests/hard_coded/sub-modules/use_transparent.exp
===================================================================
RCS file: tests/hard_coded/sub-modules/use_transparent.exp
diff -N tests/hard_coded/sub-modules/use_transparent.exp
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ tests/hard_coded/sub-modules/use_transparent.exp	3 Dec 2001 14:16:47 -0000
@@ -0,0 +1,3 @@
+auto_parent__nested: hello
+auto_parent__nested__nested: hello
+auto_parent__separate: hello
Index: tests/hard_coded/sub-modules/use_transparent.m
===================================================================
RCS file: tests/hard_coded/sub-modules/use_transparent.m
diff -N tests/hard_coded/sub-modules/use_transparent.m
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ tests/hard_coded/sub-modules/use_transparent.m	3 Dec 2001 14:16:47 -0000
@@ -0,0 +1,19 @@
+% Test the when importing the module auto_parent that we also import the
+% public transparent nested and seperate sub-modules.
+
+:- module use_transparent.
+
+:- interface.
+
+:- import_module io.
+
+:- pred main(io__state::di, io__state::uo) is det.
+
+:- implementation.
+
+:- import_module auto_parent.
+
+main -->
+	auto_parent__nested__hello,
+	nested__nested__hello,
+	auto_parent__separate__hello.
Index: tests/invalid/Mmakefile
===================================================================
RCS file: /home/mercury1/repository/tests/invalid/Mmakefile,v
retrieving revision 1.101
diff -u -r1.101 Mmakefile
--- tests/invalid/Mmakefile	15 Nov 2001 13:32:48 -0000	1.101
+++ tests/invalid/Mmakefile	3 Dec 2001 14:16:47 -0000
@@ -93,6 +93,7 @@
 	spurious_mode_error.m \
 	tc_err1.m \
 	tc_err2.m \
+	transparent.m \
 	tricky_assert1.m \
 	type_inf_loop.m \
 	type_loop.m \
@@ -185,6 +186,7 @@
 
 # For these test cases, the bug is caught when generating dependencies,
 # so it is easiest just to do that step.
+MCFLAGS-transparent =	--generate-dependencies
 MCFLAGS-nested_impl_in_int =	--generate-dependencies
 MCFLAGS-duplicate_module_test =	--generate-dependencies
 

--------------------------------------------------------------------------
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