fix(library/module): deadlock?

This commit also undoes the hackish workaround used at e33bd2e665

@gebner Could you please take a quick look at this fix, and check
whether it makes sense?
This commit is contained in:
Leonardo de Moura 2016-12-29 17:54:28 -08:00
parent e33bd2e665
commit 73bf232fea
3 changed files with 28 additions and 5 deletions

View file

@ -276,13 +276,35 @@ struct decl_modification : public modification {
LEAN_MODIFICATION("decl")
declaration m_decl;
bool m_from_olean;
decl_modification() {}
decl_modification(declaration const & decl) : m_decl(decl) {}
decl_modification(declaration const & decl, bool from_olean = false):
m_decl(decl), m_from_olean(from_olean) {}
void perform(environment & env) const override {
auto decl = m_decl;
decl = unfold_untrusted_macros(env, decl);
/* Gabriel, I had to add the following condition to avoid a deadlock that was happening at Travis.
I managed to reproduce the deadlock on my macbook, but it doesn't happen in my Ubuntu desktop.
The problem was exposed by commit 7f86ad64eb9d5f644. Before this commit, unfold_untrusted_macros
was a no-op if the user did not set the trust level in the command line.
The procedure unfold_untrusted_macros tries to access decl.get_value(). I believe the dead lock
occurs when we try to perform the modification but the proof elaboration did not finish yet.
The unfold_untrusted_macros is only needed when we are importing the declaration from a .olean
file that has been created with a different (and higher) trust level. So, it may contain macros
that will not be accepted by the current kernel, and they must be unfolded.
In a single Lean session, the trust level is fixed, and we invoke unfold_untrusted_macros
at frontends/lean/definition_cmds.cpp before we even create the declaration. So, I added
the flag m_from_olean to distinguish whether the modification came from a .olean or a .lean file.
I'm setting it to true at deserialize.
*/
if (m_from_olean) {
decl = unfold_untrusted_macros(env, decl);
}
if (decl.get_name() == get_sorry_name() && has_sorry(env)) {
// ignore double sorrys
return;
@ -296,7 +318,7 @@ struct decl_modification : public modification {
}
static std::shared_ptr<modification const> deserialize(deserializer & d) {
return std::make_shared<decl_modification>(read_declaration(d));
return std::make_shared<decl_modification>(read_declaration(d), true);
}
void get_task_dependencies(std::vector<generic_task_result> & deps) const override {

View file

@ -7,7 +7,8 @@ Author: Leonardo de Moura
#pragma once
#include "library/type_context.h"
#define LEAN_AC_MACROS_TRUST_LEVEL 10
/* TODO(Leo): reduce after testing */
#define LEAN_AC_MACROS_TRUST_LEVEL 10000000
namespace lean {
class ac_manager {

View file

@ -18,7 +18,7 @@ Author: Leonardo de Moura
/* If the trust level of all macros is < LEAN_BELIEVER_TRUST_LEVEL,
then we skip the unfold_untrusted_macros potentially expensive step.
The following definition is commented because we are currently testing the AC macros. */
#define LEAN_ALL_MACROS_HAVE_SMALL_TRUST_LVL
// #define LEAN_ALL_MACROS_HAVE_SMALL_TRUST_LVL
namespace lean {
class unfold_untrusted_macros_fn {