mirror of
https://github.com/Mercury-Language/mercury.git
synced 2025-12-20 08:19:28 +00:00
Estimated hours taken: 16
Branches: main
When the typechecker finds highly ambiguous overloading, print what symbols
were overloaded, and where they occurred. Without this information, it is
very hard to fix the error if the predicate body is at all large.
Fix some software engineering problems encountered during this process.
Modify some predicates in error_util in order to simplify their typical usage.
Change the type_ctor type to be not simply a sym_name - int pair but a type
with its own identifying type constructor. Change several other types that
were also sym_name - int pairs (mode_id, inst_id, item_name, module_qual.id
and the related simple_call_id) to have their own function symbols too.
compiler/typecheck_info.m:
Add a field to the typecheck_info structure that records the overloaded
symbols encountered.
compiler/typecheck.m:
When processing ambiguous predicate and function symbols, record this
fact in the typecheck_info.
Add a field to the cons_type_info structure to make this possible.
compiler/typecheck_errors.m:
When printing the message about highly ambiguous overloading,
what the overloaded symbols were and where they occurred.
compiler/error_util.m:
Make error_msg_specs usable with plain in and out modes by separating
out the capability requiring special modes (storing a higher order
value in a function symbol) into its own, rarely used type.
Make component_list_to_line_pieces a bit more flexible.
compiler/prog_data.m:
compiler/module_qual.m:
compiler/recompilation.m:
Change the types listed above from being equivalence types (pairs)
to being proper discriminated union types.
compiler/*.m:
Conform to the changes above.
In some cases, simplify the code's use of error_util.
tests/warnings/ambiguous_overloading.{m,exp}:
Greatly extend this test case to test the new functionality.
tests/recompilation/*.err_exp.2
Reflect the fact that the expected messages now use the standard
error_util way of quoting sym_name/arity pairs.
168 lines
6.4 KiB
Mathematica
168 lines
6.4 KiB
Mathematica
%-----------------------------------------------------------------------------%
|
|
% vim: ft=mercury ts=4 sw=4 et
|
|
%-----------------------------------------------------------------------------%
|
|
% Copyright (C) 2002-2006 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.
|
|
%-----------------------------------------------------------------------------%
|
|
%-----------------------------------------------------------------------------%
|
|
|
|
% File: hlds_code_util.m.
|
|
|
|
% Various utilities routines for use during hlds generation.
|
|
|
|
%-----------------------------------------------------------------------------%
|
|
|
|
:- module hlds.hlds_code_util.
|
|
:- interface.
|
|
|
|
:- import_module hlds.hlds_data.
|
|
:- import_module hlds.hlds_module.
|
|
:- import_module parse_tree.prog_data.
|
|
|
|
:- import_module list.
|
|
|
|
%-----------------------------------------------------------------------------%
|
|
|
|
% Are equivalence types fully expanded on this backend?
|
|
%
|
|
:- pred are_equivalence_types_expanded(module_info::in) is semidet.
|
|
|
|
% Find out how a function symbol (constructor) is represented
|
|
% in the given type.
|
|
%
|
|
:- func cons_id_to_tag(cons_id, mer_type, module_info) = cons_tag.
|
|
|
|
% Given a list of types, mangle the names so into a string which
|
|
% identifies them. The types must all have their top level functor
|
|
% bound, with any arguments free variables.
|
|
%
|
|
:- pred make_instance_string(list(mer_type)::in, string::out) is det.
|
|
|
|
%-----------------------------------------------------------------------------%
|
|
%-----------------------------------------------------------------------------%
|
|
|
|
:- implementation.
|
|
|
|
:- import_module check_hlds.type_util.
|
|
:- import_module hlds.hlds_pred.
|
|
:- import_module libs.compiler_util.
|
|
:- import_module libs.globals.
|
|
:- import_module libs.options.
|
|
:- import_module mdbcomp.prim_data.
|
|
:- import_module parse_tree.prog_io.
|
|
:- import_module parse_tree.prog_out.
|
|
:- import_module parse_tree.prog_type.
|
|
|
|
:- import_module bool.
|
|
:- import_module char.
|
|
:- import_module map.
|
|
:- import_module pair.
|
|
:- import_module string.
|
|
:- import_module term.
|
|
|
|
%-----------------------------------------------------------------------------%
|
|
|
|
are_equivalence_types_expanded(ModuleInfo) :-
|
|
module_info_get_globals(ModuleInfo, Globals),
|
|
globals.lookup_bool_option(Globals, highlevel_data, HighLevelData),
|
|
HighLevelData = yes,
|
|
globals.get_target(Globals, Target),
|
|
( Target = il
|
|
; Target = java
|
|
).
|
|
|
|
%-----------------------------------------------------------------------------%
|
|
|
|
cons_id_to_tag(int_const(I), _, _) = int_constant(I).
|
|
cons_id_to_tag(float_const(F), _, _) = float_constant(F).
|
|
cons_id_to_tag(string_const(S), _, _) = string_constant(S).
|
|
cons_id_to_tag(pred_const(ShroudedPredProcId, EvalMethod), _, _) =
|
|
pred_closure_tag(PredId, ProcId, EvalMethod) :-
|
|
proc(PredId, ProcId) = unshroud_pred_proc_id(ShroudedPredProcId).
|
|
cons_id_to_tag(type_ctor_info_const(M,T,A), _, _) =
|
|
type_ctor_info_constant(M,T,A).
|
|
cons_id_to_tag(base_typeclass_info_const(M,C,_,N), _, _) =
|
|
base_typeclass_info_constant(M,C,N).
|
|
cons_id_to_tag(type_info_cell_constructor(_), _, _) = unshared_tag(0).
|
|
cons_id_to_tag(typeclass_info_cell_constructor, _, _) = unshared_tag(0).
|
|
cons_id_to_tag(tabling_pointer_const(ShroudedPredProcId), _, _) =
|
|
tabling_pointer_constant(PredId, ProcId) :-
|
|
proc(PredId, ProcId) = unshroud_pred_proc_id(ShroudedPredProcId).
|
|
cons_id_to_tag(deep_profiling_proc_layout(ShroudedPredProcId), _, _) =
|
|
deep_profiling_proc_layout_tag(PredId, ProcId) :-
|
|
proc(PredId, ProcId) = unshroud_pred_proc_id(ShroudedPredProcId).
|
|
cons_id_to_tag(table_io_decl(ShroudedPredProcId), _, _) =
|
|
table_io_decl_tag(PredId, ProcId) :-
|
|
proc(PredId, ProcId) = unshroud_pred_proc_id(ShroudedPredProcId).
|
|
cons_id_to_tag(cons(Name, Arity), Type, ModuleInfo) = Tag :-
|
|
(
|
|
% Handle the `character' type specially.
|
|
Type = builtin(character),
|
|
Name = unqualified(ConsName),
|
|
string.char_to_string(Char, ConsName)
|
|
->
|
|
char.to_int(Char, CharCode),
|
|
Tag = int_constant(CharCode)
|
|
;
|
|
% Tuples do not need a tag. Note that unary tuples are not treated
|
|
% as no_tag types. There's no reason why they couldn't be, it's just
|
|
% not worth the effort.
|
|
type_is_tuple(Type, _)
|
|
->
|
|
Tag = single_functor
|
|
;
|
|
% Use the type to determine the type_ctor.
|
|
( type_to_ctor_and_args(Type, TypeCtor0, _) ->
|
|
TypeCtor = TypeCtor0
|
|
;
|
|
% The type-checker should ensure that this never happens.
|
|
unexpected(this_file, "cons_id_to_tag: invalid type")
|
|
),
|
|
|
|
% Given the type_ctor, lookup up the constructor tag table
|
|
% for that type.
|
|
module_info_get_type_table(ModuleInfo, TypeTable),
|
|
map.lookup(TypeTable, TypeCtor, TypeDefn),
|
|
hlds_data.get_type_defn_body(TypeDefn, TypeBody),
|
|
( ConsTable0 = TypeBody ^ du_type_cons_tag_values ->
|
|
ConsTable = ConsTable0
|
|
;
|
|
unexpected(this_file, "cons_id_to_tag: type is not d.u. type?")
|
|
),
|
|
|
|
% Finally look up the cons_id in the table.
|
|
map.lookup(ConsTable, cons(Name, Arity), Tag)
|
|
).
|
|
|
|
%-----------------------------------------------------------------------------%
|
|
|
|
make_instance_string(InstanceTypes, InstanceString) :-
|
|
% Note that for historical reasons, builtin types are treated as being
|
|
% unqualified (`int') rather than being qualified (`builtin.int')
|
|
% at this point.
|
|
list.map(type_to_string, InstanceTypes, InstanceStrings),
|
|
string.append_list(InstanceStrings, InstanceString).
|
|
|
|
:- pred type_to_string(mer_type::in, string::out) is det.
|
|
|
|
type_to_string(Type, String) :-
|
|
( type_to_ctor_and_args(Type, TypeCtor, _) ->
|
|
TypeCtor = type_ctor(TypeName, TypeArity),
|
|
sym_name_to_string(TypeName, "__", TypeNameString),
|
|
string.int_to_string(TypeArity, TypeArityString),
|
|
String = TypeNameString ++ "__arity" ++ TypeArityString ++ "__"
|
|
;
|
|
unexpected(this_file, "type_to_string: invalid type")
|
|
).
|
|
|
|
%----------------------------------------------------------------------------%
|
|
|
|
:- func this_file = string.
|
|
|
|
this_file = "hlds_code_util.m".
|
|
|
|
%----------------------------------------------------------------------------%
|
|
:- end_module hlds_code_util.
|
|
%----------------------------------------------------------------------------%
|