mirror of
https://github.com/Mercury-Language/mercury.git
synced 2026-04-16 18:03:36 +00:00
Class and instance definitions both contain lists of methods,
predicates and/or functions, that each have one or more procedures.
Until now, we represented the methods in class and instance definitions
as lists of nothing more than pred_proc_ids. This fact complicated
several operations,
- partly because there was no simple way to tell which procedures
were part of the same predicate or function, and
- partly because the order of the list is important (we identify
each method procedure in our equivalent of vtables with a number,
which is simply the procedure's position in this list), but there was
absolutely no information about recorded about this.
This diff therefore replaces the lists of pred_proc_ids with lists of
method_infos. Each method_info contains
- the method procedure number, i.e. the vtable index,
- the pred_or_func, sym_name and user arity of the predicate or function
that the method procedure is a part of, to make it simple to test
whether two method_infos represent different modes of the same predicate
or function, or not,
- the original pred_proc_id of the method procedure, which never changes,
and
- the current pred_proc_id, which program transformations *can* change.
compiler/hlds_class.m:
Make the change above in the representations of class and instance
definitions.
Put the fields of both types into a better order, by putting
related fields next to each other.
Put a notag wrapper around method procedure numbers to prevent
accidentally mixing them up with plain integers.
Add some utility functions.
compiler/prog_data.m:
Replace three fields containing pred_or_func, sym_name and arity
in the parse tree representation of instance methods with just one,
which contains all three pieces of info. This makes it easier to operate
on them as a unit.
Change the representation of methods defined by clauses from a list
of clauses to a cord of clauses, since this supports constant-time
append.
compiler/hlds_goal.m:
Switch from plain ints to the new notag representation of method
procedure numbers in method call goals.
compiler/add_class.m:
Simplify the code for adding new classes to the HLDS.
Give some predicates better names.
compiler/check_typeclass.m:
Significantly simplify the code for that generates the pred_infos and
proc_infos implementing all the methods of an instances definition,
and construct lists of method_infos instead of lists of pred_proc_ids.
Give some predicates better names.
Some error messages about problems in instance definitions started with
In instance declaration for class/arity:
while others started with
In instance declaration for class(module_a.foo, module_b.bar):
Replace both with
In instance declaration for class(foo, bar):
because it contains more useful information than the first, and less
non-useful information than the second. Improve the wording of some
error messages.
Factor out some common code.
compiler/prog_mode.m:
compiler/prog_type.m:
compiler/prog_util.m:
Generalize the existing predicates for stripping "builtin.m" module
qualifiers from sym_names, cons_ids, insts, types and modes
to allow also the stripping of *all* module qualifiers. This capability
is now used when we print an instance's type vector as a context
for diagnostics about problems inside instance definitions.
compiler/add_pred.m:
Add a mechanism for returning the pred_id of a newly created pred_info,
whether or not it was declared using a predmode declaration. This
capability is now needed by add_class.m.
Move the code creating an error message into its own function, and export
that function for add_class.m.
compiler/polymorphism_type_info.m:
Fix some comment rot.
compiler/base_typeclass_info.m:
compiler/call_gen.m:
compiler/dead_proc_elim.m:
compiler/deep_profiling.m:
compiler/direct_arg_in_out.m:
compiler/error_msg_inst.m:
compiler/float_regs.m:
compiler/get_dependencies.m:
compiler/higher_order.m:
compiler/hlds_error_util.m:
compiler/hlds_out_goal.m:
compiler/hlds_out_typeclass_table.m:
compiler/instance_method_clauses.m:
compiler/intermod.m:
compiler/make_hlds_error.m:
compiler/ml_call_gen.m:
compiler/mode_errors.m:
compiler/modes.m:
compiler/module_qual.qualify_items.m:
compiler/old_type_constraints.m:
compiler/parse_class.m:
compiler/parse_tree_out.m:
compiler/parse_tree_out_inst.m:
compiler/polymorphism_post_copy.m:
compiler/polymorphism_type_class_info.m:
compiler/prog_item.m:
compiler/prog_rep.m:
compiler/recompilation.usage.m:
compiler/state_var.m:
compiler/type_class_info.m:
compiler/typecheck_debug.m:
compiler/typecheck_error_type_assign.m:
compiler/typecheck_errors.m:
compiler/typecheck_msgs.m:
compiler/unused_imports.m:
compiler/xml_documentation.m:
Conform to the changes above.
tests/invalid/bug476.err_exp:
tests/invalid/tc_err1.err_exp:
tests/invalid/tc_err2.err_exp:
tests/invalid/typeclass_bogus_method.err_exp:
tests/invalid/typeclass_missing_mode.err_exp:
tests/invalid/typeclass_missing_mode_2.err_exp:
tests/invalid/typeclass_mode.err_exp:
tests/invalid/typeclass_mode_2.err_exp:
tests/invalid/typeclass_mode_3.err_exp:
tests/invalid/typeclass_mode_4.err_exp:
tests/invalid/typeclass_test_10.err_exp:
tests/invalid/typeclass_test_3.err_exp:
tests/invalid/typeclass_test_4.err_exp:
tests/invalid/typeclass_test_5.err_exp:
tests/invalid/typeclass_test_9.err_exp:
Expect the updated wording of some error messages.
205 lines
7.8 KiB
Mathematica
205 lines
7.8 KiB
Mathematica
%---------------------------------------------------------------------------%
|
|
% vim: ft=mercury ts=4 sw=4 et
|
|
%---------------------------------------------------------------------------%
|
|
% Copyright (C) 2014-2015, 2018, 2020-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.
|
|
%---------------------------------------------------------------------------%
|
|
%
|
|
% This module has code that helps debug the type checker.
|
|
%
|
|
%---------------------------------------------------------------------------%
|
|
|
|
:- module check_hlds.typecheck_debug.
|
|
:- interface.
|
|
|
|
:- import_module check_hlds.type_assign.
|
|
:- import_module check_hlds.typecheck_info.
|
|
:- import_module parse_tree.
|
|
:- import_module parse_tree.prog_data.
|
|
|
|
:- import_module io.
|
|
|
|
%---------------------------------------------------------------------------%
|
|
|
|
:- pred type_checkpoint(string::in, typecheck_info::in, prog_varset::in,
|
|
type_assign_set::in, io::di, io::uo) is det.
|
|
|
|
%---------------------------------------------------------------------------%
|
|
%---------------------------------------------------------------------------%
|
|
|
|
:- implementation.
|
|
|
|
:- import_module check_hlds.type_util.
|
|
:- import_module hlds.
|
|
:- import_module hlds.hlds_class.
|
|
:- import_module libs.
|
|
:- import_module libs.file_util.
|
|
:- import_module parse_tree.mercury_to_mercury.
|
|
:- import_module parse_tree.parse_tree_out_term.
|
|
:- import_module parse_tree.prog_type.
|
|
:- import_module parse_tree.prog_type_subst.
|
|
:- import_module parse_tree.prog_util.
|
|
:- import_module parse_tree.vartypes.
|
|
|
|
:- import_module bool.
|
|
:- import_module list.
|
|
:- import_module map.
|
|
:- import_module string.
|
|
:- import_module varset.
|
|
|
|
%---------------------------------------------------------------------------%
|
|
|
|
type_checkpoint(Msg, Info, VarSet, TypeAssignSet, !IO) :-
|
|
typecheck_info_get_debug_info(Info, Debug),
|
|
(
|
|
Debug = typecheck_debug(DetailedStats),
|
|
io.output_stream(Stream, !IO),
|
|
do_type_checkpoint(Stream, Msg, DetailedStats, VarSet,
|
|
TypeAssignSet, !IO)
|
|
;
|
|
Debug = no_typecheck_debug
|
|
).
|
|
|
|
:- pred do_type_checkpoint(io.text_output_stream::in, string::in,
|
|
bool::in, prog_varset::in, type_assign_set::in, io::di, io::uo) is det.
|
|
|
|
do_type_checkpoint(Stream, Msg, Statistics, VarSet, TypeAssignSet, !IO) :-
|
|
io.format(Stream, "At %s:", [s(Msg)], !IO),
|
|
maybe_report_stats(Stream, Statistics, !IO),
|
|
io.nl(Stream, !IO),
|
|
( if
|
|
Statistics = yes,
|
|
TypeAssignSet = [TypeAssign | _]
|
|
then
|
|
type_assign_get_var_types(TypeAssign, VarTypes),
|
|
vartypes_count(VarTypes, VarTypesCount),
|
|
io.format(Stream, "\t`var -> type' map: count = %d\n",
|
|
[i(VarTypesCount)], !IO),
|
|
type_assign_get_type_bindings(TypeAssign, TypeBindings),
|
|
map.count(TypeBindings, TypeBindingsCount),
|
|
io.format(Stream, "\t`type var -> type' map: count = %d\n",
|
|
[i(TypeBindingsCount)], !IO)
|
|
else
|
|
true
|
|
),
|
|
write_type_assign_set(Stream, TypeAssignSet, VarSet, !IO).
|
|
|
|
:- pred write_type_assign_set(io.text_output_stream::in,
|
|
type_assign_set::in, prog_varset::in, io::di, io::uo) is det.
|
|
|
|
write_type_assign_set(_, [], _, !IO).
|
|
write_type_assign_set(Stream, [TypeAssign | TypeAssigns], VarSet, !IO) :-
|
|
io.write_string(Stream, "\t", !IO),
|
|
write_type_assign(Stream, TypeAssign, VarSet, !IO),
|
|
io.write_string(Stream, "\n", !IO),
|
|
write_type_assign_set(Stream, TypeAssigns, VarSet, !IO).
|
|
|
|
:- pred write_type_assign(io.text_output_stream::in,
|
|
type_assign::in, prog_varset::in, io::di, io::uo) is det.
|
|
|
|
write_type_assign(Stream, TypeAssign, VarSet, !IO) :-
|
|
type_assign_get_existq_tvars(TypeAssign, ExistQTVars),
|
|
type_assign_get_var_types(TypeAssign, VarTypes),
|
|
type_assign_get_typeclass_constraints(TypeAssign, Constraints),
|
|
type_assign_get_type_bindings(TypeAssign, TypeBindings),
|
|
type_assign_get_typevarset(TypeAssign, TypeVarSet),
|
|
vartypes_vars(VarTypes, Vars),
|
|
(
|
|
ExistQTVars = []
|
|
;
|
|
ExistQTVars = [_ | _],
|
|
io.write_string(Stream, "some [", !IO),
|
|
mercury_output_vars_vs(TypeVarSet, debug_varnums, ExistQTVars,
|
|
Stream, !IO),
|
|
io.write_string(Stream, "]\n\t", !IO)
|
|
),
|
|
write_type_assign_types(Stream, VarSet, TypeVarSet, VarTypes, TypeBindings,
|
|
no, Vars, !IO),
|
|
write_type_assign_hlds_constraints(Stream, TypeVarSet, TypeBindings,
|
|
Constraints, !IO),
|
|
io.write_string(Stream, "\n", !IO).
|
|
|
|
:- pred write_type_assign_types(io.text_output_stream::in,
|
|
prog_varset::in, tvarset::in, vartypes::in, tsubst::in, bool::in,
|
|
list(prog_var)::in, io::di, io::uo) is det.
|
|
|
|
write_type_assign_types(Stream, _, _, _, _, FoundOne, [], !IO) :-
|
|
(
|
|
FoundOne = no,
|
|
io.write_string(Stream, "(No variables were assigned a type)", !IO)
|
|
;
|
|
FoundOne = yes
|
|
).
|
|
write_type_assign_types(Stream, VarSet, TypeVarSet, VarTypes, TypeBindings,
|
|
FoundOne, [Var | Vars], !IO) :-
|
|
( if search_var_type(VarTypes, Var, Type) then
|
|
(
|
|
FoundOne = yes,
|
|
io.write_string(Stream, "\n\t", !IO)
|
|
;
|
|
FoundOne = no
|
|
),
|
|
mercury_output_var_vs(VarSet, debug_varnums, Var, Stream, !IO),
|
|
io.write_string(Stream, ": ", !IO),
|
|
write_type_with_bindings(Stream, TypeVarSet, TypeBindings, Type, !IO),
|
|
write_type_assign_types(Stream, VarSet, TypeVarSet, VarTypes,
|
|
TypeBindings, yes, Vars, !IO)
|
|
else
|
|
write_type_assign_types(Stream, VarSet, TypeVarSet, VarTypes,
|
|
TypeBindings, FoundOne, Vars, !IO)
|
|
).
|
|
|
|
% write_type_with_bindings writes out a type after applying the
|
|
% type bindings.
|
|
%
|
|
:- pred write_type_with_bindings(io.text_output_stream::in, tvarset::in,
|
|
tsubst::in, mer_type::in, io::di, io::uo) is det.
|
|
|
|
write_type_with_bindings(Stream, TypeVarSet, TypeBindings, Type0, !IO) :-
|
|
apply_rec_subst_to_type(TypeBindings, Type0, Type1),
|
|
strip_module_names_from_type(strip_builtin_module_name, Type1, Type),
|
|
mercury_output_type(TypeVarSet, print_name_and_num, Type, Stream, !IO).
|
|
|
|
:- pred write_type_assign_hlds_constraints(io.text_output_stream::in,
|
|
tvarset::in, tsubst::in, hlds_constraints::in, io::di, io::uo) is det.
|
|
|
|
write_type_assign_hlds_constraints(Stream, TypeVarSet, TypeBindings,
|
|
Constraints, !IO) :-
|
|
Constraints =
|
|
hlds_constraints(ConstraintsToProve, AssumedConstraints, _, _),
|
|
write_type_assign_constraints(Stream, TypeVarSet, TypeBindings,
|
|
AssumedConstraints, "&", !IO),
|
|
write_type_assign_constraints(Stream, TypeVarSet, TypeBindings,
|
|
ConstraintsToProve, "<=", !IO).
|
|
|
|
:- pred write_type_assign_constraints(io.text_output_stream::in, tvarset::in,
|
|
tsubst::in, list(hlds_constraint)::in, string::in, io::di, io::uo) is det.
|
|
|
|
write_type_assign_constraints(_, _, _, [], _, !IO).
|
|
write_type_assign_constraints(Stream, TypeVarSet, TypeBindings,
|
|
[Constraint | Constraints], MaybeOperator, !IO) :-
|
|
% Write & or <= only before the first constraint; put only a comma
|
|
% before the later constraints.
|
|
( if MaybeOperator = "" then
|
|
io.write_string(Stream, ",\n\t ", !IO)
|
|
else
|
|
io.format(Stream, "\n\t%s ", [s(MaybeOperator)], !IO)
|
|
),
|
|
apply_rec_subst_to_constraint(TypeBindings, Constraint, BoundConstraint),
|
|
retrieve_prog_constraint(BoundConstraint, ProgConstraint),
|
|
mercury_output_constraint(TypeVarSet, debug_varnums, ProgConstraint,
|
|
Stream, !IO),
|
|
write_type_assign_constraints(Stream, TypeVarSet, TypeBindings,
|
|
Constraints, "", !IO).
|
|
|
|
%---------------------------------------------------------------------------%
|
|
|
|
:- func debug_varnums = var_name_print.
|
|
|
|
debug_varnums = print_name_and_num.
|
|
|
|
%---------------------------------------------------------------------------%
|
|
:- end_module check_hlds.typecheck_debug.
|
|
%---------------------------------------------------------------------------%
|