[m-rev.] for review: correct types in java foreign procs

Peter Wang novalazy at gmail.com
Mon Aug 31 15:53:36 AEST 2009


[I won't commit this until after zs's big patch.]

Branches: main

Expose correct types to Java foreign code, e.g. a variable with a non-foreign
type like `list(T)' is now visible to Java foreign code with the type
`list.List_1' instead of `java.lang.Object'.

A complication is that foreign code for mutables is generated in the compiler
frontend, which doesn't know about the types used by the backends.  For Java,
mutable variables had the generic type `Object' (except for primitives types)
but as we now generate foreign procs with the correct variable types, the code
for accessing a mutable would be type incorrect, e.g.

        X = mutable_var;  /* list.List_1 = Object */

Here we handle generated mutable predicates as a special case, using `Object'
for the global variable and argument types and generating typecasts as before.
The correct fix would be to move mutable code generation into the backends.


compiler/make_hlds_passes.m:
        Make Java mutable variables always have the type `java.lang.Object'.

        Mark Java mutable predicates with `may_not_duplicate' attributes, as
        the generated code doesn't contain class-qualifiers for the mutable
        variable, so copying that code into other Java files won't work.

compiler/mlds.m:
        Add a new target code component `target_code_type(Type)' which is a
        placeholder for a type, to be substituted by the backend when target
        code is being printed out.

compiler/ml_code_gen.m:
        Generate Java foreign procs using `target_code_type' to declare local
        variables, except for mutable predicates as described above.

        Rename a predicate shared for C and Java.

        Assign dummy type variables the value `null' in the Java backend
        instead of `0'.

compiler/foreign.m:
        Add a comment for `exported_type_to_string'.

compiler/mlds_to_java.m:
        Handle the addition of `target_code_type'.

        Output `java.lang.Output' for builtin dummy types.  We were
        inconsistent as to whether builtin dummy types should be represented by
        `int' or `Object'.

        Output line number context in another spot. 

compiler/ml_elim_nested.m:
compiler/ml_optimize.m:
compiler/ml_util.m:
compiler/mlds_to_c.m:
compiler/mlds_to_il.m:
        Conform to the addition of `target_code_type'.

library/exception.m:
library/io.m:
library/list.m:
library/rtti_implementation.m:
library/string.m:
library/type_desc.m:
        Delete casts in some Java foreign code which are no longer required.

diff --git a/compiler/foreign.m b/compiler/foreign.m
index d289bab..947e4ff 100644
--- a/compiler/foreign.m
+++ b/compiler/foreign.m
@@ -745,6 +745,8 @@ exported_type_to_string(Lang, ExportedType) = Result :-
                 ; Type = type_variable(_, _)
                 ; Type = kinded_type(_, _)
                 ),
+                % This is here so we can share some code between C and Java
+                % backends.  This is not the correct type to use in general.
                 Result = "java.lang.Object"
             )
         ;
diff --git a/compiler/make_hlds_passes.m b/compiler/make_hlds_passes.m
index 849055f..1a84c3d 100644
--- a/compiler/make_hlds_passes.m
+++ b/compiler/make_hlds_passes.m
@@ -2311,12 +2311,8 @@ add_java_mutable_defn(TargetMutableName, Type, IsConstant,
 :- pred get_java_mutable_global_foreign_defn(module_info::in, mer_type::in,
     string::in, bool::in, prog_context::in, item::out) is det.
 
-get_java_mutable_global_foreign_defn(ModuleInfo, Type, TargetMutableName,
+get_java_mutable_global_foreign_defn(_ModuleInfo, _Type, TargetMutableName,
         IsConstant, Context, DefnItem) :-
-    module_info_get_globals(ModuleInfo, Globals),
-    globals.lookup_bool_option(Globals, mutable_always_boxed, AlwaysBoxed),
-    TypeName = global_foreign_type_name(AlwaysBoxed, lang_java, ModuleInfo,
-        Type),
     MutableMutexVarName = mutable_mutex_var_name(TargetMutableName),
 
     % Constant mutables do not require mutexes as their values are never
@@ -2331,7 +2327,7 @@ get_java_mutable_global_foreign_defn(ModuleInfo, Type, TargetMutableName,
     ),
 
     DefnBody = string.append_list([
-        "static ", TypeName, " ", TargetMutableName, ";\n" | LockDefn]),
+        "static java.lang.Object ", TargetMutableName, ";\n" | LockDefn]),
     DefnPragma = pragma_foreign_code(lang_java, DefnBody),
     DefnItemPragma = item_pragma_info(compiler(mutable_decl), DefnPragma,
         Context, -1),
@@ -2348,7 +2344,11 @@ add_java_mutable_preds(ItemMutable, TargetMutableName,
     ItemMutable = item_mutable_info(MercuryMutableName, _Type, InitTerm, Inst,
         MutAttrs, MutVarset, Context, _SeqNum),
     IsConstant = mutable_var_constant(MutAttrs),
-    Attrs = default_attributes(lang_java),
+    Attrs0 = default_attributes(lang_java),
+    % The mutable variable name is not module-qualified so cannot be exported
+    % to `.opt' files. We could add the qualification but it would be better
+    % to move the mutable code generation into the backends first.
+    set_may_duplicate(yes(proc_may_not_duplicate), Attrs0, Attrs),
     module_info_get_globals(!.ModuleInfo, Globals),
     globals.lookup_bool_option(Globals, mutable_always_boxed, AlwaysBoxed),
     (
diff --git a/compiler/ml_code_gen.m b/compiler/ml_code_gen.m
index 801349a..608ef55 100644
--- a/compiler/ml_code_gen.m
+++ b/compiler/ml_code_gen.m
@@ -2382,10 +2382,10 @@ ml_gen_nondet_pragma_foreign_proc(CodeModel, Attributes, PredId, _ProcId,
         ], HashUndefs),
 
     % Generate code to set the values of the input variables.
-    ml_gen_pragma_c_input_arg_list(Lang, Args, AssignInputsList, !Info),
+    ml_gen_pragma_c_java_input_arg_list(Lang, Args, AssignInputsList, !Info),
 
     % Generate code to assign the values of the output variables.
-    ml_gen_pragma_c_output_arg_list(Lang, Args, Context,
+    ml_gen_pragma_c_output_arg_list(Args, Context,
         AssignOutputsList, ConvDecls, ConvStatements, !Info),
 
     % Generate code fragments to obtain and release the global lock.
@@ -2601,21 +2601,29 @@ ml_gen_ordinary_pragma_foreign_proc(CodeModel, Attributes, PredId, ProcId,
     prog_context::in, list(mlds_defn)::out, list(statement)::out,
     ml_gen_info::in, ml_gen_info::out) is det.
 
-ml_gen_ordinary_pragma_java_proc(_CodeModel, Attributes, _PredId, _ProcId,
+ml_gen_ordinary_pragma_java_proc(_CodeModel, Attributes, PredId, _ProcId,
         Args, ExtraArgs, JavaCode, Context, Decls, Statements, !Info) :-
-
     Lang = get_foreign_language(Attributes),
 
+    ml_gen_info_get_module_info(!.Info, ModuleInfo),
+    module_info_pred_info(ModuleInfo, PredId, PredInfo),
+    pred_info_get_markers(PredInfo, Markers),
+    ( check_marker(Markers, marker_mutable_access_pred) ->
+        MutableSpecial = mutable_special_case
+    ;
+        MutableSpecial = not_mutable_special_case
+    ),
+
     % Generate <declaration of one local variable for each arg>
-    ml_gen_pragma_c_decls(!.Info, Lang, Args, ArgDeclsList),
+    ml_gen_pragma_java_decls(!.Info, MutableSpecial, Args, ArgDeclsList),
     expect(unify(ExtraArgs, []), this_file,
         "ml_gen_ordinary_pragma_java_proc: extra args"),
 
     % Generate code to set the values of the input variables.
-    ml_gen_pragma_c_input_arg_list(Lang, Args, AssignInputsList, !Info),
+    ml_gen_pragma_c_java_input_arg_list(Lang, Args, AssignInputsList, !Info),
 
     % Generate MLDS statements to assign the values of the output variables.
-    ml_gen_pragma_java_output_arg_list(Lang, Args, Context,
+    ml_gen_pragma_java_output_arg_list(MutableSpecial, Args, Context,
         AssignOutputsList, ConvDecls, ConvStatements, !Info),
 
     % Put it all together
@@ -2971,10 +2979,10 @@ ml_gen_ordinary_pragma_c_proc(OrdinaryKind, Attributes, PredId, _ProcId,
     ml_gen_pragma_c_decls(!.Info, Lang, Args, ArgDeclsList),
 
     % Generate code to set the values of the input variables.
-    ml_gen_pragma_c_input_arg_list(Lang, Args, AssignInputsList, !Info),
+    ml_gen_pragma_c_java_input_arg_list(Lang, Args, AssignInputsList, !Info),
 
     % Generate code to assign the values of the output variables.
-    ml_gen_pragma_c_output_arg_list(Lang, Args, Context,
+    ml_gen_pragma_c_output_arg_list(Args, Context,
         AssignOutputsList, ConvDecls, ConvStatements, !Info),
 
     % Generate code fragments to obtain and release the global lock.
@@ -3142,9 +3150,6 @@ get_target_code_attributes(Lang, [ProcAttr | ProcAttrs]) = TargetAttrs :-
 :- pred ml_gen_pragma_c_decls(ml_gen_info::in, foreign_language::in,
     list(foreign_arg)::in, list(target_code_component)::out) is det.
 
-    % XXX Maybe this ought to be renamed as it works for, and
-    % is used by the Java back-end as well.
-    %
 ml_gen_pragma_c_decls(_, _, [], []).
 ml_gen_pragma_c_decls(Info, Lang, [Arg | Args], [Decl | Decls]) :-
     ml_gen_pragma_c_decl(Info, Lang, Arg, Decl),
@@ -3181,6 +3186,55 @@ ml_gen_pragma_c_decl(Info, Lang, Arg, Decl) :-
 
 %-----------------------------------------------------------------------------%
 
+:- type mutable_special_case
+    --->    mutable_special_case
+    ;       not_mutable_special_case.
+
+    % ml_gen_pragma_java_decls generates Java code to declare the arguments
+    % for a `pragma foreign_proc' declaration.
+    %
+:- pred ml_gen_pragma_java_decls(ml_gen_info::in, mutable_special_case::in,
+    list(foreign_arg)::in, list(target_code_component)::out) is det.
+
+ml_gen_pragma_java_decls(_, _, [], []).
+ml_gen_pragma_java_decls(Info, MutableSpecial, [Arg | Args], Decl ++ Decls) :-
+    ml_gen_pragma_java_decl(Info, MutableSpecial, Arg, Decl),
+    ml_gen_pragma_java_decls(Info, MutableSpecial, Args, Decls).
+
+    % ml_gen_pragma_java_decl generates Java code to declare an argument
+    % of a `pragma foreign_proc' declaration.
+    %
+:- pred ml_gen_pragma_java_decl(ml_gen_info::in, mutable_special_case::in,
+    foreign_arg::in, list(target_code_component)::out) is det.
+
+ml_gen_pragma_java_decl(Info, MutableSpecial, Arg, Decl) :-
+    Arg = foreign_arg(_Var, MaybeNameAndMode, Type, _BoxPolicy),
+    ml_gen_info_get_module_info(Info, ModuleInfo),
+    (
+        MaybeNameAndMode = yes(ArgName - _Mode),
+        not var_is_singleton(ArgName)
+    ->
+        (
+            MutableSpecial = not_mutable_special_case,
+            MLDS_Type = mercury_type_to_mlds_type(ModuleInfo, Type)
+        ;
+            MutableSpecial = mutable_special_case,
+            % The code for mutables is generated in the frontend.
+            % All mutable variables have the type `java.lang.Object'.
+            MLDS_Type = mlds_generic_type
+        ),
+        TypeDecl = target_code_type(MLDS_Type),
+        string.format(" %s;\n", [s(ArgName)], VarDeclString),
+        VarDecl = raw_target_code(VarDeclString, []),
+        Decl = [TypeDecl, VarDecl]
+    ;
+        % If the variable doesn't occur in the ArgNames list,
+        % it can't be used, so we just ignore it.
+        Decl = []
+    ).
+
+%-----------------------------------------------------------------------------%
+
     % var_is_singleton determines whether or not a given foreign_proc variable
     % is singleton (i.e. starts with an underscore)
     %
@@ -3197,26 +3251,25 @@ var_is_singleton(Name) :-
 
 %-----------------------------------------------------------------------------%
 
-    % XXX Maybe this ought to be renamed as it works for, and is used
-    % by the Java back-end as well.
+    % For both C and Java.
     %
-:- pred ml_gen_pragma_c_input_arg_list(foreign_language::in,
+:- pred ml_gen_pragma_c_java_input_arg_list(foreign_language::in,
     list(foreign_arg)::in, list(target_code_component)::out,
     ml_gen_info::in, ml_gen_info::out) is det.
 
-ml_gen_pragma_c_input_arg_list(Lang, ArgList, AssignInputs, !Info) :-
-    list.map_foldl(ml_gen_pragma_c_input_arg(Lang), ArgList,
+ml_gen_pragma_c_java_input_arg_list(Lang, ArgList, AssignInputs, !Info) :-
+    list.map_foldl(ml_gen_pragma_c_java_input_arg(Lang), ArgList,
         AssignInputsList, !Info),
     list.condense(AssignInputsList, AssignInputs).
 
-    % ml_gen_pragma_c_input_arg generates C code to assign the value of an
-    % input arg for a `pragma foreign_proc' declaration.
+    % ml_gen_pragma_c_input_arg generates C or Java code to assign the value of
+    % an input arg for a `pragma foreign_proc' declaration.
     %
-:- pred ml_gen_pragma_c_input_arg(foreign_language::in, foreign_arg::in,
+:- pred ml_gen_pragma_c_java_input_arg(foreign_language::in, foreign_arg::in,
     list(target_code_component)::out,
     ml_gen_info::in, ml_gen_info::out) is det.
 
-ml_gen_pragma_c_input_arg(Lang, ForeignArg, AssignInput, !Info) :-
+ml_gen_pragma_c_java_input_arg(Lang, ForeignArg, AssignInput, !Info) :-
     ml_gen_info_get_module_info(!.Info, ModuleInfo),
     (
         ForeignArg = foreign_arg(Var, MaybeNameAndMode, OrigType, BoxPolicy),
@@ -3224,7 +3277,7 @@ ml_gen_pragma_c_input_arg(Lang, ForeignArg, AssignInput, !Info) :-
         not var_is_singleton(ArgName),
         mode_to_arg_mode(ModuleInfo, Mode, OrigType, top_in)
     ->
-        ml_gen_pragma_c_gen_input_arg(Lang, Var, ArgName, OrigType,
+        ml_gen_pragma_c_java_gen_input_arg(Lang, Var, ArgName, OrigType,
             BoxPolicy, AssignInput, !Info)
     ;
         % If the variable doesn't occur in the ArgNames list,
@@ -3232,11 +3285,11 @@ ml_gen_pragma_c_input_arg(Lang, ForeignArg, AssignInput, !Info) :-
         AssignInput = []
     ).
 
-:- pred ml_gen_pragma_c_gen_input_arg(foreign_language::in, prog_var::in,
+:- pred ml_gen_pragma_c_java_gen_input_arg(foreign_language::in, prog_var::in,
     string::in, mer_type::in, box_policy::in, list(target_code_component)::out,
     ml_gen_info::in, ml_gen_info::out) is det.
 
-ml_gen_pragma_c_gen_input_arg(Lang, Var, ArgName, OrigType, BoxPolicy,
+ml_gen_pragma_c_java_gen_input_arg(Lang, Var, ArgName, OrigType, BoxPolicy,
         AssignInput, !Info) :-
     ml_variable_type(!.Info, Var, VarType),
     ml_gen_var(!.Info, Var, VarLval),
@@ -3245,10 +3298,10 @@ ml_gen_pragma_c_gen_input_arg(Lang, Var, ArgName, OrigType, BoxPolicy,
     (
         IsDummy = is_dummy_type,
         % The variable may not have been declared, so we need to generate
-        % a dummy value for it. Using `0' here is more efficient than using
-        % private_builtin.dummy_var, which is what ml_gen_var will have
+        % a dummy value for it. Using a constant here is more efficient than
+        % using private_builtin.dummy_var, which is what ml_gen_var will have
         % generated for this variable.
-        ArgRval = ml_const(mlconst_int(0))
+        ArgRval = dummy_arg_rval(Lang, ModuleInfo, VarType)
     ;
         IsDummy = is_not_dummy_type,
         ml_gen_box_or_unbox_rval(VarType, OrigType, BoxPolicy,
@@ -3259,48 +3312,13 @@ ml_gen_pragma_c_gen_input_arg(Lang, Var, ArgName, OrigType, BoxPolicy,
     % to convert this to the appropriate type to use for the C interface.
     ExportedType = foreign.to_exported_type(ModuleInfo, OrigType),
     TypeString = exported_type_to_string(Lang, ExportedType),
-    IsForeign = foreign.is_foreign_type(ExportedType),
+    module_info_get_globals(ModuleInfo, Globals),
+    globals.lookup_bool_option(Globals, highlevel_data, HighLevelData),
     (
-        (
-            Lang = lang_java,
-            MaybeCast = no
-        ;
-            Lang = lang_c,
-            IsForeign = no,
-            MaybeCast = no
-        ;
-            Lang = lang_c,
-            IsForeign = yes(Assertions),
-            list.member(foreign_type_can_pass_as_mercury_type, Assertions),
-            MaybeCast = yes("(" ++ TypeString ++ ") ")
-        )
+        input_arg_assignable_with_cast(Lang, HighLevelData, OrigType,
+            ExportedType, TypeString, Cast)
     ->
         % In the usual case, we can just use an assignment and perhaps a cast.
-        module_info_get_globals(ModuleInfo, Globals),
-        globals.lookup_bool_option(Globals, highlevel_data, HighLevelData),
-        (
-            HighLevelData = yes,
-            % In general, the types used for the C interface are not the same
-            % as the types used by --high-level-data, so we always use a cast
-            % here. (Strictly speaking the cast is not needed for a few cases
-            % like `int', but it doesn't do any harm.)
-            string.format("(%s)", [s(TypeString)], Cast)
-        ;
-            HighLevelData = no,
-            % For --no-high-level-data, we only need to use a cast is for
-            % polymorphic types, which are `MR_Word' in the C interface but
-            % `MR_Box' in the MLDS back-end.
-            ( OrigType = type_variable(_, _) ->
-                Cast = "(MR_Word) "
-            ;
-                (
-                    MaybeCast = yes(Cast)
-                ;
-                    MaybeCast = no,
-                    Cast = ""
-                )
-            )
-        ),
         string.format("\t%s = %s ", [s(ArgName), s(Cast)], AssignToArgName),
         AssignInput = [
             raw_target_code(AssignToArgName, []),
@@ -3308,9 +3326,8 @@ ml_gen_pragma_c_gen_input_arg(Lang, Var, ArgName, OrigType, BoxPolicy,
             raw_target_code(";\n", [])
         ]
     ;
-        % For foreign types,
-        % we need to call MR_MAYBE_UNBOX_FOREIGN_TYPE
-        % XXX not if can_pass_as_mercury_type is set
+        % For foreign types (without the `can_pass_as_mercury_type' assertion)
+        % we need to call MR_MAYBE_UNBOX_FOREIGN_TYPE.
         AssignInput = [
             raw_target_code("\tMR_MAYBE_UNBOX_FOREIGN_TYPE("
                 ++ TypeString ++ ", ", []),
@@ -3319,17 +3336,73 @@ ml_gen_pragma_c_gen_input_arg(Lang, Var, ArgName, OrigType, BoxPolicy,
         ]
     ).
 
-:- pred ml_gen_pragma_java_output_arg_list(foreign_language::in,
+:- func dummy_arg_rval(foreign_language, module_info, mer_type) = mlds_rval.
+
+dummy_arg_rval(Lang, ModuleInfo, Type) = Rval :-
+    MLDS_Type = mercury_type_to_mlds_type(ModuleInfo, Type),
+    ( Lang = lang_java ->
+        Rval = ml_const(mlconst_null(MLDS_Type))
+    ;
+        Rval = ml_const(mlconst_int(0))
+    ).
+
+:- pred input_arg_assignable_with_cast(foreign_language::in, bool::in,
+    mer_type::in, exported_type::in, string::in, string::out) is semidet.
+
+input_arg_assignable_with_cast(Lang, HighLevelData, OrigType, ExportedType,
+        TypeString, Cast) :-
+    (
+        Lang = lang_c,
+        HighLevelData = yes,
+        % In general, the types used for the C interface are not the same
+        % as the types used by --high-level-data, so we always use a cast
+        % here. (Strictly speaking the cast is not needed for a few cases
+        % like `int', but it doesn't do any harm.)
+        Cast = "(" ++ TypeString ++ ")"
+    ;
+        Lang = lang_c,
+        HighLevelData = no,
+        ( OrigType = type_variable(_, _) ->
+            % For --no-high-level-data, we only need to use a cast for
+            % polymorphic types, which are `MR_Word' in the C interface but
+            % `MR_Box' in the MLDS back-end.
+            Cast = "(MR_Word)"
+        ;
+            IsForeign = foreign.is_foreign_type(ExportedType),
+            (
+                IsForeign = yes(Assertions),
+                list.member(foreign_type_can_pass_as_mercury_type, Assertions),
+                Cast = "(" ++ TypeString ++ ")"
+            ;
+                IsForeign = no,
+                Cast = ""
+            )
+        )
+    ;
+        Lang = lang_java,
+        % There is no difference between types used by the foreign interface
+        % and the generated code.
+        Cast = ""
+    ;
+        ( Lang = lang_csharp
+        ; Lang = lang_il
+        ; Lang = lang_erlang
+        ),
+        unexpected(this_file,
+            "input_arg_assignable_with_cast: unexpected language")
+    ).
+
+:- pred ml_gen_pragma_java_output_arg_list(mutable_special_case::in,
     list(foreign_arg)::in, prog_context::in, list(statement)::out,
     list(mlds_defn)::out, list(statement)::out,
     ml_gen_info::in, ml_gen_info::out) is det.
 
 ml_gen_pragma_java_output_arg_list(_, [], _, [], [], [], !Info).
-ml_gen_pragma_java_output_arg_list(Lang, [Java_Arg | Java_Args], Context,
-        Statements, ConvDecls, ConvStatements, !Info) :-
-    ml_gen_pragma_java_output_arg(Lang, Java_Arg, Context, Statements1,
-        ConvDecls1, ConvStatements1, !Info),
-    ml_gen_pragma_java_output_arg_list(Lang, Java_Args, Context,
+ml_gen_pragma_java_output_arg_list(MutableSpecial, [JavaArg | JavaArgs],
+        Context, Statements, ConvDecls, ConvStatements, !Info) :-
+    ml_gen_pragma_java_output_arg(MutableSpecial, JavaArg, Context,
+        Statements1, ConvDecls1, ConvStatements1, !Info),
+    ml_gen_pragma_java_output_arg_list(MutableSpecial, JavaArgs, Context,
         Statements2, ConvDecls2, ConvStatements2, !Info),
     Statements = Statements1 ++ Statements2,
     ConvDecls = ConvDecls1 ++ ConvDecls2,
@@ -3338,13 +3411,13 @@ ml_gen_pragma_java_output_arg_list(Lang, [Java_Arg | Java_Args], Context,
     % ml_gen_pragma_java_output_arg generates MLDS statements to assign the
     % value of an output arg for a `pragma foreign_proc' declaration.
     %
-:- pred ml_gen_pragma_java_output_arg(foreign_language::in,
+:- pred ml_gen_pragma_java_output_arg(mutable_special_case::in,
     foreign_arg::in, prog_context::in, list(statement)::out,
     list(mlds_defn)::out, list(statement)::out,
     ml_gen_info::in, ml_gen_info::out) is det.
 
-ml_gen_pragma_java_output_arg(_Lang, ForeignArg, Context, AssignOutput,
-        ConvDecls, ConvOutputStatements, !Info) :-
+ml_gen_pragma_java_output_arg(MutableSpecial, ForeignArg, Context,
+        AssignOutput, ConvDecls, ConvOutputStatements, !Info) :-
     ForeignArg = foreign_arg(Var, MaybeNameAndMode, OrigType, BoxPolicy),
     ml_gen_info_get_module_info(!.Info, ModuleInfo),
     (
@@ -3361,24 +3434,24 @@ ml_gen_pragma_java_output_arg(_Lang, ForeignArg, Context, AssignOutput,
             VarLval, mlds_var_name(ArgName, no), Context, no, 0,
             ArgLval, ConvDecls, _ConvInputStatements,
             ConvOutputStatements, !Info),
-        % This is the MLDS type of the original argument, which we need to
-        % cast the local (Java) representation of the argument back to.
         MLDSType = mercury_type_to_mlds_type(ModuleInfo, OrigType),
-        % Construct an MLDS lval for the local Java representation
-        % of the argument.
         module_info_get_name(ModuleInfo, ModuleName),
         MLDSModuleName = mercury_module_name_to_mlds(ModuleName),
         NonMangledVarName = mlds_var_name(ArgName, no),
         QualLocalVarName = qual(MLDSModuleName, module_qual,
             NonMangledVarName),
-        % XXX MLDSType is the incorrect type for this variable.
-        % It should have the Java foreign language representation
-        % of that type. Unfortunately this is not easily expressed
-        % as an mlds_type.
         LocalVarLval = ml_var(QualLocalVarName, MLDSType),
-        % We cast this variable back to the corresponding
-        % MLDS type before assigning it to the lval.
-        Rval = ml_unop(cast(MLDSType), ml_lval(LocalVarLval)),
+        (
+            MutableSpecial = not_mutable_special_case,
+            Rval = ml_lval(LocalVarLval)
+        ;
+            MutableSpecial = mutable_special_case,
+            % The code for mutables is generated in the frontend.
+            % All mutable variables have the type `java.lang.Object'
+            % so we need to cast the variable or extract the primitive
+            % value from the box.
+            Rval = ml_unop(unbox(MLDSType), ml_lval(LocalVarLval))
+        ),
         AssignOutput = [ml_gen_assign(ArgLval, Rval, Context)]
     ;
         % If the variable doesn't occur in the ArgNames list,
@@ -3388,18 +3461,17 @@ ml_gen_pragma_java_output_arg(_Lang, ForeignArg, Context, AssignOutput,
         ConvOutputStatements = []
     ).
 
-:- pred ml_gen_pragma_c_output_arg_list(foreign_language::in,
-    list(foreign_arg)::in, prog_context::in,
-    list(target_code_component)::out,
+:- pred ml_gen_pragma_c_output_arg_list(list(foreign_arg)::in,
+    prog_context::in, list(target_code_component)::out,
     list(mlds_defn)::out, list(statement)::out,
     ml_gen_info::in, ml_gen_info::out) is det.
 
-ml_gen_pragma_c_output_arg_list(_, [], _, [], [], [], !Info).
-ml_gen_pragma_c_output_arg_list(Lang, [ForeignArg | ForeignArgs], Context,
+ml_gen_pragma_c_output_arg_list([], _, [], [], [], !Info).
+ml_gen_pragma_c_output_arg_list([ForeignArg | ForeignArgs], Context,
         Components, ConvDecls, ConvStatements, !Info) :-
-    ml_gen_pragma_c_output_arg(Lang, ForeignArg, Context, Components1,
+    ml_gen_pragma_c_output_arg(ForeignArg, Context, Components1,
         ConvDecls1, ConvStatements1, !Info),
-    ml_gen_pragma_c_output_arg_list(Lang, ForeignArgs, Context,
+    ml_gen_pragma_c_output_arg_list(ForeignArgs, Context,
         Components2, ConvDecls2, ConvStatements2, !Info),
     Components = Components1 ++ Components2,
     ConvDecls = ConvDecls1 ++ ConvDecls2,
@@ -3408,12 +3480,12 @@ ml_gen_pragma_c_output_arg_list(Lang, [ForeignArg | ForeignArgs], Context,
     % ml_gen_pragma_c_output_arg generates C code to assign the value of
     % an output arg for a `pragma foreign_proc' declaration.
     %
-:- pred ml_gen_pragma_c_output_arg(foreign_language::in, foreign_arg::in,
+:- pred ml_gen_pragma_c_output_arg(foreign_arg::in,
     prog_context::in, list(target_code_component)::out,
     list(mlds_defn)::out, list(statement)::out,
     ml_gen_info::in, ml_gen_info::out) is det.
 
-ml_gen_pragma_c_output_arg(Lang, Arg, Context, AssignOutput, ConvDecls,
+ml_gen_pragma_c_output_arg(Arg, Context, AssignOutput, ConvDecls,
         ConvOutputStatements, !Info) :-
     Arg = foreign_arg(Var, MaybeNameAndMode, OrigType, BoxPolicy),
     ml_gen_info_get_module_info(!.Info, ModuleInfo),
@@ -3423,7 +3495,7 @@ ml_gen_pragma_c_output_arg(Lang, Arg, Context, AssignOutput, ConvDecls,
         check_dummy_type(ModuleInfo, OrigType) = is_not_dummy_type,
         mode_to_arg_mode(ModuleInfo, Mode, OrigType, top_out)
     ->
-        ml_gen_pragma_c_gen_output_arg(Lang, Var, ArgName, OrigType, BoxPolicy,
+        ml_gen_pragma_c_gen_output_arg(Var, ArgName, OrigType, BoxPolicy,
             Context, AssignOutput, ConvDecls, ConvOutputStatements, !Info)
     ;
         % If the variable doesn't occur in the ArgNames list,
@@ -3433,13 +3505,13 @@ ml_gen_pragma_c_output_arg(Lang, Arg, Context, AssignOutput, ConvDecls,
         ConvOutputStatements = []
     ).
 
-:- pred ml_gen_pragma_c_gen_output_arg(foreign_language::in, prog_var::in,
+:- pred ml_gen_pragma_c_gen_output_arg(prog_var::in,
     string::in, mer_type::in, box_policy::in, prog_context::in,
     list(target_code_component)::out,
     list(mlds_defn)::out, list(statement)::out,
     ml_gen_info::in, ml_gen_info::out) is det.
 
-ml_gen_pragma_c_gen_output_arg(Lang, Var, ArgName, OrigType, BoxPolicy,
+ml_gen_pragma_c_gen_output_arg(Var, ArgName, OrigType, BoxPolicy,
         Context, AssignOutput, ConvDecls, ConvOutputStatements, !Info) :-
     ml_variable_type(!.Info, Var, VarType),
     ml_gen_var(!.Info, Var, VarLval),
@@ -3451,19 +3523,13 @@ ml_gen_pragma_c_gen_output_arg(Lang, Var, ArgName, OrigType, BoxPolicy,
     % to convert this to the appropriate type to use for the C interface.
     ml_gen_info_get_module_info(!.Info, ModuleInfo),
     ExportedType = foreign.to_exported_type(ModuleInfo, OrigType),
-    TypeString = exported_type_to_string(Lang, ExportedType),
+    TypeString = exported_type_to_string(lang_c, ExportedType),
     IsForeign = foreign.is_foreign_type(ExportedType),
     (
         (
-            Lang = lang_java,
-            IsForeign = no,
-            Cast = no
-        ;
-            Lang = lang_c,
             IsForeign = no,
             Cast = no
         ;
-            Lang = lang_c,
             IsForeign = yes(Assertions),
             list.member(foreign_type_can_pass_as_mercury_type, Assertions),
             Cast = yes
diff --git a/compiler/ml_elim_nested.m b/compiler/ml_elim_nested.m
index 79c03ea..caf07f3 100644
--- a/compiler/ml_elim_nested.m
+++ b/compiler/ml_elim_nested.m
@@ -1947,6 +1947,7 @@ fixup_target_code_component(Action, Info, Component0, Component) :-
     (
         ( Component0 = raw_target_code(_Code, _Attrs)
         ; Component0 = user_target_code(_Code, _Context, _Attrs)
+        ; Component0 = target_code_type(_Type)
         ; Component0 = target_code_name(_Name)
         ),
         Component = Component0
diff --git a/compiler/ml_optimize.m b/compiler/ml_optimize.m
index 7ff4f61..7521476 100644
--- a/compiler/ml_optimize.m
+++ b/compiler/ml_optimize.m
@@ -1268,6 +1268,7 @@ eliminate_var_in_target_code_component(Component0, Component, !VarElimInfo) :-
     (
         ( Component0 = raw_target_code(_Code, _Attrs)
         ; Component0 = user_target_code(_Code, _Context, _Attrs)
+        ; Component0 = target_code_type(_Type)
         ; Component0 = target_code_name(_Name)
         ),
         Component = Component0
diff --git a/compiler/ml_util.m b/compiler/ml_util.m
index 6622c5e..72161b5 100644
--- a/compiler/ml_util.m
+++ b/compiler/ml_util.m
@@ -443,7 +443,7 @@ atomic_stmt_contains_var(trail_op(TrailOp), Name) :-
     trail_op_contains_var(TrailOp, Name).
 atomic_stmt_contains_var(inline_target_code(_Lang, Components), Name) :-
     list.member(Component, Components),
-    target_code_component_contains_var(Component, Name).
+    target_code_component_contains_var(Component, Name) = yes.
 
 :- pred trail_op_contains_var(trail_op::in, mlds_data::in) is semidet.
 
@@ -458,22 +458,34 @@ trail_op_contains_var(mark_ticket_stack(Lval), Name) :-
 trail_op_contains_var(prune_tickets_to(Rval), Name) :-
     rval_contains_var(Rval, Name).
 
-:- pred target_code_component_contains_var(target_code_component::in,
-    mlds_data::in) is semidet.
+:- func target_code_component_contains_var(target_code_component, mlds_data)
+    = bool.
 
-%target_code_component_contains_var(raw_target_code(_Code), _Name) :-
-%   fail.
-%target_code_component_contains_var(user_target_code(_Code, _Ctxt), _Name) :-
-%   fail.
-target_code_component_contains_var(target_code_input(Rval), Name) :-
-    rval_contains_var(Rval, Name).
-target_code_component_contains_var(target_code_output(Lval), Name) :-
-    lval_contains_var(Lval, Name).
-target_code_component_contains_var(target_code_name(EntityName), DataName) :-
-    EntityName = qual(ModuleName, QualKind, entity_data(UnqualDataName)),
-    DataName = qual(ModuleName, QualKind, UnqualDataName),
-    % This is a place where we can succeed.
-    true.
+target_code_component_contains_var(TargetCode, DataName) = ContainsVar :-
+    (
+        ( TargetCode = user_target_code(_, _, _)
+        ; TargetCode = raw_target_code(_, _)
+        ; TargetCode = target_code_type(_)
+        ),
+        ContainsVar = no
+    ;
+        TargetCode = target_code_input(Rval),
+        ContainsVar = pred_to_bool(rval_contains_var(Rval, DataName))
+    ;
+        TargetCode = target_code_output(Lval),
+        ContainsVar = pred_to_bool(lval_contains_var(Lval, DataName))
+    ;
+        TargetCode = target_code_name(EntityName),
+        (
+            EntityName = qual(ModuleName, QualKind,
+                entity_data(UnqualDataName)),
+            DataName = qual(ModuleName, QualKind, UnqualDataName)
+        ->
+            ContainsVar = yes
+        ;
+            ContainsVar = no
+        )
+    ).
 
 has_foreign_languages(Statement, Langs) :-
     GetTargetCode = (pred(Lang::out) is nondet :-
diff --git a/compiler/mlds.m b/compiler/mlds.m
index 0ce2417..4b1474c 100644
--- a/compiler/mlds.m
+++ b/compiler/mlds.m
@@ -1417,6 +1417,7 @@
 
     ;       target_code_input(mlds_rval)
     ;       target_code_output(mlds_lval)
+    ;       target_code_type(mlds_type)
     ;       target_code_name(mlds_qualified_entity_name).
 
 :- type target_code_attributes == list(target_code_attribute).
diff --git a/compiler/mlds_to_c.m b/compiler/mlds_to_c.m
index c8b7f3e..2bd82b1 100644
--- a/compiler/mlds_to_c.m
+++ b/compiler/mlds_to_c.m
@@ -3362,6 +3362,10 @@ mlds_output_target_code_component(Context, TargetCode, !IO) :-
         mlds_output_lval(Lval, !IO),
         io.write_string(" ", !IO)
     ;
+        TargetCode = target_code_type(Type),
+        mlds_output_type(Type, !IO),
+        io.write_string(" ", !IO)
+    ;
         % Note: `target_code_name(Name)' target_code_components are used to
         % generate the #define for `MR_PROC_LABEL'.
         % The fact that they're used in a #define means that we can't do
diff --git a/compiler/mlds_to_il.m b/compiler/mlds_to_il.m
index 1dd0490..c973039 100644
--- a/compiler/mlds_to_il.m
+++ b/compiler/mlds_to_il.m
@@ -2230,6 +2230,9 @@ inline_code_to_il_asm([T | Ts]) = Instrs ++ Rest :-
         T = target_code_output(_),
         Instrs = empty
     ;
+        T = target_code_type(_),
+        Instrs = empty
+    ;
         T = target_code_name(_),
         Instrs = empty
     ),
diff --git a/compiler/mlds_to_java.m b/compiler/mlds_to_java.m
index 796c0fb..72d053c 100644
--- a/compiler/mlds_to_java.m
+++ b/compiler/mlds_to_java.m
@@ -2641,18 +2641,25 @@ output_mlds_var_name(mlds_var_name(Name, yes(Num)), !IO) :-
 :- pred output_type(output_style::in, mlds_type::in, io::di, io::uo) is det.
 
 output_type(Style, mercury_type(Type, CtorCat, _), !IO) :-
-    ( Type = c_pointer_type ->
-        % The c_pointer type is used in the c back-end as a generic way
-        % to pass foreign types to automatically generated Compare and Unify
-        % code. When compiling to Java we must instead use java.lang.Object.
-        io.write_string("/* c_pointer */ java.lang.Object", !IO)
-    ;
+    (
         % We need to handle type_info (etc.) types specially -- they get mapped
         % to types in the runtime rather than in private_builtin.
         hand_defined_type(CtorCat, SubstituteName)
     ->
         io.write_string(SubstituteName, !IO)
     ;
+        % io.state and store.store
+        CtorCat = ctor_cat_builtin_dummy
+    ->
+        io.write_string("/* builtin_dummy */ java.lang.Object", !IO)
+    ;
+        Type = c_pointer_type
+    ->
+        % The c_pointer type is used in the c back-end as a generic way
+        % to pass foreign types to automatically generated Compare and Unify
+        % code. When compiling to Java we must instead use java.lang.Object.
+        io.write_string("/* c_pointer */ java.lang.Object", !IO)
+    ;
         output_mercury_type(Style, Type, CtorCat, !IO)
     ).
 
@@ -3709,9 +3716,13 @@ output_atomic_stmt(_Indent, _, _FuncInfo,
 output_target_code_component(ModuleInfo, ModuleName, _Context, TargetCode,
         !IO) :-
     (
-        TargetCode = user_target_code(CodeString, _MaybeUserContext, _Attrs),
-        % XXX Java does not have an equivalent of the C #line preprocessor
-        % directive. If it did, we should use it here.
+        TargetCode = user_target_code(CodeString, MaybeUserContext, _Attrs),
+        (
+            MaybeUserContext = yes(ProgContext),
+            output_context(mlds_make_context(ProgContext), !IO)
+        ;
+            MaybeUserContext = no
+        ),
         io.write_string(CodeString, !IO)
     ;
         TargetCode = raw_target_code(CodeString, _Attrs),
@@ -3723,6 +3734,9 @@ output_target_code_component(ModuleInfo, ModuleName, _Context, TargetCode,
         TargetCode = target_code_output(Lval),
         output_lval(ModuleInfo, Lval, ModuleName, !IO)
     ;
+        TargetCode = target_code_type(Type),
+        output_type(normal_style, Type, !IO)
+    ;
         TargetCode = target_code_name(Name),
         output_maybe_qualified_name(Name, ModuleName, !IO)
     ).
diff --git a/library/exception.m b/library/exception.m
index 6afb777..7d65df4 100644
--- a/library/exception.m
+++ b/library/exception.m
@@ -1654,12 +1654,12 @@ call_handler(Handler, Exception, Result) :- Handler(Exception, Result).
 "
     try {
         T = exception.ML_call_goal_det(
-            (jmercury.runtime.TypeInfo_Struct) TypeInfo_for_T,
+            TypeInfo_for_T,
             (Object[]) Pred);
     }
     catch (jmercury.runtime.Exception ex) {
         T = exception.ML_call_handler_det(
-            (jmercury.runtime.TypeInfo_Struct) TypeInfo_for_T,
+            TypeInfo_for_T,
             (Object[]) Handler,
             (univ.Univ_0) ex.exception);
     }
@@ -1670,12 +1670,12 @@ call_handler(Handler, Exception, Result) :- Handler(Exception, Result).
 "
     try {
         T = exception.ML_call_goal_semidet(
-            (jmercury.runtime.TypeInfo_Struct) TypeInfo_for_T,
+            TypeInfo_for_T,
             (Object[]) Pred);
     }
     catch (jmercury.runtime.Exception ex) {
         T = exception.ML_call_handler_det(
-            (jmercury.runtime.TypeInfo_Struct) TypeInfo_for_T,
+            TypeInfo_for_T,
             (Object[]) Handler,
             (univ.Univ_0) ex.exception);
     }
@@ -1722,8 +1722,7 @@ call_handler(Handler, Exception, Result) :- Handler(Exception, Result).
         pred.call___0_0(new java.lang.Object[] { Pred, cont, cont_env_ptr });
     }
     catch (jmercury.runtime.Exception ex) {
-        Object T = exception.ML_call_handler_det(
-            (jmercury.runtime.TypeInfo_Struct) TypeInfo_for_T, Handler,
+        Object T = exception.ML_call_handler_det(TypeInfo_for_T, Handler,
             (univ.Univ_0) ex.exception);
         cont.call___0_0(new java.lang.Object[] { T, cont_env_ptr });
     }
@@ -1740,8 +1739,7 @@ call_handler(Handler, Exception, Result) :- Handler(Exception, Result).
         pred.call___0_0(new java.lang.Object[] { Pred, cont, cont_env_ptr });
     }
     catch (jmercury.runtime.Exception ex) {
-        Object T = exception.ML_call_handler_det(
-            (jmercury.runtime.TypeInfo_Struct) TypeInfo_for_T, Handler,
+        Object T = exception.ML_call_handler_det(TypeInfo_for_T, Handler,
             (univ.Univ_0) ex.exception);
         cont.call___0_0(new java.lang.Object[] { T, cont_env_ptr });
     }
diff --git a/library/io.m b/library/io.m
index 78c55e6..96c0546 100644
--- a/library/io.m
+++ b/library/io.m
@@ -1805,8 +1805,7 @@
 "
     static tree234.Tree234_2 ML_io_stream_db =
         new tree234.Tree234_2.Empty_0();
-    static java.lang.Object ML_io_user_globals =
-        new tree234.Tree234_2.Empty_0();
+    static univ.Univ_0 ML_io_user_globals = null;
 ").
 
 :- type io.stream_putback ==  map(io.stream_id, list(char)).
@@ -2347,7 +2346,7 @@ io.read_file_as_string(Result, !IO) :-
     io.MR_TextInputFile File;
     StringBuilder sb;
 
-    File = (io.MR_TextInputFile) ((io.Input_stream_0) InputStream).F1;
+    File = (io.MR_TextInputFile) InputStream.F1;
     sb = new StringBuilder();
 
     try {
@@ -3393,11 +3392,11 @@ io.check_file_accessibility(FileName, AccessTypes, Result, !IO) :-
 "
     java.lang.String permissions = null;
 
-    if (ML_access_types_includes_read((list.List_1) AccessTypes)) {
+    if (ML_access_types_includes_read(AccessTypes)) {
         permissions = ""read"";
     }
 
-    if (ML_access_types_includes_write((list.List_1) AccessTypes)) {
+    if (ML_access_types_includes_write(AccessTypes)) {
         if (permissions == null) {
             permissions = ""write"";
         } else {
@@ -3405,7 +3404,7 @@ io.check_file_accessibility(FileName, AccessTypes, Result, !IO) :-
         }
     }
 
-    if (ML_access_types_includes_execute((list.List_1) AccessTypes))
+    if (ML_access_types_includes_execute(AccessTypes))
     {
         if (permissions == null) {
             permissions = ""execute"";
@@ -5093,7 +5092,7 @@ io.unlock_stream_db(!IO).
     io.set_stream_db(StreamDb::in, _IO0::di, _IO::uo),
     [will_not_call_mercury, promise_pure, tabled_for_io],
 "
-    io.ML_io_stream_db = (tree234.Tree234_2) StreamDb;
+    io.ML_io_stream_db = StreamDb;
 ").
 
 % XXX the following Erlang implementation doesn't work with multiple threads
diff --git a/library/list.m b/library/list.m
index 4ffd307..9f111be 100644
--- a/library/list.m
+++ b/library/list.m
@@ -2820,7 +2820,7 @@ public static List_1 det_tail(List_1 lst)
 */
 
 public static class ListIterator<E>
-    implements java.lang.Iterable, java.util.Iterator<E>
+    implements java.lang.Iterable<E>, java.util.Iterator<E>
 {
     private List_1 lst;
 
diff --git a/library/rtti_implementation.m b/library/rtti_implementation.m
index 96bd622..437a59b 100644
--- a/library/rtti_implementation.m
+++ b/library/rtti_implementation.m
@@ -805,48 +805,42 @@ result_call_9(_::in, (=)::out, _::in, _::in, _::in, _::in, _::in,
     [will_not_call_mercury, promise_pure, thread_safe],
 "
     jmercury.runtime.MethodPtr P = (jmercury.runtime.MethodPtr) Pred;
-    Object res = P.call___0_0(new Object[] { X, Y });
-    succeeded = ((Boolean) res).booleanValue();
+    succeeded = (Boolean) P.call___0_0(new Object[] { X, Y });
 ").
 :- pragma foreign_proc("Java",
     semidet_call_4(Pred::in, A::in, X::in, Y::in),
     [will_not_call_mercury, promise_pure, thread_safe],
 "
     jmercury.runtime.MethodPtr P = (jmercury.runtime.MethodPtr) Pred;
-    Object res = P.call___0_0(new Object[] { A, X, Y });
-    succeeded = ((Boolean) res).booleanValue();
+    succeeded = (Boolean) P.call___0_0(new Object[] { A, X, Y });
 ").
 :- pragma foreign_proc("Java",
     semidet_call_5(Pred::in, A::in, B::in, X::in, Y::in),
     [will_not_call_mercury, promise_pure, thread_safe],
 "
     jmercury.runtime.MethodPtr P = (jmercury.runtime.MethodPtr) Pred;
-    Object res = P.call___0_0(new Object[] { A, B, X, Y });
-    succeeded = ((Boolean) res).booleanValue();
+    succeeded = (Boolean) P.call___0_0(new Object[] { A, B, X, Y });
 ").
 :- pragma foreign_proc("Java",
     semidet_call_6(Pred::in, A::in, B::in, C::in, X::in, Y::in),
     [will_not_call_mercury, promise_pure, thread_safe],
 "
     jmercury.runtime.MethodPtr P = (jmercury.runtime.MethodPtr) Pred;
-    Object res = P.call___0_0(new Object[] { A, B, C, X, Y });
-    succeeded = ((Boolean) res).booleanValue();
+    succeeded = (Boolean) P.call___0_0(new Object[] { A, B, C, X, Y });
 ").
 :- pragma foreign_proc("Java",
     semidet_call_7(Pred::in, A::in, B::in, C::in, D::in, X::in, Y::in),
     [will_not_call_mercury, promise_pure, thread_safe],
 "
     jmercury.runtime.MethodPtr P = (jmercury.runtime.MethodPtr) Pred;
-    Object res = P.call___0_0(new Object[] { A, B, C, D, X, Y });
-    succeeded = ((Boolean) res).booleanValue();
+    succeeded = (Boolean) P.call___0_0(new Object[] { A, B, C, D, X, Y });
 ").
 :- pragma foreign_proc("Java",
     semidet_call_8(Pred::in, A::in, B::in, C::in, D::in, E::in, X::in, Y::in),
     [will_not_call_mercury, promise_pure, thread_safe],
 "
     jmercury.runtime.MethodPtr P = (jmercury.runtime.MethodPtr) Pred;
-    Object res = P.call___0_0(new Object[] { A, B, C, D, E, X, Y });
-    succeeded = ((Boolean) res).booleanValue();
+    succeeded = (Boolean) P.call___0_0(new Object[] { A, B, C, D, E, X, Y });
 ").
 
 :- pragma foreign_proc("Java",
@@ -854,7 +848,8 @@ result_call_9(_::in, (=)::out, _::in, _::in, _::in, _::in, _::in,
     [will_not_call_mercury, promise_pure, thread_safe],
 "
     jmercury.runtime.MethodPtr P = (jmercury.runtime.MethodPtr) Pred;
-    Res = P.call___0_0(new Object[] { X, Y });
+    Res = (builtin.Comparison_result_0)
+        P.call___0_0(new Object[] { X, Y });
 ").
 
 :- pragma foreign_proc("Java",
@@ -862,28 +857,32 @@ result_call_9(_::in, (=)::out, _::in, _::in, _::in, _::in, _::in,
     [will_not_call_mercury, promise_pure, thread_safe],
 "
     jmercury.runtime.MethodPtr P = (jmercury.runtime.MethodPtr) Pred;
-    Res = P.call___0_0(new Object[] { A, X, Y });
+    Res = (builtin.Comparison_result_0)
+        P.call___0_0(new Object[] { A, X, Y });
 ").
 :- pragma foreign_proc("Java",
     result_call_6(Pred::in, Res::out, A::in, B::in, X::in, Y::in),
     [will_not_call_mercury, promise_pure, thread_safe],
 "
     jmercury.runtime.MethodPtr P = (jmercury.runtime.MethodPtr) Pred;
-    Res = P.call___0_0(new Object[] { A, B, X, Y });
+    Res = (builtin.Comparison_result_0)
+        P.call___0_0(new Object[] { A, B, X, Y });
 ").
 :- pragma foreign_proc("Java",
     result_call_7(Pred::in, Res::out, A::in, B::in, C::in, X::in, Y::in),
     [will_not_call_mercury, promise_pure, thread_safe],
 "
     jmercury.runtime.MethodPtr P = (jmercury.runtime.MethodPtr) Pred;
-    Res = P.call___0_0(new Object[] { A, B, C, X, Y });
+    Res = (builtin.Comparison_result_0)
+        P.call___0_0(new Object[] { A, B, C, X, Y });
 ").
 :- pragma foreign_proc("Java",
     result_call_8(Pred::in, Res::out, A::in, B::in, C::in, D::in, X::in, Y::in),
     [will_not_call_mercury, promise_pure, thread_safe],
 "
     jmercury.runtime.MethodPtr P = (jmercury.runtime.MethodPtr) Pred;
-    Res = P.call___0_0(new Object[] { A, B, C, D, X, Y });
+    Res = (builtin.Comparison_result_0)
+        P.call___0_0(new Object[] { A, B, C, D, X, Y });
 ").
 :- pragma foreign_proc("Java",
     result_call_9(Pred::in, Res::out, A::in, B::in, C::in, D::in, E::in,
@@ -891,7 +890,8 @@ result_call_9(_::in, (=)::out, _::in, _::in, _::in, _::in, _::in,
     [will_not_call_mercury, promise_pure, thread_safe],
 "
     jmercury.runtime.MethodPtr P = (jmercury.runtime.MethodPtr) Pred;
-    Res = P.call___0_0(new Object[] { A, B, C, D, E, X, Y });
+    Res = (builtin.Comparison_result_0)
+        P.call___0_0(new Object[] { A, B, C, D, E, X, Y });
 ").
 
 %-----------------------------------------------------------------------------%
@@ -1447,9 +1447,9 @@ iterate(Start, Max, Func) = Results :-
     construct(TypeInfo::in, FunctorNumber::in, ArgList::in) = (Term::out),
     [will_not_call_mercury, promise_pure, thread_safe, may_not_duplicate],
 "
-    Object[] rc = ML_construct(TypeInfo, FunctorNumber, (list.List_1) ArgList);
+    Object[] rc = ML_construct(TypeInfo, FunctorNumber, ArgList);
     succeeded = (Boolean) rc[0];
-    Term = rc[1];
+    Term = (univ.Univ_0) rc[1];
 ").
 
 construct(_, _, _) = _ :-
@@ -1462,7 +1462,7 @@ construct(_, _, _) = _ :-
     [will_not_call_mercury, promise_pure, thread_safe,
         may_not_duplicate],
 "
-    list.List_1 args_list = (list.List_1) Args;
+    list.List_1 args_list = Args;
     Object[] args_array = new Object[Arity];
 
     for (int i = 0; i < Arity; i++) {
@@ -1471,7 +1471,7 @@ construct(_, _, _) = _ :-
         args_list = list.det_tail(args_list);
     }
 
-    Object[] args = ML_list_to_array((list.List_1) ArgTypes, Arity);
+    Object[] args = ML_list_to_array(ArgTypes, Arity);
     TypeInfo_Struct ti = new TypeInfo_Struct();
     ti.init(builtin.builtin__type_ctor_info_tuple_0, args);
 
diff --git a/library/string.m b/library/string.m
index 8a360b8..ae36d4b 100644
--- a/library/string.m
+++ b/library/string.m
@@ -1442,7 +1442,7 @@ string.from_char_list(Chars::in, Str::uo) :-
         does_not_affect_liveness],
 "
     java.lang.StringBuilder sb = new StringBuilder();
-    Iterable<Character> iterable = new list.ListIterator((list.List_1) CharList);
+    Iterable<Character> iterable = new list.ListIterator<Character>(CharList);
     for (char c : iterable) {
         sb.append(c);
     }
@@ -1798,7 +1798,7 @@ string.append_list(Lists, string.append_list(Lists)).
 "
     java.lang.StringBuilder sb = new java.lang.StringBuilder();
 
-    Iterable<String> iterable = new list.ListIterator((list.List_1) Strs);
+    Iterable<String> iterable = new list.ListIterator<String>(Strs);
     for (String s : iterable) {
         sb.append(s);
     }
@@ -1882,7 +1882,7 @@ string.append_list(Strs::in) = (Str::uo) :-
     java.lang.StringBuilder sb = new java.lang.StringBuilder();
     boolean add_sep = false;
 
-    Iterable<String> iterable = new list.ListIterator((list.List_1) Strs);
+    Iterable<String> iterable = new list.ListIterator<String>(Strs);
     for (String s : iterable) {
         if (add_sep) {
             sb.append(Sep);
diff --git a/library/type_desc.m b/library/type_desc.m
index ab2f41d..50c2cd3 100644
--- a/library/type_desc.m
+++ b/library/type_desc.m
@@ -264,7 +264,7 @@ type_desc_to_type_info(TypeDesc, TypeInfo) :-
     type_desc_to_type_info(TypeDesc::in, TypeInfo::out),
     [will_not_call_mercury, promise_pure, thread_safe],
 "
-    TypeInfo = ((type_desc.Type_desc_0) TypeDesc).type_info();
+    TypeInfo = TypeDesc.type_info();
 ").
 
 type_info_to_type_desc(TypeInfo, TypeDesc) :-
@@ -299,7 +299,7 @@ type_ctor_desc_to_type_ctor_info(TypeCtorDesc, TypeCtorInfo) :-
     type_ctor_desc_to_type_ctor_info(TypeCtorDesc::in, TypeCtorInfo::out),
     [will_not_call_mercury, promise_pure, thread_safe],
 "
-    TypeCtorInfo = ((type_desc.Type_ctor_desc_0) TypeCtorDesc).type_ctor_info();
+    TypeCtorInfo = TypeCtorDesc.type_ctor_info();
 ").
 
 type_ctor_info_to_type_ctor_desc(TypeCtorInfo, TypeCtorDesc) :-
@@ -526,7 +526,7 @@ ground_pseudo_type_desc_to_type_desc_det(PseudoTypeDesc) = TypeDesc :-
     ground_pseudo_type_desc_to_type_desc(PseudoTypeDesc::in) = (TypeDesc::out),
     [will_not_call_mercury, promise_pure, thread_safe, will_not_modify_trail],
 "
-    Pseudo_type_desc_0 ptd = (Pseudo_type_desc_0) PseudoTypeDesc;
+    Pseudo_type_desc_0 ptd = PseudoTypeDesc;
 
     if (ptd.struct instanceof jmercury.runtime.TypeInfo_Struct) {
         TypeDesc = new Type_desc_0(
@@ -543,7 +543,7 @@ ground_pseudo_type_desc_to_type_desc_det(PseudoTypeDesc) = TypeDesc :-
         = (TypeDesc::out),
     [will_not_call_mercury, promise_pure, thread_safe, will_not_modify_trail],
 "
-    Pseudo_type_desc_0 ptd = (Pseudo_type_desc_0) PseudoTypeDesc;
+    Pseudo_type_desc_0 ptd = PseudoTypeDesc;
 
     if (ptd.struct instanceof jmercury.runtime.TypeInfo_Struct) {
         TypeDesc = new Type_desc_0(
@@ -615,7 +615,7 @@ ground_pseudo_type_desc_to_type_desc_det(PseudoTypeDesc) = TypeDesc :-
     has_type(_Arg::unused, TypeInfo::in),
     [will_not_call_mercury, thread_safe, promise_pure],
 "
-    TypeInfo_for_T = ((type_desc.Type_desc_0) TypeInfo).type_info();
+    TypeInfo_for_T = TypeInfo.type_info();
 ").
 
 :- pragma foreign_proc("Erlang",
@@ -797,15 +797,14 @@ type_ctor(TypeDesc) = TypeCtorDesc :-
     [may_call_mercury, thread_safe, promise_pure, terminates],
 "
     java.lang.Object [] result =
-        rtti_implementation.type_ctor_and_args_3_p_0(
-        ((type_desc.Type_desc_0) TypeDesc).type_info());
+        rtti_implementation.type_ctor_and_args_3_p_0(TypeDesc.type_info());
 
     TypeCtorDesc = new Type_ctor_desc_0(
         (jmercury.runtime.TypeCtorInfo_Struct) result[0]);
-    ArgTypes = result[1];
+    ArgTypes = (list.List_1) result[1];
 
     // Convert list from jmercury.runtime.TypeInfo_Struct to type_desc_0
-    list.List_1 type_list = (list.List_1) ArgTypes;
+    list.List_1 type_list = ArgTypes;
     while (type_list.data_tag == 1) {
         ((list.List_1.F_cons_2) type_list).F1 =
             new type_desc.Type_desc_0((jmercury.runtime.TypeInfo_Struct)
@@ -965,8 +964,7 @@ make_type(_TypeCtorDesc::out, _ArgTypes::out) = (_TypeDesc::in) :-
     [will_not_call_mercury, thread_safe, promise_pure],
 "
     Object[] result = rtti_implementation.
-        type_ctor_name_and_arity_4_p_0(
-            ((Type_ctor_desc_0) TypeCtorDesc).type_ctor_info());
+        type_ctor_name_and_arity_4_p_0(TypeCtorDesc.type_ctor_info());
 
     TypeCtorModuleName = (java.lang.String) result[0];
     TypeCtorName = (java.lang.String) result[1];

--------------------------------------------------------------------------
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