[m-rev.] for review: use typeclass constraints to help resolve overloading

Peter Ross petdr at cs.mu.OZ.AU
Wed Jan 16 15:15:36 AEDT 2002


Hi,

For review by fjh or dgj.

===================================================================


Estimated hours taken: 3
Branches: main

compiler/typecheck.m:
    When resolving predicate overloading to a typeclass method use the
    instance declarations to help resolve the overloading.

tests/hard_coded/typeclasses/Mmakefile:
tests/hard_coded/typeclasses/overload.exp:
tests/hard_coded/typeclasses/overload.m:
    A test case.

Index: compiler/typecheck.m
===================================================================
RCS file: /home/staff/zs/imp/mercury/compiler/typecheck.m,v
retrieving revision 1.308
diff -u -r1.308 typecheck.m
--- compiler/typecheck.m	25 Sep 2001 09:36:55 -0000	1.308
+++ compiler/typecheck.m	16 Jan 2002 04:11:17 -0000
@@ -1587,7 +1587,11 @@
 			PredArgTypes0),
 
 		arg_type_list_subsumes(TVarSet, ArgTypes,
-			PredTVarSet, PredExistQVars0, PredArgTypes0)
+			PredTVarSet, PredExistQVars0, PredArgTypes0),
+
+		% We also need to check the universal typeclass constraints.
+		check_univ_constraints(ModuleInfo, PredInfo,
+				ArgTypes, PredArgTypes0)
 	->
 		%
 		% we've found a matching predicate
@@ -1610,6 +1614,69 @@
 		typecheck__find_matching_pred_id(PredIds, ModuleInfo,
 				TVarSet, ArgTypes, ThePredId, PredName)
 	).
+
+	% check_univ_constraints(MI, PI, ArgTypes, PredArgTypes)
+	%
+	% For each universally constrained type variable in
+	% PredArgTypes, check that the corresponding type in ArgTypes
+	% has an instance declaration.  The predicate succeeds if this
+	% test succeeds for each constrained type variable.
+	%
+	% eg If we call predicate p with type signature p(int) and p is a
+	% member of the typeclass tc(T) with the type signature p(T).
+	% Then check whether or not there is an instance tc(int).
+	%
+:- pred check_univ_constraints(module_info::in, pred_info::in,
+		list(type)::in, list(type)::in) is semidet.
+
+check_univ_constraints(_ModuleInfo, _PredInfo, [], []).
+check_univ_constraints(ModuleInfo, PredInfo,
+		[ArgType | ArgTypes], [PredArg | PredArgs]) :-
+	obeys_universal_constraints(ModuleInfo, PredInfo, ArgType, PredArg),
+	check_univ_constraints(ModuleInfo, PredInfo,
+				ArgTypes, PredArgs).
+
+:- pred obeys_universal_constraints(module_info::in, pred_info::in,
+		(type)::in, (type)::in) is semidet.
+
+obeys_universal_constraints(ModuleInfo, PredInfo, ArgType, PredArgType) :-
+	( PredArgType = term__variable(_TVar) ->
+		pred_info_get_class_context(PredInfo, ClassConstraints),
+		ClassConstraints = constraints(Univs, _Exist),
+
+			% Get the Univ constraints which mention TVar
+		list__filter_map((pred(C::in, {N, C}::out) is semidet :-
+				C = constraint(_CName, CTypes),
+				list__nth_member_search(CTypes, PredArgType, N)
+			), Univs, TVarUnivs),
+
+			% Ensure that there exists at least one instance
+			% declaration with ArgType for each typeclass
+			% constraint.
+		list__filter(instance_decl_exists(ModuleInfo, ArgType),
+				TVarUnivs, _Compatible, Incompatible),
+		Incompatible = []
+	;
+		true
+	).
+	
+:- pred instance_decl_exists(module_info::in, (type)::in,
+		{int, class_constraint}::in) is semidet.
+
+instance_decl_exists(ModuleInfo, ArgType, {N, constraint(Name, Types)}) :-
+	module_info_instances(ModuleInfo, Instances),
+	map__lookup(Instances, class_id(Name, list__length(Types)),
+			InstanceDefns),
+	list__filter((pred(InstanceDefn::in) is semidet :-
+			InstanceDefn = hlds_instance_defn(_, _, _, _,
+					InstanceTypes, _, _, _, _),
+			list__index1_det(InstanceTypes, N, InstanceType),
+			type_list_subsumes([ArgType], [InstanceType], _)
+		), InstanceDefns, Compatible, _Incompatible),
+
+		% There must be at least one instance declaration which
+		% metions the ArgType.
+	Compatible = [_ | _].
 
 %-----------------------------------------------------------------------------%
 
Index: tests/hard_coded/typeclasses/Mmakefile
===================================================================
RCS file: /home/staff/zs/imp/tests/hard_coded/typeclasses/Mmakefile,v
retrieving revision 1.44
diff -u -r1.44 Mmakefile
--- tests/hard_coded/typeclasses/Mmakefile	12 Feb 2001 05:14:57 -0000	1.44
+++ tests/hard_coded/typeclasses/Mmakefile	16 Jan 2002 04:08:57 -0000
@@ -41,6 +41,7 @@
 	multi_parameter_bug \
 	nondet_class_method \
 	operator_classname \
+	overload \
 	record_syntax \
 	reordered_existential_constraint \
 	superclass_bug \
Index: tests/hard_coded/typeclasses/overload.exp
===================================================================
RCS file: tests/hard_coded/typeclasses/overload.exp
diff -N tests/hard_coded/typeclasses/overload.exp
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ tests/hard_coded/typeclasses/overload.exp	16 Jan 2002 04:08:32 -0000
@@ -0,0 +1 @@
+5
Index: tests/hard_coded/typeclasses/overload.m
===================================================================
RCS file: tests/hard_coded/typeclasses/overload.m
diff -N tests/hard_coded/typeclasses/overload.m
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ tests/hard_coded/typeclasses/overload.m	16 Jan 2002 04:09:51 -0000
@@ -0,0 +1,35 @@
+% Check that we can resolve unambigiously which call to f/1 we mean, by
+% checking the typeclass constraints on f.
+:- module overload.
+:- interface.
+:- import_module io.
+
+:- pred main(io__state::di, io__state::uo) is det.
+
+:- implementation.
+
+:- typeclass tc(T) where
+[
+	func f(T) = int
+].
+:- instance tc(int) where
+[
+	f(X) = X
+].
+
+:- import_module overload__sub.
+:- module sub.
+:- interface.
+:- typeclass tc2(T) where
+[
+	func f(T) = int
+].
+:- instance tc2(string) where
+[
+	f(_) = 123456789
+].
+:- end_module sub.
+
+main -->
+	io__write_int(f(5)),
+	io__nl.

--------------------------------------------------------------------------
mercury-reviews mailing list
post:  mercury-reviews at cs.mu.oz.au
administrative address: owner-mercury-reviews at cs.mu.oz.au
unsubscribe: Address: mercury-reviews-request at cs.mu.oz.au Message: unsubscribe
subscribe:   Address: mercury-reviews-request at cs.mu.oz.au Message: subscribe
--------------------------------------------------------------------------



More information about the reviews mailing list