[m-rev.] for review: restrict some typeclass definitions in .int{, 3} files to be abstract

Peter Wang novalazy at gmail.com
Wed Aug 2 11:02:09 AEST 2023


On Wed, 02 Aug 2023 07:00:20 +1000 "Zoltan Somogyi" <zoltan.somogyi at runbox.com> wrote:
> For review by Peter, because he may have an idea about why
> the situation described in the new comment in list.m arises.
> 
> Zoltan.

> Use abstract typeclasses in parse_tree_int[13].
> 
> compiler/prog_data.m:
>     Define a subtype of the typeclass interface type for abstract typeclasses.
> 
> compiler/prog_item.m:
>     Change the types of the fields representing
>     
>     - implementation section typeclasses in .int files, and
>     - interface section typeclasses in .int3 files
> 
>     to a subtype that allows the definition of only abstract typeclasses.
> 
>     The interface section typeclasses in .int3 files have more invariants
>     than just being abstract, but these cannot currently be expressed
>     using subtypes.
> 
> library/list.m:
>     Add a comment (which is visible only to Mercury developers)
>     about why this is so.
> 
> compiler/comp_unit_interface.m:
> compiler/convert_parse_tree.m:
> compiler/equiv_type.m:
> compiler/make_hlds_separate_items.m:
> compiler/module_qual.collect_mq_info.m:
> compiler/module_qual.qualify_items.m:
> compiler/parse_tree_out.m:
> compiler/recompilation.check.m:
> compiler/recompilation.version.m:
>     Conform to the changes above.

That looks fine.

> diff --git a/library/list.m b/library/list.m
> index 93f039d5a..71ea25cf8 100644
> --- a/library/list.m
> +++ b/library/list.m
> @@ -32,6 +32,22 @@
>      --->    []
>      ;       [T | list(T)].
>  
> +% UNDOC_PART_START
> +% :- type empty_list(T) =< list(T)
> +%     --->    [].
> +%
> +% :- type non_empty_list(T) =< list(T)
> +%     --->    [T | list(T)].
> +%
> +% XXX Including the above subtype definitions generates errors like these:
> +% term_conversion.m:199: In clause for predicate `term_to_univ_special_case'/6:
> +% term_conversion.m:199:   error: ambiguous overloading causes type ambiguity.
> +% term_conversion.m:199:   Possible type assignments include:
> +% term_conversion.m:199:   V_95:
> +% term_conversion.m:199:     `some [T] (list.list(T))'
> +% term_conversion.m:199:   or
> +% term_conversion.m:199:     `some [T] (list.non_empty_list(T))'
> +% UNDOC_PART_END

This occurs because [|]/2 is a constructor of both list(T) and
non_empty_list(T). The fix is to use explicit type qualification,
as below.

Perhaps we can point out which lines the terms with ambiguous types
occur on.

diff --git a/library/term_conversion.m b/library/term_conversion.m
index b9ac854b8..3117bf641 100644
--- a/library/term_conversion.m
+++ b/library/term_conversion.m
@@ -286,7 +291,7 @@ term_to_univ_special_case(ModuleName, TypeCtorName, TypeArgs, Term,
         % convert the term representing the list of elements back to a list,
         % and then (if successful) we just call the array/1 function.
         has_type(Elem, ElemType),
-        ListType = type_of([Elem]),
+        ListType = type_of([Elem] : list(_)),
         ArgContext = arg_context(atom("array"), 1, TermContext),
         NewContext = [ArgContext | PrevContext],
         try_term_to_univ_2(ArgList, ListType, NewContext, ArgResult),
@@ -309,7 +314,7 @@ term_to_univ_special_case(ModuleName, TypeCtorName, TypeArgs, Term,
         % as normal arrays.
         Term = functor(atom("version_array"), [ArgList], TermContext),
         has_type(Elem, ElemType),
-        ListType = type_of([Elem]),
+        ListType = type_of([Elem] : list(_)),
         ArgContext = arg_context(atom("version_array"), 1, TermContext),
         NewContext = [ArgContext | PrevContext],
         try_term_to_univ_2(ArgList, ListType, NewContext, ArgResult),

Peter


More information about the reviews mailing list