diff options
-rw-r--r-- | .depend | 2 | ||||
-rw-r--r-- | Changes | 3 | ||||
-rw-r--r-- | toplevel/topcommon.ml | 36 |
3 files changed, 41 insertions, 0 deletions
@@ -6305,6 +6305,7 @@ toplevel/genprintval.cmi : \ typing/env.cmi toplevel/topcommon.cmo : \ typing/typedtree.cmi \ + bytecomp/symtable.cmi \ parsing/printast.cmi \ typing/predef.cmi \ parsing/pprintast.cmi \ @@ -6332,6 +6333,7 @@ toplevel/topcommon.cmo : \ toplevel/topcommon.cmi toplevel/topcommon.cmx : \ typing/typedtree.cmx \ + bytecomp/symtable.cmx \ parsing/printast.cmx \ typing/predef.cmx \ parsing/pprintast.cmx \ @@ -244,6 +244,9 @@ Working version - #11774: ocamlyacc: fail if there is an I/O error (Demi Marie Obenour) +- #10647: Show hints for the "undefined global" error in the toplevel + (Wiktor Kuchta, review by Gabriel Scherer) + ### Manual and documentation: - #9430, #11291: Document the general desugaring rules for binding operators. diff --git a/toplevel/topcommon.ml b/toplevel/topcommon.ml index fc2336e8d3..dcee7bbff5 100644 --- a/toplevel/topcommon.ml +++ b/toplevel/topcommon.ml @@ -380,3 +380,39 @@ let try_run_directive ppf dir_name pdir_arg = dir_name dir_type arg_type; false end + +(* Overriding exception printers with toplevel-specific ones *) + +let loading_hint_printer ppf s = + Symtable.report_error ppf (Symtable.Undefined_global s); + let find_with_ext ext = + try Some (Load_path.find_uncap (s ^ ext)) with Not_found -> None + in + fprintf ppf + "@.Hint: @[\ + This means that the interface of a module is loaded, \ + but its implementation is not.@,"; + (* Filenames don't have to correspond to module names, + especially for archives (cmas), which bundle multiple modules. + But very often they do. *) + begin match List.find_map find_with_ext [".cma"; ".cmo"] with + | Some path -> + fprintf ppf + "Found %s @,in the load paths. \ + @,Did you mean to load it using @,#load \"%s\" \ + @,or by passing it as an argument to the toplevel?" + path (Filename.basename path) + | None -> + fprintf ppf + "Did you mean to load a compiled implementation of the module \ + @,using #load or by passing it as an argument to the toplevel?" + end; + fprintf ppf "@]" + +let () = + Location.register_error_of_exn + (function + | Symtable.Error (Symtable.Undefined_global s) -> + Some (Location.error_of_printer_file loading_hint_printer s) + | _ -> None + ) |