[m-rev.] for review: type qualifications in instance method clauses
Peter Wang
novalazy at gmail.com
Mon Jan 11 13:43:28 AEDT 2010
Branches: main
Fix bug #123. There was an incorrect assumption that instance method clauses
will not contain explicit type qualifications.
compiler/add_class.m:
compiler/check_typeclass.m:
compiler/make_hlds.m:
Thread the type varset through `produce_instance_method_clause' instead
of creating a dummy varset at each call and discarding the final varset
from `clauses_info_add_clause'.
compiler/options.m:
Fix a typo.
compiler/typecheck_info.m:
Show variable number suffixes with `--debug-types'.
tests/valid/Mmakefile:
tests/valid/instance_typequal.m:
Add test case.
diff --git a/compiler/add_class.m b/compiler/add_class.m
index 7f13902..d838592 100644
--- a/compiler/add_class.m
+++ b/compiler/add_class.m
@@ -37,10 +37,11 @@
% for that definition.
%
:- pred do_produce_instance_method_clauses(instance_proc_def::in,
- pred_or_func::in, arity::in, list(mer_type)::in, pred_markers::in,
- term.context::in, import_status::in, clauses_info::out,
- module_info::in, module_info::out, qual_info::in, qual_info::out,
- list(error_spec)::in, list(error_spec)::out) is det.
+ pred_or_func::in, arity::in, list(mer_type)::in,
+ pred_markers::in, term.context::in, import_status::in, clauses_info::out,
+ tvarset::in, tvarset::out, module_info::in, module_info::out,
+ qual_info::in, qual_info::out, list(error_spec)::in, list(error_spec)::out)
+ is det.
%-----------------------------------------------------------------------------%
%-----------------------------------------------------------------------------%
@@ -598,9 +599,9 @@ same_type_hlds_instance_defn(InstanceDefnA, InstanceDefnB) :-
apply_variable_renaming_to_type_list(Renaming, TypesB1, TypesB),
TypesA = TypesB.
-
+
do_produce_instance_method_clauses(InstanceProcDefn, PredOrFunc, PredArity,
- ArgTypes, Markers, Context, Status, ClausesInfo, !ModuleInfo,
+ ArgTypes, Markers, Context, Status, ClausesInfo, !TVarSet, !ModuleInfo,
!QualInfo, !Specs) :-
(
% Handle the `pred(<MethodName>/<Arity>) is <ImplName>' syntax.
@@ -640,20 +641,20 @@ do_produce_instance_method_clauses(InstanceProcDefn, PredOrFunc, PredArity,
InstanceProcDefn = instance_proc_def_clauses(InstanceClauses),
clauses_info_init(PredOrFunc, PredArity,
init_clause_item_numbers_comp_gen, ClausesInfo0),
- list.foldl4(
+ list.foldl5(
produce_instance_method_clause(PredOrFunc, Context, Status),
- InstanceClauses, !ModuleInfo, !QualInfo,
+ InstanceClauses, !TVarSet, !ModuleInfo, !QualInfo,
ClausesInfo0, ClausesInfo, !Specs)
).
:- pred produce_instance_method_clause(pred_or_func::in,
prog_context::in, import_status::in, item_clause_info::in,
- module_info::in, module_info::out, qual_info::in, qual_info::out,
- clauses_info::in, clauses_info::out,
+ tvarset::in, tvarset::out, module_info::in, module_info::out,
+ qual_info::in, qual_info::out, clauses_info::in, clauses_info::out,
list(error_spec)::in, list(error_spec)::out) is det.
produce_instance_method_clause(PredOrFunc, Context, Status, InstanceClause,
- !ModuleInfo, !QualInfo, !ClausesInfo, !Specs) :-
+ TVarSet0, TVarSet, !ModuleInfo, !QualInfo, !ClausesInfo, !Specs) :-
InstanceClause = item_clause_info(_Origin, CVarSet, ClausePredOrFunc,
PredName, HeadTerms0, Body, _ClauseContext, _SeqNum),
% XXX Can this ever fail? If yes, we should generate an error message
@@ -661,14 +662,13 @@ produce_instance_method_clause(PredOrFunc, Context, Status, InstanceClause,
expect(unify(PredOrFunc, ClausePredOrFunc), this_file,
"produce_instance_method_clause: PredOrFunc mismatch"),
( illegal_state_var_func_result(PredOrFunc, HeadTerms0, StateVar) ->
+ TVarSet = TVarSet0,
report_illegal_func_svar_result(Context, CVarSet, StateVar, !Specs)
;
HeadTerms = expand_bang_state_var_args(HeadTerms0),
PredArity = list.length(HeadTerms),
adjust_func_arity(PredOrFunc, Arity, PredArity),
- % TVarSet0 is only used for explicit type qualifications, of which
- % there are none in this clause, so this dummy value should be ok.
- varset.init(TVarSet0),
+
% AllProcIds is only used when the predicate has foreign procs,
% which the instance method pred should not have, so this dummy value
% should be ok.
@@ -677,7 +677,7 @@ produce_instance_method_clause(PredOrFunc, Context, Status, InstanceClause,
GoalType = goal_type_none, % goal is not a promise
clauses_info_add_clause(all_modes, AllProcIds, CVarSet, TVarSet0,
HeadTerms, Body, Context, no, Status, PredOrFunc, Arity,
- GoalType, Goal, VarSet, _TVarSet, !ClausesInfo, Warnings,
+ GoalType, Goal, VarSet, TVarSet, !ClausesInfo, Warnings,
!ModuleInfo, !QualInfo, !Specs),
SimpleCallId = simple_call_id(PredOrFunc, PredName, Arity),
diff --git a/compiler/check_typeclass.m b/compiler/check_typeclass.m
index d70df57..4ff80bd 100644
--- a/compiler/check_typeclass.m
+++ b/compiler/check_typeclass.m
@@ -657,7 +657,7 @@ produce_auxiliary_procs(ClassId, ClassVars, MethodName, Markers0,
list.sort_and_remove_dups(VarsToKeep0, VarsToKeep),
% Project away the unwanted type variables.
- varset.squash(TVarSet1, VarsToKeep, TVarSet, SquashSubst),
+ varset.squash(TVarSet1, VarsToKeep, TVarSet2, SquashSubst),
apply_variable_renaming_to_type_list(SquashSubst, ArgTypes1, ArgTypes),
apply_variable_renaming_to_prog_constraints(SquashSubst,
ClassMethodClassContext1, ClassMethodClassContext),
@@ -703,7 +703,8 @@ produce_auxiliary_procs(ClassId, ClassVars, MethodName, Markers0,
adjust_func_arity(PredOrFunc, Arity, PredArity),
produce_instance_method_clauses(InstancePredDefn, PredOrFunc,
PredArity, ArgTypes, Markers, Context, Status, ClausesInfo,
- ModuleInfo0, ModuleInfo1, QualInfo0, QualInfo, !Specs),
+ TVarSet2, TVarSet, ModuleInfo0, ModuleInfo1, QualInfo0, QualInfo,
+ !Specs),
% Fill in some information in the pred_info which is used by polymorphism
% to make sure the type-infos and typeclass-infos are added in the correct
diff --git a/compiler/make_hlds.m b/compiler/make_hlds.m
index ab0107d..27f6a99 100644
--- a/compiler/make_hlds.m
+++ b/compiler/make_hlds.m
@@ -96,9 +96,9 @@
% for that definition.
%
:- pred produce_instance_method_clauses(instance_proc_def::in,
- pred_or_func::in, arity::in, list(mer_type)::in, pred_markers::in,
- term.context::in, import_status::in, clauses_info::out,
- module_info::in, module_info::out,
+ pred_or_func::in, arity::in, list(mer_type)::in,
+ pred_markers::in, term.context::in, import_status::in, clauses_info::out,
+ tvarset::in, tvarset::out, module_info::in, module_info::out,
make_hlds_qual_info::in, make_hlds_qual_info::out,
list(error_spec)::in, list(error_spec)::out) is det.
@@ -165,9 +165,9 @@ add_special_pred_decl_for_real(SpecialPredId, TVarSet,
produce_instance_method_clauses(InstanceProcDefn,
PredOrFunc, PredArity, ArgTypes, Markers, Context, Status,
- ClausesInfo, !ModuleInfo, !QualInfo, !Specs) :-
+ ClausesInfo, !TVarSet, !ModuleInfo, !QualInfo, !Specs) :-
do_produce_instance_method_clauses(InstanceProcDefn, PredOrFunc,
- PredArity, ArgTypes, Markers, Context, Status, ClausesInfo,
+ PredArity, ArgTypes, Markers, Context, Status, ClausesInfo, !TVarSet,
!ModuleInfo, !QualInfo, !Specs).
set_module_recomp_info(QualInfo, !ModuleInfo) :-
diff --git a/compiler/options.m b/compiler/options.m
index 06e405d..1936a1b 100644
--- a/compiler/options.m
+++ b/compiler/options.m
@@ -3438,7 +3438,7 @@ options_help_verbosity -->
% "\tOutput more detailed messages about the compiler's",
% "\ttime/space usage.",
% --debug-types works only if the compiler was compiled with
-% "--trace-flags type_checkpoint".
+% "--trace-flag type_checkpoint".
% "-T, --debug-types",
% "\tOutput detailed debugging traces of the type checking.",
"-N, --debug-modes",
diff --git a/compiler/typecheck_info.m b/compiler/typecheck_info.m
index 963572e..58d92c1 100644
--- a/compiler/typecheck_info.m
+++ b/compiler/typecheck_info.m
@@ -964,7 +964,7 @@ type_assign_constraints_to_pieces_list(Operator, [Constraint | Constraints],
write_type_with_bindings(Type0, TypeVarSet, TypeBindings, !IO) :-
apply_rec_subst_to_type(TypeBindings, Type0, Type1),
strip_builtin_qualifiers_from_type(Type1, Type),
- mercury_output_type(TypeVarSet, no, Type, !IO).
+ mercury_output_type(TypeVarSet, yes, Type, !IO).
:- func type_with_bindings_to_string(mer_type, tvarset, tsubst) = string.
diff --git a/tests/valid/Mmakefile b/tests/valid/Mmakefile
index 95a7681..f1d2608 100644
--- a/tests/valid/Mmakefile
+++ b/tests/valid/Mmakefile
@@ -31,6 +31,7 @@ TYPECLASS_PROGS= \
fundeps \
fundeps_poly_instance \
instance_superclass \
+ instance_typequal \
instance_unconstrained_tvar \
logged_stream \
mpj2 \
diff --git a/tests/valid/instance_typequal.m b/tests/valid/instance_typequal.m
new file mode 100644
index 0000000..ac7091a
--- /dev/null
+++ b/tests/valid/instance_typequal.m
@@ -0,0 +1,31 @@
+% Explicit type qualification didn't work with methods defined directly in the
+% instance declaration. Bug #123.
+
+:- module instance_typequal.
+
+:- interface.
+
+:- type e(E) ---> e(E).
+
+:- type y(A) ---> y(A).
+
+:- typeclass tc(S, T) where [
+ pred x1(S::in, T::in) is det,
+ pred x2(S::in, T::in) is det
+].
+
+:- implementation.
+
+:- instance tc(e(E), y(A)) <= tc(E, A) where [
+ ( x1(e(E), y(A : _)) :-
+ x1(E, A)
+ ),
+
+ % Explicit type variables in different clauses are distinct.
+ ( x2(e(E), y(A : T)) :-
+ x2(E, A : T)
+ ),
+ ( x2(e(E : T), y(A)) :-
+ x2(E : T, A)
+ )
+].
--------------------------------------------------------------------------
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