diff --git a/src/frontends/lean/definition_cmds.cpp b/src/frontends/lean/definition_cmds.cpp index c05cfc958d..cf4b86a497 100644 --- a/src/frontends/lean/definition_cmds.cpp +++ b/src/frontends/lean/definition_cmds.cpp @@ -278,22 +278,15 @@ static void check_noncomputable(parser & p, environment const & env, name const } } -static environment compile_decl(parser & p, environment const & env, def_cmd_kind kind, bool is_noncomputable, - name const & c_name, name const & c_real_name, pos_info const & pos) { +static environment compile_decl(environment const & env, def_cmd_kind kind, bool is_noncomputable, + name const & c_name, name const & c_real_name) { if (is_noncomputable || kind == Theorem || is_vm_builtin_function(c_real_name)) return env; try { declaration d = env.get(c_real_name); return vm_compile(env, d); - } catch (exception & ext) { - flycheck_warning wrn(p.ios()); - auto & out = p.ios().get_regular_stream(); - display_pos(out, p, pos); - out << "failed to generate bytecode for '" << c_name << "'" << std::endl; - type_context ctx(p.env()); - auto out2 = regular(p.env(), p.ios(), ctx); - display_error(out2, get_pos_info_provider(), ext); - return env; + } catch (exception & ex) { + throw nested_exception(sstream() << "failed to generate bytecode for '" << c_name << "'", ex); } } @@ -323,7 +316,7 @@ declare_definition(parser & p, environment const & env, def_cmd_kind kind, buffe } new_env = attrs.apply(new_env, p.ios(), c_real_name); - new_env = compile_decl(p, new_env, kind, is_noncomputable, c_name, c_real_name, pos); + new_env = compile_decl(new_env, kind, is_noncomputable, c_name, c_real_name); return mk_pair(new_env, c_real_name); } diff --git a/src/library/equations_compiler/elim_match.cpp b/src/library/equations_compiler/elim_match.cpp index 95150f74c7..e5e03a81c1 100644 --- a/src/library/equations_compiler/elim_match.cpp +++ b/src/library/equations_compiler/elim_match.cpp @@ -621,9 +621,8 @@ struct elim_match_fn { lean_assert(length(new_goals) == length(ilist)); lean_assert(length(new_goals) == length(slist)); } catch (exception & ex) { - trace_match(tout() << "dependent pattern matching step failed\n" << ex.what() << "\n";); - throw_error("equation compiler failed (use 'set_option trace.eqn_compiler.elim_match true' " - "for additional details)"); + throw nested_exception("equation compiler failed (use 'set_option trace.eqn_compiler.elim_match true' " + "for additional details)", ex); } if (empty(new_goals)) return list(); list eqns = normalize_next_pattern(P.m_equations); diff --git a/src/library/exception.cpp b/src/library/exception.cpp index c4c77e0689..e77706f313 100644 --- a/src/library/exception.cpp +++ b/src/library/exception.cpp @@ -15,4 +15,28 @@ static pp_fn mk_pp_fn(char const * msg) { generic_exception::generic_exception(optional const & m, char const * msg): generic_exception(msg, m, mk_pp_fn(msg)) {} + +optional nested_exception::get_main_expr() const { + if (m_main_expr) + return m_main_expr; + else if (ext_exception * ex = dynamic_cast(m_exception.get())) + return ex->get_main_expr(); + else + return none_expr(); +} + +format nested_exception::pp(formatter const & fmt) const { + format r = m_pp_fn(fmt); + r += line() + format("nested exception message") + line(); + if (ext_exception * ex = dynamic_cast(m_exception.get())) { + r += ex->pp(fmt); + } else { + r += format(m_exception->what()); + } + return r; +} + +throwable * nested_exception::clone() const { + return new nested_exception(m_main_expr, m_pp_fn, *m_exception); +} } diff --git a/src/library/exception.h b/src/library/exception.h index db514995e9..a94e5728d1 100644 --- a/src/library/exception.h +++ b/src/library/exception.h @@ -35,6 +35,27 @@ public: virtual void rethrow() const override { throw *this; } }; +class nested_exception : public generic_exception { + std::shared_ptr m_exception; +public: + nested_exception(optional const & m, pp_fn const & fn, throwable const & ex): + generic_exception(m, fn), m_exception(std::shared_ptr(ex.clone())) {} + nested_exception(optional const & m, char const * msg, throwable const & ex): + generic_exception(m, msg), m_exception(std::shared_ptr(ex.clone())) {} + nested_exception(optional const & m, sstream const & strm, throwable const & ex): + generic_exception(m, strm), m_exception(std::shared_ptr(ex.clone())) {} + explicit nested_exception(char const * msg, throwable const & ex): + nested_exception(none_expr(), msg, ex) {} + explicit nested_exception(sstream const & strm, throwable const & ex): + nested_exception(none_expr(), strm, ex) {} + virtual ~nested_exception() noexcept {} + + virtual optional get_main_expr() const override; + virtual format pp(formatter const & fmt) const override; + virtual throwable * clone() const override; + virtual void rethrow() const override { throw *this; } +}; + /** \brief Lean exception occurred when parsing file. */ class parser_nested_exception : public exception { std::shared_ptr m_exception;