Fix some bugs in the handling of "non-simple" type class constraints

Estimated hours taken: 12

Fix some bugs in the handling of "non-simple" type class constraints
(ones for which the types being constrained are not just type variables).

compiler/prog_io_typeclass.m:
	Ensure that constraints on type class declarations must be "simple".
	This is needed the ensure termination of type checking.
	(We already did this for instance declarations, but not for
	superclass constraints on type class declarations.)

compiler/prog_data.m:
	Document the invariant that the types in a type class constraint
	must not contain any information in their term__context fields.

compiler/type_util.m:
compiler/equiv_type.m:
compiler/polymorphism.m:
compiler/prog_io_typeclass.m:
	Enforce the above-mentioned invariant.

compiler/typecheck.m:
	Allow the declared constraints to be a superset of the
	inferred constraints.
	When performing context reduction, eliminate declared
	constraints at each step rather than only at the end.
	Remove declared constraints and apply superclass rules
	before applying instance rules.
	When applying instance rules, make sure that it is a type
	error if there is no matching instance rule for a ground
	constraint.
	If context reduction results in an error, restore the
	original type assign set, to avoid repeating the same
	error message at every subsequent call to perform_context_reduction.

compiler/check_typeclass.m:
	Change the way we superclass conformance for instance declarations
	to take advantage of the new "DeclaredConstraints" argument to
	typecheck__reduce_context_by_rule_application.
This commit is contained in:
Fergus Henderson
1998-04-08 15:23:35 +00:00
parent b09da35e8e
commit 5e86fb5715
7 changed files with 237 additions and 125 deletions

View File

@@ -64,7 +64,7 @@
% Given a variable type, return its type variable.
:- pred type_util__var(type, var).
:- pred type_util__var(type, tvar).
:- mode type_util__var(in, out) is semidet.
:- mode type_util__var(out, in) is det.
@@ -181,6 +181,12 @@
class_constraint).
:- mode apply_subst_to_constraint(in, in, out) is det.
% strip out the term__context fields, replacing them with empty
% term__contexts (as obtained by term__context_init/1)
% in a type or list of types
:- pred strip_term_contexts(list(term)::in, list(term)::out) is det.
:- pred strip_term_context(term::in, term::out) is det.
%-----------------------------------------------------------------------------%
%-----------------------------------------------------------------------------%
@@ -720,7 +726,10 @@ apply_rec_subst_to_constraints(Subst, Constraints0, Constraints) :-
apply_rec_subst_to_constraint(Subst, Constraint0, Constraint) :-
Constraint0 = constraint(ClassName, Types0),
term__apply_rec_substitution_to_list(Types0, Subst, Types),
term__apply_rec_substitution_to_list(Types0, Subst, Types1),
% we need to maintain the invariant that types in class constraints
% do not have any information in their term__context fields
strip_term_contexts(Types1, Types),
Constraint = constraint(ClassName, Types).
apply_subst_to_constraints(Subst, Constraints0, Constraints) :-
@@ -731,5 +740,13 @@ apply_subst_to_constraint(Subst, Constraint0, Constraint) :-
term__apply_substitution_to_list(Types0, Subst, Types),
Constraint = constraint(ClassName, Types).
strip_term_contexts(Terms, StrippedTerms) :-
list__map(strip_term_context, Terms, StrippedTerms).
strip_term_context(term__variable(V), term__variable(V)).
strip_term_context(term__functor(F, As0, _C0), term__functor(F, As, C)) :-
term__context_init(C),
strip_term_contexts(As0, As).
%-----------------------------------------------------------------------------%
%-----------------------------------------------------------------------------%