[m-rev.] diff: fix bug reported by Peter Ross
Mark Brown
mark at csse.unimelb.edu.au
Thu Jan 11 15:54:22 AEDT 2007
Estimated hours taken: 1.5
Branches: main
Fix a bug reported by Peter Ross.
compiler/check_typeclass.m:
Only check concrete instance definitions for mutual consistency.
Abstract definitions will always appear to be inconsistent with
the concrete ones.
tests/valid/Mmakefile:
tests/valid/logged_stream.m:
New test case.
Index: compiler/check_typeclass.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/check_typeclass.m,v
retrieving revision 1.109
diff -u -r1.109 check_typeclass.m
--- compiler/check_typeclass.m 1 Dec 2006 15:03:50 -0000 1.109
+++ compiler/check_typeclass.m 10 Jan 2007 16:16:12 -0000
@@ -63,7 +63,12 @@
% dependencies. This doesn't necessarily catch all cases of inconsistent
% instances, however, since in general that cannot be done until link time.
% We try to catch as many cases as possible here, though, since we can give
-% better error messages.
+% better error messages. Note that we only check concrete instance definitions
+% for mutual consistency, since otherwise the abstract instance definitions
+% would conflict with their corresponding concrete definitions. If in
+% future we allow stub instances, where the concrete definition is compiler
+% generated, we should add the concrete definitions before this pass to
+% ensure that they get checked.
%
% Last, in check_typeclass_constraints/4, we check typeclass constraints on
% predicate and function declarations and on existentially typed data
@@ -1102,8 +1107,17 @@
map.lookup(InstanceTable, ClassId, InstanceDefns),
FunDeps = ClassDefn ^ class_fundeps,
check_coverage(ClassId, InstanceDefns, FunDeps, !ModuleInfo, !Specs),
- check_consistency(ClassId, ClassDefn, InstanceDefns, FunDeps,
+ % Concrete definitions will always overlap with abstract ones; we only
+ % need to check the former.
+ list.filter(is_concrete_instance_defn, InstanceDefns,
+ ConcreteInstanceDefns),
+ check_consistency(ClassId, ClassDefn, ConcreteInstanceDefns, FunDeps,
!ModuleInfo, !Specs).
+
+:- pred is_concrete_instance_defn(hlds_instance_defn::in) is semidet.
+
+is_concrete_instance_defn(InstanceDefn) :-
+ InstanceDefn ^ instance_body = instance_body_concrete(_).
:- pred check_coverage(class_id::in, list(hlds_instance_defn)::in,
hlds_class_fundeps::in, module_info::in, module_info::out,
Index: tests/valid/Mmakefile
===================================================================
RCS file: /home/mercury1/repository/tests/valid/Mmakefile,v
retrieving revision 1.184
diff -u -r1.184 Mmakefile
--- tests/valid/Mmakefile 19 Dec 2006 03:01:49 -0000 1.184
+++ tests/valid/Mmakefile 10 Jan 2007 16:16:12 -0000
@@ -32,6 +32,7 @@
fundeps_poly_instance \
instance_superclass \
instance_unconstrained_tvar \
+ logged_stream \
mpj2 \
mpj5 \
mpj6 \
Index: tests/valid/logged_stream.m
===================================================================
RCS file: tests/valid/logged_stream.m
diff -N tests/valid/logged_stream.m
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ tests/valid/logged_stream.m 10 Jan 2007 16:16:12 -0000
@@ -0,0 +1,41 @@
+% $ mmc -e logged_stream.m
+% logged_stream.m:041: Inconsistent instance declaration for typeclass
+% logged_stream.m:041: `stream.input'/3 with functional dependency
+% logged_stream.m:041: `(Stream -> Error)'.
+% logged_stream.m:027: Here is the conflicting instance.
+:- module logged_stream.
+
+:- interface.
+
+:- import_module stream.
+:- import_module io.
+
+:- type logged_stream(S, L)
+ ---> logged_stream(
+ stream :: S,
+ logged :: L
+ ).
+
+:- type logged_error(E)
+ ---> error(E)
+ .
+
+:- instance stream(logged_stream(S, L), io) <= (stream(S, io), stream(L, io)).
+:- instance error(logged_error(E)) <= error(E).
+
+% Comment the following line out and this code compiles fine.
+:- instance input(logged_stream(S, L), io, logged_error(E)) <= (input(S, io, E), output(L, io)).
+
+:- implementation.
+
+:- instance stream(logged_stream(S, L), io) <= (stream(S, io), stream(L, io)) where [
+ (name(logged_stream(S, _), Name, !State) :-
+ name(S, Name, !State)
+ )
+].
+
+:- instance error(logged_error(E)) <= error(E) where [
+ error_message(error(E)) = error_message(E)
+].
+
+:- instance input(logged_stream(S, L), io, logged_error(E)) <= (input(S, io, E), output(L, io)) where [].
--------------------------------------------------------------------------
mercury-reviews mailing list
Post messages to: mercury-reviews at csse.unimelb.edu.au
Administrative Queries: owner-mercury-reviews at csse.unimelb.edu.au
Subscriptions: mercury-reviews-request at csse.unimelb.edu.au
--------------------------------------------------------------------------
More information about the reviews
mailing list