[m-rev.] for review: Make subtypes share high-level data representation with base type.

Julien Fischer jfischer at opturion.com
Thu Apr 8 21:29:12 AEST 2021


Hi Peter,

On Thu, 1 Apr 2021, Peter Wang wrote:

> In the high-level data representation, make a subtype term be
> represented using the class corresponding to the base type constructor
> instead of its own class. This is necessary to be able to downcast
> a term from a type to a subtype in Java and C#.

...

> compiler/unify_proc.m:
>    When using the high-level data representation,
>    generate unify/compare procs for subtypes that just call the
>    unify/compare proc for the base type constructor.

(Apologies if you've addressed this in a latter diff; I'm a bit behind
on reviews posts.)

So, if the base type has a user defined equality or comparison predicate
then the subtype in high-level data grades inherits that (by virtue of the
above)?

Do we allow user-defined equality / comparison on subtypes at the moment?
If so, I think we should just disallow them and subtypes (in all grades)
should just inherit those operations from their base type.

...

> +%---------------------%
> +
> +:- pred compilation_target_uses_high_level_data(module_info::in) is semidet.
> +
> +compilation_target_uses_high_level_data(ModuleInfo) :-
> +    module_info_get_globals(ModuleInfo, Globals),
> +    globals.get_target(Globals, Target),
> +    compilation_target_high_level_data(Target) = yes.
> +
> +:- pred get_base_type_maybe_phony_arg_types(module_info::in, type_ctor::in,
> +    mer_type::out) is det.
> +
> +get_base_type_maybe_phony_arg_types(ModuleInfo, SuperTypeCtor, BaseType) :-
> +    %
> +    % XXX If a type is a subtype of a subtype, we should substitute the type
> +    % arguments into the supertype recursively until we get to the base type.
> +    % This requires that the tvarset containing the variables of the original
> +    % type be passed into mercury_type_to_mlds_type. But that would still not
> +    % solve the next problem.
> +    %
> +    % XXX If a type is a subtype of an abstract supertype, we will only know
> +    % the type ctor of the supertype, as supertype arguments are not written to
> +    % interface files (we may need to revisit that decision).
> +    %
> +    % Instead, we find the base type ctor of a type ctor and simply apply
> +    % `c_pointer' for all its type parameters. `c_pointer' corresponds to
> +    % `Object' in Java and `object' in C#.
> +    %
> +    % In almost all cases, only the type ctor in a mercury_nb_type is used,
> +    % not the type arguments. The phony type arguments only makes a difference
> +    % when generating the Java class corresponding to a Mercury type, e.g. for
> +    %
> +    %   :- type mytype(T)
> +    %       --->    mytype(abs(T)).     % abstract subtype
> +    %
> +    % we generate
> +    %
> +    %   public static class Mytype_1<MR_tvar_1>
> +    %       implements jmercury.runtime.MercuryType
> +    %   {
> +    %       public Abs_1<Object> F1;
> +    %
> +    %       public Mytype_1(Abs_1<Object> F1)
> +    %       {
> +    %           this.F1 = F1;
> +    %       }
> +    %   }
> +    %
> +    % The member F1 and constructor argument has type Abs_1<Object> instead of
> +    % Abs_1<MR_tvar_1>. The Java code will still compile and run, but there is
> +    % a slight loss of type information for hand written code that uses the F1
> +    % member. This is a very minor problem and does not seem worth fixing
> +    % unless other problems arise.

It's also not the only place where the Java backend drops type information.

The diff looks fine.

Julien.


More information about the reviews mailing list