[m-dev.] diff: fix bug in inter-module optimization
Simon Taylor
stayl at cs.mu.OZ.AU
Wed Mar 7 13:48:54 AEDT 2001
Estimated hours taken: 1.5
Branches: main and release
compiler/intermod.m:
Fix a bug which caused a software error when writing
instance declarations to a `.opt' file when the
method implementation for a function matched a constructor
or a field access function.
Test case: tests/hard_coded/typeclasses/record_syntax.m.
Index: compiler/intermod.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/intermod.m,v
retrieving revision 1.92
diff -u -u -r1.92 intermod.m
--- compiler/intermod.m 2001/03/05 04:02:35 1.92
+++ compiler/intermod.m 2001/03/07 02:38:09
@@ -873,18 +873,16 @@
list__remove_adjacent_dups(ClassPreds0,
ClassPreds),
assoc_list__from_corresponding_lists(
- ClassPreds, Methods0, MethodAL0)
+ ClassPreds, Methods0, MethodAL)
;
error(
"intermod__gather_instances_3: method pred_proc_ids not filled in")
},
- { list__map(
+ { list__map_foldl(
intermod__qualify_instance_method(ModuleInfo),
- MethodAL0, MethodAL) },
- { assoc_list__keys(MethodAL, PredIds) },
- { assoc_list__values(MethodAL, Methods) },
- list__map_foldl(intermod__add_proc,
- PredIds, DoWriteMethodsList),
+ MethodAL, Methods, [], PredIds) },
+ list__map_foldl(intermod__add_proc, PredIds,
+ DoWriteMethodsList),
{ bool__and_list(DoWriteMethodsList, DoWriteMethods) },
(
{ DoWriteMethods = yes },
@@ -936,11 +934,12 @@
% Resolve overloading of instance methods before writing them
% to the `.opt' file.
:- pred intermod__qualify_instance_method(module_info::in,
- pair(pred_id, instance_method)::in,
- pair(pred_id, instance_method)::out) is det.
+ pair(pred_id, instance_method)::in, instance_method::out,
+ list(pred_id)::in, list(pred_id)::out) is det.
intermod__qualify_instance_method(ModuleInfo,
- MethodCallPredId - InstanceMethod0, PredId - InstanceMethod) :-
+ MethodCallPredId - InstanceMethod0,
+ InstanceMethod, PredIds0, PredIds) :-
module_info_pred_info(ModuleInfo, MethodCallPredId,
MethodCallPredInfo),
pred_info_arg_types(MethodCallPredInfo, MethodCallTVarSet, _,
@@ -950,32 +949,34 @@
(
InstanceMethodDefn0 = name(InstanceMethodName0),
PredOrFunc = function,
- module_info_get_predicate_table(ModuleInfo, PredicateTable),
(
- predicate_table_search_func_sym_arity(PredicateTable,
- InstanceMethodName0, MethodArity, PredIds),
- typecheck__find_matching_pred_id(PredIds, ModuleInfo,
+ find_func_matching_instance_method(ModuleInfo,
+ InstanceMethodName0, MethodArity,
MethodCallTVarSet, MethodCallArgTypes,
- PredId0, InstanceMethodName1)
+ MaybePredId, InstanceMethodName)
->
- PredId = PredId0,
- InstanceMethodName = InstanceMethodName1
+ ( MaybePredId = yes(PredId) ->
+ PredIds = [PredId | PredIds0]
+ ;
+ PredIds = PredIds0
+ ),
+ InstanceMethodDefn = name(InstanceMethodName)
;
- hlds_out__simple_call_id_to_string(
- function - InstanceMethodName0/MethodArity,
- MethodStr),
- string__append(
- "intermod__qualify_instance_method: undefined ",
- MethodStr, Msg),
- error(Msg)
- ),
- InstanceMethodDefn = name(InstanceMethodName)
+ % This will force intermod__add_proc to
+ % return DoWrite = no
+ invalid_pred_id(PredId),
+ PredIds = [PredId | PredIds0],
+
+ % We can just leave the method definition unchanged
+ InstanceMethodDefn = InstanceMethodDefn0
+ )
;
InstanceMethodDefn0 = name(InstanceMethodName0),
PredOrFunc = predicate,
typecheck__resolve_pred_overloading(ModuleInfo,
MethodCallArgTypes, MethodCallTVarSet,
InstanceMethodName0, InstanceMethodName, PredId),
+ PredIds = [PredId | PredIds0],
InstanceMethodDefn = name(InstanceMethodName)
;
InstanceMethodDefn0 = clauses(_ItemList),
@@ -988,11 +989,78 @@
%
% This will force intermod__add_proc to return DoWrite = no
invalid_pred_id(PredId),
+ PredIds = [PredId | PredIds0],
% We can just leave the method definition unchanged
InstanceMethodDefn = InstanceMethodDefn0
),
InstanceMethod = instance_method(PredOrFunc, MethodName,
InstanceMethodDefn, MethodArity, MethodContext).
+
+ %
+ % A `func(x/n) is y' method implementation can match an ordinary
+ % function, a field access function or a constructor.
+ % For now, if there are multiple possible matches, we don't write
+ % the instance method.
+ %
+:- pred find_func_matching_instance_method(module_info::in, sym_name::in,
+ arity::in, tvarset::in, list(type)::in,
+ maybe(pred_id)::out, sym_name::out) is semidet.
+
+find_func_matching_instance_method(ModuleInfo, InstanceMethodName0,
+ MethodArity, MethodCallTVarSet, MethodCallArgTypes,
+ MaybePredId, InstanceMethodName) :-
+
+ module_info_ctor_field_table(ModuleInfo, CtorFieldTable),
+ (
+ is_field_access_function_name(ModuleInfo, InstanceMethodName0,
+ MethodArity, _, FieldName),
+ map__search(CtorFieldTable, FieldName, FieldDefns)
+ ->
+ TypeIds0 = list__map(
+ (func(FieldDefn) = TypeId :-
+ FieldDefn = hlds_ctor_field_defn(_, _,
+ TypeId, _, _)
+ ), FieldDefns)
+ ;
+ TypeIds0 = []
+ ),
+ module_info_ctors(ModuleInfo, Ctors),
+ (
+ map__search(Ctors, cons(InstanceMethodName0, MethodArity),
+ MatchingConstructors)
+ ->
+ TypeIds1 = list__map(
+ (func(ConsDefn) = TypeId :-
+ ConsDefn = hlds_cons_defn(_, _, _, TypeId, _)
+ ), MatchingConstructors)
+ ;
+ TypeIds1 = []
+ ),
+ TypeIds = list__append(TypeIds0, TypeIds1),
+
+ module_info_get_predicate_table(ModuleInfo, PredicateTable),
+ (
+ predicate_table_search_func_sym_arity(PredicateTable,
+ InstanceMethodName0, MethodArity, PredIds),
+ typecheck__find_matching_pred_id(PredIds, ModuleInfo,
+ MethodCallTVarSet, MethodCallArgTypes,
+ PredId, InstanceMethodFuncName)
+ ->
+ TypeIds = [],
+ MaybePredId = yes(PredId),
+ InstanceMethodName = InstanceMethodFuncName
+ ;
+ TypeIds = [TheTypeId],
+ MaybePredId = no,
+ ( TheTypeId = qualified(TypeModule, _) - _ ->
+ unqualify_name(InstanceMethodName0, UnqualMethodName),
+ InstanceMethodName =
+ qualified(TypeModule, UnqualMethodName)
+ ;
+ error(
+ "unqualified type_id in hlds_cons_defn or hlds_ctor_field_defn")
+ )
+ ).
%-----------------------------------------------------------------------------%
--------------------------------------------------------------------------
mercury-developers mailing list
Post messages to: mercury-developers at cs.mu.oz.au
Administrative Queries: owner-mercury-developers at cs.mu.oz.au
Subscriptions: mercury-developers-request at cs.mu.oz.au
--------------------------------------------------------------------------
More information about the developers
mailing list