[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