1995-08-09 08:06:35 -07:00
|
|
|
(***********************************************************************)
|
|
|
|
(* *)
|
2011-07-27 07:17:02 -07:00
|
|
|
(* OCaml *)
|
1995-08-09 08:06:35 -07:00
|
|
|
(* *)
|
|
|
|
(* Xavier Leroy, projet Cristal, INRIA Rocquencourt *)
|
|
|
|
(* *)
|
1996-04-30 07:53:58 -07:00
|
|
|
(* Copyright 1996 Institut National de Recherche en Informatique et *)
|
1999-11-17 10:59:06 -08:00
|
|
|
(* en Automatique. All rights reserved. This file is distributed *)
|
|
|
|
(* under the terms of the Q Public License version 1.0. *)
|
1995-08-09 08:06:35 -07:00
|
|
|
(* *)
|
|
|
|
(***********************************************************************)
|
|
|
|
|
2002-04-18 00:27:47 -07:00
|
|
|
(* typetexp.ml,v 1.34.4.9 2002/01/07 08:39:16 garrigue Exp *)
|
1995-08-09 08:06:35 -07:00
|
|
|
|
1995-05-04 03:15:53 -07:00
|
|
|
(* Typechecking of type expressions for the core language *)
|
|
|
|
|
2012-05-30 07:52:37 -07:00
|
|
|
open Asttypes
|
1996-04-22 04:15:41 -07:00
|
|
|
open Misc
|
1995-05-04 03:15:53 -07:00
|
|
|
open Parsetree
|
2012-05-30 07:52:37 -07:00
|
|
|
open Typedtree
|
1996-09-23 04:33:27 -07:00
|
|
|
open Types
|
1995-05-04 03:15:53 -07:00
|
|
|
open Ctype
|
|
|
|
|
2014-05-04 16:08:45 -07:00
|
|
|
exception Already_bound
|
1995-05-04 03:15:53 -07:00
|
|
|
|
|
|
|
type error =
|
|
|
|
Unbound_type_variable of string
|
|
|
|
| Unbound_type_constructor of Longident.t
|
2001-11-27 18:14:39 -08:00
|
|
|
| Unbound_type_constructor_2 of Path.t
|
1995-05-04 03:15:53 -07:00
|
|
|
| Type_arity_mismatch of Longident.t * int * int
|
1996-04-22 04:15:41 -07:00
|
|
|
| Bound_type_variable of string
|
|
|
|
| Recursive_type
|
|
|
|
| Unbound_row_variable of Longident.t
|
1997-02-20 12:39:02 -08:00
|
|
|
| Type_mismatch of (type_expr * type_expr) list
|
|
|
|
| Alias_type_mismatch of (type_expr * type_expr) list
|
1999-11-30 08:07:38 -08:00
|
|
|
| Present_has_conjunction of string
|
|
|
|
| Present_has_no_type of string
|
2001-09-25 02:54:18 -07:00
|
|
|
| Constructor_mismatch of type_expr * type_expr
|
|
|
|
| Not_a_variant of type_expr
|
2002-01-03 18:02:50 -08:00
|
|
|
| Variant_tags of string * string
|
2003-03-07 00:59:15 -08:00
|
|
|
| Invalid_variable_name of string
|
2003-05-19 02:21:17 -07:00
|
|
|
| Cannot_quantify of string * type_expr
|
2011-12-14 02:26:15 -08:00
|
|
|
| Multiple_constraints_on_type of Longident.t
|
2010-01-20 08:26:46 -08:00
|
|
|
| Repeated_method_label of string
|
2010-05-18 09:46:46 -07:00
|
|
|
| Unbound_value of Longident.t
|
|
|
|
| Unbound_constructor of Longident.t
|
|
|
|
| Unbound_label of Longident.t
|
|
|
|
| Unbound_module of Longident.t
|
|
|
|
| Unbound_class of Longident.t
|
2010-05-18 10:18:24 -07:00
|
|
|
| Unbound_modtype of Longident.t
|
2010-05-18 10:25:02 -07:00
|
|
|
| Unbound_cltype of Longident.t
|
2010-05-18 09:46:46 -07:00
|
|
|
| Ill_typed_functor_application of Longident.t
|
2013-04-29 08:39:00 -07:00
|
|
|
| Illegal_reference_to_recursive_module
|
2014-05-11 01:13:04 -07:00
|
|
|
| Access_functor_as_structure of Longident.t
|
2015-10-24 07:28:53 -07:00
|
|
|
| Apply_structure_as_functor of Longident.t
|
2015-10-22 09:11:08 -07:00
|
|
|
| Cannot_scrape_alias of Longident.t * Path.t
|
1995-05-04 03:15:53 -07:00
|
|
|
|
2013-01-29 06:21:12 -08:00
|
|
|
exception Error of Location.t * Env.t * error
|
2014-05-07 01:26:17 -07:00
|
|
|
exception Error_forward of Location.error
|
1995-05-04 03:15:53 -07:00
|
|
|
|
2014-12-27 00:44:50 -08:00
|
|
|
|
2002-08-04 22:58:08 -07:00
|
|
|
type variable_context = int * (string, type_expr) Tbl.t
|
|
|
|
|
2011-11-24 01:02:48 -08:00
|
|
|
(* Local definitions *)
|
|
|
|
|
|
|
|
let instance_list = Ctype.instance_list Env.empty
|
|
|
|
|
2010-05-18 09:46:46 -07:00
|
|
|
(* Narrowing unbound identifier errors. *)
|
|
|
|
|
2012-12-26 18:34:49 -08:00
|
|
|
let rec narrow_unbound_lid_error : 'a. _ -> _ -> _ -> _ -> 'a =
|
|
|
|
fun env loc lid make_error ->
|
2010-05-18 09:46:46 -07:00
|
|
|
let check_module mlid =
|
2014-05-12 05:02:26 -07:00
|
|
|
try ignore (Env.lookup_module true mlid env) with
|
2014-05-09 12:40:19 -07:00
|
|
|
| Not_found ->
|
2014-05-12 05:02:26 -07:00
|
|
|
narrow_unbound_lid_error env loc mlid (fun lid -> Unbound_module lid)
|
2014-05-09 12:40:19 -07:00
|
|
|
| Env.Recmodule ->
|
|
|
|
raise (Error (loc, env, Illegal_reference_to_recursive_module))
|
2010-05-18 09:46:46 -07:00
|
|
|
in
|
|
|
|
begin match lid with
|
|
|
|
| Longident.Lident _ -> ()
|
2014-05-11 01:13:04 -07:00
|
|
|
| Longident.Ldot (mlid, _) ->
|
|
|
|
check_module mlid;
|
2014-05-12 05:02:26 -07:00
|
|
|
let md = Env.find_module (Env.lookup_module true mlid env) env in
|
2014-05-11 01:13:04 -07:00
|
|
|
begin match Env.scrape_alias env md.md_type with
|
2015-10-24 07:28:53 -07:00
|
|
|
| Mty_functor _ ->
|
2014-05-11 01:13:04 -07:00
|
|
|
raise (Error (loc, env, Access_functor_as_structure mlid))
|
2015-10-22 09:11:08 -07:00
|
|
|
| Mty_alias p ->
|
|
|
|
raise (Error (loc, env, Cannot_scrape_alias(mlid, p)))
|
2014-05-11 01:13:04 -07:00
|
|
|
| _ -> ()
|
|
|
|
end
|
2010-05-18 09:46:46 -07:00
|
|
|
| Longident.Lapply (flid, mlid) ->
|
|
|
|
check_module flid;
|
2015-10-24 07:28:53 -07:00
|
|
|
let fmd = Env.find_module (Env.lookup_module true flid env) env in
|
|
|
|
begin match Env.scrape_alias env fmd.md_type with
|
|
|
|
| Mty_signature _ ->
|
|
|
|
raise (Error (loc, env, Apply_structure_as_functor flid))
|
|
|
|
| Mty_alias p ->
|
|
|
|
raise (Error (loc, env, Cannot_scrape_alias(flid, p)))
|
|
|
|
| _ -> ()
|
|
|
|
end;
|
|
|
|
let mmd = Env.find_module (Env.lookup_module true mlid env) env in
|
2010-05-18 09:46:46 -07:00
|
|
|
check_module mlid;
|
2015-10-24 07:28:53 -07:00
|
|
|
begin match Env.scrape_alias env mmd.md_type with
|
|
|
|
| Mty_alias p ->
|
|
|
|
raise (Error (loc, env, Cannot_scrape_alias(mlid, p)))
|
|
|
|
| _ ->
|
|
|
|
raise (Error (loc, env, Ill_typed_functor_application lid))
|
|
|
|
end
|
2010-05-18 09:46:46 -07:00
|
|
|
end;
|
2013-01-29 06:21:12 -08:00
|
|
|
raise (Error (loc, env, make_error lid))
|
2010-05-18 09:46:46 -07:00
|
|
|
|
|
|
|
let find_component lookup make_error env loc lid =
|
|
|
|
try
|
|
|
|
match lid with
|
2011-09-22 02:05:42 -07:00
|
|
|
| Longident.Ldot (Longident.Lident "*predef*", s) ->
|
2015-12-02 01:21:24 -08:00
|
|
|
lookup ?loc:(Some loc) (Longident.Lident s) Env.initial_safe_string
|
2015-11-27 10:31:58 -08:00
|
|
|
| _ ->
|
2015-12-02 01:21:24 -08:00
|
|
|
lookup ?loc:(Some loc) lid env
|
2010-05-18 09:46:46 -07:00
|
|
|
with Not_found ->
|
2012-12-26 18:34:49 -08:00
|
|
|
narrow_unbound_lid_error env loc lid make_error
|
2013-04-29 08:39:00 -07:00
|
|
|
| Env.Recmodule ->
|
|
|
|
raise (Error (loc, env, Illegal_reference_to_recursive_module))
|
2010-05-18 09:46:46 -07:00
|
|
|
|
2013-09-27 08:04:03 -07:00
|
|
|
let find_type env loc lid =
|
|
|
|
let (path, decl) as r =
|
|
|
|
find_component Env.lookup_type (fun lid -> Unbound_type_constructor lid)
|
|
|
|
env loc lid
|
|
|
|
in
|
2015-12-02 05:46:14 -08:00
|
|
|
Builtin_attributes.check_deprecated loc decl.type_attributes (Path.name path);
|
2013-09-27 08:04:03 -07:00
|
|
|
r
|
|
|
|
|
2011-09-22 02:05:42 -07:00
|
|
|
let find_constructor =
|
|
|
|
find_component Env.lookup_constructor (fun lid -> Unbound_constructor lid)
|
2012-10-29 00:54:06 -07:00
|
|
|
let find_all_constructors =
|
|
|
|
find_component Env.lookup_all_constructors
|
2013-01-29 06:21:12 -08:00
|
|
|
(fun lid -> Unbound_constructor lid)
|
2011-09-22 02:05:42 -07:00
|
|
|
let find_label =
|
|
|
|
find_component Env.lookup_label (fun lid -> Unbound_label lid)
|
2012-10-29 00:54:06 -07:00
|
|
|
let find_all_labels =
|
2013-01-29 06:21:12 -08:00
|
|
|
find_component Env.lookup_all_labels (fun lid -> Unbound_label lid)
|
2013-09-27 08:04:03 -07:00
|
|
|
|
|
|
|
let find_class env loc lid =
|
|
|
|
let (path, decl) as r =
|
|
|
|
find_component Env.lookup_class (fun lid -> Unbound_class lid) env loc lid
|
|
|
|
in
|
2015-12-02 05:46:14 -08:00
|
|
|
Builtin_attributes.check_deprecated loc decl.cty_attributes (Path.name path);
|
2013-09-27 08:04:03 -07:00
|
|
|
r
|
|
|
|
|
|
|
|
let find_value env loc lid =
|
2015-03-09 10:39:50 -07:00
|
|
|
Env.check_value_name (Longident.last lid) loc;
|
2013-09-27 08:04:03 -07:00
|
|
|
let (path, decl) as r =
|
|
|
|
find_component Env.lookup_value (fun lid -> Unbound_value lid) env loc lid
|
|
|
|
in
|
2015-12-02 05:46:14 -08:00
|
|
|
Builtin_attributes.check_deprecated loc decl.val_attributes (Path.name path);
|
2013-09-27 08:04:03 -07:00
|
|
|
r
|
|
|
|
|
2014-05-12 05:42:15 -07:00
|
|
|
let lookup_module ?(load=false) env loc lid =
|
2013-09-27 10:05:39 -07:00
|
|
|
let (path, decl) as r =
|
2015-12-02 01:21:24 -08:00
|
|
|
find_component (fun ?loc lid env -> (Env.lookup_module ~load ?loc lid env, ()))
|
2013-10-08 01:18:38 -07:00
|
|
|
(fun lid -> Unbound_module lid) env loc lid
|
2015-11-27 10:13:56 -08:00
|
|
|
in
|
|
|
|
path
|
2014-05-12 05:02:26 -07:00
|
|
|
|
|
|
|
let find_module env loc lid =
|
2014-05-12 05:42:15 -07:00
|
|
|
let path = lookup_module ~load:true env loc lid in
|
2014-05-12 05:02:26 -07:00
|
|
|
let decl = Env.find_module path env in
|
2015-12-01 09:01:59 -08:00
|
|
|
(* No need to check for deprecated here, this is done in Env. *)
|
2014-05-12 05:02:26 -07:00
|
|
|
(path, decl)
|
|
|
|
|
2013-10-01 08:14:04 -07:00
|
|
|
let find_modtype env loc lid =
|
|
|
|
let (path, decl) as r =
|
|
|
|
find_component Env.lookup_modtype (fun lid -> Unbound_modtype lid)
|
|
|
|
env loc lid
|
|
|
|
in
|
2015-12-02 05:46:14 -08:00
|
|
|
Builtin_attributes.check_deprecated loc decl.mtd_attributes (Path.name path);
|
2013-10-01 08:14:04 -07:00
|
|
|
r
|
2013-09-27 08:04:03 -07:00
|
|
|
|
|
|
|
let find_class_type env loc lid =
|
|
|
|
let (path, decl) as r =
|
|
|
|
find_component Env.lookup_cltype (fun lid -> Unbound_cltype lid)
|
|
|
|
env loc lid
|
|
|
|
in
|
2015-12-02 05:46:14 -08:00
|
|
|
Builtin_attributes.check_deprecated loc decl.clty_attributes (Path.name path);
|
2013-09-27 08:04:03 -07:00
|
|
|
r
|
2010-05-18 10:25:02 -07:00
|
|
|
|
2012-10-29 00:54:06 -07:00
|
|
|
let unbound_constructor_error env lid =
|
|
|
|
narrow_unbound_lid_error env lid.loc lid.txt
|
2013-01-29 06:21:12 -08:00
|
|
|
(fun lid -> Unbound_constructor lid)
|
2012-10-29 00:54:06 -07:00
|
|
|
|
|
|
|
let unbound_label_error env lid =
|
|
|
|
narrow_unbound_lid_error env lid.loc lid.txt
|
2013-01-29 06:21:12 -08:00
|
|
|
(fun lid -> Unbound_label lid)
|
2012-10-29 00:54:06 -07:00
|
|
|
|
2009-10-26 03:53:16 -07:00
|
|
|
(* Support for first-class modules. *)
|
|
|
|
|
|
|
|
let transl_modtype_longident = ref (fun _ -> assert false)
|
|
|
|
let transl_modtype = ref (fun _ -> assert false)
|
|
|
|
|
|
|
|
let create_package_mty fake loc env (p, l) =
|
|
|
|
let l =
|
|
|
|
List.sort
|
|
|
|
(fun (s1, t1) (s2, t2) ->
|
2012-05-31 01:07:31 -07:00
|
|
|
if s1.txt = s2.txt then
|
2013-01-29 06:21:12 -08:00
|
|
|
raise (Error (loc, env, Multiple_constraints_on_type s1.txt));
|
2014-03-09 19:06:10 -07:00
|
|
|
compare s1.txt s2.txt)
|
2009-10-26 03:53:16 -07:00
|
|
|
l
|
|
|
|
in
|
|
|
|
l,
|
|
|
|
List.fold_left
|
|
|
|
(fun mty (s, t) ->
|
2013-03-06 03:47:59 -08:00
|
|
|
let d = {ptype_name = mkloc (Longident.last s.txt) s.loc;
|
|
|
|
ptype_params = [];
|
2009-10-26 03:53:16 -07:00
|
|
|
ptype_cstrs = [];
|
|
|
|
ptype_kind = Ptype_abstract;
|
|
|
|
ptype_private = Asttypes.Public;
|
|
|
|
ptype_manifest = if fake then None else Some t;
|
2013-03-01 04:44:04 -08:00
|
|
|
ptype_attributes = [];
|
2009-10-26 03:53:16 -07:00
|
|
|
ptype_loc = loc} in
|
2014-01-14 03:29:02 -08:00
|
|
|
Ast_helper.Mty.mk ~loc
|
|
|
|
(Pmty_with (mty, [ Pwith_type ({ txt = s.txt; loc }, d) ]))
|
2009-10-26 03:53:16 -07:00
|
|
|
)
|
2013-03-08 06:59:45 -08:00
|
|
|
(Ast_helper.Mty.mk ~loc (Pmty_ident p))
|
2009-10-26 03:53:16 -07:00
|
|
|
l
|
|
|
|
|
1995-05-04 03:15:53 -07:00
|
|
|
(* Translation of type expressions *)
|
|
|
|
|
|
|
|
let type_variables = ref (Tbl.empty : (string, type_expr) Tbl.t)
|
2003-05-19 02:21:17 -07:00
|
|
|
let univars = ref ([] : (string * type_expr) list)
|
2002-04-18 00:27:47 -07:00
|
|
|
let pre_univars = ref ([] : type_expr list)
|
2005-07-21 21:11:47 -07:00
|
|
|
let used_variables = ref (Tbl.empty : (string, type_expr * Location.t) Tbl.t)
|
2003-03-19 23:36:55 -08:00
|
|
|
|
1995-05-04 03:15:53 -07:00
|
|
|
let reset_type_variables () =
|
1996-04-22 04:15:41 -07:00
|
|
|
reset_global_level ();
|
2015-09-09 01:51:02 -07:00
|
|
|
Ctype.reset_reified_var_counter ();
|
2002-08-04 22:58:08 -07:00
|
|
|
type_variables := Tbl.empty
|
1998-06-24 12:22:26 -07:00
|
|
|
|
|
|
|
let narrow () =
|
2002-08-04 22:58:08 -07:00
|
|
|
(increase_global_level (), !type_variables)
|
|
|
|
|
|
|
|
let widen (gl, tv) =
|
|
|
|
restore_global_level gl;
|
|
|
|
type_variables := tv
|
1995-05-04 03:15:53 -07:00
|
|
|
|
2015-10-10 00:22:35 -07:00
|
|
|
let strict_ident c = (c = '_' || c >= 'a' && c <= 'z' || c >= 'A' && c <= 'Z')
|
2011-09-22 02:05:42 -07:00
|
|
|
|
|
|
|
let validate_name = function
|
|
|
|
None -> None
|
|
|
|
| Some name as s ->
|
2015-10-10 00:22:35 -07:00
|
|
|
if name <> "" && strict_ident name.[0] then s else None
|
2011-09-22 02:05:42 -07:00
|
|
|
|
|
|
|
let new_global_var ?name () =
|
|
|
|
new_global_var ?name:(validate_name name) ()
|
|
|
|
let newvar ?name () =
|
|
|
|
newvar ?name:(validate_name name) ()
|
|
|
|
|
1996-04-22 04:15:41 -07:00
|
|
|
let type_variable loc name =
|
|
|
|
try
|
|
|
|
Tbl.find name !type_variables
|
|
|
|
with Not_found ->
|
2013-01-29 06:21:12 -08:00
|
|
|
raise(Error(loc, Env.empty, Unbound_type_variable ("'" ^ name)))
|
1996-04-22 04:15:41 -07:00
|
|
|
|
2014-05-04 16:08:45 -07:00
|
|
|
let transl_type_param env styp =
|
|
|
|
let loc = styp.ptyp_loc in
|
|
|
|
match styp.ptyp_desc with
|
|
|
|
Ptyp_any ->
|
|
|
|
let ty = new_global_var ~name:"_" () in
|
|
|
|
{ ctyp_desc = Ttyp_any; ctyp_type = ty; ctyp_env = env;
|
|
|
|
ctyp_loc = loc; ctyp_attributes = styp.ptyp_attributes; }
|
|
|
|
| Ptyp_var name ->
|
|
|
|
let ty =
|
|
|
|
try
|
|
|
|
if name <> "" && name.[0] = '_' then
|
|
|
|
raise (Error (loc, Env.empty, Invalid_variable_name ("'" ^ name)));
|
|
|
|
ignore (Tbl.find name !type_variables);
|
|
|
|
raise Already_bound
|
|
|
|
with Not_found ->
|
|
|
|
let v = new_global_var ~name () in
|
|
|
|
type_variables := Tbl.add name v !type_variables;
|
|
|
|
v
|
|
|
|
in
|
|
|
|
{ ctyp_desc = Ttyp_var name; ctyp_type = ty; ctyp_env = env;
|
|
|
|
ctyp_loc = loc; ctyp_attributes = styp.ptyp_attributes; }
|
|
|
|
| _ -> assert false
|
|
|
|
|
2011-09-22 02:05:42 -07:00
|
|
|
let new_pre_univar ?name () =
|
|
|
|
let v = newvar ?name () in pre_univars := v :: !pre_univars; v
|
2002-04-18 00:27:47 -07:00
|
|
|
|
|
|
|
let rec swap_list = function
|
|
|
|
x :: y :: l -> y :: x :: swap_list l
|
|
|
|
| l -> l
|
|
|
|
|
2005-07-21 21:11:47 -07:00
|
|
|
type policy = Fixed | Extensible | Univars
|
2002-04-18 00:27:47 -07:00
|
|
|
|
2003-05-19 02:21:17 -07:00
|
|
|
let rec transl_type env policy styp =
|
2012-05-30 07:52:37 -07:00
|
|
|
let loc = styp.ptyp_loc in
|
2013-03-25 07:16:07 -07:00
|
|
|
let ctyp ctyp_desc ctyp_type =
|
2014-02-25 00:16:25 -08:00
|
|
|
{ ctyp_desc; ctyp_type; ctyp_env = env;
|
|
|
|
ctyp_loc = loc; ctyp_attributes = styp.ptyp_attributes }
|
2013-03-25 07:16:07 -07:00
|
|
|
in
|
1995-05-04 03:15:53 -07:00
|
|
|
match styp.ptyp_desc with
|
2002-04-18 00:27:47 -07:00
|
|
|
Ptyp_any ->
|
2012-05-30 07:52:37 -07:00
|
|
|
let ty =
|
|
|
|
if policy = Univars then new_pre_univar () else
|
|
|
|
if policy = Fixed then
|
2013-01-29 06:21:12 -08:00
|
|
|
raise (Error (styp.ptyp_loc, env, Unbound_type_variable "_"))
|
2012-05-30 07:52:37 -07:00
|
|
|
else newvar ()
|
|
|
|
in
|
2013-03-25 07:16:07 -07:00
|
|
|
ctyp Ttyp_any ty
|
1997-02-11 10:24:47 -08:00
|
|
|
| Ptyp_var name ->
|
2012-05-30 07:52:37 -07:00
|
|
|
let ty =
|
2003-03-07 00:59:15 -08:00
|
|
|
if name <> "" && name.[0] = '_' then
|
2013-01-29 06:21:12 -08:00
|
|
|
raise (Error (styp.ptyp_loc, env, Invalid_variable_name ("'" ^ name)));
|
2002-04-18 00:27:47 -07:00
|
|
|
begin try
|
2012-05-31 01:07:31 -07:00
|
|
|
instance env (List.assoc name !univars)
|
|
|
|
with Not_found -> try
|
|
|
|
instance env (fst(Tbl.find name !used_variables))
|
|
|
|
with Not_found ->
|
|
|
|
let v =
|
|
|
|
if policy = Univars then new_pre_univar ~name () else newvar ~name ()
|
|
|
|
in
|
|
|
|
used_variables := Tbl.add name (v, styp.ptyp_loc) !used_variables;
|
|
|
|
v
|
1995-05-04 03:15:53 -07:00
|
|
|
end
|
2012-05-30 07:52:37 -07:00
|
|
|
in
|
2013-03-25 07:16:07 -07:00
|
|
|
ctyp (Ttyp_var name) ty
|
1999-11-30 08:07:38 -08:00
|
|
|
| Ptyp_arrow(l, st1, st2) ->
|
2012-05-30 07:52:37 -07:00
|
|
|
let cty1 = transl_type env policy st1 in
|
|
|
|
let cty2 = transl_type env policy st2 in
|
2014-12-22 01:06:02 -08:00
|
|
|
let ty1 = cty1.ctyp_type in
|
|
|
|
let ty1 =
|
|
|
|
if Btype.is_optional l
|
|
|
|
then newty (Tconstr(Predef.path_option,[ty1], ref Mnil))
|
|
|
|
else ty1 in
|
|
|
|
let ty = newty (Tarrow(l, ty1, cty2.ctyp_type, Cok)) in
|
2013-03-25 07:16:07 -07:00
|
|
|
ctyp (Ttyp_arrow (l, cty1, cty2)) ty
|
1995-05-04 03:15:53 -07:00
|
|
|
| Ptyp_tuple stl ->
|
2014-08-22 06:45:02 -07:00
|
|
|
if List.length stl < 2 then
|
|
|
|
Syntaxerr.ill_formed_ast loc "Tuples must have at least 2 components.";
|
2012-05-30 07:52:37 -07:00
|
|
|
let ctys = List.map (transl_type env policy) stl in
|
|
|
|
let ty = newty (Ttuple (List.map (fun ctyp -> ctyp.ctyp_type) ctys)) in
|
2013-03-25 07:16:07 -07:00
|
|
|
ctyp (Ttyp_tuple ctys) ty
|
1997-03-07 14:26:29 -08:00
|
|
|
| Ptyp_constr(lid, stl) ->
|
2012-05-30 07:52:37 -07:00
|
|
|
let (path, decl) = find_type env styp.ptyp_loc lid.txt in
|
2014-04-22 08:28:20 -07:00
|
|
|
let stl =
|
|
|
|
match stl with
|
|
|
|
| [ {ptyp_desc=Ptyp_any} as t ] when decl.type_arity > 1 ->
|
|
|
|
List.map (fun _ -> t) decl.type_params
|
|
|
|
| _ -> stl
|
|
|
|
in
|
1995-05-04 03:15:53 -07:00
|
|
|
if List.length stl <> decl.type_arity then
|
2013-01-29 06:21:12 -08:00
|
|
|
raise(Error(styp.ptyp_loc, env,
|
2014-04-12 03:17:02 -07:00
|
|
|
Type_arity_mismatch(lid.txt, decl.type_arity,
|
2013-01-29 06:21:12 -08:00
|
|
|
List.length stl)));
|
2003-05-19 02:21:17 -07:00
|
|
|
let args = List.map (transl_type env policy) stl in
|
2011-11-24 01:02:48 -08:00
|
|
|
let params = instance_list decl.type_params in
|
2003-03-26 00:24:02 -08:00
|
|
|
let unify_param =
|
|
|
|
match decl.type_manifest with
|
|
|
|
None -> unify_var
|
|
|
|
| Some ty ->
|
|
|
|
if (repr ty).level = Btype.generic_level then unify_var else unify
|
|
|
|
in
|
1997-02-20 12:39:02 -08:00
|
|
|
List.iter2
|
2012-05-30 07:52:37 -07:00
|
|
|
(fun (sty, cty) ty' ->
|
|
|
|
try unify_param env ty' cty.ctyp_type with Unify trace ->
|
2013-01-29 06:21:12 -08:00
|
|
|
raise (Error(sty.ptyp_loc, env, Type_mismatch (swap_list trace))))
|
1997-02-20 12:39:02 -08:00
|
|
|
(List.combine stl args) params;
|
2012-05-31 01:07:31 -07:00
|
|
|
let constr =
|
|
|
|
newconstr path (List.map (fun ctyp -> ctyp.ctyp_type) args) in
|
2003-06-30 01:04:42 -07:00
|
|
|
begin try
|
|
|
|
Ctype.enforce_constraints env constr
|
|
|
|
with Unify trace ->
|
2013-01-29 06:21:12 -08:00
|
|
|
raise (Error(styp.ptyp_loc, env, Type_mismatch trace))
|
2003-06-30 01:04:42 -07:00
|
|
|
end;
|
2013-03-25 07:16:07 -07:00
|
|
|
ctyp (Ttyp_constr (path, lid, args)) constr
|
2013-04-09 06:29:00 -07:00
|
|
|
| Ptyp_object (fields, o) ->
|
|
|
|
let fields =
|
2014-05-05 04:21:45 -07:00
|
|
|
List.map (fun (s, a, t) -> (s, a, transl_poly_type env policy t))
|
2013-04-09 06:29:00 -07:00
|
|
|
fields
|
|
|
|
in
|
|
|
|
let ty = newobj (transl_fields loc env policy [] o fields) in
|
|
|
|
ctyp (Ttyp_object (fields, o)) ty
|
2013-04-16 05:17:17 -07:00
|
|
|
| Ptyp_class(lid, stl) ->
|
1999-11-30 08:07:38 -08:00
|
|
|
let (path, decl, is_variant) =
|
1996-04-22 04:15:41 -07:00
|
|
|
try
|
2012-05-30 07:52:37 -07:00
|
|
|
let (path, decl) = Env.lookup_type lid.txt env in
|
2001-09-19 06:09:42 -07:00
|
|
|
let rec check decl =
|
|
|
|
match decl.type_manifest with
|
|
|
|
None -> raise Not_found
|
|
|
|
| Some ty ->
|
|
|
|
match (repr ty).desc with
|
|
|
|
Tvariant row when Btype.static_row row -> ()
|
|
|
|
| Tconstr (path, _, _) ->
|
|
|
|
check (Env.find_type path env)
|
|
|
|
| _ -> raise Not_found
|
|
|
|
in check decl;
|
2013-05-28 04:05:58 -07:00
|
|
|
Location.prerr_warning styp.ptyp_loc
|
|
|
|
(Warnings.Deprecated "old syntax for polymorphic variant type");
|
2001-09-19 06:09:42 -07:00
|
|
|
(path, decl,true)
|
1999-11-30 08:07:38 -08:00
|
|
|
with Not_found -> try
|
|
|
|
let lid2 =
|
2012-05-30 07:52:37 -07:00
|
|
|
match lid.txt with
|
1999-11-30 08:07:38 -08:00
|
|
|
Longident.Lident s -> Longident.Lident ("#" ^ s)
|
|
|
|
| Longident.Ldot(r, s) -> Longident.Ldot (r, "#" ^ s)
|
|
|
|
| Longident.Lapply(_, _) -> fatal_error "Typetexp.transl_type"
|
|
|
|
in
|
|
|
|
let (path, decl) = Env.lookup_type lid2 env in
|
|
|
|
(path, decl, false)
|
1996-04-22 04:15:41 -07:00
|
|
|
with Not_found ->
|
2014-04-28 06:29:51 -07:00
|
|
|
ignore (find_class env styp.ptyp_loc lid.txt); assert false
|
1999-11-30 08:07:38 -08:00
|
|
|
in
|
1996-04-22 04:15:41 -07:00
|
|
|
if List.length stl <> decl.type_arity then
|
2013-01-29 06:21:12 -08:00
|
|
|
raise(Error(styp.ptyp_loc, env,
|
2013-05-28 04:05:58 -07:00
|
|
|
Type_arity_mismatch(lid.txt, decl.type_arity,
|
2013-01-29 06:21:12 -08:00
|
|
|
List.length stl)));
|
2003-05-19 02:21:17 -07:00
|
|
|
let args = List.map (transl_type env policy) stl in
|
2011-11-24 01:02:48 -08:00
|
|
|
let params = instance_list decl.type_params in
|
1997-02-20 12:39:02 -08:00
|
|
|
List.iter2
|
2012-05-30 07:52:37 -07:00
|
|
|
(fun (sty, cty) ty' ->
|
|
|
|
try unify_var env ty' cty.ctyp_type with Unify trace ->
|
2013-01-29 06:21:12 -08:00
|
|
|
raise (Error(sty.ptyp_loc, env, Type_mismatch (swap_list trace))))
|
1997-02-20 12:39:02 -08:00
|
|
|
(List.combine stl args) params;
|
2012-07-30 11:04:46 -07:00
|
|
|
let ty_args = List.map (fun ctyp -> ctyp.ctyp_type) args in
|
2003-06-30 01:04:42 -07:00
|
|
|
let ty =
|
2012-05-30 07:52:37 -07:00
|
|
|
try Ctype.expand_head env (newconstr path ty_args)
|
2003-06-30 01:04:42 -07:00
|
|
|
with Unify trace ->
|
2013-01-29 06:21:12 -08:00
|
|
|
raise (Error(styp.ptyp_loc, env, Type_mismatch trace))
|
2003-06-30 01:04:42 -07:00
|
|
|
in
|
2012-05-30 07:52:37 -07:00
|
|
|
let ty = match ty.desc with
|
1999-11-30 08:07:38 -08:00
|
|
|
Tvariant row ->
|
|
|
|
let row = Btype.row_repr row in
|
|
|
|
let fields =
|
|
|
|
List.map
|
|
|
|
(fun (l,f) -> l,
|
|
|
|
match Btype.row_field_repr f with
|
|
|
|
| Rpresent (Some ty) ->
|
2003-05-19 02:21:17 -07:00
|
|
|
Reither(false, [ty], false, ref None)
|
1999-11-30 08:07:38 -08:00
|
|
|
| Rpresent None ->
|
2003-05-19 02:21:17 -07:00
|
|
|
Reither (true, [], false, ref None)
|
1999-11-30 08:07:38 -08:00
|
|
|
| _ -> f)
|
|
|
|
row.row_fields
|
|
|
|
in
|
2002-06-09 19:39:35 -07:00
|
|
|
let row = { row_closed = true; row_fields = fields;
|
2012-05-30 07:52:37 -07:00
|
|
|
row_bound = (); row_name = Some (path, ty_args);
|
2003-05-19 02:21:17 -07:00
|
|
|
row_fixed = false; row_more = newvar () } in
|
2002-06-09 19:39:35 -07:00
|
|
|
let static = Btype.static_row row in
|
|
|
|
let row =
|
2011-11-24 01:02:48 -08:00
|
|
|
if static then { row with row_more = newty Tnil }
|
|
|
|
else if policy <> Univars then row
|
2007-10-08 07:19:34 -07:00
|
|
|
else { row with row_more = new_pre_univar () }
|
2003-05-19 02:21:17 -07:00
|
|
|
in
|
2002-06-09 19:39:35 -07:00
|
|
|
newty (Tvariant row)
|
2002-04-18 00:27:47 -07:00
|
|
|
| Tobject (fi, _) ->
|
|
|
|
let _, tv = flatten_fields fi in
|
|
|
|
if policy = Univars then pre_univars := tv :: !pre_univars;
|
1999-11-30 08:07:38 -08:00
|
|
|
ty
|
2002-04-18 00:27:47 -07:00
|
|
|
| _ ->
|
|
|
|
assert false
|
2012-05-30 07:52:37 -07:00
|
|
|
in
|
2013-04-16 05:17:17 -07:00
|
|
|
ctyp (Ttyp_class (path, lid, args)) ty
|
1997-03-07 14:26:29 -08:00
|
|
|
| Ptyp_alias(st, alias) ->
|
2012-05-30 07:52:37 -07:00
|
|
|
let cty =
|
2002-04-18 00:27:47 -07:00
|
|
|
try
|
2002-06-03 00:33:48 -07:00
|
|
|
let t =
|
2003-05-19 02:21:17 -07:00
|
|
|
try List.assoc alias !univars
|
|
|
|
with Not_found ->
|
2011-11-24 01:02:48 -08:00
|
|
|
instance env (fst(Tbl.find alias !used_variables))
|
2002-06-03 00:33:48 -07:00
|
|
|
in
|
2003-05-19 02:21:17 -07:00
|
|
|
let ty = transl_type env policy st in
|
2012-05-30 07:52:37 -07:00
|
|
|
begin try unify_var env t ty.ctyp_type with Unify trace ->
|
2002-04-18 00:27:47 -07:00
|
|
|
let trace = swap_list trace in
|
2013-01-29 06:21:12 -08:00
|
|
|
raise(Error(styp.ptyp_loc, env, Alias_type_mismatch trace))
|
2002-04-18 00:27:47 -07:00
|
|
|
end;
|
|
|
|
ty
|
|
|
|
with Not_found ->
|
2006-12-21 04:07:53 -08:00
|
|
|
if !Clflags.principal then begin_def ();
|
2002-04-18 00:27:47 -07:00
|
|
|
let t = newvar () in
|
2005-07-21 21:11:47 -07:00
|
|
|
used_variables := Tbl.add alias (t, styp.ptyp_loc) !used_variables;
|
2003-05-19 02:21:17 -07:00
|
|
|
let ty = transl_type env policy st in
|
2012-05-30 07:52:37 -07:00
|
|
|
begin try unify_var env t ty.ctyp_type with Unify trace ->
|
2002-04-18 00:27:47 -07:00
|
|
|
let trace = swap_list trace in
|
2013-01-29 06:21:12 -08:00
|
|
|
raise(Error(styp.ptyp_loc, env, Alias_type_mismatch trace))
|
2002-04-18 00:27:47 -07:00
|
|
|
end;
|
2006-12-21 04:07:53 -08:00
|
|
|
if !Clflags.principal then begin
|
|
|
|
end_def ();
|
|
|
|
generalize_structure t;
|
|
|
|
end;
|
2011-11-24 01:02:48 -08:00
|
|
|
let t = instance env t in
|
2011-09-22 02:05:42 -07:00
|
|
|
let px = Btype.proxy t in
|
|
|
|
begin match px.desc with
|
|
|
|
| Tvar None -> Btype.log_type px; px.desc <- Tvar (Some alias)
|
|
|
|
| Tunivar None -> Btype.log_type px; px.desc <- Tunivar (Some alias)
|
|
|
|
| _ -> ()
|
|
|
|
end;
|
2012-05-30 07:52:37 -07:00
|
|
|
{ ty with ctyp_type = t }
|
|
|
|
in
|
2013-03-25 07:16:07 -07:00
|
|
|
ctyp (Ttyp_alias (cty, alias)) cty.ctyp_type
|
1999-11-30 08:07:38 -08:00
|
|
|
| Ptyp_variant(fields, closed, present) ->
|
2008-01-11 08:13:18 -08:00
|
|
|
let name = ref None in
|
2001-09-25 02:54:18 -07:00
|
|
|
let mkfield l f =
|
2002-06-09 19:39:35 -07:00
|
|
|
newty (Tvariant {row_fields=[l,f]; row_more=newvar();
|
2008-01-11 08:13:18 -08:00
|
|
|
row_bound=(); row_closed=true;
|
2003-05-19 02:21:17 -07:00
|
|
|
row_fixed=false; row_name=None}) in
|
2008-01-11 08:13:18 -08:00
|
|
|
let hfields = Hashtbl.create 17 in
|
|
|
|
let add_typed_field loc l f =
|
|
|
|
let h = Btype.hash_variant l in
|
2001-09-25 02:54:18 -07:00
|
|
|
try
|
2008-01-11 08:13:18 -08:00
|
|
|
let (l',f') = Hashtbl.find hfields h in
|
|
|
|
(* Check for tag conflicts *)
|
2013-01-29 06:21:12 -08:00
|
|
|
if l <> l' then raise(Error(styp.ptyp_loc, env, Variant_tags(l, l')));
|
2001-09-25 02:54:18 -07:00
|
|
|
let ty = mkfield l f and ty' = mkfield l f' in
|
2008-01-11 08:13:18 -08:00
|
|
|
if equal env false [ty] [ty'] then () else
|
|
|
|
try unify env ty ty'
|
2012-01-22 23:59:45 -08:00
|
|
|
with Unify trace ->
|
2013-01-29 06:21:12 -08:00
|
|
|
raise(Error(loc, env, Constructor_mismatch (ty,ty')))
|
2001-09-25 02:54:18 -07:00
|
|
|
with Not_found ->
|
2008-01-11 08:13:18 -08:00
|
|
|
Hashtbl.add hfields h (l,f)
|
1999-11-30 08:07:38 -08:00
|
|
|
in
|
2012-05-29 06:41:14 -07:00
|
|
|
let add_field = function
|
2014-04-30 01:19:55 -07:00
|
|
|
Rtag (l, attrs, c, stl) ->
|
2001-09-25 02:54:18 -07:00
|
|
|
name := None;
|
2012-05-30 07:52:37 -07:00
|
|
|
let tl = List.map (transl_type env policy) stl in
|
2001-09-25 02:54:18 -07:00
|
|
|
let f = match present with
|
2005-06-12 18:11:02 -07:00
|
|
|
Some present when not (List.mem l present) ->
|
2012-07-30 11:04:46 -07:00
|
|
|
let ty_tl = List.map (fun cty -> cty.ctyp_type) tl in
|
2012-05-30 07:52:37 -07:00
|
|
|
Reither(c, ty_tl, false, ref None)
|
2001-09-25 02:54:18 -07:00
|
|
|
| _ ->
|
|
|
|
if List.length stl > 1 || c && stl <> [] then
|
2013-01-29 06:21:12 -08:00
|
|
|
raise(Error(styp.ptyp_loc, env, Present_has_conjunction l));
|
2012-05-30 07:52:37 -07:00
|
|
|
match tl with [] -> Rpresent None
|
|
|
|
| st :: _ ->
|
2012-07-30 11:04:46 -07:00
|
|
|
Rpresent (Some st.ctyp_type)
|
2001-09-25 02:54:18 -07:00
|
|
|
in
|
2012-05-30 07:52:37 -07:00
|
|
|
add_typed_field styp.ptyp_loc l f;
|
2014-04-30 01:19:55 -07:00
|
|
|
Ttag (l,attrs,c,tl)
|
2001-09-25 02:54:18 -07:00
|
|
|
| Rinherit sty ->
|
2012-05-30 07:52:37 -07:00
|
|
|
let cty = transl_type env policy sty in
|
2012-07-30 11:04:46 -07:00
|
|
|
let ty = cty.ctyp_type in
|
2001-11-27 18:14:39 -08:00
|
|
|
let nm =
|
2012-05-30 07:52:37 -07:00
|
|
|
match repr cty.ctyp_type with
|
2001-11-27 18:14:39 -08:00
|
|
|
{desc=Tconstr(p, tl, _)} -> Some(p, tl)
|
|
|
|
| _ -> None
|
|
|
|
in
|
2008-01-11 08:13:18 -08:00
|
|
|
begin try
|
|
|
|
(* Set name if there are no fields yet *)
|
|
|
|
Hashtbl.iter (fun _ _ -> raise Exit) hfields;
|
|
|
|
name := nm
|
|
|
|
with Exit ->
|
|
|
|
(* Unset it otherwise *)
|
|
|
|
name := None
|
|
|
|
end;
|
2012-05-30 07:52:37 -07:00
|
|
|
let fl = match expand_head env cty.ctyp_type, nm with
|
2001-11-27 18:14:39 -08:00
|
|
|
{desc=Tvariant row}, _ when Btype.static_row row ->
|
2001-09-25 02:54:18 -07:00
|
|
|
let row = Btype.row_repr row in
|
|
|
|
row.row_fields
|
2011-09-22 02:05:42 -07:00
|
|
|
| {desc=Tvar _}, Some(p, _) ->
|
2013-01-29 06:21:12 -08:00
|
|
|
raise(Error(sty.ptyp_loc, env, Unbound_type_constructor_2 p))
|
2001-11-27 18:14:39 -08:00
|
|
|
| _ ->
|
2013-01-29 06:21:12 -08:00
|
|
|
raise(Error(sty.ptyp_loc, env, Not_a_variant ty))
|
2001-09-25 02:54:18 -07:00
|
|
|
in
|
2008-01-11 08:13:18 -08:00
|
|
|
List.iter
|
|
|
|
(fun (l, f) ->
|
2001-09-25 02:54:18 -07:00
|
|
|
let f = match present with
|
2005-06-12 18:11:02 -07:00
|
|
|
Some present when not (List.mem l present) ->
|
2001-09-25 02:54:18 -07:00
|
|
|
begin match f with
|
|
|
|
Rpresent(Some ty) ->
|
2003-05-19 02:21:17 -07:00
|
|
|
Reither(false, [ty], false, ref None)
|
2001-09-25 02:54:18 -07:00
|
|
|
| Rpresent None ->
|
2003-05-19 02:21:17 -07:00
|
|
|
Reither(true, [], false, ref None)
|
2001-09-25 02:54:18 -07:00
|
|
|
| _ ->
|
|
|
|
assert false
|
|
|
|
end
|
|
|
|
| _ -> f
|
|
|
|
in
|
2008-01-11 08:13:18 -08:00
|
|
|
add_typed_field sty.ptyp_loc l f)
|
2012-05-30 07:52:37 -07:00
|
|
|
fl;
|
2012-07-30 11:04:46 -07:00
|
|
|
Tinherit cty
|
2001-09-25 02:54:18 -07:00
|
|
|
in
|
2012-05-30 07:52:37 -07:00
|
|
|
let tfields = List.map add_field fields in
|
2008-01-11 08:13:18 -08:00
|
|
|
let fields = Hashtbl.fold (fun _ p l -> p :: l) hfields [] in
|
2001-09-25 02:54:18 -07:00
|
|
|
begin match present with None -> ()
|
|
|
|
| Some present ->
|
|
|
|
List.iter
|
|
|
|
(fun l -> if not (List.mem_assoc l fields) then
|
2013-01-29 06:21:12 -08:00
|
|
|
raise(Error(styp.ptyp_loc, env, Present_has_no_type l)))
|
2001-09-25 02:54:18 -07:00
|
|
|
present
|
|
|
|
end;
|
1999-11-30 08:07:38 -08:00
|
|
|
let row =
|
2001-09-25 02:54:18 -07:00
|
|
|
{ row_fields = List.rev fields; row_more = newvar ();
|
2013-04-12 09:08:52 -07:00
|
|
|
row_bound = (); row_closed = (closed = Closed);
|
2003-05-19 02:21:17 -07:00
|
|
|
row_fixed = false; row_name = !name } in
|
2002-04-18 00:27:47 -07:00
|
|
|
let static = Btype.static_row row in
|
|
|
|
let row =
|
2011-11-24 01:02:48 -08:00
|
|
|
if static then { row with row_more = newty Tnil }
|
|
|
|
else if policy <> Univars then row
|
2009-07-20 04:51:50 -07:00
|
|
|
else { row with row_more = new_pre_univar () }
|
2007-10-08 07:19:34 -07:00
|
|
|
in
|
2012-05-30 07:52:37 -07:00
|
|
|
let ty = newty (Tvariant row) in
|
2013-03-25 07:16:07 -07:00
|
|
|
ctyp (Ttyp_variant (tfields, closed, present)) ty
|
2012-05-30 07:52:37 -07:00
|
|
|
| Ptyp_poly(vars, st) ->
|
2003-05-19 02:21:17 -07:00
|
|
|
begin_def();
|
2011-09-22 02:05:42 -07:00
|
|
|
let new_univars = List.map (fun name -> name, newvar ~name ()) vars in
|
2002-04-18 00:27:47 -07:00
|
|
|
let old_univars = !univars in
|
|
|
|
univars := new_univars @ !univars;
|
2012-05-30 07:52:37 -07:00
|
|
|
let cty = transl_type env policy st in
|
|
|
|
let ty = cty.ctyp_type in
|
2002-04-18 00:27:47 -07:00
|
|
|
univars := old_univars;
|
2003-05-19 02:21:17 -07:00
|
|
|
end_def();
|
|
|
|
generalize ty;
|
|
|
|
let ty_list =
|
|
|
|
List.fold_left
|
|
|
|
(fun tyl (name, ty1) ->
|
|
|
|
let v = Btype.proxy ty1 in
|
|
|
|
if deep_occur v ty then begin
|
2011-09-22 02:05:42 -07:00
|
|
|
match v.desc with
|
|
|
|
Tvar name when v.level = Btype.generic_level ->
|
|
|
|
v.desc <- Tunivar name;
|
|
|
|
v :: tyl
|
|
|
|
| _ ->
|
2013-01-29 06:21:12 -08:00
|
|
|
raise (Error (styp.ptyp_loc, env, Cannot_quantify (name, v)))
|
2003-05-19 02:21:17 -07:00
|
|
|
end else tyl)
|
|
|
|
[] new_univars
|
|
|
|
in
|
|
|
|
let ty' = Btype.newgenty (Tpoly(ty, List.rev ty_list)) in
|
|
|
|
unify_var env (newvar()) ty';
|
2013-03-25 07:16:07 -07:00
|
|
|
ctyp (Ttyp_poly (vars, cty)) ty'
|
2009-10-26 03:53:16 -07:00
|
|
|
| Ptyp_package (p, l) ->
|
|
|
|
let l, mty = create_package_mty true styp.ptyp_loc env (p, l) in
|
|
|
|
let z = narrow () in
|
2012-05-30 07:52:37 -07:00
|
|
|
let mty = !transl_modtype env mty in
|
2009-10-26 03:53:16 -07:00
|
|
|
widen z;
|
2012-05-30 07:52:37 -07:00
|
|
|
let ptys = List.map (fun (s, pty) ->
|
2012-07-30 11:04:46 -07:00
|
|
|
s, transl_type env policy pty
|
|
|
|
) l in
|
2012-05-30 07:52:37 -07:00
|
|
|
let path = !transl_modtype_longident styp.ptyp_loc env p.txt in
|
|
|
|
let ty = newty (Tpackage (path,
|
|
|
|
List.map (fun (s, pty) -> s.txt) l,
|
|
|
|
List.map (fun (_,cty) -> cty.ctyp_type) ptys))
|
|
|
|
in
|
2013-03-25 07:16:07 -07:00
|
|
|
ctyp (Ttyp_package {
|
2014-05-04 16:08:45 -07:00
|
|
|
pack_path = path;
|
2013-03-25 07:16:07 -07:00
|
|
|
pack_type = mty.mty_type;
|
|
|
|
pack_fields = ptys;
|
|
|
|
pack_txt = p;
|
|
|
|
}) ty
|
2014-05-07 01:26:17 -07:00
|
|
|
| Ptyp_extension ext ->
|
2015-12-02 05:46:14 -08:00
|
|
|
raise (Error_forward (Builtin_attributes.error_of_extension ext))
|
1996-04-22 04:15:41 -07:00
|
|
|
|
2013-04-09 07:10:54 -07:00
|
|
|
and transl_poly_type env policy t =
|
|
|
|
transl_type env policy (Ast_helper.Typ.force_poly t)
|
|
|
|
|
2013-04-09 06:29:00 -07:00
|
|
|
and transl_fields loc env policy seen o =
|
1996-04-22 04:15:41 -07:00
|
|
|
function
|
|
|
|
[] ->
|
2013-04-09 06:29:00 -07:00
|
|
|
begin match o, policy with
|
|
|
|
| Closed, _ -> newty Tnil
|
|
|
|
| Open, Univars -> new_pre_univar ()
|
|
|
|
| Open, _ -> newvar ()
|
|
|
|
end
|
2014-05-05 04:21:45 -07:00
|
|
|
| (s, _attrs, ty1) :: l ->
|
2013-01-29 06:21:12 -08:00
|
|
|
if List.mem s seen then raise (Error (loc, env, Repeated_method_label s));
|
2013-04-09 06:29:00 -07:00
|
|
|
let ty2 = transl_fields loc env policy (s :: seen) o l in
|
|
|
|
newty (Tfield (s, Fpresent, ty1.ctyp_type, ty2))
|
2003-05-19 02:21:17 -07:00
|
|
|
|
|
|
|
(* Make the rows "fixed" in this type, to make universal check easier *)
|
|
|
|
let rec make_fixed_univars ty =
|
|
|
|
let ty = repr ty in
|
|
|
|
if ty.level >= Btype.lowest_level then begin
|
|
|
|
Btype.mark_type_node ty;
|
|
|
|
match ty.desc with
|
|
|
|
| Tvariant row ->
|
|
|
|
let row = Btype.row_repr row in
|
2011-09-22 02:05:42 -07:00
|
|
|
if Btype.is_Tunivar (Btype.row_more row) then
|
2003-05-19 02:21:17 -07:00
|
|
|
ty.desc <- Tvariant
|
|
|
|
{row with row_fixed=true;
|
|
|
|
row_fields = List.map
|
|
|
|
(fun (s,f as p) -> match Btype.row_field_repr f with
|
|
|
|
Reither (c, tl, m, r) -> s, Reither (c, tl, true, r)
|
|
|
|
| _ -> p)
|
|
|
|
row.row_fields};
|
|
|
|
Btype.iter_row make_fixed_univars row
|
|
|
|
| _ ->
|
|
|
|
Btype.iter_type_expr make_fixed_univars ty
|
|
|
|
end
|
|
|
|
|
|
|
|
let make_fixed_univars ty =
|
|
|
|
make_fixed_univars ty;
|
|
|
|
Btype.unmark_type ty
|
|
|
|
|
2009-10-26 03:53:16 -07:00
|
|
|
let create_package_mty = create_package_mty false
|
|
|
|
|
2005-07-21 23:42:36 -07:00
|
|
|
let globalize_used_variables env fixed =
|
|
|
|
let r = ref [] in
|
2005-07-21 21:11:47 -07:00
|
|
|
Tbl.iter
|
|
|
|
(fun name (ty, loc) ->
|
|
|
|
let v = new_global_var () in
|
|
|
|
let snap = Btype.snapshot () in
|
|
|
|
if try unify env v ty; true with _ -> Btype.backtrack snap; false
|
|
|
|
then try
|
2005-07-21 23:42:36 -07:00
|
|
|
r := (loc, v, Tbl.find name !type_variables) :: !r
|
|
|
|
with Not_found ->
|
2011-09-22 02:05:42 -07:00
|
|
|
if fixed && Btype.is_Tvar (repr ty) then
|
2013-01-29 06:21:12 -08:00
|
|
|
raise(Error(loc, env, Unbound_type_variable ("'"^name)));
|
2005-07-21 23:42:36 -07:00
|
|
|
let v2 = new_global_var () in
|
|
|
|
r := (loc, v, v2) :: !r;
|
|
|
|
type_variables := Tbl.add name v2 !type_variables)
|
2005-07-21 21:11:47 -07:00
|
|
|
!used_variables;
|
2005-07-21 23:42:36 -07:00
|
|
|
used_variables := Tbl.empty;
|
|
|
|
fun () ->
|
|
|
|
List.iter
|
|
|
|
(function (loc, t1, t2) ->
|
|
|
|
try unify env t1 t2 with Unify trace ->
|
2013-01-29 06:21:12 -08:00
|
|
|
raise (Error(loc, env, Type_mismatch trace)))
|
2005-07-21 23:42:36 -07:00
|
|
|
!r
|
2005-07-21 21:11:47 -07:00
|
|
|
|
1997-01-20 09:11:47 -08:00
|
|
|
let transl_simple_type env fixed styp =
|
2005-07-21 21:11:47 -07:00
|
|
|
univars := []; used_variables := Tbl.empty;
|
2003-05-19 02:21:17 -07:00
|
|
|
let typ = transl_type env (if fixed then Fixed else Extensible) styp in
|
2005-07-21 23:42:36 -07:00
|
|
|
globalize_used_variables env fixed ();
|
2012-05-30 07:52:37 -07:00
|
|
|
make_fixed_univars typ.ctyp_type;
|
1997-01-20 09:11:47 -08:00
|
|
|
typ
|
|
|
|
|
2002-04-18 00:27:47 -07:00
|
|
|
let transl_simple_type_univars env styp =
|
2005-07-21 21:11:47 -07:00
|
|
|
univars := []; used_variables := Tbl.empty; pre_univars := [];
|
2002-04-18 00:27:47 -07:00
|
|
|
begin_def ();
|
2003-05-19 02:21:17 -07:00
|
|
|
let typ = transl_type env Univars styp in
|
2005-07-21 21:11:47 -07:00
|
|
|
(* Only keep already global variables in used_variables *)
|
|
|
|
let new_variables = !used_variables in
|
|
|
|
used_variables := Tbl.empty;
|
|
|
|
Tbl.iter
|
|
|
|
(fun name p ->
|
|
|
|
if Tbl.mem name !type_variables then
|
|
|
|
used_variables := Tbl.add name p !used_variables)
|
|
|
|
new_variables;
|
2005-07-21 23:42:36 -07:00
|
|
|
globalize_used_variables env false ();
|
2002-04-18 00:27:47 -07:00
|
|
|
end_def ();
|
2012-05-30 07:52:37 -07:00
|
|
|
generalize typ.ctyp_type;
|
2002-04-18 00:27:47 -07:00
|
|
|
let univs =
|
|
|
|
List.fold_left
|
|
|
|
(fun acc v ->
|
|
|
|
let v = repr v in
|
2011-09-22 02:05:42 -07:00
|
|
|
match v.desc with
|
|
|
|
Tvar name when v.level = Btype.generic_level ->
|
|
|
|
v.desc <- Tunivar name; v :: acc
|
|
|
|
| _ -> acc)
|
2002-04-18 00:27:47 -07:00
|
|
|
[] !pre_univars
|
|
|
|
in
|
2012-05-30 07:52:37 -07:00
|
|
|
make_fixed_univars typ.ctyp_type;
|
|
|
|
{ typ with ctyp_type =
|
2012-07-30 11:04:46 -07:00
|
|
|
instance env (Btype.newgenty (Tpoly (typ.ctyp_type, univs))) }
|
2002-04-18 00:27:47 -07:00
|
|
|
|
1997-01-20 09:11:47 -08:00
|
|
|
let transl_simple_type_delayed env styp =
|
2005-07-21 21:11:47 -07:00
|
|
|
univars := []; used_variables := Tbl.empty;
|
|
|
|
let typ = transl_type env Extensible styp in
|
2012-05-30 07:52:37 -07:00
|
|
|
make_fixed_univars typ.ctyp_type;
|
2005-07-21 23:42:36 -07:00
|
|
|
(typ, globalize_used_variables env false)
|
1997-01-20 09:11:47 -08:00
|
|
|
|
1995-05-04 03:15:53 -07:00
|
|
|
let transl_type_scheme env styp =
|
|
|
|
reset_type_variables();
|
|
|
|
begin_def();
|
|
|
|
let typ = transl_simple_type env false styp in
|
|
|
|
end_def();
|
2012-05-30 07:52:37 -07:00
|
|
|
generalize typ.ctyp_type;
|
1995-05-04 03:15:53 -07:00
|
|
|
typ
|
|
|
|
|
2010-05-18 09:46:46 -07:00
|
|
|
|
1995-05-04 03:15:53 -07:00
|
|
|
(* Error report *)
|
|
|
|
|
2000-03-06 14:12:09 -08:00
|
|
|
open Format
|
1995-05-04 03:15:53 -07:00
|
|
|
open Printtyp
|
|
|
|
|
2012-10-16 06:54:24 -07:00
|
|
|
let spellcheck ppf fold env lid =
|
2014-12-13 06:46:16 -08:00
|
|
|
let choices ~path name =
|
|
|
|
let env = fold (fun x xs -> x::xs) path env [] in
|
|
|
|
Misc.spellcheck env name in
|
2012-10-16 06:54:24 -07:00
|
|
|
match lid with
|
|
|
|
| Longident.Lapply _ -> ()
|
|
|
|
| Longident.Lident s ->
|
2014-12-13 06:46:16 -08:00
|
|
|
Misc.did_you_mean ppf (fun () -> choices ~path:None s)
|
2012-10-16 06:54:24 -07:00
|
|
|
| Longident.Ldot (r, s) ->
|
2014-12-13 06:46:16 -08:00
|
|
|
Misc.did_you_mean ppf (fun () -> choices ~path:(Some r) s)
|
2012-10-24 05:03:00 -07:00
|
|
|
|
2014-12-13 06:46:16 -08:00
|
|
|
let fold_descr fold get_name f = fold (fun descr acc -> f (get_name descr) acc)
|
|
|
|
let fold_simple fold4 f = fold4 (fun name _path _descr acc -> f name acc)
|
2012-10-24 05:03:00 -07:00
|
|
|
|
2014-12-13 06:46:16 -08:00
|
|
|
let fold_values = fold_simple Env.fold_values
|
|
|
|
let fold_types = fold_simple Env.fold_types
|
|
|
|
let fold_modules = fold_simple Env.fold_modules
|
|
|
|
let fold_constructors = fold_descr Env.fold_constructors (fun d -> d.cstr_name)
|
|
|
|
let fold_labels = fold_descr Env.fold_labels (fun d -> d.lbl_name)
|
|
|
|
let fold_classs = fold_simple Env.fold_classs
|
|
|
|
let fold_modtypes = fold_simple Env.fold_modtypes
|
|
|
|
let fold_cltypes = fold_simple Env.fold_cltypes
|
2012-10-31 20:32:34 -07:00
|
|
|
|
2013-01-29 06:21:12 -08:00
|
|
|
let report_error env ppf = function
|
2000-03-06 14:12:09 -08:00
|
|
|
| Unbound_type_variable name ->
|
2014-12-13 06:46:22 -08:00
|
|
|
(* we don't use "spellcheck" here: the function that raises this
|
|
|
|
error seems not to be called anywhere, so it's unclear how it
|
|
|
|
should be handled *)
|
2012-10-16 06:54:24 -07:00
|
|
|
fprintf ppf "Unbound type parameter %s@." name
|
1995-05-04 03:15:53 -07:00
|
|
|
| Unbound_type_constructor lid ->
|
2012-10-16 06:54:24 -07:00
|
|
|
fprintf ppf "Unbound type constructor %a" longident lid;
|
2014-12-13 06:46:16 -08:00
|
|
|
spellcheck ppf fold_types env lid;
|
2001-11-27 18:14:39 -08:00
|
|
|
| Unbound_type_constructor_2 p ->
|
2012-10-16 06:54:24 -07:00
|
|
|
fprintf ppf "The type constructor@ %a@ is not yet completely defined"
|
|
|
|
path p
|
1995-05-04 03:15:53 -07:00
|
|
|
| Type_arity_mismatch(lid, expected, provided) ->
|
2012-10-16 06:54:24 -07:00
|
|
|
fprintf ppf
|
|
|
|
"@[The type constructor %a@ expects %i argument(s),@ \
|
2000-03-06 14:12:09 -08:00
|
|
|
but is here applied to %i argument(s)@]"
|
2012-10-16 06:54:24 -07:00
|
|
|
longident lid expected provided
|
1996-04-22 04:15:41 -07:00
|
|
|
| Bound_type_variable name ->
|
2012-10-16 06:54:24 -07:00
|
|
|
fprintf ppf "Already bound type parameter '%s" name
|
1996-04-22 04:15:41 -07:00
|
|
|
| Recursive_type ->
|
2012-10-16 06:54:24 -07:00
|
|
|
fprintf ppf "This type is recursive"
|
1996-04-22 04:15:41 -07:00
|
|
|
| Unbound_row_variable lid ->
|
2012-10-16 06:54:24 -07:00
|
|
|
(* we don't use "spellcheck" here: this error is not raised
|
|
|
|
anywhere so it's unclear how it should be handled *)
|
2000-03-06 14:12:09 -08:00
|
|
|
fprintf ppf "Unbound row variable in #%a" longident lid
|
1997-02-20 12:39:02 -08:00
|
|
|
| Type_mismatch trace ->
|
2013-01-29 06:21:12 -08:00
|
|
|
Printtyp.report_unification_error ppf Env.empty trace
|
2000-03-06 14:12:09 -08:00
|
|
|
(function ppf ->
|
|
|
|
fprintf ppf "This type")
|
|
|
|
(function ppf ->
|
|
|
|
fprintf ppf "should be an instance of type")
|
1997-02-20 12:39:02 -08:00
|
|
|
| Alias_type_mismatch trace ->
|
2013-01-29 06:21:12 -08:00
|
|
|
Printtyp.report_unification_error ppf Env.empty trace
|
2000-03-06 14:12:09 -08:00
|
|
|
(function ppf ->
|
|
|
|
fprintf ppf "This alias is bound to type")
|
|
|
|
(function ppf ->
|
|
|
|
fprintf ppf "but is used as an instance of type")
|
1999-11-30 08:07:38 -08:00
|
|
|
| Present_has_conjunction l ->
|
2000-03-06 14:12:09 -08:00
|
|
|
fprintf ppf "The present constructor %s has a conjunctive type" l
|
1999-11-30 08:07:38 -08:00
|
|
|
| Present_has_no_type l ->
|
2000-03-06 14:12:09 -08:00
|
|
|
fprintf ppf "The present constructor %s has no type" l
|
2001-09-25 02:54:18 -07:00
|
|
|
| Constructor_mismatch (ty, ty') ->
|
2013-01-29 06:21:12 -08:00
|
|
|
wrap_printing_env env (fun () ->
|
2014-04-12 03:17:02 -07:00
|
|
|
Printtyp.reset_and_mark_loops_list [ty; ty'];
|
|
|
|
fprintf ppf "@[<hov>%s %a@ %s@ %a@]"
|
2012-01-22 23:59:45 -08:00
|
|
|
"This variant type contains a constructor"
|
|
|
|
Printtyp.type_expr ty
|
|
|
|
"which should be"
|
|
|
|
Printtyp.type_expr ty')
|
2001-09-25 02:54:18 -07:00
|
|
|
| Not_a_variant ty ->
|
|
|
|
Printtyp.reset_and_mark_loops ty;
|
|
|
|
fprintf ppf "@[The type %a@ is not a polymorphic variant type@]"
|
2015-10-17 06:46:02 -07:00
|
|
|
Printtyp.type_expr ty;
|
|
|
|
begin match ty.desc with
|
|
|
|
| Tvar (Some s) ->
|
|
|
|
(* PR#7012: help the user that wrote 'Foo instead of `Foo *)
|
|
|
|
Misc.did_you_mean ppf (fun () -> ["`" ^ s])
|
|
|
|
| _ -> ()
|
|
|
|
end
|
2002-01-03 18:02:50 -08:00
|
|
|
| Variant_tags (lab1, lab2) ->
|
|
|
|
fprintf ppf
|
2011-11-24 01:02:48 -08:00
|
|
|
"@[Variant tags `%s@ and `%s have the same hash value.@ %s@]"
|
|
|
|
lab1 lab2 "Change one of them."
|
2003-03-07 00:59:15 -08:00
|
|
|
| Invalid_variable_name name ->
|
|
|
|
fprintf ppf "The type variable name %s is not allowed in programs" name
|
2003-05-19 02:21:17 -07:00
|
|
|
| Cannot_quantify (name, v) ->
|
2011-11-24 01:02:48 -08:00
|
|
|
fprintf ppf
|
|
|
|
"@[<hov>The universal type variable '%s cannot be generalized:@ %s.@]"
|
|
|
|
name
|
|
|
|
(if Btype.is_Tvar v then "it escapes its scope" else
|
|
|
|
if Btype.is_Tunivar v then "it is already bound to another variable"
|
2003-05-19 02:21:17 -07:00
|
|
|
else "it is not a variable")
|
2009-10-26 03:53:16 -07:00
|
|
|
| Multiple_constraints_on_type s ->
|
2011-12-14 02:26:15 -08:00
|
|
|
fprintf ppf "Multiple constraints for type %a" longident s
|
2010-01-20 08:26:46 -08:00
|
|
|
| Repeated_method_label s ->
|
|
|
|
fprintf ppf "@[This is the second method `%s' of this object type.@ %s@]"
|
|
|
|
s "Multiple occurences are not allowed."
|
2010-05-18 09:46:46 -07:00
|
|
|
| Unbound_value lid ->
|
2012-10-16 06:54:24 -07:00
|
|
|
fprintf ppf "Unbound value %a" longident lid;
|
2014-12-13 06:46:16 -08:00
|
|
|
spellcheck ppf fold_values env lid;
|
2010-05-18 09:46:46 -07:00
|
|
|
| Unbound_module lid ->
|
2012-10-16 06:54:24 -07:00
|
|
|
fprintf ppf "Unbound module %a" longident lid;
|
2014-12-13 06:46:16 -08:00
|
|
|
spellcheck ppf fold_modules env lid;
|
2010-05-18 09:46:46 -07:00
|
|
|
| Unbound_constructor lid ->
|
2012-10-16 06:54:24 -07:00
|
|
|
fprintf ppf "Unbound constructor %a" longident lid;
|
2014-12-13 06:46:16 -08:00
|
|
|
spellcheck ppf fold_constructors env lid;
|
2010-05-18 09:46:46 -07:00
|
|
|
| Unbound_label lid ->
|
2012-11-10 19:46:59 -08:00
|
|
|
fprintf ppf "Unbound record field %a" longident lid;
|
2014-12-13 06:46:16 -08:00
|
|
|
spellcheck ppf fold_labels env lid;
|
2010-05-18 09:46:46 -07:00
|
|
|
| Unbound_class lid ->
|
2012-10-16 06:54:24 -07:00
|
|
|
fprintf ppf "Unbound class %a" longident lid;
|
2014-12-13 06:46:16 -08:00
|
|
|
spellcheck ppf fold_classs env lid;
|
2010-05-18 10:18:24 -07:00
|
|
|
| Unbound_modtype lid ->
|
2012-10-16 06:54:24 -07:00
|
|
|
fprintf ppf "Unbound module type %a" longident lid;
|
2014-12-13 06:46:16 -08:00
|
|
|
spellcheck ppf fold_modtypes env lid;
|
2010-05-18 10:25:02 -07:00
|
|
|
| Unbound_cltype lid ->
|
2012-10-16 06:54:24 -07:00
|
|
|
fprintf ppf "Unbound class type %a" longident lid;
|
2014-12-13 06:46:16 -08:00
|
|
|
spellcheck ppf fold_cltypes env lid;
|
2010-05-18 09:46:46 -07:00
|
|
|
| Ill_typed_functor_application lid ->
|
|
|
|
fprintf ppf "Ill-typed functor application %a" longident lid
|
2013-04-29 08:39:00 -07:00
|
|
|
| Illegal_reference_to_recursive_module ->
|
|
|
|
fprintf ppf "Illegal recursive module reference"
|
2014-05-11 01:13:04 -07:00
|
|
|
| Access_functor_as_structure lid ->
|
|
|
|
fprintf ppf "The module %a is a functor, not a structure" longident lid
|
2015-10-24 07:28:53 -07:00
|
|
|
| Apply_structure_as_functor lid ->
|
|
|
|
fprintf ppf "The module %a is a structure, not a functor" longident lid
|
2015-10-22 09:11:08 -07:00
|
|
|
| Cannot_scrape_alias(lid, p) ->
|
|
|
|
fprintf ppf
|
|
|
|
"The module %a is an alias for module %a, which is missing"
|
|
|
|
longident lid path p
|
2013-09-12 07:06:48 -07:00
|
|
|
|
|
|
|
let () =
|
|
|
|
Location.register_error_of_exn
|
|
|
|
(function
|
|
|
|
| Error (loc, env, err) ->
|
|
|
|
Some (Location.error_of_printer loc (report_error env) err)
|
2014-05-07 01:26:17 -07:00
|
|
|
| Error_forward err ->
|
|
|
|
Some err
|
2013-09-12 07:06:48 -07:00
|
|
|
| _ ->
|
|
|
|
None
|
|
|
|
)
|