[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