[m-rev.] for post-commit review: erlang rtti improvements

Peter Wang novalazy at gmail.com
Fri Aug 31 11:07:19 AEST 2007


Estimated hours taken: 10
Branches: main

Improvements to the Erlang backend RTTI implementation.

- Remember the lexical order of discriminated union functors, and use that
  for functor numbers, as in the C backends.

- Change the representation of type_ctor_descs, which are now different from
  the representation of type_ctor_infos in the case of variable arity types
  (higher order types and tuples).  This is necessary so we can get the arity
  from a variable arity type_ctor_desc.

- Implement some related procedures:

	construct.get_functor_ordinal
	construct.get_functor_lex
	deconstruct.functor_number
	deconstruct.functor_number_cc


compiler/erl_rtti.m:
compiler/erlang_rtti.m:
	For d.u. functors, output the functor number (based on lexicographic
	order) as well in the RTTI data.

library/erlang_rtti_implementation.m:
	Implement the functor numbering and type_ctor_desc changes.

	Rename some procedures to distinguish between type_ctor_infos and
	type_ctor_descs.

	Fix some minor bugs.

library/construct.m:
	Make get_functor_ordinal, get_functor_lex call the corresponding
	procedures in erlang_rtti_implementation.

library/deconstruct.m:
	Make deconstruct_du, functor_number, functor_number_cc
	call the corresponding procedures in erlang_rtti_implementation.

library/type_desc.m:
	Make type_ctor, type_ctor_and_args, make_type,
	type_ctor_name_and_arity call the corresponding procedures in
	erlang_rtti_implementation.

	Fix the comparisons of type_ctor_descs which were not updated when the
	calling convention of single output procedures was changed.

tests/hard_coded/construct_test.exp:
tests/hard_coded/construct_test.m:
	Do additional tests on list and dummy types, which were not covered
	previously.


Index: compiler/erl_rtti.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/erl_rtti.m,v
retrieving revision 1.16
diff -u -r1.16 erl_rtti.m
--- compiler/erl_rtti.m	20 Aug 2007 03:35:53 -0000	1.16
+++ compiler/erl_rtti.m	30 Aug 2007 05:27:41 -0000
@@ -126,29 +126,37 @@
 :- func erlang_type_ctor_details_2(type_ctor_details) =
     erlang_type_ctor_details.
 
-erlang_type_ctor_details_2(enum(_, Functors, _, _, IsDummy, _)) =
+erlang_type_ctor_details_2(enum(_, Functors, _, _, IsDummy, FunctorNums))
+        = Details :-
     ( IsDummy = yes ->
         ( Functors = [F] ->
-            erlang_dummy(F ^ enum_name)
+            Details = erlang_dummy(F ^ enum_name)
         ;
             unexpected(this_file, "dummy type with more than one functor")
         )
     ;
-        erlang_du(list.map(convert_enum_functor, Functors))
+        list.map_corresponding(convert_enum_functor, Functors, FunctorNums,
+            ErlFunctors),
+        Details = erlang_du(ErlFunctors)
     ).
 erlang_type_ctor_details_2(foreign_enum(_, _, _, _, _)) =
     sorry(this_file, "NYI foreign enumerations for Erlang.").
-erlang_type_ctor_details_2(du(_, Functors, _, _, _)) =
-    erlang_du(list.map(convert_du_functor, Functors)).
+erlang_type_ctor_details_2(du(_, Functors, _, _, FunctorNums)) = Details :-
+    list.map_corresponding(convert_du_functor, Functors, FunctorNums,
+        ErlangFunctors),
+    Details = erlang_du(ErlangFunctors).
 erlang_type_ctor_details_2(reserved(_, _, _, _, _, _)) =
         % Reserved types are not supported on the Erlang backend.
     unexpected(this_file, "erlang_type_ctor_details: reserved").
 erlang_type_ctor_details_2(notag(_, NoTagFunctor)) = Details :-
     NoTagFunctor = notag_functor(Name, TypeInfo, ArgName),
+    OrigArity = 1,
+    Ordinal = 0,
+    FunctorNum = 0,
     ArgTypeInfo = convert_to_rtti_maybe_pseudo_type_info_or_self(TypeInfo),
     ArgInfos = [du_arg_info(ArgName, ArgTypeInfo)],
-    DUFunctor =
-        erlang_du_functor(Name, 1, 1, erlang_atom_raw(Name), ArgInfos, no),
+    DUFunctor = erlang_du_functor(Name, OrigArity, Ordinal, FunctorNum,
+        erlang_atom_raw(Name), ArgInfos, no),
     Details = erlang_du([DUFunctor]).
 erlang_type_ctor_details_2(eqv(Type)) = erlang_eqv(Type).
 erlang_type_ctor_details_2(builtin(Builtin)) = erlang_builtin(Builtin).
@@ -159,19 +167,24 @@
     %
     % Convert an enum_functor into the equivalent erlang_du_functor
     %
-:- func convert_enum_functor(enum_functor) = erlang_du_functor.
+:- pred convert_enum_functor(enum_functor::in, int::in, erlang_du_functor::out)
+    is det.
 
-convert_enum_functor(enum_functor(Name, Ordinal)) =
-    erlang_du_functor(Name, 0, Ordinal, erlang_atom_raw(Name), [], no).
+convert_enum_functor(EnumFunctor, FunctorNum, ErlangFunctor) :-
+    EnumFunctor = enum_functor(Name, Ordinal),
+    ErlangFunctor = erlang_du_functor(Name, 0, Ordinal, FunctorNum,
+        erlang_atom_raw(Name), [], no).
 
     %
     % Convert a du_functor into the equivalent erlang_du_functor
     %
-:- func convert_du_functor(du_functor) = erlang_du_functor.
+:- pred convert_du_functor(du_functor::in, int::in, erlang_du_functor::out)
+    is det.
 
-convert_du_functor(du_functor(Name, Arity, Ordinal, _, ArgInfos, Exist)) =
-    erlang_du_functor(Name, Arity,
-        Ordinal, erlang_atom_raw(Name), ArgInfos, Exist).
+convert_du_functor(Functor, FunctorNum, ErlangFunctor) :-
+    Functor = du_functor(Name, Arity, Ordinal, _, ArgInfos, Exist),
+    ErlangFunctor = erlang_du_functor(Name, Arity, Ordinal, FunctorNum,
+        erlang_atom_raw(Name), ArgInfos, Exist).
 
 :- func convert_to_rtti_maybe_pseudo_type_info_or_self(
     rtti_maybe_pseudo_type_info) = rtti_maybe_pseudo_type_info_or_self.
Index: compiler/erlang_rtti.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/erlang_rtti.m,v
retrieving revision 1.5
diff -u -r1.5 erlang_rtti.m
--- compiler/erlang_rtti.m	7 Jun 2007 07:53:05 -0000	1.5
+++ compiler/erlang_rtti.m	30 Aug 2007 05:27:44 -0000
@@ -113,6 +113,9 @@
                     % The declaration order of the functor.
                 edu_ordinal         :: int,
 
+                    % The lexicographic order of the functor.
+                edu_lex             :: int,
+
                     % erlang atom which represents the functor
                     % currently encoded version of name
                     % in the future maybe name_arity
Index: library/construct.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/library/construct.m,v
retrieving revision 1.37
diff -u -r1.37 construct.m
--- library/construct.m	20 Aug 2007 03:36:16 -0000	1.37
+++ library/construct.m	30 Aug 2007 05:27:44 -0000
@@ -361,6 +361,14 @@
 get_functor_ordinal(TypeDesc, FunctorNumber) = Ordinal :-
     get_functor_ordinal(TypeDesc, FunctorNumber, Ordinal).
 
+get_functor_ordinal(TypeDesc, FunctorNumber, Ordinal) :-
+    ( erlang_rtti_implementation.is_erlang_backend ->
+        erlang_rtti_implementation.get_functor_ordinal(TypeDesc, FunctorNumber,
+            Ordinal)
+    ;
+        private_builtin.sorry("get_functor_ordinal/3")
+    ).
+
 :- pragma foreign_proc("C",
     get_functor_ordinal(TypeDesc::in, FunctorNumber::in, Ordinal::out),
     [will_not_call_mercury, thread_safe, promise_pure],
@@ -453,6 +461,14 @@
     SUCCESS_INDICATOR = success;
 }").
 
+get_functor_lex(TypeDesc, Ordinal) = FunctorNumber :-
+    ( erlang_rtti_implementation.is_erlang_backend ->
+        erlang_rtti_implementation.get_functor_lex(TypeDesc, Ordinal,
+            FunctorNumber)
+    ;
+        private_builtin.sorry("get_functor_lex/3")
+    ).
+
 :- pragma foreign_proc("C",
     get_functor_lex(TypeDesc::in, Ordinal::in) = (FunctorNumber::out),
     [will_not_call_mercury, thread_safe, promise_pure],
Index: library/deconstruct.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/library/deconstruct.m,v
retrieving revision 1.46
diff -u -r1.46 deconstruct.m
--- library/deconstruct.m	25 Jul 2007 03:08:50 -0000	1.46
+++ library/deconstruct.m	30 Aug 2007 05:27:44 -0000
@@ -432,6 +432,21 @@
     ).
 
 deconstruct_du(Term, NonCanon, FunctorNumber, Arity, Arguments) :-
+    ( erlang_rtti_implementation.is_erlang_backend ->
+        erlang_rtti_implementation.deconstruct(Term, NonCanon, _Functor,
+            FunctorNumber, Arity, Arguments)
+    ;
+        deconstruct_du_2(Term, NonCanon, FunctorNumber, Arity, Arguments)
+    ).
+
+:- pred deconstruct_du_2(T, noncanon_handling, functor_number_lex,
+    int, list(univ)).
+:- mode deconstruct_du_2(in, in(do_not_allow), out, out, out) is semidet.
+:- mode deconstruct_du_2(in, in(include_details_cc), out, out, out)
+    is cc_nondet.
+:- mode deconstruct_du_2(in, in, out, out, out) is cc_nondet.
+
+deconstruct_du_2(Term, NonCanon, FunctorNumber, Arity, Arguments) :-
     ( _ = construct.num_functors(type_of(Term)) ->
         (
             NonCanon = do_not_allow,
@@ -581,10 +596,21 @@
 SUCCESS_INDICATOR = (FunctorNumber >= 0);
 }").
 
-functor_number(_Term::in, _FunctorNumber::out, _Arity::out) :-
-    private_builtin.sorry("deconstruct.functor_number").
-functor_number_cc(_Term::in, _FunctorNumber::out, _Arity::out) :-
-    private_builtin.sorry("deconstruct.functor_number_cc").
+functor_number(Term::in, FunctorNumber::out, Arity::out) :-
+    ( erlang_rtti_implementation.is_erlang_backend ->
+        erlang_rtti_implementation.deconstruct(Term, do_not_allow,
+            _Functor, FunctorNumber, Arity, _Args)
+    ;
+        private_builtin.sorry("deconstruct.functor_number")
+    ).
+
+functor_number_cc(Term::in, FunctorNumber::out, Arity::out) :-
+    ( erlang_rtti_implementation.is_erlang_backend ->
+        erlang_rtti_implementation.deconstruct(Term, include_details_cc,
+            _Functor, FunctorNumber, Arity, _Args)
+    ;
+        private_builtin.sorry("deconstruct.functor_number_cc")
+    ).
 
 %-----------------------------------------------------------------------------%
 
@@ -1017,7 +1043,7 @@
 
 local_deconstruct(T, H, F, A, As) :-
     ( erlang_rtti_implementation.is_erlang_backend ->
-        erlang_rtti_implementation.deconstruct(T, H, F, A, As)
+        erlang_rtti_implementation.deconstruct(T, H, F, _FN, A, As)
     ;
         rtti_implementation.deconstruct(T, H, F, A, As)
     ).
Index: library/erlang_rtti_implementation.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/library/erlang_rtti_implementation.m,v
retrieving revision 1.16
diff -u -r1.16 erlang_rtti_implementation.m
--- library/erlang_rtti_implementation.m	24 Aug 2007 07:56:27 -0000	1.16
+++ library/erlang_rtti_implementation.m	30 Aug 2007 05:27:44 -0000
@@ -7,7 +7,7 @@
 %-----------------------------------------------------------------------------%
 %
 % File: erlang_rtti_implementation.m.
-% Main author: petdr.
+% Main author: petdr, wangp.
 % Stability: low.
 %
 % This file is intended to provide the RTTI implementation for the Erlang
@@ -42,17 +42,26 @@
 :- pred compare_type_infos(comparison_result::out,
     type_info::in, type_info::in) is det.
 
-:- pred type_ctor_and_args(type_info::in, type_ctor_info_evaled::out,
+:- pred type_ctor_info_and_args(type_info::in, type_ctor_info_evaled::out,
     list(type_info)::out) is det.
 
-:- pred type_ctor_name_and_arity(type_ctor_info_evaled::in,
+:- pred type_ctor_desc(type_desc::in, type_ctor_desc::out) is det.
+
+:- pred type_ctor_desc_and_args(type_desc::in, type_ctor_desc::out,
+    list(type_desc)::out) is det.
+
+:- pred make_type_desc(type_ctor_desc::in, list(type_desc)::in,
+    type_desc::out) is semidet.
+
+:- pred type_ctor_desc_name_and_arity(type_ctor_desc::in,
     string::out, string::out, int::out) is det.
 
-:- pred deconstruct(T, noncanon_handling, string, int, list(univ)).
-:- mode deconstruct(in, in(do_not_allow), out, out, out) is det.
-:- mode deconstruct(in, in(canonicalize), out, out, out) is det.
-:- mode deconstruct(in, in(include_details_cc), out, out, out) is cc_multi.
-:- mode deconstruct(in, in, out, out, out) is cc_multi.
+:- pred deconstruct(T, noncanon_handling, string, int, int, list(univ)).
+:- mode deconstruct(in, in(do_not_allow), out, out, out, out) is det.
+:- mode deconstruct(in, in(canonicalize), out, out, out, out) is det.
+:- mode deconstruct(in, in(include_details_cc), out, out, out, out)
+    is cc_multi.
+:- mode deconstruct(in, in, out, out, out, out) is cc_multi.
 
 %-----------------------------------------------------------------------------%
 %
@@ -67,6 +76,12 @@
     int::out, list(type_desc.type_desc)::out, list(string)::out)
     is semidet.
 
+:- pred get_functor_ordinal(type_desc.type_desc::in, int::in, int::out)
+    is semidet.
+
+:- pred get_functor_lex(type_desc.type_desc::in, int::in, int::out)
+    is semidet.
+
 %-----------------------------------------------------------------------------%
 %-----------------------------------------------------------------------------%
 
@@ -144,6 +159,18 @@
     ;       etcr_ticket
     .
 
+    % Values of type `type_desc' are represented the same way as values of
+    % type `type_info'.
+    %
+    % Values of type `type_ctor_desc' are NOT represented the same way as
+    % values of type `type_ctor_info'.  The representations *are* in fact
+    % identical for fixed arity types, but they differ for higher order and
+    % tuple types. In that case they are one of the following:
+    %
+    %   {pred, Arity},
+    %   {func, Arity},
+    %   {tuple, Arity}
+
 %-----------------------------------------------------------------------------%
 %-----------------------------------------------------------------------------%
 
@@ -318,18 +345,15 @@
 %-----------------------------------------------------------------------------%
 %-----------------------------------------------------------------------------%
 
-type_ctor_and_args(TypeInfo0, TypeCtorInfo, Args) :-
+type_ctor_info_and_args(TypeInfo0, TypeCtorInfo, Args) :-
     TypeInfo = collapse_equivalences(TypeInfo0),
     TypeCtorInfo = TypeInfo ^ type_ctor_info_evaled,
     ( type_ctor_is_variable_arity(TypeCtorInfo) ->
-        Arity = TypeInfo ^ var_arity_type_info_arity,
-        Args = list.map(
-            func(L) = TypeInfo ^ var_arity_type_info_index(L), 1 .. Arity)
+        Args = get_var_arity_arg_type_infos(TypeInfo)
     ;
-        Arity = TypeCtorInfo ^ type_ctor_arity,
-        Args = list.map(func(L) = TypeInfo ^ type_info_index(L), 1 .. Arity)
+        Args = get_fixed_arity_arg_type_infos(TypeInfo)
     ).
-    
+
 :- pred type_ctor_is_variable_arity(type_ctor_info_evaled::in) is semidet.
 
 type_ctor_is_variable_arity(TypeCtorInfo) :-
@@ -339,11 +363,203 @@
     ; TypeCtorRep = etcr_func
     ).
 
+%-----------------------------------------------------------------------------%
+%-----------------------------------------------------------------------------%
+
+type_ctor_desc(TypeDesc, TypeCtorDesc) :-
+    type_ctor_desc_and_args(TypeDesc, TypeCtorDesc, _Args).
+
+type_ctor_desc_and_args(TypeDesc, TypeCtorDesc, ArgsDescs) :-
+    TypeInfo0 = type_info_from_type_desc(TypeDesc),
+    TypeInfo = collapse_equivalences(TypeInfo0),
+    TypeCtorInfo = TypeInfo ^ type_ctor_info_evaled,
+    TypeCtorRep = TypeCtorInfo ^ type_ctor_rep,
+    % Handle variable arity types.
+    ( TypeCtorRep = etcr_pred ->
+        Arity = TypeInfo ^ var_arity_type_info_arity,
+        TypeCtorDesc = make_pred_type_ctor_desc(Arity),
+        ArgInfos = get_var_arity_arg_type_infos(TypeInfo)
+
+    ; TypeCtorRep = etcr_func ->
+        Arity = TypeInfo ^ var_arity_type_info_arity,
+        TypeCtorDesc = make_func_type_ctor_desc(Arity),
+        ArgInfos = get_var_arity_arg_type_infos(TypeInfo)
+
+    ; TypeCtorRep = etcr_tuple ->
+        Arity = TypeInfo ^ var_arity_type_info_arity,
+        TypeCtorDesc = make_tuple_type_ctor_desc(Arity),
+        ArgInfos = get_var_arity_arg_type_infos(TypeInfo)
+    ;
+        % Handle fixed arity types.
+        TypeCtorDesc = make_fixed_arity_type_ctor_desc(TypeCtorInfo),
+        ArgInfos = get_fixed_arity_arg_type_infos(TypeInfo)
+    ),
+    ArgsDescs = type_descs_from_type_infos(ArgInfos).
+
+:- func make_pred_type_ctor_desc(int) = type_ctor_desc.
+
+:- pragma foreign_proc("Erlang",
+    make_pred_type_ctor_desc(Arity::in) = (TypeCtorDesc::out),
+    [will_not_call_mercury, promise_pure, thread_safe],
+"
+    TypeCtorDesc = {pred, Arity}
+").
+
+make_pred_type_ctor_desc(_) = _ :-
+    private_builtin.sorry("make_pred_type_ctor_desc").
+
+:- func make_func_type_ctor_desc(int) = type_ctor_desc.
+
+:- pragma foreign_proc("Erlang",
+    make_func_type_ctor_desc(Arity::in) = (TypeCtorDesc::out),
+    [will_not_call_mercury, promise_pure, thread_safe],
+"
+    TypeCtorDesc = {func, Arity}
+").
+
+make_func_type_ctor_desc(_) = _ :-
+    private_builtin.sorry("make_func_type_ctor_desc").
+
+:- func make_tuple_type_ctor_desc(int) = type_ctor_desc.
+
+:- pragma foreign_proc("Erlang",
+    make_tuple_type_ctor_desc(Arity::in) = (TypeCtorDesc::out),
+    [will_not_call_mercury, promise_pure, thread_safe],
+"
+    TypeCtorDesc = {tuple, Arity}
+").
+
+make_tuple_type_ctor_desc(_) = _ :-
+    private_builtin.sorry("make_tuple_type_ctor_desc").
+
+:- func make_fixed_arity_type_ctor_desc(type_ctor_info_evaled)
+    = type_ctor_desc.
+
+make_fixed_arity_type_ctor_desc(TypeCtorInfo) = TypeCtorDesc :-
+    % Fixed arity types have the same representations.
+    TypeCtorDesc = unsafe_cast(TypeCtorInfo).
+
+:- func type_info_from_type_desc(type_desc) = type_info.
+
+type_info_from_type_desc(TypeDesc) = TypeInfo :-
+    % They have the same representation.
+    TypeInfo = unsafe_cast(TypeDesc).
+
+:- func type_descs_from_type_infos(list(type_info)) = list(type_desc).
+
+type_descs_from_type_infos(TypeInfos) = TypeDescs :-
+    % They have the same representation.
+    TypeDescs = unsafe_cast(TypeInfos).
 
 %-----------------------------------------------------------------------------%
 %-----------------------------------------------------------------------------%
 
-type_ctor_name_and_arity(TypeCtorInfo, ModuleName, Name, Arity) :-
+:- pragma foreign_proc("Erlang",
+    make_type_desc(TypeCtorDesc::in, ArgTypeDescs::in, TypeDesc::out),
+    [will_not_call_mercury, promise_pure, thread_safe],
+"
+    MakeVarArityTypeDesc =
+        (fun(TypeCtorInfo, Arity, ArgTypeInfos) ->
+            case Arity =:= length(ArgTypeInfos) of
+                true ->
+                    TypeInfo = 
+                        list_to_tuple([TypeCtorInfo, Arity | ArgTypeDescs]),
+                    {true, TypeInfo};
+                false ->
+                    {false, null}
+            end
+        end),
+
+    case TypeCtorDesc of
+        % Handle the variable arity types.
+        {pred, Arity} ->
+            TCI = fun mercury__builtin:builtin__type_ctor_info_pred_0/0,
+            {SUCCESS_INDICATOR, TypeDesc} = MakeVarArityTypeDesc(TCI, Arity,
+                ArgTypeDescs);
+
+        {func, Arity} ->
+            TCI = fun mercury__builtin:builtin__type_ctor_info_func_0/0,
+            {SUCCESS_INDICATOR, TypeDesc} = MakeVarArityTypeDesc(TCI, Arity,
+                ArgTypeDescs);
+
+        {tuple, Arity} ->
+            TCI = fun mercury__builtin:builtin__type_ctor_info_tuple_0/0,
+            {SUCCESS_INDICATOR, TypeDesc} = MakeVarArityTypeDesc(TCI, Arity,
+                ArgTypeDescs);
+
+        % Handle fixed arity types.
+        TypeCtorInfo ->
+            ArgTypeInfos = ArgTypeDescs,
+            case
+                mercury__erlang_rtti_implementation:
+                    'ML_make_fixed_arity_type_info'(TypeCtorInfo, ArgTypeInfos)
+            of
+                {TypeInfo} ->
+                    SUCCESS_INDICATOR = true,
+                    % type_desc and type_info have same representation.
+                    TypeDesc = TypeInfo;
+                fail ->
+                    SUCCESS_INDICATOR = false,
+                    TypeDesc = null
+            end
+    end
+").
+
+make_type_desc(_, _, _) :-
+    private_builtin.sorry("make_type_desc/3").
+
+:- pred make_fixed_arity_type_info(type_ctor_info_evaled::in,
+    list(type_info)::in, type_info::out) is semidet.
+
+:- pragma foreign_export("Erlang", make_fixed_arity_type_info(in, in, out),
+    "ML_make_fixed_arity_type_info").
+
+make_fixed_arity_type_info(TypeCtorInfo, ArgTypeInfos, TypeInfo) :-
+    TypeCtorInfo ^ type_ctor_arity = list.length(ArgTypeInfos),
+    TypeInfo = create_type_info(TypeCtorInfo, ArgTypeInfos).
+
+%-----------------------------------------------------------------------------%
+%-----------------------------------------------------------------------------%
+
+:- pragma foreign_proc("Erlang",
+    type_ctor_desc_name_and_arity(TypeCtorDesc::in, ModuleName::out, Name::out,
+        Arity::out),
+    [will_not_call_mercury, promise_pure, thread_safe],
+"
+    case TypeCtorDesc of
+        {pred, Arity} ->
+            ModuleName = <<""builtin"">>,
+            Name = <<""pred"">>,
+            Arity = Arity;
+
+        {func, Arity} ->
+            ModuleName = <<""builtin"">>,
+            Name = <<""func"">>,
+            Arity = Arity;
+
+        {tuple, Arity} ->
+            ModuleName = <<""builtin"">>,
+            Name = <<""{}"">>,
+            Arity = Arity;
+
+        TypeCtorInfo ->
+            {ModuleName, Name, Arity} =
+                mercury__erlang_rtti_implementation:
+                    'ML_type_ctor_info_name_and_arity'(TypeCtorInfo)
+    end
+").
+
+type_ctor_desc_name_and_arity(_, _, _, _) :-
+    private_builtin.sorry("type_ctor_desc_name_and_arity/4").
+
+:- pred type_ctor_info_name_and_arity(type_ctor_info_evaled::in,
+    string::out, string::out, int::out) is det.
+
+:- pragma foreign_export("Erlang",
+    type_ctor_info_name_and_arity(in, out, out, out),
+    "ML_type_ctor_info_name_and_arity").
+
+type_ctor_info_name_and_arity(TypeCtorInfo, ModuleName, Name, Arity) :-
     ModuleName = TypeCtorInfo ^ type_ctor_module_name,
     Name = TypeCtorInfo ^ type_ctor_type_name,
     Arity = TypeCtorInfo ^ type_ctor_arity.
@@ -351,27 +567,29 @@
 %-----------------------------------------------------------------------------%
 %-----------------------------------------------------------------------------%
 
-deconstruct(Term, NonCanon, Functor, Arity, Arguments) :-
+deconstruct(Term, NonCanon, Functor, FunctorNumber, Arity, Arguments) :-
     TypeInfo = Term ^ type_info,
     TypeCtorInfo = TypeInfo ^ type_ctor_info_evaled,
     TypeCtorRep = TypeCtorInfo ^ type_ctor_rep,
     deconstruct_2(Term, TypeInfo, TypeCtorInfo, TypeCtorRep, NonCanon,
-        Functor, Arity, Arguments).
+        Functor, FunctorNumber, Arity, Arguments).
 
 :- pred deconstruct_2(T, type_info, type_ctor_info_evaled,
-    erlang_type_ctor_rep, noncanon_handling, string, int, list(univ)).
-:- mode deconstruct_2(in, in, in, in, in(do_not_allow), out, out, out) is det.
-:- mode deconstruct_2(in, in, in, in, in(canonicalize), out, out, out) is det.
+    erlang_type_ctor_rep, noncanon_handling, string, int, int, list(univ)).
+:- mode deconstruct_2(in, in, in, in, in(do_not_allow), out, out, out, out)
+    is det.
+:- mode deconstruct_2(in, in, in, in, in(canonicalize), out, out, out, out)
+    is det.
 :- mode deconstruct_2(in, in, in, in,
-    in(include_details_cc), out, out, out) is cc_multi.
-:- mode deconstruct_2(in, in, in, in, in, out, out, out) is cc_multi.
+    in(include_details_cc), out, out, out, out) is cc_multi.
+:- mode deconstruct_2(in, in, in, in, in, out, out, out, out) is cc_multi.
 
 deconstruct_2(Term, TypeInfo, TypeCtorInfo, TypeCtorRep, NonCanon,
-        Functor, Arity, Arguments) :-
+        Functor, FunctorNumber, Arity, Arguments) :-
     (
         TypeCtorRep = etcr_du,
         FunctorReps = TypeCtorInfo ^ type_ctor_functors,
-        FunctorRep = matching_du_functor(FunctorReps, Term),
+        matching_du_functor(FunctorReps, 0, Term, FunctorRep, FunctorNumber),
         Functor = string.from_char_list(FunctorRep ^ edu_name),
         Arity = FunctorRep ^ edu_orig_arity,
         Arguments = list.map(
@@ -379,6 +597,7 @@
     ;
         TypeCtorRep = etcr_dummy,
         Functor = TypeCtorInfo ^ type_ctor_dummy_functor_name,
+        FunctorNumber = 0,
         Arity = 0,
         Arguments = []
     ;
@@ -386,10 +605,12 @@
         ArgTypeInfo = TypeInfo ^ type_info_index(1),
         ( is_non_empty_list(TypeInfo, ArgTypeInfo, Term, H, T) ->
             Functor = "[|]",
+            FunctorNumber = 1,
             Arity = 2,
             Arguments = [univ(H), univ(T)]
         ;
             Functor = "[]",
+            FunctorNumber = 0,
             Arity = 0,
             Arguments = []
         )
@@ -408,6 +629,7 @@
         det_dynamic_cast(Term, Array),
 
         Functor = "<<array>>",
+        FunctorNumber = 0,
         Arity = array.size(Array),
         Arguments = array.foldr(
             (func(Elem, List) = [univ(Elem) | List]),
@@ -418,34 +640,39 @@
         EqvTypeCtorInfo = EqvTypeInfo ^ type_ctor_info_evaled,
         EqvTypeCtorRep = EqvTypeCtorInfo ^ type_ctor_rep,
         deconstruct_2(Term, EqvTypeInfo, EqvTypeCtorInfo, EqvTypeCtorRep,
-            NonCanon, Functor, Arity, Arguments)
+            NonCanon, Functor, FunctorNumber, Arity, Arguments)
     ;
         TypeCtorRep = etcr_tuple,
         Arity = TypeInfo ^ var_arity_type_info_arity,
         Functor = "{}",
+        FunctorNumber = 0,
         Arguments = list.map(get_tuple_arg(TypeInfo, Term), 1 .. Arity)
     ;
         TypeCtorRep = etcr_int,
         det_dynamic_cast(Term, Int),
         Functor = string.int_to_string(Int),
+        FunctorNumber = 0,
         Arity = 0,
         Arguments = []
     ;
         TypeCtorRep = etcr_float,
         det_dynamic_cast(Term, Float),
         Functor = float_to_string(Float),
+        FunctorNumber = 0,
         Arity = 0,
         Arguments = []
     ;
         TypeCtorRep = etcr_char,
         det_dynamic_cast(Term, Char),
         Functor = term_io.quoted_char(Char),
+        FunctorNumber = 0,
         Arity = 0,
         Arguments = []
     ;
         TypeCtorRep = etcr_string,
         det_dynamic_cast(Term, String),
         Functor = term_io.quoted_string(String),
+        FunctorNumber = 0,
         Arity = 0,
         Arguments = []
     ;
@@ -457,12 +684,14 @@
         TypeCtorRep = etcr_stable_c_pointer,
         det_dynamic_cast(Term, CPtr),
         Functor = "stable_" ++ string.c_pointer_to_string(CPtr),
+        FunctorNumber = 0,
         Arity = 0,
         Arguments = []
     ;
         TypeCtorRep = etcr_c_pointer,
         det_dynamic_cast(Term, CPtr),
         Functor = string.c_pointer_to_string(CPtr),
+        FunctorNumber = 0,
         Arity = 0,
         Arguments = []
     ;
@@ -493,18 +722,21 @@
         ;
             NonCanon = canonicalize,
             Functor = Name,
+            FunctorNumber = 0,
             Arity = 0,
             Arguments = []
         ;
                 % XXX this needs to be fixed
             NonCanon = include_details_cc,
             Functor = Name,
+            FunctorNumber = 0,
             Arity = 0,
             Arguments = []
         )
     ;
         TypeCtorRep = etcr_foreign,
         Functor = "<<foreign>>",
+        FunctorNumber = 0,
         Arity = 0,
         Arguments = []
     ;
@@ -521,19 +753,22 @@
     ).
 
     %
-    % matching_du_functor(Functors, Term)
+    % matching_du_functor(FunctorReps, Index, Term, FunctorRep, FunctorNumber)
     %
     % finds the erlang_du_functor in the list Functors which describes
     % the given Term.
     %
-:- func matching_du_functor(list(erlang_du_functor), T) = erlang_du_functor.
+:- pred matching_du_functor(list(erlang_du_functor)::in, int::in, T::in,
+    erlang_du_functor::out, int::out) is det.
 
-matching_du_functor([], _) = func_error(this_file ++ " matching_du_functor/2").
-matching_du_functor([F | Fs], T) =
+matching_du_functor([], _, _, _, _) :-
+    error(this_file ++ " matching_du_functor/2").
+matching_du_functor([F | Fs], Index, T, Functor, FunctorNumber) :-
     ( matches_du_functor(T, F) ->
-        F
+        Functor = F,
+        FunctorNumber = Index
     ;
-        matching_du_functor(Fs, T)
+        matching_du_functor(Fs, Index + 1, T, Functor, FunctorNumber)
     ).
 
     %
@@ -685,7 +920,8 @@
 %-----------------------------------------------------------------------------%
 
 num_functors(TypeDesc) = NumFunctors :-
-    num_functors(unsafe_cast(TypeDesc), yes(NumFunctors)).
+    TypeInfo = type_info_from_type_desc(TypeDesc),
+    num_functors(TypeInfo, yes(NumFunctors)).
 
 :- pred num_functors(type_info::in, maybe(int)::out) is det.
 
@@ -740,10 +976,12 @@
 get_functor(TypeDesc, FunctorNum, Name, Arity, ArgTypes) :-
     get_functor_with_names(TypeDesc, FunctorNum, Name, Arity, ArgTypes, _).
 
-get_functor_with_names(TypeDesc, FunctorNum, Name, Arity, ArgTypes, ArgNames) :-
-    MaybeResult = get_functor_with_names(unsafe_cast(TypeDesc), FunctorNum),
+get_functor_with_names(TypeDesc, FunctorNum, Name, Arity, ArgTypeDescs,
+        ArgNames) :-
+    TypeInfo = type_info_from_type_desc(TypeDesc),
+    MaybeResult = get_functor_with_names(TypeInfo, FunctorNum),
     MaybeResult = yes({Name, Arity, ArgTypeInfos, ArgNames}),
-    ArgTypes = list.map(unsafe_cast, ArgTypeInfos).
+    ArgTypeDescs = type_descs_from_type_infos(ArgTypeInfos).
 
 :- func get_functor_with_names(type_info, int) =
     maybe({string, int, list(type_info), list(string)}).
@@ -754,7 +992,7 @@
     (
         TypeCtorRep = etcr_du,
         FunctorReps = TypeCtorInfo ^ type_ctor_functors,
-        ( list.index0(FunctorReps, NumFunctor, FunctorRep) ->
+        ( matching_du_functor_number(FunctorReps, NumFunctor, FunctorRep) ->
             MaybeExistInfo = FunctorRep ^ edu_exist_info,
             (
                 MaybeExistInfo = yes(_),
@@ -763,12 +1001,11 @@
                 MaybeExistInfo = no,
                 ArgInfos = FunctorRep ^ edu_arg_infos,
 
-                list.foldl2(
-                    (pred(ArgInfo::in, T0::in, T::out, N0::in, N::out) is det :-
+                list.map2(
+                    (pred(ArgInfo::in, ArgTypeInfo::out, ArgName::out) is det :-
                         MaybePTI = ArgInfo ^ du_arg_type,
                         Info = yes({TypeInfo, no : pti_info(int)}),
                         ArgTypeInfo = type_info(Info, MaybePTI),
-                        T = [ArgTypeInfo | T0],
                         
                         MaybeArgName = ArgInfo ^ du_arg_name,
                         (
@@ -777,14 +1014,11 @@
                         ;
                             MaybeArgName = no,
                             ArgName = ""
-                        ),
-                        N = [ArgName | N0]
-                    ), ArgInfos, [], RevArgTypes, [], RevArgNames),
+                        )
+                    ), ArgInfos, ArgTypes, ArgNames),
 
                 Name = string.from_char_list(FunctorRep ^ edu_name),
                 Arity = FunctorRep ^ edu_orig_arity,
-                ArgTypes = list.reverse(RevArgTypes),
-                ArgNames = list.reverse(RevArgNames),
                 Result = yes({Name, Arity, ArgTypes, ArgNames})
             )
         ;
@@ -799,21 +1033,21 @@
         Result = yes({Name, Arity, ArgTypes, ArgNames})
     ;
         TypeCtorRep = etcr_tuple,
-        type_ctor_and_args(TypeInfo, _TypeCtorInfo, ArgTypes),
+        type_ctor_info_and_args(TypeInfo, _TypeCtorInfo, ArgTypes),
         Name = "{}",
         Arity = list.length(ArgTypes),
         ArgNames = list.duplicate(Arity, ""),
         Result = yes({Name, Arity, ArgTypes, ArgNames})
     ;
         TypeCtorRep = etcr_list,
-        ( NumFunctor = 1 ->
+        ( NumFunctor = 0 ->
             Name = "[]",
             Arity = 0,
             ArgTypes = [],
             ArgNames = [],
             Result = yes({Name, Arity, ArgTypes, ArgNames})
 
-        ; NumFunctor = 2 ->
+        ; NumFunctor = 1 ->
             ArgTypeInfo = TypeInfo ^ type_info_index(1),
 
             Name = "[|]",
@@ -855,10 +1089,83 @@
         error("num_functors: type_ctor_rep not handled")
     ).
 
+get_functor_ordinal(TypeDesc, FunctorNum, Ordinal) :-
+    TypeInfo = type_info_from_type_desc(TypeDesc),
+    TypeCtorInfo = TypeInfo ^ type_ctor_info_evaled,
+    TypeCtorRep = TypeCtorInfo ^ type_ctor_rep,
+    (
+        TypeCtorRep = etcr_du,
+        FunctorReps = TypeCtorInfo ^ type_ctor_functors,
+        matching_du_functor_number(FunctorReps, FunctorNum, FunctorRep),
+        Ordinal = FunctorRep ^ edu_ordinal
+    ;
+        TypeCtorRep = etcr_dummy,
+        FunctorNum = 0,
+        Ordinal = 0
+    ;
+        TypeCtorRep = etcr_list,
+        (
+            Ordinal = 0,
+            FunctorNum = 0
+        ;
+            Ordinal = 1,
+            FunctorNum = 1
+        )
+    ;
+        TypeCtorRep = etcr_tuple,
+        FunctorNum = 0,
+        Ordinal = 0
+    ).
+
+get_functor_lex(TypeDesc, Ordinal, FunctorNum) :-
+    TypeInfo = type_info_from_type_desc(TypeDesc),
+    TypeCtorInfo = TypeInfo ^ type_ctor_info_evaled,
+    TypeCtorRep = TypeCtorInfo ^ type_ctor_rep,
+    (
+        TypeCtorRep = etcr_du,
+        FunctorReps = TypeCtorInfo ^ type_ctor_functors,
+        matching_du_ordinal(FunctorReps, Ordinal, FunctorRep),
+        FunctorNum = FunctorRep ^ edu_lex
+    ;
+        TypeCtorRep = etcr_dummy,
+        FunctorNum = 0,
+        Ordinal = 0
+    ;
+        TypeCtorRep = etcr_list,
+        (
+            Ordinal = 0,
+            FunctorNum = 0
+        ;
+            Ordinal = 1,
+            FunctorNum = 1
+        )
+    ;
+        TypeCtorRep = etcr_tuple,
+        Ordinal = 0,
+        FunctorNum = 0
+    ).
 
+:- pred matching_du_ordinal(list(erlang_du_functor)::in, int::in,
+    erlang_du_functor::out) is semidet.
 
+matching_du_ordinal(Fs, Ordinal, Functor) :-
+    list.index0(Fs, Ordinal, Functor),
+    % Sanity check.
+    ( Functor ^ edu_ordinal = Ordinal ->
+        true
+    ;
+        error(this_file ++ " matching_du_ordinal/3")
+    ).
 
+:- pred matching_du_functor_number(list(erlang_du_functor)::in, int::in,
+    erlang_du_functor::out) is semidet.
 
+matching_du_functor_number([F | Fs], FunctorNum, Functor) :-
+    ( F ^ edu_lex = FunctorNum ->
+        Functor = F
+    ;
+        matching_du_functor_number(Fs, FunctorNum, Functor)
+    ).
 
 %-----------------------------------------------------------------------------%
 %-----------------------------------------------------------------------------%
@@ -911,7 +1218,7 @@
         % We evaluate the thunk to get the actual type_ctor_info data.
         %
     if
-        is_function(TypeInfo) ->
+        is_function(TypeInfo, 0) ->
             TypeCtorInfo = TypeInfo();
         true ->
             FirstElement = element(?ML_ti_type_ctor_info, TypeInfo),
@@ -970,6 +1277,35 @@
 unsafe_type_info_index(_, _) = type_info :-
     det_unimplemented("unsafe_type_info_index").
 
+:- func get_fixed_arity_arg_type_infos(type_info) = list(type_info).
+
+:- pragma foreign_proc("Erlang",
+    get_fixed_arity_arg_type_infos(TypeInfo::in) = (Args::out),
+    [will_not_call_mercury, promise_pure, thread_safe],
+"
+    if
+        is_tuple(TypeInfo) ->
+            [_TypeCtorInfo | Args] = tuple_to_list(TypeInfo);
+        is_function(TypeInfo, 0) ->
+            Args = []   % zero arity type_info
+    end
+").
+
+get_fixed_arity_arg_type_infos(_) = _ :-
+    private_builtin.sorry("get_fixed_arity_arg_type_infos").
+
+:- func get_var_arity_arg_type_infos(type_info) = list(type_info).
+
+:- pragma foreign_proc("Erlang",
+    get_var_arity_arg_type_infos(TypeInfo::in) = (Args::out),
+    [will_not_call_mercury, promise_pure, thread_safe],
+"
+    Args = lists:nthtail(?ML_ti_var_arity, tuple_to_list(TypeInfo))
+").
+
+get_var_arity_arg_type_infos(_) = _ :-
+    private_builtin.sorry("get_var_arity_arg_type_infos").
+
 %-----------------------------------------------------------------------------%
 %-----------------------------------------------------------------------------%
 
@@ -1339,6 +1675,7 @@
                 edu_name            :: list(char),
                 edu_orig_arity      :: int,
                 edu_ordinal         :: int,
+                edu_lex             :: int,
                 edu_rep             :: erlang_atom,
                 edu_arg_infos       :: list(du_arg_info),
                 edu_exist_info      :: maybe(exist_info)
Index: library/type_desc.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/library/type_desc.m,v
retrieving revision 1.51
diff -u -r1.51 type_desc.m
--- library/type_desc.m	24 Aug 2007 04:15:29 -0000	1.51
+++ library/type_desc.m	30 Aug 2007 05:27:46 -0000
@@ -209,6 +209,7 @@
 :- import_module require.
 :- import_module string.
 
+:- use_module    erlang_rtti_implementation. 
 :- use_module    rtti_implementation.
 
 :- pragma foreign_decl("C", "
@@ -580,6 +581,13 @@
     TypeCtor = (MR_Word) MR_make_type_ctor_desc(type_info, type_ctor_info);
 }").
 
+type_ctor(TypeDesc) = TypeCtorDesc :-
+    ( erlang_rtti_implementation.is_erlang_backend ->
+        erlang_rtti_implementation.type_ctor_desc(TypeDesc, TypeCtorDesc)
+    ;
+        private_builtin.sorry("type_ctor/1")
+    ).
+
 :- pragma foreign_proc("C",
     pseudo_type_ctor(PseudoTypeInfo::in) = (TypeCtor::out),
     [will_not_call_mercury, thread_safe, promise_pure, will_not_modify_trail],
@@ -641,20 +649,17 @@
     }
 ").
 
-:- pragma foreign_proc("Erlang",
-    type_ctor_and_args(TypeDesc::in, TypeCtorDesc::out, ArgTypes::out),
-    [may_call_mercury, thread_safe, promise_pure, terminates],
-"
-    {TypeCtorDesc, ArgTypes} =
-        mercury__erlang_rtti_implementation:type_ctor_and_args_3_p_0(TypeDesc)
-").
-
 type_ctor_and_args(TypeDesc::in, TypeCtorDesc::out, ArgTypes::out) :-
-    rtti_implementation.type_ctor_and_args(
-        rtti_implementation.unsafe_cast(TypeDesc),
-        TypeCtorDesc0, ArgTypes0),
-    TypeCtorDesc = rtti_implementation.unsafe_cast(TypeCtorDesc0),
-    ArgTypes = rtti_implementation.unsafe_cast(ArgTypes0).
+    ( erlang_rtti_implementation.is_erlang_backend ->
+        erlang_rtti_implementation.type_ctor_desc_and_args(TypeDesc,
+            TypeCtorDesc, ArgTypes)
+    ;
+        rtti_implementation.type_ctor_and_args(
+            rtti_implementation.unsafe_cast(TypeDesc),
+            TypeCtorDesc0, ArgTypes0),
+        TypeCtorDesc = rtti_implementation.unsafe_cast(TypeCtorDesc0),
+        ArgTypes = rtti_implementation.unsafe_cast(ArgTypes0)
+    ).
 
 :- pragma foreign_proc("C",
     pseudo_type_ctor_and_args(PseudoTypeDesc::in, TypeCtorDesc::out,
@@ -741,6 +746,17 @@
     MR_restore_transient_registers();
 }").
 
+make_type(TypeCtorDesc::in, ArgTypes::in) = (TypeDesc::out) :-
+    ( erlang_rtti_implementation.is_erlang_backend ->
+        erlang_rtti_implementation.make_type_desc(TypeCtorDesc, ArgTypes,
+            TypeDesc)
+    ;
+        private_builtin.sorry("make_type/2")
+    ).
+
+make_type(_TypeCtorDesc::out, _ArgTypes::out) = (_TypeDesc::in) :-
+    private_builtin.sorry("make_type/2").
+
 :- pragma foreign_proc("C",
     type_ctor_name_and_arity(TypeCtorDesc::in, TypeCtorModuleName::out,
         TypeCtorName::out, TypeCtorArity::out),
@@ -789,27 +805,16 @@
     TypeCtorArity = ((java.lang.Integer) result[2]).intValue();
 ").
 
-:- pragma foreign_proc("Erlang",
-    type_ctor_name_and_arity(TypeCtorDesc0::in, TypeCtorModuleName::out,
-        TypeCtorName::out, TypeCtorArity::out),
-    [will_not_call_mercury, thread_safe, promise_pure],
-"
-    if
-        is_function(TypeCtorDesc0) ->
-            TypeCtorDesc = TypeCtorDesc0();
-        true ->
-            TypeCtorDesc = TypeCtorDesc0
-    end,
-    {TypeCtorModuleName, TypeCtorName, TypeCtorArity} =
-        mercury__erlang_rtti_implementation:
-            type_ctor_name_and_arity_4_p_0(TypeCtorDesc)
-").
-
 type_ctor_name_and_arity(TypeCtorDesc::in, ModuleName::out,
         TypeCtorName::out, TypeCtorArity::out) :-
-    rtti_implementation.type_ctor_name_and_arity(
-        rtti_implementation.unsafe_cast(TypeCtorDesc),
-        ModuleName, TypeCtorName, TypeCtorArity).
+    ( erlang_rtti_implementation.is_erlang_backend ->
+        erlang_rtti_implementation.type_ctor_desc_name_and_arity(TypeCtorDesc,
+            ModuleName, TypeCtorName, TypeCtorArity)
+    ;
+        rtti_implementation.type_ctor_name_and_arity(
+            rtti_implementation.unsafe_cast(TypeCtorDesc),
+            ModuleName, TypeCtorName, TypeCtorArity)
+    ).
 
 %-----------------------------------------------------------------------------%
 
@@ -911,24 +916,24 @@
         X = eval_if_function(X0),
         Y = eval_if_function(Y0),
         if
-            X =:= Y -> {{'='}};
-            X  <  Y -> {{'<'}};
-            true    -> {{'>'}}
+            X =:= Y -> {'='};
+            X  <  Y -> {'<'};
+            true    -> {'>'}
         end.
 
     '__Compare____type_ctor_desc_0_0'(X0, Y0) ->
         X = eval_if_function(X0),
         Y = eval_if_function(Y0),
         if
-            X =:= Y -> {{'='}};
-            X  <  Y -> {{'<'}};
-            true    -> {{'>'}}
+            X =:= Y -> {'='};
+            X  <  Y -> {'<'};
+            true    -> {'>'}
         end.
 
     '__Compare____pseudo_type_desc_0_0'(_, _) ->
         throw(""foreign code for comparing pseudo_type_desc"").
 
-    eval_if_function(X) when is_function(X) -> X();
+    eval_if_function(X) when is_function(X, 0) -> X();
     eval_if_function(X) when is_tuple(X) ->
         list_to_tuple([eval_if_function(E) || E <- tuple_to_list(X)]);
     eval_if_function(X) -> X.
Index: tests/hard_coded/construct_test.exp
===================================================================
RCS file: /home/mercury/mercury1/repository/tests/hard_coded/construct_test.exp,v
retrieving revision 1.6
diff -u -r1.6 construct_test.exp
--- tests/hard_coded/construct_test.exp	15 Feb 2007 00:41:51 -0000	1.6
+++ tests/hard_coded/construct_test.exp	30 Aug 2007 05:27:47 -0000
@@ -150,6 +150,11 @@
 0 - {}/4 [_, _, _, _] ordinal: 0 lex: 0
 
 
+2 functors in this type
+1 - [|]/2 [_, _] ordinal: 1 lex: 1
+0 - []/0 [] ordinal: 0 lex: 0
+
+
 
 TESTING OTHER TYPES
 1 functors in this type
@@ -176,6 +181,10 @@
 
 
 1 functors in this type
+0 - dummy/0 [] ordinal: 0 lex: 0
+
+
+1 functors in this type
 0 - xyzzy/1 [f21name] ordinal: 0 lex: 0
 
 
Index: tests/hard_coded/construct_test.m
===================================================================
RCS file: /home/mercury/mercury1/repository/tests/hard_coded/construct_test.m,v
retrieving revision 1.6
diff -u -r1.6 construct_test.m
--- tests/hard_coded/construct_test.m	5 Jan 2007 02:19:44 -0000	1.6
+++ tests/hard_coded/construct_test.m	30 Aug 2007 05:27:47 -0000
@@ -29,6 +29,8 @@
 
 :- type no_tag		---> 	qwerty(qwerty_field :: int).
 
+:- type dummy		--->	dummy.
+
 :- type exist_type	--->	some [T] xyzzy(f21name :: T).
 
 %----------------------------------------------------------------------------%
@@ -284,6 +286,9 @@
 		% test tuples
 	test_all({1, "a", 'a', {4, 'd'}}), newline,
 
+		% test lists
+	test_all([1, 2, 3, 4]), newline,
+
 	newline.
 
 	% Note: testing abstract types is always going to have results
@@ -308,6 +313,9 @@
 		% a no tag type 
 	test_all(qwerty(4)), newline,
 
+		% a dummy type
+	test_all(dummy), newline,
+
 		% an existential type:
 	{ ExistVal = 'new xyzzy'(8) },
 	test_all(ExistVal), newline.

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