[m-dev.] for review: improve typeclass error message
Fergus Henderson
fjh at cs.mu.OZ.AU
Fri Nov 3 04:31:48 AEDT 2000
Estimated hours taken: 0.75
Improve the error message for errors in type class instance
definitions that use the named (e.g. "pred(foo/N) is bar") syntax, as
suggested by Ralph Becket: for such procedures, just output "in bar/N"
rather than "in call to bar/N", since the user didn't write any
explicit call.
compiler/hlds_pred.m:
Add a new marker `named_class_instance_method' to the pred_marker type.
compiler/hlds_out.m:
compiler/intermod.m:
Handle the new marker.
compiler/check_typeclass.m:
For instance methods defined using the named syntax,
add the `named_class_instance_method' marker to their markers.
compiler/typecheck.m:
compiler/mode_errors.m:
Pass the pred_markers down to hlds_out__write_call_arg_id.
compiler/hlds_out.m:
Change hlds_out__write_call_arg_id so that for predicates with
the `named_class_instance_method' marker, it doesn't output the
"call to".
Workspace: /home/pgrad/fjh/ws/hg
Index: compiler/check_typeclass.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/check_typeclass.m,v
retrieving revision 1.36
diff -u -d -r1.36 check_typeclass.m
--- compiler/check_typeclass.m 2000/11/01 05:11:49 1.36
+++ compiler/check_typeclass.m 2000/11/02 01:42:23
@@ -663,7 +663,17 @@
Cond = true,
map__init(Proofs),
- add_marker(Markers0, class_instance_method, Markers),
+ add_marker(Markers0, class_instance_method, Markers1),
+ ( InstancePredDefn = name(_) ->
+ % For instance methods which are defined using the named
+ % syntax (e.g. "pred(...) is ...") rather than the clauses
+ % syntax, we record an additional marker; the only effect
+ % of this marker is that we output slightly different
+ % error messages for such predicates.
+ add_marker(Markers1, named_class_instance_method, Markers)
+ ;
+ Markers = Markers1
+ ),
module_info_globals(ModuleInfo0, Globals),
globals__lookup_string_option(Globals, aditi_user, User),
Index: compiler/hlds_out.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/hlds_out.m,v
retrieving revision 1.248
diff -u -d -r1.248 hlds_out.m
--- compiler/hlds_out.m 2000/11/01 05:11:53 1.248
+++ compiler/hlds_out.m 2000/11/02 02:14:19
@@ -87,8 +87,13 @@
:- mode hlds_out__simple_call_id_to_string(in, out) is det.
% Write "argument %i of call to pred_or_func `foo/n'".
-:- pred hlds_out__write_call_arg_id(call_id, int, io__state, io__state).
-:- mode hlds_out__write_call_arg_id(in, in, di, uo) is det.
+ % The pred_markers argument is used to tell if the calling
+ % predicate is a type class method implementation; if so,
+ % we omit the "call to" part, since the user didn't write
+ % any explicit call.
+:- pred hlds_out__write_call_arg_id(call_id, int, pred_markers,
+ io__state, io__state).
+:- mode hlds_out__write_call_arg_id(in, in, in, di, uo) is det.
:- pred hlds_out__write_pred_or_func(pred_or_func, io__state, io__state).
:- mode hlds_out__write_pred_or_func(in, di, uo) is det.
@@ -400,7 +405,7 @@
io__write_strings(["`", Name, "' of "]),
hlds_out__write_simple_call_id(CallId).
-hlds_out__write_call_arg_id(CallId, ArgNum) -->
+hlds_out__write_call_arg_id(CallId, ArgNum, PredMarkers) -->
( { ArgNum =< 0 } ->
% Argument numbers that are less than or equal to zero
% are used for the type_info and typeclass_info arguments
@@ -416,12 +421,26 @@
io__write_string(" of ")
),
(
- { CallId = generic_call(GenericCall) },
- \+ { GenericCall = class_method(_, _) },
- \+ { GenericCall = aditi_builtin(aditi_call(_, _, _, _), _) }
+ (
+ % The text printed for generic calls other than
+ % `aditi_call' and `class__method' does not need
+ % the "call to" prefix ("in call to higher-order
+ % call" is redundant, it's much better to just say
+ % "in higher-order call").
+ { CallId = generic_call(GenericCall) },
+ \+ { GenericCall = class_method(_, _) },
+ \+ { GenericCall = aditi_builtin(aditi_call(_, _,
+ _, _), _) }
+ ;
+ % For calls from type class instance implementations
+ % that were defined using the named syntax rather
+ % than the clause syntax, we also omit the "call to",
+ % since in that case there was no explicit call in
+ % the user's source code.
+ { check_marker(PredMarkers,
+ named_class_instance_method) }
+ )
->
- % The text printed for generic calls other than `aditi_call'
- % and `class__method' does not need the "call to" prefix.
[]
;
io__write_string("call to ")
@@ -545,7 +564,15 @@
hlds_out__write_unify_main_context(First, call(CallId, ArgNum), Context, no) -->
hlds_out__start_in_message(First, Context),
- hlds_out__write_call_arg_id(CallId, ArgNum),
+ % The markers argument below is used only for type class method
+ % implementations defined using the named syntax rather than
+ % the clause syntax, and the bodies of such procedures should
+ % only contain a single call, so we shouldn't get unifications
+ % nested inside calls. Hence we can safely initialize the
+ % markers to empty here. (Anyway the worst possible consequence
+ % is slightly sub-optimal text for an error message.)
+ { init_markers(Markers) },
+ hlds_out__write_call_arg_id(CallId, ArgNum, Markers),
io__write_string(":\n").
:- pred hlds_out__write_unify_sub_contexts(bool, unify_sub_contexts,
@@ -833,6 +860,8 @@
hlds_out__marker_name(obsolete, "obsolete").
hlds_out__marker_name(class_method, "class_method").
hlds_out__marker_name(class_instance_method, "class_instance_method").
+hlds_out__marker_name(named_class_instance_method,
+ "named_class_instance_method").
hlds_out__marker_name((impure), "impure").
hlds_out__marker_name((semipure), "semipure").
hlds_out__marker_name(promised_pure, "promise_pure").
Index: compiler/hlds_pred.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/hlds_pred.m,v
retrieving revision 1.85
diff -u -d -r1.85 hlds_pred.m
--- compiler/hlds_pred.m 2000/10/13 13:55:25 1.85
+++ compiler/hlds_pred.m 2000/11/02 01:43:36
@@ -371,6 +371,15 @@
% This predicate was automatically
% generated for the implementation of
% a class method for an instance.
+ ; named_class_instance_method
+ % This predicate was automatically
+ % generated for the implementation of
+ % a class method for an instance,
+ % and the instance was defined using the
+ % named syntax (e.g. "pred(...) is ...")
+ % rather than the clause syntax.
+ % (For such predicates, we output slightly
+ % different error messages.)
; (impure) % Requests that no transformation that would
% be inappropriate for impure code be
Index: compiler/intermod.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/intermod.m,v
retrieving revision 1.86
diff -u -d -r1.86 intermod.m
--- compiler/intermod.m 2000/11/01 05:11:55 1.86
+++ compiler/intermod.m 2000/11/02 01:57:10
@@ -1563,6 +1563,7 @@
% There is no pragma required for generated class methods.
intermod__should_output_marker(class_method, no).
intermod__should_output_marker(class_instance_method, no).
+intermod__should_output_marker(named_class_instance_method, no).
% The warning for calls to local obsolete predicates should appear
% once in the defining module, not in importing modules.
intermod__should_output_marker(obsolete, no).
Index: compiler/mode_errors.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/mode_errors.m,v
retrieving revision 1.66
diff -u -d -r1.66 mode_errors.m
--- compiler/mode_errors.m 1999/10/26 07:39:45 1.66
+++ compiler/mode_errors.m 2000/11/02 02:37:15
@@ -817,11 +817,10 @@
{ mode_info_get_context(ModeInfo, Context) },
{ mode_info_get_predid(ModeInfo, PredId) },
{ mode_info_get_procid(ModeInfo, ProcId) },
- { module_info_preds(ModuleInfo, Preds) },
- { map__lookup(Preds, PredId, PredInfo) },
- { pred_info_procedures(PredInfo, Procs) },
+ { module_info_pred_proc_info(ModuleInfo, PredId, ProcId,
+ PredInfo, ProcInfo) },
{ pred_info_get_is_pred_or_func(PredInfo, PredOrFunc) },
- { map__lookup(Procs, ProcId, ProcInfo) },
+ { pred_info_get_markers(PredInfo, PredMarkers) },
{ proc_info_declared_argmodes(ProcInfo, Modes0) },
{ strip_builtin_qualifiers_from_mode_list(Modes0, Modes) },
{ pred_info_name(PredInfo, Name0) },
@@ -835,7 +834,7 @@
MaybeDet, Context),
io__write_string("':\n"),
{ mode_info_get_mode_context(ModeInfo, ModeContext) },
- write_mode_context(ModeContext, Context, ModuleInfo).
+ write_mode_context(ModeContext, Context, PredMarkers, ModuleInfo).
%-----------------------------------------------------------------------------%
@@ -883,20 +882,21 @@
% XXX some parts of the mode context never get set up
-:- pred write_mode_context(mode_context, prog_context, module_info,
- io__state, io__state).
-:- mode write_mode_context(in, in, in, di, uo) is det.
+:- pred write_mode_context(mode_context, prog_context, pred_markers,
+ module_info, io__state, io__state).
+:- mode write_mode_context(in, in, in, in, di, uo) is det.
-write_mode_context(uninitialized, _Context, _ModuleInfo) -->
+write_mode_context(uninitialized, _Context, _Markers, _ModuleInfo) -->
[].
-write_mode_context(call(CallId, ArgNum), Context, _ModuleInfo) -->
+write_mode_context(call(CallId, ArgNum), Context, Markers, _ModuleInfo) -->
prog_out__write_context(Context),
io__write_string(" in "),
- hlds_out__write_call_arg_id(CallId, ArgNum),
+ hlds_out__write_call_arg_id(CallId, ArgNum, Markers),
io__write_string(":\n").
-write_mode_context(unify(UnifyContext, _Side), Context, _ModuleInfo) -->
+write_mode_context(unify(UnifyContext, _Side), Context, _Markers,
+ _ModuleInfo) -->
hlds_out__write_unify_context(UnifyContext, Context).
%-----------------------------------------------------------------------------%
Index: compiler/typecheck.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/typecheck.m,v
retrieving revision 1.290
diff -u -d -r1.290 typecheck.m
--- compiler/typecheck.m 2000/11/01 05:12:14 1.290
+++ compiler/typecheck.m 2000/11/02 17:30:49
@@ -3295,6 +3295,17 @@
%-----------------------------------------------------------------------------%
+:- pred typecheck_info_get_pred_markers(typecheck_info, pred_markers).
+:- mode typecheck_info_get_pred_markers(in, out) is det.
+
+typecheck_info_get_pred_markers(TypeCheckInfo, PredMarkers) :-
+ typecheck_info_get_module_info(TypeCheckInfo, ModuleInfo),
+ typecheck_info_get_predid(TypeCheckInfo, PredId),
+ module_info_pred_info(ModuleInfo, PredId, PredInfo),
+ pred_info_get_markers(PredInfo, PredMarkers).
+
+%-----------------------------------------------------------------------------%
+
:- pred typecheck_info_set_called_predid(call_id, typecheck_info,
typecheck_info).
:- mode typecheck_info_set_called_predid(in, typecheck_info_di,
@@ -5186,6 +5197,7 @@
:- mode report_error_var(typecheck_info_no_io, in, in, in, di, uo) is det.
report_error_var(TypeCheckInfo, VarId, Type, TypeAssignSet0) -->
+ { typecheck_info_get_pred_markers(TypeCheckInfo, PredMarkers) },
{ typecheck_info_get_called_predid(TypeCheckInfo, CalledPredId) },
{ typecheck_info_get_arg_num(TypeCheckInfo, ArgNum) },
{ typecheck_info_get_context(TypeCheckInfo, Context) },
@@ -5193,7 +5205,8 @@
{ get_type_stuff(TypeAssignSet0, VarId, TypeStuffList) },
{ typecheck_info_get_varset(TypeCheckInfo, VarSet) },
write_context_and_pred_id(TypeCheckInfo),
- write_call_context(Context, CalledPredId, ArgNum, UnifyContext),
+ write_call_context(Context, PredMarkers,
+ CalledPredId, ArgNum, UnifyContext),
prog_out__write_context(Context),
io__write_string(" type error: "),
( { TypeStuffList = [SingleTypeStuff] } ->
@@ -5231,6 +5244,7 @@
:- mode report_error_arg_var(typecheck_info_no_io, in, in, di, uo) is det.
report_error_arg_var(TypeCheckInfo, VarId, ArgTypeAssignSet0) -->
+ { typecheck_info_get_pred_markers(TypeCheckInfo, PredMarkers) },
{ typecheck_info_get_called_predid(TypeCheckInfo, CalledPredId) },
{ typecheck_info_get_arg_num(TypeCheckInfo, ArgNum) },
{ typecheck_info_get_context(TypeCheckInfo, Context) },
@@ -5238,7 +5252,8 @@
{ get_arg_type_stuff(ArgTypeAssignSet0, VarId, ArgTypeStuffList) },
{ typecheck_info_get_varset(TypeCheckInfo, VarSet) },
write_context_and_pred_id(TypeCheckInfo),
- write_call_context(Context, CalledPredId, ArgNum, UnifyContext),
+ write_call_context(Context, PredMarkers,
+ CalledPredId, ArgNum, UnifyContext),
prog_out__write_context(Context),
io__write_string(" type error: "),
( { ArgTypeStuffList = [SingleArgTypeStuff] } ->
@@ -5531,12 +5546,14 @@
in, in, di, uo) is det.
report_error_undef_cons(TypeCheckInfo, InvalidFieldUpdates, Functor, Arity) -->
+ { typecheck_info_get_pred_markers(TypeCheckInfo, PredMarkers) },
{ typecheck_info_get_called_predid(TypeCheckInfo, CalledPredId) },
{ typecheck_info_get_arg_num(TypeCheckInfo, ArgNum) },
{ typecheck_info_get_context(TypeCheckInfo, Context) },
{ typecheck_info_get_unify_context(TypeCheckInfo, UnifyContext) },
write_context_and_pred_id(TypeCheckInfo),
- write_call_context(Context, CalledPredId, ArgNum, UnifyContext),
+ write_call_context(Context, PredMarkers,
+ CalledPredId, ArgNum, UnifyContext),
prog_out__write_context(Context),
%
% check for some special cases, so that we can give
@@ -5779,17 +5796,17 @@
language_builtin("aditi_bulk_modify", 3).
language_builtin("aditi_bulk_modify", 4).
-:- pred write_call_context(prog_context, call_id, int, unify_context,
- io__state, io__state).
-:- mode write_call_context(in, in, in, in, di, uo) is det.
+:- pred write_call_context(prog_context, pred_markers,
+ call_id, int, unify_context, io__state, io__state).
+:- mode write_call_context(in, in, in, in, in, di, uo) is det.
-write_call_context(Context, CallId, ArgNum, UnifyContext) -->
+write_call_context(Context, PredMarkers, CallId, ArgNum, UnifyContext) -->
( { ArgNum = 0 } ->
hlds_out__write_unify_context(UnifyContext, Context)
;
prog_out__write_context(Context),
io__write_string(" in "),
- hlds_out__write_call_arg_id(CallId, ArgNum),
+ hlds_out__write_call_arg_id(CallId, ArgNum, PredMarkers),
io__write_string(":\n")
).
--
Fergus Henderson <fjh at cs.mu.oz.au> | "I have always known that the pursuit
| of excellence is a lethal habit"
WWW: <http://www.cs.mu.oz.au/~fjh> | -- the last words of T. S. Garp.
--------------------------------------------------------------------------
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