diff options
| author | Emilio Jesus Gallego Arias | 2020-02-11 11:33:55 +0100 |
|---|---|---|
| committer | Emilio Jesus Gallego Arias | 2020-05-15 02:19:01 +0200 |
| commit | 7e078b070b3acf6c0b24d66a150b09a7df57b09d (patch) | |
| tree | 380d22bee9648f4b828141f035500d9d2cd3ad04 /interp | |
| parent | 56e23844e80e6d607ad5fa56dfeedcd70e97ee70 (diff) | |
[misc] Better preserve backtraces in several modules
Re-raising inside exception handlers must be done with care in order
to preserve backtraces; even if newer OCaml versions do a better job
in automatically spilling `%reraise` in places that matter, there is
no guarantee for that to happen.
I've done a best-effort pass of places that were re-raising
incorrectly, hopefully I got the logic right.
There is the special case of `Nametab.error_global_not_found` which is
raised many times in response to a `Not_found` error; IMHO this error
should be converted to something more specific, however the scope of
that change would be huge as to do easily...
Diffstat (limited to 'interp')
| -rw-r--r-- | interp/constrexpr_ops.ml | 5 | ||||
| -rw-r--r-- | interp/constrintern.ml | 35 | ||||
| -rw-r--r-- | interp/modintern.ml | 9 | ||||
| -rw-r--r-- | interp/notation.ml | 46 | ||||
| -rw-r--r-- | interp/smartlocate.ml | 8 |
5 files changed, 66 insertions, 37 deletions
diff --git a/interp/constrexpr_ops.ml b/interp/constrexpr_ops.ml index d6097304ec..ea27870535 100644 --- a/interp/constrexpr_ops.ml +++ b/interp/constrexpr_ops.ml @@ -618,8 +618,9 @@ let interp_univ_constraints env evd cstrs = let cstrs' = Univ.Constraint.add cstr cstrs in try let evd = Evd.add_constraints evd (Univ.Constraint.singleton cstr) in evd, cstrs' - with Univ.UniverseInconsistency e -> - CErrors.user_err ~hdr:"interp_constraint" + with Univ.UniverseInconsistency e as exn -> + let _, info = Exninfo.capture exn in + CErrors.user_err ~hdr:"interp_constraint" ~info (Univ.explain_universe_inconsistency (Termops.pr_evd_level evd) e) in List.fold_left interp (evd,Univ.Constraint.empty) cstrs diff --git a/interp/constrintern.ml b/interp/constrintern.ml index 5ad8af6d57..af84e85d8e 100644 --- a/interp/constrintern.ml +++ b/interp/constrintern.ml @@ -164,8 +164,8 @@ let explain_internalization_error e = explain_projections_of_diff_records inductive1_id inductive2_id in pp ++ str "." -let error_bad_inductive_type ?loc = - user_err ?loc (str +let error_bad_inductive_type ?loc ?info () = + user_err ?loc ?info (str "This should be an inductive type applied to patterns.") let error_parameter_not_implicit ?loc = @@ -1086,7 +1086,9 @@ let intern_extended_global_of_qualid qid = let intern_reference qid = let r = try intern_extended_global_of_qualid qid - with Not_found -> Nametab.error_global_not_found qid + with Not_found as exn -> + let _, info = Exninfo.capture exn in + Nametab.error_global_not_found ~info qid in Smartlocate.global_of_extended_global r @@ -1170,16 +1172,20 @@ let intern_applied_reference ~isproj intern env namedctx (_, ntnvars as lvar) us let r, realref, args2 = intern_qualid ~no_secvar:true qid intern env ntnvars us args in check_applied_projection isproj realref qid; find_appl_head_data r, args2 - with Not_found -> + with Not_found as exn -> (* Extra allowance for non globalizing functions *) if !interning_grammar || env.unb then (* check_applied_projection ?? *) (gvar (loc,qualid_basename qid) us, [], []), args - else Nametab.error_global_not_found qid + else + let _, info = Exninfo.capture exn in + Nametab.error_global_not_found ~info qid else let r,realref,args2 = try intern_qualid qid intern env ntnvars us args - with Not_found -> Nametab.error_global_not_found qid + with Not_found as exn -> + let _, info = Exninfo.capture exn in + Nametab.error_global_not_found ~info qid in check_applied_projection isproj realref qid; find_appl_head_data r, args2 @@ -1810,20 +1816,22 @@ let intern_ind_pattern genv ntnvars scopes pat = let no_not = try drop_notations_pattern (function (GlobRef.IndRef _ | GlobRef.ConstructRef _) -> () | _ -> raise Not_found) genv scopes pat - with InternalizationError(loc,NotAConstructor _) -> error_bad_inductive_type ?loc + with InternalizationError(loc,NotAConstructor _) as exn -> + let _, info = Exninfo.capture exn in + error_bad_inductive_type ?loc ~info () in let loc = no_not.CAst.loc in match DAst.get no_not with | RCPatCstr (head, expl_pl, pl) -> - let c = (function GlobRef.IndRef ind -> ind | _ -> error_bad_inductive_type ?loc) head in + let c = (function GlobRef.IndRef ind -> ind | _ -> error_bad_inductive_type ?loc ()) head in let with_letin, pl2 = add_implicits_check_ind_length genv loc c (List.length expl_pl) pl in let idslpl = List.map (intern_pat genv ntnvars empty_alias) (expl_pl@pl2) in (with_letin, match product_of_cases_patterns empty_alias idslpl with | ids,[asubst,pl] -> (c,ids,asubst,chop_params_pattern loc c pl with_letin) - | _ -> error_bad_inductive_type ?loc) - | x -> error_bad_inductive_type ?loc + | _ -> error_bad_inductive_type ?loc ()) + | x -> error_bad_inductive_type ?loc () (**********************************************************************) (* Utilities for application *) @@ -2385,9 +2393,10 @@ let intern_pattern globalenv patt = try intern_cases_pattern globalenv Id.Map.empty (None,[]) empty_alias patt with - InternalizationError (loc,e) -> - user_err ?loc ~hdr:"internalize" (explain_internalization_error e) - + InternalizationError (loc,e) as exn -> + (* XXX: use regular printer? *) + let _, info = Exninfo.capture exn in + user_err ?loc ~info ~hdr:"internalize" (explain_internalization_error e) (*********************************************************************) (* Functions to parse and interpret constructions *) diff --git a/interp/modintern.ml b/interp/modintern.ml index ae152e1c1c..50f90ebea7 100644 --- a/interp/modintern.ml +++ b/interp/modintern.ml @@ -22,14 +22,15 @@ exception ModuleInternalizationError of module_internalization_error type module_kind = Module | ModType | ModAny -let error_not_a_module_loc kind loc qid = +let error_not_a_module_loc ~info kind loc qid = let s = string_of_qualid qid in let e = match kind with | Module -> Modops.ModuleTypingError (Modops.NotAModule s) | ModType -> Modops.ModuleTypingError (Modops.NotAModuleType s) | ModAny -> ModuleInternalizationError (NotAModuleNorModtype s) in - Loc.raise ?loc e + let info = Option.cata (Loc.add_loc info) info loc in + Exninfo.iraise (e,info) let error_application_to_not_path loc me = Loc.raise ?loc (Modops.ModuleTypingError (Modops.ApplicationToNotPath me)) @@ -57,7 +58,9 @@ let lookup_module_or_modtype kind qid = if kind == Module then raise Not_found; let mp = Nametab.locate_modtype qid in Dumpglob.dump_modref ?loc mp "mod"; (mp,ModType) - with Not_found -> error_not_a_module_loc kind loc qid + with Not_found as exn -> + let _, info = Exninfo.capture exn in + error_not_a_module_loc ~info kind loc qid let lookup_module lqid = fst (lookup_module_or_modtype Module lqid) diff --git a/interp/notation.ml b/interp/notation.ml index fb3cefd624..cd2df58ed4 100644 --- a/interp/notation.ml +++ b/interp/notation.ml @@ -125,13 +125,14 @@ let declare_scope scope = with Not_found -> scope_map := String.Map.add scope empty_scope !scope_map -let error_unknown_scope sc = - user_err ~hdr:"Notation" +let error_unknown_scope ~info sc = + user_err ~hdr:"Notation" ~info (str "Scope " ++ str sc ++ str " is not declared.") let find_scope ?(tolerant=false) scope = try String.Map.find scope !scope_map - with Not_found -> + with Not_found as exn -> + let _, info = Exninfo.capture exn in if tolerant then (* tolerant mode to be turn off after deprecation phase *) begin @@ -140,7 +141,7 @@ let find_scope ?(tolerant=false) scope = empty_scope end else - error_unknown_scope scope + error_unknown_scope ~info scope let check_scope ?(tolerant=false) scope = let _ = find_scope ~tolerant scope in () @@ -158,7 +159,9 @@ let normalize_scope sc = try let sc = String.Map.find sc !delimiters_map in let _ = String.Map.find sc !scope_map in sc - with Not_found -> error_unknown_scope sc + with Not_found as exn -> + let _, info = Exninfo.capture exn in + error_unknown_scope ~info sc (**********************************************************************) (* The global stack of scopes *) @@ -257,8 +260,10 @@ let remove_delimiters scope = try let _ = ignore (String.Map.find key !delimiters_map) in delimiters_map := String.Map.remove key !delimiters_map - with Not_found -> - assert false (* A delimiter for scope [scope] should exist *) + with Not_found as exn -> + let _, info = Exninfo.capture exn in + (* XXX info *) + CErrors.anomaly ~info (str "A delimiter for scope [scope] should exist") let find_delimiters_scope ?loc key = try String.Map.find key !delimiters_map @@ -1031,12 +1036,17 @@ let declare_string_interpreter ?(local=false) sc dir interp (patl,uninterp,b) = let check_required_module ?loc sc (sp,d) = try let _ = Nametab.global_of_path sp in () - with Not_found -> + with Not_found as exn -> + let _, info = Exninfo.capture exn in match d with - | [] -> user_err ?loc ~hdr:"prim_token_interpreter" - (str "Cannot interpret in " ++ str sc ++ str " because " ++ pr_path sp ++ str " could not be found in the current environment.") - | _ -> user_err ?loc ~hdr:"prim_token_interpreter" - (str "Cannot interpret in " ++ str sc ++ str " without requiring first module " ++ str (List.last d) ++ str ".") + | [] -> + user_err ?loc ~info ~hdr:"prim_token_interpreter" + (str "Cannot interpret in " ++ str sc ++ str " because " ++ pr_path sp ++ + str " could not be found in the current environment.") + | _ -> + user_err ?loc ~info ~hdr:"prim_token_interpreter" + (str "Cannot interpret in " ++ str sc ++ str " without requiring first module " ++ + str (List.last d) ++ str ".") (* Look if some notation or numeral printer in [scope] can be used in the scope stack [scopes], and if yes, using delimiters or not *) @@ -1158,8 +1168,9 @@ let interp_prim_token_gen ?loc g p local_scopes = try let (pat,loc), sc = find_interpretation p_as_ntn (find_prim_token ?loc g p) scopes in pat, (loc,sc) - with Not_found -> - user_err ?loc ~hdr:"interp_prim_token" + with Not_found as exn -> + let _, info = Exninfo.capture exn in + user_err ?loc ~info ~hdr:"interp_prim_token" ((match p with | Numeral _ -> str "No interpretation for numeral " ++ pr_notation (notation_of_prim_token p) @@ -1192,9 +1203,10 @@ let interp_notation ?loc ntn local_scopes = let (n,sc) = find_interpretation ntn (find_notation ntn) scopes in Option.iter (fun d -> warn_deprecated_notation ?loc (ntn,d)) n.not_deprecation; n.not_interp, (n.not_location, sc) - with Not_found -> - user_err ?loc - (str "Unknown interpretation for notation " ++ pr_notation ntn ++ str ".") + with Not_found as exn -> + let _, info = Exninfo.capture exn in + user_err ?loc ~info + (str "Unknown interpretation for notation " ++ pr_notation ntn ++ str ".") let uninterp_notations c = List.map_append (fun key -> keymap_find key !notations_key_table) diff --git a/interp/smartlocate.ml b/interp/smartlocate.ml index 03977fcb4e..33d8aa6064 100644 --- a/interp/smartlocate.ml +++ b/interp/smartlocate.ml @@ -56,11 +56,15 @@ let global_inductive_with_alias qid = | ref -> user_err ?loc:qid.CAst.loc ~hdr:"global_inductive" (pr_qualid qid ++ spc () ++ str "is not an inductive type.") - with Not_found -> Nametab.error_global_not_found qid + with Not_found as exn -> + let _, info = Exninfo.capture exn in + Nametab.error_global_not_found ~info qid let global_with_alias ?head qid = try locate_global_with_alias ?head qid - with Not_found -> Nametab.error_global_not_found qid + with Not_found as exn -> + let _, info = Exninfo.capture exn in + Nametab.error_global_not_found ~info qid let smart_global ?(head = false) = let open Constrexpr in CAst.with_loc_val (fun ?loc -> function | AN r -> |
