summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--typing/env.ml1
-rw-r--r--typing/includecore.ml28
-rw-r--r--typing/includecore.mli2
-rw-r--r--typing/typedecl.ml41
-rw-r--r--typing/typedecl.mli2
-rw-r--r--typing/typemod.ml10
6 files changed, 64 insertions, 20 deletions
diff --git a/typing/env.ml b/typing/env.ml
index 92b0c0f0d..3d4893240 100644
--- a/typing/env.ml
+++ b/typing/env.ml
@@ -1053,6 +1053,7 @@ let labels_of_type ty_path decl =
| Record_exception (Pident id) ->
begin match ty_path with
| Path.Pdot (path, _, pos) ->
+ Format.printf "XXX@.";
Record_exception (Path.Pdot (path, Ident.name id, pos))
| Path.Pident _ ->
rep
diff --git a/typing/includecore.ml b/typing/includecore.ml
index 0757c73e7..1514a85cd 100644
--- a/typing/includecore.ml
+++ b/typing/includecore.ml
@@ -120,7 +120,7 @@ type type_mismatch =
| Field_arity of Ident.t
| Field_names of int * Ident.t * Ident.t
| Field_missing of bool * Ident.t
- | Record_representation of bool
+ | Record_representation of record_representation * record_representation
let report_type_mismatch0 first second decl ppf err =
let pr fmt = Format.fprintf ppf fmt in
@@ -143,10 +143,16 @@ let report_type_mismatch0 first second decl ppf err =
| Field_missing (b, s) ->
pr "The field %s is only present in %s %s"
(Ident.name s) (if b then second else first) decl
- | Record_representation b ->
- pr "Their internal representations differ:@ %s %s %s"
- (if b then second else first) decl
- "uses unboxed float representation"
+ | Record_representation (r1, r2) ->
+ let repr = function
+ | Record_regular 0 -> "regular"
+ | Record_regular i -> Printf.sprintf"inline record (tag %i)" i
+ | Record_float -> "unboxed float"
+ | Record_exception p -> Printf.sprintf "exception %s" (Path.name p)
+ in
+ pr "Their internal representations differ:@ %s vs %s"
+ (repr r1)
+ (repr r2)
let report_type_mismatch first second decl ppf =
List.iter
@@ -196,6 +202,14 @@ let rec compare_records env decl1 decl2 n labels1 labels2 =
then compare_records env decl1 decl2 (n+1) rem1 rem2
else [Field_type lab1]
+let record_representations r1 r2 =
+ match r1, r2 with
+ | Record_regular i, Record_regular j -> i = j
+ | Record_float, Record_float -> true
+ | Record_exception _, Record_exception _ -> true
+ (* allow a different path to support exception rebinding *)
+ | _ -> false
+
let type_declarations ?(equality = false) env name decl1 id decl2 =
if decl1.type_arity <> decl2.type_arity then [Arity] else
if not (private_flags decl1 decl2) then [Privacy] else
@@ -217,8 +231,8 @@ let type_declarations ?(equality = false) env name decl1 id decl2 =
compare_variants env decl1 decl2 1 cstrs1 cstrs2
| (Type_record(labels1,rep1), Type_record(labels2,rep2)) ->
let err = compare_records env decl1 decl2 1 labels1 labels2 in
- if err <> [] || rep1 = rep2 then err else
- [Record_representation (rep2 = Record_float)]
+ if err <> [] || record_representations rep1 rep2 then err else
+ [Record_representation (rep1, rep2)]
| (_, _) -> [Kind]
in
if err <> [] then err else
diff --git a/typing/includecore.mli b/typing/includecore.mli
index 083624194..75e6c1957 100644
--- a/typing/includecore.mli
+++ b/typing/includecore.mli
@@ -29,7 +29,7 @@ type type_mismatch =
| Field_arity of Ident.t
| Field_names of int * Ident.t * Ident.t
| Field_missing of bool * Ident.t
- | Record_representation of bool
+ | Record_representation of record_representation * record_representation
val value_descriptions:
Env.t -> value_description -> value_description -> module_coercion
diff --git a/typing/typedecl.ml b/typing/typedecl.ml
index c264864e7..0a99a3c70 100644
--- a/typing/typedecl.ml
+++ b/typing/typedecl.ml
@@ -278,7 +278,7 @@ let transl_declaration ?exnid env sdecl id =
match sdecl.ptype_attributes with
| [{txt="#tag#"}, PStr [{pstr_desc=Pstr_eval({pexp_desc=Pexp_constant(Const_int tag)}, _)}]] ->
begin match exnid with
- | Some id -> print_endline "XXX"; Record_exception (Path.Pident id)
+ | Some id -> Record_exception (Path.Pident id)
| None -> Record_regular tag
end
| _ ->
@@ -1189,20 +1189,43 @@ let transl_exception env excdecl =
let transl_type_decl = transl_type_decl ?exnid:None
(* Translate an exception rebinding *)
-let transl_exn_rebind env loc lid =
+let transl_exn_rebind env loc name lid =
let cdescr =
try
Env.lookup_constructor lid env
with Not_found ->
raise(Error(loc, Unbound_exception lid)) in
Env.mark_constructor Env.Positive env (Longident.last lid) cdescr;
- match cdescr.cstr_tag with
- Cstr_exception (path, _) ->
- (path, {exn_args = cdescr.cstr_args;
- exn_attributes = [];
- exn_inlined = cdescr.cstr_inlined;
- Types.exn_loc = loc})
- | _ -> raise(Error(loc, Not_an_exception lid))
+ let path =
+ match cdescr.cstr_tag with
+ | Cstr_exception (path, _) -> path
+ | _ -> raise(Error(loc, Not_an_exception lid))
+ in
+ let tdecls, exn_args =
+ if cdescr.cstr_inlined then
+ match cdescr.cstr_args with
+ | [{desc=Tconstr(p, [], _)} as ty] ->
+ let tdecl =
+ try Env.find_type p env
+ with Not_found -> assert false
+ in
+ let tdecl = {tdecl with type_manifest = Some ty} in
+ let (id, env) =
+ Env.enter_type ("exn." ^ name) tdecl env
+ in
+ ([id, tdecl], env), [ Ctype.newconstr (Path.Pident id) [] ]
+ | _ -> assert false
+ else
+ ([], env), cdescr.cstr_args
+ in
+ let d = {
+ Types.exn_args;
+ exn_attributes = [];
+ exn_inlined = cdescr.cstr_inlined;
+ exn_loc = loc
+ }
+ in
+ (tdecls, path, d)
(* Translate a value declaration *)
let transl_value_decl env loc valdecl =
diff --git a/typing/typedecl.mli b/typing/typedecl.mli
index 89989cefb..ee68aa2e3 100644
--- a/typing/typedecl.mli
+++ b/typing/typedecl.mli
@@ -24,7 +24,7 @@ val transl_exception:
Parsetree.constructor_declaration -> (Typedtree.type_declaration list * Env.t) * Typedtree.constructor_declaration * exception_declaration * Env.t
val transl_exn_rebind:
- Env.t -> Location.t -> Longident.t -> Path.t * exception_declaration
+ Env.t -> Location.t -> string -> Longident.t -> ((Ident.t * Types.type_declaration) list * Env.t) * Path.t * exception_declaration
val transl_value_decl:
Env.t -> Location.t ->
diff --git a/typing/typemod.ml b/typing/typemod.ml
index 593b49e1e..ddea66977 100644
--- a/typing/typemod.ml
+++ b/typing/typemod.ml
@@ -474,6 +474,10 @@ let mksig desc env loc =
let prepend_sig_types decls rem =
map_rec'' (fun rs td -> Sig_type(td.typ_id, td.typ_type, rs)) decls rem
+let prepend_sig_types' decls rem =
+ map_rec (fun rs (id, td) -> Sig_type(id, td, rs)) decls rem
+
+
let rec transl_modtype env smty =
let loc = smty.pmty_loc in
match smty.pmty_desc with
@@ -1167,10 +1171,12 @@ and type_structure ?(toplevel = false) funct_body anchor env sstr scope =
prepend_sig_types tdecls [Sig_exception(arg.cd_id, decl)],
newenv
| Pstr_exn_rebind(name, longid, attrs) ->
- let (path, arg) = Typedecl.transl_exn_rebind env loc longid.txt in
+ let ((tdecls, env), path, arg) =
+ Typedecl.transl_exn_rebind env loc name.txt longid.txt
+ in
let (id, newenv) = Env.enter_exception name.txt arg env in
Tstr_exn_rebind(id, name, path, longid, attrs),
- [Sig_exception(id, arg)],
+ prepend_sig_types' tdecls [Sig_exception(id, arg)],
newenv
| Pstr_module {pmb_name = name; pmb_expr = smodl; pmb_attributes = attrs;
pmb_loc;