mirror of
https://github.com/Mercury-Language/mercury.git
synced 2026-04-16 18:03:36 +00:00
compiler/prog_type_construct.m:
New module for constructing types.
compiler/prog_type_repn.m:
New module for testing things related to type representation.
compiler/prog_type_scan.m:
New module for gather type vars in types.
compiler/prog_type_test.m:
New module containing simple tests on types.
compiler/prog_type_unify.m:
New module for testing whether two types unify, or whether
one type subsumes another.
compiler/prog_type.m:
Delete the code moved to the new modules.
compiler/parse_tree.m:
Include the new modules.
compiler/notes/compiler_design.html:
Document the new modules.
compiler/*.m:
Conform to the changes above, by adjusting imports as needed,
and by deleting any explicit module qualifications that
this diff makes obsolete.
2732 lines
121 KiB
Mathematica
2732 lines
121 KiB
Mathematica
%---------------------------------------------------------------------------%
|
|
% vim: ft=mercury ts=4 sw=4 et
|
|
%---------------------------------------------------------------------------%
|
|
% Copyright (C) 1996-2012 The University of Melbourne.
|
|
% Copyright (C) 2014-2021 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: equiv_type.m.
|
|
% Main author: fjh.
|
|
%
|
|
% This module contains a parse-tree to parse-tree transformation
|
|
% that expands equivalence types. It also expands away `with_type`
|
|
% and `with_inst` annotations on predicate and function type declarations.
|
|
%
|
|
%---------------------------------------------------------------------------%
|
|
%
|
|
% XXX We do not currently expand out inst definitions.
|
|
%
|
|
% If inst i1's body contains inst i2, and i2 has been defined to be equivalent
|
|
% to some other inst i3, then we *could* replace i2 with i3 in i1's body.
|
|
% Instead of doing this once for this user-defined inst, we do it on every use
|
|
% of this inst. This is significantly less efficient, but if there is
|
|
% any error that involves this inst, the error message we generate will refer
|
|
% to the inst by the name the user gave it. If the user e.g. wrote an inst i1
|
|
% in a mode declaration, but an error message about that mode declaration
|
|
% referred to the expanded form of i1, this would be confusing to many
|
|
% programmers. Most likely, it would also be harder to read, since
|
|
% inst names are almost always shorter than the insts they are defined
|
|
% to be equivalent to.
|
|
%
|
|
% XXX INST_FOR_TYPE_CONSTRUCTOR
|
|
% If inst i1 is for type t2, and t2 has been defined to be equivalent
|
|
% to type t3, then we SHOULD record that i1 is really for t3.
|
|
% However, while t2 is required to be just a type_ctor and arity,
|
|
% t3 may be more complex. The obvious thing to do would be to record that
|
|
% i1 is for t3's top type_ctor and its arity. Whether that is good enough
|
|
% depends on what *exactly* we will do with the "inst for type ctor"
|
|
% information. We don't yet know the answer to that question.
|
|
% XXX This should allow us to fix Mantis bug #89.
|
|
%
|
|
% XXX We do not currently expand out mode definitions either,
|
|
% even though the first paragraph above definitely applies to them as well,
|
|
% and if we ever extend the language to allow (and maybe even require)
|
|
% programmers to record "mode for type constructor" information,
|
|
% the second paragraph will apply as well.
|
|
%
|
|
%---------------------------------------------------------------------------%
|
|
%
|
|
% XXX We do not currently expand out clauses.
|
|
% This will leave any with_type annotations in clauses unexpanded.
|
|
% XXX This applies both to clauses that define predicates and functions,
|
|
% and to clauses that define instance methods.
|
|
%
|
|
%---------------------------------------------------------------------------%
|
|
%
|
|
% XXX A big comment on an commented-out import of hlds.pred_table
|
|
% in hlds_out_module.m explores in detail a problem with the operation
|
|
% of this module.
|
|
%
|
|
%---------------------------------------------------------------------------%
|
|
|
|
:- module parse_tree.equiv_type.
|
|
:- interface.
|
|
|
|
:- import_module libs.
|
|
:- import_module libs.maybe_util.
|
|
:- import_module parse_tree.error_spec.
|
|
:- import_module parse_tree.prog_data.
|
|
:- import_module parse_tree.prog_data_event.
|
|
:- import_module parse_tree.prog_data_used_modules.
|
|
:- import_module parse_tree.prog_item.
|
|
:- import_module recompilation.
|
|
|
|
:- import_module list.
|
|
:- import_module map.
|
|
:- import_module maybe.
|
|
:- import_module one_or_more.
|
|
|
|
%---------------------------------------------------------------------------%
|
|
|
|
% expand_eqv_types_insts(!AugCompUnit, !EventSpecMap,
|
|
% CircularTypes, TypeEqvMap, !MaybeRecompInfo, Specs):
|
|
%
|
|
% This predicate finds all type and inst declarations that define a type
|
|
% or inst to be equivalent to another type or inst. It builds up two maps
|
|
% of such declarations, and then traverses through all the items in the
|
|
% given item blocks and through all the given event specs, expanding all
|
|
% type and inst synonyms, which has the effect of eliminating all the
|
|
% equivalence types and insts from the source code. We return the
|
|
% equivalence map for types (our callers don't need the corresponding map
|
|
% for insts).
|
|
%
|
|
% It also expands `with_type` and `with_inst` annotations on predicate and
|
|
% function type declarations.
|
|
%
|
|
% It generates error messages for any circular equivalence types and insts
|
|
% and for invalid `with_type` and `with_inst` annotations.
|
|
%
|
|
% For items not defined in the current module, the items expanded
|
|
% while processing each item are recorded in the recompilation_info,
|
|
% for use by smart recompilation.
|
|
%
|
|
:- pred expand_eqv_types_insts(
|
|
aug_compilation_unit::in, aug_compilation_unit::out,
|
|
event_spec_map::in, event_spec_map::out,
|
|
type_eqv_map::out, used_modules::out,
|
|
maybe(recompilation_info)::in, maybe(recompilation_info)::out,
|
|
list(error_spec)::out) is det.
|
|
|
|
% Replace equivalence types in the representation of an equivalence type.
|
|
% Generate an error message if the expansion reveals that the definition
|
|
% is circular.
|
|
%
|
|
:- pred replace_in_type_repn_eqv(type_eqv_map::in,
|
|
item_type_repn_info_eqv::in, item_type_repn_info_eqv::out,
|
|
list(error_spec)::in, list(error_spec)::out) is det.
|
|
|
|
% Replace all equivalence types in a given type, reporting
|
|
% any circularities, and whether the type has changed.
|
|
%
|
|
:- pred replace_in_type_report_circular_eqvs(type_eqv_map::in, tvarset::in,
|
|
prog_context::in, mer_type::in, mer_type::out, maybe_changed::out,
|
|
list(error_spec)::in, list(error_spec)::out) is det.
|
|
|
|
% Replace equivalence types in a given type.
|
|
% The bool output is `yes' if anything changed.
|
|
%
|
|
:- pred replace_in_type(type_eqv_map::in, mer_type::in, mer_type::out,
|
|
maybe_changed::out, tvarset::in, tvarset::out,
|
|
eqv_expand_info::in, eqv_expand_info::out) is det.
|
|
|
|
:- pred replace_in_type_list(type_eqv_map::in,
|
|
list(mer_type)::in, list(mer_type)::out, maybe_changed::out,
|
|
tvarset::in, tvarset::out,
|
|
eqv_expand_info::in, eqv_expand_info::out) is det.
|
|
|
|
:- pred replace_in_prog_constraints(type_eqv_map::in,
|
|
prog_constraints::in, prog_constraints::out, tvarset::in, tvarset::out,
|
|
eqv_expand_info::in, eqv_expand_info::out) is det.
|
|
|
|
:- pred replace_in_prog_constraint_list(type_eqv_map::in,
|
|
list(prog_constraint)::in, list(prog_constraint)::out,
|
|
tvarset::in, tvarset::out, eqv_expand_info::in, eqv_expand_info::out)
|
|
is det.
|
|
|
|
:- pred replace_in_ctors(type_eqv_map::in,
|
|
one_or_more(constructor)::in, one_or_more(constructor)::out,
|
|
tvarset::in, tvarset::out,
|
|
eqv_expand_info::in, eqv_expand_info::out) is det.
|
|
|
|
:- type eqv_type_body
|
|
---> eqv_type_body(
|
|
tvarset,
|
|
list(type_param),
|
|
mer_type
|
|
).
|
|
|
|
:- type type_eqv_map == map(type_ctor, eqv_type_body).
|
|
|
|
%---------------------------------------------------------------------------%
|
|
%---------------------------------------------------------------------------%
|
|
|
|
:- implementation.
|
|
|
|
:- import_module mdbcomp.
|
|
:- import_module mdbcomp.prim_data.
|
|
:- import_module mdbcomp.sym_name.
|
|
:- import_module parse_tree.builtin_lib_types.
|
|
:- import_module parse_tree.parse_tree_out_type.
|
|
:- import_module parse_tree.prog_data_foreign.
|
|
:- import_module parse_tree.prog_data_pragma.
|
|
:- import_module parse_tree.prog_mode.
|
|
:- import_module parse_tree.prog_type.
|
|
:- import_module parse_tree.prog_type_construct.
|
|
:- import_module parse_tree.prog_type_subst.
|
|
:- import_module parse_tree.prog_type_test.
|
|
:- import_module parse_tree.prog_util.
|
|
|
|
:- import_module assoc_list.
|
|
:- import_module bool.
|
|
:- import_module pair.
|
|
:- import_module require.
|
|
:- import_module set.
|
|
:- import_module term.
|
|
:- import_module varset.
|
|
|
|
:- type circ_types == set(type_ctor).
|
|
|
|
%---------------------------------------------------------------------------%
|
|
%---------------------------------------------------------------------------%
|
|
|
|
expand_eqv_types_insts(AugCompUnit0, AugCompUnit, EventSpecMap0, EventSpecMap,
|
|
TypeEqvMap, !:UsedModules, !RecompInfo, !:Specs) :-
|
|
AugCompUnit0 = aug_compilation_unit(ParseTreeModuleSrc0,
|
|
AncestorIntSpecs0, DirectInt1Specs0, IndirectInt2Specs0,
|
|
PlainOpts0, TransOpts0, IntForOptSpecs0, TypeRepnSpecs0,
|
|
ModuleVersionNumbers),
|
|
ModuleName = ParseTreeModuleSrc0 ^ ptms_module_name,
|
|
% First we build up a mapping which records the equivalence type
|
|
% definitions, ...
|
|
some [!TypeEqvMap, !InstEqvMap] (
|
|
map.init(!:TypeEqvMap),
|
|
map.init(!:InstEqvMap),
|
|
build_eqv_maps_in_parse_tree_module_src(ParseTreeModuleSrc0,
|
|
!TypeEqvMap, !InstEqvMap),
|
|
map.foldl2_values(build_eqv_maps_in_ancestor_int_spec,
|
|
AncestorIntSpecs0,
|
|
!TypeEqvMap, !InstEqvMap),
|
|
map.foldl2_values(build_eqv_maps_in_direct_int1_spec,
|
|
DirectInt1Specs0,
|
|
!TypeEqvMap, !InstEqvMap),
|
|
map.foldl2_values(build_eqv_maps_in_indirect_int2_spec,
|
|
IndirectInt2Specs0,
|
|
!TypeEqvMap, !InstEqvMap),
|
|
map.foldl2_values(build_eqv_maps_in_parse_tree_plain_opt, PlainOpts0,
|
|
!TypeEqvMap, !InstEqvMap),
|
|
map.foldl2_values(build_eqv_maps_in_parse_tree_trans_opt, TransOpts0,
|
|
!TypeEqvMap, !InstEqvMap),
|
|
map.foldl2_values(build_eqv_maps_in_int_for_opt_spec, IntForOptSpecs0,
|
|
!TypeEqvMap, !InstEqvMap),
|
|
TypeEqvMap = !.TypeEqvMap,
|
|
InstEqvMap = !.InstEqvMap
|
|
),
|
|
|
|
% .. and then we go through all the items in the relevant blocks
|
|
% and in all the event specs, and replace all occurrences of
|
|
% equivalence types and insts in them.
|
|
!:UsedModules = used_modules_init,
|
|
!:Specs = [],
|
|
replace_in_parse_tree_module_src(TypeEqvMap, InstEqvMap,
|
|
ParseTreeModuleSrc0, ParseTreeModuleSrc,
|
|
!RecompInfo, !UsedModules, !Specs),
|
|
map.map_values_foldl3(
|
|
replace_in_ancestor_int_spec(ModuleName, TypeEqvMap, InstEqvMap),
|
|
AncestorIntSpecs0, AncestorIntSpecs,
|
|
!RecompInfo, !UsedModules, !Specs),
|
|
map.map_values_foldl3(
|
|
replace_in_direct_int1_spec(ModuleName, TypeEqvMap, InstEqvMap),
|
|
DirectInt1Specs0, DirectInt1Specs, !RecompInfo, !UsedModules, !Specs),
|
|
map.map_values_foldl3(
|
|
replace_in_indirect_int2_spec(ModuleName, TypeEqvMap, InstEqvMap),
|
|
IndirectInt2Specs0, IndirectInt2Specs,
|
|
!RecompInfo, !UsedModules, !Specs),
|
|
map.map_values_foldl3(
|
|
replace_in_parse_tree_trans_opt(ModuleName, TypeEqvMap, InstEqvMap),
|
|
TransOpts0, TransOpts, !RecompInfo, !UsedModules, !Specs),
|
|
map.map_values_foldl3(
|
|
replace_in_parse_tree_plain_opt(ModuleName, TypeEqvMap, InstEqvMap),
|
|
PlainOpts0, PlainOpts, !RecompInfo, !UsedModules, !Specs),
|
|
map.map_values_foldl3(
|
|
replace_in_int_for_opt_spec(ModuleName, TypeEqvMap, InstEqvMap),
|
|
IntForOptSpecs0, IntForOptSpecs, !RecompInfo, !UsedModules, !Specs),
|
|
|
|
% XXX TYPE_REPN Type repns items should be generated fully eqv-expanded,
|
|
% but it may be worth while checking whether this is really so.
|
|
TypeRepnSpecs = TypeRepnSpecs0,
|
|
AugCompUnit = aug_compilation_unit(ParseTreeModuleSrc,
|
|
AncestorIntSpecs, DirectInt1Specs, IndirectInt2Specs,
|
|
PlainOpts, TransOpts, IntForOptSpecs, TypeRepnSpecs,
|
|
ModuleVersionNumbers),
|
|
|
|
map.to_assoc_list(EventSpecMap0, EventSpecList0),
|
|
replace_in_event_specs(TypeEqvMap, EventSpecList0, EventSpecList,
|
|
!RecompInfo, !UsedModules, !Specs),
|
|
map.from_sorted_assoc_list(EventSpecList, EventSpecMap).
|
|
|
|
%---------------------------------------------------------------------------%
|
|
|
|
% We need to expand equivalence insts in
|
|
% `:- pred p `with_inst` i' declarations.
|
|
:- type eqv_inst_body
|
|
---> eqv_inst_body(
|
|
list(inst_var),
|
|
mer_inst
|
|
).
|
|
|
|
:- type inst_eqv_map == map(inst_ctor, eqv_inst_body).
|
|
|
|
%---------------------------------------------------------------------------%
|
|
|
|
:- pred build_eqv_maps_in_parse_tree_module_src(parse_tree_module_src::in,
|
|
type_eqv_map::in, type_eqv_map::out,
|
|
inst_eqv_map::in, inst_eqv_map::out) is det.
|
|
|
|
build_eqv_maps_in_parse_tree_module_src(ParseTreeModuleSrc,
|
|
!TypeEqvMap, !InstEqvMap) :-
|
|
map.foldl(build_eqv_maps_in_type_ctor_checked_defns_int_imp,
|
|
ParseTreeModuleSrc ^ ptms_type_defns, !TypeEqvMap),
|
|
map.foldl(build_eqv_maps_in_inst_ctor_checked_defns_int_imp,
|
|
ParseTreeModuleSrc ^ ptms_inst_defns, !InstEqvMap).
|
|
|
|
%---------------------%
|
|
|
|
:- pred build_eqv_maps_in_ancestor_int_spec(ancestor_int_spec::in,
|
|
type_eqv_map::in, type_eqv_map::out,
|
|
inst_eqv_map::in, inst_eqv_map::out) is det.
|
|
|
|
build_eqv_maps_in_ancestor_int_spec(AncestorIntSpec,
|
|
!TypeEqvMap, !InstEqvMap) :-
|
|
AncestorIntSpec = ancestor_int0(ParseTreeInt0, ReadWhy0),
|
|
build_eqv_maps_in_parse_tree_int0(ReadWhy0, ParseTreeInt0,
|
|
!TypeEqvMap, !InstEqvMap).
|
|
|
|
:- pred build_eqv_maps_in_direct_int1_spec(direct_int1_spec::in,
|
|
type_eqv_map::in, type_eqv_map::out,
|
|
inst_eqv_map::in, inst_eqv_map::out) is det.
|
|
|
|
build_eqv_maps_in_direct_int1_spec(DirectIntSpec,
|
|
!TypeEqvMap, !InstEqvMap) :-
|
|
DirectIntSpec = direct_int1(ParseTreeInt1, ReadWhy1),
|
|
build_eqv_maps_in_parse_tree_int1(ReadWhy1, ParseTreeInt1,
|
|
!TypeEqvMap, !InstEqvMap).
|
|
|
|
:- pred build_eqv_maps_in_indirect_int2_spec(indirect_int2_spec::in,
|
|
type_eqv_map::in, type_eqv_map::out,
|
|
inst_eqv_map::in, inst_eqv_map::out) is det.
|
|
|
|
build_eqv_maps_in_indirect_int2_spec(IndirectIntSpec,
|
|
!TypeEqvMap, !InstEqvMap) :-
|
|
IndirectIntSpec = indirect_int2(ParseTreeInt2, ReadWhy2),
|
|
build_eqv_maps_in_parse_tree_int2(ReadWhy2, ParseTreeInt2,
|
|
!TypeEqvMap, !InstEqvMap).
|
|
|
|
:- pred build_eqv_maps_in_int_for_opt_spec(int_for_opt_spec::in,
|
|
type_eqv_map::in, type_eqv_map::out,
|
|
inst_eqv_map::in, inst_eqv_map::out) is det.
|
|
|
|
build_eqv_maps_in_int_for_opt_spec(IntForOptSpec, !TypeEqvMap, !InstEqvMap) :-
|
|
(
|
|
IntForOptSpec = for_opt_int0(ParseTreeInt0, ReadWhy0),
|
|
build_eqv_maps_in_parse_tree_int0(ReadWhy0, ParseTreeInt0,
|
|
!TypeEqvMap, !InstEqvMap)
|
|
;
|
|
IntForOptSpec = for_opt_int1(ParseTreeInt1, ReadWhy1),
|
|
build_eqv_maps_in_parse_tree_int1(ReadWhy1, ParseTreeInt1,
|
|
!TypeEqvMap, !InstEqvMap)
|
|
;
|
|
IntForOptSpec = for_opt_int2(ParseTreeInt2, ReadWhy2),
|
|
build_eqv_maps_in_parse_tree_int2(ReadWhy2, ParseTreeInt2,
|
|
!TypeEqvMap, !InstEqvMap)
|
|
).
|
|
|
|
%---------------------%
|
|
|
|
:- pred build_eqv_maps_in_parse_tree_int0(read_why_int0::in,
|
|
parse_tree_int0::in,
|
|
type_eqv_map::in, type_eqv_map::out,
|
|
inst_eqv_map::in, inst_eqv_map::out) is det.
|
|
|
|
build_eqv_maps_in_parse_tree_int0(_ReadWhy0, ParseTreeInt0,
|
|
!TypeEqvMap, !InstEqvMap) :-
|
|
% All possible values of _ReadWhy0 call for things in both
|
|
% the interface and the implementation sections to be imported
|
|
% in a non-abstract form.
|
|
map.foldl(build_eqv_maps_in_type_ctor_checked_defns_int_imp,
|
|
ParseTreeInt0 ^ pti0_type_defns, !TypeEqvMap),
|
|
map.foldl(build_eqv_maps_in_inst_ctor_checked_defns_int_imp,
|
|
ParseTreeInt0 ^ pti0_inst_defns, !InstEqvMap).
|
|
|
|
:- pred build_eqv_maps_in_parse_tree_int1(read_why_int1::in,
|
|
parse_tree_int1::in,
|
|
type_eqv_map::in, type_eqv_map::out,
|
|
inst_eqv_map::in, inst_eqv_map::out) is det.
|
|
|
|
build_eqv_maps_in_parse_tree_int1(_ReadWhy1, ParseTreeInt1,
|
|
!TypeEqvMap, !InstEqvMap) :-
|
|
% All possible values of _ReadWhy1 call for things in the interface section
|
|
% to be imported in a non-abstract form, and for things in the
|
|
% implementation section to be imported in an abstract form.
|
|
map.foldl(build_eqv_maps_in_type_ctor_checked_defns_int,
|
|
ParseTreeInt1 ^ pti1_type_defns, !TypeEqvMap),
|
|
% Do not allow the expansion of abstract-imported type definitions.
|
|
% list.foldl(build_eqv_maps_in_type_ctor_all_defns,
|
|
% map.values(ParseTreeInt1 ^ pti1_imp_type_defns), !TypeEqvMap),
|
|
map.foldl(build_eqv_maps_in_inst_ctor_checked_defns_int,
|
|
ParseTreeInt1 ^ pti1_inst_defns, !InstEqvMap).
|
|
|
|
:- pred build_eqv_maps_in_parse_tree_int2(read_why_int2::in,
|
|
parse_tree_int2::in,
|
|
type_eqv_map::in, type_eqv_map::out,
|
|
inst_eqv_map::in, inst_eqv_map::out) is det.
|
|
|
|
build_eqv_maps_in_parse_tree_int2(ReadWhy2, ParseTreeInt2,
|
|
!TypeEqvMap, !InstEqvMap) :-
|
|
% Some values of ReadWhy2 call for things in the interface section
|
|
% to be imported in a non-abstract form, while others call for them
|
|
% to be imported in an abstract form.
|
|
%
|
|
% All possible values of ReadWhy2 call for things in the implementation
|
|
% section to be imported in an abstract form.
|
|
(
|
|
ReadWhy2 = rwi2_abstract
|
|
;
|
|
( ReadWhy2 = rwi2_int_use
|
|
; ReadWhy2 = rwi2_imp_use
|
|
; ReadWhy2 = rwi2_opt
|
|
),
|
|
map.foldl(build_eqv_maps_in_type_ctor_checked_defns_int,
|
|
ParseTreeInt2 ^ pti2_type_defns, !TypeEqvMap),
|
|
map.foldl(build_eqv_maps_in_inst_ctor_checked_defns_int,
|
|
ParseTreeInt2 ^ pti2_inst_defns, !InstEqvMap)
|
|
).
|
|
|
|
%---------------------%
|
|
|
|
:- pred build_eqv_maps_in_parse_tree_plain_opt(parse_tree_plain_opt::in,
|
|
type_eqv_map::in, type_eqv_map::out,
|
|
inst_eqv_map::in, inst_eqv_map::out) is det.
|
|
|
|
build_eqv_maps_in_parse_tree_plain_opt(ParseTreePlainOpt,
|
|
!TypeEqvMap, !InstEqvMap) :-
|
|
list.foldl(build_eqv_maps_in_type_defn,
|
|
ParseTreePlainOpt ^ ptpo_type_defns, !TypeEqvMap),
|
|
list.foldl(build_eqv_maps_in_inst_defn,
|
|
ParseTreePlainOpt ^ ptpo_inst_defns, !InstEqvMap).
|
|
|
|
:- pred build_eqv_maps_in_parse_tree_trans_opt(parse_tree_trans_opt::in,
|
|
type_eqv_map::in, type_eqv_map::out,
|
|
inst_eqv_map::in, inst_eqv_map::out) is det.
|
|
|
|
build_eqv_maps_in_parse_tree_trans_opt(_ParseTreePlainOpt,
|
|
!TypeEqvMap, !InstEqvMap).
|
|
% .trans_opt files can contain neither type nor inst definitions.
|
|
|
|
%---------------------%
|
|
|
|
:- pred build_eqv_maps_in_type_defn(item_type_defn_info::in,
|
|
type_eqv_map::in, type_eqv_map::out) is det.
|
|
|
|
build_eqv_maps_in_type_defn(ItemTypeDefn, !TypeEqvMap) :-
|
|
ItemTypeDefn = item_type_defn_info(Name, TypeParams, TypeDefn,
|
|
TVarSet, _Context, _SeqNum),
|
|
( if TypeDefn = parse_tree_eqv_type(type_details_eqv(EqvType)) then
|
|
list.length(TypeParams, Arity),
|
|
TypeCtor = type_ctor(Name, Arity),
|
|
map.set(TypeCtor, eqv_type_body(TVarSet, TypeParams, EqvType),
|
|
!TypeEqvMap)
|
|
else
|
|
true
|
|
).
|
|
|
|
:- pred build_eqv_maps_in_type_ctor_checked_defns_int_imp(type_ctor::in,
|
|
type_ctor_checked_defn::in,
|
|
type_eqv_map::in, type_eqv_map::out) is det.
|
|
|
|
build_eqv_maps_in_type_ctor_checked_defns_int_imp(TypeCtor, CheckedDefn,
|
|
!TypeEqvMap) :-
|
|
(
|
|
CheckedDefn = checked_defn_solver(_, _)
|
|
;
|
|
CheckedDefn = checked_defn_std(StdTypeDefn, _SrcDefns),
|
|
(
|
|
StdTypeDefn = std_mer_type_eqv(_Status, ItemTypeDefnEqv),
|
|
ItemTypeDefnEqv = item_type_defn_info(_Name, TypeParams,
|
|
TypeDefn, TVarSet, _Context, _SeqNum),
|
|
TypeDefn = type_details_eqv(EqvType),
|
|
map.set(TypeCtor, eqv_type_body(TVarSet, TypeParams, EqvType),
|
|
!TypeEqvMap)
|
|
;
|
|
( StdTypeDefn = std_mer_type_subtype(_, _)
|
|
; StdTypeDefn = std_mer_type_du_all_plain_constants(_, _, _, _, _)
|
|
; StdTypeDefn = std_mer_type_du_not_all_plain_constants(_, _, _)
|
|
; StdTypeDefn = std_mer_type_abstract(_, _, _)
|
|
)
|
|
)
|
|
).
|
|
|
|
:- pred build_eqv_maps_in_type_ctor_checked_defns_int(type_ctor::in,
|
|
type_ctor_checked_defn::in,
|
|
type_eqv_map::in, type_eqv_map::out) is det.
|
|
|
|
build_eqv_maps_in_type_ctor_checked_defns_int(TypeCtor, CheckedDefn,
|
|
!TypeEqvMap) :-
|
|
(
|
|
CheckedDefn = checked_defn_solver(_, _)
|
|
;
|
|
CheckedDefn = checked_defn_std(StdTypeDefn, _SrcDefns),
|
|
(
|
|
StdTypeDefn = std_mer_type_eqv(Status, ItemTypeDefnEqv),
|
|
(
|
|
Status = std_eqv_type_mer_exported,
|
|
ItemTypeDefnEqv = item_type_defn_info(_Name, TypeParams,
|
|
TypeDefn, TVarSet, _Context, _SeqNum),
|
|
TypeDefn = type_details_eqv(EqvType),
|
|
map.set(TypeCtor, eqv_type_body(TVarSet, TypeParams, EqvType),
|
|
!TypeEqvMap)
|
|
;
|
|
( Status = std_eqv_type_abstract_exported
|
|
; Status = std_eqv_type_all_private
|
|
)
|
|
)
|
|
;
|
|
( StdTypeDefn = std_mer_type_subtype(_, _)
|
|
; StdTypeDefn = std_mer_type_du_all_plain_constants(_, _, _, _, _)
|
|
; StdTypeDefn = std_mer_type_du_not_all_plain_constants(_, _, _)
|
|
; StdTypeDefn = std_mer_type_abstract(_, _, _)
|
|
)
|
|
)
|
|
).
|
|
|
|
%---------------------%
|
|
|
|
:- pred build_eqv_maps_in_inst_defn(item_inst_defn_info::in,
|
|
inst_eqv_map::in, inst_eqv_map::out) is det.
|
|
|
|
build_eqv_maps_in_inst_defn(ItemInstDefn, !InstEqvMap) :-
|
|
ItemInstDefn = item_inst_defn_info(Name, InstParams, _IFTC,
|
|
InstDefn, _InstVarSet, _Context, _SeqNum),
|
|
( if InstDefn = nonabstract_inst_defn(eqv_inst(EqvInst)) then
|
|
list.length(InstParams, Arity),
|
|
InstCtor = inst_ctor(Name, Arity),
|
|
map.set(InstCtor, eqv_inst_body(InstParams, EqvInst), !InstEqvMap)
|
|
else
|
|
true
|
|
).
|
|
|
|
:- pred build_eqv_maps_in_inst_ctor_checked_defns_int_imp(inst_ctor::in,
|
|
inst_ctor_checked_defn::in,
|
|
inst_eqv_map::in, inst_eqv_map::out) is det.
|
|
|
|
build_eqv_maps_in_inst_ctor_checked_defns_int_imp(InstCtor, CheckedDefn,
|
|
!InstEqvMap) :-
|
|
CheckedDefn = checked_defn_inst(StdInstDefn, _SrcDefns),
|
|
StdInstDefn = std_inst_defn(_Status, ItemInstDefn),
|
|
ItemInstDefn = item_inst_defn_info(_Name, InstParams, _MaybeForType,
|
|
MaybeAbstractInstDefn, _InstVarSet, _Context, _SeqNum),
|
|
(
|
|
MaybeAbstractInstDefn = abstract_inst_defn
|
|
;
|
|
MaybeAbstractInstDefn = nonabstract_inst_defn(InstDefn),
|
|
InstDefn = eqv_inst(EqvInst),
|
|
map.set(InstCtor, eqv_inst_body(InstParams, EqvInst), !InstEqvMap)
|
|
).
|
|
|
|
:- pred build_eqv_maps_in_inst_ctor_checked_defns_int(inst_ctor::in,
|
|
inst_ctor_checked_defn::in,
|
|
inst_eqv_map::in, inst_eqv_map::out) is det.
|
|
|
|
build_eqv_maps_in_inst_ctor_checked_defns_int(InstCtor, CheckedDefn,
|
|
!InstEqvMap) :-
|
|
CheckedDefn = checked_defn_inst(StdInstDefn, _SrcDefns),
|
|
StdInstDefn = std_inst_defn(Status, ItemInstDefn),
|
|
ItemInstDefn = item_inst_defn_info(_Name, InstParams, _MaybeForType,
|
|
MaybeAbstractInstDefn, _InstVarSet, _Context, _SeqNum),
|
|
(
|
|
MaybeAbstractInstDefn = abstract_inst_defn
|
|
;
|
|
MaybeAbstractInstDefn = nonabstract_inst_defn(InstDefn),
|
|
(
|
|
Status = std_inst_exported,
|
|
InstDefn = eqv_inst(EqvInst),
|
|
map.set(InstCtor, eqv_inst_body(InstParams, EqvInst), !InstEqvMap)
|
|
;
|
|
( Status = std_inst_abstract_exported
|
|
; Status = std_inst_all_private
|
|
)
|
|
)
|
|
).
|
|
|
|
%---------------------------------------------------------------------------%
|
|
|
|
:- pred replace_in_parse_tree_module_src(type_eqv_map::in, inst_eqv_map::in,
|
|
parse_tree_module_src::in, parse_tree_module_src::out,
|
|
maybe(recompilation_info)::in, maybe(recompilation_info)::out,
|
|
used_modules::in, used_modules::out,
|
|
list(error_spec)::in, list(error_spec)::out) is det.
|
|
|
|
replace_in_parse_tree_module_src(TypeEqvMap, InstEqvMap,
|
|
ParseTreeModuleSrc0, ParseTreeModuleSrc,
|
|
!RecompInfo, !UsedModules, !Specs) :-
|
|
MaybeRecordInt = record_sym_name_use(visibility_public),
|
|
MaybeRecordImp = record_sym_name_use(visibility_private),
|
|
|
|
ParseTreeModuleSrc0 = parse_tree_module_src(ModuleName, ModuleNameContext,
|
|
InclMap, ImportUseMap,
|
|
IntFIMSpecMap, ImpFIMSpecMap, IntSelfFIMLangs, ImpSelfFIMLangs,
|
|
|
|
TypeCtorCheckedMap0, InstCtorCheckedMap0, ModeCtorCheckedMap0,
|
|
TypeSpecs, InstModeSpecs,
|
|
|
|
IntTypeClasses0, IntInstances0, IntPredDecls0, IntModeDecls0,
|
|
IntDeclPragmas0, IntDeclMarkers, IntPromises, IntBadPreds,
|
|
|
|
ImpTypeClasses0, ImpInstances0, ImpPredDecls0, ImpModeDecls0,
|
|
ImpClauses0, ImpForeignProcs0, ImpForeignExportEnums,
|
|
ImpDeclPragmas0, ImpDeclMarkers, ImpImplPragmas, ImpImplMarkers,
|
|
ImpPromises, ImpInitialises, ImpFinalises, ImpMutables0),
|
|
|
|
map.map_values_foldl3(
|
|
replace_in_type_ctor_checked_defn(ModuleName,
|
|
MaybeRecordInt, MaybeRecordImp, TypeEqvMap, InstEqvMap),
|
|
TypeCtorCheckedMap0, TypeCtorCheckedMap,
|
|
!RecompInfo, !UsedModules, !Specs),
|
|
% XXX See the comment at module top.
|
|
InstCtorCheckedMap = InstCtorCheckedMap0,
|
|
ModeCtorCheckedMap = ModeCtorCheckedMap0,
|
|
|
|
replace_in_list(ModuleName, MaybeRecordInt, TypeEqvMap, InstEqvMap,
|
|
replace_in_typeclass_info, IntTypeClasses0, IntTypeClasses,
|
|
!RecompInfo, !UsedModules, !Specs),
|
|
replace_in_list(ModuleName, MaybeRecordInt, TypeEqvMap, InstEqvMap,
|
|
replace_in_instance_info, IntInstances0, IntInstances,
|
|
!RecompInfo, !UsedModules, !Specs),
|
|
replace_in_list(ModuleName, MaybeRecordInt, TypeEqvMap, InstEqvMap,
|
|
replace_in_pred_decl_info, IntPredDecls0, IntPredDecls,
|
|
!RecompInfo, !UsedModules, !Specs),
|
|
replace_in_list(ModuleName, MaybeRecordInt, TypeEqvMap, InstEqvMap,
|
|
replace_in_mode_decl_info, IntModeDecls0, IntModeDecls,
|
|
!RecompInfo, !UsedModules, !Specs),
|
|
replace_in_list(ModuleName, MaybeRecordInt, TypeEqvMap, InstEqvMap,
|
|
replace_in_decl_pragma_info, IntDeclPragmas0, IntDeclPragmas,
|
|
!RecompInfo, !UsedModules, !Specs),
|
|
|
|
replace_in_list(ModuleName, MaybeRecordImp, TypeEqvMap, InstEqvMap,
|
|
replace_in_typeclass_info, ImpTypeClasses0, ImpTypeClasses,
|
|
!RecompInfo, !UsedModules, !Specs),
|
|
replace_in_list(ModuleName, MaybeRecordImp, TypeEqvMap, InstEqvMap,
|
|
replace_in_instance_info, ImpInstances0, ImpInstances,
|
|
!RecompInfo, !UsedModules, !Specs),
|
|
replace_in_list(ModuleName, MaybeRecordImp, TypeEqvMap, InstEqvMap,
|
|
replace_in_pred_decl_info, ImpPredDecls0, ImpPredDecls,
|
|
!RecompInfo, !UsedModules, !Specs),
|
|
replace_in_list(ModuleName, MaybeRecordImp, TypeEqvMap, InstEqvMap,
|
|
replace_in_mode_decl_info, ImpModeDecls0, ImpModeDecls,
|
|
!RecompInfo, !UsedModules, !Specs),
|
|
ImpClauses = ImpClauses0, % XXX See the comment at module top.
|
|
replace_in_list(ModuleName, MaybeRecordImp, TypeEqvMap, InstEqvMap,
|
|
replace_in_decl_pragma_info, ImpDeclPragmas0, ImpDeclPragmas,
|
|
!RecompInfo, !UsedModules, !Specs),
|
|
replace_in_list(ModuleName, MaybeRecordImp, TypeEqvMap, InstEqvMap,
|
|
replace_in_foreign_proc, ImpForeignProcs0, ImpForeignProcs,
|
|
!RecompInfo, !UsedModules, !Specs),
|
|
replace_in_list(ModuleName, MaybeRecordImp, TypeEqvMap, InstEqvMap,
|
|
replace_in_mutable_info, ImpMutables0, ImpMutables,
|
|
!RecompInfo, !UsedModules, !Specs),
|
|
|
|
ParseTreeModuleSrc = parse_tree_module_src(ModuleName, ModuleNameContext,
|
|
InclMap, ImportUseMap,
|
|
IntFIMSpecMap, ImpFIMSpecMap, IntSelfFIMLangs, ImpSelfFIMLangs,
|
|
|
|
TypeCtorCheckedMap, InstCtorCheckedMap, ModeCtorCheckedMap,
|
|
TypeSpecs, InstModeSpecs,
|
|
|
|
IntTypeClasses, IntInstances, IntPredDecls, IntModeDecls,
|
|
IntDeclPragmas, IntDeclMarkers, IntPromises, IntBadPreds,
|
|
|
|
ImpTypeClasses, ImpInstances, ImpPredDecls, ImpModeDecls,
|
|
ImpClauses, ImpForeignProcs, ImpForeignExportEnums,
|
|
ImpDeclPragmas, ImpDeclMarkers, ImpImplPragmas, ImpImplMarkers,
|
|
ImpPromises, ImpInitialises, ImpFinalises, ImpMutables).
|
|
|
|
:- pred replace_in_ancestor_int_spec(module_name::in,
|
|
type_eqv_map::in, inst_eqv_map::in,
|
|
ancestor_int_spec::in, ancestor_int_spec::out,
|
|
maybe(recompilation_info)::in, maybe(recompilation_info)::out,
|
|
used_modules::in, used_modules::out,
|
|
list(error_spec)::in, list(error_spec)::out) is det.
|
|
|
|
replace_in_ancestor_int_spec(ModuleName, TypeEqvMap, InstEqvMap,
|
|
AncestorIntSpec0, AncestorIntSpec, !RecompInfo, !UsedModules,
|
|
!Specs) :-
|
|
AncestorIntSpec0 = ancestor_int0(OrigParseTree0, ReadWhy0),
|
|
replace_in_parse_tree_int0(ModuleName, TypeEqvMap, InstEqvMap,
|
|
OrigParseTree0, ParseTree0, !RecompInfo, !UsedModules, !Specs),
|
|
AncestorIntSpec = ancestor_int0(ParseTree0, ReadWhy0).
|
|
|
|
:- pred replace_in_direct_int1_spec(module_name::in,
|
|
type_eqv_map::in, inst_eqv_map::in,
|
|
direct_int1_spec::in, direct_int1_spec::out,
|
|
maybe(recompilation_info)::in, maybe(recompilation_info)::out,
|
|
used_modules::in, used_modules::out,
|
|
list(error_spec)::in, list(error_spec)::out) is det.
|
|
|
|
replace_in_direct_int1_spec(ModuleName, TypeEqvMap, InstEqvMap,
|
|
DirectIntSpec0, DirectIntSpec, !RecompInfo, !UsedModules, !Specs) :-
|
|
DirectIntSpec0 = direct_int1(OrigParseTree1, ReadWhy1),
|
|
replace_in_parse_tree_int1(ModuleName, TypeEqvMap, InstEqvMap,
|
|
OrigParseTree1, ParseTree1, !RecompInfo, !UsedModules, !Specs),
|
|
DirectIntSpec = direct_int1(ParseTree1, ReadWhy1).
|
|
|
|
:- pred replace_in_indirect_int2_spec(module_name::in,
|
|
type_eqv_map::in, inst_eqv_map::in,
|
|
indirect_int2_spec::in, indirect_int2_spec::out,
|
|
maybe(recompilation_info)::in, maybe(recompilation_info)::out,
|
|
used_modules::in, used_modules::out,
|
|
list(error_spec)::in, list(error_spec)::out) is det.
|
|
|
|
replace_in_indirect_int2_spec(ModuleName, TypeEqvMap, InstEqvMap,
|
|
IndirectIntSpec0, IndirectIntSpec,
|
|
!RecompInfo, !UsedModules, !Specs) :-
|
|
IndirectIntSpec0 = indirect_int2(OrigParseTree2, ReadWhy2),
|
|
replace_in_parse_tree_int2(ModuleName, TypeEqvMap, InstEqvMap,
|
|
OrigParseTree2, ParseTree2, !RecompInfo, !UsedModules, !Specs),
|
|
IndirectIntSpec = indirect_int2(ParseTree2, ReadWhy2).
|
|
|
|
:- pred replace_in_int_for_opt_spec(module_name::in,
|
|
type_eqv_map::in, inst_eqv_map::in,
|
|
int_for_opt_spec::in, int_for_opt_spec::out,
|
|
maybe(recompilation_info)::in, maybe(recompilation_info)::out,
|
|
used_modules::in, used_modules::out,
|
|
list(error_spec)::in, list(error_spec)::out) is det.
|
|
|
|
replace_in_int_for_opt_spec(ModuleName, TypeEqvMap, InstEqvMap,
|
|
IntForOptSpec0, IntForOptSpec, !RecompInfo, !UsedModules, !Specs) :-
|
|
(
|
|
IntForOptSpec0 = for_opt_int0(OrigParseTree0, ReadWhy0),
|
|
replace_in_parse_tree_int0(ModuleName, TypeEqvMap, InstEqvMap,
|
|
OrigParseTree0, ParseTree0, !RecompInfo, !UsedModules, !Specs),
|
|
IntForOptSpec = for_opt_int0(ParseTree0, ReadWhy0)
|
|
;
|
|
IntForOptSpec0 = for_opt_int1(OrigParseTree1, ReadWhy1),
|
|
replace_in_parse_tree_int1(ModuleName, TypeEqvMap, InstEqvMap,
|
|
OrigParseTree1, ParseTree1, !RecompInfo, !UsedModules, !Specs),
|
|
IntForOptSpec = for_opt_int1(ParseTree1, ReadWhy1)
|
|
;
|
|
IntForOptSpec0 = for_opt_int2(OrigParseTree2, ReadWhy2),
|
|
replace_in_parse_tree_int2(ModuleName, TypeEqvMap, InstEqvMap,
|
|
OrigParseTree2, ParseTree2, !RecompInfo, !UsedModules, !Specs),
|
|
IntForOptSpec = for_opt_int2(ParseTree2, ReadWhy2)
|
|
).
|
|
|
|
%---------------------------------------------------------------------------%
|
|
|
|
:- pred replace_in_parse_tree_int0(module_name::in,
|
|
type_eqv_map::in, inst_eqv_map::in,
|
|
parse_tree_int0::in, parse_tree_int0::out,
|
|
maybe(recompilation_info)::in, maybe(recompilation_info)::out,
|
|
used_modules::in, used_modules::out,
|
|
list(error_spec)::in, list(error_spec)::out) is det.
|
|
|
|
replace_in_parse_tree_int0(ModuleName, TypeEqvMap, InstEqvMap,
|
|
OrigParseTreeInt0, ParseTreeInt0, !RecompInfo, !UsedModules, !Specs) :-
|
|
MaybeRecordInt = dont_record_sym_name_use,
|
|
MaybeRecordImp = dont_record_sym_name_use,
|
|
OrigParseTreeInt0 = parse_tree_int0(IntModuleName, IntModuleNameContext,
|
|
MaybeVersionNumbers, InclMap, ImportUseMap, IntFIMSpecs, ImpFIMSpecs,
|
|
TypeCtorCheckedMap0, InstCtorCheckedMap0, ModeCtorCheckedMap0,
|
|
IntTypeClasses0, IntInstances0, IntPredDecls0, IntModeDecls0,
|
|
IntDeclPragmas0, IntDeclMarkers, IntPromises,
|
|
ImpTypeClasses0, ImpInstances0, ImpPredDecls0, ImpModeDecls0,
|
|
ImpDeclPragmas0, ImpDeclMarkers, ImpPromises),
|
|
|
|
map.map_values_foldl3(
|
|
replace_in_type_ctor_checked_defn(ModuleName,
|
|
MaybeRecordInt, MaybeRecordImp, TypeEqvMap, InstEqvMap),
|
|
TypeCtorCheckedMap0, TypeCtorCheckedMap,
|
|
!RecompInfo, !UsedModules, !Specs),
|
|
% XXX See the comment at module top.
|
|
InstCtorCheckedMap = InstCtorCheckedMap0,
|
|
ModeCtorCheckedMap = ModeCtorCheckedMap0,
|
|
|
|
replace_in_list(ModuleName, MaybeRecordInt, TypeEqvMap, InstEqvMap,
|
|
replace_in_typeclass_info, IntTypeClasses0, IntTypeClasses,
|
|
!RecompInfo, !UsedModules, !Specs),
|
|
replace_in_list(ModuleName, MaybeRecordInt, TypeEqvMap, InstEqvMap,
|
|
replace_in_abstract_instance_info, IntInstances0, IntInstances,
|
|
!RecompInfo, !UsedModules, !Specs),
|
|
replace_in_list(ModuleName, MaybeRecordInt, TypeEqvMap, InstEqvMap,
|
|
replace_in_pred_decl_info, IntPredDecls0, IntPredDecls,
|
|
!RecompInfo, !UsedModules, !Specs),
|
|
replace_in_list(ModuleName, MaybeRecordInt, TypeEqvMap, InstEqvMap,
|
|
replace_in_mode_decl_info, IntModeDecls0, IntModeDecls,
|
|
!RecompInfo, !UsedModules, !Specs),
|
|
replace_in_list(ModuleName, MaybeRecordInt, TypeEqvMap, InstEqvMap,
|
|
replace_in_decl_pragma_info, IntDeclPragmas0, IntDeclPragmas,
|
|
!RecompInfo, !UsedModules, !Specs),
|
|
|
|
replace_in_list(ModuleName, MaybeRecordImp, TypeEqvMap, InstEqvMap,
|
|
replace_in_typeclass_info, ImpTypeClasses0, ImpTypeClasses,
|
|
!RecompInfo, !UsedModules, !Specs),
|
|
replace_in_list(ModuleName, MaybeRecordImp, TypeEqvMap, InstEqvMap,
|
|
replace_in_abstract_instance_info, ImpInstances0, ImpInstances,
|
|
!RecompInfo, !UsedModules, !Specs),
|
|
replace_in_list(ModuleName, MaybeRecordImp, TypeEqvMap, InstEqvMap,
|
|
replace_in_pred_decl_info, ImpPredDecls0, ImpPredDecls,
|
|
!RecompInfo, !UsedModules, !Specs),
|
|
replace_in_list(ModuleName, MaybeRecordImp, TypeEqvMap, InstEqvMap,
|
|
replace_in_mode_decl_info, ImpModeDecls0, ImpModeDecls,
|
|
!RecompInfo, !UsedModules, !Specs),
|
|
replace_in_list(ModuleName, MaybeRecordImp, TypeEqvMap, InstEqvMap,
|
|
replace_in_decl_pragma_info, ImpDeclPragmas0, ImpDeclPragmas,
|
|
!RecompInfo, !UsedModules, !Specs),
|
|
|
|
ParseTreeInt0 = parse_tree_int0(IntModuleName, IntModuleNameContext,
|
|
MaybeVersionNumbers, InclMap, ImportUseMap, IntFIMSpecs, ImpFIMSpecs,
|
|
TypeCtorCheckedMap, InstCtorCheckedMap, ModeCtorCheckedMap,
|
|
IntTypeClasses, IntInstances, IntPredDecls, IntModeDecls,
|
|
IntDeclPragmas, IntDeclMarkers, IntPromises,
|
|
ImpTypeClasses, ImpInstances, ImpPredDecls, ImpModeDecls,
|
|
ImpDeclPragmas, ImpDeclMarkers, ImpPromises).
|
|
|
|
:- pred replace_in_parse_tree_int1(module_name::in,
|
|
type_eqv_map::in, inst_eqv_map::in,
|
|
parse_tree_int1::in, parse_tree_int1::out,
|
|
maybe(recompilation_info)::in, maybe(recompilation_info)::out,
|
|
used_modules::in, used_modules::out,
|
|
list(error_spec)::in, list(error_spec)::out) is det.
|
|
|
|
replace_in_parse_tree_int1(ModuleName, TypeEqvMap, InstEqvMap,
|
|
OrigParseTreeInt1, ParseTreeInt1, !RecompInfo, !UsedModules, !Specs) :-
|
|
MaybeRecordInt = dont_record_sym_name_use,
|
|
MaybeRecordImp = dont_record_sym_name_use,
|
|
OrigParseTreeInt1 = parse_tree_int1(IntModuleName, IntModuleNameContext,
|
|
MaybeVersionNumbers, InclMap, ImportUseMap, IntFIMSpecs, ImpFIMSpecs,
|
|
TypeCtorCheckedMap0, InstCtorCheckedMap0, ModeCtorCheckedMap0,
|
|
IntTypeClasses0, IntInstances0, IntPredDecls0, IntModeDecls0,
|
|
IntDeclPragmas0, IntDeclMarkers0, IntPromises, IntTypeRepnMap0,
|
|
ImpTypeClasses0),
|
|
|
|
map.map_values_foldl3(
|
|
replace_in_type_ctor_checked_defn(ModuleName,
|
|
MaybeRecordInt, MaybeRecordImp, TypeEqvMap, InstEqvMap),
|
|
TypeCtorCheckedMap0, TypeCtorCheckedMap,
|
|
!RecompInfo, !UsedModules, !Specs),
|
|
% XXX See the comment at module top.
|
|
InstCtorCheckedMap = InstCtorCheckedMap0,
|
|
ModeCtorCheckedMap = ModeCtorCheckedMap0,
|
|
|
|
replace_in_list(ModuleName, MaybeRecordInt, TypeEqvMap, InstEqvMap,
|
|
replace_in_typeclass_info, IntTypeClasses0, IntTypeClasses,
|
|
!RecompInfo, !UsedModules, !Specs),
|
|
replace_in_list(ModuleName, MaybeRecordInt, TypeEqvMap, InstEqvMap,
|
|
replace_in_abstract_instance_info, IntInstances0, IntInstances,
|
|
!RecompInfo, !UsedModules, !Specs),
|
|
replace_in_list(ModuleName, MaybeRecordInt, TypeEqvMap, InstEqvMap,
|
|
replace_in_pred_decl_info, IntPredDecls0, IntPredDecls,
|
|
!RecompInfo, !UsedModules, !Specs),
|
|
replace_in_list(ModuleName, MaybeRecordInt, TypeEqvMap, InstEqvMap,
|
|
replace_in_mode_decl_info, IntModeDecls0, IntModeDecls,
|
|
!RecompInfo, !UsedModules, !Specs),
|
|
replace_in_list(ModuleName, MaybeRecordInt, TypeEqvMap, InstEqvMap,
|
|
replace_in_decl_pragma_info, IntDeclPragmas0, IntDeclPragmas,
|
|
!RecompInfo, !UsedModules, !Specs),
|
|
map.map_values_foldl3(
|
|
replace_in_type_repn_info(ModuleName, MaybeRecordInt, TypeEqvMap),
|
|
IntTypeRepnMap0, IntTypeRepnMap,
|
|
!RecompInfo, !UsedModules, !Specs),
|
|
|
|
replace_in_list(ModuleName, MaybeRecordImp, TypeEqvMap, InstEqvMap,
|
|
replace_in_abstract_typeclass_info, ImpTypeClasses0, ImpTypeClasses,
|
|
!RecompInfo, !UsedModules, !Specs),
|
|
|
|
ParseTreeInt1 = parse_tree_int1(IntModuleName, IntModuleNameContext,
|
|
MaybeVersionNumbers, InclMap, ImportUseMap, IntFIMSpecs, ImpFIMSpecs,
|
|
TypeCtorCheckedMap, InstCtorCheckedMap, ModeCtorCheckedMap,
|
|
IntTypeClasses, IntInstances, IntPredDecls, IntModeDecls,
|
|
IntDeclPragmas, IntDeclMarkers0, IntPromises, IntTypeRepnMap,
|
|
ImpTypeClasses).
|
|
|
|
:- pred replace_in_parse_tree_int2(module_name::in,
|
|
type_eqv_map::in, inst_eqv_map::in,
|
|
parse_tree_int2::in, parse_tree_int2::out,
|
|
maybe(recompilation_info)::in, maybe(recompilation_info)::out,
|
|
used_modules::in, used_modules::out,
|
|
list(error_spec)::in, list(error_spec)::out) is det.
|
|
|
|
replace_in_parse_tree_int2(ModuleName, TypeEqvMap, InstEqvMap,
|
|
OrigParseTreeInt2, ParseTreeInt2, !RecompInfo, !UsedModules, !Specs) :-
|
|
MaybeRecordInt = dont_record_sym_name_use,
|
|
MaybeRecordImp = dont_record_sym_name_use,
|
|
OrigParseTreeInt2 = parse_tree_int2(IntModuleName, IntModuleNameContext,
|
|
MaybeVersionNumbers, InclMap, ImportUseMap, IntFIMSpecs, ImpFIMSpecs,
|
|
TypeCtorCheckedMap0, InstCtorCheckedMap0, ModeCtorCheckedMap0,
|
|
IntTypeClasses0, IntInstances0, IntTypeRepnMap0),
|
|
|
|
map.map_values_foldl3(
|
|
replace_in_type_ctor_checked_defn(ModuleName,
|
|
MaybeRecordInt, MaybeRecordImp, TypeEqvMap, InstEqvMap),
|
|
TypeCtorCheckedMap0, TypeCtorCheckedMap,
|
|
!RecompInfo, !UsedModules, !Specs),
|
|
% XXX See the comment at module top.
|
|
InstCtorCheckedMap = InstCtorCheckedMap0,
|
|
ModeCtorCheckedMap = ModeCtorCheckedMap0,
|
|
|
|
replace_in_list(ModuleName, MaybeRecordInt, TypeEqvMap, InstEqvMap,
|
|
replace_in_typeclass_info, IntTypeClasses0, IntTypeClasses,
|
|
!RecompInfo, !UsedModules, !Specs),
|
|
replace_in_list(ModuleName, MaybeRecordInt, TypeEqvMap, InstEqvMap,
|
|
replace_in_abstract_instance_info, IntInstances0, IntInstances,
|
|
!RecompInfo, !UsedModules, !Specs),
|
|
map.map_values_foldl3(
|
|
replace_in_type_repn_info(ModuleName, MaybeRecordInt, TypeEqvMap),
|
|
IntTypeRepnMap0, IntTypeRepnMap,
|
|
!RecompInfo, !UsedModules, !Specs),
|
|
|
|
ParseTreeInt2 = parse_tree_int2(IntModuleName, IntModuleNameContext,
|
|
MaybeVersionNumbers, InclMap, ImportUseMap, IntFIMSpecs, ImpFIMSpecs,
|
|
TypeCtorCheckedMap, InstCtorCheckedMap, ModeCtorCheckedMap,
|
|
IntTypeClasses, IntInstances, IntTypeRepnMap).
|
|
|
|
:- pred replace_in_parse_tree_plain_opt(module_name::in,
|
|
type_eqv_map::in, inst_eqv_map::in,
|
|
parse_tree_plain_opt::in, parse_tree_plain_opt::out,
|
|
maybe(recompilation_info)::in, maybe(recompilation_info)::out,
|
|
used_modules::in, used_modules::out,
|
|
list(error_spec)::in, list(error_spec)::out) is det.
|
|
|
|
replace_in_parse_tree_plain_opt(ModuleName, TypeEqvMap, InstEqvMap,
|
|
OrigParseTreePlainOpt, ParseTreePlainOpt,
|
|
!RecompInfo, !UsedModules, !Specs) :-
|
|
MaybeRecord = dont_record_sym_name_use,
|
|
OrigParseTreePlainOpt = parse_tree_plain_opt(
|
|
OptModuleName, OptModuleNameContext,
|
|
UsedModuleNames, FIMSpecs, TypeDefns0, ForeignEnums,
|
|
InstDefns0, ModeDefns0, TypeClasses0, Instances0,
|
|
PredDecls0, ModeDecls0, Clauses, ForeignProcs, Promises,
|
|
DeclMarkers, ImplMarkers,
|
|
TypeSpecs0, UnusedArgs, TermInfos, Term2Infos,
|
|
Exceptions, Trailings, MMTablings, Sharings, Reuses),
|
|
|
|
InstDefns = InstDefns0, % XXX See the comment at module top.
|
|
ModeDefns = ModeDefns0, % XXX See the comment at module top.
|
|
replace_in_list(ModuleName, MaybeRecord, TypeEqvMap, InstEqvMap,
|
|
replace_in_type_defn_info_general(replace_in_type_defn),
|
|
TypeDefns0, TypeDefns, !RecompInfo, !UsedModules, !Specs),
|
|
replace_in_list(ModuleName, MaybeRecord, TypeEqvMap, InstEqvMap,
|
|
replace_in_typeclass_info, TypeClasses0, TypeClasses,
|
|
!RecompInfo, !UsedModules, !Specs),
|
|
replace_in_list(ModuleName, MaybeRecord, TypeEqvMap, InstEqvMap,
|
|
replace_in_instance_info, Instances0, Instances,
|
|
!RecompInfo, !UsedModules, !Specs),
|
|
replace_in_list(ModuleName, MaybeRecord, TypeEqvMap, InstEqvMap,
|
|
replace_in_pred_decl_info, PredDecls0, PredDecls,
|
|
!RecompInfo, !UsedModules, !Specs),
|
|
replace_in_list(ModuleName, MaybeRecord, TypeEqvMap, InstEqvMap,
|
|
replace_in_mode_decl_info, ModeDecls0, ModeDecls,
|
|
!RecompInfo, !UsedModules, !Specs),
|
|
replace_in_list(ModuleName, MaybeRecord, TypeEqvMap, InstEqvMap,
|
|
replace_in_decl_pragma_type_spec, TypeSpecs0, TypeSpecs,
|
|
!RecompInfo, !UsedModules, !Specs),
|
|
|
|
ParseTreePlainOpt = parse_tree_plain_opt(
|
|
OptModuleName, OptModuleNameContext,
|
|
UsedModuleNames, FIMSpecs, TypeDefns, ForeignEnums,
|
|
InstDefns, ModeDefns, TypeClasses, Instances,
|
|
PredDecls, ModeDecls, Clauses, ForeignProcs, Promises,
|
|
DeclMarkers, ImplMarkers,
|
|
TypeSpecs, UnusedArgs, TermInfos, Term2Infos,
|
|
Exceptions, Trailings, MMTablings, Sharings, Reuses).
|
|
|
|
:- pred replace_in_parse_tree_trans_opt(module_name::in,
|
|
type_eqv_map::in, inst_eqv_map::in,
|
|
parse_tree_trans_opt::in, parse_tree_trans_opt::out,
|
|
maybe(recompilation_info)::in, maybe(recompilation_info)::out,
|
|
used_modules::in, used_modules::out,
|
|
list(error_spec)::in, list(error_spec)::out) is det.
|
|
|
|
replace_in_parse_tree_trans_opt(_ModuleName, _TypeEqvMap, _InstEqvMap,
|
|
!ParseTreeTransOpt, !RecompInfo, !UsedModules, !Specs).
|
|
% No component that may appear in a parse_tree_trans_opt
|
|
% needs any expansions.
|
|
|
|
%---------------------------------------------------------------------------%
|
|
|
|
:- type maybe_record_sym_name_use
|
|
---> dont_record_sym_name_use
|
|
; record_sym_name_use(item_visibility).
|
|
|
|
%---------------------------------------------------------------------------%
|
|
|
|
:- pred replace_in_maybe(module_name::in, maybe_record_sym_name_use::in,
|
|
type_eqv_map::in, inst_eqv_map::in,
|
|
pred(module_name, maybe_record_sym_name_use, type_eqv_map, inst_eqv_map,
|
|
T, T, maybe(recompilation_info), maybe(recompilation_info),
|
|
used_modules, used_modules, list(error_spec))
|
|
:: in(pred(in, in,in, in, in, out, in, out, in, out, out) is det),
|
|
maybe(T)::in, maybe(T)::out,
|
|
maybe(recompilation_info)::in, maybe(recompilation_info)::out,
|
|
used_modules::in, used_modules::out,
|
|
list(error_spec)::in, list(error_spec)::out) is det.
|
|
|
|
replace_in_maybe(ModuleName, MaybeRecord, TypeEqvMap, InstEqvMap,
|
|
ReplaceInItem, MaybeItem0, MaybeItem,
|
|
!RecompInfo, !UsedModules, !Specs) :-
|
|
(
|
|
MaybeItem0 = no,
|
|
MaybeItem = no
|
|
;
|
|
MaybeItem0 = yes(Item0),
|
|
ReplaceInItem(ModuleName, MaybeRecord, TypeEqvMap, InstEqvMap,
|
|
Item0, Item, !RecompInfo, !UsedModules, ItemSpecs),
|
|
(
|
|
ItemSpecs = [],
|
|
MaybeItem = yes(Item)
|
|
;
|
|
ItemSpecs = [_ | _],
|
|
!:Specs = ItemSpecs ++ !.Specs,
|
|
MaybeItem = no
|
|
)
|
|
).
|
|
|
|
%---------------------%
|
|
|
|
:- pred replace_in_list(module_name::in, maybe_record_sym_name_use::in,
|
|
type_eqv_map::in, inst_eqv_map::in,
|
|
pred(module_name, maybe_record_sym_name_use, type_eqv_map, inst_eqv_map,
|
|
T, T, maybe(recompilation_info), maybe(recompilation_info),
|
|
used_modules, used_modules, list(error_spec))
|
|
:: in(pred(in, in,in, in, in, out, in, out, in, out, out) is det),
|
|
list(T)::in, list(T)::out,
|
|
maybe(recompilation_info)::in, maybe(recompilation_info)::out,
|
|
used_modules::in, used_modules::out,
|
|
list(error_spec)::in, list(error_spec)::out) is det.
|
|
|
|
replace_in_list(ModuleName, MaybeRecord, TypeEqvMap, InstEqvMap,
|
|
ReplaceInItem, Items0, Items, !RecompInfo, !UsedModules, !Specs) :-
|
|
replace_in_list_loop(ModuleName, MaybeRecord, TypeEqvMap, InstEqvMap,
|
|
ReplaceInItem, Items0, [], RevItems,
|
|
!RecompInfo, !UsedModules, !Specs),
|
|
list.reverse(RevItems, Items).
|
|
|
|
:- pred replace_in_list_loop(module_name::in, maybe_record_sym_name_use::in,
|
|
type_eqv_map::in, inst_eqv_map::in,
|
|
pred(module_name, maybe_record_sym_name_use, type_eqv_map, inst_eqv_map,
|
|
T, T, maybe(recompilation_info), maybe(recompilation_info),
|
|
used_modules, used_modules, list(error_spec))
|
|
:: in(pred(in, in,in, in, in, out, in, out, in, out, out) is det),
|
|
list(T)::in, list(T)::in, list(T)::out,
|
|
maybe(recompilation_info)::in, maybe(recompilation_info)::out,
|
|
used_modules::in, used_modules::out,
|
|
list(error_spec)::in, list(error_spec)::out) is det.
|
|
|
|
replace_in_list_loop(_ModuleName, _MaybeRecord, _TypeEqvMap, _InstEqvMap,
|
|
_ReplaceInItem, [], !RevItems, !RecompInfo, !UsedModules, !Specs).
|
|
replace_in_list_loop(ModuleName, MaybeRecord, TypeEqvMap, InstEqvMap,
|
|
ReplaceInItem, [Item0 | Items0], !RevItems,
|
|
!RecompInfo, !UsedModules, !Specs) :-
|
|
ReplaceInItem(ModuleName, MaybeRecord, TypeEqvMap, InstEqvMap,
|
|
Item0, Item, !RecompInfo, !UsedModules, ItemSpecs),
|
|
% Discard the item if there were any errors.
|
|
(
|
|
ItemSpecs = [],
|
|
!:RevItems = [Item | !.RevItems]
|
|
;
|
|
ItemSpecs = [_ | _],
|
|
!:Specs = ItemSpecs ++ !.Specs
|
|
),
|
|
replace_in_list_loop(ModuleName, MaybeRecord, TypeEqvMap, InstEqvMap,
|
|
ReplaceInItem, Items0, !RevItems, !RecompInfo, !UsedModules, !Specs).
|
|
|
|
%---------------------------------------------------------------------------%
|
|
|
|
:- pred replace_in_type_ctor_checked_defn(module_name::in,
|
|
maybe_record_sym_name_use::in, maybe_record_sym_name_use::in,
|
|
type_eqv_map::in, inst_eqv_map::in,
|
|
type_ctor_checked_defn::in, type_ctor_checked_defn::out,
|
|
maybe(recompilation_info)::in, maybe(recompilation_info)::out,
|
|
used_modules::in, used_modules::out,
|
|
list(error_spec)::in, list(error_spec)::out) is det.
|
|
|
|
replace_in_type_ctor_checked_defn(ModuleName, MaybeRecordInt, MaybeRecordImp,
|
|
TypeEqvMap, InstEqvMap, CheckedDefn0, CheckedDefn,
|
|
!RecompInfo, !UsedModules, !Specs) :-
|
|
(
|
|
CheckedDefn0 = checked_defn_solver(SolverDefn0, SrcDefns0),
|
|
(
|
|
SolverDefn0 = solver_type_abstract(_, _),
|
|
SolverDefn = SolverDefn0
|
|
;
|
|
SolverDefn0 =
|
|
solver_type_full(MaybeAbstractDefn0, ItemSolverDefn0),
|
|
replace_in_type_defn_info_general(replace_in_type_defn_solver,
|
|
ModuleName, MaybeRecordImp, TypeEqvMap, InstEqvMap,
|
|
ItemSolverDefn0, ItemSolverDefn,
|
|
!RecompInfo, !UsedModules, SolverSpecs),
|
|
!:Specs = SolverSpecs ++ !.Specs,
|
|
% Abstract type definitions have no equivalences to expand out.
|
|
SolverDefn = solver_type_full(MaybeAbstractDefn0, ItemSolverDefn)
|
|
),
|
|
SrcDefns0 = src_defns_solver(MaybeIntDefn0, MaybeImpDefn0),
|
|
replace_in_maybe(ModuleName, MaybeRecordInt, TypeEqvMap, InstEqvMap,
|
|
replace_in_type_defn_info_general(replace_in_type_defn),
|
|
MaybeIntDefn0, MaybeIntDefn, !RecompInfo, !UsedModules, !Specs),
|
|
replace_in_maybe(ModuleName, MaybeRecordImp, TypeEqvMap, InstEqvMap,
|
|
replace_in_type_defn_info_general(replace_in_type_defn),
|
|
MaybeImpDefn0, MaybeImpDefn, !RecompInfo, !UsedModules, !Specs),
|
|
SrcDefns = src_defns_solver(MaybeIntDefn, MaybeImpDefn),
|
|
CheckedDefn = checked_defn_solver(SolverDefn, SrcDefns)
|
|
;
|
|
CheckedDefn0 = checked_defn_std(StdDefn0, SrcDefns0),
|
|
(
|
|
StdDefn0 = std_mer_type_eqv(Status, ItemEqvDefn0),
|
|
replace_in_type_defn_info_general(replace_in_type_defn_eqv,
|
|
ModuleName, MaybeRecordImp, TypeEqvMap, InstEqvMap,
|
|
ItemEqvDefn0, ItemEqvDefn, !RecompInfo, !UsedModules,
|
|
EqvSpecs),
|
|
!:Specs = EqvSpecs ++ !.Specs,
|
|
StdDefn = std_mer_type_eqv(Status, ItemEqvDefn)
|
|
;
|
|
StdDefn0 = std_mer_type_subtype(Status, ItemSubDefn0),
|
|
replace_in_type_defn_info_general(replace_in_type_defn_sub,
|
|
ModuleName, MaybeRecordImp, TypeEqvMap, InstEqvMap,
|
|
ItemSubDefn0, ItemSubDefn, !RecompInfo, !UsedModules,
|
|
SubSpecs),
|
|
!:Specs = SubSpecs ++ !.Specs,
|
|
StdDefn = std_mer_type_subtype(Status, ItemSubDefn)
|
|
;
|
|
StdDefn0 = std_mer_type_du_all_plain_constants(Status,
|
|
ItemDuDefn0, HeadCtor, TailCtors, CJCsMaybeDefnOrEnum),
|
|
replace_in_type_defn_info_general(replace_in_type_defn_du,
|
|
ModuleName, MaybeRecordImp, TypeEqvMap, InstEqvMap,
|
|
ItemDuDefn0, ItemDuDefn, !RecompInfo, !UsedModules, DuSpecs),
|
|
!:Specs = DuSpecs ++ !.Specs,
|
|
% Foreign type definitions and enums have no equivalences
|
|
% to expand out.
|
|
StdDefn = std_mer_type_du_all_plain_constants(Status,
|
|
ItemDuDefn, HeadCtor, TailCtors, CJCsMaybeDefnOrEnum)
|
|
;
|
|
StdDefn0 = std_mer_type_du_not_all_plain_constants(Status,
|
|
ItemDuDefn0, CJCsMaybeDefn),
|
|
replace_in_type_defn_info_general(replace_in_type_defn_du,
|
|
ModuleName, MaybeRecordImp, TypeEqvMap, InstEqvMap,
|
|
ItemDuDefn0, ItemDuDefn, !RecompInfo, !UsedModules, DuSpecs),
|
|
!:Specs = DuSpecs ++ !.Specs,
|
|
% Foreign type definitions have no equivalences to expand out.
|
|
StdDefn = std_mer_type_du_not_all_plain_constants(Status,
|
|
ItemDuDefn, CJCsMaybeDefn)
|
|
;
|
|
StdDefn0 = std_mer_type_abstract(_Status,
|
|
_ItemAbstractDefn, _CJCsMaybeDefn),
|
|
% Abstract type definitions and foreign type definitions
|
|
% have no equivalences to expand out.
|
|
StdDefn = StdDefn0
|
|
),
|
|
SrcDefns0 = src_defns_std(IntDefns0, ImpDefns0, ImpForeignEnums0),
|
|
replace_in_list(ModuleName, MaybeRecordInt, TypeEqvMap, InstEqvMap,
|
|
replace_in_type_defn_info_general(replace_in_type_defn),
|
|
IntDefns0, IntDefns, !RecompInfo, !UsedModules, !Specs),
|
|
replace_in_list(ModuleName, MaybeRecordImp, TypeEqvMap, InstEqvMap,
|
|
replace_in_type_defn_info_general(replace_in_type_defn),
|
|
ImpDefns0, ImpDefns, !RecompInfo, !UsedModules, !Specs),
|
|
% Foreign enum infos have no equivalences to expand out.
|
|
SrcDefns = src_defns_std(IntDefns, ImpDefns, ImpForeignEnums0),
|
|
CheckedDefn = checked_defn_std(StdDefn, SrcDefns)
|
|
).
|
|
|
|
:- pred replace_in_type_defn_info_general(
|
|
pred(maybe_record_sym_name_use, type_eqv_map, inst_eqv_map, type_ctor,
|
|
prog_context, T, T, tvarset, tvarset,
|
|
eqv_expand_info, eqv_expand_info,
|
|
used_modules, used_modules, list(error_spec))
|
|
:: in(pred(in, in, in, in, in, in, out, in, out, in, out, in, out, out)
|
|
is det),
|
|
module_name::in, maybe_record_sym_name_use::in,
|
|
type_eqv_map::in, inst_eqv_map::in,
|
|
item_type_defn_info_general(T)::in, item_type_defn_info_general(T)::out,
|
|
maybe(recompilation_info)::in, maybe(recompilation_info)::out,
|
|
used_modules::in, used_modules::out, list(error_spec)::out) is det.
|
|
|
|
replace_in_type_defn_info_general(ReplaceInTypeDefn, ModuleName, MaybeRecord,
|
|
TypeEqvMap, InstEqvMap, Info0, Info,
|
|
!RecompInfo, !UsedModules, Specs) :-
|
|
Info0 = item_type_defn_info(SymName, ArgTypeVars, TypeDefn0, TVarSet0,
|
|
Context, SeqNum),
|
|
list.length(ArgTypeVars, Arity),
|
|
TypeCtor = type_ctor(SymName, Arity),
|
|
maybe_start_recording_expanded_items(ModuleName, SymName, !.RecompInfo,
|
|
UsedTypeCtors0),
|
|
ReplaceInTypeDefn(MaybeRecord, TypeEqvMap, InstEqvMap, TypeCtor, Context,
|
|
TypeDefn0, TypeDefn, TVarSet0, TVarSet,
|
|
UsedTypeCtors0, UsedTypeCtors, !UsedModules, Specs),
|
|
ItemName = recomp_item_name(SymName, Arity),
|
|
ItemId = recomp_item_id(recomp_type_defn, ItemName),
|
|
finish_recording_expanded_items(ItemId, UsedTypeCtors, !RecompInfo),
|
|
Info = item_type_defn_info(SymName, ArgTypeVars, TypeDefn, TVarSet,
|
|
Context, SeqNum).
|
|
|
|
:- pred replace_in_type_repn_info(module_name::in,
|
|
maybe_record_sym_name_use::in, type_eqv_map::in,
|
|
item_type_repn_info::in, item_type_repn_info::out,
|
|
maybe(recompilation_info)::in, maybe(recompilation_info)::out,
|
|
used_modules::in, used_modules::out,
|
|
list(error_spec)::in, list(error_spec)::out) is det.
|
|
|
|
replace_in_type_repn_info(ModuleName, MaybeRecord, TypeEqvMap,
|
|
Info0, Info, !RecompInfo, !UsedModules, !Specs) :-
|
|
Info0 = item_type_repn_info(SymName, ArgTypeVars, TypeRepn0, TVarSet0,
|
|
Context, SeqNum),
|
|
list.length(ArgTypeVars, Arity),
|
|
maybe_start_recording_expanded_items(ModuleName, SymName, !.RecompInfo,
|
|
UsedTypeCtors0),
|
|
(
|
|
TypeRepn0 = tcrepn_is_eqv_to(Type0),
|
|
TypeCtor = type_ctor(SymName, Arity),
|
|
replace_in_type_maybe_record_use_2(MaybeRecord, TypeEqvMap, [TypeCtor],
|
|
Type0, Type, _, Circ, TVarSet0, TVarSet,
|
|
UsedTypeCtors0, UsedTypeCtors, !UsedModules),
|
|
set.to_sorted_list(Circ, CircTypes),
|
|
(
|
|
CircTypes = [_ | _],
|
|
!:Specs = [report_circular_eqv_type(TypeCtor, Context) | !.Specs]
|
|
;
|
|
CircTypes = []
|
|
),
|
|
TypeRepn = tcrepn_is_eqv_to(Type)
|
|
;
|
|
TypeRepn0 = tcrepn_is_subtype_of(SuperTypeCtor0),
|
|
% Construct a type from the type ctor, substituting 'void' for any type
|
|
% parameters, so that we can call replace_in_type_maybe_record_use_2.
|
|
% We do not care about the type arguments so we can drop them again
|
|
% afterwards.
|
|
SuperTypeCtor0 = type_ctor(_, SuperTypeCtorArity),
|
|
list.duplicate(SuperTypeCtorArity, void_type, VoidTypes),
|
|
construct_type(SuperTypeCtor0, VoidTypes, SuperType0),
|
|
TypeCtor = type_ctor(SymName, Arity),
|
|
replace_in_type_maybe_record_use_2(MaybeRecord, TypeEqvMap, [TypeCtor],
|
|
SuperType0, SuperType, _, Circ, TVarSet0, TVarSet,
|
|
UsedTypeCtors0, UsedTypeCtors, !UsedModules),
|
|
type_to_ctor_det(SuperType, SuperTypeCtor),
|
|
set.to_sorted_list(Circ, CircTypes),
|
|
(
|
|
CircTypes = [_ | _],
|
|
!:Specs = [report_circular_eqv_type(TypeCtor, Context) | !.Specs]
|
|
;
|
|
CircTypes = []
|
|
),
|
|
TypeRepn = tcrepn_is_subtype_of(SuperTypeCtor)
|
|
;
|
|
( TypeRepn0 = tcrepn_is_word_aligned_ptr
|
|
; TypeRepn0 = tcrepn_du(_)
|
|
; TypeRepn0 = tcrepn_foreign(_)
|
|
),
|
|
TypeRepn = TypeRepn0,
|
|
TVarSet = TVarSet0,
|
|
UsedTypeCtors = UsedTypeCtors0
|
|
),
|
|
ItemName = recomp_item_name(SymName, Arity),
|
|
ItemId = recomp_item_id(recomp_type_defn, ItemName),
|
|
finish_recording_expanded_items(ItemId, UsedTypeCtors, !RecompInfo),
|
|
Info = item_type_repn_info(SymName, ArgTypeVars, TypeRepn, TVarSet,
|
|
Context, SeqNum).
|
|
|
|
replace_in_type_repn_eqv(TypeEqvMap, Info0, Info, !Specs) :-
|
|
Info0 = item_type_repn_info(SymName, ArgTypeVars, Type0, TVarSet0,
|
|
Context, SeqNum),
|
|
list.length(ArgTypeVars, Arity),
|
|
TypeCtor = type_ctor(SymName, Arity),
|
|
replace_in_type_maybe_record_use_2(dont_record_sym_name_use, TypeEqvMap,
|
|
[], Type0, Type, _Changed, Circ, TVarSet0, TVarSet,
|
|
no_eqv_expand_info, _, used_modules_init, _),
|
|
set.to_sorted_list(Circ, CircTypes),
|
|
(
|
|
CircTypes = [_ | _],
|
|
!:Specs = [report_circular_eqv_type(TypeCtor, Context) | !.Specs]
|
|
;
|
|
CircTypes = []
|
|
),
|
|
Info = item_type_repn_info(SymName, ArgTypeVars, Type, TVarSet,
|
|
Context, SeqNum).
|
|
|
|
:- pred replace_in_pred_decl_info(module_name::in,
|
|
maybe_record_sym_name_use::in, type_eqv_map::in, inst_eqv_map::in,
|
|
item_pred_decl_info::in, item_pred_decl_info::out,
|
|
maybe(recompilation_info)::in, maybe(recompilation_info)::out,
|
|
used_modules::in, used_modules::out, list(error_spec)::out) is det.
|
|
|
|
replace_in_pred_decl_info(ModuleName, MaybeRecord, TypeEqvMap, InstEqvMap,
|
|
Info0, Info, !RecompInfo, !UsedModules, Specs) :-
|
|
Info0 = item_pred_decl_info(PredName, PredOrFunc, TypesAndModes0,
|
|
MaybeWithType0, MaybeWithInst0, MaybeDetism0, Origin,
|
|
TVarSet0, InstVarSet, ExistQVars, Purity, ClassContext0,
|
|
Context, SeqNum),
|
|
maybe_start_recording_expanded_items(ModuleName, PredName, !.RecompInfo,
|
|
ExpandedItems0),
|
|
replace_in_pred_type(MaybeRecord, PredName, PredOrFunc, Context,
|
|
TypeEqvMap, InstEqvMap, ClassContext0, ClassContext,
|
|
TypesAndModes0, TypesAndModes, TVarSet0, TVarSet,
|
|
MaybeWithType0, MaybeWithType, MaybeWithInst0, MaybeWithInst,
|
|
MaybeDetism0, MaybeDetism, ExpandedItems0, ExpandedItems,
|
|
!UsedModules, Specs),
|
|
ItemType = pred_or_func_to_recomp_item_type(PredOrFunc),
|
|
list.length(TypesAndModes, Arity),
|
|
adjust_func_arity(PredOrFunc, OrigArity, Arity),
|
|
ItemName = recomp_item_name(PredName, OrigArity),
|
|
ItemId = recomp_item_id(ItemType, ItemName),
|
|
finish_recording_expanded_items(ItemId, ExpandedItems, !RecompInfo),
|
|
Info = item_pred_decl_info(PredName, PredOrFunc, TypesAndModes,
|
|
MaybeWithType, MaybeWithInst, MaybeDetism, Origin,
|
|
TVarSet, InstVarSet, ExistQVars, Purity, ClassContext,
|
|
Context, SeqNum).
|
|
|
|
%---------------------%
|
|
|
|
:- pred replace_in_mode_decl_info(module_name::in,
|
|
maybe_record_sym_name_use::in, type_eqv_map::in, inst_eqv_map::in,
|
|
item_mode_decl_info::in, item_mode_decl_info::out,
|
|
maybe(recompilation_info)::in, maybe(recompilation_info)::out,
|
|
used_modules::in, used_modules::out, list(error_spec)::out) is det.
|
|
|
|
replace_in_mode_decl_info(ModuleName, MaybeRecord, _TypeEqvMap, InstEqvMap,
|
|
Info0, Info, !RecompInfo, !UsedModules, Specs) :-
|
|
Info0 = item_mode_decl_info(PredName, MaybePredOrFunc0, Modes0,
|
|
WithInst0, MaybeDetism0, InstVarSet, Context, SeqNum),
|
|
maybe_start_recording_expanded_items(ModuleName, PredName, !.RecompInfo,
|
|
ExpandedItems0),
|
|
replace_in_pred_mode(MaybeRecord, InstEqvMap, PredName,
|
|
list.length(Modes0), Context, mode_decl, ExtraModes,
|
|
MaybePredOrFunc0, MaybePredOrFunc, WithInst0, WithInst,
|
|
MaybeDetism0, MaybeDetism, ExpandedItems0, ExpandedItems,
|
|
!UsedModules, Specs),
|
|
(
|
|
ExtraModes = [],
|
|
Modes = Modes0
|
|
;
|
|
ExtraModes = [_ | _],
|
|
Modes = Modes0 ++ ExtraModes
|
|
),
|
|
(
|
|
MaybePredOrFunc = yes(PredOrFunc),
|
|
ItemType = pred_or_func_to_recomp_item_type(PredOrFunc),
|
|
list.length(Modes, Arity),
|
|
adjust_func_arity(PredOrFunc, OrigArity, Arity),
|
|
ItemName = recomp_item_name(PredName, OrigArity),
|
|
ItemId = recomp_item_id(ItemType, ItemName),
|
|
finish_recording_expanded_items(ItemId, ExpandedItems, !RecompInfo)
|
|
;
|
|
MaybePredOrFunc = no
|
|
),
|
|
Info = item_mode_decl_info(PredName, MaybePredOrFunc, Modes,
|
|
WithInst, MaybeDetism, InstVarSet, Context, SeqNum).
|
|
|
|
%---------------------%
|
|
%
|
|
% The next two predicates have identical definitions except for the treatment
|
|
% of the class interfaces, but one is for item_typeclass_infos, while the other
|
|
% is for item_abstract_typeclass_infos.
|
|
% XXX Ideally, this should not be necessary.
|
|
%
|
|
|
|
:- pred replace_in_typeclass_info(module_name::in,
|
|
maybe_record_sym_name_use::in, type_eqv_map::in, inst_eqv_map::in,
|
|
item_typeclass_info::in, item_typeclass_info::out,
|
|
maybe(recompilation_info)::in, maybe(recompilation_info)::out,
|
|
used_modules::in, used_modules::out, list(error_spec)::out) is det.
|
|
|
|
replace_in_typeclass_info(ModuleName, MaybeRecord, TypeEqvMap, InstEqvMap,
|
|
Info0, Info, !RecompInfo, !UsedModules, Specs) :-
|
|
Info0 = item_typeclass_info(ClassName, Vars, Constraints0, FunDeps,
|
|
ClassInterface0, TVarSet0, Context, SeqNum),
|
|
list.length(Vars, Arity),
|
|
maybe_start_recording_expanded_items(ModuleName, ClassName, !.RecompInfo,
|
|
ExpandedItems0),
|
|
replace_in_prog_constraint_list_location(MaybeRecord, TypeEqvMap,
|
|
Constraints0, Constraints, TVarSet0, TVarSet,
|
|
ExpandedItems0, ExpandedItems1, !UsedModules),
|
|
(
|
|
ClassInterface0 = class_interface_abstract,
|
|
ClassInterface = class_interface_abstract,
|
|
ExpandedItems = ExpandedItems1,
|
|
Specs = []
|
|
;
|
|
ClassInterface0 = class_interface_concrete(Methods0),
|
|
replace_in_class_interface(MaybeRecord, TypeEqvMap, InstEqvMap,
|
|
Methods0, Methods, ExpandedItems1, ExpandedItems,
|
|
!UsedModules, [], Specs),
|
|
ClassInterface = class_interface_concrete(Methods)
|
|
),
|
|
ItemName = recomp_item_name(ClassName, Arity),
|
|
ItemId = recomp_item_id(recomp_typeclass, ItemName),
|
|
finish_recording_expanded_items(ItemId, ExpandedItems, !RecompInfo),
|
|
Info = item_typeclass_info(ClassName, Vars, Constraints, FunDeps,
|
|
ClassInterface, TVarSet, Context, SeqNum).
|
|
|
|
:- pred replace_in_abstract_typeclass_info(module_name::in,
|
|
maybe_record_sym_name_use::in, type_eqv_map::in, inst_eqv_map::in,
|
|
item_abstract_typeclass_info::in, item_abstract_typeclass_info::out,
|
|
maybe(recompilation_info)::in, maybe(recompilation_info)::out,
|
|
used_modules::in, used_modules::out, list(error_spec)::out) is det.
|
|
|
|
replace_in_abstract_typeclass_info(ModuleName, MaybeRecord, TypeEqvMap,
|
|
_InstEqvMap, Info0, Info, !RecompInfo, !UsedModules, Specs) :-
|
|
Info0 = item_typeclass_info(ClassName, Vars, Constraints0, FunDeps,
|
|
ClassInterface, TVarSet0, Context, SeqNum),
|
|
list.length(Vars, Arity),
|
|
maybe_start_recording_expanded_items(ModuleName, ClassName, !.RecompInfo,
|
|
ExpandedItems0),
|
|
replace_in_prog_constraint_list_location(MaybeRecord, TypeEqvMap,
|
|
Constraints0, Constraints, TVarSet0, TVarSet,
|
|
ExpandedItems0, ExpandedItems, !UsedModules),
|
|
Specs = [],
|
|
ItemName = recomp_item_name(ClassName, Arity),
|
|
ItemId = recomp_item_id(recomp_typeclass, ItemName),
|
|
finish_recording_expanded_items(ItemId, ExpandedItems, !RecompInfo),
|
|
Info = item_typeclass_info(ClassName, Vars, Constraints, FunDeps,
|
|
ClassInterface, TVarSet, Context, SeqNum).
|
|
|
|
%---------------------%
|
|
%
|
|
% The next two predicates have identical definitions except for the treatment
|
|
% of the instance bodies, but one is for item_instance_infos, while the other
|
|
% is for item_abstract_instance_infos.
|
|
% XXX Ideally, this should not be necessary.
|
|
%
|
|
|
|
:- pred replace_in_instance_info(module_name::in,
|
|
maybe_record_sym_name_use::in, type_eqv_map::in, inst_eqv_map::in,
|
|
item_instance_info::in, item_instance_info::out,
|
|
maybe(recompilation_info)::in, maybe(recompilation_info)::out,
|
|
used_modules::in, used_modules::out, list(error_spec)::out) is det.
|
|
|
|
replace_in_instance_info(ModuleName, MaybeRecord, TypeEqvMap, _InstEqvMap,
|
|
InstanceInfo0, InstanceInfo, !RecompInfo, !UsedModules, []) :-
|
|
InstanceInfo0 = item_instance_info(ClassName, Types0, OriginalTypes,
|
|
Constraints0, InstanceBody0, TVarSet0, ContainingModuleName,
|
|
Context, SeqNum),
|
|
( if
|
|
( !.RecompInfo = no
|
|
; ContainingModuleName = ModuleName
|
|
)
|
|
then
|
|
UsedTypeCtors0 = no_eqv_expand_info
|
|
else
|
|
UsedTypeCtors0 = eqv_expand_info(ModuleName, set.init)
|
|
),
|
|
replace_in_prog_constraint_list_location(MaybeRecord, TypeEqvMap,
|
|
Constraints0, Constraints, TVarSet0, TVarSet1,
|
|
UsedTypeCtors0, UsedTypeCtors1, !UsedModules),
|
|
replace_in_type_list_location_circ(MaybeRecord, TypeEqvMap, Types0, Types,
|
|
_, _, TVarSet1, TVarSet, UsedTypeCtors1, UsedTypeCtors, !UsedModules),
|
|
(
|
|
InstanceBody0 = instance_body_abstract,
|
|
InstanceBody = instance_body_abstract
|
|
;
|
|
InstanceBody0 = instance_body_concrete(_InstanceMethods0),
|
|
InstanceBody = InstanceBody0
|
|
% We don't yet have code to expand out type equivalences in explicit
|
|
% type qualifications in clauses.
|
|
%
|
|
% replace_in_list(ModuleName, MaybeRecord, TypeEqvMap, InstEqvMap,
|
|
% replace_in_instance_method, InstanceMethods0, InstanceMethods,
|
|
% !RecompInfo, !UsedModules, [], Specs),
|
|
% InstanceBody = instance_body_concrete(InstanceMethods)
|
|
),
|
|
% We specifically do NOT expand equivalence types in OriginalTypes.
|
|
% If we did, that would defeat the purpose of the field.
|
|
ItemName = recomp_item_name(ClassName, list.length(Types0)),
|
|
ItemId = recomp_item_id(recomp_typeclass, ItemName),
|
|
finish_recording_expanded_items(ItemId, UsedTypeCtors, !RecompInfo),
|
|
InstanceInfo = item_instance_info(ClassName, Types, OriginalTypes,
|
|
Constraints, InstanceBody, TVarSet, ContainingModuleName,
|
|
Context, SeqNum).
|
|
|
|
:- pred replace_in_abstract_instance_info(module_name::in,
|
|
maybe_record_sym_name_use::in, type_eqv_map::in, inst_eqv_map::in,
|
|
item_abstract_instance_info::in, item_abstract_instance_info::out,
|
|
maybe(recompilation_info)::in, maybe(recompilation_info)::out,
|
|
used_modules::in, used_modules::out, list(error_spec)::out) is det.
|
|
|
|
replace_in_abstract_instance_info(ModuleName, MaybeRecord, TypeEqvMap, _,
|
|
InstanceInfo0, InstanceInfo, !RecompInfo, !UsedModules, []) :-
|
|
InstanceInfo0 = item_instance_info(ClassName, Types0, OriginalTypes,
|
|
Constraints0, InstanceBody, TVarSet0, ContainingModuleName,
|
|
Context, SeqNum),
|
|
( if
|
|
( !.RecompInfo = no
|
|
; ContainingModuleName = ModuleName
|
|
)
|
|
then
|
|
UsedTypeCtors0 = no_eqv_expand_info
|
|
else
|
|
UsedTypeCtors0 = eqv_expand_info(ModuleName, set.init)
|
|
),
|
|
replace_in_prog_constraint_list_location(MaybeRecord, TypeEqvMap,
|
|
Constraints0, Constraints, TVarSet0, TVarSet1,
|
|
UsedTypeCtors0, UsedTypeCtors1, !UsedModules),
|
|
replace_in_type_list_location_circ(MaybeRecord, TypeEqvMap, Types0, Types,
|
|
_, _, TVarSet1, TVarSet, UsedTypeCtors1, UsedTypeCtors, !UsedModules),
|
|
% We specifically do NOT expand equivalence types in OriginalTypes.
|
|
% If we did, that would defeat the purpose of the field.
|
|
ItemName = recomp_item_name(ClassName, list.length(Types0)),
|
|
ItemId = recomp_item_id(recomp_typeclass, ItemName),
|
|
finish_recording_expanded_items(ItemId, UsedTypeCtors, !RecompInfo),
|
|
InstanceInfo = item_instance_info(ClassName, Types, OriginalTypes,
|
|
Constraints, InstanceBody, TVarSet, ContainingModuleName,
|
|
Context, SeqNum).
|
|
|
|
%---------------------%
|
|
|
|
% We don't yet have code to expand out type equivalences in explicit
|
|
% type qualifications in clauses.
|
|
%
|
|
% :- pred replace_in_instance_method(module_name::in,
|
|
% maybe_record_sym_name_use::in, type_eqv_map::in, inst_eqv_map::in,
|
|
% instance_method::in, instance_method::out,
|
|
% maybe(recompilation_info)::in, maybe(recompilation_info)::out,
|
|
% used_modules::in, used_modules::out, list(error_spec)::out) is det.
|
|
|
|
% replace_in_instance_method(ModuleName, MaybeRecord, TypeEqvMap, InstEqvMap,
|
|
% InstanceMethod0, InstanceMethod, !RecompInfo, !UsedModules, Specs) :-
|
|
% InstanceMethod0 = instance_method(_MethorNameArity, _ProcDef0, _Context),
|
|
% (
|
|
% ProcDef0 = instance_proc_def_name(_Name),
|
|
% InstanceMethod = InstanceMethod0
|
|
% ;
|
|
% ProcDef0 = instance_proc_def_clauses(Clauses0),
|
|
% replace_in_clauses(..., Clauses0, Clauses, ...),
|
|
% ProcDef = instance_proc_def_clauses(Clauses),
|
|
% InstanceMethod = instance_method(MethorNameArity, ProcDef, Context)
|
|
% ).
|
|
|
|
%---------------------%
|
|
|
|
:- pred replace_in_decl_pragma_info(module_name::in,
|
|
maybe_record_sym_name_use::in, type_eqv_map::in, inst_eqv_map::in,
|
|
item_decl_pragma_info::in, item_decl_pragma_info::out,
|
|
maybe(recompilation_info)::in, maybe(recompilation_info)::out,
|
|
used_modules::in, used_modules::out, list(error_spec)::out) is det.
|
|
|
|
replace_in_decl_pragma_info(ModuleName, MaybeRecord, TypeEqvMap, InstEqvMap,
|
|
DeclPragma0, DeclPragma, !RecompInfo, !UsedModules, Specs) :-
|
|
(
|
|
DeclPragma0 = decl_pragma_type_spec(TypeSpec0),
|
|
replace_in_decl_pragma_type_spec(ModuleName, MaybeRecord,
|
|
TypeEqvMap, InstEqvMap, TypeSpec0, TypeSpec,
|
|
!RecompInfo, !UsedModules, Specs),
|
|
DeclPragma = decl_pragma_type_spec(TypeSpec)
|
|
;
|
|
( DeclPragma0 = decl_pragma_obsolete_pred(_)
|
|
; DeclPragma0 = decl_pragma_obsolete_proc(_)
|
|
; DeclPragma0 = decl_pragma_format_call(_)
|
|
; DeclPragma0 = decl_pragma_oisu(_)
|
|
; DeclPragma0 = decl_pragma_termination(_)
|
|
; DeclPragma0 = decl_pragma_termination2(_)
|
|
; DeclPragma0 = decl_pragma_struct_reuse(_)
|
|
; DeclPragma0 = decl_pragma_struct_sharing(_)
|
|
),
|
|
DeclPragma = DeclPragma0,
|
|
Specs = []
|
|
).
|
|
|
|
:- pred replace_in_decl_pragma_type_spec(module_name::in,
|
|
maybe_record_sym_name_use::in, type_eqv_map::in, inst_eqv_map::in,
|
|
decl_pragma_type_spec_info::in, decl_pragma_type_spec_info::out,
|
|
maybe(recompilation_info)::in, maybe(recompilation_info)::out,
|
|
used_modules::in, used_modules::out, list(error_spec)::out) is det.
|
|
|
|
replace_in_decl_pragma_type_spec(ModuleName, MaybeRecord,
|
|
TypeEqvMap, _InstEqvMap, TypeSpecInfo0, TypeSpecInfo,
|
|
!RecompInfo, !UsedModules, []) :-
|
|
TypeSpecInfo0 = decl_pragma_type_spec_info(PFUMM, PredName, NewName,
|
|
Subst0, TVarSet0, ItemIds0, Context, SeqNum),
|
|
( if
|
|
( !.RecompInfo = no
|
|
; PredName = qualified(ModuleName, _)
|
|
)
|
|
then
|
|
ExpandedItems0 = no_eqv_expand_info
|
|
else
|
|
ExpandedItems0 = eqv_expand_info(ModuleName, ItemIds0)
|
|
),
|
|
Subst0 = one_or_more(HeadSubst0, TailSubsts0),
|
|
replace_in_subst(MaybeRecord, TypeEqvMap,
|
|
HeadSubst0, HeadSubst, TailSubsts0, TailSubsts,
|
|
TVarSet0, TVarSet, ExpandedItems0, ExpandedItems, !UsedModules),
|
|
Subst = one_or_more(HeadSubst, TailSubsts),
|
|
(
|
|
ExpandedItems = no_eqv_expand_info,
|
|
ItemIds = ItemIds0
|
|
;
|
|
ExpandedItems = eqv_expand_info(_, ItemIds)
|
|
),
|
|
TypeSpecInfo = decl_pragma_type_spec_info(PFUMM, PredName, NewName,
|
|
Subst, TVarSet, ItemIds, Context, SeqNum).
|
|
|
|
%---------------------%
|
|
|
|
:- pred replace_in_foreign_proc(module_name::in,
|
|
maybe_record_sym_name_use::in, type_eqv_map::in, inst_eqv_map::in,
|
|
item_foreign_proc_info::in, item_foreign_proc_info::out,
|
|
maybe(recompilation_info)::in, maybe(recompilation_info)::out,
|
|
used_modules::in, used_modules::out, list(error_spec)::out) is det.
|
|
|
|
replace_in_foreign_proc(ModuleName, MaybeRecord, TypeEqvMap, _InstEqvMap,
|
|
FPInfo0, FPInfo, !RecompInfo, !UsedModules, []) :-
|
|
FPInfo0 = item_foreign_proc_info(Attrs0, PName, PredOrFunc,
|
|
ProcVars, ProcVarset, ProcInstVarset, ProcImpl, Context, SeqNum),
|
|
some [!EquivTypeInfo] (
|
|
maybe_start_recording_expanded_items(ModuleName, PName,
|
|
!.RecompInfo, !:EquivTypeInfo),
|
|
UserSharing0 = get_user_annotated_sharing(Attrs0),
|
|
( if
|
|
UserSharing0 = user_sharing(Sharing0, MaybeTypes0),
|
|
MaybeTypes0 = yes(user_type_info(Types0, TVarSet0))
|
|
then
|
|
replace_in_type_list_location(MaybeRecord,
|
|
TypeEqvMap, Types0, Types, _AnythingChanged,
|
|
TVarSet0, TVarSet, !EquivTypeInfo, !UsedModules),
|
|
replace_in_structure_sharing_domain(MaybeRecord, TypeEqvMap,
|
|
TVarSet0, Sharing0, Sharing, !EquivTypeInfo, !UsedModules),
|
|
MaybeTypes = yes(user_type_info(Types, TVarSet)),
|
|
UserSharing = user_sharing(Sharing, MaybeTypes),
|
|
set_user_annotated_sharing(UserSharing, Attrs0, Attrs)
|
|
else
|
|
Attrs = Attrs0
|
|
),
|
|
ItemName = recomp_item_name(PName, list.length(ProcVars)),
|
|
ItemId = recomp_item_id(recomp_foreign_proc, ItemName),
|
|
finish_recording_expanded_items(ItemId, !.EquivTypeInfo, !RecompInfo)
|
|
),
|
|
FPInfo = item_foreign_proc_info(Attrs, PName, PredOrFunc,
|
|
ProcVars, ProcVarset, ProcInstVarset, ProcImpl, Context, SeqNum).
|
|
|
|
%---------------------%
|
|
|
|
:- pred replace_in_mutable_info(module_name::in, maybe_record_sym_name_use::in,
|
|
type_eqv_map::in, inst_eqv_map::in,
|
|
item_mutable_info::in, item_mutable_info::out,
|
|
maybe(recompilation_info)::in, maybe(recompilation_info)::out,
|
|
used_modules::in, used_modules::out, list(error_spec)::out) is det.
|
|
|
|
replace_in_mutable_info(ModuleName, MaybeRecord, TypeEqvMap, InstEqvMap,
|
|
Info0, Info, !RecompInfo, !UsedModules, []) :-
|
|
MutName = Info0 ^ mut_name,
|
|
QualName = qualified(ModuleName, MutName),
|
|
maybe_start_recording_expanded_items(ModuleName, QualName, !.RecompInfo,
|
|
ExpandedItems0),
|
|
replace_in_mutable_defn(MaybeRecord, TypeEqvMap, InstEqvMap, Info0, Info,
|
|
ExpandedItems0, ExpandedItems, !UsedModules),
|
|
ItemId = recomp_item_id(recomp_mutable, recomp_item_name(QualName, 0)),
|
|
finish_recording_expanded_items(ItemId, ExpandedItems, !RecompInfo).
|
|
|
|
:- pred replace_in_mutable_defn(maybe_record_sym_name_use::in,
|
|
type_eqv_map::in, inst_eqv_map::in,
|
|
item_mutable_info::in, item_mutable_info::out,
|
|
eqv_expand_info::in, eqv_expand_info::out,
|
|
used_modules::in, used_modules::out) is det.
|
|
|
|
replace_in_mutable_defn(MaybeRecord, TypeEqvMap, InstEqvMap, Info0, Info,
|
|
!ExpandedItems, !UsedModules) :-
|
|
Info0 = item_mutable_info(MutName, OrigType, Type0, OrigInst, Inst0,
|
|
InitValue, Attrs, Varset, Context, SeqNum),
|
|
TVarSet0 = varset.init,
|
|
replace_in_type_maybe_record_use(MaybeRecord, TypeEqvMap, Type0, Type,
|
|
_TypeChanged, TVarSet0, _TVarSet, !ExpandedItems, !UsedModules),
|
|
replace_in_inst(MaybeRecord, InstEqvMap, Inst0, Inst, !ExpandedItems,
|
|
!UsedModules),
|
|
Info = item_mutable_info(MutName, OrigType, Type, OrigInst, Inst,
|
|
InitValue, Attrs, Varset, Context, SeqNum).
|
|
|
|
%---------------------%
|
|
|
|
:- pred replace_in_event_specs(type_eqv_map::in,
|
|
assoc_list(string, event_spec)::in, assoc_list(string, event_spec)::out,
|
|
maybe(recompilation_info)::in, maybe(recompilation_info)::out,
|
|
used_modules::in, used_modules::out,
|
|
list(error_spec)::in, list(error_spec)::out) is det.
|
|
|
|
replace_in_event_specs(_, [], [], !RecompInfo, !UsedModules, !Specs).
|
|
replace_in_event_specs(TypeEqvMap,
|
|
[Name - EventSpec0 | NameSpecs0], [Name - EventSpec | NameSpecs],
|
|
!RecompInfo, !UsedModules, !Specs) :-
|
|
replace_in_event_spec(TypeEqvMap, EventSpec0, EventSpec,
|
|
!RecompInfo, !UsedModules, !Specs),
|
|
replace_in_event_specs(TypeEqvMap, NameSpecs0, NameSpecs,
|
|
!RecompInfo, !UsedModules, !Specs).
|
|
|
|
:- pred replace_in_event_spec(type_eqv_map::in,
|
|
event_spec::in, event_spec::out,
|
|
maybe(recompilation_info)::in, maybe(recompilation_info)::out,
|
|
used_modules::in, used_modules::out,
|
|
list(error_spec)::in, list(error_spec)::out) is det.
|
|
|
|
replace_in_event_spec(TypeEqvMap, EventSpec0, EventSpec,
|
|
!RecompInfo, !UsedModules, !Specs) :-
|
|
EventSpec0 = event_spec(EventNumber, EventName, EventLineNumber,
|
|
Attrs0, SyntAttrNumOrder),
|
|
replace_in_event_attrs(TypeEqvMap, Attrs0, Attrs,
|
|
!RecompInfo, !UsedModules, !Specs),
|
|
EventSpec = event_spec(EventNumber, EventName, EventLineNumber,
|
|
Attrs, SyntAttrNumOrder).
|
|
|
|
:- pred replace_in_event_attrs(type_eqv_map::in,
|
|
list(event_attribute)::in, list(event_attribute)::out,
|
|
maybe(recompilation_info)::in, maybe(recompilation_info)::out,
|
|
used_modules::in, used_modules::out,
|
|
list(error_spec)::in, list(error_spec)::out) is det.
|
|
|
|
replace_in_event_attrs(_TypeEqvMap, [], [],
|
|
!RecompInfo, !UsedModules, !Specs).
|
|
replace_in_event_attrs(TypeEqvMap, [Attr0 | Attrs0], [Attr | Attrs],
|
|
!RecompInfo, !UsedModules, !Specs) :-
|
|
replace_in_event_attr(TypeEqvMap, Attr0, Attr,
|
|
!RecompInfo, !UsedModules, !Specs),
|
|
replace_in_event_attrs(TypeEqvMap, Attrs0, Attrs,
|
|
!RecompInfo, !UsedModules, !Specs).
|
|
|
|
:- pred replace_in_event_attr(type_eqv_map::in,
|
|
event_attribute::in, event_attribute::out,
|
|
maybe(recompilation_info)::in, maybe(recompilation_info)::out,
|
|
used_modules::in, used_modules::out,
|
|
list(error_spec)::in, list(error_spec)::out) is det.
|
|
|
|
replace_in_event_attr(TypeEqvMap, Attr0, Attr,
|
|
!RecompInfo, !UsedModules, !Specs) :-
|
|
% We construct the attributes' modes ourselves in event_spec.m; they should
|
|
% not contain type names.
|
|
Attr0 = event_attribute(AttrNum, AttrName, AttrType0, AttrMode,
|
|
MaybeSynthCall),
|
|
TVarSet0 = varset.init,
|
|
replace_in_type_maybe_record_use(dont_record_sym_name_use, TypeEqvMap,
|
|
AttrType0, AttrType, _Changed, TVarSet0, _TVarSet,
|
|
no_eqv_expand_info, _EquivTypeInfo, !UsedModules),
|
|
Attr = event_attribute(AttrNum, AttrName, AttrType, AttrMode,
|
|
MaybeSynthCall).
|
|
|
|
%---------------------------------------------------------------------------%
|
|
|
|
:- pred replace_in_type_defn(maybe_record_sym_name_use::in,
|
|
type_eqv_map::in, inst_eqv_map::in, type_ctor::in, prog_context::in,
|
|
type_defn::in, type_defn::out,
|
|
tvarset::in, tvarset::out, eqv_expand_info::in, eqv_expand_info::out,
|
|
used_modules::in, used_modules::out, list(error_spec)::out) is det.
|
|
|
|
replace_in_type_defn(MaybeRecord, TypeEqvMap, InstEqvMap, TypeCtor, Context,
|
|
TypeDefn0, TypeDefn, !TVarSet, !EquivTypeInfo, !UsedModules, Specs) :-
|
|
(
|
|
TypeDefn0 = parse_tree_eqv_type(DetailsEqv0),
|
|
replace_in_type_defn_eqv(MaybeRecord, TypeEqvMap, InstEqvMap,
|
|
TypeCtor, Context, DetailsEqv0, DetailsEqv,
|
|
!TVarSet, !EquivTypeInfo, !UsedModules, Specs),
|
|
TypeDefn = parse_tree_eqv_type(DetailsEqv)
|
|
;
|
|
TypeDefn0 = parse_tree_du_type(DetailsDu0),
|
|
replace_in_type_defn_du(MaybeRecord, TypeEqvMap, InstEqvMap,
|
|
TypeCtor, Context, DetailsDu0, DetailsDu,
|
|
!TVarSet, !EquivTypeInfo, !UsedModules, Specs),
|
|
TypeDefn = parse_tree_du_type(DetailsDu)
|
|
;
|
|
TypeDefn0 = parse_tree_sub_type(DetailsSub0),
|
|
replace_in_type_defn_sub(MaybeRecord, TypeEqvMap, InstEqvMap,
|
|
TypeCtor, Context, DetailsSub0, DetailsSub,
|
|
!TVarSet, !EquivTypeInfo, !UsedModules, Specs),
|
|
TypeDefn = parse_tree_sub_type(DetailsSub)
|
|
;
|
|
TypeDefn0 = parse_tree_solver_type(DetailsSolver0),
|
|
replace_in_type_defn_solver(MaybeRecord, TypeEqvMap, InstEqvMap,
|
|
TypeCtor, Context, DetailsSolver0, DetailsSolver,
|
|
!TVarSet, !EquivTypeInfo, !UsedModules, Specs),
|
|
TypeDefn = parse_tree_solver_type(DetailsSolver)
|
|
;
|
|
( TypeDefn0 = parse_tree_abstract_type(_)
|
|
; TypeDefn0 = parse_tree_foreign_type(_)
|
|
),
|
|
TypeDefn = TypeDefn0,
|
|
Specs = []
|
|
).
|
|
|
|
:- pred replace_in_type_defn_eqv(maybe_record_sym_name_use::in,
|
|
type_eqv_map::in, inst_eqv_map::in, type_ctor::in, prog_context::in,
|
|
type_details_eqv::in, type_details_eqv::out,
|
|
tvarset::in, tvarset::out, eqv_expand_info::in, eqv_expand_info::out,
|
|
used_modules::in, used_modules::out, list(error_spec)::out) is det.
|
|
|
|
replace_in_type_defn_eqv(MaybeRecord, TypeEqvMap, _InstEqvMap, TypeCtor,
|
|
Context, DetailsEqv0, DetailsEqv,
|
|
!TVarSet, !EquivTypeInfo, !UsedModules, Specs) :-
|
|
DetailsEqv0 = type_details_eqv(TypeBody0),
|
|
replace_in_type_maybe_record_use_2(MaybeRecord, TypeEqvMap, [TypeCtor],
|
|
TypeBody0, TypeBody, _, Circ, !TVarSet, !EquivTypeInfo, !UsedModules),
|
|
set.to_sorted_list(Circ, CircTypes),
|
|
(
|
|
CircTypes = [_ | _],
|
|
Specs = [report_circular_eqv_type(TypeCtor, Context)]
|
|
;
|
|
CircTypes = [],
|
|
Specs = []
|
|
),
|
|
DetailsEqv = type_details_eqv(TypeBody).
|
|
|
|
:- func report_circular_eqv_type(type_ctor, prog_context) = error_spec.
|
|
|
|
report_circular_eqv_type(TypeCtor, Context) = Spec :-
|
|
Pieces = [words("Error: circular equivalence type"),
|
|
qual_type_ctor(TypeCtor), suffix("."), nl],
|
|
Spec = simplest_spec($pred, severity_error, phase_expand_types,
|
|
Context, Pieces).
|
|
|
|
:- func report_contains_circular_eqv_type(tvarset, mer_type, prog_context,
|
|
type_ctor, list(type_ctor)) = error_spec.
|
|
|
|
report_contains_circular_eqv_type(TVarSet, Type, Context,
|
|
HeadTypeCtor, TailTypeCtors) = Spec :-
|
|
TypeStr = mercury_type_to_string(TVarSet, print_name_only, Type),
|
|
MainPieces = [words("Error: the type"), quote(TypeStr),
|
|
words("cannot have its equivalences fully expanded,"),
|
|
words("because its expansion contains")],
|
|
(
|
|
TailTypeCtors = [],
|
|
CircSpecs = [words("the circular equivalence type"),
|
|
qual_type_ctor(HeadTypeCtor), suffix("."), nl]
|
|
;
|
|
TailTypeCtors = [_ | _],
|
|
TypeCtorPieces = list.map((func(TC) = qual_type_ctor(TC)),
|
|
[HeadTypeCtor | TailTypeCtors]),
|
|
CircSpecs = [words("the circular equivalence types")] ++
|
|
component_list_to_pieces("and", TypeCtorPieces) ++
|
|
[suffix("."), nl]
|
|
),
|
|
Pieces = MainPieces ++ CircSpecs,
|
|
Spec = simplest_spec($pred, severity_error, phase_expand_types,
|
|
Context, Pieces).
|
|
|
|
:- pred replace_in_type_defn_du(maybe_record_sym_name_use::in,
|
|
type_eqv_map::in, inst_eqv_map::in, type_ctor::in, prog_context::in,
|
|
type_details_du::in, type_details_du::out,
|
|
tvarset::in, tvarset::out, eqv_expand_info::in, eqv_expand_info::out,
|
|
used_modules::in, used_modules::out, list(error_spec)::out) is det.
|
|
|
|
replace_in_type_defn_du(MaybeRecord, TypeEqvMap, _InstEqvMap,
|
|
_TypeCtor, _Context, DetailsDu0, DetailsDu,
|
|
!TVarSet, !EquivTypeInfo, !UsedModules, Specs) :-
|
|
DetailsDu0 = type_details_du(Ctors0, MaybeCanon, DirectArgFunctors),
|
|
replace_in_ctors_location(MaybeRecord, TypeEqvMap, Ctors0, Ctors,
|
|
!TVarSet, !EquivTypeInfo, !UsedModules),
|
|
DetailsDu = type_details_du(Ctors, MaybeCanon, DirectArgFunctors),
|
|
Specs = [].
|
|
|
|
:- pred replace_in_type_defn_sub(maybe_record_sym_name_use::in,
|
|
type_eqv_map::in, inst_eqv_map::in, type_ctor::in, prog_context::in,
|
|
type_details_sub::in, type_details_sub::out,
|
|
tvarset::in, tvarset::out, eqv_expand_info::in, eqv_expand_info::out,
|
|
used_modules::in, used_modules::out, list(error_spec)::out) is det.
|
|
|
|
replace_in_type_defn_sub(MaybeRecord, TypeEqvMap, _InstEqvMap,
|
|
_TypeCtor, _Context, DetailsSub0, DetailsSub,
|
|
!TVarSet, !EquivTypeInfo, !UsedModules, Specs) :-
|
|
DetailsSub0 = type_details_sub(SuperType0, Ctors0),
|
|
replace_in_type_maybe_record_use(MaybeRecord, TypeEqvMap,
|
|
SuperType0, SuperType, _, !TVarSet, !EquivTypeInfo, !UsedModules),
|
|
replace_in_ctors_location(MaybeRecord, TypeEqvMap, Ctors0, Ctors,
|
|
!TVarSet, !EquivTypeInfo, !UsedModules),
|
|
DetailsSub = type_details_sub(SuperType, Ctors),
|
|
Specs = [].
|
|
|
|
:- pred replace_in_type_defn_solver(maybe_record_sym_name_use::in,
|
|
type_eqv_map::in, inst_eqv_map::in, type_ctor::in, prog_context::in,
|
|
type_details_solver::in, type_details_solver::out,
|
|
tvarset::in, tvarset::out, eqv_expand_info::in, eqv_expand_info::out,
|
|
used_modules::in, used_modules::out, list(error_spec)::out) is det.
|
|
|
|
replace_in_type_defn_solver(MaybeRecord, TypeEqvMap, InstEqvMap, TypeCtor,
|
|
Context, DetailsSolver0, DetailsSolver,
|
|
!TVarSet, !EquivTypeInfo, !UsedModules, Specs) :-
|
|
DetailsSolver0 = type_details_solver(SolverDetails0, MaybeUserEqComp),
|
|
SolverDetails0 = solver_type_details(RepresentationType0,
|
|
GroundInst, AnyInst, MutableInfos0),
|
|
replace_in_type_maybe_record_use_2(MaybeRecord, TypeEqvMap, [TypeCtor],
|
|
RepresentationType0, RepresentationType,
|
|
_Changed, Circ, !TVarSet, !EquivTypeInfo, !UsedModules),
|
|
set.to_sorted_list(Circ, CircTypes),
|
|
(
|
|
CircTypes = [_ | _],
|
|
% We used to abort the compiler if we found circular equivalence types
|
|
% in any non-equivalence type definition. I (zs) don't remember
|
|
% hearing about it ever being triggered in the wild, but it
|
|
% *does* get triggered by code such as
|
|
% ":- solver type foo where representation is foo, ...".
|
|
%
|
|
% XXX I (zs) don't know in what other scenarios we may find
|
|
% circular equivalence types, so the wording of this message
|
|
% is targeted towards the above scenario.
|
|
Pieces = [words("Error: circular type expansion"),
|
|
words("in the representation of solver type"),
|
|
qual_type_ctor(TypeCtor), suffix("."), nl],
|
|
Specs = [simplest_spec($pred, severity_error, phase_expand_types,
|
|
Context, Pieces)]
|
|
;
|
|
CircTypes = [],
|
|
Specs = []
|
|
),
|
|
replace_in_constraint_store(MaybeRecord, TypeEqvMap, InstEqvMap,
|
|
MutableInfos0, MutableInfos, !EquivTypeInfo, !UsedModules),
|
|
SolverDetails = solver_type_details(RepresentationType,
|
|
GroundInst, AnyInst, MutableInfos),
|
|
DetailsSolver = type_details_solver(SolverDetails, MaybeUserEqComp).
|
|
|
|
%---------------------------------------------------------------------------%
|
|
|
|
replace_in_type_report_circular_eqvs(TypeEqvMap, TVarSet0, Context,
|
|
Type0, Type, Changed, !Specs) :-
|
|
replace_in_type_maybe_record_use_2(dont_record_sym_name_use,
|
|
TypeEqvMap, [], Type0, Type, Changed, Circ,
|
|
TVarSet0, _TVarSet, no_eqv_expand_info, _, used_modules_init, _),
|
|
set.to_sorted_list(Circ, CircTypes),
|
|
(
|
|
CircTypes = [HeadCircTypeCtor | TailCircTypeCtors],
|
|
Spec = report_contains_circular_eqv_type(TVarSet0, Type0, Context,
|
|
HeadCircTypeCtor, TailCircTypeCtors),
|
|
!:Specs = [Spec | !.Specs]
|
|
;
|
|
CircTypes = []
|
|
).
|
|
|
|
replace_in_type(TypeEqvMap, Type0, Type, Changed, !TVarSet, !EquivTypeInfo) :-
|
|
replace_in_type_maybe_record_use_2(dont_record_sym_name_use,
|
|
TypeEqvMap, [], Type0, Type, Changed, _Circ, !TVarSet,
|
|
!EquivTypeInfo, used_modules_init, _).
|
|
|
|
:- pred replace_in_type_maybe_record_use(maybe_record_sym_name_use::in,
|
|
type_eqv_map::in, mer_type::in, mer_type::out, maybe_changed::out,
|
|
tvarset::in, tvarset::out, eqv_expand_info::in, eqv_expand_info::out,
|
|
used_modules::in, used_modules::out) is det.
|
|
|
|
replace_in_type_maybe_record_use(MaybeRecord, TypeEqvMap,
|
|
Type0, Type, Changed, !TVarSet, !EquivTypeInfo, !UsedModules) :-
|
|
replace_in_type_maybe_record_use_2(MaybeRecord, TypeEqvMap, [],
|
|
Type0, Type, Changed, _, !TVarSet, !EquivTypeInfo, !UsedModules).
|
|
|
|
% Replace all equivalence types in a given type, detecting
|
|
% any circularities.
|
|
%
|
|
:- pred replace_in_type_maybe_record_use_2(maybe_record_sym_name_use::in,
|
|
type_eqv_map::in, list(type_ctor)::in, mer_type::in, mer_type::out,
|
|
maybe_changed::out, circ_types::out, tvarset::in, tvarset::out,
|
|
eqv_expand_info::in, eqv_expand_info::out,
|
|
used_modules::in, used_modules::out) is det.
|
|
|
|
replace_in_type_maybe_record_use_2(MaybeRecord, TypeEqvMap,
|
|
TypeCtorsAlreadyExpanded, Type0, Type, Changed, Circ,
|
|
!TVarSet, !EquivTypeInfo, !UsedModules) :-
|
|
(
|
|
Type0 = type_variable(Var, Kind),
|
|
Type = type_variable(Var, Kind),
|
|
Changed = unchanged,
|
|
Circ = set.init
|
|
;
|
|
Type0 = defined_type(SymName, TArgs0, Kind),
|
|
replace_in_type_list_location_circ_2(MaybeRecord, TypeEqvMap,
|
|
TypeCtorsAlreadyExpanded, TArgs0, TArgs, ArgsChanged,
|
|
set.init, Circ0, !TVarSet, !EquivTypeInfo, !UsedModules),
|
|
Arity = list.length(TArgs),
|
|
TypeCtor = type_ctor(SymName, Arity),
|
|
replace_type_ctor(MaybeRecord, TypeEqvMap, TypeCtorsAlreadyExpanded,
|
|
Type0, TypeCtor, TArgs, Kind, Type, ArgsChanged, Changed,
|
|
Circ0, Circ, !TVarSet, !EquivTypeInfo, !UsedModules)
|
|
;
|
|
Type0 = builtin_type(_),
|
|
Type = Type0,
|
|
Changed = unchanged,
|
|
Circ = set.init
|
|
;
|
|
Type0 = higher_order_type(PorF, Args0, HOInstInfo, Purity, EvalMethod),
|
|
replace_in_type_list_location_circ_2(MaybeRecord, TypeEqvMap,
|
|
TypeCtorsAlreadyExpanded, Args0, Args, Changed, set.init, Circ,
|
|
!TVarSet, !EquivTypeInfo, !UsedModules),
|
|
(
|
|
Changed = changed,
|
|
Type = higher_order_type(PorF, Args, HOInstInfo, Purity,
|
|
EvalMethod)
|
|
;
|
|
Changed = unchanged,
|
|
Type = Type0
|
|
)
|
|
;
|
|
Type0 = tuple_type(Args0, Kind),
|
|
replace_in_type_list_location_circ_2(MaybeRecord, TypeEqvMap,
|
|
TypeCtorsAlreadyExpanded, Args0, Args, Changed, set.init, Circ,
|
|
!TVarSet, !EquivTypeInfo, !UsedModules),
|
|
(
|
|
Changed = changed,
|
|
Type = tuple_type(Args, Kind)
|
|
;
|
|
Changed = unchanged,
|
|
Type = Type0
|
|
)
|
|
;
|
|
Type0 = apply_n_type(Var, Args0, Kind),
|
|
replace_in_type_list_location_circ_2(MaybeRecord, TypeEqvMap,
|
|
TypeCtorsAlreadyExpanded, Args0, Args, Changed, set.init, Circ,
|
|
!TVarSet, !EquivTypeInfo, !UsedModules),
|
|
(
|
|
Changed = changed,
|
|
Type = apply_n_type(Var, Args, Kind)
|
|
;
|
|
Changed = unchanged,
|
|
Type = Type0
|
|
)
|
|
;
|
|
Type0 = kinded_type(RawType0, Kind),
|
|
replace_in_type_maybe_record_use_2(MaybeRecord, TypeEqvMap,
|
|
TypeCtorsAlreadyExpanded, RawType0, RawType, Changed, Circ,
|
|
!TVarSet, !EquivTypeInfo, !UsedModules),
|
|
(
|
|
Changed = changed,
|
|
Type = kinded_type(RawType, Kind)
|
|
;
|
|
Changed = unchanged,
|
|
Type = Type0
|
|
)
|
|
).
|
|
|
|
:- pred replace_type_ctor(maybe_record_sym_name_use::in, type_eqv_map::in,
|
|
list(type_ctor)::in, mer_type::in, type_ctor::in, list(mer_type)::in,
|
|
kind::in, mer_type::out, maybe_changed::in, maybe_changed::out,
|
|
circ_types::in, circ_types::out, tvarset::in, tvarset::out,
|
|
eqv_expand_info::in, eqv_expand_info::out,
|
|
used_modules::in, used_modules::out) is det.
|
|
|
|
replace_type_ctor(MaybeRecord, TypeEqvMap, TypeCtorsAlreadyExpanded, Type0,
|
|
TypeCtor, TArgs, Kind, Type, !Changed, !Circ, !TVarSet,
|
|
!EquivTypeInfo, !UsedModules) :-
|
|
( if list.member(TypeCtor, TypeCtorsAlreadyExpanded) then
|
|
AlreadyExpanded = yes,
|
|
NewCirc = set.make_singleton_set(TypeCtor)
|
|
else
|
|
AlreadyExpanded = no,
|
|
NewCirc = set.init
|
|
),
|
|
( if
|
|
map.search(TypeEqvMap, TypeCtor, EqvTypeBody),
|
|
EqvTypeBody = eqv_type_body(EqvTVarSet, Args0, Body0),
|
|
|
|
% Don't merge in the variable names from the type declaration to avoid
|
|
% creating multiple variables with the same name so that
|
|
% `varset.create_name_var_map' can be used on the resulting tvarset.
|
|
% make_hlds uses `varset.create_name_var_map' to match up type
|
|
% variables in `:- pragma type_spec' declarations and explicit type
|
|
% qualifications with the type variables in the predicate's
|
|
% declaration.
|
|
|
|
tvarset_merge_renaming_without_names(!.TVarSet, EqvTVarSet, !:TVarSet,
|
|
Renaming),
|
|
set.is_empty(!.Circ),
|
|
AlreadyExpanded = no
|
|
then
|
|
maybe_record_type_ctor_sym_name_use(MaybeRecord, TypeCtor,
|
|
!UsedModules),
|
|
|
|
!:Changed = changed,
|
|
map.apply_to_list(Args0, Renaming, Args),
|
|
apply_variable_renaming_to_type(Renaming, Body0, Body1),
|
|
TypeCtorItem = type_ctor_to_recomp_item_name(TypeCtor),
|
|
record_expanded_item(recomp_item_id(recomp_type_name, TypeCtorItem),
|
|
!EquivTypeInfo),
|
|
map.from_corresponding_lists(Args, TArgs, Subst),
|
|
apply_subst_to_type(Subst, Body1, Body),
|
|
replace_in_type_maybe_record_use_2(MaybeRecord, TypeEqvMap,
|
|
[TypeCtor | TypeCtorsAlreadyExpanded], Body,
|
|
Type, _, !:Circ, !TVarSet, !EquivTypeInfo, !UsedModules)
|
|
else
|
|
(
|
|
!.Changed = changed,
|
|
TypeCtor = type_ctor(SymName, _Arity),
|
|
Type = defined_type(SymName, TArgs, Kind)
|
|
;
|
|
!.Changed = unchanged,
|
|
Type = Type0
|
|
),
|
|
set.union(NewCirc, !Circ)
|
|
).
|
|
|
|
%---------------------------------------------------------------------------%
|
|
|
|
replace_in_type_list(TypeEqvMap, !Types, Changed, !TVarSet, !EquivTypeInfo) :-
|
|
replace_in_type_list_location(dont_record_sym_name_use, TypeEqvMap,
|
|
!Types, Changed, !TVarSet, !EquivTypeInfo, used_modules_init, _).
|
|
|
|
:- pred replace_in_type_list_location(maybe_record_sym_name_use::in,
|
|
type_eqv_map::in, list(mer_type)::in, list(mer_type)::out,
|
|
maybe_changed::out, tvarset::in, tvarset::out,
|
|
eqv_expand_info::in, eqv_expand_info::out,
|
|
used_modules::in, used_modules::out) is det.
|
|
|
|
replace_in_type_list_location(MaybeRecord, TypeEqvMap, !Types,
|
|
Changed, !TVarSet, !EquivTypeInfo, !UsedModules) :-
|
|
replace_in_type_list_location_circ_2(MaybeRecord, TypeEqvMap, [], !Types,
|
|
Changed, set.init, _, !TVarSet, !EquivTypeInfo, !UsedModules).
|
|
|
|
:- pred replace_in_type_list_location_circ(maybe_record_sym_name_use::in,
|
|
type_eqv_map::in, list(mer_type)::in, list(mer_type)::out,
|
|
maybe_changed::out, circ_types::out, tvarset::in, tvarset::out,
|
|
eqv_expand_info::in, eqv_expand_info::out,
|
|
used_modules::in, used_modules::out) is det.
|
|
|
|
replace_in_type_list_location_circ(MaybeRecord, TypeEqvMap, !Types,
|
|
Changed, ContainsCirc, !TVarSet, !EquivTypeInfo, !UsedModules) :-
|
|
replace_in_type_list_location_circ_2(MaybeRecord, TypeEqvMap, [], !Types,
|
|
Changed, set.init, ContainsCirc, !TVarSet,
|
|
!EquivTypeInfo, !UsedModules).
|
|
|
|
:- pred replace_in_type_list_location_circ_2(maybe_record_sym_name_use::in,
|
|
type_eqv_map::in, list(type_ctor)::in,
|
|
list(mer_type)::in, list(mer_type)::out,
|
|
maybe_changed::out, circ_types::in, circ_types::out,
|
|
tvarset::in, tvarset::out, eqv_expand_info::in, eqv_expand_info::out,
|
|
used_modules::in, used_modules::out) is det.
|
|
|
|
replace_in_type_list_location_circ_2(_MaybeRecord, _TypeEqvMap, _Seen,
|
|
[], [], unchanged, !ContainsCirc, !TVarSet,
|
|
!EquivTypeInfo, !UsedModules).
|
|
replace_in_type_list_location_circ_2(MaybeRecord, TypeEqvMap, Seen,
|
|
List0 @ [Type0 | Types0], List, Changed, !Circ, !TVarSet,
|
|
!EquivTypeInfo, !UsedModules) :-
|
|
replace_in_type_maybe_record_use_2(MaybeRecord, TypeEqvMap, Seen,
|
|
Type0, Type, HeadChanged, HeadCirc, !TVarSet,
|
|
!EquivTypeInfo, !UsedModules),
|
|
set.union(HeadCirc, !Circ),
|
|
replace_in_type_list_location_circ_2(MaybeRecord, TypeEqvMap, Seen,
|
|
Types0, Types, TailChanged, !Circ, !TVarSet,
|
|
!EquivTypeInfo, !UsedModules),
|
|
( if
|
|
( HeadChanged = changed
|
|
; TailChanged = changed
|
|
)
|
|
then
|
|
Changed = changed,
|
|
List = [Type | Types]
|
|
else
|
|
Changed = unchanged,
|
|
List = List0
|
|
).
|
|
|
|
%---------------------------------------------------------------------------%
|
|
|
|
:- pred replace_in_ctor_arg_list(maybe_record_sym_name_use::in,
|
|
type_eqv_map::in, list(constructor_arg)::in, list(constructor_arg)::out,
|
|
circ_types::out, tvarset::in, tvarset::out,
|
|
eqv_expand_info::in, eqv_expand_info::out,
|
|
used_modules::in, used_modules::out) is det.
|
|
|
|
replace_in_ctor_arg_list(MaybeRecord, TypeEqvMap, !Args,
|
|
ContainsCirc, !TVarSet, !EquivTypeInfo, !UsedModules) :-
|
|
replace_in_ctor_arg_list_loop(MaybeRecord, TypeEqvMap, [], !Args,
|
|
set.init, ContainsCirc, !TVarSet, !EquivTypeInfo, !UsedModules).
|
|
|
|
:- pred replace_in_ctor_arg_list_loop(maybe_record_sym_name_use::in,
|
|
type_eqv_map::in, list(type_ctor)::in,
|
|
list(constructor_arg)::in, list(constructor_arg)::out,
|
|
circ_types::in, circ_types::out, tvarset::in, tvarset::out,
|
|
eqv_expand_info::in, eqv_expand_info::out,
|
|
used_modules::in, used_modules::out) is det.
|
|
|
|
replace_in_ctor_arg_list_loop(_MaybeRecord, _TypeEqvMap, _Seen, [], [],
|
|
!Circ, !TVarSet, !EquivTypeInfo, !UsedModules).
|
|
replace_in_ctor_arg_list_loop(MaybeRecord, TypeEqvMap, Seen,
|
|
[Arg0 | Args0], [Arg | Args],
|
|
!Circ, !TVarSet, !EquivTypeInfo, !UsedModules) :-
|
|
Arg0 = ctor_arg(Name, Type0, Context),
|
|
replace_in_type_maybe_record_use_2(MaybeRecord, TypeEqvMap, Seen,
|
|
Type0, Type, _, TypeCirc, !TVarSet, !EquivTypeInfo, !UsedModules),
|
|
Arg = ctor_arg(Name, Type, Context),
|
|
set.union(TypeCirc, !Circ),
|
|
replace_in_ctor_arg_list_loop(MaybeRecord, TypeEqvMap, Seen, Args0, Args,
|
|
!Circ, !TVarSet, !EquivTypeInfo, !UsedModules).
|
|
|
|
%---------------------------------------------------------------------------%
|
|
|
|
:- pred replace_in_constraint_store(maybe_record_sym_name_use::in,
|
|
type_eqv_map::in, inst_eqv_map::in,
|
|
list(item_mutable_info)::in, list(item_mutable_info)::out,
|
|
eqv_expand_info::in, eqv_expand_info::out,
|
|
used_modules::in, used_modules::out) is det.
|
|
|
|
replace_in_constraint_store(_, _, _, [], [], !EquivTypeInfo, !UsedModules).
|
|
replace_in_constraint_store(MaybeRecord, TypeEqvMap, InstEqvMap,
|
|
[MutableInfo0 | MutableInfos0], [MutableInfo | MutableInfos],
|
|
!EquivTypeInfo, !UsedModules) :-
|
|
replace_in_mutable_defn(MaybeRecord, TypeEqvMap, InstEqvMap,
|
|
MutableInfo0, MutableInfo, !EquivTypeInfo, !UsedModules),
|
|
replace_in_constraint_store(MaybeRecord, TypeEqvMap, InstEqvMap,
|
|
MutableInfos0, MutableInfos, !EquivTypeInfo, !UsedModules).
|
|
|
|
%---------------------------------------------------------------------------%
|
|
|
|
replace_in_prog_constraints(TypeEqvMap, Cs0, Cs, !TVarSet, !EquivTypeInfo) :-
|
|
replace_in_prog_constraints_location(dont_record_sym_name_use, TypeEqvMap,
|
|
Cs0, Cs, !TVarSet, !EquivTypeInfo, used_modules_init, _).
|
|
|
|
:- pred replace_in_prog_constraints_location(maybe_record_sym_name_use::in,
|
|
type_eqv_map::in, prog_constraints::in, prog_constraints::out,
|
|
tvarset::in, tvarset::out, eqv_expand_info::in, eqv_expand_info::out,
|
|
used_modules::in, used_modules::out) is det.
|
|
|
|
replace_in_prog_constraints_location(MaybeRecord, TypeEqvMap, Cs0, Cs,
|
|
!TVarSet, !EquivTypeInfo, !UsedModules) :-
|
|
Cs0 = constraints(UnivCs0, ExistCs0),
|
|
replace_in_prog_constraint_list_location(MaybeRecord, TypeEqvMap,
|
|
UnivCs0, UnivCs, !TVarSet, !EquivTypeInfo, !UsedModules),
|
|
replace_in_prog_constraint_list_location(MaybeRecord, TypeEqvMap,
|
|
ExistCs0, ExistCs, !TVarSet, !EquivTypeInfo, !UsedModules),
|
|
Cs = constraints(UnivCs, ExistCs).
|
|
|
|
replace_in_prog_constraint_list(TypeEqvMap,
|
|
!Constraints, !TVarSet, !EquivTypeInfo) :-
|
|
replace_in_prog_constraint_list_location(dont_record_sym_name_use,
|
|
TypeEqvMap, !Constraints,
|
|
!TVarSet, !EquivTypeInfo, used_modules_init, _).
|
|
|
|
:- pred replace_in_prog_constraint_list_location(maybe_record_sym_name_use::in,
|
|
type_eqv_map::in, list(prog_constraint)::in, list(prog_constraint)::out,
|
|
tvarset::in, tvarset::out, eqv_expand_info::in, eqv_expand_info::out,
|
|
used_modules::in, used_modules::out) is det.
|
|
|
|
replace_in_prog_constraint_list_location(MaybeRecord, TypeEqvMap,
|
|
!Constraints, !TVarSet, !EquivTypeInfo, !UsedModules) :-
|
|
list.map_foldl3(
|
|
replace_in_prog_constraint_location(MaybeRecord, TypeEqvMap),
|
|
!Constraints, !TVarSet, !EquivTypeInfo, !UsedModules).
|
|
|
|
:- pred replace_in_prog_constraint_location(maybe_record_sym_name_use::in,
|
|
type_eqv_map::in, prog_constraint::in, prog_constraint::out,
|
|
tvarset::in, tvarset::out, eqv_expand_info::in, eqv_expand_info::out,
|
|
used_modules::in, used_modules::out) is det.
|
|
|
|
replace_in_prog_constraint_location(MaybeRecord, TypeEqvMap,
|
|
Constraint0, Constraint, !TVarSet, !EquivTypeInfo, !UsedModules) :-
|
|
Constraint0 = constraint(ClassName, ArgTypes0),
|
|
replace_in_type_list_location_circ(MaybeRecord, TypeEqvMap,
|
|
ArgTypes0, ArgTypes, _, _, !TVarSet, !EquivTypeInfo, !UsedModules),
|
|
Constraint = constraint(ClassName, ArgTypes).
|
|
|
|
%---------------------------------------------------------------------------%
|
|
|
|
:- pred replace_in_class_interface(maybe_record_sym_name_use::in,
|
|
type_eqv_map::in, inst_eqv_map::in,
|
|
list(class_decl)::in, list(class_decl)::out,
|
|
eqv_expand_info::in, eqv_expand_info::out,
|
|
used_modules::in, used_modules::out,
|
|
list(error_spec)::in, list(error_spec)::out) is det.
|
|
|
|
replace_in_class_interface(MaybeRecord, TypeEqvMap, InstEqvMap,
|
|
ClassInterface0, ClassInterface, !EquivTypeInfo, !UsedModules,
|
|
!Specs) :-
|
|
list.map_foldl3(
|
|
replace_in_class_decl(MaybeRecord, TypeEqvMap, InstEqvMap),
|
|
ClassInterface0, ClassInterface, !EquivTypeInfo, !UsedModules, !Specs).
|
|
|
|
:- pred replace_in_class_decl(maybe_record_sym_name_use::in,
|
|
type_eqv_map::in, inst_eqv_map::in, class_decl::in, class_decl::out,
|
|
eqv_expand_info::in, eqv_expand_info::out,
|
|
used_modules::in, used_modules::out,
|
|
list(error_spec)::in, list(error_spec)::out) is det.
|
|
|
|
replace_in_class_decl(MaybeRecord, TypeEqvMap, InstEqvMap, Decl0, Decl,
|
|
!EquivTypeInfo, !UsedModules, !Specs) :-
|
|
(
|
|
Decl0 = class_decl_pred_or_func(PredOrFuncInfo0),
|
|
PredOrFuncInfo0 = class_pred_or_func_info(PredName, PredOrFunc,
|
|
TypesAndModes0, WithType0, WithInst0, MaybeDetism0,
|
|
TVarSet0, InstVarSet, ExistQVars, Purity,
|
|
ClassContext0, Context),
|
|
replace_in_pred_type(MaybeRecord, PredName, PredOrFunc, Context,
|
|
TypeEqvMap, InstEqvMap, ClassContext0, ClassContext,
|
|
TypesAndModes0, TypesAndModes, TVarSet0, TVarSet,
|
|
WithType0, WithType, WithInst0, WithInst,
|
|
MaybeDetism0, MaybeDetism, !EquivTypeInfo, !UsedModules, NewSpecs),
|
|
!:Specs = NewSpecs ++ !.Specs,
|
|
PredOrFuncInfo = class_pred_or_func_info(PredName, PredOrFunc,
|
|
TypesAndModes, WithType, WithInst, MaybeDetism,
|
|
TVarSet, InstVarSet, ExistQVars, Purity,
|
|
ClassContext, Context),
|
|
Decl = class_decl_pred_or_func(PredOrFuncInfo)
|
|
;
|
|
Decl0 = class_decl_mode(ModeInfo0),
|
|
ModeInfo0 = class_mode_info(PredName, MaybePredOrFunc0, Modes0,
|
|
WithInst0, MaybeDetism0, InstVarSet, Context),
|
|
replace_in_pred_mode(MaybeRecord, InstEqvMap,
|
|
PredName, list.length(Modes0), Context, mode_decl, ExtraModes,
|
|
MaybePredOrFunc0, MaybePredOrFunc, WithInst0, WithInst,
|
|
MaybeDetism0, MaybeDetism, !EquivTypeInfo, !UsedModules, NewSpecs),
|
|
(
|
|
ExtraModes = [],
|
|
Modes = Modes0
|
|
;
|
|
ExtraModes = [_ | _],
|
|
Modes = Modes0 ++ ExtraModes
|
|
),
|
|
!:Specs = NewSpecs ++ !.Specs,
|
|
ModeInfo = class_mode_info(PredName, MaybePredOrFunc, Modes,
|
|
WithInst, MaybeDetism, InstVarSet, Context),
|
|
Decl = class_decl_mode(ModeInfo)
|
|
).
|
|
|
|
%---------------------------------------------------------------------------%
|
|
|
|
:- pred replace_in_subst(maybe_record_sym_name_use::in, type_eqv_map::in,
|
|
pair(tvar, mer_type)::in, pair(tvar, mer_type)::out,
|
|
assoc_list(tvar, mer_type)::in, assoc_list(tvar, mer_type)::out,
|
|
tvarset::in, tvarset::out, eqv_expand_info::in, eqv_expand_info::out,
|
|
used_modules::in, used_modules::out) is det.
|
|
|
|
replace_in_subst(MaybeRecord, TypeEqvMap,
|
|
HeadVar - HeadType0, HeadVar - HeadType,
|
|
TailVarsTypes0, TailVarsTypes,
|
|
!TVarSet, !EquivTypeInfo, !UsedModules) :-
|
|
replace_in_type_maybe_record_use(MaybeRecord, TypeEqvMap,
|
|
HeadType0, HeadType, _, !TVarSet, !EquivTypeInfo, !UsedModules),
|
|
(
|
|
TailVarsTypes0 = [],
|
|
TailVarsTypes = []
|
|
;
|
|
TailVarsTypes0 = [HeadTailVarType0 | TailTailVarsTypes0],
|
|
replace_in_subst(MaybeRecord, TypeEqvMap,
|
|
HeadTailVarType0, HeadTailVarType,
|
|
TailTailVarsTypes0, TailTailVarsTypes,
|
|
!TVarSet, !EquivTypeInfo, !UsedModules),
|
|
TailVarsTypes = [HeadTailVarType | TailTailVarsTypes]
|
|
).
|
|
|
|
%---------------------------------------------------------------------------%
|
|
|
|
replace_in_ctors(TypeEqvMap, !Ctors, !TVarSet, !EquivTypeInfo) :-
|
|
replace_in_ctors_location(dont_record_sym_name_use, TypeEqvMap,
|
|
!Ctors, !TVarSet, !EquivTypeInfo, used_modules_init, _).
|
|
|
|
:- pred replace_in_ctors_location(maybe_record_sym_name_use::in,
|
|
type_eqv_map::in,
|
|
one_or_more(constructor)::in, one_or_more(constructor)::out,
|
|
tvarset::in, tvarset::out, eqv_expand_info::in, eqv_expand_info::out,
|
|
used_modules::in, used_modules::out) is det.
|
|
|
|
replace_in_ctors_location(MaybeRecord, TypeEqvMap, Ctors0, Ctors, !TVarSet,
|
|
!EquivTypeInfo, !UsedModules) :-
|
|
Ctors0 = one_or_more(HeadCtor0, TailCtors0),
|
|
replace_in_ctor(MaybeRecord, TypeEqvMap, HeadCtor0, HeadCtor,
|
|
!TVarSet, !EquivTypeInfo, !UsedModules),
|
|
list.map_foldl3(replace_in_ctor(MaybeRecord, TypeEqvMap),
|
|
TailCtors0, TailCtors,
|
|
!TVarSet, !EquivTypeInfo, !UsedModules),
|
|
Ctors = one_or_more(HeadCtor, TailCtors).
|
|
|
|
:- pred replace_in_ctor(maybe_record_sym_name_use::in, type_eqv_map::in,
|
|
constructor::in, constructor::out, tvarset::in, tvarset::out,
|
|
eqv_expand_info::in, eqv_expand_info::out,
|
|
used_modules::in, used_modules::out) is det.
|
|
|
|
replace_in_ctor(MaybeRecord, TypeEqvMap, Ctor0, Ctor,
|
|
!TVarSet, !EquivTypeInfo, !UsedModules) :-
|
|
Ctor0 = ctor(Ordinal, MaybeExistConstraints0, CtorName, CtorArgs0, Arity,
|
|
Ctxt),
|
|
replace_in_ctor_arg_list(MaybeRecord, TypeEqvMap,
|
|
CtorArgs0, CtorArgs, _, !TVarSet, !EquivTypeInfo, !UsedModules),
|
|
(
|
|
MaybeExistConstraints0 = no_exist_constraints,
|
|
MaybeExistConstraints = no_exist_constraints
|
|
;
|
|
MaybeExistConstraints0 = exist_constraints(ExistConstraints0),
|
|
ExistConstraints0 = cons_exist_constraints(ExistQVars, Constraints0,
|
|
UnconstrainedExistQTVars, ConstrainedExistQTVars),
|
|
replace_in_prog_constraint_list_location(MaybeRecord, TypeEqvMap,
|
|
Constraints0, Constraints, !TVarSet, !EquivTypeInfo, !UsedModules),
|
|
ExistConstraints = cons_exist_constraints(ExistQVars, Constraints,
|
|
UnconstrainedExistQTVars, ConstrainedExistQTVars),
|
|
MaybeExistConstraints = exist_constraints(ExistConstraints)
|
|
),
|
|
Ctor = ctor(Ordinal, MaybeExistConstraints, CtorName, CtorArgs, Arity,
|
|
Ctxt).
|
|
|
|
%---------------------------------------------------------------------------%
|
|
|
|
:- pred replace_in_inst(maybe_record_sym_name_use::in, inst_eqv_map::in,
|
|
mer_inst::in, mer_inst::out, eqv_expand_info::in, eqv_expand_info::out,
|
|
used_modules::in, used_modules::out) is det.
|
|
|
|
replace_in_inst(MaybeRecord, InstEqvMap, Inst0, Inst,
|
|
!EquivTypeInfo, !UsedModules) :-
|
|
replace_in_inst_location(MaybeRecord, InstEqvMap, set.init, Inst0, Inst,
|
|
!EquivTypeInfo, !UsedModules).
|
|
|
|
:- pred replace_in_inst_location(maybe_record_sym_name_use::in,
|
|
inst_eqv_map::in, set(inst_ctor)::in, mer_inst::in, mer_inst::out,
|
|
eqv_expand_info::in, eqv_expand_info::out,
|
|
used_modules::in, used_modules::out) is det.
|
|
|
|
replace_in_inst_location(MaybeRecord, InstEqvMap, ExpandedInstCtors,
|
|
Inst0, Inst, !EquivTypeInfo, !UsedModules) :-
|
|
% XXX Need to record the used modules
|
|
( if Inst0 = defined_inst(user_inst(SymName, ArgInsts)) then
|
|
InstCtor = inst_ctor(SymName, length(ArgInsts)),
|
|
( if
|
|
set.member(InstCtor, ExpandedInstCtors)
|
|
then
|
|
Inst = Inst0
|
|
else if
|
|
map.search(InstEqvMap, InstCtor, EqvInstBody),
|
|
EqvInstBody = eqv_inst_body(EqvInstParams, EqvInst)
|
|
then
|
|
inst_substitute_arg_list(EqvInstParams, ArgInsts, EqvInst, Inst1),
|
|
InstCtorItem = inst_ctor_to_recomp_item_name(InstCtor),
|
|
record_expanded_item(recomp_item_id(recomp_inst, InstCtorItem),
|
|
!EquivTypeInfo),
|
|
replace_in_inst_location(MaybeRecord, InstEqvMap,
|
|
set.insert(ExpandedInstCtors, InstCtor), Inst1, Inst,
|
|
!EquivTypeInfo, !UsedModules)
|
|
else
|
|
Inst = Inst0
|
|
)
|
|
else
|
|
Inst = Inst0
|
|
).
|
|
|
|
%---------------------------------------------------------------------------%
|
|
|
|
:- pred replace_in_pred_type(maybe_record_sym_name_use::in, sym_name::in,
|
|
pred_or_func::in, prog_context::in, type_eqv_map::in, inst_eqv_map::in,
|
|
prog_constraints::in, prog_constraints::out,
|
|
list(type_and_mode)::in, list(type_and_mode)::out,
|
|
tvarset::in, tvarset::out,
|
|
maybe(mer_type)::in, maybe(mer_type)::out,
|
|
maybe(mer_inst)::in, maybe(mer_inst)::out,
|
|
maybe(determinism)::in, maybe(determinism)::out,
|
|
eqv_expand_info::in, eqv_expand_info::out,
|
|
used_modules::in, used_modules::out, list(error_spec)::out) is det.
|
|
|
|
replace_in_pred_type(MaybeRecord, PredName, PredOrFunc, Context,
|
|
TypeEqvMap, InstEqvMap, ClassContext0, ClassContext,
|
|
TypesAndModes0, TypesAndModes, !TVarSet,
|
|
MaybeWithType0, MaybeWithType, MaybeWithInst0, MaybeWithInst,
|
|
!MaybeDetism, !EquivTypeInfo, !UsedModules, !:Specs) :-
|
|
replace_in_prog_constraints_location(MaybeRecord, TypeEqvMap,
|
|
ClassContext0, ClassContext, !TVarSet,
|
|
!EquivTypeInfo, !UsedModules),
|
|
replace_in_types_and_modes(MaybeRecord, TypeEqvMap,
|
|
TypesAndModes0, TypesAndModes1,
|
|
!TVarSet, !EquivTypeInfo, !UsedModules),
|
|
(
|
|
MaybeWithType0 = yes(WithType0),
|
|
replace_in_type_maybe_record_use(MaybeRecord, TypeEqvMap,
|
|
WithType0, WithType, _, !TVarSet, !EquivTypeInfo, !UsedModules),
|
|
( if
|
|
type_is_higher_order_details(WithType, _Purity, PredOrFunc,
|
|
_EvalMethod, ExtraTypesPrime)
|
|
then
|
|
ExtraTypes = ExtraTypesPrime,
|
|
!:Specs = []
|
|
else
|
|
ExtraTypes = [],
|
|
Pieces1 = [words("In type declaration for"),
|
|
p_or_f(PredOrFunc), qual_sym_name(PredName), suffix(":"), nl,
|
|
words("error: expected higher order"), p_or_f(PredOrFunc),
|
|
words("type after `with_type`."), nl],
|
|
Spec1 = simplest_spec($pred, severity_error, phase_expand_types,
|
|
Context, Pieces1),
|
|
!:Specs = [Spec1]
|
|
)
|
|
;
|
|
MaybeWithType0 = no,
|
|
ExtraTypes = [],
|
|
!:Specs = []
|
|
),
|
|
|
|
replace_in_pred_mode(MaybeRecord, InstEqvMap,
|
|
PredName, list.length(TypesAndModes0), Context, type_decl,
|
|
ExtraModes, yes(PredOrFunc), _, MaybeWithInst0, _, !MaybeDetism,
|
|
!EquivTypeInfo, !UsedModules, ModeSpecs),
|
|
!:Specs = !.Specs ++ ModeSpecs,
|
|
|
|
(
|
|
!.Specs = [_ | _],
|
|
ExtraTypesAndModes = []
|
|
;
|
|
!.Specs = [],
|
|
(
|
|
ExtraModes = [],
|
|
ExtraTypesAndModes = list.map((func(Type) = type_only(Type)),
|
|
ExtraTypes)
|
|
;
|
|
ExtraModes = [_ | _],
|
|
pair_extra_types_and_modes(ExtraTypes, ExtraModes,
|
|
ExtraTypesAndModes, LeftOverExtraTypes, LeftOverExtraModes),
|
|
(
|
|
LeftOverExtraTypes = [],
|
|
LeftOverExtraModes = []
|
|
;
|
|
LeftOverExtraTypes = [],
|
|
LeftOverExtraModes = [_ | _],
|
|
list.length(ExtraTypes, NumExtraTypes),
|
|
list.length(ExtraModes, NumExtraModes),
|
|
Pieces2 = [words("In type declaration for"),
|
|
p_or_f(PredOrFunc), qual_sym_name(PredName),
|
|
suffix(":"), nl,
|
|
words("error: the `with_type` and `with_inst`"),
|
|
words("annotations are incompatible;"),
|
|
words("they specify"), int_fixed(NumExtraModes),
|
|
words(choose_number(ExtraModes, "mode", "modes")),
|
|
words("but only"), int_fixed(NumExtraTypes),
|
|
words(choose_number(ExtraTypes, "type.", "types.")), nl],
|
|
Spec2 = simplest_spec($pred, severity_error,
|
|
phase_expand_types, Context, Pieces2),
|
|
!:Specs = [Spec2 | !.Specs]
|
|
;
|
|
LeftOverExtraTypes = [_ | _],
|
|
LeftOverExtraModes = [],
|
|
list.length(ExtraTypes, NumExtraTypes),
|
|
list.length(ExtraModes, NumExtraModes),
|
|
Pieces2 = [words("In type declaration for"),
|
|
p_or_f(PredOrFunc), qual_sym_name(PredName),
|
|
suffix(":"), nl,
|
|
words("error: the `with_type` and `with_inst`"),
|
|
words("annotations are incompatible;"),
|
|
words("they specify"), int_fixed(NumExtraTypes),
|
|
words(choose_number(ExtraTypes, "type", "types")),
|
|
words("but only"), int_fixed(NumExtraModes),
|
|
words(choose_number(ExtraModes, "mode.", "modes.")), nl],
|
|
Spec2 = simplest_spec($pred, severity_error,
|
|
phase_expand_types, Context, Pieces2),
|
|
!:Specs = [Spec2 | !.Specs]
|
|
;
|
|
LeftOverExtraTypes = [_ | _],
|
|
LeftOverExtraModes = [_ | _],
|
|
% pair_extra_types_and_modes should have paired these up.
|
|
unexpected($pred, "both types and modes left over")
|
|
)
|
|
)
|
|
),
|
|
(
|
|
!.Specs = [],
|
|
MaybeWithType = no,
|
|
MaybeWithInst = no
|
|
;
|
|
!.Specs = [_ | _],
|
|
% Leave the `with_type` and `with_inst` fields so that make_hlds knows
|
|
% to discard this declaration.
|
|
MaybeWithType = MaybeWithType0,
|
|
MaybeWithInst = MaybeWithInst0
|
|
),
|
|
(
|
|
ExtraTypesAndModes = [],
|
|
TypesAndModes = TypesAndModes1
|
|
;
|
|
ExtraTypesAndModes = [_ | _],
|
|
OrigItemType = pred_or_func_to_recomp_item_type(PredOrFunc),
|
|
OrigItemName = recomp_item_name(PredName, list.length(TypesAndModes0)),
|
|
OrigItemId = recomp_item_id(OrigItemType, OrigItemName),
|
|
record_expanded_item(OrigItemId, !EquivTypeInfo),
|
|
TypesAndModes = TypesAndModes1 ++ ExtraTypesAndModes
|
|
).
|
|
|
|
:- pred pair_extra_types_and_modes(list(mer_type)::in, list(mer_mode)::in,
|
|
list(type_and_mode)::out, list(mer_type)::out, list(mer_mode)::out) is det.
|
|
|
|
pair_extra_types_and_modes([], [], [], [], []).
|
|
pair_extra_types_and_modes(LeftOverTypes @ [_ | _], [], [], LeftOverTypes, []).
|
|
pair_extra_types_and_modes([], LeftOverModes @ [_ | _], [], [], LeftOverModes).
|
|
pair_extra_types_and_modes([Type | Types], [Mode | Modes],
|
|
[type_and_mode(Type, Mode) | TypesAndModes],
|
|
LeftOverTypes, LeftOverModes) :-
|
|
pair_extra_types_and_modes(Types, Modes, TypesAndModes,
|
|
LeftOverTypes, LeftOverModes).
|
|
|
|
:- type pred_or_func_decl_type
|
|
---> type_decl
|
|
; mode_decl.
|
|
|
|
:- pred replace_in_pred_mode(maybe_record_sym_name_use::in, inst_eqv_map::in,
|
|
sym_name::in, arity::in, prog_context::in, pred_or_func_decl_type::in,
|
|
list(mer_mode)::out,
|
|
maybe(pred_or_func)::in, maybe(pred_or_func)::out,
|
|
maybe(mer_inst)::in, maybe(mer_inst)::out,
|
|
maybe(determinism)::in, maybe(determinism)::out,
|
|
eqv_expand_info::in, eqv_expand_info::out,
|
|
used_modules::in, used_modules::out, list(error_spec)::out) is det.
|
|
|
|
replace_in_pred_mode(MaybeRecord, InstEqvMap, PredName, OrigArity, Context,
|
|
DeclType, ExtraModes, MaybePredOrFunc0, MaybePredOrFunc,
|
|
MaybeWithInst0, MaybeWithInst, !MaybeDetism,
|
|
!EquivTypeInfo, !UsedModules, Specs) :-
|
|
(
|
|
MaybeWithInst0 = yes(WithInst0),
|
|
replace_in_inst(MaybeRecord, InstEqvMap, WithInst0, WithInst,
|
|
!EquivTypeInfo, !UsedModules),
|
|
( if
|
|
WithInst = ground(_, GroundInstInfo),
|
|
GroundInstInfo = higher_order(HOInst),
|
|
HOInst = pred_inst_info(PredOrFunc, ExtraModes0, _, DetPrime),
|
|
( MaybePredOrFunc0 = no
|
|
; MaybePredOrFunc0 = yes(PredOrFunc)
|
|
)
|
|
then
|
|
!:MaybeDetism = yes(DetPrime),
|
|
MaybeWithInst = no,
|
|
MaybePredOrFunc = yes(PredOrFunc),
|
|
ExtraModes = ExtraModes0,
|
|
(
|
|
MaybePredOrFunc0 = no,
|
|
RecordedPredOrFunc = pf_predicate
|
|
;
|
|
MaybePredOrFunc0 = yes(RecordedPredOrFunc)
|
|
),
|
|
ItemType = pred_or_func_to_recomp_item_type(RecordedPredOrFunc),
|
|
ItemName = recomp_item_name(PredName, OrigArity),
|
|
OrigItemId = recomp_item_id(ItemType, ItemName),
|
|
record_expanded_item(OrigItemId, !EquivTypeInfo),
|
|
Specs = []
|
|
else
|
|
ExtraModes = [],
|
|
MaybePredOrFunc = MaybePredOrFunc0,
|
|
% Leave the `with_inst` fields so that make_hlds
|
|
% knows to discard this declaration.
|
|
MaybeWithInst = MaybeWithInst0,
|
|
( DeclType = type_decl, DeclStr = "declaration"
|
|
; DeclType = mode_decl, DeclStr = "mode declaration"
|
|
),
|
|
(
|
|
MaybePredOrFunc = no,
|
|
PredOrFuncPieces = []
|
|
;
|
|
MaybePredOrFunc = yes(PredOrFunc),
|
|
PredOrFuncPieces = [p_or_f(PredOrFunc)]
|
|
),
|
|
Pieces = [words("In"), words(DeclStr), words("for")] ++
|
|
PredOrFuncPieces ++ [qual_sym_name(PredName), suffix(":"), nl,
|
|
words("error: expected higher order ")] ++ PredOrFuncPieces ++
|
|
[words("inst after `with_inst`."), nl],
|
|
Spec = simplest_spec($pred, severity_error, phase_expand_types,
|
|
Context, Pieces),
|
|
Specs = [Spec]
|
|
)
|
|
;
|
|
MaybeWithInst0 = no,
|
|
MaybeWithInst = MaybeWithInst0,
|
|
MaybePredOrFunc = MaybePredOrFunc0,
|
|
ExtraModes = [],
|
|
Specs = []
|
|
).
|
|
|
|
:- pred replace_in_types_and_modes(maybe_record_sym_name_use::in,
|
|
type_eqv_map::in, list(type_and_mode)::in, list(type_and_mode)::out,
|
|
tvarset::in, tvarset::out, eqv_expand_info::in, eqv_expand_info::out,
|
|
used_modules::in, used_modules::out) is det.
|
|
|
|
replace_in_types_and_modes(MaybeRecord, TypeEqvMap,
|
|
!TypeAndModes, !TVarSet, !EquivTypeInfo, !UsedModules) :-
|
|
list.map_foldl3(replace_in_type_and_mode(MaybeRecord, TypeEqvMap),
|
|
!TypeAndModes, !TVarSet, !EquivTypeInfo, !UsedModules).
|
|
|
|
:- pred replace_in_type_and_mode(maybe_record_sym_name_use::in,
|
|
type_eqv_map::in, type_and_mode::in, type_and_mode::out,
|
|
tvarset::in, tvarset::out, eqv_expand_info::in, eqv_expand_info::out,
|
|
used_modules::in, used_modules::out) is det.
|
|
|
|
replace_in_type_and_mode(MaybeRecord, TypeEqvMap, TypeAndMode0, TypeAndMode,
|
|
!TVarSet, !EquivTypeInfo, !UsedModules) :-
|
|
(
|
|
TypeAndMode0 = type_only(Type0),
|
|
replace_in_type_maybe_record_use(MaybeRecord, TypeEqvMap,
|
|
Type0, Type, _, !TVarSet, !EquivTypeInfo, !UsedModules),
|
|
TypeAndMode = type_only(Type)
|
|
;
|
|
TypeAndMode0 = type_and_mode(Type0, Mode),
|
|
replace_in_type_maybe_record_use(MaybeRecord, TypeEqvMap,
|
|
Type0, Type, _, !TVarSet, !EquivTypeInfo, !UsedModules),
|
|
TypeAndMode = type_and_mode(Type, Mode)
|
|
).
|
|
|
|
%---------------------------------------------------------------------------%
|
|
|
|
:- pred replace_in_structure_sharing_domain(maybe_record_sym_name_use::in,
|
|
type_eqv_map::in, tvarset::in,
|
|
structure_sharing_domain::in, structure_sharing_domain::out,
|
|
eqv_expand_info::in, eqv_expand_info::out,
|
|
used_modules::in, used_modules::out) is det.
|
|
|
|
replace_in_structure_sharing_domain(MaybeRecord, TypeEqvMap, TVarSet,
|
|
SharingDomain0, SharingDomain, !EquivTypeInfo, !UsedModules) :-
|
|
(
|
|
( SharingDomain0 = structure_sharing_bottom
|
|
; SharingDomain0 = structure_sharing_top(_)
|
|
),
|
|
SharingDomain = SharingDomain0
|
|
;
|
|
SharingDomain0 = structure_sharing_real(SharingPairs0),
|
|
list.map_foldl2(
|
|
replace_in_structure_sharing_pair(MaybeRecord, TypeEqvMap,
|
|
TVarSet),
|
|
SharingPairs0, SharingPairs, !EquivTypeInfo, !UsedModules),
|
|
SharingDomain = structure_sharing_real(SharingPairs)
|
|
).
|
|
|
|
:- pred replace_in_structure_sharing_pair(maybe_record_sym_name_use::in,
|
|
type_eqv_map::in, tvarset::in,
|
|
structure_sharing_pair::in, structure_sharing_pair::out,
|
|
eqv_expand_info::in, eqv_expand_info::out,
|
|
used_modules::in, used_modules::out) is det.
|
|
|
|
replace_in_structure_sharing_pair(MaybeRecord, TypeEqvMap, TVarSet,
|
|
SSA0 - SSB0, SSA - SSB, !EquivTypeInfo, !UsedModules) :-
|
|
replace_in_datastruct(MaybeRecord, TypeEqvMap, TVarSet, SSA0, SSA,
|
|
!EquivTypeInfo, !UsedModules),
|
|
replace_in_datastruct(MaybeRecord, TypeEqvMap, TVarSet, SSB0, SSB,
|
|
!EquivTypeInfo, !UsedModules).
|
|
|
|
:- pred replace_in_datastruct(maybe_record_sym_name_use::in,
|
|
type_eqv_map::in, tvarset::in, datastruct::in,
|
|
datastruct::out, eqv_expand_info::in, eqv_expand_info::out,
|
|
used_modules::in, used_modules::out) is det.
|
|
|
|
replace_in_datastruct(MaybeRecord, TypeEqvMap, TVarSet, DS0, DS,
|
|
!EquivTypeInfo, !UsedModules) :-
|
|
DS0 = selected_cel(Var, Sel0),
|
|
list.map_foldl2(replace_in_unit_selector(MaybeRecord, TypeEqvMap, TVarSet),
|
|
Sel0, Sel, !EquivTypeInfo, !UsedModules),
|
|
DS = selected_cel(Var, Sel).
|
|
|
|
:- pred replace_in_unit_selector(maybe_record_sym_name_use::in,
|
|
type_eqv_map::in, tvarset::in, unit_selector::in,
|
|
unit_selector::out, eqv_expand_info::in, eqv_expand_info::out,
|
|
used_modules::in, used_modules::out) is det.
|
|
|
|
replace_in_unit_selector(MaybeRecord, TypeEqvMap, TVarSet, Sel0, Sel,
|
|
!EquivTypeInfo, !UsedModules) :-
|
|
(
|
|
Sel0 = termsel(_, _),
|
|
Sel = Sel0
|
|
;
|
|
Sel0 = typesel(Type0),
|
|
replace_in_type_maybe_record_use(MaybeRecord, TypeEqvMap,
|
|
Type0, Type, _, TVarSet, _, !EquivTypeInfo, !UsedModules),
|
|
Sel = typesel(Type)
|
|
).
|
|
|
|
%---------------------------------------------------------------------------%
|
|
|
|
:- pred maybe_record_type_ctor_sym_name_use(maybe_record_sym_name_use::in,
|
|
type_ctor::in, used_modules::in, used_modules::out) is det.
|
|
|
|
maybe_record_type_ctor_sym_name_use(MaybeRecord, TypeCtor, !UsedModules) :-
|
|
(
|
|
MaybeRecord = dont_record_sym_name_use
|
|
;
|
|
MaybeRecord = record_sym_name_use(Visibility),
|
|
TypeCtor = type_ctor(TypeCtorSymName, _TypeCtorArity),
|
|
record_sym_name_module_as_used(Visibility, TypeCtorSymName,
|
|
!UsedModules)
|
|
).
|
|
|
|
%---------------------------------------------------------------------------%
|
|
:- end_module parse_tree.equiv_type.
|
|
%---------------------------------------------------------------------------%
|