diff --git a/compiler/add_class.m b/compiler/add_class.m
index 0479bcf0f..420ba04b6 100644
--- a/compiler/add_class.m
+++ b/compiler/add_class.m
@@ -50,6 +50,7 @@
:- import_module mdbcomp.prim_data.
:- import_module mdbcomp.sym_name.
:- import_module parse_tree.prog_data.
+:- import_module parse_tree.prog_item_pred_proc_id.
:- import_module parse_tree.prog_type.
:- import_module parse_tree.prog_util.
diff --git a/compiler/add_foreign_enum.m b/compiler/add_foreign_enum.m
index e44f5f6fd..5faf40587 100644
--- a/compiler/add_foreign_enum.m
+++ b/compiler/add_foreign_enum.m
@@ -34,6 +34,7 @@
:- import_module parse_tree.error_spec.
:- import_module parse_tree.prog_data.
:- import_module parse_tree.prog_item.
+:- import_module parse_tree.prog_item_type.
:- import_module list.
:- import_module map.
diff --git a/compiler/add_mode.m b/compiler/add_mode.m
index 8ef4915d3..386697d72 100644
--- a/compiler/add_mode.m
+++ b/compiler/add_mode.m
@@ -21,7 +21,7 @@
:- import_module hlds.status.
:- import_module parse_tree.
:- import_module parse_tree.error_spec.
-:- import_module parse_tree.prog_item.
+:- import_module parse_tree.prog_item_inst_mode.
:- import_module list.
diff --git a/compiler/add_mutable_aux_preds.m b/compiler/add_mutable_aux_preds.m
index 00f7c94d3..c2fdf4e31 100644
--- a/compiler/add_mutable_aux_preds.m
+++ b/compiler/add_mutable_aux_preds.m
@@ -27,6 +27,7 @@
:- import_module parse_tree.prog_data.
:- import_module parse_tree.prog_foreign.
:- import_module parse_tree.prog_item.
+:- import_module parse_tree.prog_item_pragma.
:- import_module cord.
:- import_module list.
diff --git a/compiler/add_pragma_decl.m b/compiler/add_pragma_decl.m
index c543484bc..5ad7de9b5 100644
--- a/compiler/add_pragma_decl.m
+++ b/compiler/add_pragma_decl.m
@@ -19,7 +19,7 @@
:- import_module hlds.make_hlds.qual_info.
:- import_module parse_tree.
:- import_module parse_tree.error_spec.
-:- import_module parse_tree.prog_item.
+:- import_module parse_tree.prog_item_pragma.
:- import_module io.
:- import_module list.
@@ -88,6 +88,7 @@
:- import_module parse_tree.maybe_error.
:- import_module parse_tree.prog_data.
:- import_module parse_tree.prog_data_pragma.
+:- import_module parse_tree.prog_item_pred_proc_id.
:- import_module parse_tree.prog_util.
:- import_module transform_hlds.
:- import_module transform_hlds.term_constr_main_types.
diff --git a/compiler/add_pragma_gen.m b/compiler/add_pragma_gen.m
index 1cd3fe29a..eca41e264 100644
--- a/compiler/add_pragma_gen.m
+++ b/compiler/add_pragma_gen.m
@@ -17,7 +17,7 @@
:- import_module hlds.hlds_module.
:- import_module parse_tree.
:- import_module parse_tree.error_spec.
-:- import_module parse_tree.prog_item.
+:- import_module parse_tree.prog_item_pragma.
:- import_module list.
@@ -53,6 +53,7 @@
:- import_module parse_tree.maybe_error.
:- import_module parse_tree.prog_data.
:- import_module parse_tree.prog_data_pragma.
+:- import_module parse_tree.prog_item_pred_proc_id.
:- import_module map.
:- import_module maybe.
diff --git a/compiler/add_pragma_impl.m b/compiler/add_pragma_impl.m
index a950317e9..e6f5cee01 100644
--- a/compiler/add_pragma_impl.m
+++ b/compiler/add_pragma_impl.m
@@ -19,7 +19,7 @@
:- import_module hlds.make_hlds.qual_info.
:- import_module parse_tree.
:- import_module parse_tree.error_spec.
-:- import_module parse_tree.prog_item.
+:- import_module parse_tree.prog_item_pragma.
:- import_module io.
:- import_module list.
@@ -84,6 +84,8 @@
:- import_module parse_tree.prog_data_foreign.
:- import_module parse_tree.prog_data_pragma.
:- import_module parse_tree.prog_foreign.
+:- import_module parse_tree.prog_item.
+:- import_module parse_tree.prog_item_pred_proc_id.
:- import_module parse_tree.prog_util.
:- import_module bool.
diff --git a/compiler/add_pragma_tabling.m b/compiler/add_pragma_tabling.m
index 279cb8049..ef47356c6 100644
--- a/compiler/add_pragma_tabling.m
+++ b/compiler/add_pragma_tabling.m
@@ -14,7 +14,7 @@
:- import_module hlds.status.
:- import_module parse_tree.
:- import_module parse_tree.error_spec.
-:- import_module parse_tree.prog_item.
+:- import_module parse_tree.prog_item_pragma.
:- import_module io.
:- import_module list.
@@ -60,6 +60,8 @@
:- import_module parse_tree.prog_data.
:- import_module parse_tree.prog_data_foreign.
:- import_module parse_tree.prog_data_pragma.
+:- import_module parse_tree.prog_item.
+:- import_module parse_tree.prog_item_pred_proc_id.
:- import_module parse_tree.prog_mode.
:- import_module parse_tree.prog_util.
diff --git a/compiler/add_pragma_type_spec.m b/compiler/add_pragma_type_spec.m
index a6825ee8c..8fec50445 100644
--- a/compiler/add_pragma_type_spec.m
+++ b/compiler/add_pragma_type_spec.m
@@ -13,7 +13,7 @@
:- import_module hlds.make_hlds.qual_info.
:- import_module parse_tree.
:- import_module parse_tree.error_spec.
-:- import_module parse_tree.prog_item.
+:- import_module parse_tree.prog_item_pragma.
:- import_module list.
@@ -49,6 +49,7 @@
:- import_module parse_tree.maybe_error.
:- import_module parse_tree.prog_data.
:- import_module parse_tree.prog_data_pragma.
+:- import_module parse_tree.prog_item_pred_proc_id.
:- import_module parse_tree.prog_type_scan.
:- import_module parse_tree.prog_type_subst.
:- import_module parse_tree.prog_util.
diff --git a/compiler/add_pragma_type_spec_constr.m b/compiler/add_pragma_type_spec_constr.m
index 3d00d6cfd..4fc68e7e9 100644
--- a/compiler/add_pragma_type_spec_constr.m
+++ b/compiler/add_pragma_type_spec_constr.m
@@ -13,7 +13,7 @@
:- import_module hlds.make_hlds.qual_info.
:- import_module parse_tree.
:- import_module parse_tree.error_spec.
-:- import_module parse_tree.prog_item.
+:- import_module parse_tree.prog_item_pragma.
:- import_module io.
:- import_module list.
@@ -48,6 +48,7 @@
:- import_module parse_tree.parse_tree_out_type.
:- import_module parse_tree.prog_data.
:- import_module parse_tree.prog_data_pragma.
+:- import_module parse_tree.prog_item_pred_proc_id.
:- import_module parse_tree.prog_type_scan.
:- import_module parse_tree.prog_type_subst.
:- import_module parse_tree.prog_type_test.
diff --git a/compiler/add_pragma_util.m b/compiler/add_pragma_util.m
index 75ce2c5e1..992437fc4 100644
--- a/compiler/add_pragma_util.m
+++ b/compiler/add_pragma_util.m
@@ -28,7 +28,7 @@
:- import_module parse_tree.error_spec.
:- import_module parse_tree.maybe_error.
:- import_module parse_tree.prog_data.
-:- import_module parse_tree.prog_item.
+:- import_module parse_tree.prog_item_pred_proc_id.
:- import_module list.
:- import_module one_or_more.
diff --git a/compiler/add_pred.m b/compiler/add_pred.m
index 5ec333e1e..99e1fb916 100644
--- a/compiler/add_pred.m
+++ b/compiler/add_pred.m
@@ -111,6 +111,7 @@
:- import_module libs.options.
:- import_module mdbcomp.builtin_modules.
:- import_module parse_tree.builtin_lib_types.
+:- import_module parse_tree.prog_item_pred_proc_id.
:- import_module parse_tree.prog_mode.
:- import_module parse_tree.prog_parse_tree.
:- import_module parse_tree.prog_type.
diff --git a/compiler/add_solver.m b/compiler/add_solver.m
index bd4e130ed..44a981ac4 100644
--- a/compiler/add_solver.m
+++ b/compiler/add_solver.m
@@ -71,6 +71,7 @@
:- import_module mdbcomp.prim_data.
:- import_module parse_tree.prog_data_foreign.
+:- import_module parse_tree.prog_item_pred_proc_id.
:- import_module parse_tree.prog_mode.
:- import_module parse_tree.prog_type.
diff --git a/compiler/add_type.m b/compiler/add_type.m
index edf519a47..2a57f2bc0 100644
--- a/compiler/add_type.m
+++ b/compiler/add_type.m
@@ -25,7 +25,7 @@
:- import_module parse_tree.
:- import_module parse_tree.error_spec.
:- import_module parse_tree.prog_data.
-:- import_module parse_tree.prog_item.
+:- import_module parse_tree.prog_item_type.
:- import_module list.
diff --git a/compiler/build_eqv_maps.m b/compiler/build_eqv_maps.m
index ba451e7f6..531736c84 100644
--- a/compiler/build_eqv_maps.m
+++ b/compiler/build_eqv_maps.m
@@ -55,6 +55,8 @@
:- import_module parse_tree.error_spec.
:- import_module parse_tree.prog_data_foreign.
:- import_module parse_tree.prog_item.
+:- import_module parse_tree.prog_item_inst_mode.
+:- import_module parse_tree.prog_item_type.
:- import_module recompilation.
:- import_module recompilation.item_types.
diff --git a/compiler/check_type_inst_mode_defns.m b/compiler/check_type_inst_mode_defns.m
index 832020a2d..6e539ffbd 100644
--- a/compiler/check_type_inst_mode_defns.m
+++ b/compiler/check_type_inst_mode_defns.m
@@ -21,7 +21,8 @@
:- import_module parse_tree.error_spec.
:- import_module parse_tree.prog_data.
:- import_module parse_tree.prog_foreign_enum.
-:- import_module parse_tree.prog_item.
+:- import_module parse_tree.prog_item_inst_mode.
+:- import_module parse_tree.prog_item_type.
:- import_module list.
diff --git a/compiler/comp_unit_interface.m b/compiler/comp_unit_interface.m
index b9a5f8171..f17bc5a5b 100644
--- a/compiler/comp_unit_interface.m
+++ b/compiler/comp_unit_interface.m
@@ -161,6 +161,8 @@
:- import_module parse_tree.prog_data_foreign.
:- import_module parse_tree.prog_foreign.
:- import_module parse_tree.prog_item.
+:- import_module parse_tree.prog_item_inst_mode.
+:- import_module parse_tree.prog_item_type.
:- import_module parse_tree.prog_mutable.
:- import_module parse_tree.prog_type.
:- import_module parse_tree.prog_type_repn.
diff --git a/compiler/convert_parse_tree.m b/compiler/convert_parse_tree.m
index 5083c0868..3b2113a0e 100644
--- a/compiler/convert_parse_tree.m
+++ b/compiler/convert_parse_tree.m
@@ -168,6 +168,10 @@
:- import_module parse_tree.prog_data_foreign.
:- import_module parse_tree.prog_data_pragma.
:- import_module parse_tree.prog_foreign.
+:- import_module parse_tree.prog_item_inst_mode.
+:- import_module parse_tree.prog_item_pragma.
+:- import_module parse_tree.prog_item_pred_proc_id.
+:- import_module parse_tree.prog_item_type.
:- import_module parse_tree.prog_util.
:- import_module parse_tree.type_inst_mode_map.
:- import_module recompilation.
diff --git a/compiler/dead_proc_elim.m b/compiler/dead_proc_elim.m
index c24fea52a..c86ae6605 100644
--- a/compiler/dead_proc_elim.m
+++ b/compiler/dead_proc_elim.m
@@ -202,7 +202,6 @@
:- import_module libs.options.
:- import_module mdbcomp.builtin_modules.
:- import_module parse_tree.prog_data_pragma.
-:- import_module parse_tree.prog_item. % undesirable dependency
:- import_module parse_tree.prog_parse_tree. % undesirable dependency
:- import_module assoc_list.
diff --git a/compiler/decide_type_repn.m b/compiler/decide_type_repn.m
index 17027b678..c5dff7101 100644
--- a/compiler/decide_type_repn.m
+++ b/compiler/decide_type_repn.m
@@ -131,7 +131,7 @@
:- import_module mdbcomp.
:- import_module mdbcomp.sym_name.
:- import_module parse_tree.error_spec.
-:- import_module parse_tree.prog_item.
+:- import_module parse_tree.prog_item_type.
:- import_module parse_tree.prog_parse_tree.
:- import_module list.
@@ -169,6 +169,7 @@
:- import_module parse_tree.equiv_type_parse_tree.
:- import_module parse_tree.parse_tree_out_type_repn.
:- import_module parse_tree.prog_data.
+:- import_module parse_tree.prog_item.
:- import_module parse_tree.prog_type.
:- import_module parse_tree.prog_type_construct.
:- import_module parse_tree.prog_type_subst.
diff --git a/compiler/du_type_layout.m b/compiler/du_type_layout.m
index 79144b62f..7b10db77e 100644
--- a/compiler/du_type_layout.m
+++ b/compiler/du_type_layout.m
@@ -125,7 +125,7 @@
:- import_module parse_tree.parse_tree_out_term.
:- import_module parse_tree.parse_tree_out_type.
:- import_module parse_tree.prog_data.
-:- import_module parse_tree.prog_item. % undesirable dependency
+:- import_module parse_tree.prog_item_type.
:- import_module parse_tree.prog_parse_tree. % undesirable dependency
:- import_module parse_tree.prog_type.
:- import_module parse_tree.prog_type_test.
diff --git a/compiler/equiv_type_parse_tree.m b/compiler/equiv_type_parse_tree.m
index ad9889c1e..88ab45893 100644
--- a/compiler/equiv_type_parse_tree.m
+++ b/compiler/equiv_type_parse_tree.m
@@ -68,7 +68,7 @@
:- import_module parse_tree.error_spec.
:- import_module parse_tree.prog_data_event.
:- import_module parse_tree.prog_data_used_modules.
-:- import_module parse_tree.prog_item.
+:- import_module parse_tree.prog_item_type.
:- import_module parse_tree.prog_parse_tree.
:- import_module recompilation.
:- import_module recompilation.record_uses.
@@ -136,6 +136,8 @@
:- import_module parse_tree.prog_data.
:- import_module parse_tree.prog_data_foreign.
:- import_module parse_tree.prog_data_pragma.
+:- import_module parse_tree.prog_item.
+:- import_module parse_tree.prog_item_pragma.
:- import_module parse_tree.prog_type.
:- import_module parse_tree.prog_type_construct.
:- import_module parse_tree.prog_type_test.
diff --git a/compiler/get_dependencies.m b/compiler/get_dependencies.m
index 302147700..37518ecbb 100644
--- a/compiler/get_dependencies.m
+++ b/compiler/get_dependencies.m
@@ -188,6 +188,8 @@
:- import_module parse_tree.maybe_error.
:- import_module parse_tree.prog_data_pragma.
:- import_module parse_tree.prog_foreign.
+:- import_module parse_tree.prog_item_pragma.
+:- import_module parse_tree.prog_item_type.
:- import_module bool.
:- import_module cord.
diff --git a/compiler/hlds_module.m b/compiler/hlds_module.m
index d3609e8f1..bc86dceb5 100644
--- a/compiler/hlds_module.m
+++ b/compiler/hlds_module.m
@@ -49,6 +49,8 @@
:- import_module parse_tree.prog_data_used_modules.
:- import_module parse_tree.prog_foreign.
:- import_module parse_tree.prog_item.
+:- import_module parse_tree.prog_item_pragma.
+:- import_module parse_tree.prog_item_type.
:- import_module parse_tree.prog_parse_tree.
:- import_module recompilation.
:- import_module recompilation.record_uses.
diff --git a/compiler/intermod.m b/compiler/intermod.m
index a68a900e2..1cfaebac8 100644
--- a/compiler/intermod.m
+++ b/compiler/intermod.m
@@ -153,6 +153,10 @@
:- import_module parse_tree.prog_data.
:- import_module parse_tree.prog_data_foreign.
:- import_module parse_tree.prog_item.
+:- import_module parse_tree.prog_item_inst_mode.
+:- import_module parse_tree.prog_item_pragma.
+:- import_module parse_tree.prog_item_pred_proc_id.
+:- import_module parse_tree.prog_item_type.
:- import_module parse_tree.prog_util.
:- import_module parse_tree.var_db.
:- import_module parse_tree.var_table.
diff --git a/compiler/intermod_analysis.m b/compiler/intermod_analysis.m
index 285a67ca8..3abb5e66a 100644
--- a/compiler/intermod_analysis.m
+++ b/compiler/intermod_analysis.m
@@ -66,7 +66,7 @@
:- import_module hlds.hlds_module.
:- import_module hlds.hlds_pred.
:- import_module parse_tree.
-:- import_module parse_tree.prog_item.
+:- import_module parse_tree.prog_item_pragma.
:- import_module parse_tree.prog_parse_tree.
:- import_module set.
@@ -157,6 +157,7 @@
:- import_module parse_tree.prog_data.
:- import_module parse_tree.prog_data_foreign.
:- import_module parse_tree.prog_data_pragma.
+:- import_module parse_tree.prog_item_pred_proc_id.
:- import_module parse_tree.var_table.
:- import_module transform_hlds.intermod_order_pred_info.
:- import_module transform_hlds.term_constr_data.
diff --git a/compiler/item_util.m b/compiler/item_util.m
index d41bbc2d3..643e604d9 100644
--- a/compiler/item_util.m
+++ b/compiler/item_util.m
@@ -23,6 +23,9 @@
:- import_module parse_tree.prog_data.
:- import_module parse_tree.prog_data_foreign.
:- import_module parse_tree.prog_item.
+:- import_module parse_tree.prog_item_inst_mode.
+:- import_module parse_tree.prog_item_pragma.
+:- import_module parse_tree.prog_item_type.
:- import_module parse_tree.prog_parse_tree.
:- import_module list.
diff --git a/compiler/make_hlds_error.m b/compiler/make_hlds_error.m
index 26d4cadb6..94503a3f1 100644
--- a/compiler/make_hlds_error.m
+++ b/compiler/make_hlds_error.m
@@ -29,7 +29,7 @@
:- import_module parse_tree.
:- import_module parse_tree.error_spec.
:- import_module parse_tree.prog_data.
-:- import_module parse_tree.prog_item.
+:- import_module parse_tree.prog_item_pred_proc_id.
:- import_module list.
:- import_module maybe.
diff --git a/compiler/make_hlds_passes.m b/compiler/make_hlds_passes.m
index 5ee3e2bdb..7455eb363 100644
--- a/compiler/make_hlds_passes.m
+++ b/compiler/make_hlds_passes.m
@@ -94,7 +94,11 @@
:- import_module parse_tree.prog_data.
:- import_module parse_tree.prog_foreign.
:- import_module parse_tree.prog_item.
+:- import_module parse_tree.prog_item_inst_mode.
+:- import_module parse_tree.prog_item_pragma.
+:- import_module parse_tree.prog_item_pred_proc_id.
:- import_module parse_tree.prog_item_stats.
+:- import_module parse_tree.prog_item_type.
:- import_module parse_tree.prog_mode.
:- import_module parse_tree.prog_type.
:- import_module parse_tree.prog_type_construct.
diff --git a/compiler/make_hlds_separate_items.m b/compiler/make_hlds_separate_items.m
index c24b072ca..ecb1cb833 100644
--- a/compiler/make_hlds_separate_items.m
+++ b/compiler/make_hlds_separate_items.m
@@ -19,6 +19,9 @@
:- import_module parse_tree.
:- import_module parse_tree.prog_data.
:- import_module parse_tree.prog_item.
+:- import_module parse_tree.prog_item_inst_mode.
+:- import_module parse_tree.prog_item_pragma.
+:- import_module parse_tree.prog_item_type.
:- import_module parse_tree.prog_parse_tree.
:- import_module list.
diff --git a/compiler/mercury_compile_middle_passes.m b/compiler/mercury_compile_middle_passes.m
index 0244d5ac0..b705d6c46 100644
--- a/compiler/mercury_compile_middle_passes.m
+++ b/compiler/mercury_compile_middle_passes.m
@@ -23,11 +23,13 @@
:- import_module libs.op_mode.
:- import_module parse_tree.
:- import_module parse_tree.error_util.
-:- import_module parse_tree.prog_item.
+:- import_module parse_tree.prog_item_pragma.
:- import_module io.
:- import_module set.
+%---------------------------------------------------------------------------%
+
:- pred middle_pass(io.text_output_stream::in, io.text_output_stream::in,
op_mode_front_and_middle::in,
module_info::in, module_info::out, dump_info::in, dump_info::out,
diff --git a/compiler/module_qual.collect_mq_info.m b/compiler/module_qual.collect_mq_info.m
index 0ffef14c7..1151643f7 100644
--- a/compiler/module_qual.collect_mq_info.m
+++ b/compiler/module_qual.collect_mq_info.m
@@ -50,6 +50,8 @@
:- import_module parse_tree.parse_sym_name.
:- import_module parse_tree.prog_data.
:- import_module parse_tree.prog_item.
+:- import_module parse_tree.prog_item_inst_mode.
+:- import_module parse_tree.prog_item_type.
:- import_module bool.
:- import_module list.
diff --git a/compiler/module_qual.qual_errors.m b/compiler/module_qual.qual_errors.m
index 223e1c594..af9b6cee4 100644
--- a/compiler/module_qual.qual_errors.m
+++ b/compiler/module_qual.qual_errors.m
@@ -20,7 +20,7 @@
:- import_module parse_tree.module_qual.id_set.
:- import_module parse_tree.module_qual.mq_info.
:- import_module parse_tree.prog_data.
-:- import_module parse_tree.prog_item.
+:- import_module parse_tree.prog_item_pragma.
:- import_module list.
:- import_module maybe.
diff --git a/compiler/module_qual.qualify_items.m b/compiler/module_qual.qualify_items.m
index d39a44824..e07a8942d 100644
--- a/compiler/module_qual.qualify_items.m
+++ b/compiler/module_qual.qualify_items.m
@@ -92,6 +92,10 @@
:- import_module parse_tree.prog_data_foreign.
:- import_module parse_tree.prog_data_pragma.
:- import_module parse_tree.prog_item.
+:- import_module parse_tree.prog_item_inst_mode.
+:- import_module parse_tree.prog_item_pragma.
+:- import_module parse_tree.prog_item_pred_proc_id.
+:- import_module parse_tree.prog_item_type.
:- import_module parse_tree.prog_type_test.
:- import_module parse_tree.prog_util.
:- import_module recompilation.
diff --git a/compiler/notes/compiler_design.html b/compiler/notes/compiler_design.html
index 208fda325..9876a87fd 100644
--- a/compiler/notes/compiler_design.html
+++ b/compiler/notes/compiler_design.html
@@ -379,7 +379,9 @@ but that is not part of the parse_tree.m package.)
The parse tree data structure definition is in prog_data.m,
prog_data_event.m, prog_data_foreign.m, prog_data_pragma.m,
-prog_data_used_modules.m, prog_item.m, prog_parse_tree.m and file_kind.m,
+prog_data_used_modules.m, prog_item.m, prog_item_inst_mode.m,
+prog_item_pragma.m, prog_item_pred_proc_id.m, prog_item_type.m,
+prog_parse_tree.m and file_kind.m,
while the code to create it is in the following modules.
diff --git a/compiler/parse_inst_mode_defn.m b/compiler/parse_inst_mode_defn.m
index 26ad0bf51..34beb37ab 100644
--- a/compiler/parse_inst_mode_defn.m
+++ b/compiler/parse_inst_mode_defn.m
@@ -59,6 +59,7 @@
:- import_module parse_tree.parse_tree_out_term.
:- import_module parse_tree.parse_util.
:- import_module parse_tree.prog_item.
+:- import_module parse_tree.prog_item_inst_mode.
:- import_module cord.
:- import_module maybe.
diff --git a/compiler/parse_item.m b/compiler/parse_item.m
index 06a8b3df0..0006c50d8 100644
--- a/compiler/parse_item.m
+++ b/compiler/parse_item.m
@@ -127,6 +127,7 @@
:- import_module parse_tree.parse_type_repn.
:- import_module parse_tree.parse_util.
:- import_module parse_tree.parse_vars.
+:- import_module parse_tree.prog_item_pred_proc_id.
:- import_module parse_tree.prog_mode.
:- import_module parse_tree.prog_parse_tree.
:- import_module recompilation.
diff --git a/compiler/parse_mutable.m b/compiler/parse_mutable.m
index 0803b4e63..ce916aac8 100644
--- a/compiler/parse_mutable.m
+++ b/compiler/parse_mutable.m
@@ -59,6 +59,7 @@
:- import_module parse_tree.parse_tree_out_term.
:- import_module parse_tree.parse_type_name.
:- import_module parse_tree.parse_util.
+:- import_module parse_tree.prog_item_pred_proc_id.
:- import_module assoc_list.
:- import_module cord.
diff --git a/compiler/parse_pragma.m b/compiler/parse_pragma.m
index 9c6b0997e..c76699dca 100644
--- a/compiler/parse_pragma.m
+++ b/compiler/parse_pragma.m
@@ -55,6 +55,8 @@
:- import_module parse_tree.parse_util.
:- import_module parse_tree.prog_data_pragma.
:- import_module parse_tree.prog_item.
+:- import_module parse_tree.prog_item_pragma.
+:- import_module parse_tree.prog_item_pred_proc_id.
:- import_module parse_tree.prog_type_scan.
:- import_module parse_tree.prog_type_test.
diff --git a/compiler/parse_pragma_analysis.m b/compiler/parse_pragma_analysis.m
index 007775a52..283a5188b 100644
--- a/compiler/parse_pragma_analysis.m
+++ b/compiler/parse_pragma_analysis.m
@@ -77,6 +77,8 @@
:- import_module parse_tree.prog_ctgc.
:- import_module parse_tree.prog_data_pragma.
:- import_module parse_tree.prog_item.
+:- import_module parse_tree.prog_item_pragma.
+:- import_module parse_tree.prog_item_pred_proc_id.
:- import_module bool.
:- import_module cord.
diff --git a/compiler/parse_pragma_foreign.m b/compiler/parse_pragma_foreign.m
index bb5ca3e0c..3fddf9b34 100644
--- a/compiler/parse_pragma_foreign.m
+++ b/compiler/parse_pragma_foreign.m
@@ -117,6 +117,9 @@
:- import_module parse_tree.prog_data_foreign.
:- import_module parse_tree.prog_data_pragma.
:- import_module parse_tree.prog_item.
+:- import_module parse_tree.prog_item_pragma.
+:- import_module parse_tree.prog_item_pred_proc_id.
+:- import_module parse_tree.prog_item_type.
:- import_module parse_tree.prog_mode.
:- import_module assoc_list.
diff --git a/compiler/parse_pragma_tabling.m b/compiler/parse_pragma_tabling.m
index 9c47aa0d8..49a484e61 100644
--- a/compiler/parse_pragma_tabling.m
+++ b/compiler/parse_pragma_tabling.m
@@ -45,6 +45,7 @@
:- import_module parse_tree.parse_tree_out_term.
:- import_module parse_tree.parse_util.
:- import_module parse_tree.prog_item.
+:- import_module parse_tree.prog_item_pragma.
:- import_module assoc_list.
:- import_module bool.
diff --git a/compiler/parse_tree.m b/compiler/parse_tree.m
index 719879073..d4fbd2f06 100644
--- a/compiler/parse_tree.m
+++ b/compiler/parse_tree.m
@@ -18,11 +18,16 @@
:- interface.
% The parse tree data type itself.
-% The parse tree is split in two. The parts defined in prog_parse_tree.m and
-% prog_item.m are needed only by the frontend of the compiler, the parts
-% in prog_data*.m are needed throughout.
+% The parse tree is split in two. The parts defined in prog_parse_tree.m,
+% prog_item.m, prog_item_pragma.m, prog_item_pred_proc_id.m, and
+% prog_item_type.m are needed only by the frontend of the compiler,
+% the parts in prog_data*.m are needed throughout.
:- include_module prog_parse_tree.
:- include_module prog_item.
+:- include_module prog_item_inst_mode.
+:- include_module prog_item_pragma.
+:- include_module prog_item_pred_proc_id.
+:- include_module prog_item_type.
:- include_module prog_data.
:- include_module prog_data_event.
:- include_module prog_data_foreign.
diff --git a/compiler/parse_tree_out_item.m b/compiler/parse_tree_out_item.m
index 2ed81c7f3..101ecffa4 100644
--- a/compiler/parse_tree_out_item.m
+++ b/compiler/parse_tree_out_item.m
@@ -22,6 +22,8 @@
:- import_module parse_tree.prog_data.
:- import_module parse_tree.prog_data_foreign.
:- import_module parse_tree.prog_item.
+:- import_module parse_tree.prog_item_inst_mode.
+:- import_module parse_tree.prog_item_type.
:- import_module io.
:- import_module list.
diff --git a/compiler/parse_tree_out_pragma.m b/compiler/parse_tree_out_pragma.m
index b0a8509a8..4214f0f2f 100644
--- a/compiler/parse_tree_out_pragma.m
+++ b/compiler/parse_tree_out_pragma.m
@@ -19,6 +19,7 @@
:- import_module parse_tree.prog_data.
:- import_module parse_tree.prog_data_pragma.
:- import_module parse_tree.prog_item.
+:- import_module parse_tree.prog_item_pragma.
:- import_module bool.
:- import_module io.
@@ -151,6 +152,7 @@
:- import_module parse_tree.parse_tree_out_type.
:- import_module parse_tree.prog_ctgc.
:- import_module parse_tree.prog_data_foreign.
+:- import_module parse_tree.prog_item_pred_proc_id.
:- import_module parse_tree.prog_util.
:- import_module parse_tree.var_db.
diff --git a/compiler/parse_tree_out_type_repn.m b/compiler/parse_tree_out_type_repn.m
index 7ebb6e0f6..88f4a285b 100644
--- a/compiler/parse_tree_out_type_repn.m
+++ b/compiler/parse_tree_out_type_repn.m
@@ -17,7 +17,7 @@
:- import_module parse_tree.parse_tree_out_info.
:- import_module parse_tree.parse_tree_output.
:- import_module parse_tree.prog_data.
-:- import_module parse_tree.prog_item.
+:- import_module parse_tree.prog_item_type.
:- import_module io.
:- import_module string.
diff --git a/compiler/parse_type_defn.m b/compiler/parse_type_defn.m
index 6de65fb51..c75c98e13 100644
--- a/compiler/parse_type_defn.m
+++ b/compiler/parse_type_defn.m
@@ -82,6 +82,7 @@
:- import_module parse_tree.parse_util.
:- import_module parse_tree.parse_vars.
:- import_module parse_tree.prog_item.
+:- import_module parse_tree.prog_item_type.
:- import_module parse_tree.prog_mode.
:- import_module parse_tree.prog_type.
:- import_module parse_tree.prog_type_scan.
diff --git a/compiler/parse_type_repn.m b/compiler/parse_type_repn.m
index 08be19fd2..74dafe8e9 100644
--- a/compiler/parse_type_repn.m
+++ b/compiler/parse_type_repn.m
@@ -44,6 +44,7 @@
:- import_module parse_tree.parse_type_name.
:- import_module parse_tree.parse_util.
:- import_module parse_tree.prog_item.
+:- import_module parse_tree.prog_item_type.
:- import_module cord.
:- import_module int.
diff --git a/compiler/parse_util.m b/compiler/parse_util.m
index 6e73065a5..7dbd44de7 100644
--- a/compiler/parse_util.m
+++ b/compiler/parse_util.m
@@ -34,7 +34,7 @@
:- import_module parse_tree.error_spec.
:- import_module parse_tree.maybe_error.
:- import_module parse_tree.prog_data.
-:- import_module parse_tree.prog_item.
+:- import_module parse_tree.prog_item_pred_proc_id.
:- import_module cord.
:- import_module integer.
diff --git a/compiler/prog_data.m b/compiler/prog_data.m
index e483f99c9..1d94b375a 100644
--- a/compiler/prog_data.m
+++ b/compiler/prog_data.m
@@ -876,6 +876,10 @@ cons_id_is_const_struct(ConsId, ConstNum) :-
; apply_n_type(tvar, list(ground_type), kind)
; kinded_type(ground_type, kind).
+:- type var_or_ground_type
+ ---> type_var_name(tvar, string)
+ ; ground_type(ground_type).
+
% We could use this subtype in the mercury_nb_type function symbol
% of mlds_type in mlds.m.
%
@@ -1230,6 +1234,13 @@ get_type_kind(kinded_type(_, Kind)) = Kind.
---> is_not_a_class_method
; is_a_class_method.
+:- type var_or_ground_constraint
+ ---> var_or_ground_constraint(
+ class_name,
+ list(var_or_ground_type),
+ prog_context
+ ).
+
:- implementation.
prog_constraint_get_class(Constraint) = Constraint ^ constraint_class.
diff --git a/compiler/prog_item.m b/compiler/prog_item.m
index c9ff201ca..2a67cb270 100644
--- a/compiler/prog_item.m
+++ b/compiler/prog_item.m
@@ -37,163 +37,17 @@
:- import_module parse_tree.maybe_error.
:- import_module parse_tree.prog_data.
:- import_module parse_tree.prog_data_foreign.
-:- import_module parse_tree.prog_data_pragma.
-:- import_module recompilation.
-:- import_module recompilation.item_types.
+:- import_module parse_tree.prog_item_inst_mode.
+:- import_module parse_tree.prog_item_pragma.
+:- import_module parse_tree.prog_item_pred_proc_id.
+:- import_module parse_tree.prog_item_type.
:- import_module assoc_list.
:- import_module list.
:- import_module map.
:- import_module maybe.
-:- import_module one_or_more.
-:- import_module pair.
:- import_module set.
-%---------------------------------------------------------------------------%
-%
-% The intended semantics of a type_ctor_defn_map is a map of
-% all the type constructors defined in a given SECTION of a given
-% interface file to all its definitions in that section.
-%
-% There are four intended uses of a type_ctor_defn_map. The most
-% important is the fourth one.
-%
-% One is to eliminate unnecessary items from interface files.
-% For example, library/set.m contains two definitions of the set
-% type constructor: an abstract definition in the publicly documented
-% interface section, and an actual du definition in another interface
-% section that we do not include in the automatically generated
-% documentation but we *do* export to other modules. In situations
-% like this, the abstract definition is redundant. Never including it
-% in an interface file lets that interface file to remain unchanged
-% in the event that the user deletes the abstract definition from
-% the source file as well.
-%
-% The second use is to canonicalize the parts of interface files
-% containing type definitions.
-%
-% The third use is to help deal with sets of definitions that
-% don't make sense. There are many rules that a set of definitions
-% for a given type constructor must meet (such as "there may be at most one
-% definition for a type constructor that is a du, equivalence or solver
-% definition), and bugs may manifest themselves as violations of these rules.
-%
-% We have a choice in when these violations are detected.
-%
-% - If we allow the inclusion of inconsistent sets of type definitions
-% in interface files, then we must detect and handle these
-% inconsistencies every time a compiler invocation reads that interface
-% file. These invocations won't generate error messages for these
-% inconsistencies since the type constructor won't be local, but
-% they may generate messages for other "errors" that look like errors
-% only because the compiler's resolution of the inconsistency (i.e.
-% its choice of which type definitions to keep and which to throw out)
-% differs from the programmer's choice.
-%
-% - If we do NOT allow the inclusion of inconsistent sets of type
-% definitions in interface files, then we must report any violations
-% at interface file construction time, and make them cause that
-% construction to fail. Printing such error messages to stdout
-% instead of the module's .err file is less than ideal, but
-% this early detection can avoid avalanches of misleading diagnostics
-% of the kind mentioned in the previous point. It can also save
-% recompilations. If a module's source file contains inconsistent
-% definitions for a type constructor, then the programmer will
-% have to delete the unintended ones. Once this is done, the
-% interface file will have to be rebuilt. If we allow inconsistent
-% definitions in the interface file, its new contents will differ
-% from its old contents, which means that all the compilations
-% of *other* modules that read the old contents will have been wasted.
-% If we cause the construction of the interface file to fail instead,
-% those compilations won't have taken place.
-%
-% We implement the first choice by checking whether each entry in
-% a type_ctor_defn_map makes sense, and generating error messages
-% when they don't. This is done by code in check_type_inst_mode_defns.m.
-%
-% The fourth and most motivating use is that having all the definitions
-% of a type_ctor, *and* all the foreign_enum pragmas that apply to that
-% type_ctor, all together at once will make the code that decides
-% the proper representation of that type significantly simpler.
-%
-% Everything above except the fourth use also applies to the inst_
-% and mode_ctor_defn_maps, though for those, the consistency rules are
-% much simpler: that each inst and mode constructor must have at most one
-% non-abstract definition.
-%
-
-:- type type_ctor_defn_map == map(type_ctor, type_ctor_all_defns).
-
-:- type type_ctor_all_defns
- ---> type_ctor_all_defns(
- % Abstract and nonabstract solver type definitions.
- tcad_abstract_solver :: list(item_type_defn_info_abstract),
- tcad_solver :: list(item_type_defn_info_solver),
-
- % Abstract and nonabstract nonsolver type definitions.
- tcad_abstract_std :: list(item_type_defn_info_abstract),
- tcad_eqv :: list(item_type_defn_info_eqv),
- tcad_du :: list(item_type_defn_info_du),
- tcad_sub :: list(item_type_defn_info_sub),
- tcad_foreign :: c_j_cs_defns
- ).
-
-:- type type_ctor_maybe_defn
- ---> type_ctor_maybe_defn(
- % Abstract and nonabstract solver type definitions.
- tcmd_abstract_solver :: maybe(item_type_defn_info_abstract),
- tcmd_solver :: maybe(item_type_defn_info_solver),
-
- % Abstract and nonabstract nonsolver type definitions.
- tcmd_abstract_std :: maybe(item_type_defn_info_abstract),
- tcmd_eqv :: maybe(item_type_defn_info_eqv),
- tcmd_du :: maybe(item_type_defn_info_du),
- tcmd_sub :: maybe(item_type_defn_info_sub),
- tcmd_foreign :: c_j_cs_maybe_defn
- ).
-
- % We support foreign type definitions in all three of our target languages,
- % C, Java and C#. Likewise, we allow foreign enum declarations
- % in these three languages.
- %
- % There are several kinds of info that we may want to store for every
- % one of these foreign languages. This can be done in instances
- % of this type, whose fields always contain the info for C, Java and C#
- % (in that order).
-:- type c_java_csharp(T)
- ---> c_java_csharp(T, T, T).
-
-:- type c_j_cs_defns ==
- c_java_csharp(list(item_type_defn_info_foreign)).
-:- type c_j_cs_maybe_defn ==
- c_java_csharp(maybe(item_type_defn_info_foreign)).
-:- type c_j_cs_enums ==
- c_java_csharp(list(item_foreign_enum_info)).
-:- type c_j_cs_maybe_enum ==
- c_java_csharp(maybe(item_foreign_enum_info)).
-:- type c_j_cs_repn ==
- c_java_csharp(maybe(foreign_type_repn)).
-:- type c_j_cs_enum_repn ==
- c_java_csharp(maybe(enum_foreign_repn)).
-
-:- type inst_ctor_defn_map == map(inst_ctor, inst_ctor_all_defns).
-:- type inst_ctor_all_defns
- ---> inst_ctor_all_defns(
- icad_abstract :: list(item_inst_defn_info_abstract),
- icad_eqv :: list(item_inst_defn_info_eqv)
- ).
-
-:- type mode_ctor_defn_map == map(mode_ctor, mode_ctor_all_defns).
-:- type mode_ctor_all_defns
- ---> mode_ctor_all_defns(
- mcad_abstract :: list(item_mode_defn_info_abstract),
- mcad_eqv :: list(item_mode_defn_info_eqv)
- ).
-
-:- type type_ctor_foreign_enum_map == map(type_ctor, c_j_cs_enums).
-
-:- type type_ctor_repn_map == map(type_ctor, item_type_repn_info).
-
%---------------------------------------------------------------------------%
%
% The main parts of parse trees are items. There are many kinds of items,
@@ -223,41 +77,7 @@
% to have more than item with that name, the main fields that distinguish
% items of the same name from each other.
%
-
- % Did an item originate in user code or was it added by the compiler
- % as part of a source-to-source transformation, e.g. the initialise
- % declarations? If the latter, specify the information that the
- % make_hlds pass may need to answer questions about the item.
- %
-:- type item_maybe_attrs
- ---> item_origin_user
- ; item_origin_compiler(item_compiler_attributes).
-
-:- type item_compiler_attributes
- ---> item_compiler_attributes(
- compiler_origin
- ).
-
-:- type compiler_origin
- ---> compiler_origin_initialise
- ; compiler_origin_finalise
- ; compiler_origin_class_method(
- cm_class_id :: class_id,
- cm_method :: pf_sym_name_user_arity
- )
- ; compiler_origin_solver_repn(
- cosr_type_ctor :: type_ctor,
- cosr_aux_pred_kind :: solver_type_pred_kind
- )
- ; compiler_origin_mutable(
- com_module_name :: module_name,
- com_mutable_name :: string,
- com_aux_pred_kind :: mutable_pred_kind
- )
- ; compiler_origin_tabling(
- cot_pred_spec :: pf_sym_name_user_arity,
- cot_aux_pred_kind :: tabling_aux_pred_kind
- ).
+%---------------------------------------------------------------------------%
:- type item
---> item_clause(item_clause_info)
@@ -282,6 +102,8 @@
; item_mutable(item_mutable_info)
; item_type_repn(item_type_repn_info).
+%---------------------------------------------------------------------------%
+
:- type item_clause_info
---> item_clause_info(
cl_pred_or_func :: pred_or_func,
@@ -293,87 +115,7 @@
cl_seq_num :: item_seq_num
).
-:- type item_type_defn_info == item_type_defn_info_general(type_defn).
-
-:- type item_type_defn_info_abstract
- == item_type_defn_info_general(type_details_abstract).
-:- type item_type_defn_info_solver
- == item_type_defn_info_general(type_details_solver).
-:- type item_type_defn_info_eqv
- == item_type_defn_info_general(type_details_eqv).
-:- type item_type_defn_info_du
- == item_type_defn_info_general(type_details_du).
-:- type item_type_defn_info_sub
- == item_type_defn_info_general(type_details_sub).
-:- type item_type_defn_info_foreign
- == item_type_defn_info_general(type_details_foreign_generic).
-
-:- type item_type_defn_info_general(T)
- ---> item_type_defn_info(
- % `:- type ...':
- % a definition of a type, or a declaration of an abstract type.
- td_ctor_name :: sym_name,
- td_ctor_args :: list(type_param),
- td_ctor_defn :: T,
- td_tvarset :: tvarset,
- td_context :: prog_context,
- td_seq_num :: item_seq_num
- ).
-
-:- type item_inst_defn_info
- == item_inst_defn_info_general(maybe_abstract_inst_defn).
-
-:- type item_inst_defn_info_abstract
- == item_inst_defn_info_general(no_inst_defn).
-:- type item_inst_defn_info_eqv
- == item_inst_defn_info_general(inst_defn).
-
-:- type item_inst_defn_info_general(T)
- ---> item_inst_defn_info(
- % `:- inst ... = ...':
- % a definition of an inst.
- id_inst_name :: sym_name,
- id_inst_args :: list(inst_var),
- id_maybe_for_type :: maybe(type_ctor),
- id_inst_defn :: T,
- id_varset :: inst_varset,
- id_context :: prog_context,
- id_seq_num :: item_seq_num
- ).
-
-:- type no_inst_defn
- ---> no_inst_defn.
-
-:- type maybe_abstract_inst_defn
- ---> abstract_inst_defn
- ; nonabstract_inst_defn(inst_defn).
-
-:- type item_mode_defn_info
- == item_mode_defn_info_general(maybe_abstract_mode_defn).
-
-:- type item_mode_defn_info_abstract
- == item_mode_defn_info_general(no_mode_defn).
-:- type item_mode_defn_info_eqv
- == item_mode_defn_info_general(mode_defn).
-
-:- type item_mode_defn_info_general(T)
- ---> item_mode_defn_info(
- % `:- mode ... = ...':
- % a definition of a mode.
- md_mode_name :: sym_name,
- md_mode_args :: list(inst_var),
- md_mode_defn :: T,
- md_varset :: inst_varset,
- md_context :: prog_context,
- md_seq_num :: item_seq_num
- ).
-
-:- type no_mode_defn
- ---> no_mode_defn.
-
-:- type maybe_abstract_mode_defn
- ---> abstract_mode_defn
- ; nonabstract_mode_defn(mode_defn).
+%---------------------------------------------------------------------------%
:- type item_pred_decl_info
---> item_pred_decl_info(
@@ -400,6 +142,8 @@
pf_seq_num :: item_seq_num
).
+%---------------------------------------------------------------------------%
+
:- type item_mode_decl_info
---> item_mode_decl_info(
% `:- mode ...':
@@ -417,6 +161,8 @@
pfm_seq_num :: item_seq_num
).
+%---------------------------------------------------------------------------%
+
:- type item_foreign_proc_info
---> item_foreign_proc_info(
% Set of foreign proc attributes, such as:
@@ -436,22 +182,7 @@
proc_seq_num :: item_seq_num
).
-:- type item_foreign_enum_info
- ---> item_foreign_enum_info(
- fe_language :: foreign_language,
- fe_type_ctor :: type_ctor,
- fe_values :: one_or_more(
- pair(sym_name, string)),
- fe_context :: prog_context,
- fe_seq_num :: item_seq_num
- ).
-
-:- type foreign_enum_spec
- ---> foreign_enum_spec(
- foreign_language,
- type_ctor,
- one_or_more(pair(sym_name, string))
- ).
+%---------------------------------------------------------------------------%
:- type item_foreign_export_enum_info
---> item_foreign_export_enum_info(
@@ -464,6 +195,8 @@
fee_seq_num :: item_seq_num
).
+%---------------------------------------------------------------------------%
+
:- type item_promise_info
---> item_promise_info(
prom_type :: promise_type,
@@ -474,6 +207,8 @@
prom_seq_num :: item_seq_num
).
+%---------------------------------------------------------------------------%
+
:- type item_typeclass_info
---> item_typeclass_info(
tc_class_name :: class_name,
@@ -519,6 +254,8 @@
tc_seq_num :: item_seq_num
).
+%---------------------------------------------------------------------------%
+
:- type item_instance_info
---> item_instance_info(
% The original types field preserves the types in the instance
@@ -551,6 +288,8 @@
ci_seq_num :: item_seq_num
).
+%---------------------------------------------------------------------------%
+
:- type item_initialise_info
---> item_initialise_info(
% :- initialise pred_name.
@@ -561,6 +300,8 @@
init_seq_num :: item_seq_num
).
+%---------------------------------------------------------------------------%
+
:- type item_finalise_info
---> item_finalise_info(
% :- finalise pred_name.
@@ -571,6 +312,8 @@
final_seq_num :: item_seq_num
).
+%---------------------------------------------------------------------------%
+
:- type item_mutable_info
---> item_mutable_info(
% :- mutable(var_name, type, inst, value, attrs).
@@ -589,32 +332,6 @@
mut_seq_num :: item_seq_num
).
-:- type item_type_repn_info_eqv
- == item_type_repn_info_general(mer_type).
-:- type item_type_repn_info_subtype
- == item_type_repn_info_general(type_ctor).
-:- type item_type_repn_info
- == item_type_repn_info_general(type_ctor_repn_info).
-
-:- type item_type_repn_info_general(T)
- ---> item_type_repn_info(
- % `:- type_representation ...':
- % An item added by the compiler to a .int3 file
- % to tell readers of that file the information they need
- % to correctly reconstruct the representation of the given
- % type constructor, even when that information is supposed
- % to be invisible to them semantically.
- % There should be at most one such item for any type_ctor
- % in the .int3 file of its defining module.
- % The sym_name should be fully qualified.
- tr_ctor :: sym_name,
- tr_ctor_arg_tvars :: list(tvar),
- tr_ctor_repn_info :: T,
- tr_tvarset :: tvarset,
- tr_context :: prog_context,
- tr_seq_num :: item_seq_num
- ).
-
%---------------------------------------------------------------------------%
%
% Declarations of relationships between modules.
@@ -844,1246 +561,6 @@
:- func mutable_thread_local_trailed(mutable_maybe_thread_local)
= mutable_trailed.
-%---------------------------------------------------------------------------%
-%
-% The representation of a checked-to-be-consistent set of type and
-% foreign enum definitions for every type constructor defined in a module.
-%
-
-:- type type_ctor_checked_map == map(type_ctor, type_ctor_checked_defn).
-
- % A type is either a solver type, or not.
-:- type type_ctor_checked_defn
- ---> checked_defn_solver(solver_type_defn, src_defns_solver)
- ; checked_defn_std(std_type_defn, src_defns_std).
-
-%---------------------%
-
- % Replace this one general type with one type for each function symbol
- % in solver_type_defn.
-:- type src_defns_solver
- ---> src_defns_solver(
- % The item_type_defn_info (if any) in the interface section.
- maybe(item_type_defn_info),
-
- % The item_type_defn_info (if any) in the impl section.
- maybe(item_type_defn_info)
- ).
-
- % Replace this one general type with one type for each function symbol
- % in std_type_defn.
-:- type src_defns_std
- ---> src_defns_std(
- % The item_type_defn_infos in the interface section.
- list(item_type_defn_info),
-
- % The item_type_defn_infos and item_foreign_enum_infos
- % in the implementation section.
- list(item_type_defn_info),
- list(item_foreign_enum_info)
- ).
-
-%---------------------%
-
-:- type solver_type_defn
- ---> solver_type_abstract(
- abstract_solver_type_status,
-
- % The abstract definition. It may be in either section;
- % the status specifies the section.
- item_type_defn_info_abstract
- )
- ; solver_type_full(
- % The abstract definition in the interface section,
- % if one exists.
- maybe(item_type_defn_info_abstract),
-
- % The full solver type definition, which must be in the
- % implementation section.
- item_type_defn_info_solver
- ).
-
-:- type abstract_solver_type_status
- ---> abstract_solver_type_exported
- % The type name is exported. The abstract definition
- % is in the interface section.
- ; abstract_solver_type_private.
- % The type name is not exported. The abstract definition
- % is in the implementation section.
-
-%---------------------%
-
-:- type std_type_defn
- ---> std_mer_type_eqv(
- std_eqv_type_status,
-
- % The equivalence type definition.
- item_type_defn_info_eqv
- )
- ; std_mer_type_subtype(
- std_subtype_status,
-
- % The subtype definition.
- item_type_defn_info_sub
- )
- ; std_mer_type_du_all_plain_constants(
- std_du_type_status,
-
- % The discriminated union type definition which represents
- % either a direct dummy type or an enum.
- item_type_defn_info_du,
-
- % The first functor name in the type, and any later functor
- % names. If there are no later functor names, then the type
- % is a direct dummy type, and must satisfy the requirements
- % of non_sub_du_type_is_dummy; if there are, then the type
- % is an enum type, and must satisfy the requirements of
- % non_sub_du_type_is_enum. (Function symbols that do not meet
- % the relevant requirements may be constants, but we
- % don't consider them *plain* constants.)
- string,
- list(string),
-
- % For each of our target foreign languages, this field
- % specifies whether we have either a foreign language
- % definition for this type, or a foreign enum definition.
- %
- % While the Mercury representation uses small integers
- % allocated consecutively from 0 to represent function symbols,
- % this is not true even for foreign enum definitions,
- % much less foreign type definitions.
- c_j_cs_maybe_defn_or_enum
- )
- ; std_mer_type_du_not_all_plain_constants(
- std_du_type_status,
-
- % The discriminated union type definition which represents
- % a type *other* than a direct dummy type or an enum.
- item_type_defn_info_du,
-
- % For each of our target foreign languages, this field
- % specifies whether we have a foreign language type definition
- % for this type.
- c_j_cs_maybe_defn
- )
- ; std_mer_type_abstract(
- std_abs_type_status,
-
- % The abstract declaration of the type (not a subtype).
- item_type_defn_info_abstract,
-
- % For each of our target foreign languages, this field
- % specifies whether we have a foreign language type definition
- % for this type.
- c_j_cs_maybe_defn
- ).
-
-:- type maybe_only_constants
- ---> not_only_plain_constants
- ; only_plain_constants(
- % The names of the constants, in the order of declaration.
- opc_head_name :: string,
- opc_tail_names :: list(string)
- ).
-
-:- type std_eqv_type_status
- ---> std_eqv_type_mer_exported
- % The Mercury definition (i.e. the equivalence) is exported.
- ; std_eqv_type_abstract_exported
- % Only the type name is exported. The Mercury definition
- % is private.
- ; std_eqv_type_all_private.
- % Everything about the type is private.
-
-:- type std_du_type_status
- ---> std_du_type_mer_ft_exported
- % Both the Mercury and any foreign type definitions are exported.
- % Any foreign enum definitions are private, as they have to be.
- % This status is not applicable to equivalence types or subtypes,
- % since they may not have foreign type definitions.
- ; std_du_type_mer_exported
- % The Mercury definition is exported. Any foreign type definitions
- % and/or foreign enum definitions are private.
- ; std_du_type_abstract_exported
- % Only the type name is exported. The Mercury definition and
- % any foreign type definitions and/or foreign enum definitions
- % are private.
- ; std_du_type_all_private.
- % Everything about the type is private.
-
- % A version of std_du_type_status for subtypes, which may not have
- % any foreign type definitions, and for which therefore the question of
- % whether any foreign type definitions are exported is moot.
-:- type std_subtype_status
- ---> std_sub_type_mer_exported
- ; std_sub_type_abstract_exported
- ; std_sub_type_all_private.
-
-:- type std_abs_type_status
- ---> std_abs_type_ft_exported
- % The type has foreign type definitions that are exported.
- % Any foreign enum definitions are private, as they have to be.
- ; std_abs_type_abstract_exported
- % Only the type name is exported. Any foreign type definitions
- % and/or foreign enum definitions are private.
- ; std_abs_type_all_private.
- % Everything about the type is private.
-
-%---------------------%
-
-:- type c_j_cs_maybe_defn_or_enum ==
- c_java_csharp(maybe(foreign_type_or_enum)).
-
-:- type foreign_type_or_enum
- ---> foreign_type_or_enum_type(item_type_defn_info_foreign)
- ; foreign_type_or_enum_enum(checked_foreign_enum).
-
- % Part of checking a foreign enum definition is checking whether
- % the correspondence it describes between the Mercury functors
- % of the type on the one hand and their foreign language counterparts
- % on the other hand is a bijection. If it is, then the second argument
- % of the checked_foreign_enum we construct gives the foreign language
- % counterpart of each Mercury function symbol in the type in the order
- % in which the Mercury function symbols are defined.
- %
- % For example, given
- %
- % :- type t ---> m1 ; m2 ; m3.
- %
- % and a foreign enum definition that gives the correspondence correctly
- % but in a different order, such as
- %
- % :- pragma foreign_enum("C", t/0, [m2 - "f2", m3 - "f3", m1 - "f1"]).
- %
- % the second argument will contain the (nonempty) list "f1", "f2", "f3".
- %
- % On the other hand, if the mapping in the foreign enum definition is
- % *not* a bijection, then we will not generate a checked_foreign_enum
- % structure for it.
- %
-:- type checked_foreign_enum
- ---> checked_foreign_enum(item_foreign_enum_info, one_or_more(string)).
-
-%---------------------------------------------------------------------------%
-%
-% The representation of a checked-to-be-consistent set of inst definitions
-% for every inst constructor defined in a module.
-%
-
-:- type inst_ctor_checked_map == map(inst_ctor, inst_ctor_checked_defn).
-
-:- type inst_ctor_checked_defn
- ---> checked_defn_inst(std_inst_defn, src_defns_inst).
-
-:- type std_inst_defn
- ---> std_inst_defn(std_inst_status, item_inst_defn_info).
-
-:- type std_inst_status
- ---> std_inst_exported
- % The inst definition is exported.
- ; std_inst_abstract_exported
- % Only the inst name is exported. Its definition is private.
- ; std_inst_all_private.
- % Everything about the inst is private.
-
-:- type src_defns_inst
- ---> src_defns_inst(
- % The inst definition (if any) in the interface.
- maybe(item_inst_defn_info),
-
- % The inst definition (if any) in the implementation.
- maybe(item_inst_defn_info)
- ).
-
-%---------------------------------------------------------------------------%
-%
-% The representation of a checked-to-be-consistent set of mode definitions
-% for every mode constructor defined in a module.
-%
-
-:- type mode_ctor_checked_map == map(mode_ctor, mode_ctor_checked_defn).
-
-:- type mode_ctor_checked_defn
- ---> checked_defn_mode(std_mode_defn, src_defns_mode).
-
-:- type std_mode_defn
- ---> std_mode_defn(std_mode_status, item_mode_defn_info).
-
-:- type std_mode_status
- ---> std_mode_exported
- % The mode definition is exported.
- ; std_mode_abstract_exported
- % Only the mode name is exported. Its definition is private.
- ; std_mode_all_private.
- % Everything about the mode is private.
-
-:- type src_defns_mode
- ---> src_defns_mode(
- % The mode definition (if any) in the interface.
- maybe(item_mode_defn_info),
-
- % The mode definition (if any) in the implementation.
- maybe(item_mode_defn_info)
- ).
-
-%---------------------------------------------------------------------------%
-%
-% Information about the representations of types defined in other modules.
-%
-
- % This type and type_ctor_checked_defn are closely related.
- % The principal differences are the following.
- %
- % - type_ctor_checked_defn deals with solver types. Since solver types
- % have no representation information themselves (they are represented
- % by values of another type), this type does not deal with them.
- %
- % - One of the purposes of type_ctor_checked_defn is to decide
- % what items to include in interface files, for use by code using
- % the compiler's ancient approach to deciding type representation,
- % where each compiler invocation that generated code decided for itself
- % how every type it had access to was represented, including the types
- % imported from other modules. This means that it needs to contain
- % either whole items (of particular kinds), or information from which
- % whole items can be reconstructed.
- %
- % - The above consideration also requires a type_ctor_checked_defn
- % to specify the status of the type. On the other hand, values of
- % this type have no use for status information. Status information
- % is used only for checking whether an access to a type should be
- % allowed or not; the only use of values of this type is to help
- % compute type representations.
- %
- % - Only this type needs to contain representation information.
- % A value of the type_ctor_checked_defn type needs to contain *part*
- % of the information from which this representation information is
- % computed for its type, but not *all* of it; some of that information
- % comes from information about the representation of *other* types.
- %
- % One sort-of difference is while both contain information that has been
- % checked by a compiler invocation, values of this type that have been
- % read in from an interface file, while checked by another compiler
- % invocation before being written out, may be corrupted in the filesystem.
- % However, while this danger is always present, we need not take any
- % special steps to guard against it, precisely because no perfect defense
- % is possible.
- %
- % XXX TYPE_REPN Consider whether we can split this type into two,
- % one for the tcrepns that can occur in .int3 files, and one for the
- % tcrepns that can occur in .int/.int2 files.
- %
-:- type type_ctor_repn_info
- ---> tcrepn_is_word_aligned_ptr
- ; tcrepn_is_eqv_to(mer_type)
- ; tcrepn_is_subtype_of(type_ctor)
- ; tcrepn_du(du_repn)
- ; tcrepn_foreign(c_j_cs_repn).
-
- % A type that has a discriminated union definition in Mercury
- % may also have a definition in each of our foreign languages,
- % If it is an direct_dummy or enum type, that definition may be
- % either a foreign type definition or a foreign enum definition;
- % otherwise, it can only be a foreign type definition.
-:- type du_repn
- ---> dur_direct_dummy(direct_dummy_repn)
- ; dur_enum(enum_repn)
- ; dur_notag(notag_repn)
- ; dur_gen_only_functor(gen_du_only_functor_repn)
- ; dur_gen_more_functors(gen_du_more_functors_repn).
-
- % When targeting C, many argument packing decisions depend on
- % three properties of the target platform, i.e. on the combination
- % of the target hardware and the target grade:
- %
- % - whether the target is 64 or 32 bit;
- % - whether the grade is an spf (single-precision float) grade; and
- % - whether the grade allows the direct arg optimization.
- %
- % These have eight combinations, but the spf grade component has
- % no effect on argument packing on 64 bit targets (a float is one word
- % either way), so only six are meaningful.
- %
- % If the decision represented by the T parameter happens to be the same
- % on all six platforms, that decision can be represented by c_repns_same.
- %
- % If they are different on 64 vs 32 bit platforms, but are consistent
- % for each word size, then they can be represented by c_repns_64_32.
- %
- % If neither is the case, we can record all six decisions using
- % c_repns_all.
- %
- % XXX We should look for other partitions of the set of six platforms
- % which often have identical decision results; one could be da vs noda.
- %
- % The name of this type is c_repns because argument packing applies
- % only to the low level data representation, which is applicable only
- % when targeting C.
-:- type c_repns(T)
- ---> c_repns_same(
- c_repn_same :: T
- )
- ; c_repns_64_32(
- c_repn_all_64 :: T,
- c_repn_all_32 :: T
- )
- ; c_repns_all(
- c_repn_64_nospf_noda :: T,
- c_repn_64_nospf_da :: T,
- % c_repn_64_spf_noda :: T, % not needed; see above
- % c_repn_64_spf_da :: T, % not needed; see above
- c_repn_32_nospf_noda :: T,
- c_repn_32_nospf_da :: T,
- c_repn_32_spf_noda :: T,
- c_repn_32_spf_da :: T
- ).
-
-%---------------------%
-
-:- type direct_dummy_repn
- ---> direct_dummy_repn(
- % The type is a direct dummy type that satisfies the
- % requirements of du_type_is_dummy.
-
- % The name of the one functor in the type, which must be
- % arity 0. Its representation will be dummy_tag.
- dummy_functor_name :: string,
-
- % Any foreign type or foreign enum definitions for the type.
- dummy_foreign :: c_j_cs_enum_repn
- ).
-
-%---------------------%
-
-:- type enum_repn
- ---> enum_repn(
- % The type is an enum type that satisfies the requirements
- % of non_sub_du_type_is_enum.
-
- % The list of the functor names (all arity 0). We store
- % the first two separately to enforce the structural invariant
- % that an enum must have at least two functors.
- %
- % The representation of functor #N in Mercury will be
- % int_tag(int_tag_int(N)), with counting starting at 0.
- %
- % We do not care about the 32 vs 64 bit distinction here,
- % because the definition of an enum type with more than 2^32
- % function symbols will cause a compiler to run out of memory
- % for a *very* long time to come.
- enum_functor1 :: string,
- enum_functor2 :: string,
- enum_functors3plus :: list(string),
-
- % Any foreign type or foreign enum definitions for the type.
- enum_foreign :: c_j_cs_enum_repn
- ).
-
-%---------------------%
-
-:- type notag_repn
- ---> notag_repn(
- % The name of the one functor in the type, which must be
- % arity 1. Its representation will be no_tag.
- % The representation of the argument be *recorded*
- % as a full word at offset 0, but this should never be
- % looked up, since the argument will actually be stored
- % wherever the whole term is stored.
- notag_functor_name :: string,
-
- % The type of the one functor's one argument.
- % We record this because without this information,
- % we cannot recognize that a notag type whose argument size
- % is less than one word can itself be stored in less than
- % one word.
- notag_functor_arg_type :: mer_type,
-
- % The foreign language definitions for this type, if any.
- notag_foreign :: c_j_cs_repn
- ).
-
-%---------------------%
-
-:- type gen_du_only_functor_repn
- ---> gen_du_only_functor_repn(
- % The name of the data constructor. The arity is given by
- % the length of list of argument types. The lists of argument
- % representations in all of the nonconstant_repns inside
- % the c_repns must also ave this length.
- only_functor :: string,
-
- % The types of the constructor's arguments, after
- % the expansion of both equivalence types and notag types.
- only_deref_arg_types :: list(mer_type),
-
- % The representation of this functor for each possible
- % target platform with the low level data representation.
- % The nonconstant_repn cannot be ncr_direct_arg.
- % XXX TYPE_REPN could we encode that invariant in the type?
- only_arg_repns :: c_repns(only_nonconstant_repn),
-
- % The foreign language definitions for this type, if any.
- only_foreign :: c_j_cs_repn
- ).
-
-:- type gen_du_more_functors_repn
- ---> gen_du_more_functors_repn(
- % The first, second and any later functors in the type,
- % in declaration order, i.e. ordered on the functors'
- % original ordinal numbers.
- more_functor1 :: gen_du_functor_repn,
- more_functor2 :: gen_du_functor_repn,
- more_functors3plus :: list(gen_du_functor_repn),
-
- % The foreign language definitions for this type, if any.
- more_foreign :: c_j_cs_repn
- ).
-
-%---------------------%
-
-:- type gen_du_functor_repn
- ---> gen_du_constant_functor_repn(
- % The name of the data constructor. The arity is zero.
- gducf_functor :: string,
-
- % The representation of this functor for each possible
- % target platform with the low level data representation.
- gducf_functor_repn :: c_repns(constant_repn)
- )
- ; gen_du_nonconstant_functor_repn(
- % The name of the data constructor. The arity is given by
- % the length of list of argument types. The lists of argument
- % representations in all of the nonconstant_repns inside
- % the c_repns must also ave this length.
- gduncf_functor :: string,
-
- % The types of the constructor's arguments, after
- % the expansion of both equivalence types and notag types.
- %
- % Logically, the type of each argument belongs with
- % the representation of that argument, but we have to store
- % up to six versions of the representation, and we don't want
- % a duplicate copy of the type next to each version.
- gduncf_deref_arg_types :: list(mer_type),
-
- % The representation of this functor for each possible
- % target platform with the low level data representation.
- gduncf_functor_repn :: c_repns(more_nonconstant_repn)
- ).
-
-:- type constant_repn
- ---> constant_repn(
- % The ptag is 0. The next two fields specify the value
- % and the size of the local secondary tag.
- cr_sectag :: uint,
- cr_sectag_size :: lsectag_word_or_size
- ).
-
-:- type only_nonconstant_repn
- ---> oncr_local_cell(only_nonconstant_local_cell_repn)
- ; oncr_remote_cell(only_nonconstant_remote_cell_repn).
-
-:- type more_nonconstant_repn
- ---> mncr_local_cell(more_nonconstant_local_cell_repn)
- ; mncr_remote_cell(more_nonconstant_remote_cell_repn)
- ; mncr_direct_arg(ptag).
-
-:- type only_nonconstant_local_cell_repn
- ---> only_nonconstant_local_cell_repn(
- % The ptag and local sectag are both implicitly 0u.
- onclcr_arg_repns :: one_or_more(local_arg_repn)
- ).
-
-:- type more_nonconstant_local_cell_repn
- ---> more_nonconstant_local_cell_repn(
- % The ptag is implicitly 0u.
- mnclcr_sectag :: cell_local_sectag,
- mnclcr_arg_repns :: one_or_more(local_arg_repn)
- ).
-
-:- type only_nonconstant_remote_cell_repn
- ---> only_nonconstant_remote_cell_repn(
- % The ptag is both implicitly 0u, and there is
- % no remote sectag.
- ncrcr_arg_repns :: one_or_more(remote_arg_repn)
- ).
-
-:- type more_nonconstant_remote_cell_repn
- ---> more_nonconstant_remote_cell_repn(
- ncrcr_ptag :: ptag,
- ncrcr_sectag :: cell_remote_sectag,
- ncrcr_arg_repns :: one_or_more(remote_arg_repn)
- ).
-
-:- type cell_local_sectag
- ---> cell_local_sectag(
- clss_sectag :: uint,
- clss_sectag_size :: uint8
- ).
-
-:- type cell_remote_sectag
- ---> cell_remote_no_sectag
- ; cell_remote_sectag(
- crss_sectag :: uint,
- crss_sectag_size :: rsectag_word_or_size
- ).
-
-:- type lsectag_word_or_size
- ---> lsectag_rest_of_word(uint8)
- ; lsectag_part_of_word(uint8).
-
-:- type rsectag_word_or_size
- ---> rsectag_full_word
- ; rsectag_part_of_word(uint8).
-
-:- type local_arg_repn
- ---> local_partial(
- lp_shift :: uint,
- lp_fill :: fill_kind_size
- )
- ; local_none.
-
-:- type remote_arg_repn
- ---> remote_full(
- rf_arg_only_offset :: arg_only_offset,
- rf_cell_offset :: cell_offset
- )
- ; remote_double(
- rd_arg_only_offset :: arg_only_offset,
- rd_cell_offset :: cell_offset,
- rd_kind :: double_word_kind
- )
- ; remote_partial_first(
- rpf_arg_only_offset :: arg_only_offset,
- rpf_cell_offset :: cell_offset,
- rpf_shift :: uint8,
- rpf_fill :: fill_kind_size
- )
- ; remote_partial_shifted(
- rps_arg_only_offset :: arg_only_offset,
- rps_cell_offset :: cell_offset,
- rps_shift :: uint8,
- rps_fill :: fill_kind_size
- )
- ; remote_none_shifted(
- rns_arg_only_offset :: arg_only_offset,
- rns_cell_offset :: cell_offset
- )
- ; remote_none_nowhere.
-
-:- type fill_kind_size
- ---> fk_enum(uint) % XXX TYPE_REPN should be uint8
- ; fk_int8
- ; fk_int16
- ; fk_int32
- ; fk_uint8
- ; fk_uint16
- ; fk_uint32
- ; fk_char21.
-
- % XXX TYPE_REPN should return uint8
-:- func fill_kind_size_num_bits(fill_kind_size) = uint.
-
-%---------------------%
-
-:- type foreign_type_lang_repn
- ---> foreign_type_lang_repn(
- ftlr_lang :: foreign_language,
- ftlr_foreign_type :: foreign_type_repn
- ).
-
-:- type foreign_type_repn
- ---> foreign_type_repn(
- % The name of the foreign type that represents values
- % of this Mercury type.
- ftr_foreign_type :: string,
-
- % The assertions about this foreign type.
- ftr_assertions :: foreign_type_assertions
- ).
-
-:- type enum_foreign_repn
- ---> enum_foreign_type(foreign_type_repn)
- ; enum_foreign_enum(one_or_more(string)).
-
-%---------------------------------------------------------------------------%
-%
-% Pragmas.
-%
-
-:- type item_decl_pragma_info
- ---> decl_pragma_obsolete_pred(decl_pragma_obsolete_pred_info)
- ; decl_pragma_obsolete_proc(decl_pragma_obsolete_proc_info)
- ; decl_pragma_format_call(decl_pragma_format_call_info)
- ; decl_pragma_type_spec_constr(decl_pragma_type_spec_constr_info)
- ; decl_pragma_type_spec(decl_pragma_type_spec_info)
- ; decl_pragma_oisu(decl_pragma_oisu_info)
- ; decl_pragma_termination(decl_pragma_termination_info)
- ; decl_pragma_termination2(decl_pragma_termination2_info)
- ; decl_pragma_struct_sharing(decl_pragma_struct_sharing_info)
- ; decl_pragma_struct_reuse(decl_pragma_struct_reuse_info).
-
-:- type item_impl_pragma_info
- ---> impl_pragma_foreign_decl(impl_pragma_foreign_decl_info)
- ; impl_pragma_foreign_code(impl_pragma_foreign_code_info)
- ; impl_pragma_fproc_export(impl_pragma_fproc_export_info)
- ; impl_pragma_external_proc(impl_pragma_external_proc_info)
- ; impl_pragma_fact_table(impl_pragma_fact_table_info)
- ; impl_pragma_tabled(impl_pragma_tabled_info)
- ; impl_pragma_req_tail_rec(impl_pragma_req_tail_rec_info)
- ; impl_pragma_req_feature_set(impl_pragma_req_feature_set_info).
-
-:- type item_generated_pragma_info
- ---> gen_pragma_unused_args(gen_pragma_unused_args_info)
- ; gen_pragma_exceptions(gen_pragma_exceptions_info)
- ; gen_pragma_trailing(gen_pragma_trailing_info)
- ; gen_pragma_mm_tabling(gen_pragma_mm_tabling_info).
-
-%---------------------------------------------------------------------------%
-%
-% Decl pragmas.
-%
-
-:- type decl_pragma_obsolete_pred_info
- ---> decl_pragma_obsolete_pred_info(
- obspred_obsolete_pred :: pred_pfu_name_arity,
- obspred_in_favour_of :: list(sym_name_arity),
- obspred_context :: prog_context,
- obspred_seq_num :: item_seq_num
- ).
-
-:- type decl_pragma_obsolete_proc_info
- ---> decl_pragma_obsolete_proc_info(
- obsproc_obsolete_proc :: proc_pf_name_modes,
- obsproc_in_favour_of :: list(sym_name_arity),
- obsproc_context :: prog_context,
- obsproc_seq_num :: item_seq_num
- ).
-
-:- type decl_pragma_format_call_info
- ---> decl_pragma_format_call_info(
- format_pred :: pf_sym_name_user_arity,
- format_values :: one_or_more(format_string_values),
- format_context :: prog_context,
- format_seq_num :: item_seq_num
- ).
-
-:- type decl_pragma_type_spec_constr_info
- ---> decl_pragma_type_spec_constr_info(
- % The name of the module from whose (source or interface) file
- % we read the type_spec_constrained_preds pragma. This will
- % always name the module that contains the pragma, because
- % we never put a type_spec_constrained_preds pragma into
- % any interface file other than an interface file of the
- % module containing the pragma.
- tsc_module_name :: module_name,
-
- % The list of constraints in the first argument of the pragma.
- % The pragma asks for the type specialization of any predicates
- % whose class context includes any nonempty subset of these
- % constraints, and possibly (see the next field) their
- % superclasses, as instances.
- tsc_constraints :: one_or_more(var_or_ground_constraint),
-
- % The second argument of the pragma, which specifies whether
- % the constraints in the first argument also implicitly specify
- % their superclasses, *their* superclasses, and so on.
- % If e.g. tc1(A, B, C) has tc2(A, B) as one of its
- % superclasses, then a setting of apply_to_supers in this field
- % means that the pragma asks us to specialize not only
- % predicates whose class context includes tc1(A, char, B)
- % (if that is has as its instance of one of the constraints),
- % but also e.g. tc2(A, char).
- tsc_apply_to_supers :: maybe_apply_to_supers,
-
- % The third argument of the pragma, which specifies the list
- % of type substitutions for which the pragma asks us to create
- % type-specialized versions of each predicate that matches
- % the requirements described by the first and second args.
- %
- % Each type var on the left-hand-side of a substitution
- % must occur in tsc_constraints, while all type vars that
- % occur in a type on the right-hand-side of a substitution
- % must be anonymous. These requirements are enforced by the
- % code that parses these pragmas.
- tsc_tsubst :: one_or_more(type_subst),
-
- % The varset of the term containing the pragma, coerced
- % to being a tvarset (since all variables in the pragma
- % are type variables).
- %
- % All variables in this tvarset have to have explicit names.
- % If the original pragma contains anonymous variables, the
- % code constructing this decl_pragma_type_spec will give
- % those variable names. See the comment on the tspec_tvarset
- % field below for the reason behind this requirement.
- tsc_tvarset :: tvarset,
-
- % The equivalence types used.
- tsc_items :: set(recomp_item_id),
-
- tsc_context :: prog_context,
- tsc_seq_num :: item_seq_num
- ).
-
-:- type decl_pragma_type_spec_info
- ---> decl_pragma_type_spec_info(
- tspec_pfumm :: pred_func_or_unknown_maybe_modes,
-
- % The existing predicate name.
- tspec_pred_name :: sym_name,
-
- % The name of the module from whose (source or interface) file
- % we read the type_spec pragma. This will always name
- % the module that contains the pragma, because we never put
- % a type_spec pragma into any interface file other than
- % an interface file of the module containing the pragma.
- tspec_module_name :: module_name,
-
- % The type substitution (using the variable names
- % from the pred declaration).
- tspec_tsubst :: type_subst,
-
- % The varset of the term containing the pragma, coerced
- % to being a tvarset (since no part of the pragma except
- % the type substitution may contain variables).
- %
- % All variables in this tvarset have to have explicit names.
- % If the original pragma contains anonymous variables, the
- % code constructing this decl_pragma_type_spec will give
- % those variable names.
- %
- % The reason for this requirement is that the process
- % of writing out an anonymous variable and reading it back in
- % will produce a non-anonymous variable. Since the names
- % (if any) of the variables in tspec_tsubst are an input
- % to the code that constructs the name of the type-specialized
- % predicate, we would get a discrepancy between the predicate
- % name constructed by compiler invocations that know the
- % variable as unnamed (this will be the invocation that
- % compiles the module containing the type_spec pragma,
- % which constructs the code of the type specialized predicate),
- % and compiler invocations that know that variable as named
- % (this will be all the invocations that read the original
- % module's .int file, which will be constructing many of
- % the *calls* to the type specialized predicate). The result
- % will be calls to the type specialized predicate that refer
- % to it by the wrong name, leading to link errors.
- %
- % By giving all anonymous variables in the type_spec pragma
- % in the original source file as soon as we have parsed it,
- % and then always using the resulting names, we avoid this
- % problem.
- tspec_tvarset :: tvarset,
-
- % The equivalence types used.
- tspec_items :: set(recomp_item_id),
-
- tspec_context :: prog_context,
- tspec_seq_num :: item_seq_num
- ).
-
-:- type var_or_ground_constraint
- ---> var_or_ground_constraint(
- class_name,
- list(var_or_ground_type),
- prog_context
- ).
-
-:- type var_or_ground_type
- ---> type_var_name(tvar, string)
- ; ground_type(ground_type).
-
-:- type maybe_apply_to_supers
- ---> do_not_apply_to_supers
- ; apply_to_supers.
-
-:- type decl_pragma_oisu_info
- ---> decl_pragma_oisu_info(
- oisu_type_ctor :: type_ctor,
- oisu_creator_preds :: list(pf_sym_name_user_arity),
- oisu_transformer_preds :: list(pf_sym_name_user_arity),
- oisu_destroyer_preds :: list(pf_sym_name_user_arity),
- oisu_context :: prog_context,
- oisu_seq_num :: item_seq_num
- ).
-
-% The termination/termination2 pragmas record information
-% about a predicate's or function's termination properties for our
-% two different termination analyzers. Even though they are usually
-% compiler generated, they are decl pragmas, not gen pragmas, because
-% we allow users to include them in Mercury source programs, to tell
-% the analyzers some things that they cannot figure out for themselves,
-% such as the termination properties of foreign language code in
-% foreign_procs.
-
-:- type decl_pragma_termination_info
- ---> decl_pragma_termination_info(
- % The modes represent the declared argmodes of the procedure,
- % unless there are no declared argmodes, in which case
- % we use the inferred argmodes.
- terminfo_pred_id :: proc_pf_name_modes,
- terminfo_args :: maybe(pragma_arg_size_info),
- terminfo_term :: maybe(pragma_termination_info),
- terminfo_context :: prog_context,
- terminfo_seq_num :: item_seq_num
- ).
-
-:- type decl_pragma_termination2_info
- ---> decl_pragma_termination2_info(
- terminfo2_pred_id :: proc_pf_name_modes,
- terminfo2_args :: maybe(pragma_constr_arg_size_info),
- terminfo2_args2 :: maybe(pragma_constr_arg_size_info),
- terminfo2_term :: maybe(pragma_termination_info),
- terminfo2_context :: prog_context,
- terminfo2_seq_num :: item_seq_num
- ).
-
-% The sharing/reuse pragmas record information about a predicate's or
-% function's properties that are relevant for compile-time garbage
-% collection (ctgx). Even though they are usually compiler generated,
-% they are decl pragmas, not gen pragmas, because we allow users
-% to include them in Mercury source programs, to tell the compiler some things
-% that it cannot figure out for itself, such as the ctgc properties
-% of foreign language code in foreign_procs.
-
-:- type decl_pragma_struct_sharing_info
- ---> decl_pragma_struct_sharing_info(
- % After structure sharing analysis, the compiler generates
- % structure sharing pragmas to be stored in and read from
- % optimization interface files.
- %
- % The list of modes consists of the declared argmodes
- % (or inferred argmodes if there are no declared ones).
- sharing_pred_id :: proc_pf_name_modes,
- sharing_headvars :: list(prog_var),
- sharing_headvar_types :: list(mer_type),
-
- % The prog_varset and tvarset are meaningful only when
- % writing out this pragma; add_pragma.m ignores both varsets.
- sharing_varset :: prog_varset,
- sharing_tvarset :: tvarset,
-
- % As of 2019 10 29, and probably long before then,
- % the compiler *always* fills this slot with `yes(...)'.
- % A `no' would mean that the relevant information is not
- % available, but in that case, we simply do not write out
- % this pragma.
- sharing_description :: maybe(structure_sharing_domain),
-
- sharing_context :: prog_context,
- sharing_seq_num :: item_seq_num
- ).
-
-:- type decl_pragma_struct_reuse_info
- ---> decl_pragma_struct_reuse_info(
- % After reuse analysis, the compiler generates structure reuse
- % pragmas to be stored in and read from optimization interface
- % files.
- %
- % The list of modes consists of the declared argmodes
- % (or inferred argmodes if there are no declared ones).
- %
- % The last sym_name (reuse_optimised_name) stores the name
- % of the optimised version of the exported predicate.
- % XXX As of 2019 10 29, the word "reuse_optimised_name"
- % appears nowhere in the compiler apart from this comment.
- reuse_pred_id :: proc_pf_name_modes,
- reuse_headvars :: list(prog_var),
- reuse_headvar_types :: list(mer_type),
-
- % The prog_varset and tvarset are meaningful only when
- % writing out this pragma; add_pragma.m ignores both varsets.
- reuse_varset :: prog_varset,
- reuse_tvarset :: tvarset,
-
- % As of 2019 10 29, and probably long before then,
- % the compiler *always* fills this slot with `yes(...)'.
- % A `no' would mean that the relevant information is not
- % available, but in that case, we simply do not write out
- % this pragma.
- reuse_description :: maybe(structure_reuse_domain),
-
- reuse_context :: prog_context,
- reuse_seq_num :: item_seq_num
- ).
-
-:- type item_decl_marker_info
- ---> item_decl_marker_info(
- dm_marker_kind :: decl_pragma_marker_kind,
- dm_pred_spec :: pred_pfu_name_arity,
- dm_context :: prog_context,
- dm_seq_num :: item_seq_num
- ).
-
-:- type item_decl_marker_info_opt =< item_decl_marker_info
- ---> item_decl_marker_info(
- dm_marker_kind :: decl_pragma_marker_kind_opt,
- dm_pred_spec :: pred_pfu_name_arity_pf,
- dm_context :: prog_context,
- dm_seq_num :: item_seq_num
- ).
-
- % XXX The "terminates" and "does_not_terminate" markers are assertions
- % about the behavior of a given predicate that the compiler may be able
- % to exploit when compiling other modules. The "check_termination" marker
- % is not like that: it is a directive that is useful only while
- % the compiler is working on the module in which it occurs. We should
- % therefore consider making this an *impl* marker, which would entail
- % allowing the "check_termination" pragma to occur only in implementation
- % sections, even when the predicate/function they name is exported.
-:- type decl_pragma_marker_kind
- ---> dpmk_terminates
- ; dpmk_does_not_terminate
- ; dpmk_check_termination.
-
-:- type decl_pragma_marker_kind_opt =< decl_pragma_marker_kind
- ---> dpmk_terminates
- ; dpmk_does_not_terminate.
-
-%---------------------------------------------------------------------------%
-%
-% Impl pragmas.
-%
-
-:- type impl_pragma_foreign_decl_info
- ---> impl_pragma_foreign_decl_info(
- % A foreign language declaration, such as C header code.
- decl_lang :: foreign_language,
- decl_is_local :: foreign_decl_is_local,
- decl_decl :: foreign_literal_or_include,
- decl_context :: prog_context,
- decl_seq_num :: item_seq_num
- ).
-
-:- type impl_pragma_foreign_code_info
- ---> impl_pragma_foreign_code_info(
- code_lang :: foreign_language,
- code_code :: foreign_literal_or_include,
- code_context :: prog_context,
- code_seq_num :: item_seq_num
- ).
-
-:- type impl_pragma_fproc_export_info
- ---> impl_pragma_fproc_export_info(
- exp_maybe_attrs :: item_maybe_attrs,
-
- exp_language :: foreign_language,
- % Predname, Predicate/function, Modes, foreign function name.
- exp_pred_id :: proc_pf_name_modes,
- exp_foreign_name :: string,
-
- % Specified the names of any variables in the modes above.
- % Used for generating error messages about foreign_export
- % pragmas for undeclared modes.
- exp_varset :: prog_varset,
-
- exp_context :: prog_context,
- exp_seq_num :: item_seq_num
- ).
-
-:- type impl_pragma_external_proc_info
- ---> impl_pragma_external_proc_info(
- % The specified procedure(s) is/are implemented outside
- % of Mercury code, for the named backend if there is one,
- % or if there isn't a named backend, then for all backends.
- external_name :: pf_sym_name_user_arity,
- external_maybe_backend :: maybe(backend),
- external_context :: prog_context,
- external_seq_num :: item_seq_num
- ).
-
-:- type impl_pragma_fact_table_info
- ---> impl_pragma_fact_table_info(
- % Predname and Arity, Fact file name.
- fact_table_pred :: pred_pfu_name_arity,
- fact_table_filename :: string,
- fact_table_context :: prog_context,
- fact_table_seq_num :: item_seq_num
- ).
-
-:- type impl_pragma_tabled_info
- ---> impl_pragma_tabled_info(
- % Tabling type, Predname, Arity, PredOrFunc?, Mode?
- tabled_method :: tabled_eval_method,
- tabled_name :: pred_or_proc_pfumm_name,
- tabled_attributes :: maybe(table_attributes),
- tabled_context :: prog_context,
- tabled_seq_num :: item_seq_num
- ).
-
-:- type impl_pragma_req_tail_rec_info
- ---> impl_pragma_req_tail_rec_info(
- rtr_proc_id :: pred_or_proc_pfumm_name,
- rtr_require_tailrec :: require_tail_recursion,
- % This parameter only makes sense when options contains
- % either rtro_mutual_rec_only or rtro_all_recursion.
- % TODO, currently unused, may be used later to implement one
- % of Zoltan's suggestions here:
- % http://www.mercurylang.org/list-archives/developers/
- % 2015-November/016482.html
- % rtr_maybe_scc :: maybe(list(
- % pred_or_proc_pfumm_name))
- rtr_context :: prog_context,
- rtr_seq_num :: item_seq_num
- ).
-
-:- type impl_pragma_req_feature_set_info
- ---> impl_pragma_req_feature_set_info(
- rfs_feature_set :: set(required_feature),
- rfs_context :: prog_context,
- rfs_seq_num :: item_seq_num
- ).
-
-:- type item_impl_marker_info
- ---> item_impl_marker_info(
- im_marker_kind :: impl_pragma_marker_kind,
- im_pred_spec :: pred_pfu_name_arity,
- im_context :: prog_context,
- im_seq_num :: item_seq_num
- ).
-
-:- type item_impl_marker_info_opt =< item_impl_marker_info
- ---> item_impl_marker_info(
- im_marker_kind :: impl_pragma_marker_kind_opt,
- im_pred_spec :: pred_pfu_name_arity_pf,
- im_context :: prog_context,
- im_seq_num :: item_seq_num
- ).
-
-:- type impl_pragma_marker_kind
- ---> ipmk_inline
- ; ipmk_no_inline
- ; ipmk_consider_used
- ; ipmk_mode_check_clauses
- ; ipmk_no_detism_warning
- ; ipmk_promise_pure
- ; ipmk_promise_semipure
- ; ipmk_promise_eqv_clauses
- ; ipmk_req_sw_arms_type_order.
-
- % These are the kinds of impl markers that we put into .opt files.
-:- type impl_pragma_marker_kind_opt =< impl_pragma_marker_kind
- ---> ipmk_inline
- ; ipmk_no_inline
- ; ipmk_mode_check_clauses
- ; ipmk_promise_pure
- ; ipmk_promise_semipure
- ; ipmk_promise_eqv_clauses.
-
-%---------------------------------------------------------------------------%
-%
-% Generated pragmas.
-%
-
-:- type gen_pragma_unused_args_info
- ---> gen_pragma_unused_args_info(
- % This pragma Should only appear in .opt files.
- unused_proc_id :: proc_pf_name_arity_mn,
-
- % The argument positions of the unused arguments.
- % Used for intermodule unused argument removal.
- unused_args :: list(int),
-
- unused_context :: prog_context,
- unused_seq_num :: item_seq_num
- ).
-
-:- type gen_pragma_exceptions_info
- ---> gen_pragma_exceptions_info(
- % This pragma should only appear in `.opt' and
- % `.trans_opt' files.
- exceptions_proc_id :: proc_pf_name_arity_mn,
- exceptions_status :: exception_status,
-
- exceptions_context :: prog_context,
- exceptions_seq_num :: item_seq_num
- ).
-
-:- type gen_pragma_trailing_info
- ---> gen_pragma_trailing_info(
- % This pragma should only appear in `.trans_opt' files.
- trailing_proc_id :: proc_pf_name_arity_mn,
- trailing_status :: trailing_status,
-
- trailing_context :: prog_context,
- trailing_seq_num :: item_seq_num
- ).
-
-:- type gen_pragma_mm_tabling_info
- ---> gen_pragma_mm_tabling_info(
- % This pragma should only appear in `.opt' and
- % `.trans_opt' files.
- mm_tabling_proc_id :: proc_pf_name_arity_mn,
- mm_tabling_status :: mm_tabling_status,
-
- mm_tabling_context :: prog_context,
- mm_tabling_seq_num :: item_seq_num
- ).
-
-%---------------------------------------------------------------------------%
-
- % These types identify predicates, functions and/or procedures in pragmas.
-
-:- type pred_pfu_name_arity
- ---> pred_pfu_name_arity(
- ppfuna_pfu :: pred_func_or_unknown,
- ppfuna_pred_name :: sym_name,
- ppfuna_arity :: user_arity
- ).
-
-:- type pred_pfu_name_arity_pf =< pred_pfu_name_arity
- ---> pred_pfu_name_arity(
- ppfuna_pfu :: pred_func_or_unknown_pf,
- ppfuna_pred_name :: sym_name,
- ppfuna_arity :: user_arity
- ).
-
-:- type proc_pf_name_arity_mn
- ---> proc_pf_name_arity_mn(
- ppfnamn_pf :: pred_or_func,
- ppfnamn_pred_name :: sym_name,
- ppfnamn_arity :: user_arity,
- ppfnamn_mode_num :: mode_num
- ).
-
-:- type proc_pf_name_modes
- ---> proc_pf_name_modes(
- ppfnm_pf :: pred_or_func,
- ppfnm_pred_name :: sym_name,
- ppfnm_arity :: list(mer_mode)
- ).
-
-:- type pred_or_proc_pfumm_name
- ---> pred_or_proc_pfumm_name(
- ppfummn_pfumm :: pred_func_or_unknown_maybe_modes,
- ppfummn_pred_name :: sym_name
- ).
-
-:- type pred_func_or_unknown
- ---> pfu_predicate
- ; pfu_function
- ; pfu_unknown.
-
-:- type pred_func_or_unknown_pf =< pred_func_or_unknown
- ---> pfu_predicate
- ; pfu_function.
-
-:- type pred_func_or_unknown_maybe_modes
- ---> pfumm_predicate(modes_or_arity)
- ; pfumm_function(modes_or_arity)
- ; pfumm_unknown(user_arity).
-
-:- type modes_or_arity
- ---> moa_modes(list(mer_mode))
- ; moa_arity(user_arity).
-
-:- func pfu_to_maybe_pred_or_func(pred_func_or_unknown) = maybe(pred_or_func).
-:- func maybe_pred_or_func_to_pfu(maybe(pred_or_func)) = pred_func_or_unknown.
-
-:- pred pfumm_to_maybe_pf_arity_maybe_modes(
- pred_func_or_unknown_maybe_modes::in, maybe(pred_or_func)::out,
- user_arity::out, maybe(list(mer_mode))::out) is det.
-
%---------------------------------------------------------------------------%
%
% Goals.
@@ -2311,9 +788,6 @@
%---------------------------------------------------------------------------%
:- func get_item_context(item) = prog_context.
-:- func get_decl_pragma_context(item_decl_pragma_info) = prog_context.
-:- func get_impl_pragma_context(item_impl_pragma_info) = prog_context.
-:- func get_gen_pragma_context(item_generated_pragma_info) = prog_context.
:- func get_goal_context(goal) = prog_context.
%---------------------------------------------------------------------------%
@@ -2428,8 +902,9 @@
:- implementation.
:- import_module parse_tree.error_spec.
-:- import_module parse_tree.prog_util.
+:- import_module one_or_more.
+:- import_module pair.
:- import_module term.
:- import_module varset.
@@ -2459,68 +934,6 @@ mutable_thread_local_trailed(Local) = Trail :-
%---------------------------------------------------------------------------%
-fill_kind_size_num_bits(FillKindSize) = NumBits :-
- (
- FillKindSize = fk_enum(NumBits)
- ;
- ( FillKindSize = fk_int8
- ; FillKindSize = fk_uint8
- ),
- NumBits = 8u
- ;
- ( FillKindSize = fk_int16
- ; FillKindSize = fk_uint16
- ),
- NumBits = 16u
- ;
- ( FillKindSize = fk_int32
- ; FillKindSize = fk_uint32
- ),
- NumBits = 32u
- ;
- FillKindSize = fk_char21,
- NumBits = 21u
- ).
-
-%---------------------------------------------------------------------------%
-
-pfu_to_maybe_pred_or_func(pfu_predicate) = yes(pf_predicate).
-pfu_to_maybe_pred_or_func(pfu_function) = yes(pf_function).
-pfu_to_maybe_pred_or_func(pfu_unknown) = no.
-
-maybe_pred_or_func_to_pfu(yes(pf_predicate)) = pfu_predicate.
-maybe_pred_or_func_to_pfu(yes(pf_function)) = pfu_function.
-maybe_pred_or_func_to_pfu(no) = pfu_unknown.
-
-pfumm_to_maybe_pf_arity_maybe_modes(PFUMM, MaybePredOrFunc, UserArity,
- MaybeModes) :-
- (
- (
- PFUMM = pfumm_predicate(ModesOrArity),
- PredOrFunc = pf_predicate
- ;
- PFUMM = pfumm_function(ModesOrArity),
- PredOrFunc = pf_function
- ),
- MaybePredOrFunc = yes(PredOrFunc),
- (
- ModesOrArity = moa_modes(Modes),
- list.length(Modes, NumModes),
- PredFormArity = pred_form_arity(NumModes),
- user_arity_pred_form_arity(PredOrFunc, UserArity, PredFormArity),
- MaybeModes = yes(Modes)
- ;
- ModesOrArity = moa_arity(UserArity),
- MaybeModes = no
- )
- ;
- PFUMM = pfumm_unknown(UserArity),
- MaybePredOrFunc = no,
- MaybeModes = no
- ).
-
-%---------------------------------------------------------------------------%
-
get_item_context(Item) = Context :-
(
Item = item_clause(ItemClause),
@@ -2587,81 +1000,6 @@ get_item_context(Item) = Context :-
Context = ItemTypeRepn ^ tr_context
).
-get_decl_pragma_context(DeclPragma) = Context :-
- (
- DeclPragma = decl_pragma_obsolete_pred(ObsPred),
- Context = ObsPred ^ obspred_context
- ;
- DeclPragma = decl_pragma_obsolete_proc(ObsProc),
- Context = ObsProc ^ obsproc_context
- ;
- DeclPragma = decl_pragma_format_call(FormatCall),
- Context = FormatCall ^ format_context
- ;
- DeclPragma = decl_pragma_type_spec_constr(TypeSpecConstr),
- Context = TypeSpecConstr ^ tsc_context
- ;
- DeclPragma = decl_pragma_type_spec(TypeSpec),
- Context = TypeSpec ^ tspec_context
- ;
- DeclPragma = decl_pragma_oisu(OISU),
- Context = OISU ^ oisu_context
- ;
- DeclPragma = decl_pragma_termination(Term),
- Context = Term ^ terminfo_context
- ;
- DeclPragma = decl_pragma_termination2(Term2),
- Context = Term2 ^ terminfo2_context
- ;
- DeclPragma = decl_pragma_struct_sharing(Sharing),
- Context = Sharing ^ sharing_context
- ;
- DeclPragma = decl_pragma_struct_reuse(Reuse),
- Context = Reuse ^ reuse_context
- ).
-
-get_impl_pragma_context(ImplPragma) = Context :-
- (
- ImplPragma = impl_pragma_foreign_decl(ForeignDecl),
- Context = ForeignDecl ^ decl_context
- ;
- ImplPragma = impl_pragma_foreign_code(ForeignCode),
- Context = ForeignCode ^ code_context
- ;
- ImplPragma = impl_pragma_fproc_export(Export),
- Context = Export ^ exp_context
- ;
- ImplPragma = impl_pragma_external_proc(ExternalProc),
- Context = ExternalProc ^ external_context
- ;
- ImplPragma = impl_pragma_fact_table(FactTable),
- Context = FactTable ^ fact_table_context
- ;
- ImplPragma = impl_pragma_tabled(Tabled),
- Context = Tabled ^ tabled_context
- ;
- ImplPragma = impl_pragma_req_tail_rec(TailRec),
- Context = TailRec ^ rtr_context
- ;
- ImplPragma = impl_pragma_req_feature_set(FeatureSet),
- Context = FeatureSet ^ rfs_context
- ).
-
-get_gen_pragma_context(GenPragma) = Context :-
- (
- GenPragma = gen_pragma_unused_args(UnusedArgs),
- Context = UnusedArgs ^ unused_context
- ;
- GenPragma = gen_pragma_exceptions(Excps),
- Context = Excps ^ exceptions_context
- ;
- GenPragma = gen_pragma_trailing(Trailing),
- Context = Trailing ^ trailing_context
- ;
- GenPragma = gen_pragma_mm_tabling(MMTabling),
- Context = MMTabling ^ mm_tabling_context
- ).
-
get_goal_context(Goal) = Context :-
( Goal = conj_expr(Context, _, _)
; Goal = par_conj_expr(Context, _, _)
diff --git a/compiler/prog_item_inst_mode.m b/compiler/prog_item_inst_mode.m
new file mode 100644
index 000000000..1f90a0108
--- /dev/null
+++ b/compiler/prog_item_inst_mode.m
@@ -0,0 +1,148 @@
+%---------------------------------------------------------------------------%
+% vim: ft=mercury ts=4 sw=4 et
+%---------------------------------------------------------------------------%
+% Copyright (C) 2019-2026 The Mercury team.
+% This file may only be copied under the terms of the GNU General
+% Public License - see the file COPYING in the Mercury distribution.
+%---------------------------------------------------------------------------%
+%
+% File: prog_item_inst_mode.m.
+% Author: zs.
+%
+%---------------------------------------------------------------------------%
+
+:- module parse_tree.prog_item_inst_mode.
+:- interface.
+
+:- import_module mdbcomp.
+:- import_module mdbcomp.sym_name.
+:- import_module parse_tree.prog_data.
+
+:- import_module list.
+:- import_module map.
+:- import_module maybe.
+
+%---------------------------------------------------------------------------%
+
+:- type item_inst_defn_info
+ == item_inst_defn_info_general(maybe_abstract_inst_defn).
+
+:- type item_inst_defn_info_abstract
+ == item_inst_defn_info_general(no_inst_defn).
+:- type item_inst_defn_info_eqv
+ == item_inst_defn_info_general(inst_defn).
+
+:- type item_inst_defn_info_general(T)
+ ---> item_inst_defn_info(
+ % `:- inst ... = ...':
+ % a definition of an inst.
+ id_inst_name :: sym_name,
+ id_inst_args :: list(inst_var),
+ id_maybe_for_type :: maybe(type_ctor),
+ id_inst_defn :: T,
+ id_varset :: inst_varset,
+ id_context :: prog_context,
+ id_seq_num :: item_seq_num
+ ).
+
+:- type no_inst_defn
+ ---> no_inst_defn.
+
+:- type maybe_abstract_inst_defn
+ ---> abstract_inst_defn
+ ; nonabstract_inst_defn(inst_defn).
+
+%---------------------------------------------------------------------------%
+
+:- type item_mode_defn_info
+ == item_mode_defn_info_general(maybe_abstract_mode_defn).
+
+:- type item_mode_defn_info_abstract
+ == item_mode_defn_info_general(no_mode_defn).
+:- type item_mode_defn_info_eqv
+ == item_mode_defn_info_general(mode_defn).
+
+:- type item_mode_defn_info_general(T)
+ ---> item_mode_defn_info(
+ % `:- mode ... = ...':
+ % a definition of a mode.
+ md_mode_name :: sym_name,
+ md_mode_args :: list(inst_var),
+ md_mode_defn :: T,
+ md_varset :: inst_varset,
+ md_context :: prog_context,
+ md_seq_num :: item_seq_num
+ ).
+
+:- type no_mode_defn
+ ---> no_mode_defn.
+
+:- type maybe_abstract_mode_defn
+ ---> abstract_mode_defn
+ ; nonabstract_mode_defn(mode_defn).
+
+%---------------------------------------------------------------------------%
+%
+% The representation of a checked-to-be-consistent set of inst definitions
+% for every inst constructor defined in a module.
+%
+
+:- type inst_ctor_checked_map == map(inst_ctor, inst_ctor_checked_defn).
+
+:- type inst_ctor_checked_defn
+ ---> checked_defn_inst(std_inst_defn, src_defns_inst).
+
+:- type std_inst_defn
+ ---> std_inst_defn(std_inst_status, item_inst_defn_info).
+
+:- type std_inst_status
+ ---> std_inst_exported
+ % The inst definition is exported.
+ ; std_inst_abstract_exported
+ % Only the inst name is exported. Its definition is private.
+ ; std_inst_all_private.
+ % Everything about the inst is private.
+
+:- type src_defns_inst
+ ---> src_defns_inst(
+ % The inst definition (if any) in the interface.
+ maybe(item_inst_defn_info),
+
+ % The inst definition (if any) in the implementation.
+ maybe(item_inst_defn_info)
+ ).
+
+%---------------------------------------------------------------------------%
+%
+% The representation of a checked-to-be-consistent set of mode definitions
+% for every mode constructor defined in a module.
+%
+
+:- type mode_ctor_checked_map == map(mode_ctor, mode_ctor_checked_defn).
+
+:- type mode_ctor_checked_defn
+ ---> checked_defn_mode(std_mode_defn, src_defns_mode).
+
+:- type std_mode_defn
+ ---> std_mode_defn(std_mode_status, item_mode_defn_info).
+
+:- type std_mode_status
+ ---> std_mode_exported
+ % The mode definition is exported.
+ ; std_mode_abstract_exported
+ % Only the mode name is exported. Its definition is private.
+ ; std_mode_all_private.
+ % Everything about the mode is private.
+
+:- type src_defns_mode
+ ---> src_defns_mode(
+ % The mode definition (if any) in the interface.
+ maybe(item_mode_defn_info),
+
+ % The mode definition (if any) in the implementation.
+ maybe(item_mode_defn_info)
+ ).
+
+%---------------------------------------------------------------------------%
+:- end_module parse_tree.prog_item_inst_mode.
+%---------------------------------------------------------------------------%
diff --git a/compiler/prog_item_pragma.m b/compiler/prog_item_pragma.m
new file mode 100644
index 000000000..c9490a5f0
--- /dev/null
+++ b/compiler/prog_item_pragma.m
@@ -0,0 +1,662 @@
+%---------------------------------------------------------------------------%
+% vim: ft=mercury ts=4 sw=4 et
+%---------------------------------------------------------------------------%
+% Copyright (C) 2015-2026 The Mercury team.
+% This file may only be copied under the terms of the GNU General
+% Public License - see the file COPYING in the Mercury distribution.
+%---------------------------------------------------------------------------%
+%
+% File: prog_item_pragma.m.
+% Original author: fjh.
+% Main author of the current version: zs.
+%
+%---------------------------------------------------------------------------%
+
+:- module parse_tree.prog_item_pragma.
+:- interface.
+
+:- import_module libs.
+:- import_module libs.globals.
+:- import_module mdbcomp.
+:- import_module mdbcomp.sym_name.
+:- import_module parse_tree.prog_data.
+:- import_module parse_tree.prog_data_foreign.
+:- import_module parse_tree.prog_data_pragma.
+:- import_module parse_tree.prog_item_pred_proc_id.
+:- import_module recompilation.
+:- import_module recompilation.item_types.
+
+:- import_module list.
+:- import_module maybe.
+:- import_module one_or_more.
+:- import_module set.
+
+%---------------------------------------------------------------------------%
+
+:- type item_decl_pragma_info
+ ---> decl_pragma_obsolete_pred(decl_pragma_obsolete_pred_info)
+ ; decl_pragma_obsolete_proc(decl_pragma_obsolete_proc_info)
+ ; decl_pragma_format_call(decl_pragma_format_call_info)
+ ; decl_pragma_type_spec_constr(decl_pragma_type_spec_constr_info)
+ ; decl_pragma_type_spec(decl_pragma_type_spec_info)
+ ; decl_pragma_oisu(decl_pragma_oisu_info)
+ ; decl_pragma_termination(decl_pragma_termination_info)
+ ; decl_pragma_termination2(decl_pragma_termination2_info)
+ ; decl_pragma_struct_sharing(decl_pragma_struct_sharing_info)
+ ; decl_pragma_struct_reuse(decl_pragma_struct_reuse_info).
+
+:- type item_impl_pragma_info
+ ---> impl_pragma_foreign_decl(impl_pragma_foreign_decl_info)
+ ; impl_pragma_foreign_code(impl_pragma_foreign_code_info)
+ ; impl_pragma_fproc_export(impl_pragma_fproc_export_info)
+ ; impl_pragma_external_proc(impl_pragma_external_proc_info)
+ ; impl_pragma_fact_table(impl_pragma_fact_table_info)
+ ; impl_pragma_tabled(impl_pragma_tabled_info)
+ ; impl_pragma_req_tail_rec(impl_pragma_req_tail_rec_info)
+ ; impl_pragma_req_feature_set(impl_pragma_req_feature_set_info).
+
+:- type item_generated_pragma_info
+ ---> gen_pragma_unused_args(gen_pragma_unused_args_info)
+ ; gen_pragma_exceptions(gen_pragma_exceptions_info)
+ ; gen_pragma_trailing(gen_pragma_trailing_info)
+ ; gen_pragma_mm_tabling(gen_pragma_mm_tabling_info).
+
+:- func get_decl_pragma_context(item_decl_pragma_info) = prog_context.
+:- func get_impl_pragma_context(item_impl_pragma_info) = prog_context.
+:- func get_gen_pragma_context(item_generated_pragma_info) = prog_context.
+
+%---------------------------------------------------------------------------%
+%
+% Decl pragmas.
+%
+
+:- type decl_pragma_obsolete_pred_info
+ ---> decl_pragma_obsolete_pred_info(
+ obspred_obsolete_pred :: pred_pfu_name_arity,
+ obspred_in_favour_of :: list(sym_name_arity),
+ obspred_context :: prog_context,
+ obspred_seq_num :: item_seq_num
+ ).
+
+%---------------------%
+
+:- type decl_pragma_obsolete_proc_info
+ ---> decl_pragma_obsolete_proc_info(
+ obsproc_obsolete_proc :: proc_pf_name_modes,
+ obsproc_in_favour_of :: list(sym_name_arity),
+ obsproc_context :: prog_context,
+ obsproc_seq_num :: item_seq_num
+ ).
+
+%---------------------%
+
+:- type decl_pragma_format_call_info
+ ---> decl_pragma_format_call_info(
+ format_pred :: pf_sym_name_user_arity,
+ format_values :: one_or_more(format_string_values),
+ format_context :: prog_context,
+ format_seq_num :: item_seq_num
+ ).
+
+%---------------------%
+
+:- type decl_pragma_type_spec_constr_info
+ ---> decl_pragma_type_spec_constr_info(
+ % The name of the module from whose (source or interface) file
+ % we read the type_spec_constrained_preds pragma. This will
+ % always name the module that contains the pragma, because
+ % we never put a type_spec_constrained_preds pragma into
+ % any interface file other than an interface file of the
+ % module containing the pragma.
+ tsc_module_name :: module_name,
+
+ % The list of constraints in the first argument of the pragma.
+ % The pragma asks for the type specialization of any predicates
+ % whose class context includes any nonempty subset of these
+ % constraints, and possibly (see the next field) their
+ % superclasses, as instances.
+ tsc_constraints :: one_or_more(var_or_ground_constraint),
+
+ % The second argument of the pragma, which specifies whether
+ % the constraints in the first argument also implicitly specify
+ % their superclasses, *their* superclasses, and so on.
+ % If e.g. tc1(A, B, C) has tc2(A, B) as one of its
+ % superclasses, then a setting of apply_to_supers in this field
+ % means that the pragma asks us to specialize not only
+ % predicates whose class context includes tc1(A, char, B)
+ % (if that is has as its instance of one of the constraints),
+ % but also e.g. tc2(A, char).
+ tsc_apply_to_supers :: maybe_apply_to_supers,
+
+ % The third argument of the pragma, which specifies the list
+ % of type substitutions for which the pragma asks us to create
+ % type-specialized versions of each predicate that matches
+ % the requirements described by the first and second args.
+ %
+ % Each type var on the left-hand-side of a substitution
+ % must occur in tsc_constraints, while all type vars that
+ % occur in a type on the right-hand-side of a substitution
+ % must be anonymous. These requirements are enforced by the
+ % code that parses these pragmas.
+ tsc_tsubst :: one_or_more(type_subst),
+
+ % The varset of the term containing the pragma, coerced
+ % to being a tvarset (since all variables in the pragma
+ % are type variables).
+ %
+ % All variables in this tvarset have to have explicit names.
+ % If the original pragma contains anonymous variables, the
+ % code constructing this decl_pragma_type_spec will give
+ % those variable names. See the comment on the tspec_tvarset
+ % field below for the reason behind this requirement.
+ tsc_tvarset :: tvarset,
+
+ % The equivalence types used.
+ tsc_items :: set(recomp_item_id),
+
+ tsc_context :: prog_context,
+ tsc_seq_num :: item_seq_num
+ ).
+
+:- type maybe_apply_to_supers
+ ---> do_not_apply_to_supers
+ ; apply_to_supers.
+
+%---------------------%
+
+:- type decl_pragma_type_spec_info
+ ---> decl_pragma_type_spec_info(
+ tspec_pfumm :: pred_func_or_unknown_maybe_modes,
+
+ % The existing predicate name.
+ tspec_pred_name :: sym_name,
+
+ % The name of the module from whose (source or interface) file
+ % we read the type_spec pragma. This will always name
+ % the module that contains the pragma, because we never put
+ % a type_spec pragma into any interface file other than
+ % an interface file of the module containing the pragma.
+ tspec_module_name :: module_name,
+
+ % The type substitution (using the variable names
+ % from the pred declaration).
+ tspec_tsubst :: type_subst,
+
+ % The varset of the term containing the pragma, coerced
+ % to being a tvarset (since no part of the pragma except
+ % the type substitution may contain variables).
+ %
+ % All variables in this tvarset have to have explicit names.
+ % If the original pragma contains anonymous variables, the
+ % code constructing this decl_pragma_type_spec will give
+ % those variable names.
+ %
+ % The reason for this requirement is that the process
+ % of writing out an anonymous variable and reading it back in
+ % will produce a non-anonymous variable. Since the names
+ % (if any) of the variables in tspec_tsubst are an input
+ % to the code that constructs the name of the type-specialized
+ % predicate, we would get a discrepancy between the predicate
+ % name constructed by compiler invocations that know the
+ % variable as unnamed (this will be the invocation that
+ % compiles the module containing the type_spec pragma,
+ % which constructs the code of the type specialized predicate),
+ % and compiler invocations that know that variable as named
+ % (this will be all the invocations that read the original
+ % module's .int file, which will be constructing many of
+ % the *calls* to the type specialized predicate). The result
+ % will be calls to the type specialized predicate that refer
+ % to it by the wrong name, leading to link errors.
+ %
+ % By giving all anonymous variables in the type_spec pragma
+ % in the original source file as soon as we have parsed it,
+ % and then always using the resulting names, we avoid this
+ % problem.
+ tspec_tvarset :: tvarset,
+
+ % The equivalence types used.
+ tspec_items :: set(recomp_item_id),
+
+ tspec_context :: prog_context,
+ tspec_seq_num :: item_seq_num
+ ).
+
+%---------------------%
+
+:- type decl_pragma_oisu_info
+ ---> decl_pragma_oisu_info(
+ oisu_type_ctor :: type_ctor,
+ oisu_creator_preds :: list(pf_sym_name_user_arity),
+ oisu_transformer_preds :: list(pf_sym_name_user_arity),
+ oisu_destroyer_preds :: list(pf_sym_name_user_arity),
+ oisu_context :: prog_context,
+ oisu_seq_num :: item_seq_num
+ ).
+
+%---------------------%
+
+% The termination/termination2 pragmas record information
+% about a predicate's or function's termination properties for our
+% two different termination analyzers. Even though they are usually
+% compiler generated, they are decl pragmas, not gen pragmas, because
+% we allow users to include them in Mercury source programs, to tell
+% the analyzers some things that they cannot figure out for themselves,
+% such as the termination properties of foreign language code in
+% foreign_procs.
+
+:- type decl_pragma_termination_info
+ ---> decl_pragma_termination_info(
+ % The modes represent the declared argmodes of the procedure,
+ % unless there are no declared argmodes, in which case
+ % we use the inferred argmodes.
+ terminfo_pred_id :: proc_pf_name_modes,
+ terminfo_args :: maybe(pragma_arg_size_info),
+ terminfo_term :: maybe(pragma_termination_info),
+ terminfo_context :: prog_context,
+ terminfo_seq_num :: item_seq_num
+ ).
+
+%---------------------%
+
+:- type decl_pragma_termination2_info
+ ---> decl_pragma_termination2_info(
+ terminfo2_pred_id :: proc_pf_name_modes,
+ terminfo2_args :: maybe(pragma_constr_arg_size_info),
+ terminfo2_args2 :: maybe(pragma_constr_arg_size_info),
+ terminfo2_term :: maybe(pragma_termination_info),
+ terminfo2_context :: prog_context,
+ terminfo2_seq_num :: item_seq_num
+ ).
+
+%---------------------%
+
+% The sharing/reuse pragmas record information about a predicate's or
+% function's properties that are relevant for compile-time garbage
+% collection (ctgx). Even though they are usually compiler generated,
+% they are decl pragmas, not gen pragmas, because we allow users
+% to include them in Mercury source programs, to tell the compiler some things
+% that it cannot figure out for itself, such as the ctgc properties
+% of foreign language code in foreign_procs.
+
+:- type decl_pragma_struct_sharing_info
+ ---> decl_pragma_struct_sharing_info(
+ % After structure sharing analysis, the compiler generates
+ % structure sharing pragmas to be stored in and read from
+ % optimization interface files.
+ %
+ % The list of modes consists of the declared argmodes
+ % (or inferred argmodes if there are no declared ones).
+ sharing_pred_id :: proc_pf_name_modes,
+ sharing_headvars :: list(prog_var),
+ sharing_headvar_types :: list(mer_type),
+
+ % The prog_varset and tvarset are meaningful only when
+ % writing out this pragma; add_pragma.m ignores both varsets.
+ sharing_varset :: prog_varset,
+ sharing_tvarset :: tvarset,
+
+ % As of 2019 10 29, and probably long before then,
+ % the compiler *always* fills this slot with `yes(...)'.
+ % A `no' would mean that the relevant information is not
+ % available, but in that case, we simply do not write out
+ % this pragma.
+ sharing_description :: maybe(structure_sharing_domain),
+
+ sharing_context :: prog_context,
+ sharing_seq_num :: item_seq_num
+ ).
+
+%---------------------%
+
+:- type decl_pragma_struct_reuse_info
+ ---> decl_pragma_struct_reuse_info(
+ % After reuse analysis, the compiler generates structure reuse
+ % pragmas to be stored in and read from optimization interface
+ % files.
+ %
+ % The list of modes consists of the declared argmodes
+ % (or inferred argmodes if there are no declared ones).
+ %
+ % The last sym_name (reuse_optimised_name) stores the name
+ % of the optimised version of the exported predicate.
+ % XXX As of 2019 10 29, the word "reuse_optimised_name"
+ % appears nowhere in the compiler apart from this comment.
+ reuse_pred_id :: proc_pf_name_modes,
+ reuse_headvars :: list(prog_var),
+ reuse_headvar_types :: list(mer_type),
+
+ % The prog_varset and tvarset are meaningful only when
+ % writing out this pragma; add_pragma.m ignores both varsets.
+ reuse_varset :: prog_varset,
+ reuse_tvarset :: tvarset,
+
+ % As of 2019 10 29, and probably long before then,
+ % the compiler *always* fills this slot with `yes(...)'.
+ % A `no' would mean that the relevant information is not
+ % available, but in that case, we simply do not write out
+ % this pragma.
+ reuse_description :: maybe(structure_reuse_domain),
+
+ reuse_context :: prog_context,
+ reuse_seq_num :: item_seq_num
+ ).
+
+%---------------------%
+
+:- type item_decl_marker_info
+ ---> item_decl_marker_info(
+ dm_marker_kind :: decl_pragma_marker_kind,
+ dm_pred_spec :: pred_pfu_name_arity,
+ dm_context :: prog_context,
+ dm_seq_num :: item_seq_num
+ ).
+
+:- type item_decl_marker_info_opt =< item_decl_marker_info
+ ---> item_decl_marker_info(
+ dm_marker_kind :: decl_pragma_marker_kind_opt,
+ dm_pred_spec :: pred_pfu_name_arity_pf,
+ dm_context :: prog_context,
+ dm_seq_num :: item_seq_num
+ ).
+
+ % XXX The "terminates" and "does_not_terminate" markers are assertions
+ % about the behavior of a given predicate that the compiler may be able
+ % to exploit when compiling other modules. The "check_termination" marker
+ % is not like that: it is a directive that is useful only while
+ % the compiler is working on the module in which it occurs. We should
+ % therefore consider making this an *impl* marker, which would entail
+ % allowing the "check_termination" pragma to occur only in implementation
+ % sections, even when the predicate/function they name is exported.
+:- type decl_pragma_marker_kind
+ ---> dpmk_terminates
+ ; dpmk_does_not_terminate
+ ; dpmk_check_termination.
+
+:- type decl_pragma_marker_kind_opt =< decl_pragma_marker_kind
+ ---> dpmk_terminates
+ ; dpmk_does_not_terminate.
+
+%---------------------------------------------------------------------------%
+%
+% Impl pragmas.
+%
+
+:- type impl_pragma_foreign_decl_info
+ ---> impl_pragma_foreign_decl_info(
+ % A foreign language declaration, such as C header code.
+ decl_lang :: foreign_language,
+ decl_is_local :: foreign_decl_is_local,
+ decl_decl :: foreign_literal_or_include,
+ decl_context :: prog_context,
+ decl_seq_num :: item_seq_num
+ ).
+
+%---------------------%
+
+:- type impl_pragma_foreign_code_info
+ ---> impl_pragma_foreign_code_info(
+ code_lang :: foreign_language,
+ code_code :: foreign_literal_or_include,
+ code_context :: prog_context,
+ code_seq_num :: item_seq_num
+ ).
+
+%---------------------%
+
+:- type impl_pragma_fproc_export_info
+ ---> impl_pragma_fproc_export_info(
+ exp_maybe_attrs :: item_maybe_attrs,
+
+ exp_language :: foreign_language,
+ % Predname, Predicate/function, Modes, foreign function name.
+ exp_pred_id :: proc_pf_name_modes,
+ exp_foreign_name :: string,
+
+ % Specified the names of any variables in the modes above.
+ % Used for generating error messages about foreign_export
+ % pragmas for undeclared modes.
+ exp_varset :: prog_varset,
+
+ exp_context :: prog_context,
+ exp_seq_num :: item_seq_num
+ ).
+
+%---------------------%
+
+:- type impl_pragma_external_proc_info
+ ---> impl_pragma_external_proc_info(
+ % The specified procedure(s) is/are implemented outside
+ % of Mercury code, for the named backend if there is one,
+ % or if there isn't a named backend, then for all backends.
+ external_name :: pf_sym_name_user_arity,
+ external_maybe_backend :: maybe(backend),
+ external_context :: prog_context,
+ external_seq_num :: item_seq_num
+ ).
+
+%---------------------%
+
+:- type impl_pragma_fact_table_info
+ ---> impl_pragma_fact_table_info(
+ % Predname and Arity, Fact file name.
+ fact_table_pred :: pred_pfu_name_arity,
+ fact_table_filename :: string,
+ fact_table_context :: prog_context,
+ fact_table_seq_num :: item_seq_num
+ ).
+
+%---------------------%
+
+:- type impl_pragma_tabled_info
+ ---> impl_pragma_tabled_info(
+ % Tabling type, Predname, Arity, PredOrFunc?, Mode?
+ tabled_method :: tabled_eval_method,
+ tabled_name :: pred_or_proc_pfumm_name,
+ tabled_attributes :: maybe(table_attributes),
+ tabled_context :: prog_context,
+ tabled_seq_num :: item_seq_num
+ ).
+
+%---------------------%
+
+:- type impl_pragma_req_tail_rec_info
+ ---> impl_pragma_req_tail_rec_info(
+ rtr_proc_id :: pred_or_proc_pfumm_name,
+ rtr_require_tailrec :: require_tail_recursion,
+ % This parameter only makes sense when options contains
+ % either rtro_mutual_rec_only or rtro_all_recursion.
+ % TODO, currently unused, may be used later to implement one
+ % of Zoltan's suggestions here:
+ % http://www.mercurylang.org/list-archives/developers/
+ % 2015-November/016482.html
+ % rtr_maybe_scc :: maybe(list(
+ % pred_or_proc_pfumm_name))
+ rtr_context :: prog_context,
+ rtr_seq_num :: item_seq_num
+ ).
+
+%---------------------%
+
+:- type impl_pragma_req_feature_set_info
+ ---> impl_pragma_req_feature_set_info(
+ rfs_feature_set :: set(required_feature),
+ rfs_context :: prog_context,
+ rfs_seq_num :: item_seq_num
+ ).
+
+%---------------------%
+
+:- type item_impl_marker_info
+ ---> item_impl_marker_info(
+ im_marker_kind :: impl_pragma_marker_kind,
+ im_pred_spec :: pred_pfu_name_arity,
+ im_context :: prog_context,
+ im_seq_num :: item_seq_num
+ ).
+
+:- type item_impl_marker_info_opt =< item_impl_marker_info
+ ---> item_impl_marker_info(
+ im_marker_kind :: impl_pragma_marker_kind_opt,
+ im_pred_spec :: pred_pfu_name_arity_pf,
+ im_context :: prog_context,
+ im_seq_num :: item_seq_num
+ ).
+
+:- type impl_pragma_marker_kind
+ ---> ipmk_inline
+ ; ipmk_no_inline
+ ; ipmk_consider_used
+ ; ipmk_mode_check_clauses
+ ; ipmk_no_detism_warning
+ ; ipmk_promise_pure
+ ; ipmk_promise_semipure
+ ; ipmk_promise_eqv_clauses
+ ; ipmk_req_sw_arms_type_order.
+
+ % These are the kinds of impl markers that we put into .opt files.
+:- type impl_pragma_marker_kind_opt =< impl_pragma_marker_kind
+ ---> ipmk_inline
+ ; ipmk_no_inline
+ ; ipmk_mode_check_clauses
+ ; ipmk_promise_pure
+ ; ipmk_promise_semipure
+ ; ipmk_promise_eqv_clauses.
+
+%---------------------------------------------------------------------------%
+%
+% Generated pragmas.
+%
+
+:- type gen_pragma_unused_args_info
+ ---> gen_pragma_unused_args_info(
+ % This pragma Should only appear in .opt files.
+ unused_proc_id :: proc_pf_name_arity_mn,
+
+ % The argument positions of the unused arguments.
+ % Used for intermodule unused argument removal.
+ unused_args :: list(int),
+
+ unused_context :: prog_context,
+ unused_seq_num :: item_seq_num
+ ).
+
+:- type gen_pragma_exceptions_info
+ ---> gen_pragma_exceptions_info(
+ % This pragma should only appear in `.opt' and
+ % `.trans_opt' files.
+ exceptions_proc_id :: proc_pf_name_arity_mn,
+ exceptions_status :: exception_status,
+
+ exceptions_context :: prog_context,
+ exceptions_seq_num :: item_seq_num
+ ).
+
+:- type gen_pragma_trailing_info
+ ---> gen_pragma_trailing_info(
+ % This pragma should only appear in `.trans_opt' files.
+ trailing_proc_id :: proc_pf_name_arity_mn,
+ trailing_status :: trailing_status,
+
+ trailing_context :: prog_context,
+ trailing_seq_num :: item_seq_num
+ ).
+
+:- type gen_pragma_mm_tabling_info
+ ---> gen_pragma_mm_tabling_info(
+ % This pragma should only appear in `.opt' and
+ % `.trans_opt' files.
+ mm_tabling_proc_id :: proc_pf_name_arity_mn,
+ mm_tabling_status :: mm_tabling_status,
+
+ mm_tabling_context :: prog_context,
+ mm_tabling_seq_num :: item_seq_num
+ ).
+
+%---------------------------------------------------------------------------%
+%---------------------------------------------------------------------------%
+
+:- implementation.
+
+:- import_module term.
+:- import_module varset.
+
+%---------------------------------------------------------------------------%
+
+get_decl_pragma_context(DeclPragma) = Context :-
+ (
+ DeclPragma = decl_pragma_obsolete_pred(ObsPred),
+ Context = ObsPred ^ obspred_context
+ ;
+ DeclPragma = decl_pragma_obsolete_proc(ObsProc),
+ Context = ObsProc ^ obsproc_context
+ ;
+ DeclPragma = decl_pragma_format_call(FormatCall),
+ Context = FormatCall ^ format_context
+ ;
+ DeclPragma = decl_pragma_type_spec_constr(TypeSpecConstr),
+ Context = TypeSpecConstr ^ tsc_context
+ ;
+ DeclPragma = decl_pragma_type_spec(TypeSpec),
+ Context = TypeSpec ^ tspec_context
+ ;
+ DeclPragma = decl_pragma_oisu(OISU),
+ Context = OISU ^ oisu_context
+ ;
+ DeclPragma = decl_pragma_termination(Term),
+ Context = Term ^ terminfo_context
+ ;
+ DeclPragma = decl_pragma_termination2(Term2),
+ Context = Term2 ^ terminfo2_context
+ ;
+ DeclPragma = decl_pragma_struct_sharing(Sharing),
+ Context = Sharing ^ sharing_context
+ ;
+ DeclPragma = decl_pragma_struct_reuse(Reuse),
+ Context = Reuse ^ reuse_context
+ ).
+
+get_impl_pragma_context(ImplPragma) = Context :-
+ (
+ ImplPragma = impl_pragma_foreign_decl(ForeignDecl),
+ Context = ForeignDecl ^ decl_context
+ ;
+ ImplPragma = impl_pragma_foreign_code(ForeignCode),
+ Context = ForeignCode ^ code_context
+ ;
+ ImplPragma = impl_pragma_fproc_export(Export),
+ Context = Export ^ exp_context
+ ;
+ ImplPragma = impl_pragma_external_proc(ExternalProc),
+ Context = ExternalProc ^ external_context
+ ;
+ ImplPragma = impl_pragma_fact_table(FactTable),
+ Context = FactTable ^ fact_table_context
+ ;
+ ImplPragma = impl_pragma_tabled(Tabled),
+ Context = Tabled ^ tabled_context
+ ;
+ ImplPragma = impl_pragma_req_tail_rec(TailRec),
+ Context = TailRec ^ rtr_context
+ ;
+ ImplPragma = impl_pragma_req_feature_set(FeatureSet),
+ Context = FeatureSet ^ rfs_context
+ ).
+
+get_gen_pragma_context(GenPragma) = Context :-
+ (
+ GenPragma = gen_pragma_unused_args(UnusedArgs),
+ Context = UnusedArgs ^ unused_context
+ ;
+ GenPragma = gen_pragma_exceptions(Excps),
+ Context = Excps ^ exceptions_context
+ ;
+ GenPragma = gen_pragma_trailing(Trailing),
+ Context = Trailing ^ trailing_context
+ ;
+ GenPragma = gen_pragma_mm_tabling(MMTabling),
+ Context = MMTabling ^ mm_tabling_context
+ ).
+
+%---------------------------------------------------------------------------%
+:- end_module parse_tree.prog_item_pragma.
+%---------------------------------------------------------------------------%
diff --git a/compiler/prog_item_pred_proc_id.m b/compiler/prog_item_pred_proc_id.m
new file mode 100644
index 000000000..4e3a93884
--- /dev/null
+++ b/compiler/prog_item_pred_proc_id.m
@@ -0,0 +1,176 @@
+%---------------------------------------------------------------------------%
+% vim: ft=mercury ts=4 sw=4 et
+%---------------------------------------------------------------------------%
+% Copyright (C) 1996-2011 The University of Melbourne.
+% Copyright (C) 2014-2026 The Mercury team.
+% This file may only be copied under the terms of the GNU General
+% Public License - see the file COPYING in the Mercury distribution.
+%---------------------------------------------------------------------------%
+%
+% File: prog_item_pred_proc_id.m.
+% Author: zs.
+
+% This module defines types that identify predicates, functions
+% and/or procedures, in pragmas and in other kinds of items.
+%
+%---------------------------------------------------------------------------%
+
+:- module parse_tree.prog_item_pred_proc_id.
+:- interface.
+
+:- import_module mdbcomp.
+:- import_module mdbcomp.prim_data.
+:- import_module mdbcomp.sym_name.
+:- import_module parse_tree.prog_data.
+:- import_module parse_tree.prog_data_pragma.
+
+:- import_module list.
+:- import_module maybe.
+
+%---------------------------------------------------------------------------%
+
+:- type pred_pfu_name_arity
+ ---> pred_pfu_name_arity(
+ ppfuna_pfu :: pred_func_or_unknown,
+ ppfuna_pred_name :: sym_name,
+ ppfuna_arity :: user_arity
+ ).
+
+:- type pred_pfu_name_arity_pf =< pred_pfu_name_arity
+ ---> pred_pfu_name_arity(
+ ppfuna_pfu :: pred_func_or_unknown_pf,
+ ppfuna_pred_name :: sym_name,
+ ppfuna_arity :: user_arity
+ ).
+
+:- type proc_pf_name_arity_mn
+ ---> proc_pf_name_arity_mn(
+ ppfnamn_pf :: pred_or_func,
+ ppfnamn_pred_name :: sym_name,
+ ppfnamn_arity :: user_arity,
+ ppfnamn_mode_num :: mode_num
+ ).
+
+:- type proc_pf_name_modes
+ ---> proc_pf_name_modes(
+ ppfnm_pf :: pred_or_func,
+ ppfnm_pred_name :: sym_name,
+ ppfnm_arity :: list(mer_mode)
+ ).
+
+:- type pred_or_proc_pfumm_name
+ ---> pred_or_proc_pfumm_name(
+ ppfummn_pfumm :: pred_func_or_unknown_maybe_modes,
+ ppfummn_pred_name :: sym_name
+ ).
+
+:- type pred_func_or_unknown
+ ---> pfu_predicate
+ ; pfu_function
+ ; pfu_unknown.
+
+:- type pred_func_or_unknown_pf =< pred_func_or_unknown
+ ---> pfu_predicate
+ ; pfu_function.
+
+:- type pred_func_or_unknown_maybe_modes
+ ---> pfumm_predicate(modes_or_arity)
+ ; pfumm_function(modes_or_arity)
+ ; pfumm_unknown(user_arity).
+
+:- type modes_or_arity
+ ---> moa_modes(list(mer_mode))
+ ; moa_arity(user_arity).
+
+%---------------------------------------------------------------------------%
+
+:- func pfu_to_maybe_pred_or_func(pred_func_or_unknown) = maybe(pred_or_func).
+:- func maybe_pred_or_func_to_pfu(maybe(pred_or_func)) = pred_func_or_unknown.
+
+:- pred pfumm_to_maybe_pf_arity_maybe_modes(
+ pred_func_or_unknown_maybe_modes::in, maybe(pred_or_func)::out,
+ user_arity::out, maybe(list(mer_mode))::out) is det.
+
+%---------------------------------------------------------------------------%
+
+ % Did an item originate in user code or was it added by the compiler
+ % as part of a source-to-source transformation, e.g. the initialise
+ % declarations? If the latter, specify the information that the
+ % make_hlds pass may need to answer questions about the item.
+ %
+:- type item_maybe_attrs
+ ---> item_origin_user
+ ; item_origin_compiler(item_compiler_attributes).
+
+:- type item_compiler_attributes
+ ---> item_compiler_attributes(
+ compiler_origin
+ ).
+
+:- type compiler_origin
+ ---> compiler_origin_initialise
+ ; compiler_origin_finalise
+ ; compiler_origin_class_method(
+ cm_class_id :: class_id,
+ cm_method :: pf_sym_name_user_arity
+ )
+ ; compiler_origin_solver_repn(
+ cosr_type_ctor :: type_ctor,
+ cosr_aux_pred_kind :: solver_type_pred_kind
+ )
+ ; compiler_origin_mutable(
+ com_module_name :: module_name,
+ com_mutable_name :: string,
+ com_aux_pred_kind :: mutable_pred_kind
+ )
+ ; compiler_origin_tabling(
+ cot_pred_spec :: pf_sym_name_user_arity,
+ cot_aux_pred_kind :: tabling_aux_pred_kind
+ ).
+
+%---------------------------------------------------------------------------%
+
+:- implementation.
+
+:- import_module parse_tree.prog_util.
+
+%---------------------------------------------------------------------------%
+
+pfu_to_maybe_pred_or_func(pfu_predicate) = yes(pf_predicate).
+pfu_to_maybe_pred_or_func(pfu_function) = yes(pf_function).
+pfu_to_maybe_pred_or_func(pfu_unknown) = no.
+
+maybe_pred_or_func_to_pfu(yes(pf_predicate)) = pfu_predicate.
+maybe_pred_or_func_to_pfu(yes(pf_function)) = pfu_function.
+maybe_pred_or_func_to_pfu(no) = pfu_unknown.
+
+pfumm_to_maybe_pf_arity_maybe_modes(PFUMM, MaybePredOrFunc, UserArity,
+ MaybeModes) :-
+ (
+ (
+ PFUMM = pfumm_predicate(ModesOrArity),
+ PredOrFunc = pf_predicate
+ ;
+ PFUMM = pfumm_function(ModesOrArity),
+ PredOrFunc = pf_function
+ ),
+ MaybePredOrFunc = yes(PredOrFunc),
+ (
+ ModesOrArity = moa_modes(Modes),
+ list.length(Modes, NumModes),
+ PredFormArity = pred_form_arity(NumModes),
+ user_arity_pred_form_arity(PredOrFunc, UserArity, PredFormArity),
+ MaybeModes = yes(Modes)
+ ;
+ ModesOrArity = moa_arity(UserArity),
+ MaybeModes = no
+ )
+ ;
+ PFUMM = pfumm_unknown(UserArity),
+ MaybePredOrFunc = no,
+ MaybeModes = no
+ ).
+
+%---------------------------------------------------------------------------%
+:- end_module parse_tree.prog_item_pred_proc_id.
+%---------------------------------------------------------------------------%
diff --git a/compiler/prog_item_stats.m b/compiler/prog_item_stats.m
index abf16516b..f0f3909ee 100644
--- a/compiler/prog_item_stats.m
+++ b/compiler/prog_item_stats.m
@@ -37,6 +37,7 @@
:- import_module mdbcomp.sym_name.
:- import_module parse_tree.maybe_error.
:- import_module parse_tree.prog_item.
+:- import_module parse_tree.prog_item_pragma.
:- import_module int.
:- import_module list.
diff --git a/compiler/prog_item_type.m b/compiler/prog_item_type.m
new file mode 100644
index 000000000..40f10d262
--- /dev/null
+++ b/compiler/prog_item_type.m
@@ -0,0 +1,878 @@
+%---------------------------------------------------------------------------%
+% vim: ft=mercury ts=4 sw=4 et
+%---------------------------------------------------------------------------%
+% Copyright (C) 2019-2026 The Mercury team.
+% This file may only be copied under the terms of the GNU General
+% Public License - see the file COPYING in the Mercury distribution.
+%---------------------------------------------------------------------------%
+%
+% File: prog_item_type.m.
+% Author: zs.
+%
+%---------------------------------------------------------------------------%
+
+:- module parse_tree.prog_item_type.
+:- interface.
+
+:- import_module libs.
+:- import_module libs.globals.
+:- import_module mdbcomp.
+:- import_module mdbcomp.sym_name.
+:- import_module parse_tree.prog_data.
+:- import_module parse_tree.prog_item_inst_mode.
+
+:- import_module list.
+:- import_module map.
+:- import_module maybe.
+:- import_module one_or_more.
+:- import_module pair.
+
+%---------------------------------------------------------------------------%
+
+:- type item_type_defn_info == item_type_defn_info_general(type_defn).
+
+:- type item_type_defn_info_abstract
+ == item_type_defn_info_general(type_details_abstract).
+:- type item_type_defn_info_solver
+ == item_type_defn_info_general(type_details_solver).
+:- type item_type_defn_info_eqv
+ == item_type_defn_info_general(type_details_eqv).
+:- type item_type_defn_info_du
+ == item_type_defn_info_general(type_details_du).
+:- type item_type_defn_info_sub
+ == item_type_defn_info_general(type_details_sub).
+:- type item_type_defn_info_foreign
+ == item_type_defn_info_general(type_details_foreign_generic).
+
+:- type item_type_defn_info_general(T)
+ ---> item_type_defn_info(
+ % `:- type ...':
+ % a definition of a type, or a declaration of an abstract type.
+ td_ctor_name :: sym_name,
+ td_ctor_args :: list(type_param),
+ td_ctor_defn :: T,
+ td_tvarset :: tvarset,
+ td_context :: prog_context,
+ td_seq_num :: item_seq_num
+ ).
+
+%---------------------------------------------------------------------------%
+
+:- type item_foreign_enum_info
+ ---> item_foreign_enum_info(
+ fe_language :: foreign_language,
+ fe_type_ctor :: type_ctor,
+ fe_values :: one_or_more(
+ pair(sym_name, string)),
+ fe_context :: prog_context,
+ fe_seq_num :: item_seq_num
+ ).
+
+%---------------------------------------------------------------------------%
+
+:- type item_type_repn_info_eqv
+ == item_type_repn_info_general(mer_type).
+:- type item_type_repn_info_subtype
+ == item_type_repn_info_general(type_ctor).
+:- type item_type_repn_info
+ == item_type_repn_info_general(type_ctor_repn_info).
+
+:- type item_type_repn_info_general(T)
+ ---> item_type_repn_info(
+ % `:- type_representation ...':
+ % An item added by the compiler to a .int3 file
+ % to tell readers of that file the information they need
+ % to correctly reconstruct the representation of the given
+ % type constructor, even when that information is supposed
+ % to be invisible to them semantically.
+ % There should be at most one such item for any type_ctor
+ % in the .int3 file of its defining module.
+ % The sym_name should be fully qualified.
+ tr_ctor :: sym_name,
+ tr_ctor_arg_tvars :: list(tvar),
+ tr_ctor_repn_info :: T,
+ tr_tvarset :: tvarset,
+ tr_context :: prog_context,
+ tr_seq_num :: item_seq_num
+ ).
+
+%---------------------------------------------------------------------------%
+%
+% The intended semantics of a type_ctor_defn_map is a map of
+% all the type constructors defined in a given SECTION of a given
+% interface file to all its definitions in that section.
+%
+% There are four intended uses of a type_ctor_defn_map. The most
+% important is the fourth one.
+%
+% One is to eliminate unnecessary items from interface files.
+% For example, library/set.m contains two definitions of the set
+% type constructor: an abstract definition in the publicly documented
+% interface section, and an actual du definition in another interface
+% section that we do not include in the automatically generated
+% documentation but we *do* export to other modules. In situations
+% like this, the abstract definition is redundant. Never including it
+% in an interface file lets that interface file to remain unchanged
+% in the event that the user deletes the abstract definition from
+% the source file as well.
+%
+% The second use is to canonicalize the parts of interface files
+% containing type definitions.
+%
+% The third use is to help deal with sets of definitions that
+% don't make sense. There are many rules that a set of definitions
+% for a given type constructor must meet (such as "there may be at most one
+% definition for a type constructor that is a du, equivalence or solver
+% definition), and bugs may manifest themselves as violations of these rules.
+%
+% We have a choice in when these violations are detected.
+%
+% - If we allow the inclusion of inconsistent sets of type definitions
+% in interface files, then we must detect and handle these
+% inconsistencies every time a compiler invocation reads that interface
+% file. These invocations won't generate error messages for these
+% inconsistencies since the type constructor won't be local, but
+% they may generate messages for other "errors" that look like errors
+% only because the compiler's resolution of the inconsistency (i.e.
+% its choice of which type definitions to keep and which to throw out)
+% differs from the programmer's choice.
+%
+% - If we do NOT allow the inclusion of inconsistent sets of type
+% definitions in interface files, then we must report any violations
+% at interface file construction time, and make them cause that
+% construction to fail. Printing such error messages to stdout
+% instead of the module's .err file is less than ideal, but
+% this early detection can avoid avalanches of misleading diagnostics
+% of the kind mentioned in the previous point. It can also save
+% recompilations. If a module's source file contains inconsistent
+% definitions for a type constructor, then the programmer will
+% have to delete the unintended ones. Once this is done, the
+% interface file will have to be rebuilt. If we allow inconsistent
+% definitions in the interface file, its new contents will differ
+% from its old contents, which means that all the compilations
+% of *other* modules that read the old contents will have been wasted.
+% If we cause the construction of the interface file to fail instead,
+% those compilations won't have taken place.
+%
+% We implement the first choice by checking whether each entry in
+% a type_ctor_defn_map makes sense, and generating error messages
+% when they don't. This is done by code in check_type_inst_mode_defns.m.
+%
+% The fourth and most motivating use is that having all the definitions
+% of a type_ctor, *and* all the foreign_enum pragmas that apply to that
+% type_ctor, all together at once will make the code that decides
+% the proper representation of that type significantly simpler.
+%
+% Everything above except the fourth use also applies to the inst_
+% and mode_ctor_defn_maps, though for those, the consistency rules are
+% much simpler: that each inst and mode constructor must have at most one
+% non-abstract definition.
+%
+
+:- type type_ctor_defn_map == map(type_ctor, type_ctor_all_defns).
+
+:- type type_ctor_all_defns
+ ---> type_ctor_all_defns(
+ % Abstract and nonabstract solver type definitions.
+ tcad_abstract_solver :: list(item_type_defn_info_abstract),
+ tcad_solver :: list(item_type_defn_info_solver),
+
+ % Abstract and nonabstract nonsolver type definitions.
+ tcad_abstract_std :: list(item_type_defn_info_abstract),
+ tcad_eqv :: list(item_type_defn_info_eqv),
+ tcad_du :: list(item_type_defn_info_du),
+ tcad_sub :: list(item_type_defn_info_sub),
+ tcad_foreign :: c_j_cs_defns
+ ).
+
+:- type type_ctor_maybe_defn
+ ---> type_ctor_maybe_defn(
+ % Abstract and nonabstract solver type definitions.
+ tcmd_abstract_solver :: maybe(item_type_defn_info_abstract),
+ tcmd_solver :: maybe(item_type_defn_info_solver),
+
+ % Abstract and nonabstract nonsolver type definitions.
+ tcmd_abstract_std :: maybe(item_type_defn_info_abstract),
+ tcmd_eqv :: maybe(item_type_defn_info_eqv),
+ tcmd_du :: maybe(item_type_defn_info_du),
+ tcmd_sub :: maybe(item_type_defn_info_sub),
+ tcmd_foreign :: c_j_cs_maybe_defn
+ ).
+
+ % We support foreign type definitions in all three of our target languages,
+ % C, Java and C#. Likewise, we allow foreign enum declarations
+ % in these three languages.
+ %
+ % There are several kinds of info that we may want to store for every
+ % one of these foreign languages. This can be done in instances
+ % of this type, whose fields always contain the info for C, Java and C#
+ % (in that order).
+:- type c_java_csharp(T)
+ ---> c_java_csharp(T, T, T).
+
+:- type c_j_cs_defns ==
+ c_java_csharp(list(item_type_defn_info_foreign)).
+:- type c_j_cs_maybe_defn ==
+ c_java_csharp(maybe(item_type_defn_info_foreign)).
+:- type c_j_cs_enums ==
+ c_java_csharp(list(item_foreign_enum_info)).
+:- type c_j_cs_maybe_enum ==
+ c_java_csharp(maybe(item_foreign_enum_info)).
+:- type c_j_cs_repn ==
+ c_java_csharp(maybe(foreign_type_repn)).
+:- type c_j_cs_enum_repn ==
+ c_java_csharp(maybe(enum_foreign_repn)).
+
+:- type inst_ctor_defn_map == map(inst_ctor, inst_ctor_all_defns).
+:- type inst_ctor_all_defns
+ ---> inst_ctor_all_defns(
+ icad_abstract :: list(item_inst_defn_info_abstract),
+ icad_eqv :: list(item_inst_defn_info_eqv)
+ ).
+
+:- type mode_ctor_defn_map == map(mode_ctor, mode_ctor_all_defns).
+:- type mode_ctor_all_defns
+ ---> mode_ctor_all_defns(
+ mcad_abstract :: list(item_mode_defn_info_abstract),
+ mcad_eqv :: list(item_mode_defn_info_eqv)
+ ).
+
+:- type type_ctor_foreign_enum_map == map(type_ctor, c_j_cs_enums).
+
+:- type type_ctor_repn_map == map(type_ctor, item_type_repn_info).
+
+%---------------------------------------------------------------------------%
+%
+% The representation of a checked-to-be-consistent set of type and
+% foreign enum definitions for every type constructor defined in a module.
+%
+
+:- type type_ctor_checked_map == map(type_ctor, type_ctor_checked_defn).
+
+ % A type is either a solver type, or not.
+:- type type_ctor_checked_defn
+ ---> checked_defn_solver(solver_type_defn, src_defns_solver)
+ ; checked_defn_std(std_type_defn, src_defns_std).
+
+%---------------------%
+
+ % Replace this one general type with one type for each function symbol
+ % in solver_type_defn.
+:- type src_defns_solver
+ ---> src_defns_solver(
+ % The item_type_defn_info (if any) in the interface section.
+ maybe(item_type_defn_info),
+
+ % The item_type_defn_info (if any) in the impl section.
+ maybe(item_type_defn_info)
+ ).
+
+ % Replace this one general type with one type for each function symbol
+ % in std_type_defn.
+:- type src_defns_std
+ ---> src_defns_std(
+ % The item_type_defn_infos in the interface section.
+ list(item_type_defn_info),
+
+ % The item_type_defn_infos and item_foreign_enum_infos
+ % in the implementation section.
+ list(item_type_defn_info),
+ list(item_foreign_enum_info)
+ ).
+
+%---------------------%
+
+:- type solver_type_defn
+ ---> solver_type_abstract(
+ abstract_solver_type_status,
+
+ % The abstract definition. It may be in either section;
+ % the status specifies the section.
+ item_type_defn_info_abstract
+ )
+ ; solver_type_full(
+ % The abstract definition in the interface section,
+ % if one exists.
+ maybe(item_type_defn_info_abstract),
+
+ % The full solver type definition, which must be in the
+ % implementation section.
+ item_type_defn_info_solver
+ ).
+
+:- type abstract_solver_type_status
+ ---> abstract_solver_type_exported
+ % The type name is exported. The abstract definition
+ % is in the interface section.
+ ; abstract_solver_type_private.
+ % The type name is not exported. The abstract definition
+ % is in the implementation section.
+
+%---------------------%
+
+:- type std_type_defn
+ ---> std_mer_type_eqv(
+ std_eqv_type_status,
+
+ % The equivalence type definition.
+ item_type_defn_info_eqv
+ )
+ ; std_mer_type_subtype(
+ std_subtype_status,
+
+ % The subtype definition.
+ item_type_defn_info_sub
+ )
+ ; std_mer_type_du_all_plain_constants(
+ std_du_type_status,
+
+ % The discriminated union type definition which represents
+ % either a direct dummy type or an enum.
+ item_type_defn_info_du,
+
+ % The first functor name in the type, and any later functor
+ % names. If there are no later functor names, then the type
+ % is a direct dummy type, and must satisfy the requirements
+ % of non_sub_du_type_is_dummy; if there are, then the type
+ % is an enum type, and must satisfy the requirements of
+ % non_sub_du_type_is_enum. (Function symbols that do not meet
+ % the relevant requirements may be constants, but we
+ % don't consider them *plain* constants.)
+ string,
+ list(string),
+
+ % For each of our target foreign languages, this field
+ % specifies whether we have either a foreign language
+ % definition for this type, or a foreign enum definition.
+ %
+ % While the Mercury representation uses small integers
+ % allocated consecutively from 0 to represent function symbols,
+ % this is not true even for foreign enum definitions,
+ % much less foreign type definitions.
+ c_j_cs_maybe_defn_or_enum
+ )
+ ; std_mer_type_du_not_all_plain_constants(
+ std_du_type_status,
+
+ % The discriminated union type definition which represents
+ % a type *other* than a direct dummy type or an enum.
+ item_type_defn_info_du,
+
+ % For each of our target foreign languages, this field
+ % specifies whether we have a foreign language type definition
+ % for this type.
+ c_j_cs_maybe_defn
+ )
+ ; std_mer_type_abstract(
+ std_abs_type_status,
+
+ % The abstract declaration of the type (not a subtype).
+ item_type_defn_info_abstract,
+
+ % For each of our target foreign languages, this field
+ % specifies whether we have a foreign language type definition
+ % for this type.
+ c_j_cs_maybe_defn
+ ).
+
+:- type maybe_only_constants
+ ---> not_only_plain_constants
+ ; only_plain_constants(
+ % The names of the constants, in the order of declaration.
+ opc_head_name :: string,
+ opc_tail_names :: list(string)
+ ).
+
+:- type std_eqv_type_status
+ ---> std_eqv_type_mer_exported
+ % The Mercury definition (i.e. the equivalence) is exported.
+ ; std_eqv_type_abstract_exported
+ % Only the type name is exported. The Mercury definition
+ % is private.
+ ; std_eqv_type_all_private.
+ % Everything about the type is private.
+
+:- type std_du_type_status
+ ---> std_du_type_mer_ft_exported
+ % Both the Mercury and any foreign type definitions are exported.
+ % Any foreign enum definitions are private, as they have to be.
+ % This status is not applicable to equivalence types or subtypes,
+ % since they may not have foreign type definitions.
+ ; std_du_type_mer_exported
+ % The Mercury definition is exported. Any foreign type definitions
+ % and/or foreign enum definitions are private.
+ ; std_du_type_abstract_exported
+ % Only the type name is exported. The Mercury definition and
+ % any foreign type definitions and/or foreign enum definitions
+ % are private.
+ ; std_du_type_all_private.
+ % Everything about the type is private.
+
+ % A version of std_du_type_status for subtypes, which may not have
+ % any foreign type definitions, and for which therefore the question of
+ % whether any foreign type definitions are exported is moot.
+:- type std_subtype_status
+ ---> std_sub_type_mer_exported
+ ; std_sub_type_abstract_exported
+ ; std_sub_type_all_private.
+
+:- type std_abs_type_status
+ ---> std_abs_type_ft_exported
+ % The type has foreign type definitions that are exported.
+ % Any foreign enum definitions are private, as they have to be.
+ ; std_abs_type_abstract_exported
+ % Only the type name is exported. Any foreign type definitions
+ % and/or foreign enum definitions are private.
+ ; std_abs_type_all_private.
+ % Everything about the type is private.
+
+%---------------------%
+
+:- type c_j_cs_maybe_defn_or_enum ==
+ c_java_csharp(maybe(foreign_type_or_enum)).
+
+:- type foreign_type_or_enum
+ ---> foreign_type_or_enum_type(item_type_defn_info_foreign)
+ ; foreign_type_or_enum_enum(checked_foreign_enum).
+
+ % Part of checking a foreign enum definition is checking whether
+ % the correspondence it describes between the Mercury functors
+ % of the type on the one hand and their foreign language counterparts
+ % on the other hand is a bijection. If it is, then the second argument
+ % of the checked_foreign_enum we construct gives the foreign language
+ % counterpart of each Mercury function symbol in the type in the order
+ % in which the Mercury function symbols are defined.
+ %
+ % For example, given
+ %
+ % :- type t ---> m1 ; m2 ; m3.
+ %
+ % and a foreign enum definition that gives the correspondence correctly
+ % but in a different order, such as
+ %
+ % :- pragma foreign_enum("C", t/0, [m2 - "f2", m3 - "f3", m1 - "f1"]).
+ %
+ % the second argument will contain the (nonempty) list "f1", "f2", "f3".
+ %
+ % On the other hand, if the mapping in the foreign enum definition is
+ % *not* a bijection, then we will not generate a checked_foreign_enum
+ % structure for it.
+ %
+:- type checked_foreign_enum
+ ---> checked_foreign_enum(item_foreign_enum_info, one_or_more(string)).
+
+%---------------------------------------------------------------------------%
+%
+% Information about the representations of types.
+%
+
+ % This type and type_ctor_checked_defn are closely related.
+ % The principal differences are the following.
+ %
+ % - type_ctor_checked_defn deals with solver types. Since solver types
+ % have no representation information themselves (they are represented
+ % by values of another type), this type does not deal with them.
+ %
+ % - One of the purposes of type_ctor_checked_defn is to decide
+ % what items to include in interface files, for use by code using
+ % the compiler's ancient approach to deciding type representation,
+ % where each compiler invocation that generated code decided for itself
+ % how every type it had access to was represented, including the types
+ % imported from other modules. This means that it needs to contain
+ % either whole items (of particular kinds), or information from which
+ % whole items can be reconstructed.
+ %
+ % - The above consideration also requires a type_ctor_checked_defn
+ % to specify the status of the type. On the other hand, values of
+ % this type have no use for status information. Status information
+ % is used only for checking whether an access to a type should be
+ % allowed or not; the only use of values of this type is to help
+ % compute type representations.
+ %
+ % - Only this type needs to contain representation information.
+ % A value of the type_ctor_checked_defn type needs to contain *part*
+ % of the information from which this representation information is
+ % computed for its type, but not *all* of it; some of that information
+ % comes from information about the representation of *other* types.
+ %
+ % One sort-of difference is while both contain information that has been
+ % checked by a compiler invocation, values of this type that have been
+ % read in from an interface file, while checked by another compiler
+ % invocation before being written out, may be corrupted in the filesystem.
+ % However, while this danger is always present, we need not take any
+ % special steps to guard against it, precisely because no perfect defense
+ % is possible.
+ %
+ % XXX TYPE_REPN Consider whether we can split this type into two,
+ % one for the tcrepns that can occur in .int3 files, and one for the
+ % tcrepns that can occur in .int/.int2 files.
+ %
+:- type type_ctor_repn_info
+ ---> tcrepn_is_word_aligned_ptr
+ ; tcrepn_is_eqv_to(mer_type)
+ ; tcrepn_is_subtype_of(type_ctor)
+ ; tcrepn_du(du_repn)
+ ; tcrepn_foreign(c_j_cs_repn).
+
+ % A type that has a discriminated union definition in Mercury
+ % may also have a definition in each of our foreign languages,
+ % If it is an direct_dummy or enum type, that definition may be
+ % either a foreign type definition or a foreign enum definition;
+ % otherwise, it can only be a foreign type definition.
+:- type du_repn
+ ---> dur_direct_dummy(direct_dummy_repn)
+ ; dur_enum(enum_repn)
+ ; dur_notag(notag_repn)
+ ; dur_gen_only_functor(gen_du_only_functor_repn)
+ ; dur_gen_more_functors(gen_du_more_functors_repn).
+
+ % When targeting C, many argument packing decisions depend on
+ % three properties of the target platform, i.e. on the combination
+ % of the target hardware and the target grade:
+ %
+ % - whether the target is 64 or 32 bit;
+ % - whether the grade is an spf (single-precision float) grade; and
+ % - whether the grade allows the direct arg optimization.
+ %
+ % These have eight combinations, but the spf grade component has
+ % no effect on argument packing on 64 bit targets (a float is one word
+ % either way), so only six are meaningful.
+ %
+ % If the decision represented by the T parameter happens to be the same
+ % on all six platforms, that decision can be represented by c_repns_same.
+ %
+ % If they are different on 64 vs 32 bit platforms, but are consistent
+ % for each word size, then they can be represented by c_repns_64_32.
+ %
+ % If neither is the case, we can record all six decisions using
+ % c_repns_all.
+ %
+ % XXX We should look for other partitions of the set of six platforms
+ % which often have identical decision results; one could be da vs noda.
+ %
+ % The name of this type is c_repns because argument packing applies
+ % only to the low level data representation, which is applicable only
+ % when targeting C.
+:- type c_repns(T)
+ ---> c_repns_same(
+ c_repn_same :: T
+ )
+ ; c_repns_64_32(
+ c_repn_all_64 :: T,
+ c_repn_all_32 :: T
+ )
+ ; c_repns_all(
+ c_repn_64_nospf_noda :: T,
+ c_repn_64_nospf_da :: T,
+ % c_repn_64_spf_noda :: T, % not needed; see above
+ % c_repn_64_spf_da :: T, % not needed; see above
+ c_repn_32_nospf_noda :: T,
+ c_repn_32_nospf_da :: T,
+ c_repn_32_spf_noda :: T,
+ c_repn_32_spf_da :: T
+ ).
+
+%---------------------%
+
+:- type direct_dummy_repn
+ ---> direct_dummy_repn(
+ % The type is a direct dummy type that satisfies the
+ % requirements of du_type_is_dummy.
+
+ % The name of the one functor in the type, which must be
+ % arity 0. Its representation will be dummy_tag.
+ dummy_functor_name :: string,
+
+ % Any foreign type or foreign enum definitions for the type.
+ dummy_foreign :: c_j_cs_enum_repn
+ ).
+
+%---------------------%
+
+:- type enum_repn
+ ---> enum_repn(
+ % The type is an enum type that satisfies the requirements
+ % of non_sub_du_type_is_enum.
+
+ % The list of the functor names (all arity 0). We store
+ % the first two separately to enforce the structural invariant
+ % that an enum must have at least two functors.
+ %
+ % The representation of functor #N in Mercury will be
+ % int_tag(int_tag_int(N)), with counting starting at 0.
+ %
+ % We do not care about the 32 vs 64 bit distinction here,
+ % because the definition of an enum type with more than 2^32
+ % function symbols will cause a compiler to run out of memory
+ % for a *very* long time to come.
+ enum_functor1 :: string,
+ enum_functor2 :: string,
+ enum_functors3plus :: list(string),
+
+ % Any foreign type or foreign enum definitions for the type.
+ enum_foreign :: c_j_cs_enum_repn
+ ).
+
+%---------------------%
+
+:- type notag_repn
+ ---> notag_repn(
+ % The name of the one functor in the type, which must be
+ % arity 1. Its representation will be no_tag.
+ % The representation of the argument be *recorded*
+ % as a full word at offset 0, but this should never be
+ % looked up, since the argument will actually be stored
+ % wherever the whole term is stored.
+ notag_functor_name :: string,
+
+ % The type of the one functor's one argument.
+ % We record this because without this information,
+ % we cannot recognize that a notag type whose argument size
+ % is less than one word can itself be stored in less than
+ % one word.
+ notag_functor_arg_type :: mer_type,
+
+ % The foreign language definitions for this type, if any.
+ notag_foreign :: c_j_cs_repn
+ ).
+
+%---------------------%
+
+:- type gen_du_only_functor_repn
+ ---> gen_du_only_functor_repn(
+ % The name of the data constructor. The arity is given by
+ % the length of list of argument types. The lists of argument
+ % representations in all of the nonconstant_repns inside
+ % the c_repns must also ave this length.
+ only_functor :: string,
+
+ % The types of the constructor's arguments, after
+ % the expansion of both equivalence types and notag types.
+ only_deref_arg_types :: list(mer_type),
+
+ % The representation of this functor for each possible
+ % target platform with the low level data representation.
+ % The nonconstant_repn cannot be ncr_direct_arg.
+ % XXX TYPE_REPN could we encode that invariant in the type?
+ only_arg_repns :: c_repns(only_nonconstant_repn),
+
+ % The foreign language definitions for this type, if any.
+ only_foreign :: c_j_cs_repn
+ ).
+
+:- type gen_du_more_functors_repn
+ ---> gen_du_more_functors_repn(
+ % The first, second and any later functors in the type,
+ % in declaration order, i.e. ordered on the functors'
+ % original ordinal numbers.
+ more_functor1 :: gen_du_functor_repn,
+ more_functor2 :: gen_du_functor_repn,
+ more_functors3plus :: list(gen_du_functor_repn),
+
+ % The foreign language definitions for this type, if any.
+ more_foreign :: c_j_cs_repn
+ ).
+
+%---------------------%
+
+:- type gen_du_functor_repn
+ ---> gen_du_constant_functor_repn(
+ % The name of the data constructor. The arity is zero.
+ gducf_functor :: string,
+
+ % The representation of this functor for each possible
+ % target platform with the low level data representation.
+ gducf_functor_repn :: c_repns(constant_repn)
+ )
+ ; gen_du_nonconstant_functor_repn(
+ % The name of the data constructor. The arity is given by
+ % the length of list of argument types. The lists of argument
+ % representations in all of the nonconstant_repns inside
+ % the c_repns must also ave this length.
+ gduncf_functor :: string,
+
+ % The types of the constructor's arguments, after
+ % the expansion of both equivalence types and notag types.
+ %
+ % Logically, the type of each argument belongs with
+ % the representation of that argument, but we have to store
+ % up to six versions of the representation, and we don't want
+ % a duplicate copy of the type next to each version.
+ gduncf_deref_arg_types :: list(mer_type),
+
+ % The representation of this functor for each possible
+ % target platform with the low level data representation.
+ gduncf_functor_repn :: c_repns(more_nonconstant_repn)
+ ).
+
+:- type constant_repn
+ ---> constant_repn(
+ % The ptag is 0. The next two fields specify the value
+ % and the size of the local secondary tag.
+ cr_sectag :: uint,
+ cr_sectag_size :: lsectag_word_or_size
+ ).
+
+:- type only_nonconstant_repn
+ ---> oncr_local_cell(only_nonconstant_local_cell_repn)
+ ; oncr_remote_cell(only_nonconstant_remote_cell_repn).
+
+:- type more_nonconstant_repn
+ ---> mncr_local_cell(more_nonconstant_local_cell_repn)
+ ; mncr_remote_cell(more_nonconstant_remote_cell_repn)
+ ; mncr_direct_arg(ptag).
+
+:- type only_nonconstant_local_cell_repn
+ ---> only_nonconstant_local_cell_repn(
+ % The ptag and local sectag are both implicitly 0u.
+ onclcr_arg_repns :: one_or_more(local_arg_repn)
+ ).
+
+:- type more_nonconstant_local_cell_repn
+ ---> more_nonconstant_local_cell_repn(
+ % The ptag is implicitly 0u.
+ mnclcr_sectag :: cell_local_sectag,
+ mnclcr_arg_repns :: one_or_more(local_arg_repn)
+ ).
+
+:- type only_nonconstant_remote_cell_repn
+ ---> only_nonconstant_remote_cell_repn(
+ % The ptag is both implicitly 0u, and there is
+ % no remote sectag.
+ ncrcr_arg_repns :: one_or_more(remote_arg_repn)
+ ).
+
+:- type more_nonconstant_remote_cell_repn
+ ---> more_nonconstant_remote_cell_repn(
+ ncrcr_ptag :: ptag,
+ ncrcr_sectag :: cell_remote_sectag,
+ ncrcr_arg_repns :: one_or_more(remote_arg_repn)
+ ).
+
+:- type cell_local_sectag
+ ---> cell_local_sectag(
+ clss_sectag :: uint,
+ clss_sectag_size :: uint8
+ ).
+
+:- type cell_remote_sectag
+ ---> cell_remote_no_sectag
+ ; cell_remote_sectag(
+ crss_sectag :: uint,
+ crss_sectag_size :: rsectag_word_or_size
+ ).
+
+:- type lsectag_word_or_size
+ ---> lsectag_rest_of_word(uint8)
+ ; lsectag_part_of_word(uint8).
+
+:- type rsectag_word_or_size
+ ---> rsectag_full_word
+ ; rsectag_part_of_word(uint8).
+
+:- type local_arg_repn
+ ---> local_partial(
+ lp_shift :: uint,
+ lp_fill :: fill_kind_size
+ )
+ ; local_none.
+
+:- type remote_arg_repn
+ ---> remote_full(
+ rf_arg_only_offset :: arg_only_offset,
+ rf_cell_offset :: cell_offset
+ )
+ ; remote_double(
+ rd_arg_only_offset :: arg_only_offset,
+ rd_cell_offset :: cell_offset,
+ rd_kind :: double_word_kind
+ )
+ ; remote_partial_first(
+ rpf_arg_only_offset :: arg_only_offset,
+ rpf_cell_offset :: cell_offset,
+ rpf_shift :: uint8,
+ rpf_fill :: fill_kind_size
+ )
+ ; remote_partial_shifted(
+ rps_arg_only_offset :: arg_only_offset,
+ rps_cell_offset :: cell_offset,
+ rps_shift :: uint8,
+ rps_fill :: fill_kind_size
+ )
+ ; remote_none_shifted(
+ rns_arg_only_offset :: arg_only_offset,
+ rns_cell_offset :: cell_offset
+ )
+ ; remote_none_nowhere.
+
+:- type fill_kind_size
+ ---> fk_enum(uint) % XXX TYPE_REPN should be uint8
+ ; fk_int8
+ ; fk_int16
+ ; fk_int32
+ ; fk_uint8
+ ; fk_uint16
+ ; fk_uint32
+ ; fk_char21.
+
+ % XXX TYPE_REPN should return uint8
+:- func fill_kind_size_num_bits(fill_kind_size) = uint.
+
+%---------------------%
+
+:- type foreign_type_lang_repn
+ ---> foreign_type_lang_repn(
+ ftlr_lang :: foreign_language,
+ ftlr_foreign_type :: foreign_type_repn
+ ).
+
+:- type foreign_type_repn
+ ---> foreign_type_repn(
+ % The name of the foreign type that represents values
+ % of this Mercury type.
+ ftr_foreign_type :: string,
+
+ % The assertions about this foreign type.
+ ftr_assertions :: foreign_type_assertions
+ ).
+
+:- type enum_foreign_repn
+ ---> enum_foreign_type(foreign_type_repn)
+ ; enum_foreign_enum(one_or_more(string)).
+
+%---------------------------------------------------------------------------%
+%---------------------------------------------------------------------------%
+
+:- implementation.
+
+:- import_module term.
+:- import_module varset.
+
+%---------------------------------------------------------------------------%
+
+fill_kind_size_num_bits(FillKindSize) = NumBits :-
+ (
+ FillKindSize = fk_enum(NumBits)
+ ;
+ ( FillKindSize = fk_int8
+ ; FillKindSize = fk_uint8
+ ),
+ NumBits = 8u
+ ;
+ ( FillKindSize = fk_int16
+ ; FillKindSize = fk_uint16
+ ),
+ NumBits = 16u
+ ;
+ ( FillKindSize = fk_int32
+ ; FillKindSize = fk_uint32
+ ),
+ NumBits = 32u
+ ;
+ FillKindSize = fk_char21,
+ NumBits = 21u
+ ).
+
+%---------------------------------------------------------------------------%
+:- end_module parse_tree.prog_item_type.
+%---------------------------------------------------------------------------%
diff --git a/compiler/prog_mutable.m b/compiler/prog_mutable.m
index a11b1bce5..46a200253 100644
--- a/compiler/prog_mutable.m
+++ b/compiler/prog_mutable.m
@@ -22,6 +22,7 @@
:- import_module parse_tree.prog_data.
:- import_module parse_tree.prog_foreign.
:- import_module parse_tree.prog_item.
+:- import_module parse_tree.prog_item_pragma.
:- import_module cord.
:- import_module list.
@@ -86,6 +87,7 @@
:- import_module parse_tree.file_names.
:- import_module parse_tree.maybe_error.
:- import_module parse_tree.prog_data_foreign.
+:- import_module parse_tree.prog_item_pred_proc_id.
:- import_module parse_tree.prog_mode.
:- import_module bool.
diff --git a/compiler/prog_parse_tree.m b/compiler/prog_parse_tree.m
index 9536a065a..ea7d09e77 100644
--- a/compiler/prog_parse_tree.m
+++ b/compiler/prog_parse_tree.m
@@ -64,6 +64,9 @@
:- import_module parse_tree.prog_data.
:- import_module parse_tree.prog_data_foreign.
:- import_module parse_tree.prog_item.
+:- import_module parse_tree.prog_item_inst_mode.
+:- import_module parse_tree.prog_item_pragma.
+:- import_module parse_tree.prog_item_type.
:- import_module recompilation.
:- import_module recompilation.item_types.
diff --git a/compiler/recompilation.check.m b/compiler/recompilation.check.m
index 96c22f692..3f925743a 100644
--- a/compiler/recompilation.check.m
+++ b/compiler/recompilation.check.m
@@ -79,6 +79,8 @@
:- import_module parse_tree.parse_tree_out_sym_name.
:- import_module parse_tree.prog_data.
:- import_module parse_tree.prog_item.
+:- import_module parse_tree.prog_item_inst_mode.
+:- import_module parse_tree.prog_item_type.
:- import_module parse_tree.prog_parse_tree.
:- import_module parse_tree.prog_util.
:- import_module parse_tree.write_error_spec.
diff --git a/compiler/recompilation.usage.m b/compiler/recompilation.usage.m
index c2e6ea168..16cdce5b4 100644
--- a/compiler/recompilation.usage.m
+++ b/compiler/recompilation.usage.m
@@ -46,6 +46,8 @@
:- import_module parse_tree.prog_data.
:- import_module parse_tree.prog_data_pragma.
:- import_module parse_tree.prog_item.
+:- import_module parse_tree.prog_item_pragma.
+:- import_module parse_tree.prog_item_pred_proc_id.
:- import_module parse_tree.prog_type.
:- import_module parse_tree.prog_type_test.
:- import_module parse_tree.prog_util.
diff --git a/compiler/recompilation.version.m b/compiler/recompilation.version.m
index a5f0b48c0..e93fb6f3d 100644
--- a/compiler/recompilation.version.m
+++ b/compiler/recompilation.version.m
@@ -98,6 +98,10 @@
:- import_module parse_tree.prog_data.
:- import_module parse_tree.prog_data_pragma.
:- import_module parse_tree.prog_item.
+:- import_module parse_tree.prog_item_inst_mode.
+:- import_module parse_tree.prog_item_pragma.
+:- import_module parse_tree.prog_item_pred_proc_id.
+:- import_module parse_tree.prog_item_type.
:- import_module parse_tree.prog_type.
:- import_module parse_tree.prog_type_subst.
:- import_module parse_tree.prog_type_unify.
diff --git a/compiler/type_inst_mode_map.m b/compiler/type_inst_mode_map.m
index b85c9e6a9..4d8b70ad0 100644
--- a/compiler/type_inst_mode_map.m
+++ b/compiler/type_inst_mode_map.m
@@ -19,7 +19,8 @@
:- module parse_tree.type_inst_mode_map.
:- interface.
-:- import_module parse_tree.prog_item.
+:- import_module parse_tree.prog_item_inst_mode.
+:- import_module parse_tree.prog_item_type.
:- import_module list.
diff --git a/compiler/unused_args.m b/compiler/unused_args.m
index da57b8e3f..39cdd61e2 100644
--- a/compiler/unused_args.m
+++ b/compiler/unused_args.m
@@ -52,7 +52,7 @@
:- import_module hlds.hlds_module.
:- import_module parse_tree.
:- import_module parse_tree.error_spec.
-:- import_module parse_tree.prog_item.
+:- import_module parse_tree.prog_item_pragma.
:- import_module transform_hlds.unused_args_warn_pragma.
:- import_module list.
diff --git a/compiler/unused_args_warn_pragma.m b/compiler/unused_args_warn_pragma.m
index f51d17e9e..a7a541dac 100644
--- a/compiler/unused_args_warn_pragma.m
+++ b/compiler/unused_args_warn_pragma.m
@@ -24,7 +24,7 @@
:- import_module hlds.hlds_module.
:- import_module parse_tree.
:- import_module parse_tree.error_spec.
-:- import_module parse_tree.prog_item.
+:- import_module parse_tree.prog_item_pragma.
:- import_module list.
:- import_module set.
@@ -70,6 +70,7 @@
:- import_module mdbcomp.sym_name.
:- import_module parse_tree.parse_tree_out_info.
:- import_module parse_tree.prog_data.
+:- import_module parse_tree.prog_item_pred_proc_id.
:- import_module parse_tree.prog_util.
:- import_module bool.
diff --git a/configure.ac b/configure.ac
index 5551b80a8..9935e28b3 100644
--- a/configure.ac
+++ b/configure.ac
@@ -607,7 +607,7 @@ EOF
$BOOTSTRAP_MC \
--verbose \
$link_static_opt conftest \
- --scout-disj-2025-11-15 \
+ --subtype-int2-2026-08-09 \
--warn-include-and-non-include \
--no-warn-unused-types \
--no-ssdb \