Commits

camlspotter committed 6759a4a

bizarre overloading

  • Participants
  • Parent commits 2014bc9

Comments (0)

Files changed (18)

File bytecomp/matching.ml

       let env = Env.open_pers_signature modname Env.initial in
       let p = try
         match Env.lookup_value (Longident.Lident field) env with
-        | (Path.Pdot(_,_,i), _) -> i
+        | [] | _::_::_ -> assert false
+        | [(Path.Pdot(_,_,i), _)] -> i
         | _ -> fatal_error ("Primitive "^modname^"."^field^" not found.")
       with Not_found -> fatal_error ("Primitive "^modname^"."^field^" not found.")
       in

File bytecomp/translcore.ml

 
 and transl_exp0 e =
   match e.exp_desc with
-    Texp_ident(path, {val_kind = Val_prim p}) ->
+  | Texp_over_ident(_, {contents = None}, _) -> assert false
+  | Texp_ident(path, {val_kind = Val_prim p})
+  | Texp_over_ident(_, {contents = Some (path, {val_kind = Val_prim p})}, _) ->
       let public_send = p.prim_name = "%send" in
       if public_send || p.prim_name = "%sendself" then
         let kind = if public_send then Public else Self in
                   Lsend(Cached, Lvar meth, Lvar obj, [Lvar cache; Lvar pos], e.exp_loc))
       else
         transl_primitive p
-  | Texp_ident(path, {val_kind = Val_anc _}) ->
+  | Texp_ident(path, {val_kind = Val_anc _})
+  | Texp_over_ident(_, {contents = Some (path, {val_kind = Val_anc _})}, _) ->
       raise(Error(e.exp_loc, Free_super_var))
-  | Texp_ident(path, {val_kind = Val_reg | Val_self _}) ->
+  | Texp_ident(path, {val_kind = Val_reg | Val_self _})
+  | Texp_over_ident(_, {contents = Some (path, {val_kind = Val_reg | Val_self _})}, _) ->
       transl_path path
-  | Texp_ident _ -> fatal_error "Translcore.transl_exp: bad Texp_ident"
+  | Texp_ident _ | Texp_over_ident _-> fatal_error "Translcore.transl_exp: bad Texp_ident"
   | Texp_constant cst ->
       Lconst(Const_base cst)
   | Texp_let(rec_flag, pat_expr_list, body) ->

File bytecomp/translmod.ml

 let mod_prim name =
   try
     transl_path
-      (fst (Env.lookup_value (Ldot (Lident "CamlinternalMod", name))
-                             Env.empty))
+      (fst (match Env.lookup_value (Ldot (Lident "CamlinternalMod", name))
+                             Env.empty  with [v] -> v | _ -> assert false))
   with Not_found ->
     fatal_error ("Primitive " ^ name ^ " not found.")
 

File bytecomp/translobj.ml

 let oo_prim name =
   try
     transl_path
-      (fst (Env.lookup_value (Ldot (Lident "CamlinternalOO", name)) Env.empty))
+      (fst (match Env.lookup_value (Ldot (Lident "CamlinternalOO", name)) Env.empty with [v] -> v | _ -> assert false))
   with Not_found ->
     fatal_error ("Primitive " ^ name ^ " not found.")
 

File ocamlspot/othertests/overload.ml

+module M = {
+  module N = {
+    let (+) = (+)
+    let one = 1
+  }
+  module O = {
+    let (+) = (+.)
+    let one = 1.0
+  }
+}
+
+open* M (* now M.N.(+) and M.O.(+) are available and overloaded! *)
+
+let _ = 
+  assert (1 + 2 = 3);
+  assert (1.2 + 3.4 = 4.6);
+  assert ((fun x -> x 1.2 3.4) (+) = 4.6);
+;;
+

File parsing/longident.ml

     [] -> Lident ""  (* should not happen, but don't put assert false
                         so as not to crash the toplevel (see Genprintval) *)
   | hd :: tl -> List.fold_left (fun p s -> Ldot(p, s)) (Lident hd) tl
+
+let rec to_string = function
+  | Lident s -> s
+  | Ldot(p, s) -> to_string p ^ "." ^ s
+  | Lapply(p1, p2) -> to_string p1 ^ "(" ^ to_string p2 ^ ")"

File parsing/longident.mli

 val flatten: t -> string list
 val last: t -> string
 val parse: string -> t
+val to_string : t -> string

File parsing/parser.mly

       { mkexp(Pexp_newtype($4, $6)) }
   | MATCH seq_expr WITH opt_bar match_cases
       { mkexp(Pexp_match($2, List.rev $5)) }
+  | MATCH seq_expr WITH BEGIN opt_bar match_cases END
+      { mkexp(Pexp_match($2, List.rev $6)) }
   | TRY seq_expr WITH opt_bar match_cases
       { mkexp(Pexp_try($2, List.rev $5)) }
   | TRY seq_expr WITH error

File toplevel/topdirs.ml

 
 let find_printer_type ppf lid =
   try
-    let (path, desc) = Env.lookup_value lid !toplevel_env in
+    let (path, desc) = match Env.lookup_value lid !toplevel_env with [v] -> v | _ -> assert false (* interesting though *) in
     let (ty_arg, is_old_style) =
       try
         (match_printer_type ppf desc "printer_type_new", false)
 
 let dir_trace ppf lid =
   try
-    let (path, desc) = Env.lookup_value lid !toplevel_env in
+    let (path, desc) = match Env.lookup_value lid !toplevel_env with [v] -> v | _ -> assert false in
     (* Check if this is a primitive *)
     match desc.val_kind with
     | Val_prim p ->
 
 let dir_untrace ppf lid =
   try
-    let (path, desc) = Env.lookup_value lid !toplevel_env in
+    let (path, desc) = match Env.lookup_value lid !toplevel_env with [v] -> v | _ -> assert false in
     let rec remove = function
     | [] ->
         fprintf ppf "%a was not traced.@." Printtyp.longident lid;

File typing/ctype.ml

   backtrack snap;
   ok
 
+let unifiable env ty ty' =
+  let snap = snapshot () in
+  let ok = try unify env ty ty'; true with Unify _ -> false in
+  backtrack snap;
+  ok
 
                  (*********************************************)
                  (*  Equivalence between parameterized types  *)

File typing/ctype.mli

 val matches : Env.t -> type_expr -> type_expr -> bool
         (* Same as [moregeneral false], implemented using the two above
            functions and backtracking. Ignore levels *)
+val unifiable : Env.t -> type_expr -> type_expr -> bool
+        (* Same as [unify env ty ty'], but it does not perform the real
+           unification, but just return the unifiability.
+        *)
 
 type class_match_failure =
     CM_Virtual_class

File typing/env.ml

   | Env_cltype of summary * Ident.t * cltype_declaration
   | Env_open of summary * Path.t
 
-type 'a with_open = 'a * Path.t option
+type 'a with_open = 'a * (Path.t option * bool) (* with * *)
 
 type t = {
-  values: (Path.t * (value_description * bool)) with_open Ident.tbl;
+  values: (Path.t * value_description) with_open Ident.tbl;
   annotations: (Path.t * Annot.ident) with_open Ident.tbl;
   constrs: constructor_description with_open Ident.tbl;
   labels: label_description with_open Ident.tbl;
   | Functor_comps of functor_components
 
 and structure_components = {
-  mutable comp_values: (string, ((value_description * bool) * int)) Tbl.t;
+  mutable comp_values: (string, (value_description * int)) Tbl.t;
   mutable comp_annotations: (string, (Annot.ident * int)) Tbl.t;
   mutable comp_constrs: (string, (constructor_description * int)) Tbl.t;
   mutable comp_labels: (string, (label_description * int)) Tbl.t;
     Pident _ -> true
   | Pdot _ | Papply _ -> false
 
+let is_local' (((p, _),_),_) = is_ident p
+
 let is_local ((p, _),_) = is_ident p
 
 let is_local_exn = function
   | Papply(p1, p2) ->
       raise Not_found
 
-let find' proj1 proj2 path env =
-  match path with
-    Pident id ->
-      let (p, data, _),_ = Ident.find_same id (proj1 env)
-      in data
-  | Pdot(p, s, pos) ->
-      begin match Lazy.force(find_module_descr p env) with
-        Structure_comps c ->
-          let (data, pos) = Tbl.find s (proj2 c) in data
-      | Functor_comps f ->
-          raise Not_found
-      end
-  | Papply(p1, p2) ->
-      raise Not_found
-
 let find_value =
   find (fun env -> env.values) (fun sc -> sc.comp_values)
 and find_type =
   let locs = loc :: try Hashtbl.find modules_opened_but_not_used_yet p with Not_found -> [] in
   Hashtbl.replace modules_opened_but_not_used_yet p locs
 
-let mark_opened_module (v, open_info) =
+let mark_opened_module (v, (open_info, _)) =
   begin match open_info with
   | None -> ()
   | Some p -> Hashtbl.remove modules_opened_but_not_used_yet p
   | Lapply(l1, l2) ->
       raise Not_found
 
+let find_all_overloaded data = match data.Ident.data with
+  | (_, (_, false)) as v -> [v]
+  | (_, (_, true)) as v ->
+      let rec loop data = match data.Ident.previous with
+        | None -> []
+        | Some data ->
+            match data.Ident.data with
+            | (_, (_, false)) -> []
+            | (_, (_, true)) as v -> v :: loop data
+      in
+      v :: loop data
+
+let lookup' proj1 proj2 lid env =
+  match lid with
+    Lident s -> 
+      let all = find_all_overloaded (Ident.find_data_name s (proj1 env)) in
+      List.map mark_opened_module all
+  | Ldot(l, s) ->
+      let (p, desc) = lookup_module_descr l env in
+      begin match Lazy.force desc with
+        Structure_comps c ->
+          let (data, pos) = Tbl.find s (proj2 c) in
+          [(Pdot(p, s, pos), data)]
+      | Functor_comps f ->
+          raise Not_found
+      end
+  | Lapply(l1, l2) ->
+      raise Not_found
+
 let lookup_simple proj1 proj2 lid env =
   match lid with
     Lident s ->
       raise Not_found
 
 let lookup_value =
-  lookup (fun env -> env.values) (fun sc -> sc.comp_values)
+  lookup' (fun env -> env.values) (fun sc -> sc.comp_values)
 let lookup_annot id e =
   lookup (fun env -> env.annotations) (fun sc -> sc.comp_annotations) id e
 and lookup_constructor =
           Tsig_value(id, decl) ->
             let decl' = Subst.value_description sub decl in
             c.comp_values <-
-              Tbl.add (Ident.name id) ((decl', false), !pos) c.comp_values;
+              Tbl.add (Ident.name id) (decl', !pos) c.comp_values;
             if !Clflags.annotations then begin
               c.comp_annotations <-
                 Tbl.add (Ident.name id) (Annot.Iref_external, !pos)
 
 and store_value ?opened ?(overloaded=false) id path decl env =
   { env with
-    values = Ident.add id ((path, (decl, overloaded)), opened) env.values;
+    values = Ident.add id ((path, decl), (opened, overloaded)) env.values;
     summary = Env_value(env.summary, id, decl) }
 
 and store_annot ?opened id path annot env =
   if !Clflags.annotations then
     { env with
-      annotations = Ident.add id ((path, annot), opened) env.annotations }
+      annotations = Ident.add id ((path, annot), (opened, false)) env.annotations }
   else env
 
 and store_type ?opened id path info env =
     constrs =
       List.fold_right
         (fun (name, descr) constrs ->
-          Ident.add (Ident.create name) (descr, opened) constrs)
+          Ident.add (Ident.create name) (descr, (opened, false)) constrs)
         (constructors_of_type path info)
         env.constrs;
     labels =
       List.fold_right
         (fun (name, descr) labels ->
-          Ident.add (Ident.create name) (descr, opened) labels)
+          Ident.add (Ident.create name) (descr, (opened, false)) labels)
         (labels_of_type path info)
         env.labels;
-    types = Ident.add id ((path, info), opened) env.types;
+    types = Ident.add id ((path, info), (opened, false)) env.types;
     summary = Env_type(env.summary, id, info) }
 
 and store_type_infos ?opened id path info env =
      keep track of type abbreviations (e.g. type t = float) in the
      computation of label representations. *)
   { env with
-    types = Ident.add id ((path, info), opened) env.types;
+    types = Ident.add id ((path, info), (opened, false)) env.types;
     summary = Env_type(env.summary, id, info) }
 
 and store_exception ?opened id path decl env =
   { env with
-    constrs = Ident.add id (Datarepr.exception_descr path decl, opened) env.constrs;
+    constrs = Ident.add id (Datarepr.exception_descr path decl, (opened, false)) env.constrs;
     summary = Env_exception(env.summary, id, decl) }
 
 and store_module ?opened id path mty env =
   { env with
-    modules = Ident.add id ((path, mty), opened) env.modules;
+    modules = Ident.add id ((path, mty), (opened, false)) env.modules;
     components =
-      Ident.add id ((path, components_of_module env Subst.identity path mty), opened)
+      Ident.add id ((path, components_of_module env Subst.identity path mty), (opened, false))
                    env.components;
     summary = Env_module(env.summary, id, mty) }
 
 and store_modtype ?opened id path info env =
   { env with
-    modtypes = Ident.add id ((path, info), opened) env.modtypes;
+    modtypes = Ident.add id ((path, info), (opened, false)) env.modtypes;
     summary = Env_modtype(env.summary, id, info) }
 
 and store_class ?opened id path desc env =
   { env with
-    classes = Ident.add id ((path, desc), opened) env.classes;
+    classes = Ident.add id ((path, desc), (opened, false)) env.classes;
     summary = Env_class(env.summary, id, desc) }
 
 and store_cltype ?opened id path desc env =
   { env with
-    cltypes = Ident.add id ((path, desc), opened) env.cltypes;
+    cltypes = Ident.add id ((path, desc), (opened, false)) env.cltypes;
     summary = Env_cltype(env.summary, id, desc) }
 
 (* Compute the components of a functor application in a path. *)
         match item with
           Tsig_value(id, decl) ->
             let e1 = store_value ~opened:root (Ident.hide id) p
+                        ~overloaded:true 
                         (Subst.value_description sub decl) env
             in store_annot (Ident.hide id) p (Annot.Iref_external) e1
         | Tsig_type(id, decl, _) ->
             store_exception ~opened:root (Ident.hide id) p
                             (Subst.exception_declaration sub decl) env
         | Tsig_module(id, mty, _) ->
-            let root' = Pdot (root, Ident.name id, 0) in
+            let root' = p in
             begin match !mtype_scrape env mty with
               | Tmty_signature sg' -> 
                   let env' = store_module ~opened:root (Ident.hide id) p (Subst.modtype sub mty) env in

File typing/env.mli

 
 (* Lookup by paths *)
 
-val find_value: Path.t -> t -> value_description * bool
+val find_value: Path.t -> t -> value_description
 val find_type: Path.t -> t -> type_declaration
 val find_module: Path.t -> t -> module_type
 val find_modtype: Path.t -> t -> modtype_declaration
 
 (* Lookup by long identifiers *)
 
-val lookup_value: Longident.t -> t -> Path.t * (value_description * bool)
+val lookup_value: Longident.t -> t -> (Path.t * value_description) list
 val lookup_annot: Longident.t -> t -> Path.t * Annot.ident
 val lookup_constructor: Longident.t -> t -> constructor_description
 val lookup_label: Longident.t -> t -> label_description

File typing/typecore.ml

   | Not_a_variant_type of Longident.t
   | Incoherent_label_order
   | Less_general of string * (type_expr * type_expr) list
+  | Overload_resolution_failure of Longident.t * type_expr * (Path.t * value_description) list
 
 exception Error of Location.t * error
 
        Env.t -> Location.t -> Parsetree.class_structure ->
          class_structure * class_signature * string list)
 
+let overload_instances = ref []
+let register_overload_instance e = overload_instances := e :: !overload_instances
+let resolve_overloading () = 
+  (* Save the instances and clean the ref first *)
+  let instances = !overload_instances in
+  overload_instances := [];
+  (* Check each instance *)
+  List.iter (fun e -> 
+    match e.exp_desc with
+    | Texp_over_ident (lid, r, path_descs) ->
+        begin match 
+          List.filter (fun (path, desc) ->
+            Ctype.unifiable e.exp_env e.exp_type (instance desc.val_type)) 
+            path_descs
+        with
+        | ([]|_::_::_ as cands) -> 
+            raise(Error(e.exp_loc, Overload_resolution_failure (lid, e.exp_type, cands)))
+        | [path, desc] ->
+            r := Some (path, desc);
+            Ctype.unify e.exp_env e.exp_type (instance desc.val_type)
+        end
+    | _ -> assert false
+  ) instances
+  
 (*
   Saving and outputting type information.
   We keep these function names short, because they have to be
                 (Stypes.An_ident (loc, name_of_path path, annot))
           with _ -> ()
         end;
-        let (path, desc) = Typetexp.find_value env loc lid in
-	Spot.Annot.record loc (Spot.Annot.Use (Spot.Kind.Value, path));
-        re {
-          exp_desc =
-            begin match desc.val_kind with
-              Val_ivar (_, cl_num) ->
-                let (self_path, _) =
-                  Env.lookup_value (Longident.Lident ("self-" ^ cl_num)) env
-                in
-                Texp_instvar(self_path, path)
-            | Val_self (_, _, cl_num, _) ->
-                let (path, _) =
-                  Env.lookup_value (Longident.Lident ("self-" ^ cl_num)) env
-                in
-                Texp_ident(path, desc)
-            | Val_unbound ->
-                raise(Error(loc, Masked_instance_variable lid))
-            | _ ->
-                Texp_ident(path, desc)
-            end;
-          exp_loc = loc;
-          exp_type = instance desc.val_type;
-          exp_env = env }
+        let path_descs = Typetexp.find_value env loc lid in
+        match path_descs with
+        | [(path, desc)] ->
+	    Spot.Annot.record loc (Spot.Annot.Use (Spot.Kind.Value, path));
+            re {
+              exp_desc =
+                begin match desc.val_kind with
+                  Val_ivar (_, cl_num) ->
+                    let self_path_s = 
+                      Env.lookup_value (Longident.Lident ("self-" ^ cl_num)) env
+                    in
+                    begin match self_path_s with
+                    | [(self_path, _)] ->
+                        Texp_instvar(self_path, path)
+                    | _ -> assert false
+                    end
+                | Val_self (_, _, cl_num, _) ->
+                    let path_s = 
+                      Env.lookup_value (Longident.Lident ("self-" ^ cl_num)) env
+                    in
+                    begin match path_s with
+                    | [(path, _)] -> Texp_ident(path, desc)
+                    | _ -> assert false
+                    end
+                | Val_unbound ->
+                    raise(Error(loc, Masked_instance_variable lid))
+                | _ ->
+                    Texp_ident(path, desc)
+                end;
+              exp_loc = loc;
+              exp_type = instance desc.val_type;
+              exp_env = env }
+        | [] -> assert false
+        | path_descs ->
+            let e = 
+              re { 
+                exp_desc = Texp_over_ident (lid, ref None, path_descs);
+                exp_loc = loc;
+                exp_type = Ctype.newvar ();
+                exp_env = env }
+            in
+            register_overload_instance e;
+            e
       end
   | Pexp_constant cst ->
       re {
                 Env.lookup_value (Longident.Lident ("selfpat-" ^ cl_num)) env,
                 Env.lookup_value (Longident.Lident ("self-" ^cl_num)) env
               with
-                (_, ({val_kind = Val_self (meths, _, _, privty)} as desc)),
-                (path, _) ->
+                [(_, ({val_kind = Val_self (meths, _, _, privty)} as desc))],
+                [(path, _)] ->
                   let (_, typ) =
                     filter_self_method env met Private meths privty
                   in
         end
   | Pexp_setinstvar (lab, snewval) ->
       begin try
-        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 (instance desc.val_type) in
-            let (path_self, _) =
-              Env.lookup_value (Longident.Lident ("self-" ^ cl_num)) env
-            in
-            re {
-              exp_desc = Texp_setinstvar(path_self, path, newval);
-              exp_loc = loc;
-              exp_type = instance Predef.type_unit;
-              exp_env = env }
-        | Val_ivar _ ->
-            raise(Error(loc,Instance_variable_not_mutable(true,lab)))
-        | _ ->
-            raise(Error(loc,Instance_variable_not_mutable(false,lab)))
+        let path_descs = Env.lookup_value (Longident.Lident lab) env in
+        match path_descs with
+        | [] | _::_::_ -> assert false
+        | [(path, desc)] ->
+            match desc.val_kind with
+              Val_ivar (Mutable, cl_num) ->
+                let newval = type_expect env snewval (instance desc.val_type) in
+                let (path_self, _) =
+                  match Env.lookup_value (Longident.Lident ("self-" ^ cl_num)) env with
+                  | [v] -> v
+                  | _ -> assert false
+                in
+                re {
+                  exp_desc = Texp_setinstvar(path_self, path, newval);
+                  exp_loc = loc;
+                  exp_type = instance Predef.type_unit;
+                  exp_env = env }
+            | Val_ivar _ ->
+                raise(Error(loc,Instance_variable_not_mutable(true,lab)))
+            | _ ->
+                raise(Error(loc,Instance_variable_not_mutable(false,lab)))
       with
         Not_found ->
           raise(Error(loc, Unbound_instance_variable lab))
         with Not_found ->
           raise(Error(loc, Outside_class))
       with
-        (_, {val_type = self_ty; val_kind = Val_self (_, vars, _, _)}),
-        (path_self, _) ->
+      | [], _ | _, [] | _::_::_, _ | _, _::_::_ -> assert false
+      | [(_, {val_type = self_ty; val_kind = Val_self (_, vars, _, _)})],
+        [(path_self, _)] ->
           let type_override (lab, snewval) =
             begin try
               let (id, _, _, ty) = Vars.find lab !vars in
                     false
                 | _ -> true
               in
-              if ty_fun.level >= t1.level && not_identity funct.exp_desc then
+              let not_overloaded = function
+                  Texp_over_ident _ -> false
+                | _ -> true
+              in
+              if ty_fun.level >= t1.level && not_identity funct.exp_desc && not_overloaded funct.exp_desc then
                 Location.prerr_warning sarg1.pexp_loc Warnings.Unused_argument;
               unify env ty_fun (newty (Tarrow(l1,t1,t2,Clink(ref Cunknown))));
               (t1, t2)
             {exp with exp_type = instance exp.exp_type}
         | _ -> type_expect exp_env sexp pat.pat_type)
       spat_sexp_list pat_list in
+  resolve_overloading();
   List.iter2
     (fun pat exp -> ignore(Parmatch.check_partial pat.pat_loc [pat, exp]))
     pat_list exp_list;
   Typetexp.reset_type_variables();
   begin_def();
   let exp = type_exp env sexp in
+  resolve_overloading ();
   end_def();
   if is_nonexpansive exp then generalize exp.exp_type
   else generalize_expansive env exp.exp_type;
       report_unification_error ppf trace
         (fun ppf -> fprintf ppf "This %s has type" kind)
         (fun ppf -> fprintf ppf "which is less general than")
+  | Overload_resolution_failure (lid, ty, []) ->
+      fprintf ppf "This overloaded value %a has no instance for type %a"
+        longident lid type_expr ty
+  | Overload_resolution_failure (lid, ty, path_descs) ->
+      let rec paths ppf = function
+        | [] -> ()
+        | [(x,_)] -> path ppf x
+        | (x,_)::xs -> fprintf ppf "%a, %a" path x paths xs
+      in
+      fprintf ppf "This overloaded value %a is ambiguous with candidates %a under type %a"
+        longident lid 
+        paths path_descs
+        type_expr ty

File typing/typecore.mli

   | Not_a_variant_type of Longident.t
   | Incoherent_label_order
   | Less_general of string * (type_expr * type_expr) list
+  | Overload_resolution_failure of Longident.t * type_expr * (Path.t * value_description) list
 
 exception Error of Location.t * error
 

File typing/typedtree.ml

 
 and expression_desc =
     Texp_ident of Path.t * value_description
+  | Texp_over_ident of Longident.t * (Path.t * value_description) option ref * (Path.t * value_description) list
   | Texp_constant of constant
   | Texp_let of rec_flag * (pattern * expression) list * expression
   | Texp_function of (pattern * expression) list * partial

File typing/typedtree.mli

 
 and expression_desc =
     Texp_ident of Path.t * value_description
+  | Texp_over_ident of Longident.t * (Path.t * value_description) option ref * (Path.t * value_description) list
   | Texp_constant of constant
   | Texp_let of rec_flag * (pattern * expression) list * expression
   | Texp_function of (pattern * expression) list * partial

File typing/typetexp.mli

 val find_type: Env.t -> Location.t -> Longident.t -> Path.t * Types.type_declaration
 val find_constructor: Env.t -> Location.t -> Longident.t -> Types.constructor_description
 val find_label: Env.t -> Location.t -> Longident.t -> Types.label_description
-val find_value: Env.t -> Location.t -> Longident.t -> Path.t * Types.value_description
+val find_value: Env.t -> Location.t -> Longident.t -> (Path.t * Types.value_description) list
 val find_class:  Env.t -> Location.t -> Longident.t -> Path.t * Types.class_declaration
 val find_module: Env.t -> Location.t -> Longident.t -> Path.t * Types.module_type
 val find_modtype: Env.t -> Location.t -> Longident.t -> Path.t * Types.modtype_declaration