Files
mercury/compiler/vartypes.m
Zoltan Somogyi 8122e83d2a Record typechecking results in var_tables.
compiler/hlds_clauses.m:
    The clauses_info type used to have two fields whose type is "vartypes".
    One contained type information we knew before typechecking, e.g. from
    explicit "Var : type" annotations, while the other contained the
    *results* of typechecking. Keep the former, but replace the latter
    with a var_table.

    Allow compiler passes that construct clauses to fill in the first field
    with the types of the head variables, because for the clauses of some
    kinds of predicates (such as predicates implementing builtins) that are
    "constructed correct" and do not need typechecking, this is all we need.

    Put the fields of clauses_info that deal with variables and their types
    next to each other, in the order in which they are filled in.

compiler/add_clause.m:
    Don't construct the context pieces needed for parsing mode annotations
    on arguments in the clause head unless the clause head's arguments
    *have* mode annotations, which they virtually never do.

compiler/add_pred.m:
compiler/add_special_pred.m:
    Put the types of the head variables into the var_table in the clauses_info
    we create for clauses for builtin predicates and unify/compare/index
    predicates respectively, for use by unused_imports.m.

compiler/typecheck.m:
    Fill in the var_table field in

    - predicates we have typechecked,
    - predicates for which we have created stub clauses that are
      "born type-correct", and
    - predicates for class methods whose code will be created later,
      during the polymorphism pass.

    In the last case, we fill in only the types of the head variables,
    preserving old behavior.

    Give some predicates more meaningful names. Inline a predicate at its
    only call site.

compiler/post_typecheck.m:
    Switch to using the var_tables computed by typechecking.

    Reset varsets in clauses_infos to empty, to tell hlds_out_pred.m
    not use it as the source of variable name info.

compiler/hlds_pred.m:
    Provide functionality to record the types of head variables
    in both vartypes and in var_tables.

compiler/hlds_out_pred.m:
    Get information about variable names from either the clauses_info's
    varset field (if the varset is nonempty, not yet having been reset
    by post_typecheck.m), or from its var_table field (if the varset
    *has* been reset to empty).

    Likewise, get information about variable types from either the
    clauses_info's var_table field (if it is not empty, having been filled in
    either by typechecking or by code created the type clauses "type-correct"
    at the start), or from its explicit_vartypes field (if the var_table field
    has not yet been filled in).

    It is possible that in the future, we may want to dump out the
    contents of the explicit_vartypes field even if the var_table
    has also been filled in. However, since the old code of write_pred
    had no such functionality, the chance we will need that in the future
    is small, and we can deal with it when the issue does arise.

compiler/goal_path.m:
compiler/hlds_out_goal.m:
compiler/intermod.m:
compiler/unify_proc.m:
    Convert these modules to use var_tables.

compiler/prog_type.m:
compiler/type_util.m:
    Record the fact that the builtin type "store_at_ref_type" is not a dummy
    type. Without this special-casing, the creation of a var_table containing
    a variable of this type would crash the compiler, because

    - unlike other builtin types, this one *has* a definition, in
      private_builtin.m, but
    - since it is a builtin type, its "definition" in the type table
      has no representation information, so the code of is_type_a_dummy
      cannot tell if that "definition" is a dummy or not.

compiler/prog_util.m:
    Provide the var_table equivalent of an existing utility predicate
    for varsets.

compiler/qual_info.m:
    Give a field of the qual_info type a more meaningful name.

compiler/typecheck_errors.m:
    Fix argument order and variable names.

compiler/vartypes.m:
compiler/var_table.m:
    Add a predicate to check whether a variable has a user-given name.

    Replace the varset_vartypes type in vartypes.m with the type_qual type
    in var_table.m, which uses var_tables, since its user, hlds_out_goal.m,
    has been converted to use var_tables. (Most variables of this type
    have been named TypeQual, which is why the type now has that name.)

compiler/inst_graph.m:
    Conform to the changes above.

    Export the definition of the inst_graph_info type, instead of exporting
    a getter and a setter for every one of its fields.

compiler/higher_order.m:
    Conform to the changes above, by calling clauses_info_init,
    instead of repeating its code here.

compiler/accumulator.m:
compiler/add_foreign_proc.m:
compiler/add_pragma_type_spec.m:
compiler/build_mode_constraints.m:
compiler/check_promise.m:
compiler/clause_to_proc.m:
compiler/format_call.m:
compiler/hhf.m:
compiler/instance_method_clauses.m:
compiler/lambda.m:
compiler/mode_constraints.m:
compiler/old_type_constraints.m:
compiler/par_loop_control.m:
compiler/polymorphism.m:
compiler/polymorphism_info.m:
compiler/prop_mode_constraints.m:
compiler/purity.m:
compiler/stm_expand.m:
compiler/structure_reuse.versions.m:
compiler/table_gen.m:
    Conform to the changes above.

tests/invalid/illtyped_compare.err_exp:
    Expect an improved variable name from unify_proc.m.

tests/invalid/try_detism.err_exp:
    Expect a different variable number for an unnamed variable.
2022-05-29 15:22:16 +10:00

205 lines
6.7 KiB
Mathematica

%---------------------------------------------------------------------------%
% vim: ft=mercury ts=4 sw=4 et
%---------------------------------------------------------------------------%
% Copyright (C) 1996-2012 The University of Melbourne.
% This file may only be copied under the terms of the GNU General
% Public License - see the file COPYING in the Mercury distribution.
%---------------------------------------------------------------------------%
%
% This module defines an ADT that records the types of the variables
% in a predicate or procedure.
%
%---------------------------------------------------------------------------%
:- module parse_tree.vartypes.
:- interface.
:- import_module parse_tree.prog_data.
:- import_module assoc_list.
:- import_module list.
:- import_module maybe.
:- import_module set.
%---------------------------------------------------------------------------%
:- type vartypes.
:- pred init_vartypes(vartypes::out) is det.
:- pred vartypes_is_empty(vartypes::in) is semidet.
:- pred vartypes_count(vartypes::in, int::out) is det.
:- pred vartypes_select(set(prog_var)::in, vartypes::in, vartypes::out) is det.
:- pred vartypes_optimize(vartypes::in, vartypes::out) is det.
:- pred add_var_type(prog_var::in, mer_type::in,
vartypes::in, vartypes::out) is det.
:- pred update_var_type(prog_var::in, mer_type::in,
vartypes::in, vartypes::out) is det.
:- pred search_insert_var_type(prog_var::in, mer_type::in,
maybe(mer_type)::out, vartypes::in, vartypes::out) is det.
:- pred is_in_vartypes(vartypes::in, prog_var::in) is semidet.
:- pred search_var_type(vartypes::in, prog_var::in, mer_type::out) is semidet.
:- func lookup_var_type_func(vartypes, prog_var) = mer_type.
:- pred lookup_var_type(vartypes::in, prog_var::in, mer_type::out) is det.
:- pred lookup_var_types(vartypes::in, list(prog_var)::in,
list(mer_type)::out) is det.
:- pred vartypes_vars(vartypes::in, list(prog_var)::out) is det.
:- pred vartypes_types(vartypes::in, list(mer_type)::out) is det.
:- pred vartypes_to_sorted_assoc_list(vartypes::in,
assoc_list(prog_var, mer_type)::out) is det.
:- pred vartypes_from_corresponding_lists(list(prog_var)::in,
list(mer_type)::in, vartypes::out) is det.
:- pred vartypes_from_sorted_assoc_list(assoc_list(prog_var, mer_type)::in,
vartypes::out) is det.
:- pred vartypes_from_rev_sorted_assoc_list(assoc_list(prog_var, mer_type)::in,
vartypes::out) is det.
:- pred vartypes_add_corresponding_lists(list(prog_var)::in,
list(mer_type)::in, vartypes::in, vartypes::out) is det.
:- pred delete_var_type(prog_var::in,
vartypes::in, vartypes::out) is det.
:- pred delete_var_types(list(prog_var)::in,
vartypes::in, vartypes::out) is det.
:- pred delete_sorted_var_types(list(prog_var)::in,
vartypes::in, vartypes::out) is det.
:- pred apply_variable_renaming_to_vartypes(tvar_renaming::in,
vartypes::in, vartypes::out) is det.
:- pred apply_subst_to_vartypes(tsubst::in, vartypes::in, vartypes::out)
is det.
:- pred apply_rec_subst_to_vartypes(tsubst::in, vartypes::in, vartypes::out)
is det.
:- pred transform_foldl_var_types(
pred(mer_type, mer_type, T, T)::in(pred(in, out, in, out) is det),
vartypes::in, vartypes::out, T::in, T::out) is det.
:- pred foldl_var_types(pred(mer_type, T, T)::in(pred(in, in, out) is det),
vartypes::in, T::in, T::out) is det.
:- type prog_var_set_types
---> prog_var_set_types(prog_varset, vartypes).
%---------------------------------------------------------------------------%
:- implementation.
:- import_module parse_tree.prog_type_subst.
:- import_module map.
:- type vartypes == map(prog_var, mer_type).
%---------------------------------------------------------------------------%
init_vartypes(VarTypes) :-
map.init(VarTypes).
vartypes_is_empty(VarTypes) :-
map.is_empty(VarTypes).
vartypes_count(VarTypes, Count) :-
map.count(VarTypes, Count).
vartypes_select(SelectedVars, !VarTypes) :-
map.select(!.VarTypes, SelectedVars, !:VarTypes).
vartypes_optimize(!VarTypes) :-
map.optimize(!VarTypes).
add_var_type(Var, Type, !VarTypes) :-
map.det_insert(Var, Type, !VarTypes).
update_var_type(Var, Type, !VarTypes) :-
map.det_update(Var, Type, !VarTypes).
search_insert_var_type(Var, NewType, MaybeOldType, !VarTypes) :-
map.search_insert(Var, NewType, MaybeOldType, !VarTypes).
is_in_vartypes(VarTypes, Var) :-
map.contains(VarTypes, Var).
search_var_type(VarTypes, Var, Type) :-
map.search(VarTypes, Var, Type).
lookup_var_type_func(VarTypes, Var) = Type :-
lookup_var_type(VarTypes, Var, Type).
lookup_var_type(VarTypes, Var, Type) :-
map.lookup(VarTypes, Var, Type).
lookup_var_types(_VarTypes, [], []).
lookup_var_types(VarTypes, [Var | Vars], [Type | Types]) :-
lookup_var_type(VarTypes, Var, Type),
lookup_var_types(VarTypes, Vars, Types).
vartypes_vars(VarTypes, Vars) :-
map.keys(VarTypes, Vars).
vartypes_types(VarTypes, Types) :-
map.values(VarTypes, Types).
vartypes_to_sorted_assoc_list(VarTypes, AssocList) :-
map.to_sorted_assoc_list(VarTypes, AssocList).
vartypes_from_corresponding_lists(Vars, Types, VarTypes) :-
map.from_corresponding_lists(Vars, Types, VarTypes).
vartypes_from_sorted_assoc_list(AssocList, VarTypes) :-
map.from_sorted_assoc_list(AssocList, VarTypes).
vartypes_from_rev_sorted_assoc_list(RevAssocList, VarTypes) :-
map.from_rev_sorted_assoc_list(RevAssocList, VarTypes).
vartypes_add_corresponding_lists(Vars, Types, !VarTypes) :-
map.det_insert_from_corresponding_lists(Vars, Types, !VarTypes).
delete_var_type(Var, !VarTypes) :-
map.delete(Var, !VarTypes).
delete_var_types(Vars, !VarTypes) :-
map.delete_list(Vars, !VarTypes).
delete_sorted_var_types(SortedVars, !VarTypes) :-
map.delete_sorted_list(SortedVars, !VarTypes).
apply_variable_renaming_to_vartypes(Renaming, !VarTypes) :-
transform_var_types(apply_variable_renaming_to_type(Renaming), !VarTypes).
apply_subst_to_vartypes(Subst, !VarTypes) :-
transform_var_types(apply_subst_to_type(Subst), !VarTypes).
apply_rec_subst_to_vartypes(Subst, !VarTypes) :-
transform_var_types(apply_rec_subst_to_type(Subst), !VarTypes).
:- pred transform_var_types(pred(mer_type, mer_type)::in(pred(in, out) is det),
vartypes::in, vartypes::out) is det.
transform_var_types(Transform, !VarTypes) :-
map.map_values_only(Transform, !VarTypes).
transform_foldl_var_types(Transform, !VarTypes, !Acc) :-
map.map_values_foldl(Transform, !VarTypes, !Acc).
foldl_var_types(Pred, VarTypes, !Acc) :-
map.foldl_values(Pred, VarTypes, !Acc).
%---------------------------------------------------------------------------%
:- end_module parse_tree.vartypes.
%---------------------------------------------------------------------------%