From 0a8236066f945c6026337dd4ea9342a9034f7987 Mon Sep 17 00:00:00 2001 From: Jacques Garrigue Date: Thu, 18 Apr 2002 07:27:47 +0000 Subject: [PATCH] vive les methodes polymorphes! git-svn-id: http://caml.inria.fr/svn/ocaml/trunk@4694 f963ae5c-01c2-4b8c-9fe0-0dff7051ff02 --- boot/ocamlc | Bin 812091 -> 839545 bytes boot/ocamllex | Bin 94485 -> 94494 bytes bytecomp/bytelibrarian.ml | 2 - bytecomp/bytelink.ml | 14 +- byterun/lexing.c | 4 +- byterun/unix.c | 5 +- driver/main.ml | 1 + driver/main_args.ml | 3 + driver/main_args.mli | 1 + driver/optmain.ml | 2 + otherlibs/labltk/browser/searchpos.ml | 3 +- parsing/parser.mly | 41 ++- parsing/parsetree.mli | 2 + parsing/printast.ml | 8 + stdlib/sys.ml | 2 +- tools/addlabels.ml | 3 +- tools/depend.ml | 2 + tools/ocamlcp.ml | 1 + tools/ocamlprof.ml | 2 + toplevel/genprintval.ml | 4 + toplevel/topmain.ml | 1 + typing/btype.ml | 63 +--- typing/btype.mli | 5 +- typing/ctype.ml | 497 ++++++++++++++++++++++---- typing/ctype.mli | 20 +- typing/oprint.ml | 22 +- typing/outcometree.mli | 1 + typing/parmatch.ml | 2 +- typing/printtyp.ml | 112 ++++-- typing/subst.ml | 27 +- typing/typeclass.ml | 89 +++-- typing/typecore.ml | 244 +++++++++++-- typing/typecore.mli | 2 + typing/typedecl.ml | 29 +- typing/types.ml | 10 + typing/types.mli | 10 + typing/typetexp.ml | 240 ++++++++++--- typing/typetexp.mli | 4 + utils/clflags.ml | 3 +- 39 files changed, 1169 insertions(+), 312 deletions(-) diff --git a/boot/ocamlc b/boot/ocamlc index 008e73ba7c1b83cd16f85bee4a66f4b52e28fa58..2ad1f5f4ef22d3866aee5aa21d15b48ac3e96c20 100755 GIT binary patch delta 138904 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

Flm63(v`ut5Wu))$7TV{u)){e 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 Pkd1Ta&b_Lk;qw0jEBI9N delta 118225 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 YEzh5pz4aEEbHtM%9*vbHM?A6r4;%t;WdHyG diff --git a/boot/ocamllex b/boot/ocamllex index 937aadfb3238ec95346b4359ebd9d43a1cdd1de6..8baed4885bee5167f38f4767002bec732431c9bb 100755 GIT binary patch delta 95 zcmV-l0HFVs;su`K1r#G8FLQNia%FBWZ*X)kZ)0I?Y%_rjwG08QNeQF?008*_01J+{ z!ASwk0u(eeE-*AJF)$z~GB7YQEig1KF*vuNOaZ0?1XKYSV7E$80kR+gxR?EK0T{Kr B9R>gZ delta 105 zcmbRDh;`~CRvu+V{nFwh{ha*d#GFQvts;zTJUJILFfjaNVBqfEe$tci43n_2v7Uj6 zwxxoGk%57cu7L> if dir = "" then "" else "-L" ^ dir) !load_path)) - (Ccomp.quote_files (List.rev !Clflags.ccobjs)) + (String.concat " " (List.rev !Clflags.ccobjs)) Config.bytecomp_c_libraries) | "Win32" -> let retcode = @@ -446,13 +446,13 @@ let build_custom_runtime prim_name exec_name = (Printf.sprintf "%s /Fe%s %s %s %s %s %s %s" !Clflags.c_linker - (Filename.quote exec_name) + exec_name (Clflags.std_include_flag "-I") (String.concat " " (List.rev !Clflags.ccopts)) prim_name - (Ccomp.quote_files - (List.rev_map Ccomp.expand_libname !Clflags.ccobjs)) - (Filename.quote (Ccomp.expand_libname "-lcamlrun")) + (String.concat " " + (List.rev_map Ccomp.expand_libname !Clflags.ccobjs)) + (Ccomp.expand_libname "-lcamlrun") Config.bytecomp_c_libraries) in (* C compiler doesn't clean up after itself. Note that the .obj file is created in the current working directory. *) diff --git a/byterun/lexing.c b/byterun/lexing.c index dab0a962f..ec44eb053 100644 --- a/byterun/lexing.c +++ b/byterun/lexing.c @@ -22,7 +22,7 @@ struct lexer_buffer { value refill_buff; value lex_buffer; - value lex_buffer_len; + value lex_buffer_end; value lex_abs_pos; value lex_start_pos; value lex_curr_pos; @@ -72,7 +72,7 @@ CAMLprim value lex_engine(struct lexing_table *tbl, value start_state, lexbuf->lex_last_action = Val_int(backtrk); } /* See if we need a refill */ - if (lexbuf->lex_curr_pos >= lexbuf->lex_buffer_len){ + if (lexbuf->lex_curr_pos >= lexbuf->lex_buffer_end){ if (lexbuf->lex_eof_reached == Val_bool (0)){ return Val_int(-state - 1); }else{ diff --git a/byterun/unix.c b/byterun/unix.c index 38b9b4aad..62961c40e 100644 --- a/byterun/unix.c +++ b/byterun/unix.c @@ -157,10 +157,13 @@ char * search_dll_in_path(struct ext_table * path, char * name) #ifndef RTLD_GLOBAL #define RTLD_GLOBAL 0 #endif +#ifndef RTLD_NODELETE +#define RTLD_NODELETE 0 +#endif void * caml_dlopen(char * libname) { - return dlopen(libname, RTLD_NOW|RTLD_GLOBAL); + return dlopen(libname, RTLD_NOW|RTLD_GLOBAL|RTLD_NODELETE); } void caml_dlclose(void * handle) diff --git a/driver/main.ml b/driver/main.ml index 3d0aa0cf0..6ee14e5c0 100644 --- a/driver/main.ml +++ b/driver/main.ml @@ -95,6 +95,7 @@ module Options = Main_args.Make_options (struct let _output_obj () = output_c_object := true; custom_runtime := true let _pack = set make_package let _pp s = preprocessor := Some s + let _principal = set principal let _rectypes = set recursive_types let _thread = set thread_safe let _unsafe = set fast diff --git a/driver/main_args.ml b/driver/main_args.ml index b474ccfa1..0beea91e4 100644 --- a/driver/main_args.ml +++ b/driver/main_args.ml @@ -39,6 +39,7 @@ module Make_options (F : val _output_obj : unit -> unit val _pack : unit -> unit val _pp : string -> unit + val _principal : unit -> unit val _rectypes : unit -> unit val _thread : unit -> unit val _unsafe : unit -> unit @@ -101,6 +102,8 @@ struct " Package the given .cmo files into one .cmo"; "-pp", Arg.String F._pp, " Pipe sources through preprocessor "; + "-principal", Arg.Unit F._principal, + " Check principality of type inference"; "-rectypes", Arg.Unit F._rectypes, " Allow arbitrary recursive types"; "-thread", Arg.Unit F._thread, " Use thread-safe standard library"; "-unsafe", Arg.Unit F._unsafe, diff --git a/driver/main_args.mli b/driver/main_args.mli index 1d28c8b19..137ed6892 100644 --- a/driver/main_args.mli +++ b/driver/main_args.mli @@ -39,6 +39,7 @@ module Make_options (F : val _output_obj : unit -> unit val _pack : unit -> unit val _pp : string -> unit + val _principal : unit -> unit val _rectypes : unit -> unit val _thread : unit -> unit val _unsafe : unit -> unit diff --git a/driver/optmain.ml b/driver/optmain.ml index 9cfbe2259..f1a6c39bc 100644 --- a/driver/optmain.ml +++ b/driver/optmain.ml @@ -110,6 +110,8 @@ let main () = " Package the given .cmo files into one .cmo"; "-pp", Arg.String(fun s -> preprocessor := Some s), " Pipe sources through preprocessor "; + "-principal", Arg.Set principal, + " Check principality of type inference"; "-rectypes", Arg.Set recursive_types, " Allow arbitrary recursive types"; "-S", Arg.Set keep_asm_file, " Keep intermediate assembly file"; diff --git a/otherlibs/labltk/browser/searchpos.ml b/otherlibs/labltk/browser/searchpos.ml index cf4f009b3..4302ad002 100644 --- a/otherlibs/labltk/browser/searchpos.ml +++ b/otherlibs/labltk/browser/searchpos.ml @@ -127,7 +127,8 @@ let rec search_pos_type t ~pos ~env = | Ptyp_class (lid, tl, _) -> List.iter tl ~f:(search_pos_type ~pos ~env); add_found_sig (`Type, lid) ~env ~loc:t.ptyp_loc - | Ptyp_alias (t, _) -> search_pos_type ~pos ~env t + | Ptyp_alias (t, _) + | Ptyp_poly (_, t) -> search_pos_type ~pos ~env t end let rec search_pos_class_type cl ~pos ~env = diff --git a/parsing/parser.mly b/parsing/parser.mly index d6dabc057..a037ccb08 100644 --- a/parsing/parser.mly +++ b/parsing/parser.mly @@ -612,14 +612,18 @@ value: symbol_rloc () } ; virtual_method: - METHOD PRIVATE VIRTUAL label COLON core_type + METHOD PRIVATE VIRTUAL label COLON poly_type { $4, Private, $6, symbol_rloc () } - | METHOD VIRTUAL private_flag label COLON core_type + | METHOD VIRTUAL private_flag label COLON poly_type { $4, $3, $6, symbol_rloc () } ; concrete_method : - METHOD private_flag label fun_binding - { $3, $2, $4, symbol_rloc () } + METHOD private_flag label strict_binding + { $3, $2, mkexp(Pexp_poly ($4, None)), symbol_rloc () } + | METHOD private_flag label COLON poly_type EQUAL seq_expr + { $3, $2, mkexp(Pexp_poly($7,Some $5)), symbol_rloc () } + | METHOD private_flag LABEL poly_type EQUAL seq_expr + { $3, $2, mkexp(Pexp_poly($6,Some $4)), symbol_rloc () } ; /* Class types */ @@ -680,7 +684,7 @@ XXX Should be removed */ ; method_type: - METHOD private_flag label COLON core_type + METHOD private_flag label COLON poly_type { $3, $2, $5, symbol_rloc () } ; constrain: @@ -964,10 +968,20 @@ let_binding: { ($1, $3) } ; fun_binding: +/* EQUAL seq_expr { $2 } + | labeled_simple_pattern fun_binding + { let (l, o, p) = $1 in mkexp(Pexp_function(l, o, [p, $2])) } +*/ + strict_binding + { $1 } | type_constraint EQUAL seq_expr { let (t, t') = $1 in mkexp(Pexp_constraint($3, t, t')) } +; +strict_binding: + EQUAL seq_expr + { $2 } | labeled_simple_pattern fun_binding { let (l, o, p) = $1 in mkexp(Pexp_function(l, o, [p, $2])) } ; @@ -1164,7 +1178,7 @@ label_declarations: | label_declarations SEMI label_declaration { $3 :: $1 } ; label_declaration: - mutable_flag label COLON core_type { ($2, $1, $4) } + mutable_flag label COLON poly_type { ($2, $1, $4) } ; /* "with" constraints (additional type equations over signature components) */ @@ -1188,6 +1202,19 @@ with_constraint: { ($2, Pwith_module $4) } ; +/* Polymorphic types */ + +typevar_list: + QUOTE ident { [$2] } + | typevar_list QUOTE ident { $3 :: $1 } +; +poly_type: + core_type + { mktyp(Ptyp_poly([], $1)) } + | typevar_list DOT core_type + { mktyp(Ptyp_poly(List.rev $1, $3)) } +; + /* Core types */ core_type: @@ -1306,7 +1333,7 @@ meth_list: | DOTDOT { [mkfield Pfield_var] } ; field: - label COLON core_type { mkfield(Pfield($1, $3)) } + label COLON poly_type { mkfield(Pfield($1, $3)) } ; label: LIDENT { $1 } diff --git a/parsing/parsetree.mli b/parsing/parsetree.mli index b3aa968d2..9c055afdf 100644 --- a/parsing/parsetree.mli +++ b/parsing/parsetree.mli @@ -32,6 +32,7 @@ and core_type_desc = | Ptyp_class of Longident.t * core_type list * label list | Ptyp_alias of core_type * string | Ptyp_variant of row_field list * bool * label list option + | Ptyp_poly of string list * core_type and core_field_type = { pfield_desc: core_field_desc; @@ -108,6 +109,7 @@ and expression_desc = | Pexp_assert of expression | Pexp_assertfalse | Pexp_lazy of expression + | Pexp_poly of expression * core_type option (* Value descriptions *) diff --git a/parsing/printast.ml b/parsing/printast.ml index ec96e871d..5088e590d 100644 --- a/parsing/printast.ml +++ b/parsing/printast.ml @@ -125,6 +125,10 @@ let rec core_type i ppf x = | Ptyp_alias (ct, s) -> line i ppf "Ptyp_alias \"%s\"\n" s; core_type i ppf ct; + | Ptyp_poly (sl, ct) -> + line i ppf "Ptyp_poly%a\n" + (fun ppf -> List.iter (fun x -> fprintf ppf " '%s" x)) sl; + core_type i ppf ct; and core_field_type i ppf x = line i ppf "core_field_type %a\n" fmt_location x.pfield_loc; @@ -274,6 +278,10 @@ and expression i ppf x = | Pexp_lazy (e) -> line i ppf "Pexp_lazy"; expression i ppf e; + | Pexp_poly (e, cto) -> + line i ppf "Pexp_poly\n"; + expression i ppf e; + option i core_type ppf cto; and value_description i ppf x = line i ppf "value_description\n"; diff --git a/stdlib/sys.ml b/stdlib/sys.ml index 99a164380..98373b724 100644 --- a/stdlib/sys.ml +++ b/stdlib/sys.ml @@ -78,4 +78,4 @@ let catch_break on = (* OCaml version string, moved from utils/config.mlp. Must be in the format described in sys.mli. *) -let ocaml_version = "3.04+9 (2002-04-04)" +let ocaml_version = "3.04+10 (2002-04-18)" diff --git a/tools/addlabels.ml b/tools/addlabels.ml index c04809b53..f17e9d4fd 100644 --- a/tools/addlabels.ml +++ b/tools/addlabels.ml @@ -253,7 +253,8 @@ let rec add_labels_expr ~text ~values ~classes expr = | Pexp_setinstvar (_, e) | Pexp_letmodule (_, _, e) | Pexp_assert e - | Pexp_lazy e -> + | Pexp_lazy e + | Pexp_poly (e, _) -> add_labels_rec e | Pexp_record (lst, opt) -> List.iter lst ~f:(fun (_,e) -> add_labels_rec e); diff --git a/tools/depend.ml b/tools/depend.ml index 5b4f9a2c6..4f543a192 100644 --- a/tools/depend.ml +++ b/tools/depend.ml @@ -51,6 +51,7 @@ let rec add_type bv ty = (function Rtag(_,_,stl) -> List.iter (add_type bv) stl | Rinherit sty -> add_type bv sty) fl + | Ptyp_poly(_, t) -> add_type bv t and add_field_type bv ft = match ft.pfield_desc with @@ -151,6 +152,7 @@ let rec add_expr bv exp = | Pexp_assert (e) -> add_expr bv e | Pexp_assertfalse -> () | Pexp_lazy (e) -> add_expr bv e + | Pexp_poly (e, t) -> add_expr bv e; add_opt add_type bv t and add_pat_expr_list bv pel = List.iter (fun (p, e) -> add_pattern bv p; add_expr bv e) pel diff --git a/tools/ocamlcp.ml b/tools/ocamlcp.ml index 95838365d..baad2256f 100644 --- a/tools/ocamlcp.ml +++ b/tools/ocamlcp.ml @@ -58,6 +58,7 @@ module Options = Main_args.Make_options (struct let _output_obj = option "-output-obj" let _pack = option "-pack" let _pp s = incompatible "-pp" + let _principal = option "-principal" let _rectypes = option "-rectypes" let _thread () = ismultithreaded := "-thread"; option "-thread" () let _unsafe = option "-unsafe" diff --git a/tools/ocamlprof.ml b/tools/ocamlprof.ml index 64d737c3d..b9d80c304 100644 --- a/tools/ocamlprof.ml +++ b/tools/ocamlprof.ml @@ -287,6 +287,8 @@ and rw_exp iflag sexp = | Pexp_lazy (expr) -> rewrite_exp iflag expr + | Pexp_poly (sexp, _) -> rewrite_exp iflag sexp + and rewrite_ifbody iflag ghost sifbody = if !instr_if && not ghost then insert_profile rw_exp sifbody diff --git a/toplevel/genprintval.ml b/toplevel/genprintval.ml index 788c69db4..dcafc639a 100644 --- a/toplevel/genprintval.ml +++ b/toplevel/genprintval.ml @@ -313,6 +313,10 @@ module Make(O : OBJ)(EVP : EVALPATH with type value = O.t) = struct tree_of_val (depth - 1) obj ty | Tfield(_, _, _, _) | Tnil | Tlink _ -> fatal_error "Printval.outval_of_value" + | Tpoly (ty, _) -> + tree_of_val (depth - 1) obj ty + | Tunivar -> + Oval_stuff "" end and tree_of_val_list start depth obj ty_list = diff --git a/toplevel/topmain.ml b/toplevel/topmain.ml index 5396e9fff..49142eeaa 100644 --- a/toplevel/topmain.ml +++ b/toplevel/topmain.ml @@ -45,6 +45,7 @@ let main () = "-nolabels", Arg.Set classic, " Ignore labels and do not commute"; "-nostdlib", Arg.Set no_std_include, " do not add default directory to the list of include directories"; + "-principal", Arg.Set principal, " Check principality of type inference"; "-rectypes", Arg.Set recursive_types, " Allow arbitrary recursive types"; "-unsafe", Arg.Set fast, " No bound checking on array and string access"; "-w", Arg.String (Warnings.parse_options false), diff --git a/typing/btype.ml b/typing/btype.ml index 8a8879a26..35d18909b 100644 --- a/typing/btype.ml +++ b/typing/btype.ml @@ -121,7 +121,7 @@ let rec iter_row f row = row.row_fields; match (repr row.row_more).desc with Tvariant row -> iter_row f row - | Tvar | Tnil -> + | Tvar | Tnil | Tunivar -> Misc.may (fun (_,l) -> List.iter f l) row.row_name; List.iter f row.row_bound | _ -> assert false @@ -140,8 +140,15 @@ let iter_type_expr f ty = | Tnil -> () | Tlink ty -> f ty | Tsubst ty -> f ty + | Tunivar -> () + | Tpoly (ty, tyl) -> f ty; List.iter f tyl -let copy_row f row keep more = +let rec iter_abbrev f = function + Mnil -> () + | Mcons(_, ty, ty', rem) -> f ty; f ty'; iter_abbrev f rem + | Mlink rem -> iter_abbrev f !rem + +let copy_row f fixed row keep more = let bound = ref [] in let fields = List.map (fun (l, fi) -> l, @@ -149,6 +156,7 @@ let copy_row f row keep more = | Rpresent(Some ty) -> Rpresent(Some(f ty)) | Reither(c, tl, m, e) -> let e = if keep then e else ref None in + let m = if row.row_fixed then fixed else m in let tl = List.map f tl in bound := List.filter (function {desc=Tconstr(_,[],_)} -> false | _ -> true) @@ -160,7 +168,8 @@ let copy_row f row keep more = let name = match row.row_name with None -> None | Some (path, tl) -> Some (path, List.map f tl) in - { row_fields = fields; row_more = more; row_bound = !bound; + { row_fields = fields; row_more = more; + row_bound = !bound; row_fixed = row.row_fixed && fixed; row_closed = row.row_closed; row_name = name; } let rec copy_kind = function @@ -182,56 +191,14 @@ let rec copy_type_desc f = function | Tobject (ty, _) -> Tobject (f ty, ref None) | Tvariant row -> let row = row_repr row in - Tvariant (copy_row f row false (f row.row_more)) + Tvariant (copy_row f true row false (f row.row_more)) | Tfield (p, k, ty1, ty2) -> Tfield (p, copy_kind k, f ty1, f ty2) | Tnil -> Tnil | Tlink ty -> copy_type_desc f ty.desc | Tsubst ty -> assert false + | Tunivar -> Tunivar + | Tpoly (ty, tyl) -> Tpoly (f ty, List.map f tyl) -(* -let rec iter_signature f = - List.iter (iter_signature_item f) - -and iter_signature_item f = function - Tsig_value (_, d) -> - f d.val_type; - (match d.val_kind with Val_reg | Val_prim _ -> () | _ -> assert false) - | Tsig_type (_, d) -> - List.iter f d.type_params; - begin match d.type_kind with - Type_abstract -> () - | Type_variant l -> List.iter (fun (_, tl) -> List.iter f tl) l - | Type_record r -> List.iter (fun (_, _, t) -> f t) - end; - may f d.type_manifest - | Tsig_exception (_, d) -> List.iter f d - | Tsig_module (_, m) -> iter_module_type f m - | Tsig_modtype (_, Tmodtype_manifest m) -> iter_module_type f m - | Tsig_modtype (_, Tmodtype_bastract) -> () - | Tsig_class (_, d) -> - List.iter f d.cty_params; - iter_class_type f d.cty_type; - may f d.cty_new - | Tsig_cltype (_, d) -> - List.iter f d.clty_params; - iter_class_type f d.clty_type - -and iter_module_type f = function - Tmty_ident _ -> () - | Tmty_signature sg -> iter_signature f sg - | Tmty_functor (_, m1, m2) -> iter_module_type f m1; iter_module_type f m2 - -and iter_class_type f = function - Tcty_constr (_, tl, ct) -> - List.iter f tl; - iter_class_type f ct - | Tcty_fun (_, t, ct) -> - f t; - iter_class_type f ct - | Tcty_signature s -> - f s.cty_self; - Vars.iter (fun _ (_, t) -> f t) s.cty_vars -*) (* Utilities for copying *) diff --git a/typing/btype.mli b/typing/btype.mli index a37cb2ac7..f0609d844 100644 --- a/typing/btype.mli +++ b/typing/btype.mli @@ -60,11 +60,14 @@ val iter_type_expr: (type_expr -> unit) -> type_expr -> unit (* Iteration on types *) val iter_row: (type_expr -> unit) -> row_desc -> unit (* Iteration on types in a row *) +val iter_abbrev: (type_expr -> unit) -> abbrev_memo -> unit + (* Iteration on types in an abbreviation list *) val copy_type_desc: (type_expr -> type_expr) -> type_desc -> type_desc (* Copy on types *) val copy_row: - (type_expr -> type_expr) -> row_desc -> bool -> type_expr -> row_desc + (type_expr -> type_expr) -> + bool -> row_desc -> bool -> type_expr -> row_desc val copy_kind: field_kind -> field_kind val save_desc: type_expr -> type_desc -> unit diff --git a/typing/ctype.ml b/typing/ctype.ml index 8a5637077..1bfe2538b 100644 --- a/typing/ctype.ml +++ b/typing/ctype.ml @@ -129,6 +129,10 @@ let restore_global_level () = gl::rem -> global_level := gl; saved_global_level := rem | [] -> assert false +(* Abbreviations without parameters *) +(* Shall reset after generalizing *) +let simple_abbrevs = ref Mnil + (**** Some type creators ****) (* Re-export generic type creators *) @@ -381,8 +385,7 @@ let rec free_vars_rec real ty = | Tvariant row -> let row = row_repr row in iter_row (free_vars_rec true) {row with row_bound = []}; - if not (static_row row) then - free_variables := (row_more row, false) :: !free_variables + if not (static_row row) then free_vars_rec false row.row_more | _ -> iter_type_expr (free_vars_rec true) ty end; @@ -497,22 +500,18 @@ let rec iter_generalize tyl ty = ty.level <- generic_level; begin match ty.desc with Tconstr (_, _, abbrev) -> - generalize_expans tyl !abbrev + iter_abbrev (iter_generalize tyl) !abbrev | _ -> () end; iter_type_expr (iter_generalize tyl) ty end else tyl := ty :: !tyl -and generalize_expans tyl = - function - Mnil -> () - | Mcons(_, ty, ty', rem) -> iter_generalize tyl ty; - iter_generalize tyl ty'; - generalize_expans tyl rem - | Mlink rem -> generalize_expans tyl !rem +let iter_generalize tyl ty = + simple_abbrevs := Mnil; + iter_generalize tyl ty -let rec generalize ty = +let generalize ty = iter_generalize (ref []) ty (* Efficient repeated generalisation of the same type *) @@ -522,6 +521,43 @@ let iterative_generalization min_level tyl = List.fold_right (fun ty l -> if ty.level <= min_level then l else ty::l) !tyl' [] +(* Generalize the structure and lower the variables *) + +let rec generalize_structure var_level ty = + let ty = repr ty in + if ty.level <> generic_level then begin + if ty.desc = Tvar && ty.level > var_level then + ty.level <- var_level + else if ty.level > !current_level then begin + ty.level <- generic_level; + begin match ty.desc with + Tconstr (_, _, abbrev) -> + iter_abbrev (generalize_structure var_level) !abbrev + | _ -> () + end; + iter_type_expr (generalize_structure var_level) ty + end + end + +let generalize_structure var_level ty = + simple_abbrevs := Mnil; + generalize_structure var_level ty + +let generalize_expansive ty = generalize_structure !nongen_level ty +let generalize_global ty = generalize_structure !global_level ty +let generalize_structure ty = generalize_structure !current_level ty + +(* Generalize the spine of a function, if the level >= !current_level *) + +let rec generalize_spine ty = + let ty = repr ty in + if ty.level < !current_level || ty.level = generic_level then () else + match ty.desc with + Tarrow (_, _, ty', _) | Tpoly (ty', _) -> + ty.level <- generic_level; + generalize_spine ty' + | _ -> () + let try_expand_head' = (* Forward declaration *) ref (fun env ty -> raise Cannot_expand) @@ -662,7 +698,10 @@ let rec copy ty = t.desc <- begin match desc with | Tconstr (p, tl, _) -> - begin match find_repr p !(!abbreviations) with + let abbrevs = + if tl = [] && not !Clflags.principal then simple_abbrevs + else !abbreviations in + begin match find_repr p !abbrevs with Some ty when repr ty != t -> (* XXX Commentaire... *) Tlink ty | _ -> @@ -685,19 +724,24 @@ let rec copy ty = let more = repr row.row_more in (* We must substitute in a subtle way *) begin match more.desc with - Tsubst ty2 -> + Tsubst ({desc=Tvariant _} as ty2) -> (* This variant type has been already copied *) ty.desc <- Tsubst ty2; (* avoid Tlink in the new type *) Tlink ty2 | _ -> (* If the row variable is not generic, we must keep it *) let keep = more.level <> generic_level in + let desc = more.desc in (* Register new type first for recursion *) save_desc more more.desc; more.desc <- ty.desc; (* Return a new copy *) - let more' = if keep then more else newvar () in - Tvariant (copy_row copy row keep more') + let more' = + if keep then more else + match desc with Tsubst ty -> ty + | _ -> newty desc + in + Tvariant (copy_row copy true row keep more') end | _ -> copy_type_desc copy desc end; @@ -721,12 +765,6 @@ let instance_constructor cstr = cleanup_types (); (ty_args, ty_res) -let instance_label lbl = - let ty_res = copy lbl.lbl_res in - let ty_arg = copy lbl.lbl_arg in - cleanup_types (); - (ty_arg, ty_res) - let instance_parameterized_type sch_args sch = let ty_args = List.map copy sch_args in let ty = copy sch in @@ -759,6 +797,130 @@ let instance_class params cty = cleanup_types (); (params', cty') +(**** Instanciation for types with free universal variables ****) + +module TypeHash = Hashtbl.Make(TypeOps) +module TypeSet = Set.Make(TypeOps) + +type inv_type_expr = + { inv_type : type_expr; + mutable inv_parents : inv_type_expr list } + +let rec inv_type hash pty ty = + let ty = repr ty in + try + let inv = TypeHash.find hash ty in + inv.inv_parents <- pty @ inv.inv_parents + with Not_found -> + let inv = { inv_type = ty; inv_parents = pty } in + TypeHash.add hash ty inv; + iter_type_expr (inv_type hash [inv]) ty + +let compute_univars ty = + let inverted = TypeHash.create 17 in + inv_type inverted [] ty; + let node_univars = TypeHash.create 17 in + let rec add_univar univ inv = + match inv.inv_type.desc with + Tpoly (ty, tl) when List.memq univ (List.map repr tl) -> () + | _ -> + try + let univs = TypeHash.find node_univars inv.inv_type in + if not (TypeSet.mem univ !univs) then begin + univs := TypeSet.add univ !univs; + List.iter (add_univar univ) inv.inv_parents + end + with Not_found -> + TypeHash.add node_univars inv.inv_type (ref(TypeSet.singleton univ)); + List.iter (add_univar univ) inv.inv_parents + in + TypeHash.iter + (fun ty inv -> if ty.desc = Tunivar then add_univar ty inv) + inverted; + fun ty -> + try !(TypeHash.find node_univars ty) with Not_found -> TypeSet.empty + +let rec diff_list l1 l2 = + if l1 == l2 then [] else + match l1 with [] -> invalid_arg "Ctype.diff_list" + | a :: l1 -> a :: diff_list l1 l2 + +let conflicts free bound = + let bound = List.map repr bound in + TypeSet.exists (fun t -> List.memq (repr t) bound) free + +let delayed_copy = ref [] + (* copying to do later *) + +(* Copy without sharing until there are no free univars left *) +(* all free univars must be included in [visited] *) +let rec copy_sep fixed free bound visited ty = + let ty = repr ty in + let univars = free ty in + if TypeSet.is_empty univars then + if ty.level <> generic_level then ty else + let t = newvar () in + delayed_copy := + lazy (t.desc <- Tlink (copy ty)) + :: !delayed_copy; + t + else try + let t, bound_t = List.assq ty visited in + let dl = if ty.desc = Tunivar then [] else diff_list bound bound_t in + if dl <> [] && conflicts univars dl then raise Not_found; + t + with Not_found -> begin + let t = newvar() in (* Stub *) + let visited = + match ty.desc with + Tarrow _ | Ttuple _ | Tvariant _ | Tconstr _ | Tobject _ -> + (ty,(t,bound)) :: visited + | _ -> visited in + let copy_rec = copy_sep fixed free bound visited in + t.desc <- + begin match ty.desc with + | Tvariant row0 -> + let row = row_repr row0 in + let more = repr row.row_more in + (* We shall really check the level on the row variable *) + let keep = more.desc = Tvar && more.level <> generic_level in + let more' = copy_rec more in + let row = copy_row copy_rec fixed row keep more' in + Tvariant row + | Tpoly (t1, tl) -> + let tl = List.map repr tl in + let tl' = List.map (fun t -> newty Tunivar) tl in + let bound = tl @ bound in + let visited = + List.map2 (fun ty t -> ty,(t,bound)) tl tl' @ visited in + Tpoly (copy_rec t1, tl') + | _ -> copy_type_desc copy_rec ty.desc + end; + t + end + +let instance_poly fixed univars sch = + let vars = List.map (fun _ -> newvar ()) univars in + let pairs = List.map2 (fun u v -> repr u, (v, [])) univars vars in + delayed_copy := []; + let ty = copy_sep fixed (compute_univars sch) [] pairs sch in + List.iter Lazy.force !delayed_copy; + delayed_copy := []; + cleanup_types (); + vars, ty + +let instance_label fixed lbl = + let ty_res = copy lbl.lbl_res in + let vars, ty_arg = + match repr lbl.lbl_arg with + {desc = Tpoly (ty, tl)} -> + instance_poly fixed tl ty + | ty -> + [], copy lbl.lbl_arg + in + cleanup_types (); + (vars, ty_arg, ty_res) + (**** Instantiation with parameter substitution ****) let unify' = (* Forward declaration *) @@ -771,7 +933,10 @@ let rec subst env level abbrev ty params args body = let body0 = newvar () in (* Stub *) begin match ty with None -> () - | Some ({desc = Tconstr (path, _, _)} as ty) -> + | Some ({desc = Tconstr (path, tl, _)} as ty) -> + let abbrev = + if tl = [] && not !Clflags.principal then simple_abbrevs else abbrev + in memorize_abbrev abbrev path ty body0 | _ -> assert false @@ -856,7 +1021,10 @@ let expand_abbrev env ty = end; match ty with {desc = Tconstr (path, args, abbrev); level = level} -> - begin match find_expans path !abbrev with + let lookup_abbrev = + if args = [] && not !Clflags.principal then simple_abbrevs + else abbrev in + begin match find_expans path !lookup_abbrev with Some ty -> if level <> generic_level then begin try @@ -1021,6 +1189,68 @@ let occur env ty0 ty = raise (match exn with Occur -> Unify [] | _ -> exn) + (*****************************) + (* Polymorphic Unification *) + (*****************************) + +(* Since we cannot duplicate universal variables, unification must + be done at meta-level, using bindings in univar_pairs *) +let rec unify_univar t1 t2 = function + (cl1, cl2) :: rem -> + let repr_univ = List.map (fun (t,o) -> repr t, o) in + let cl1 = repr_univ cl1 and cl2 = repr_univ cl2 in + begin try + let r1 = List.assq t1 cl1 in + match !r1 with + Some t -> if t2 != repr t then raise (Unify []) + | None -> + try + let r2 = List.assq t2 cl2 in + if !r2 <> None then raise (Unify []); + r1 := Some t2; r2 := Some t1 + with Not_found -> + raise (Unify []) + with Not_found -> + unify_univar t1 t2 rem + end + | [] -> raise (Unify []) + +module TypeMap = Map.Make (TypeOps) + +(* Test the occurence of free univars in a type *) +(* that's way too expansive. Must do some kind of cacheing *) +let occur_univar ty = + let visited = ref TypeMap.empty in + let rec occur_rec bound ty = + let ty = repr ty in + if ty.level >= lowest_level && + if TypeSet.is_empty bound then + (ty.level <- pivot_level - ty.level; true) + else try + let bound' = TypeMap.find ty !visited in + if TypeSet.exists (fun x -> not (TypeSet.mem x bound)) bound' then + (visited := TypeMap.add ty (TypeSet.inter bound bound') !visited; + true) + else false + with Not_found -> + visited := TypeMap.add ty bound !visited; + true + then + match ty.desc with + Tunivar -> if not (TypeSet.mem ty bound) then raise Occur + | Tpoly (ty, tyl) -> + let bound = List.fold_right TypeSet.add (List.map repr tyl) bound in + occur_rec bound ty + | _ -> iter_type_expr (occur_rec bound) ty + in + try + occur_rec TypeSet.empty ty; unmark_type ty + with Occur -> + unmark_type ty; raise (Unify []) + +let univar_pairs = ref [] + + (*****************) (* Unification *) (*****************) @@ -1097,13 +1327,17 @@ let rec unify env t1 t2 = | (Tconstr _, Tvar) when deep_occur t2 t1 -> unify2 env t1 t2 | (Tvar, _) -> - occur env t1 t2; + occur env t1 t2; occur_univar t2; update_level env t1.level t2; t1.desc <- Tlink t2 | (_, Tvar) -> - occur env t2 t1; + occur env t2 t1; occur_univar t1; update_level env t2.level t1; t2.desc <- Tlink t1 + | (Tunivar, Tunivar) -> + unify_univar t1 t2 !univar_pairs; + update_level env t1.level t2; + t1.desc <- Tlink t2 | (Tconstr (p1, [], a1), Tconstr (p2, [], a2)) when Path.same p1 p2 (* This optimization assumes that t1 does not expand to t2 @@ -1147,9 +1381,11 @@ and unify3 env t1 t1' t2 t2' = try begin match (d1, d2) with (Tvar, _) -> - () + occur_univar t2 | (_, Tvar) -> - occur env t2' (newty d1); + let td1 = newgenty d1 in + occur env t2' td1; + occur_univar td1; if t1 == t1' then begin (* The variable must be instantiated... *) let ty = newty2 t1'.level d1 in @@ -1178,8 +1414,8 @@ and unify3 env t1 t1' t2 t2' = (* XXX One should do some kind of unification... *) begin match (repr t2').desc with Tobject (_, {contents = Some (_, va::_)}) - when (repr va).desc = Tvar -> - () + when let va = repr va in va.desc = Tvar || va.desc = Tunivar -> + () | Tobject (_, nm2) -> nm2 := !nm1 | _ -> @@ -1191,6 +1427,30 @@ and unify3 env t1 t1' t2 t2' = unify_fields env t1' t2' | (Tnil, Tnil) -> () + | (Tpoly (t1, []), Tpoly (t2, [])) -> + unify env t1 t2 + | (Tpoly (t1, tl1), Tpoly (t2, tl2)) -> + if List.length tl1 <> List.length tl2 then raise (Unify []); + let old_univars = !univar_pairs in + let cl1 = List.map (fun t -> t, ref None) tl1 + and cl2 = List.map (fun t -> t, ref None) tl2 in + univar_pairs := (cl1,cl2) :: (cl2,cl1) :: old_univars; + begin try + unify env t1 t2; + let tl1 = List.map repr tl1 and tl2 = List.map repr tl2 in + List.iter + (fun t1 -> + if List.memq t1 tl2 then () else + try + let t2 = + List.find (fun t2 -> not (List.memq (repr t2) tl1)) tl2 in + t2.desc <- Tlink t1 + with Not_found -> assert false) + tl1; + univar_pairs := old_univars + with exn -> + univar_pairs := old_univars; raise exn + end | (_, _) -> raise (Unify []) end; @@ -1244,7 +1504,11 @@ and unify_fields env ty1 ty2 = (* Optimization *) let (fields1, rest1) = flatten_fields ty1 and (fields2, rest2) = flatten_fields ty2 in let (pairs, miss1, miss2) = associate_fields fields1 fields2 in - let va = newvar () in + let va = + if miss1 = [] then rest2 + else if miss2 = [] then rest1 + else newvar () + in unify env (build_fields (repr ty1).level miss1 va) rest2; unify env rest1 (build_fields (repr ty2).level miss2 va); List.iter @@ -1276,7 +1540,12 @@ and unify_row env row1 row2 = with Not_found -> (h,l)::hl) (List.map (fun (l,_) -> (hash_variant l, l)) row1.row_fields) (List.map fst r2)); - let more = newty2 (min rm1.level rm2.level) Tvar + let more = + if row1.row_fixed then rm1 else + if row2.row_fixed then rm2 else + newgenvar () + in update_level env (min rm1.level rm2.level) more; + let fixed = row1.row_fixed || row2.row_fixed and closed = row1.row_closed || row2.row_closed in let keep switch = List.for_all @@ -1305,28 +1574,36 @@ and unify_row env row1 row2 = in let bound = row1.row_bound @ row2.row_bound in let row0 = {row_fields = []; row_more = more; row_bound = bound; - row_closed = closed; row_name = name} in - let more row rest = + row_closed = closed; row_fixed = fixed; row_name = name} in + let set_more row rest = let rest = if closed then filter_row_fields row.row_closed rest else rest in - if rest <> [] && row.row_closed then raise (Unify []); - let ty = - newty2 generic_level (Tvariant {row0 with row_fields = rest}) in - update_level env (repr row.row_more).level ty; - ty + if rest <> [] && (row.row_closed || row.row_fixed) + || closed && row.row_fixed && not row.row_closed + then raise (Unify []); + let rm = row_more row in + if row.row_fixed then + if row0.row_more == rm then () else rm.desc <- Tlink row0.row_more + else + let ty = newty2 generic_level (Tvariant {row0 with row_fields = rest}) in + update_level env rm.level ty; + rm.desc <- Tlink ty in let md1 = rm1.desc and md2 = rm2.desc in begin try - rm1.desc <- Tlink (more row1 r2); - rm2.desc <- Tlink (more row2 r1); - List.iter (fun (l,f1,f2) -> unify_row_field env f1 f2) pairs + set_more row1 r2; + set_more row2 r1; + List.iter + (fun (l,f1,f2) -> + unify_row_field env row1.row_fixed row2.row_fixed f1 f2) + pairs with exn -> rm1.desc <- md1; rm2.desc <- md2; raise exn end -and unify_row_field env f1 f2 = +and unify_row_field env fixed1 fixed2 f1 f2 = let f1 = row_field_repr f1 and f2 = row_field_repr f2 in if f1 == f2 then () else match f1, f2 with @@ -1350,19 +1627,19 @@ and unify_row_field env f1 f2 = let f1 = Reither(c1 || c2, tl1', m1 || m2, e) and f2 = Reither(c1 || c2, tl2', m1 || m2, e) in e1 := Some f1; e2 := Some f2 - | Reither(false, tl, _, e1), Rpresent(Some t2) -> - e1 := Some f2; - (try List.iter (fun t1 -> unify env t1 t2) tl - with exn -> e1 := None; raise exn) - | Rpresent(Some t1), Reither(false, tl, _, e2) -> - e2 := Some f1; - (try List.iter (unify env t1) tl - with exn -> e2 := None; raise exn) - | Reither(true, [], _, e1), Rpresent None -> e1 := Some f2 - | Rpresent None, Reither(true, [], _, e2) -> e2 := Some f1 | Reither(_, _, false, e1), Rabsent -> e1 := Some f2 | Rabsent, Reither(_, _, false, e2) -> e2 := Some f1 | Rabsent, Rabsent -> () + | Reither(false, tl, _, e1), Rpresent(Some t2) when not fixed1 -> + e1 := Some f2; + (try List.iter (fun t1 -> unify env t1 t2) tl + with exn -> e1 := None; raise exn) + | Rpresent(Some t1), Reither(false, tl, _, e2) when not fixed2 -> + e2 := Some f1; + (try List.iter (unify env t1) tl + with exn -> e2 := None; raise exn) + | Reither(true, [], _, e1), Rpresent None when not fixed1 -> e1 := Some f2 + | Rpresent None, Reither(true, [], _, e2) when not fixed2 -> e2 := Some f1 | _ -> raise (Unify []) let unify env ty1 ty2 = @@ -1371,7 +1648,31 @@ let unify env ty1 ty2 = with Unify trace -> raise (Unify (expand_trace env trace)) -let _ = unify' := unify +let unify_var env t1 t2 = + let t1 = repr t1 and t2 = repr t2 in + if t1 == t2 then () else + match t1.desc with + Tvar -> + begin try + occur env t1 t2; + update_level env t1.level t2; + t1.desc <- Tlink t2 + with Unify trace -> + raise (Unify ((t1,t2)::trace)) + end + | _ -> + unify env t1 t2 + +let _ = unify' := unify_var + +let unify_pairs env ty1 ty2 pairs = + univar_pairs := pairs; + unify env ty1 ty2 + +let unify env ty1 ty2 = + univar_pairs := []; + unify env ty1 ty2 + (**** Special cases of unification ****) @@ -1477,6 +1778,8 @@ let moregen_occur env level ty = with Occur -> unmark_type ty; raise (Unify []) end; + (* also check for free univars *) + occur_univar ty; update_level env level ty let rec moregen inst_nongen type_pairs env t1 t2 = @@ -1487,7 +1790,9 @@ let rec moregen inst_nongen type_pairs env t1 t2 = try match (t1.desc, t2.desc) with - (Tvar, _) when if inst_nongen then t1.level <> generic_level - 1 + (Tunivar, Tunivar) -> + unify_univar t1 t2 !univar_pairs + | (Tvar, _) when if inst_nongen then t1.level <> generic_level - 1 else t1.level = generic_level -> moregen_occur env t1.level t2; occur env t1 t2; @@ -1532,6 +1837,19 @@ let rec moregen inst_nongen type_pairs env t1 t2 = moregen inst_nongen type_pairs env t1' t2'' | (Tnil, Tnil) -> () + | (Tpoly (t1, []), Tpoly (t2, [])) -> + moregen inst_nongen type_pairs env t1 t2 + | (Tpoly (t1, tl1), Tpoly (t2, tl2)) -> + let old_univars = !univar_pairs in + let cl1 = List.map (fun t -> t, ref None) tl1 + and cl2 = List.map (fun t -> t, ref None) tl2 in + univar_pairs := (cl1,cl2) :: (cl2,cl1) :: old_univars; + begin try + moregen inst_nongen type_pairs env t1 t2; + univar_pairs := old_univars + with exn -> + univar_pairs := old_univars; raise exn + end | (_, _) -> raise (Unify []) end @@ -1635,6 +1953,7 @@ let moregeneral env inst_nongen pat_sch subj_sch = current_level := generic_level; (* Duplicate generic variables *) let patt = instance pat_sch in + univar_pairs := []; let res = try moregen inst_nongen (TypePairs.create 13) env patt subj; true with Unify _ -> false @@ -1704,6 +2023,21 @@ let rec eqtype rename type_pairs subst env t1 t2 = eqtype rename type_pairs subst env t1' t2'' | (Tnil, Tnil) -> () + | (Tpoly (t1, []), Tpoly (t2, [])) -> + eqtype rename type_pairs subst env t1 t2 + | (Tpoly (t1, tl1), Tpoly (t2, tl2)) -> + let old_univars = !univar_pairs in + let cl1 = List.map (fun t -> t, ref None) tl1 + and cl2 = List.map (fun t -> t, ref None) tl2 in + univar_pairs := (cl1,cl2) :: (cl2,cl1) :: old_univars; + begin try eqtype rename type_pairs subst env t1 t2 + with exn -> + univar_pairs := old_univars; + raise exn + end; + univar_pairs := old_univars + | (Tunivar, Tunivar) -> + unify_univar t1 t2 !univar_pairs | (_, _) -> raise (Unify []) end @@ -1772,6 +2106,7 @@ and eqtype_row rename type_pairs subst env row1 row2 = (* Two modes: with or without renaming of variables *) let equal env rename tyl1 tyl2 = try + univar_pairs := []; eqtype_list rename (TypePairs.create 11) (ref []) env tyl1 tyl2; true with Unify _ -> false @@ -1843,6 +2178,7 @@ let match_class_types env pat_sch subj_sch = let type_pairs = TypePairs.create 53 in let old_level = !current_level in current_level := generic_level - 1; + univar_pairs := []; (* Generic variables are first duplicated with [instance]. So, their levels are lowered to [generic_level - 1]. The subject is @@ -1971,6 +2307,7 @@ let rec equal_clty trace type_pairs subst env cty1 cty2 = (* XXX Correct ? (variables de type dans parametres et corps de classe *) let match_class_declarations env patt_params patt_type subj_params subj_type = let type_pairs = TypePairs.create 53 in + univar_pairs := []; let subst = ref [] in let sign1 = signature_of_class_type patt_type in let sign2 = signature_of_class_type subj_type in @@ -2137,7 +2474,7 @@ let rec build_subtype env visited loops posi onlyloop t = let (ty1', _) = build_subtype env visited loops posi onlyloop ty1 in assert (t''.desc = Tvar); t''.desc <- Tobject (ty1', ref None); - (try unify env ty t with Unify _ -> assert false); + (try unify_var env ty t with Unify _ -> assert false); (t'', true) | _ -> raise Not_found with Not_found -> build_subtype env visited loops posi onlyloop t' @@ -2191,7 +2528,7 @@ let rec build_subtype env visited loops posi onlyloop t = if posi && fields = [] then (t, false) else let row = { row_fields = List.map fst fields; row_more = newvar(); - row_bound = !bound; row_closed = posi; + row_bound = !bound; row_closed = posi; row_fixed = false; row_name = if List.exists snd fields then None else row.row_name } in (newty (Tvariant row), true) @@ -2217,6 +2554,12 @@ let rec build_subtype env visited loops posi onlyloop t = (t, false) | Tsubst _ | Tlink _ -> assert false + | Tpoly(t1, tl) -> + let (t1', c) = build_subtype env visited loops posi onlyloop t1 in + if c then (newty (Tpoly(t1', tl)), true) + else (t, false) + | Tunivar -> + (t, false) let enlarge_type env ty = let (ty', _) = build_subtype env [] [] true false ty in @@ -2255,7 +2598,7 @@ let rec subtype_rec env trace t1 t2 cstrs = TypePairs.add subtypes (t1, t2) (); match (t1.desc, t2.desc) with (Tvar, _) | (_, Tvar) -> - (trace, t1, t2)::cstrs + (trace, t1, t2, !univar_pairs)::cstrs | (Tarrow(l1, t1, u1, _), Tarrow(l2, t2, u2, _)) when l1 = l2 || !Clflags.classic && not (is_optional l1 || is_optional l2) -> let cstrs = subtype_rec env ((t2, t1)::trace) t2 t1 cstrs in @@ -2276,19 +2619,19 @@ let rec subtype_rec env trace t1 t2 cstrs = if co then if cn then (trace, newty2 t1.level (Ttuple[t1]), - newty2 t2.level (Ttuple[t2])) :: cstrs + newty2 t2.level (Ttuple[t2]), !univar_pairs) :: cstrs else subtype_rec env ((t1, t2)::trace) t1 t2 cstrs else if cn then subtype_rec env ((t2, t1)::trace) t2 t1 cstrs else cstrs) cstrs decl.type_variance (List.combine tl1 tl2) with Not_found -> - (trace, t1, t2)::cstrs + (trace, t1, t2, !univar_pairs)::cstrs end | (Tobject (f1, _), Tobject (f2, _)) when opened_object f1 && opened_object f2 -> (* Same row variable implies same object. *) - (trace, t1, t2)::cstrs + (trace, t1, t2, !univar_pairs)::cstrs | (Tobject (f1, _), Tobject (f2, _)) -> subtype_fields env trace f1 f2 cstrs | (Tvariant row1, Tvariant row2) -> @@ -2311,10 +2654,20 @@ let rec subtype_rec env trace t1 t2 cstrs = | _ -> raise Exit) cstrs pairs with Exit -> - (trace, t1, t2)::cstrs + (trace, t1, t2, !univar_pairs)::cstrs end + | (Tpoly (u1, []), Tpoly (u2, [])) -> + subtype_rec env trace u1 u2 cstrs + | (Tpoly (t1, tl1), Tpoly (t2,tl2)) -> + let old_univars = !univar_pairs in + let cl1 = List.map (fun t -> t, ref None) tl1 + and cl2 = List.map (fun t -> t, ref None) tl2 in + univar_pairs := (cl1,cl2) :: (cl2,cl1) :: old_univars; + let cstrs = subtype_rec env trace t1 t2 cstrs in + univar_pairs := old_univars; + cstrs | (_, _) -> - (trace, t1, t2)::cstrs + (trace, t1, t2, !univar_pairs)::cstrs end and subtype_list env trace tl1 tl2 cstrs = @@ -2328,11 +2681,13 @@ and subtype_fields env trace ty1 ty2 cstrs = let (fields1, rest1) = flatten_fields ty1 in let (fields2, rest2) = flatten_fields ty2 in let (pairs, miss1, miss2) = associate_fields fields1 fields2 in - [(trace, rest1, build_fields (repr ty2).level miss2 (newvar ()))] - @ + (trace, rest1, build_fields (repr ty2).level miss2 (newvar ()), + !univar_pairs) + :: begin match rest2.desc with Tnil -> [] - | _ -> [(trace, build_fields (repr ty1).level miss1 rest1, rest2)] + | _ -> + [trace, build_fields (repr ty1).level miss1 rest1, rest2, !univar_pairs] end @ (List.fold_left @@ -2343,14 +2698,15 @@ and subtype_fields env trace ty1 ty2 cstrs = let subtype env ty1 ty2 = TypePairs.clear subtypes; + univar_pairs := []; (* Build constraint set. *) let cstrs = subtype_rec env [(ty1, ty2)] ty1 ty2 [] in TypePairs.clear subtypes; (* Enforce constraints. *) function () -> List.iter - (function (trace0, t1, t2) -> - try unify env t1 t2 with Unify trace -> + (function (trace0, t1, t2, pairs) -> + try unify_pairs env t1 t2 pairs with Unify trace -> raise (Subtype (expand_trace env (List.rev trace0), List.tl (List.tl trace)))) (List.rev cstrs) @@ -2444,7 +2800,7 @@ let rec normalize_type_rec env ty = | Some (n, v :: l) -> let v' = repr v in begin match v'.desc with - | Tvar -> if v' != v then nm := Some (n, v' :: l) + | Tvar|Tunivar -> if v' != v then nm := Some (n, v' :: l) | Tnil -> ty.desc <- Tconstr (n, l, ref Mnil) | _ -> nm := None end @@ -2484,7 +2840,7 @@ let normalize_type env ty = let rec nondep_type_rec env id ty = let ty = repr ty in match ty.desc with - Tvar -> ty + Tvar | Tunivar -> ty | Tsubst ty -> ty | _ -> let desc = ty.desc in @@ -2532,7 +2888,8 @@ let rec nondep_type_rec env id ty = more.desc <- ty.desc; let more' = if static then newgenvar () else more in (* Return a new copy *) - let row = copy_row (nondep_type_rec env id) row true more' in + let row = + copy_row (nondep_type_rec env id) true row true more' in match row.row_name with Some (p, tl) when Path.isfree id p -> Tvariant {row with row_name = None} diff --git a/typing/ctype.mli b/typing/ctype.mli index 4510dfafc..ce590e04a 100644 --- a/typing/ctype.mli +++ b/typing/ctype.mli @@ -83,6 +83,15 @@ val generalize: type_expr -> unit (* Generalize in-place the given type *) val iterative_generalization: int -> type_expr list -> type_expr list (* Efficient repeated generalization of a type *) +val generalize_expansive: type_expr -> unit + (* Generalize the structure of a type, making variables + non-generalizable *) +val generalize_global: type_expr -> unit + (* Same, but variables are lowered to !global_level *) +val generalize_structure: type_expr -> unit + (* Same, but variables are only lowered to !current_level *) +val generalize_spine: type_expr -> unit + (* Special function to generalize a method during inference *) val make_nongen: type_expr -> unit (* Make non-generalizable the given type *) val correct_levels: type_expr -> type_expr @@ -98,8 +107,6 @@ val instance_list: type_expr list -> type_expr list val instance_constructor: constructor_description -> type_expr list * type_expr (* Same, for a constructor *) -val instance_label: label_description -> type_expr * type_expr - (* Same, for a label *) val instance_parameterized_type: type_expr list -> type_expr -> type_expr list * type_expr val instance_parameterized_type_2: @@ -107,6 +114,12 @@ val instance_parameterized_type_2: type_expr list * type_expr list * type_expr val instance_class: type_expr list -> class_type -> type_expr list * class_type +val instance_poly: + bool -> type_expr list -> type_expr -> type_expr list * type_expr + (* Take an instance of a type scheme containing free univars *) +val instance_label: + bool -> label_description -> type_expr list * type_expr * type_expr + (* Same, for a label *) val apply: Env.t -> type_expr list -> type_expr -> type_expr list -> type_expr (* [apply [p1...pN] t [a1...aN]] match the arguments [ai] to @@ -120,6 +133,9 @@ val enforce_constraints: Env.t -> type_expr -> unit val unify: Env.t -> type_expr -> type_expr -> unit (* Unify the two types given. Raise [Unify] if not possible. *) +val unify_var: Env.t -> type_expr -> type_expr -> unit + (* Same as [unify], but allow free univars when first type + is a variable. *) val filter_arrow: Env.t -> type_expr -> label -> type_expr * type_expr (* A special case of unification (with l:'a -> 'b). *) val filter_method: Env.t -> string -> private_flag -> type_expr -> type_expr diff --git a/typing/oprint.ml b/typing/oprint.ml index e7042d124..4a16f45a8 100644 --- a/typing/oprint.ml +++ b/typing/oprint.ml @@ -116,10 +116,20 @@ let rec print_list pr sep ppf = let pr_present = print_list (fun ppf s -> fprintf ppf "`%s" s) (fun ppf -> fprintf ppf "@ ") +let pr_vars = + print_list (fun ppf s -> fprintf ppf "'%s" s) (fun ppf -> fprintf ppf "@ ") + let rec print_out_type ppf = function - Otyp_alias (ty, s) -> fprintf ppf "@[%a as '%s@]" print_out_type ty s - | ty -> print_out_type_1 ppf ty + | Otyp_alias (ty, s) -> + fprintf ppf "@[%a as '%s@]" print_out_type ty s + | Otyp_poly (sl, ty) -> + fprintf ppf "@[%a.@ %a@]" + pr_vars sl + print_out_type ty + | ty -> + print_out_type_1 ppf ty + and print_out_type_1 ppf = function Otyp_arrow (lab, ty1, ty2) -> @@ -158,10 +168,10 @@ and print_simple_out_type ppf = in fprintf ppf "%s[%s@[@[%a@]%a]@]" (if non_gen then "_" else "") (if closed then if tags = None then " " else "< " - else if tags = None then "> " - else "? ") - print_fields row_fields print_present tags - | Otyp_alias (_, _) | Otyp_arrow (_, _, _) | Otyp_tuple _ as ty -> + else if tags = None then "> " else "? ") + print_fields row_fields + print_present tags + | Otyp_alias _ | Otyp_poly _ | Otyp_arrow _ | Otyp_tuple _ as ty -> fprintf ppf "@[<1>(%a)@]" print_out_type ty | Otyp_abstract | Otyp_sum _ | Otyp_record _ | Otyp_manifest (_, _) -> () and print_fields rest ppf = diff --git a/typing/outcometree.mli b/typing/outcometree.mli index b1be465c4..6ab7cdfd8 100644 --- a/typing/outcometree.mli +++ b/typing/outcometree.mli @@ -56,6 +56,7 @@ type out_type = | Otyp_var of bool * string | Otyp_variant of bool * out_variant * bool * (string list) option + | Otyp_poly of string list * out_type and out_variant = | Ovar_fields of (string * bool * out_type list) list | Ovar_name of out_ident * out_type list diff --git a/typing/parmatch.ml b/typing/parmatch.ml index 9ef2b7c4a..0a63dc632 100644 --- a/typing/parmatch.ml +++ b/typing/parmatch.ml @@ -380,7 +380,7 @@ let full_match tdefs force env = match env with env in let row = Btype.row_repr row in - if force then begin + if force && not row.row_fixed then begin (* force=true, we are called from check_partial, and must close *) let (ok, nm) = List.fold_left diff --git a/typing/printtyp.ml b/typing/printtyp.ml index 8b28c49da..3bece5747 100644 --- a/typing/printtyp.ml +++ b/typing/printtyp.ml @@ -24,6 +24,16 @@ open Types open Btype open Outcometree +(* Redefine it here since goal differs *) + +let rec opened_object ty = + match (repr ty).desc with + Tobject (t, _) -> opened_object t + | Tfield(_, _, _, t) -> opened_object t + | Tvar -> true + | Tunivar -> true + | _ -> false + (* Print a long identifier *) let rec longident ppf = function @@ -83,21 +93,35 @@ let name_of_type t = let check_name_of_type t = ignore(name_of_type t) -let print_name_of_type ppf t = fprintf ppf "%s" (name_of_type t) +let non_gen_mark sch ty = + if sch && ty.desc = Tvar && ty.level <> generic_level then "_" else "" -let visited_objects = ref ([] : type_expr list) -let aliased = ref ([] : type_expr list) - -let is_aliased ty = List.memq ty !aliased -let add_alias ty = - if not (is_aliased ty) then aliased := ty :: !aliased +let print_name_of_type sch ppf t = + fprintf ppf "'%s%s" (non_gen_mark sch t) (name_of_type t) let proxy ty = let ty = repr ty in match ty.desc with | Tvariant row -> Btype.row_more row + | Tobject (ty, _) -> + let rec proxy_obj ty = + let ty = repr ty in + match ty.desc with + Tfield (_, _, _, ty) -> proxy_obj ty + | Tvar | Tnil | Tunivar -> ty + | _ -> assert false + in proxy_obj ty | _ -> ty +let visited_objects = ref ([] : type_expr list) +let aliased = ref ([] : type_expr list) +let delayed = ref ([] : type_expr list) + +let is_aliased ty = List.memq (proxy ty) !aliased +let add_alias ty = + let px = proxy ty in + if not (is_aliased px) then aliased := px :: !aliased + let namable_row row = row.row_name <> None && List.for_all @@ -139,9 +163,14 @@ let rec mark_loops_rec visited ty = visited_objects := px :: !visited_objects; begin match !nm with | None -> - mark_loops_rec visited fi + let fields, _ = flatten_fields fi in + List.iter + (fun (_, kind, ty) -> + if field_kind_repr kind = Fpresent then + mark_loops_rec visited ty) + fields | Some (_, l) -> - List.iter (mark_loops_rec visited) l + List.iter (mark_loops_rec visited) (List.tl l) end end | Tfield(_, kind, ty1, ty2) when field_kind_repr kind = Fpresent -> @@ -151,22 +180,26 @@ let rec mark_loops_rec visited ty = | Tnil -> () | Tsubst ty -> mark_loops_rec visited ty | Tlink _ -> fatal_error "Printtyp.mark_loops_rec (2)" + | Tpoly (ty, tyl) -> + List.iter (fun t -> add_alias t) tyl; + mark_loops_rec visited ty + | Tunivar -> () let mark_loops ty = normalize_type Env.empty ty; mark_loops_rec [] ty;; let reset_loop_marks () = - visited_objects := []; aliased := [] + visited_objects := []; aliased := []; delayed := [] let reset () = reset_names (); reset_loop_marks () let reset_and_mark_loops ty = - reset (); mark_loops ty;; + reset (); mark_loops ty let reset_and_mark_loops_list tyl = - reset (); List.iter mark_loops tyl;; + reset (); List.iter mark_loops tyl (* Disabled in classic mode when printing an unification error *) let print_labels = ref true @@ -176,12 +209,12 @@ let print_label ppf l = let rec tree_of_typexp sch ty = let ty = repr ty in let px = proxy ty in - if List.mem_assq px !names then - let mark = if ty.desc = Tvar then is_non_gen sch px else false in + if List.mem_assq px !names && not (List.memq px !delayed) then + let mark = is_non_gen sch px in Otyp_var (mark, name_of_type px) else let pr_typ () = - (match ty.desc with + match ty.desc with | Tvar -> Otyp_var (is_non_gen sch ty, name_of_type ty) | Tarrow(l, ty1, ty2, _) -> @@ -239,13 +272,25 @@ let rec tree_of_typexp sch ty = Otyp_variant (non_gen, Ovar_fields fields, row.row_closed, tags) end | Tobject (fi, nm) -> - tree_of_typobject sch ty fi nm + tree_of_typobject sch fi nm | Tsubst ty -> tree_of_typexp sch ty | Tlink _ | Tnil | Tfield _ -> fatal_error "Printtyp.tree_of_typexp" - ) in - if is_aliased px then begin + | Tpoly (ty, []) -> + tree_of_typexp sch ty + | Tpoly (ty, tyl) -> + let tyl = List.map repr tyl in + let tyl = List.filter is_aliased tyl in + if tyl = [] then tree_of_typexp sch ty else + let tl = List.map name_of_type tyl in + delayed := tyl @ !delayed; + Otyp_poly (tl, tree_of_typexp sch ty) + | Tunivar -> + Otyp_var (false, name_of_type ty) + in + if List.memq px !delayed then delayed := List.filter ((!=) px) !delayed; + if is_aliased px && ty.desc <> Tvar && ty.desc <> Tunivar then begin check_name_of_type px; Otyp_alias (pr_typ (), name_of_type px) end else pr_typ () @@ -266,7 +311,7 @@ and tree_of_typlist sch = function let tr = tree_of_typexp sch ty in tr :: tree_of_typlist sch tyl -and tree_of_typobject sch ty fi nm = +and tree_of_typobject sch fi nm = begin match !nm with | None -> let pr_fields fi = @@ -283,8 +328,8 @@ and tree_of_typobject sch ty fi nm = tree_of_typfields sch rest sorted_fields in let (fields, rest) = pr_fields fi in Otyp_object (fields, rest) - | Some (p, {desc = Tvar} :: tyl) -> - let non_gen = is_non_gen sch ty in + | Some (p, ty :: tyl) -> + let non_gen = is_non_gen sch (repr ty) in let args = tree_of_typlist sch tyl in Otyp_class (non_gen, tree_of_path p, args) | _ -> @@ -292,13 +337,13 @@ and tree_of_typobject sch ty fi nm = end and is_non_gen sch ty = - sch && ty.level <> generic_level + sch && ty.desc = Tvar && ty.level <> generic_level and tree_of_typfields sch rest = function | [] -> let rest = match rest.desc with - | Tvar -> Some (is_non_gen sch rest) + | Tvar | Tunivar -> Some (is_non_gen sch rest) | Tnil -> None | _ -> fatal_error "typfields (1)" in @@ -362,7 +407,7 @@ let rec tree_of_type_decl id decl = let params = filter_params decl.type_params in - aliased := params @ !aliased; + List.iter add_alias params; List.iter mark_loops params; List.iter check_name_of_type (List.map proxy params); begin match decl.type_manifest with @@ -485,6 +530,12 @@ let tree_of_metho sch concrete csil (lab, kind, ty) = end else csil +let prepare_class_field ty = + let ty = repr ty in + match ty.desc with + Tpoly(ty, _) -> mark_loops ty + | _ -> mark_loops ty + let rec prepare_class_type params = function | Tcty_constr (p, tyl, cty) -> let sty = Ctype.self_type cty in @@ -501,11 +552,11 @@ let rec prepare_class_type params = function let sty = repr sign.cty_self in (* Self may have a name *) if List.memq sty !visited_objects then add_alias sty - else visited_objects := sty :: !visited_objects; + else visited_objects := proxy sty :: !visited_objects; let (fields, _) = Ctype.flatten_fields (Ctype.object_fields sign.cty_self) in - List.iter (fun (_, _, ty) -> mark_loops ty) fields; + List.iter (fun (_, _, ty) -> prepare_class_field ty) fields; Vars.iter (fun _ (_, ty) -> mark_loops ty) sign.cty_vars | Tcty_fun (_, ty, cty) -> mark_loops ty; @@ -524,7 +575,8 @@ let rec tree_of_class_type sch params = | Tcty_signature sign -> let sty = repr sign.cty_self in let self_ty = - if is_aliased sty then Some (Otyp_var (false, name_of_type sty)) + if is_aliased sty then + Some (Otyp_var (false, name_of_type (proxy sty))) else None in let (fields, _) = @@ -574,13 +626,13 @@ let tree_of_class_declaration id cl = let params = filter_params cl.cty_params in reset (); - aliased := params @ !aliased; + List.iter add_alias params; prepare_class_type params cl.cty_type; let sty = self_type cl.cty_type in List.iter mark_loops params; List.iter check_name_of_type (List.map proxy params); - if is_aliased sty then check_name_of_type sty; + if is_aliased sty then check_name_of_type (proxy sty); let vir_flag = cl.cty_new = None in Osig_class @@ -600,7 +652,7 @@ let tree_of_cltype_declaration id cl = List.iter mark_loops params; List.iter check_name_of_type (List.map proxy params); - if is_aliased sty then check_name_of_type sty; + if is_aliased sty then check_name_of_type (proxy sty); let sign = Ctype.signature_of_class_type cl.clty_type in diff --git a/typing/subst.ml b/typing/subst.ml index 0c04771cb..66646c157 100644 --- a/typing/subst.ml +++ b/typing/subst.ml @@ -58,17 +58,17 @@ let type_path s = function let new_id = ref (-1) let reset_for_saving () = new_id := -1 -let newpersvar () = - decr new_id; { desc = Tvar; level = generic_level; id = !new_id } +let newpersty desc = + decr new_id; { desc = desc; level = generic_level; id = !new_id } (* Similar to [Ctype.nondep_type_rec]. *) let rec typexp s ty = let ty = repr ty in match ty.desc with - Tvar -> + Tvar | Tunivar -> if s.for_saving then - let ty' = newpersvar () in - save_desc ty Tvar; ty.desc <- Tsubst ty'; ty' + let ty' = newpersty ty.desc in + save_desc ty ty.desc; ty.desc <- Tsubst ty'; ty' else ty | Tsubst ty -> ty @@ -80,7 +80,7 @@ let rec typexp s ty = let desc = ty.desc in save_desc ty desc; (* Make a stub *) - let ty' = if s.for_saving then newpersvar () else newgenvar () in + let ty' = if s.for_saving then newpersty Tvar else newgenvar () in ty.desc <- Tsubst ty'; ty'.desc <- begin match desc with @@ -97,20 +97,25 @@ let rec typexp s ty = let more = repr row.row_more in (* We must substitute in a subtle way *) begin match more.desc with - Tsubst ty2 -> + Tsubst ({desc=Tvariant _} as ty2) -> (* This variant type has been already copied *) ty.desc <- Tsubst ty2; (* avoid Tlink in the new type *) Tlink ty2 | _ -> let static = static_row row in + (* Various cases for the row variable *) + let more' = + match more.desc with Tsubst ty -> ty + | _ -> + if s.for_saving then newpersty more.desc else + if static then newgenvar () else more + in (* Register new type first for recursion *) save_desc more more.desc; more.desc <- ty.desc; - let more' = - if s.for_saving then newpersvar () else - if static then newgenvar () else more in (* Return a new copy *) - let row = copy_row (typexp s) row (not s.for_saving) more' in + let row = + copy_row (typexp s) true row (not s.for_saving) more' in let row = if s.for_saving then {row with row_bound = []} else row in match row.row_name with diff --git a/typing/typeclass.ml b/typing/typeclass.ml index 3ede8f6fc..511ae4f67 100644 --- a/typing/typeclass.ml +++ b/typing/typeclass.ml @@ -10,7 +10,7 @@ (* *) (***********************************************************************) -(* $Id$ *) +(* typeclass.ml,v 1.57.4.6 2002/02/15 14:26:04 garrigue Exp *) open Misc open Parsetree @@ -233,6 +233,19 @@ let virtual_method val_env meths self_type lab priv sty loc = try Ctype.unify val_env ty ty' with Ctype.Unify trace -> raise(Error(loc, Method_type_mismatch (lab, trace))) +let declare_method val_env meths self_type lab priv sty loc = + let (_, ty') = + Ctype.filter_self_method val_env lab priv meths self_type + in + let ty = + match sty.ptyp_desc with + Ptyp_poly ([],sty) -> transl_simple_type_univars val_env sty + | _ -> transl_simple_type val_env false sty + in + begin try Ctype.unify val_env ty ty' with Ctype.Unify trace -> + raise(Error(loc, Method_type_mismatch (lab, trace))) + end + let type_constraint val_env sty sty' loc = let ty = transl_simple_type val_env false sty in let ty' = transl_simple_type val_env false sty' in @@ -279,11 +292,11 @@ let rec class_type_field env self_type meths (val_sig, concr_meths) = (Vars.add lab (mut, ty) val_sig, concr_meths) | Pctf_virt (lab, priv, sty, loc) -> - virtual_method env meths self_type lab priv sty loc; + declare_method env meths self_type lab priv sty loc; (val_sig, concr_meths) | Pctf_meth (lab, priv, sty, loc) -> - virtual_method env meths self_type lab priv sty loc; + declare_method env meths self_type lab priv sty loc; (val_sig, Concr.add lab concr_meths) | Pctf_cstr (sty, sty', loc) -> @@ -399,10 +412,15 @@ let rec class_field cl_num self_type meths vars | Pcf_val (lab, mut, sexp, loc) -> if StringSet.mem lab inh_vals then Location.prerr_warning loc (Warnings.Hide_instance_variable lab); + if !Clflags.principal then Ctype.begin_def (); let exp = try type_exp val_env sexp with Ctype.Unify [(ty, _)] -> raise(Error(loc, Make_nongen_seltype ty)) in + if !Clflags.principal then begin + Ctype.end_def (); + Ctype.generalize_structure exp.exp_type + end; let (id, val_env, met_env, par_env) = enter_val cl_num vars lab mut exp.exp_type val_env met_env par_env in @@ -414,23 +432,38 @@ let rec class_field cl_num self_type meths vars (val_env, met_env, par_env, fields, concr_meths, inh_vals) | Pcf_meth (lab, priv, expr, loc) -> - let meth_expr = make_method cl_num expr in - Ctype.raise_nongen_level (); let (_, ty) = Ctype.filter_self_method val_env lab priv meths self_type in - let meth_type = Ctype.newvar () in - let (obj_ty, res_ty) = Ctype.filter_arrow val_env meth_type "" in - Ctype.unify val_env obj_ty self_type; - Ctype.unify val_env res_ty ty; - let ty' = type_approx met_env expr in - begin try Ctype.unify met_env ty' res_ty with Ctype.Unify trace -> - raise(Typecore.Error(expr.pexp_loc, Expr_type_clash(trace))) + begin try match expr.pexp_desc with + Pexp_poly (sbody, sty) -> + begin match sty with None -> () + | Some sty -> + Ctype.unify val_env + (Typetexp.transl_simple_type val_env false sty) ty + end; + begin match (Ctype.repr ty).desc with + Tvar -> + let ty' = Ctype.newvar () in + Ctype.unify val_env (Ctype.newty (Tpoly (ty', []))) ty; + Ctype.unify val_env (type_approx val_env sbody) ty' + | Tpoly (ty1, tl) -> + let _, ty1' = Ctype.instance_poly false tl ty1 in + let ty2 = type_approx val_env sbody in + Ctype.unify val_env ty2 ty1' + | _ -> assert false + end + | _ -> assert false + with Ctype.Unify trace -> + raise(Error(loc, Method_type_mismatch (lab, trace))) end; - Ctype.end_def (); + let meth_expr = make_method cl_num expr in let vars_local = !vars in + let field = lazy begin + let meth_type = + Ctype.newty (Tarrow("", self_type, Ctype.instance ty, Cok)) in Ctype.raise_nongen_level (); vars := vars_local; let texp = type_expect met_env meth_expr meth_type in @@ -480,10 +513,9 @@ let rec class_field cl_num self_type meths vars let field = lazy begin Ctype.raise_nongen_level (); - let meth_type = Ctype.newvar () in - let (obj_ty, res_ty) = Ctype.filter_arrow val_env meth_type "" in - Ctype.unify val_env obj_ty self_type; - Ctype.unify val_env res_ty (Ctype.instance Predef.type_unit); + let meth_type = + Ctype.newty + (Tarrow ("", self_type, Ctype.instance Predef.type_unit, Cok)) in vars := vars_local; let texp = type_expect met_env expr meth_type in Ctype.end_def (); @@ -518,9 +550,16 @@ and class_structure cl_num val_env met_env (spat, str) = (val_env, meth_env, par_env, [], Concr.empty, StringSet.empty) str in + Ctype.unify val_env self_type (Ctype.newvar ()); + let methods = + if !Clflags.principal then + fst (Ctype.flatten_fields (Ctype.object_fields self_type)) + else [] in + List.iter (fun (_,_,ty) -> Ctype.generalize_spine ty) methods; let vars_final = !vars in let fields = List.map Lazy.force (List.rev fields) in vars := vars_final; + List.iter (fun (_,_,ty) -> Ctype.unify val_env ty (Ctype.newvar ())) methods; {cl_field = fields; cl_meths = Meths.map (function (id, ty) -> id) !meths}, @@ -592,10 +631,15 @@ and class_expr cl_num val_env met_env scl = Pcl_let(Default, [spat, smatch], sbody)})} in class_expr cl_num val_env met_env sfun - | Pcl_fun (l, _, spat, scl') -> + | Pcl_fun (l, None, spat, scl') -> + if !Clflags.principal then Ctype.begin_def (); let (pat, pv, val_env, met_env) = Typecore.type_class_arg_pattern cl_num val_env met_env l spat in + if !Clflags.principal then begin + Ctype.end_def (); + iter_pattern (fun {pat_type=ty} -> Ctype.generalize_structure ty) pat + end; let pv = List.map (function (id, id', ty) -> @@ -625,7 +669,7 @@ and class_expr cl_num val_env met_env scl = (Warnings.Other "This optional argument cannot be erased"); {cl_desc = Tclass_fun (pat, pv, cl, partial); cl_loc = scl.pcl_loc; - cl_type = Tcty_fun (l, pat.pat_type, cl.cl_type)} + cl_type = Tcty_fun (l, Ctype.instance pat.pat_type, cl.cl_type)} | Pcl_apply (scl', sargs) -> let cl = class_expr cl_num val_env met_env scl' in let rec nonopt_labels ls ty_fun = @@ -826,6 +870,7 @@ let rec initial_env define_class approx (* Temporary type for the class constructor *) let constr_type = approx cl.pci_expr in + if !Clflags.principal then Ctype.generalize_spine constr_type; let dummy_cty = Tcty_signature { cty_self = Ctype.newvar (); @@ -948,7 +993,9 @@ let class_infos define_class kind (* Type of the class constructor *) begin try - Ctype.unify env (constructor_type constr obj_type) constr_type + Ctype.unify env + (constructor_type constr obj_type) + (Ctype.instance constr_type) with Ctype.Unify trace -> raise(Error(cl.pci_loc, Constructor_type_mismatch (cl.pci_name, trace))) @@ -998,7 +1045,7 @@ let class_infos define_class kind cty_new = match cl.pci_virt with Virtual -> None - | Concrete -> Some constr_type} + | Concrete -> Some (Ctype.instance constr_type)} in let obj_abbr = {type_params = obj_params; diff --git a/typing/typecore.ml b/typing/typecore.ml index 025f6716e..b585295c9 100644 --- a/typing/typecore.ml +++ b/typing/typecore.ml @@ -55,6 +55,7 @@ type error = | Masked_instance_variable of Longident.t | Not_a_variant_type of Longident.t | Incoherent_label_order + | Less_general of string * (type_expr * type_expr) list exception Error of Location.t * error @@ -177,18 +178,19 @@ let rec build_as_type env p = | Tpat_variant(l, p', _) -> let ty = may_map (build_as_type env) p' in newty (Tvariant{row_fields=[l, Rpresent ty]; row_more=newvar(); - row_bound=[]; row_name=None; row_closed=false}) + row_bound=[]; row_name=None; + row_fixed=false; row_closed=false}) | Tpat_record lpl -> let lbl = fst(List.hd lpl) in let ty = newvar () in let do_label lbl = - let ty_arg, ty_res = instance_label lbl in + let _, ty_arg, ty_res = instance_label false lbl in unify_pat env {p with pat_type = ty} ty_res; if lbl.lbl_mut = Immutable && List.mem_assoc lbl lpl then begin let arg = List.assoc lbl lpl in unify_pat env {arg with pat_type = build_as_type env arg} ty_arg end else begin - let ty_arg', ty_res' = instance_label lbl in + let _, ty_arg', ty_res' = instance_label false lbl in unify env ty_arg ty_arg'; unify_pat env p ty_res' end in @@ -242,7 +244,7 @@ let build_or_pat env loc lid = ([],[]) fields in let row = { row_fields = List.rev fields; row_more = newvar(); row_bound = !bound; - row_closed = false; row_name = Some (path, tyl) } + row_closed = false; row_fixed = false; row_name = Some (path, tyl) } in let ty = newty (Tvariant row) in let pats = @@ -326,6 +328,7 @@ let rec type_pat env sp = row_bound = arg_type; row_closed = false; row_more = newvar (); + row_fixed = false; row_name = None } in { pat_desc = Tpat_variant(l, arg, row); pat_loc = sp.ppat_loc; @@ -346,7 +349,7 @@ let rec type_pat env sp = Env.lookup_label lid env with Not_found -> raise(Error(sp.ppat_loc, Unbound_label lid)) in - let (ty_arg, ty_res) = instance_label label in + let (_, ty_arg, ty_res) = instance_label false label in begin try unify env ty_res ty with Unify trace -> @@ -470,7 +473,7 @@ let check_unused_variant pat = begin match opat with None -> assert false | Some pat -> List.iter (unify_pat pat.pat_env pat) (ty::tl) end - | Reither (c, l, true, e) -> + | Reither (c, l, true, e) when not row.row_fixed -> e := Some (Reither (c, [], false, ref None)) | _ -> () end @@ -675,6 +678,23 @@ let rec list_labels_aux env visited ls ty_fun = let list_labels env ty = list_labels_aux env [] [] ty +(* Check that all univars are safe in a type *) +let check_univars env kind exp ty_expected vars = + let vars' = + List.filter + (fun t -> + let t = repr t in + generalize t; + if t.desc = Tvar && t.level = generic_level then + (t.desc <- Tunivar; true) + else false) + vars in + if List.length vars = List.length vars' then () else + let ty = newgenty (Tpoly(repr exp.exp_type, vars')) + and ty_expected = repr ty_expected in + raise (Error (exp.exp_loc, + Less_general(kind, [ty, ty; ty_expected, ty_expected]))) + (* Hack to allow coercion of self. Will clean-up later. *) let self_coercion = ref ([] : (Path.t * Location.t list ref) list) @@ -732,8 +752,14 @@ let rec type_exp env sexp = | Pexp_function _ -> (* defined in type_expect *) type_expect env sexp (newvar()) | Pexp_apply(sfunct, sargs) -> + if !Clflags.principal then begin_def (); let funct = type_exp env sfunct in + if !Clflags.principal then begin + end_def (); + generalize_structure funct.exp_type + end; let (args, ty_res) = type_application env funct sargs in + let funct = {funct with exp_type = instance funct.exp_type} in { exp_desc = Texp_apply(funct, args); exp_loc = sexp.pexp_loc; exp_type = ty_res; @@ -773,6 +799,7 @@ let rec type_exp env sexp = row_more = newvar (); row_bound = []; row_closed = false; + row_fixed = false; row_name = None}); exp_env = env } | Pexp_record(lid_sexp_list, opt_sexp) -> @@ -784,13 +811,22 @@ let rec type_exp env sexp = Env.lookup_label lid env with Not_found -> raise(Error(sexp.pexp_loc, Unbound_label lid)) in - let (ty_arg, ty_res) = instance_label label in + begin_def (); + if !Clflags.principal then begin_def (); + let (vars, ty_arg, ty_res) = instance_label true label in + if !Clflags.principal then begin + end_def (); + generalize_structure ty_arg; + generalize_structure ty_res + end; begin try - unify env ty_res ty + unify env (instance ty_res) ty with Unify trace -> raise(Error(sexp.pexp_loc, Label_mismatch(lid, trace))) end; - let arg = type_expect env sarg ty_arg in + let arg = type_argument env sarg ty_arg in + end_def (); + check_univars env "field value" arg label.lbl_arg vars; num_fields := Array.length label.lbl_all; (label, arg) in let lbl_exp_list = List.map type_label_exp lid_sexp_list in @@ -810,8 +846,8 @@ let rec type_exp env sexp = if List.for_all (fun (lbl',_) -> lbl'.lbl_pos <> lbl.lbl_pos) lbl_exp_list then begin - let ty_arg1, ty_res1 = instance_label lbl - and ty_arg2, ty_res2 = instance_label lbl in + let _, ty_arg1, ty_res1 = instance_label false lbl + and _, ty_arg2, ty_res2 = instance_label false lbl in unify env ty_exp ty_res1; unify env ty ty_res2; unify env ty_arg1 ty_arg2 @@ -844,7 +880,7 @@ let rec type_exp env sexp = Env.lookup_label lid env with Not_found -> raise(Error(sexp.pexp_loc, Unbound_label lid)) in - let (ty_arg, ty_res) = instance_label label in + let (_, ty_arg, ty_res) = instance_label false label in unify_exp env arg ty_res; { exp_desc = Texp_field(arg, label); exp_loc = sexp.pexp_loc; @@ -859,9 +895,12 @@ let rec type_exp env sexp = raise(Error(sexp.pexp_loc, Unbound_label lid)) in if label.lbl_mut = Immutable then raise(Error(sexp.pexp_loc, Label_not_mutable lid)); - let (ty_arg, ty_res) = instance_label label in + begin_def (); + let (vars, ty_arg, ty_res) = instance_label true label in unify_exp env record ty_res; let newval = type_expect env snewval ty_arg in + end_def (); + check_univars env "field value" newval label.lbl_arg vars; { exp_desc = Texp_setfield(record, label, newval); exp_loc = sexp.pexp_loc; exp_type = instance Predef.type_unit; @@ -922,8 +961,15 @@ let rec type_exp env sexp = let arg = type_exp env sarg in (arg, arg.exp_type) | (Some sty, None) -> + if !Clflags.principal then begin_def (); let ty = Typetexp.transl_simple_type env false sty in - (type_expect env sarg ty, ty) + if !Clflags.principal then begin + end_def (); + generalize_structure ty; + let ty1 = instance ty and ty2 = instance ty in + (type_expect env sarg ty1, ty2) + end else + (type_expect env sarg ty, ty) | (None, Some sty') -> let (ty', force) = Typetexp.transl_simple_type_delayed env sty' @@ -969,6 +1015,7 @@ let rec type_exp env sexp = exp_type = body.exp_type; exp_env = env } | Pexp_send (e, met) -> + if !Clflags.principal then begin_def (); let obj = type_exp env e in begin try let (exp, typ) = @@ -996,7 +1043,7 @@ let rec type_exp env sexp = let method_type = newvar () in let (obj_ty, res_ty) = filter_arrow env method_type "" in unify env obj_ty desc.val_type; - unify env res_ty typ; + unify env res_ty (instance typ); (Texp_apply({exp_desc = Texp_ident(Path.Pident method_id, {val_type = method_type; val_kind = Val_reg}); @@ -1015,6 +1062,29 @@ let rec type_exp env sexp = | _ -> (Texp_send(obj, Tmeth_name met), filter_method env met Public obj.exp_type) + in + if !Clflags.principal then begin + end_def (); + generalize_structure typ; + end; + let typ = + match repr typ with + {desc = Tpoly (ty, [])} -> + instance ty + | {desc = Tpoly (ty, tl); level = l} -> + if !Clflags.principal && l <> generic_level then + Location.prerr_warning sexp.pexp_loc + (Warnings.Other + "This use of a polymorphic method is not principal"); + snd (instance_poly false tl ty) + | {desc = Tvar} as ty -> + let ty' = newvar () in + unify env (instance ty) (newty(Tpoly(ty',[]))); + (* if not !Clflags.nolabels then + Location.prerr_warning loc (Warnings.Unknown_method met); *) + ty' + | _ -> + assert false in { exp_desc = exp; exp_loc = sexp.pexp_loc; @@ -1042,7 +1112,7 @@ let rec type_exp env sexp = let (path, desc) = Env.lookup_value (Longident.Lident lab) env in match desc.val_kind with Val_ivar (Mutable, cl_num) -> - let newval = type_expect env snewval desc.val_type in + let newval = type_expect env snewval (instance desc.val_type) in let (path_self, _) = Env.lookup_value (Longident.Lident ("self-" ^ cl_num)) env in @@ -1080,7 +1150,7 @@ let rec type_exp env sexp = let type_override (lab, snewval) = begin try let (id, _, ty) = Vars.find lab !vars in - (Path.Pident id, type_expect env snewval ty) + (Path.Pident id, type_expect env snewval (instance ty)) with Not_found -> raise(Error(sexp.pexp_loc, Unbound_instance_variable lab)) @@ -1138,31 +1208,45 @@ let rec type_exp env sexp = exp_type = instance (Predef.type_lazy_t arg.exp_type); exp_env = env; } + | Pexp_poly _ -> + assert false -and type_argument env sarg ty_expected = +and type_argument env sarg ty_expected' = + (* ty_expected' may be generic *) let no_labels ty = let ls, tvar = list_labels env ty in not tvar && List.for_all ((=) "") ls in - match expand_head env ty_expected, sarg with + let ty_expected = instance ty_expected' in + match expand_head env ty_expected', sarg with | _, {pexp_desc = Pexp_function(l,_,_)} when not (is_optional l) -> type_expect env sarg ty_expected - | {desc = Tarrow("",ty_arg,ty_res,_)}, _ -> + | {desc = Tarrow("",ty_arg,ty_res,_); level = lv}, _ -> (* apply optional arguments when expected type is "" *) (* we must be very careful about not breaking the semantics *) + if !Clflags.principal then begin_def (); let texp = type_exp env sarg in + if !Clflags.principal then begin + end_def (); + generalize_structure texp.exp_type + end; let rec make_args args ty_fun = match (expand_head env ty_fun).desc with | Tarrow (l,ty_arg,ty_fun,_) when is_optional l -> make_args - ((Some(option_none ty_arg sarg.pexp_loc), Optional) :: args) + ((Some(option_none (instance ty_arg) sarg.pexp_loc), Optional) + :: args) ty_fun | Tarrow (l,_,ty_res',_) when l = "" || !Clflags.classic -> args, ty_fun, no_labels ty_res' | Tvar -> args, ty_fun, false | _ -> [], texp.exp_type, false in - let args, ty_fun, simple_res = make_args [] texp.exp_type in + let args, ty_fun', simple_res = make_args [] texp.exp_type in + let warn = !Clflags.principal && + (lv <> generic_level || (repr ty_fun').level <> generic_level) + and texp = {texp with exp_type = instance texp.exp_type} + and ty_fun = instance ty_fun' in if not (simple_res || no_labels ty_res) then begin unify_exp env texp ty_expected; texp @@ -1184,6 +1268,8 @@ and type_argument env sarg ty_expected = Texp_apply (texp, args@ [Some eta_var, Required])}], Total) } in + if warn then Location.prerr_warning texp.exp_loc + (Warnings.Other "Eliminated optional argument without principality"); if is_nonexpansive texp then func texp else (* let-expand to have side effects *) let let_pat, let_var = var_pair "let" texp.exp_type in @@ -1194,6 +1280,7 @@ and type_argument env sarg ty_expected = type_expect env sarg ty_expected and type_application env funct sargs = + (* funct.exp_type may be generic *) let result_type omitted ty_fun = List.fold_left (fun ty_fun (l,ty,lv) -> newty2 lv (Tarrow(l,ty,ty_fun,Cok))) @@ -1209,7 +1296,7 @@ and type_application env funct sargs = (List.map (function None, x -> None, x | Some f, x -> Some (f ()), x) (List.rev args), - result_type omitted ty_fun) + instance (result_type omitted ty_fun)) | (l1, sarg1) :: sargl -> let (ty1, ty2) = match (expand_head env ty_fun).desc with @@ -1256,10 +1343,18 @@ and type_application env funct sargs = true) end in + let warned = ref false in let rec type_args args omitted ty_fun ty_old sargs more_sargs = match expand_head env ty_fun with {desc=Tarrow (l, ty, ty_fun, com); level=lv} as ty_fun' when (sargs <> [] || more_sargs <> []) && commu_repr com = Cok -> + let may_warn loc msg = + if not !warned && !Clflags.principal && lv <> generic_level + then begin + warned := true; + Location.prerr_warning loc (Warnings.Other msg) + end + in let name = label_name l and optional = if is_optional l then Optional else Required in let sargs, more_sargs, arg = @@ -1278,28 +1373,45 @@ and type_application env funct sargs = end else try let (l', sarg0, sargs, more_sargs) = try - let (l', sarg0, sargs1, sargs2) = extract_label name sargs - in (l', sarg0, sargs1 @ sargs2, more_sargs) + let (l', sarg0, sargs1, sargs2) = extract_label name sargs in + if sargs1 <> [] then + may_warn sarg0.pexp_loc + "Commuting this argument is not principal"; + (l', sarg0, sargs1 @ sargs2, more_sargs) with Not_found -> - let (l', sarg0, sargs1, sargs2) = extract_label name more_sargs - in (l', sarg0, sargs @ sargs1, sargs2) + let (l', sarg0, sargs1, sargs2) = + extract_label name more_sargs in + if sargs1 <> [] || sargs <> [] then + may_warn sarg0.pexp_loc + "Commuting this argument is not principal"; + (l', sarg0, sargs @ sargs1, sargs2) in sargs, more_sargs, if optional = Required || is_optional l' then Some (fun () -> type_argument env sarg0 ty) - else + else begin + may_warn sarg0.pexp_loc + "Using an optional argument here is not principal"; Some (fun () -> option_some (type_argument env sarg0 (extract_option_type env ty))) + end with Not_found -> sargs, more_sargs, if optional = Optional && (List.mem_assoc "" sargs || List.mem_assoc "" more_sargs) then begin + may_warn funct.exp_loc + "Eliminated an optional argument without principality"; ignored := (l,ty,lv) :: !ignored; - Some (fun () -> option_none ty Location.none) - end else None + Some (fun () -> option_none (instance ty) Location.none) + end else begin + may_warn funct.exp_loc + "Commuted an argument without principality"; + None + end in - let omitted = if arg = None then (l,ty,lv) :: omitted else omitted in + let omitted = + if arg = None then (l,ty,lv) :: omitted else omitted in let ty_old = if sargs = [] then ty_fun else ty_old in type_args ((arg,optional)::args) omitted ty_fun ty_old sargs more_sargs | _ -> @@ -1307,13 +1419,14 @@ and type_application env funct sargs = (l, sarg0) :: _ when ignore_labels -> raise(Error(sarg0.pexp_loc, Apply_wrong_label(l, ty_old))); | _ -> - type_unknown_args args omitted ty_fun (sargs @ more_sargs) + type_unknown_args args omitted (instance ty_fun) + (sargs @ more_sargs) in match funct.exp_desc, sargs with (* Special case for ignore: avoid discarding warning *) Texp_ident (_, {val_kind=Val_prim{Primitive.prim_name="%ignore"}}), ["", sarg] -> - let ty_arg, ty_res = filter_arrow env funct.exp_type "" in + let ty_arg, ty_res = filter_arrow env (instance funct.exp_type) "" in let exp = type_expect env sarg ty_arg in begin match expand_head env exp.exp_type with | {desc = Tarrow _} -> @@ -1343,14 +1456,20 @@ and type_construct env loc lid sarg explicit_arity ty_expected = if List.length sargs <> constr.cstr_arity then raise(Error(loc, Constructor_arity_mismatch (lid, constr.cstr_arity, List.length sargs))); + if !Clflags.principal then begin_def (); let (ty_args, ty_res) = instance_constructor constr in + if !Clflags.principal then begin + end_def (); + List.iter generalize_structure ty_args; + generalize_structure ty_res + end; let texp = { exp_desc = Texp_construct(constr, []); exp_loc = loc; - exp_type = ty_res; + exp_type = instance ty_res; exp_env = env } in unify_exp env texp ty_expected; - let args = List.map2 (type_expect env) sargs ty_args in + let args = List.map2 (type_argument env) sargs ty_args in { texp with exp_desc = Texp_construct(constr, args) } (* Typing of an expression with an expected type. @@ -1444,6 +1563,34 @@ and type_expect ?in_function env sexp ty_expected = exp_loc = sexp.pexp_loc; exp_type = newty (Tarrow(l, ty_arg, ty_res, Cok)); exp_env = env } + | Pexp_poly(sbody, sty) -> + let ty = + match sty with None -> repr ty_expected + | Some sty -> + let ty = Typetexp.transl_simple_type env false sty in + repr ty + in + let set_type ty = + unify_exp env + { exp_desc = Texp_tuple []; exp_loc = sexp.pexp_loc; + exp_type = ty; exp_env = env } ty_expected in + begin + match ty.desc with + Tpoly (ty', []) -> + if sty <> None then set_type ty; + let exp = type_expect env sbody ty' in + { exp with exp_type = ty } + | Tpoly (ty', tl) -> + if sty <> None then set_type ty; + (* One more level to generalize locally *) + begin_def (); + let vars, ty'' = instance_poly true tl ty' in + let exp = type_expect env sbody ty'' in + end_def (); + check_univars env "method" exp ty_expected vars; + { exp with exp_type = ty } + | _ -> assert false + end | _ -> let exp = type_exp env sexp in unify_exp env exp ty_expected; @@ -1470,7 +1617,15 @@ and type_cases ?in_function env ty_arg ty_res partial_loc caselist = let pat_env_list = List.map (fun (spat, sexp) -> + if !Clflags.principal then begin_def (); let (pat, ext_env) = type_pattern env spat in + let pat = + if !Clflags.principal then begin + end_def (); + iter_pattern (fun {pat_type=t} -> generalize_structure t) pat; + { pat with pat_type = instance pat.pat_type } + end else pat + in unify_pat env pat ty_arg'; (pat, ext_env)) caselist in @@ -1509,6 +1664,7 @@ and type_cases ?in_function env ty_arg ty_res partial_loc caselist = and type_let env rec_flag spat_sexp_list = begin_def(); + if !Clflags.principal then begin_def (); let (pat_list, new_env) = type_pattern_list env (List.map (fun (spat, sexp) -> spat) spat_sexp_list) in @@ -1516,6 +1672,15 @@ and type_let env rec_flag spat_sexp_list = List.iter2 (fun pat (_, sexp) -> unify_pat env pat (type_approx env sexp)) pat_list spat_sexp_list; + let pat_list = + if !Clflags.principal then begin + end_def (); + List.map + (fun pat -> + iter_pattern (fun pat -> generalize_structure pat.pat_type) pat; + {pat with pat_type = instance pat.pat_type}) + pat_list + end else pat_list in let exp_env = match rec_flag with Nonrecursive | Default -> env | Recursive -> new_env in let exp_list = @@ -1529,7 +1694,9 @@ and type_let env rec_flag spat_sexp_list = List.iter2 (fun pat exp -> if not (is_nonexpansive exp) then - iter_pattern (fun pat -> make_nongen pat.pat_type) pat) + let f = + if !Clflags.principal then generalize_expansive else make_nongen in + iter_pattern (fun pat -> f pat.pat_type) pat) pat_list exp_list; List.iter (fun pat -> iter_pattern (fun pat -> generalize pat.pat_type) pat) @@ -1550,6 +1717,7 @@ let type_expression env sexp = let exp = type_exp env sexp in end_def(); if is_nonexpansive exp then generalize exp.exp_type + else if !Clflags.principal then generalize_expansive exp.exp_type else make_nongen exp.exp_type; exp @@ -1690,3 +1858,7 @@ let report_error ppf = function fprintf ppf "This function is applied to arguments@ "; fprintf ppf "in an order different from other calls.@ "; fprintf ppf "This is only allowed when the real type is known." + | Less_general (kind, trace) -> + report_unification_error ppf trace + (fun ppf -> fprintf ppf "This %s has type" kind) + (fun ppf -> fprintf ppf "which is less general than") diff --git a/typing/typecore.mli b/typing/typecore.mli index 6df4002b5..78a8c7799 100644 --- a/typing/typecore.mli +++ b/typing/typecore.mli @@ -53,6 +53,7 @@ val type_argument: val option_some: Typedtree.expression -> Typedtree.expression val option_none: type_expr -> Location.t -> Typedtree.expression val extract_option_type: Env.t -> type_expr -> type_expr +val iter_pattern: (Typedtree.pattern -> unit) -> Typedtree.pattern -> unit val self_coercion : (Path.t * Location.t list ref) list ref @@ -88,6 +89,7 @@ type error = | Masked_instance_variable of Longident.t | Not_a_variant_type of Longident.t | Incoherent_label_order + | Less_general of string * (type_expr * type_expr) list exception Error of Location.t * error diff --git a/typing/typedecl.ml b/typing/typedecl.ml index 4fdbbed7c..4ae53bacd 100644 --- a/typing/typedecl.ml +++ b/typing/typedecl.ml @@ -87,11 +87,18 @@ module StringSet = let transl_declaration env (name, sdecl) id = (* Bind type parameters *) reset_type_variables(); + Ctype.begin_def (); let params = try List.map (enter_type_variable true) sdecl.ptype_params with Already_bound -> raise(Error(sdecl.ptype_loc, Repeated_parameter)) in + let cstrs = List.map + (fun (sty, sty', loc) -> + transl_simple_type env false sty, + transl_simple_type env false sty', loc) + sdecl.ptype_cstrs + in let decl = { type_params = params; type_arity = List.length params; @@ -125,7 +132,8 @@ let transl_declaration env (name, sdecl) id = let lbls' = List.map (fun (name, mut, arg) -> - (name, mut, transl_simple_type env true arg)) + let ty = transl_simple_type env true arg in + name, mut, match ty.desc with Tpoly(t,[]) -> t | _ -> ty) lbls in let rep = if List.for_all (fun (name, mut, arg) -> is_float env arg) lbls' @@ -147,13 +155,11 @@ let transl_declaration env (name, sdecl) id = (* Check constraints *) List.iter - (function (sty, sty', loc) -> - try - Ctype.unify env (transl_simple_type env false sty) - (transl_simple_type env false sty') - with Ctype.Unify tr -> - raise(Error(loc, Unconsistent_constraint tr))) - sdecl.ptype_cstrs; + (fun (ty, ty', loc) -> + try Ctype.unify env ty ty' with Ctype.Unify tr -> + raise(Error(loc, Unconsistent_constraint tr))) + cstrs; + Ctype.end_def (); (id, decl) @@ -201,6 +207,9 @@ let rec check_constraints_rec env loc visited ty = if not (List.for_all2 (Ctype.moregeneral env false) args' args) then raise (Error(loc, Constraint_failed (ty, ty'))); List.iter (check_constraints_rec env loc visited) args + | Tpoly (ty, tl) -> + let _, ty = Ctype.instance_poly false tl ty in + check_constraints_rec env loc visited ty | _ -> Btype.iter_type_expr (check_constraints_rec env loc visited) ty end @@ -376,7 +385,9 @@ let compute_variance env tvl nega posi ty = List.iter (compute_variance_rec posi nega) tyl | _ -> ()) (Btype.row_repr row).row_fields - | Tvar | Tnil | Tlink _ -> () + | Tpoly (ty, _) -> + compute_variance_rec posi nega ty + | Tvar | Tnil | Tlink _ | Tunivar -> () end in compute_variance_rec nega posi ty; diff --git a/typing/types.ml b/typing/types.ml index f1ed0cf01..0b9c4350f 100644 --- a/typing/types.ml +++ b/typing/types.ml @@ -35,12 +35,15 @@ and type_desc = | Tlink of type_expr | Tsubst of type_expr | Tvariant of row_desc + | Tunivar + | Tpoly of type_expr * type_expr list and row_desc = { row_fields: (label * row_field) list; row_more: type_expr; row_bound: type_expr list; row_closed: bool; + row_fixed: bool; row_name: (Path.t * type_expr list) option } and row_field = @@ -63,6 +66,13 @@ and commutable = | Cunknown | Clink of commutable ref +module TypeOps = struct + type t = type_expr + let compare t1 t2 = t1.id - t2.id + let hash t = t.id + let equal t1 t2 = t1 == t2 +end + (* Maps of methods and instance variables *) module OrderedString = struct type t = string let compare = compare end diff --git a/typing/types.mli b/typing/types.mli index 95ac8c887..096ced67a 100644 --- a/typing/types.mli +++ b/typing/types.mli @@ -34,12 +34,15 @@ and type_desc = | Tlink of type_expr | Tsubst of type_expr (* for copying *) | Tvariant of row_desc + | Tunivar + | Tpoly of type_expr * type_expr list and row_desc = { row_fields: (label * row_field) list; row_more: type_expr; row_bound: type_expr list; row_closed: bool; + row_fixed: bool; row_name: (Path.t * type_expr list) option } and row_field = @@ -65,6 +68,13 @@ and commutable = | Cunknown | Clink of commutable ref +module TypeOps : sig + type t = type_expr + val compare : t -> t -> int + val equal : t -> t -> bool + val hash : t -> int +end + (* Maps of methods and instance variables *) module Meths : Map.S with type key = string diff --git a/typing/typetexp.ml b/typing/typetexp.ml index d2947b62a..47469ecb4 100644 --- a/typing/typetexp.ml +++ b/typing/typetexp.ml @@ -10,7 +10,7 @@ (* *) (***********************************************************************) -(* $Id$ *) +(* typetexp.ml,v 1.34.4.9 2002/01/07 08:39:16 garrigue Exp *) (* Typechecking of type expressions for the core language *) @@ -37,6 +37,8 @@ type error = | Constructor_mismatch of type_expr * type_expr | Not_a_variant of type_expr | Variant_tags of string * string + | No_row_variable of string + | Bad_alias of string exception Error of Location.t * error @@ -44,6 +46,8 @@ exception Error of Location.t * error let type_variables = ref (Tbl.empty : (string, type_expr) Tbl.t) let saved_type_variables = ref ([] : (string, type_expr) Tbl.t list) +let univars = ref ([] : (string * type_expr) list) +let pre_univars = ref ([] : type_expr list) let used_variables = ref (Tbl.empty : (string, type_expr) Tbl.t) let bindings = ref ([] : (Location.t * type_expr * type_expr) list) @@ -80,33 +84,61 @@ let type_variable loc name = with Not_found -> raise(Error(loc, Unbound_type_variable ("'" ^ name))) -type policy = Fixed | Extensible | Delayed +let wrap_method ty = + match (Ctype.repr ty).desc with + Tpoly _ -> ty + | _ -> Ctype.newty (Tpoly (ty, [])) -let rec transl_type env policy styp = +let new_pre_univar () = + let v = newvar () in pre_univars := v :: !pre_univars; v + +let rec swap_list = function + x :: y :: l -> y :: x :: swap_list l + | l -> l + +type policy = Fixed | Extensible | Delayed | Univars + +let rec transl_type env policy rowvar styp = + if rowvar <> None then begin + match styp.ptyp_desc with + Ptyp_variant _ | Ptyp_object _ | Ptyp_class _ -> () + | _ -> raise(Error(styp.ptyp_loc, No_row_variable "")) + end; match styp.ptyp_desc with - Ptyp_any -> Ctype.newvar () + Ptyp_any -> + if policy = Univars then new_pre_univar () else newvar () | Ptyp_var name -> - begin + begin try + List.assoc name !univars + with Not_found -> match policy with Fixed -> begin try - Tbl.find name !type_variables + instance (Tbl.find name !type_variables) with Not_found -> raise(Error(styp.ptyp_loc, Unbound_type_variable ("'" ^ name))) end | Extensible -> begin try - Tbl.find name !type_variables + instance (Tbl.find name !type_variables) with Not_found -> let v = new_global_var () in type_variables := Tbl.add name v !type_variables; v end + | Univars -> + begin try + instance (Tbl.find name !type_variables) + with Not_found -> + let v = new_pre_univar () in + type_variables := Tbl.add name v !type_variables; + v + end | Delayed -> begin try Tbl.find name !used_variables with Not_found -> try - let v1 = Tbl.find name !type_variables in + let v1 = instance (Tbl.find name !type_variables) in let v2 = new_global_var () in used_variables := Tbl.add name v2 !used_variables; bindings := (styp.ptyp_loc, v1, v2)::!bindings; @@ -119,11 +151,11 @@ let rec transl_type env policy styp = end end | Ptyp_arrow(l, st1, st2) -> - let ty1 = transl_type env policy st1 in - let ty2 = transl_type env policy st2 in + let ty1 = transl_type env policy None st1 in + let ty2 = transl_type env policy None st2 in newty (Tarrow(l, ty1, ty2, Cok)) | Ptyp_tuple stl -> - newty (Ttuple(List.map (transl_type env policy) stl)) + newty (Ttuple(List.map (transl_type env policy None) stl)) | Ptyp_constr(lid, stl) -> let (path, decl) = try @@ -133,7 +165,7 @@ let rec transl_type env policy styp = if List.length stl <> decl.type_arity then raise(Error(styp.ptyp_loc, Type_arity_mismatch(lid, decl.type_arity, List.length stl))); - let args = List.map (transl_type env policy) stl in + let args = List.map (transl_type env policy None) stl in let params = List.map (fun _ -> Ctype.newvar ()) args in let cstr = newty (Tconstr(path, params, ref Mnil)) in begin try @@ -143,14 +175,18 @@ let rec transl_type env policy styp = end; List.iter2 (fun (sty, ty) ty' -> - try unify env ty ty' with Unify trace -> - raise (Error(sty.ptyp_loc, Type_mismatch trace))) + try unify_var env ty' ty with Unify trace -> + raise (Error(sty.ptyp_loc, Type_mismatch (swap_list trace)))) (List.combine stl args) params; cstr | Ptyp_object fields -> - newobj (transl_fields env policy fields) + begin try + newobj (transl_fields env policy rowvar fields) + with Error (loc, No_row_variable _) when loc = Location.none -> + raise (Error(styp.ptyp_loc, No_row_variable "object ")) + end | Ptyp_class(lid, stl, present) -> - if policy = Fixed then + if policy = Fixed & rowvar = None then raise(Error(styp.ptyp_loc, Unbound_row_variable lid)); let (path, decl, is_variant) = try @@ -182,8 +218,8 @@ let rec transl_type env policy styp = in if List.length stl <> decl.type_arity then raise(Error(styp.ptyp_loc, Type_arity_mismatch(lid, decl.type_arity, - List.length stl))); - let args = List.map (transl_type env policy) stl in + List.length stl))); + let args = List.map (transl_type env policy None) stl in let cstr = newty (Tconstr(path, args, ref Mnil)) in let ty = try Ctype.expand_head env cstr @@ -193,8 +229,8 @@ let rec transl_type env policy styp = let params = Ctype.instance_list decl.type_params in List.iter2 (fun (sty, ty') ty -> - try unify env ty' ty with Unify trace -> - raise (Error(sty.ptyp_loc, Type_mismatch trace))) + try unify_var env ty ty' with Unify trace -> + raise (Error(sty.ptyp_loc, Type_mismatch (swap_list trace)))) (List.combine stl args) params; begin match ty.desc with Tvariant row -> @@ -204,6 +240,7 @@ let rec transl_type env policy styp = raise(Error(styp.ptyp_loc, Present_has_no_type l))) present; let bound = ref row.row_bound in + let fixed = rowvar <> None || policy = Univars in let fields = List.map (fun (l,f) -> l, @@ -211,34 +248,78 @@ let rec transl_type env policy styp = match Btype.row_field_repr f with | Rpresent (Some ty) -> bound := ty :: !bound; - Reither(false, [ty], false, ref None) + Reither(false, [ty], fixed, ref None) | Rpresent None -> - Reither (true, [], false, ref None) + Reither (true, [], fixed, ref None) | _ -> f) row.row_fields in - let row = { row with row_fields = fields; row_bound = !bound; - row_name = Some (path, args) } in - newty (Tvariant row) - | _ -> + let row = { row_closed = true; + row_fields = fields; + row_bound = !bound; + row_name = Some (path, args); + row_fixed = fixed; + row_more = match rowvar with Some v -> v + | None -> + if policy = Univars then new_pre_univar () + else newvar () } + in newty (Tvariant row) + | Tobject (fi, _) -> + let _, tv = flatten_fields fi in + if policy = Univars then pre_univars := tv :: !pre_univars; + begin match rowvar with None -> () + | Some rv -> + let _, tv = flatten_fields fi in + try unify_var env tv rv with Unify trace -> + raise(Error(styp.ptyp_loc, Alias_type_mismatch trace)) + end; ty + | _ -> + assert false end | Ptyp_alias(st, alias) -> - if Tbl.mem alias !type_variables then - raise(Error(styp.ptyp_loc, Bound_type_variable alias)) - else - let ty' = new_global_var () in - type_variables := Tbl.add alias ty' !type_variables; - let ty = transl_type env policy st in - begin try unify env ty ty' with Unify trace -> - raise(Error(styp.ptyp_loc, Alias_type_mismatch trace)) - end; - ty + if List.mem_assoc alias !univars then + match List.assoc alias !univars with + {desc=Tlink({desc=Tunivar} as tc)} as tr -> + let ty = transl_type env policy (Some tc) st in + tr.level <- tc.level; + tr.desc <- Tvar; + begin try unify_var env tr ty with Unify trace -> + let trace = swap_list trace in + raise(Error(styp.ptyp_loc, Alias_type_mismatch trace)) + end; + ty + | _ -> + raise(Error(styp.ptyp_loc, Bound_type_variable alias)) + else begin + try + let t = instance (Tbl.find alias !type_variables) in + let ty = transl_type env policy None st in + begin try unify_var env t ty with Unify trace -> + let trace = swap_list trace in + raise(Error(styp.ptyp_loc, Alias_type_mismatch trace)) + end; + ty + with Not_found -> + begin_def (); + let t = newvar () in + type_variables := Tbl.add alias t !type_variables; + let ty = transl_type env policy None st in + begin try unify_var env t ty with Unify trace -> + let trace = swap_list trace in + raise(Error(styp.ptyp_loc, Alias_type_mismatch trace)) + end; + end_def (); + generalize_global t; + instance t + end | Ptyp_variant(fields, closed, present) -> let bound = ref [] and name = ref None in + let fixed = rowvar <> None || policy = Univars in let mkfield l f = newty (Tvariant {row_fields=[l,f]; row_more=newty Tnil; - row_bound=[]; row_closed=true; row_name=None}) in + row_bound=[]; row_closed=true; + row_fixed=fixed; row_name=None}) in let add_typed_field loc l f fields = try let f' = List.assoc l fields in @@ -253,18 +334,18 @@ let rec transl_type env policy styp = name := None; let f = match present with Some present when not (List.mem l present) -> - let tl = List.map (transl_type env policy) stl in + let tl = List.map (transl_type env policy None) stl in bound := tl @ !bound; - Reither(c, tl, false, ref None) + Reither(c, tl, fixed, ref None) | _ -> if List.length stl > 1 || c && stl <> [] then raise(Error(styp.ptyp_loc, Present_has_conjunction l)); match stl with [] -> Rpresent None - | st :: _ -> Rpresent (Some(transl_type env policy st)) + | st :: _ -> Rpresent (Some(transl_type env policy None st)) in add_typed_field styp.ptyp_loc l f fields | Rinherit sty -> - let ty = transl_type env policy sty in + let ty = transl_type env policy None sty in let nm = match repr ty with {desc=Tconstr(p, tl, _)} -> Some(p, tl) @@ -287,9 +368,9 @@ let rec transl_type env policy styp = begin match f with Rpresent(Some ty) -> bound := ty :: !bound; - Reither(false, [ty], false, ref None) + Reither(false, [ty], fixed, ref None) | Rpresent None -> - Reither(true, [], false, ref None) + Reither(true, [], fixed, ref None) | _ -> assert false end @@ -320,32 +401,77 @@ let rec transl_type env policy styp = end; let row = { row_fields = List.rev fields; row_more = newvar (); - row_bound = !bound; row_closed = closed; row_name = !name } in - if policy = Fixed && not (Btype.static_row row) then - raise(Error(styp.ptyp_loc, Unbound_type_variable "[..]")); + row_bound = !bound; row_closed = closed; + row_fixed = fixed; row_name = !name } in + let static = Btype.static_row row in + let row = + { row with row_more = + match rowvar with Some v -> v + | None -> + if static then newty Tnil else + if policy = Univars then new_pre_univar () else + if policy = Fixed && not static then + raise(Error(styp.ptyp_loc, Unbound_type_variable "[..]")) + else row.row_more + } in newty (Tvariant row) + | Ptyp_poly(vars, st) -> + (* aliases are stubs, in case one wants to redefine them *) + let ty_list = List.map (fun _ -> newty Tunivar) vars in + let new_univars = + List.map2 (fun name ty -> name, newty (Tlink ty)) vars ty_list in + let old_univars = !univars in + univars := new_univars @ !univars; + let ty = transl_type env policy None st in + univars := old_univars; + newty (Tpoly(ty, ty_list)) -and transl_fields env policy = +and transl_fields env policy rowvar = function [] -> newty Tnil | {pfield_desc = Pfield_var} as field::_ -> - if policy = Fixed then - raise(Error(field.pfield_loc, Unbound_type_variable "<..>")); - newvar () + begin match rowvar with + None -> + if policy = Fixed then + raise(Error(field.pfield_loc, Unbound_type_variable "..")); + if policy = Univars then new_pre_univar () else newvar () + | Some v -> v + end | {pfield_desc = Pfield(s, e)}::l -> - let ty1 = transl_type env policy e in - let ty2 = transl_fields env policy l in + let ty1 = transl_type env policy None e in + let ty2 = transl_fields env policy rowvar l in newty (Tfield (s, Fpresent, ty1, ty2)) let transl_simple_type env fixed styp = - let typ = transl_type env (if fixed then Fixed else Extensible) styp in + univars := []; + let typ = transl_type env (if fixed then Fixed else Extensible) None styp in typ +let transl_simple_type_univars env styp = + univars := []; + pre_univars := []; + begin_def (); + let typ = transl_type env Univars None styp in + end_def (); + generalize typ; + let univs = + List.fold_left + (fun acc v -> + let v = repr v in + if v.desc <> Tvar || v.level <> Btype.generic_level || List.memq v acc + then acc + else (v.desc <- Tunivar ; v :: acc)) + [] !pre_univars + in + pre_univars := []; + instance (Btype.newgenty (Tpoly (typ, univs))) + let transl_simple_type_delayed env styp = + univars := []; used_variables := Tbl.empty; bindings := []; - let typ = transl_type env Delayed styp in + let typ = transl_type env Delayed None styp in let b = !bindings in used_variables := Tbl.empty; bindings := []; @@ -424,3 +550,9 @@ let report_error ppf = function fprintf ppf "Variant tags `%s@ and `%s have same hash value.@ Change one of them." lab1 lab2 + | No_row_variable s -> + fprintf ppf "This %stype has no row variable" s + | Bad_alias name -> + fprintf ppf + "The alias %s cannot be used here. It captures universal variables." + name diff --git a/typing/typetexp.mli b/typing/typetexp.mli index 618c6e2bf..23ff76e90 100644 --- a/typing/typetexp.mli +++ b/typing/typetexp.mli @@ -18,6 +18,8 @@ open Format;; val transl_simple_type: Env.t -> bool -> Parsetree.core_type -> Types.type_expr +val transl_simple_type_univars: + Env.t -> Parsetree.core_type -> Types.type_expr val transl_simple_type_delayed: Env.t -> Parsetree.core_type -> Types.type_expr * (unit -> unit) (* Translate a type, but leave type variables unbound. Returns @@ -48,6 +50,8 @@ type error = | Constructor_mismatch of Types.type_expr * Types.type_expr | Not_a_variant of Types.type_expr | Variant_tags of string * string + | No_row_variable of string + | Bad_alias of string exception Error of Location.t * error diff --git a/utils/clflags.ml b/utils/clflags.ml index f7e9ada69..295e2837a 100644 --- a/utils/clflags.ml +++ b/utils/clflags.ml @@ -40,8 +40,9 @@ and noassert = ref false (* -noassert *) and verbose = ref false (* -verbose *) and use_prims = ref "" (* -use-prims ... *) and use_runtime = ref "" (* -use-runtime ... *) +and principal = ref false (* -principal *) and recursive_types = ref false (* -rectypes *) -and make_runtime = ref false (* -make-runtime *) +and make_runtime = ref false (* -make_runtime *) and gprofile = ref false (* -p *) and c_compiler = ref Config.bytecomp_c_compiler (* -cc *) and c_linker = ref Config.bytecomp_c_linker (* -cc *)