diff -aur ocaml-3.04/typing/typecore.ml ocaml-patch-record/typing/typecore.ml --- ocaml-3.04/typing/typecore.ml Fri Dec 7 08:27:59 2001 +++ ocaml-patch-record/typing/typecore.ml Tue Jan 15 12:14:33 2002 @@ -106,6 +106,40 @@ | _ -> assert false + +(* Copied from env.ml *) +let labels_of_type ty_path decl = + match decl.type_kind with + Type_record(labels, rep) -> + Datarepr.label_descrs + (Btype.newgenty (Tconstr(ty_path, decl.type_params, ref Mnil))) + labels rep + | _ -> [] + +(* Note: this is rather inefficient; it is not necessary to compute + all labels of the records (tbl_all is not used for Texp_field). + But who cares ? *) + +let rec lookup_label ty name env = + let ty = repr ty in + match ty.desc with + | Tconstr (path, _, _) -> + let td = Env.find_type path env in + let lbls = labels_of_type path td in + List.assoc name lbls + | _ -> raise Not_found + +let find_label loc ty lid env = + try + try + match lid with + | Longident.Lident name -> lookup_label ty name env + | _ -> raise Not_found + with Not_found -> Env.lookup_label lid env + with Not_found -> + raise(Error(loc, Unbound_label lid)) + + (* Typing of patterns *) (* Creating new conjunctive types is not allowed when typing patterns *) @@ -832,11 +866,7 @@ exp_env = env } | Pexp_field(sarg, lid) -> let arg = type_exp env sarg in - let label = - try - Env.lookup_label lid env - with Not_found -> - raise(Error(sexp.pexp_loc, Unbound_label lid)) in + let label = find_label sexp.pexp_loc arg.exp_type lid env in let (ty_arg, ty_res) = instance_label label in unify_exp env arg ty_res; { exp_desc = Texp_field(arg, label); @@ -845,11 +875,7 @@ exp_env = env } | Pexp_setfield(srecord, lid, snewval) -> let record = type_exp env srecord in - let label = - try - Env.lookup_label lid env - with Not_found -> - raise(Error(sexp.pexp_loc, Unbound_label lid)) in + let label = find_label sexp.pexp_loc record.exp_type lid env 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