diff options
Diffstat (limited to 'typing')
-rw-r--r-- | typing/ctype.ml | 12 | ||||
-rw-r--r-- | typing/ctype.mli | 1 | ||||
-rw-r--r-- | typing/mtype.ml | 5 | ||||
-rw-r--r-- | typing/oprint.ml | 6 | ||||
-rw-r--r-- | typing/printtyp.ml | 3 | ||||
-rw-r--r-- | typing/typeclass.ml | 32 | ||||
-rw-r--r-- | typing/typecore.ml | 109 | ||||
-rw-r--r-- | typing/typedecl.ml | 9 | ||||
-rw-r--r-- | typing/typedtree.ml | 2 | ||||
-rw-r--r-- | typing/typedtree.mli | 2 | ||||
-rw-r--r-- | typing/unused_var.ml | 1 |
11 files changed, 87 insertions, 95 deletions
diff --git a/typing/ctype.ml b/typing/ctype.ml index 5e27441eaa..cbd9ec1440 100644 --- a/typing/ctype.ml +++ b/typing/ctype.ml @@ -1176,9 +1176,15 @@ let rec copy_sep fixed free bound visited ty = 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 +let instance_poly ?(keep_names=false) fixed univars sch = + let univars = List.map repr univars in + let copy_var ty = + match ty.desc with + Tunivar name -> if keep_names then newty (Tvar name) else newvar () + | _ -> assert false + in + let vars = List.map copy_var univars in + let pairs = List.map2 (fun u v -> u, (v, [])) univars vars in delayed_copy := []; let ty = copy_sep fixed (compute_univars sch) [] pairs sch in List.iter Lazy.force !delayed_copy; diff --git a/typing/ctype.mli b/typing/ctype.mli index 0c42edafdf..c4d4ff13a3 100644 --- a/typing/ctype.mli +++ b/typing/ctype.mli @@ -128,6 +128,7 @@ val instance_declaration: type_declaration -> type_declaration val instance_class: type_expr list -> class_type -> type_expr list * class_type val instance_poly: + ?keep_names:bool -> bool -> type_expr list -> type_expr -> type_expr list * type_expr (* Take an instance of a type scheme containing free univars *) val instance_label: diff --git a/typing/mtype.ml b/typing/mtype.ml index 404dda95bc..57ed4e2901 100644 --- a/typing/mtype.ml +++ b/typing/mtype.ml @@ -48,8 +48,9 @@ and strengthen_sig env sg p = sigelt :: strengthen_sig env rem p | Tsig_type(id, decl, rs) :: rem -> let newdecl = - match decl.type_manifest with - Some ty when decl.type_private = Public -> decl + match decl.type_manifest, decl.type_private, decl.type_kind with + Some _, Public, _ -> decl + | Some _, Private, (Type_record _ | Type_variant _) -> decl | _ -> let manif = Some(Btype.newgenty(Tconstr(Pdot(p, Ident.name id, nopos), diff --git a/typing/oprint.ml b/typing/oprint.ml index 21ef160806..0bfd8797cd 100644 --- a/typing/oprint.ml +++ b/typing/oprint.ml @@ -265,9 +265,9 @@ let out_type = ref print_out_type (* Class types *) let type_parameter ppf (ty, (co, cn)) = - fprintf ppf "%s'%s" (if not cn then "+" else if not co then "-" else "") - (*if co then if cn then "!" else "+" else if cn then "-" else "?"*) - ty + fprintf ppf "%s%s" + (if not cn then "+" else if not co then "-" else "") + (if ty = "_" then ty else "'"^ty) let print_out_class_params ppf = function diff --git a/typing/printtyp.ml b/typing/printtyp.ml index ed8b2e75f9..2b5470ea48 100644 --- a/typing/printtyp.ml +++ b/typing/printtyp.ml @@ -236,7 +236,8 @@ let name_of_type t = (* No name available, create a new one *) new_name () in - names := (t, name) :: !names; + (* Exception for type declarations *) + if name <> "_" then names := (t, name) :: !names; name let check_name_of_type t = ignore(name_of_type t) diff --git a/typing/typeclass.ml b/typing/typeclass.ml index 34b651e186..512f7cf8b2 100644 --- a/typing/typeclass.ml +++ b/typing/typeclass.ml @@ -569,38 +569,6 @@ let rec class_field cl_num self_type meths vars type_constraint val_env sty sty' loc; (val_env, met_env, par_env, fields, concr_meths, warn_vals, inher) - | Pcf_let (rec_flag, sdefs, loc) -> - let (defs, val_env) = - try - Typecore.type_let val_env rec_flag sdefs None - with Ctype.Unify [(ty, _)] -> - raise(Error(loc, Make_nongen_seltype ty)) - in - let (vals, met_env, par_env) = - List.fold_right - (fun id (vals, met_env, par_env) -> - let expr = - Typecore.type_exp val_env - {pexp_desc = Pexp_ident (Longident.Lident (Ident.name id)); - pexp_loc = Location.none} - in - let desc = - {val_type = expr.exp_type; - val_kind = Val_ivar (Immutable, cl_num); - val_loc = Location.none; - } - in - let id' = Ident.create (Ident.name id) in - ((id', expr) - :: vals, - Env.add_value id' desc met_env, - Env.add_value id' desc par_env)) - (let_bound_idents defs) - ([], met_env, par_env) - in - (val_env, met_env, par_env, lazy(Cf_let(rec_flag, defs, vals))::fields, - concr_meths, warn_vals, inher) - | Pcf_init expr -> let expr = make_method cl_num expr in let vars_local = !vars in diff --git a/typing/typecore.ml b/typing/typecore.ml index a400bc23ea..9a7a1d849e 100644 --- a/typing/typecore.ml +++ b/typing/typecore.ml @@ -521,7 +521,7 @@ let rec type_pat ~constrs ~labels ~no_existentials ~mode ~env sp expected_ty = begin match ty.desc with | Tpoly (body, tyl) -> begin_def (); - let _, ty' = instance_poly false tyl body in + let _, ty' = instance_poly ~keep_names:true false tyl body in end_def (); generalize ty'; let id = enter_variable loc name ty' in @@ -870,7 +870,7 @@ let rec is_nonexpansive exp = Cf_meth _ -> true | Cf_val (_,_,e,_) -> incr count; is_nonexpansive_opt e | Cf_init e -> is_nonexpansive e - | Cf_inher _ | Cf_let _ -> false) + | Cf_inher _ -> false) fields && Vars.fold (fun _ (mut,_,_) b -> decr count; b && mut = Immutable) vars true && @@ -907,7 +907,7 @@ and is_nonexpansive_opt = function (* Typing format strings for printing or reading. - This format strings are used by functions in modules Printf, Format, and + These format strings are used by functions in modules Printf, Format, and Scanf. (Handling of * modifiers contributed by Thorsten Ohl.) *) @@ -926,25 +926,6 @@ let type_format loc fmt = let incomplete_format fmt = raise (Error (loc, Incomplete_format fmt)) in - let range_closing_index fmt i = - - let len = String.length fmt in - let find_closing j = - if j >= len then incomplete_format fmt else - try String.index_from fmt j ']' with - | Not_found -> incomplete_format fmt in - let skip_pos j = - if j >= len then incomplete_format fmt else - match fmt.[j] with - | ']' -> find_closing (j + 1) - | c -> find_closing j in - let rec skip_neg j = - if j >= len then incomplete_format fmt else - match fmt.[j] with - | '^' -> skip_pos (j + 1) - | c -> skip_pos j in - find_closing (skip_neg (i + 1)) in - let rec type_in_format fmt = let len = String.length fmt in @@ -963,14 +944,7 @@ let type_format loc fmt = else incomplete_format fmt else match fmt.[i] with | '%' -> scan_opts i (i + 1) - | '@' -> skip_indication (i + 1) | _ -> scan_format (i + 1) - and skip_indication i = - if i >= len then incomplete_format fmt else - match fmt.[i] with - | '@' | '%' -> scan_format (i + 1) - | _ -> scan_format i - and scan_opts i j = if j >= len then incomplete_format fmt else match fmt.[j] with @@ -1001,6 +975,48 @@ let type_format loc fmt = match fmt.[j] with | '.' -> scan_width_or_prec_value scan_conversion i (j + 1) | _ -> scan_conversion i j + and scan_indication j = + if j >= len then j - 1 else + match fmt.[j] with + | '@' -> + let k = j + 1 in + if k >= len then j - 1 else + begin match fmt.[k] with + | '%' -> + let k = k + 1 in + if k >= len then j - 1 else + begin match fmt.[k] with + | '%' | '@' -> k + | _c -> j - 1 + end + | _c -> k + end + | _c -> j - 1 + and scan_range j = + let rec scan_closing j = + if j >= len then incomplete_format fmt else + match fmt.[j] with + | ']' -> j + | '%' -> + let j = j + 1 in + if j >= len then incomplete_format fmt else + begin match fmt.[j] with + | '%' | '@' -> scan_closing (j + 1) + | c -> bad_conversion fmt j c + end + | c -> scan_closing (j + 1) in + let scan_first_pos j = + if j >= len then incomplete_format fmt else + match fmt.[j] with + | ']' -> scan_closing (j + 1) + | c -> scan_closing j in + let rec scan_first_neg j = + if j >= len then incomplete_format fmt else + match fmt.[j] with + | '^' -> scan_first_pos (j + 1) + | c -> scan_first_pos j in + + scan_first_neg j and conversion j ty_arg = let ty_uresult, ty_result = scan_format (j + 1) in @@ -1020,13 +1036,16 @@ let type_format loc fmt = and scan_conversion i j = if j >= len then incomplete_format fmt else match fmt.[j] with - | '%' | '!' | ',' -> scan_format (j + 1) - | 's' | 'S' -> conversion j Predef.type_string + | '%' | '@' | '!' | ',' -> scan_format (j + 1) + | 's' | 'S' -> + let j = scan_indication (j + 1) in + conversion j Predef.type_string | '[' -> - let j = range_closing_index fmt j in + let j = scan_range (j + 1) in + let j = scan_indication (j + 1) in conversion j Predef.type_string | 'c' | 'C' -> conversion j Predef.type_char - | 'd' | 'i' | 'o' | 'x' | 'X' | 'u' | 'N' -> + | 'd' | 'i' | 'o' | 'u' | 'x' | 'X' | 'N' -> conversion j Predef.type_int | 'f' | 'e' | 'E' | 'g' | 'G' | 'F' -> conversion j Predef.type_float | 'B' | 'b' -> conversion j Predef.type_bool @@ -1055,7 +1074,7 @@ let type_format loc fmt = let j = j + 1 in if j >= len then conversion (j - 1) Predef.type_int else begin match fmt.[j] with - | 'd' | 'i' | 'o' | 'x' | 'X' | 'u' -> + | 'd' | 'i' | 'o' | 'u' | 'x' | 'X' -> let ty_arg = match c with | 'l' -> Predef.type_int32 @@ -1084,9 +1103,10 @@ let type_format loc fmt = let ty_ureader, ty_args = scan_format 0 in newty (Tconstr - (Predef.path_format6, - [ty_args; ty_input; ty_aresult; ty_ureader; ty_uresult; ty_result], - ref Mnil)) in + (Predef.path_format6, + [ ty_args; ty_input; ty_aresult; + ty_ureader; ty_uresult; ty_result; ], + ref Mnil)) in type_in_format fmt @@ -2633,7 +2653,8 @@ and type_let ?(check = fun s -> Warnings.Unused_var s) ?(check_strict = fun s -> let pat = match pat.pat_type.desc with | Tpoly (ty, tl) -> - {pat with pat_type = snd (instance_poly false tl ty)} + {pat with pat_type = + snd (instance_poly ~keep_names:true false tl ty)} | _ -> pat in unify_pat env pat (type_approx env sexp)) pat_list spat_sexp_list; @@ -2722,7 +2743,7 @@ and type_let ?(check = fun s -> Warnings.Unused_var s) ?(check_strict = fun s -> | Tpoly (ty, tl) -> begin_def (); if !Clflags.principal then begin_def (); - let vars, ty' = instance_poly true tl ty in + let vars, ty' = instance_poly ~keep_names:true true tl ty in if !Clflags.principal then begin end_def (); generalize_structure ty' @@ -2744,8 +2765,7 @@ and type_let ?(check = fun s -> Warnings.Unused_var s) ?(check_strict = fun s -> iter_pattern (fun pat -> generalize_expansive env pat.pat_type) pat) pat_list exp_list; List.iter - (fun pat -> iter_pattern - (fun pat -> generalize pat.pat_type) pat) + (fun pat -> iter_pattern (fun pat -> generalize pat.pat_type) pat) pat_list; (List.combine pat_list exp_list, new_env, unpacks) @@ -2775,7 +2795,12 @@ let type_expression env sexp = end_def(); if is_nonexpansive exp then generalize exp.exp_type else generalize_expansive env exp.exp_type; - exp + match sexp.pexp_desc with + Pexp_ident lid -> + (* Special case for keeping type variables when looking-up a variable *) + let (path, desc) = Env.lookup_value lid env in + {exp with exp_type = desc.val_type} + | _ -> exp (* Error report *) diff --git a/typing/typedecl.ml b/typing/typedecl.ml index 94e09cc574..315e066d16 100644 --- a/typing/typedecl.ml +++ b/typing/typedecl.ml @@ -125,16 +125,11 @@ module StringSet = end) let make_params sdecl = - let param_counter = ref 0 in try List.map (function - None -> - incr param_counter ; - enter_type_variable true sdecl.ptype_loc - (Printf.sprintf "*%d" !param_counter) - | Some x -> - enter_type_variable true sdecl.ptype_loc x) + None -> Ctype.new_global_var ~name:"_" () + | Some x -> enter_type_variable true sdecl.ptype_loc x) sdecl.ptype_params with Already_bound -> raise(Error(sdecl.ptype_loc, Repeated_parameter)) diff --git a/typing/typedtree.ml b/typing/typedtree.ml index 3b43d1d80f..0feca199a3 100644 --- a/typing/typedtree.ml +++ b/typing/typedtree.ml @@ -110,8 +110,6 @@ and class_field = Cf_inher of class_expr * (string * Ident.t) list * (string * Ident.t) list | Cf_val of string * Ident.t * expression option * bool | Cf_meth of string * expression - | Cf_let of rec_flag * (pattern * expression) list * - (Ident.t * expression) list | Cf_init of expression (* Value expressions for the module language *) diff --git a/typing/typedtree.mli b/typing/typedtree.mli index 15acb6ac59..0c5efa8ea8 100644 --- a/typing/typedtree.mli +++ b/typing/typedtree.mli @@ -112,8 +112,6 @@ and class_field = | Cf_val of string * Ident.t * expression option * bool (* None = virtual, true = override *) | Cf_meth of string * expression - | Cf_let of rec_flag * (pattern * expression) list * - (Ident.t * expression) list | Cf_init of expression (* Value expressions for the module language *) diff --git a/typing/unused_var.ml b/typing/unused_var.ml index 61123eff50..3a6eeaeb50 100644 --- a/typing/unused_var.ml +++ b/typing/unused_var.ml @@ -274,7 +274,6 @@ and class_field ppf tbl cf = | Pcf_virt _ | Pcf_valvirt _ -> () | Pcf_meth (_, _, _, e, _) -> expression ppf tbl e; | Pcf_cstr _ -> () - | Pcf_let (recflag, pel, _) -> let_pel ppf tbl recflag pel None; | Pcf_init e -> expression ppf tbl e; ;; |