fix(library/coercion): spurious 'replacing coercion', fixes #22
Signed-off-by: Leonardo de Moura <leonardo@microsoft.com>
This commit is contained in:
parent
b832b2e33e
commit
53833c70e9
1 changed files with 21 additions and 14 deletions
|
@ -67,11 +67,11 @@ struct coercion_info {
|
||||||
};
|
};
|
||||||
|
|
||||||
struct coercion_state {
|
struct coercion_state {
|
||||||
rb_map<name, list<coercion_info>, name_quick_cmp> m_coercion_info;
|
rb_map<name, list<coercion_info>, name_quick_cmp> m_coercion_info;
|
||||||
// m_from and m_to contain "direct" coercions
|
// m_from and m_to contain "direct" coercions
|
||||||
rb_map<name, list<coercion_class>, name_quick_cmp> m_from;
|
rb_map<name, list<std::pair<coercion_class, expr>>, name_quick_cmp> m_from; // map user-class -> list of (class, coercion-fun)
|
||||||
rb_map<coercion_class, list<name>, coercion_class_cmp_fn> m_to;
|
rb_map<coercion_class, list<name>, coercion_class_cmp_fn> m_to;
|
||||||
rb_tree<name, name_quick_cmp> m_coercions;
|
rb_tree<name, name_quick_cmp> m_coercions;
|
||||||
coercion_info get_info(name const & from, coercion_class const & to) {
|
coercion_info get_info(name const & from, coercion_class const & to) {
|
||||||
auto it = m_coercion_info.find(from);
|
auto it = m_coercion_info.find(from);
|
||||||
lean_assert(it);
|
lean_assert(it);
|
||||||
|
@ -81,15 +81,21 @@ struct coercion_state {
|
||||||
}
|
}
|
||||||
lean_unreachable(); // LCOV_EXCL_LINE
|
lean_unreachable(); // LCOV_EXCL_LINE
|
||||||
}
|
}
|
||||||
void update_from_to(name const & C, coercion_class const & D, io_state const & ios) {
|
void update_from_to(name const & C, coercion_class const & D, expr const & f, io_state const & ios) {
|
||||||
auto it1 = m_from.find(C);
|
auto it1 = m_from.find(C);
|
||||||
if (!it1)
|
if (!it1) {
|
||||||
m_from.insert(C, list<coercion_class>(D));
|
m_from.insert(C, list<std::pair<coercion_class, expr>>(mk_pair(D, f)));
|
||||||
else if (std::find(it1->begin(), it1->end(), D) == it1->end())
|
} else {
|
||||||
m_from.insert(C, list<coercion_class>(D, *it1));
|
auto it = it1->begin();
|
||||||
else
|
auto end = it1->end();
|
||||||
ios.get_diagnostic_channel() << "replacing the coercion from '" << C << "' to '" << D << "'\n";
|
for (; it != end; ++it)
|
||||||
|
if (it->first == D)
|
||||||
|
break;
|
||||||
|
if (it == end)
|
||||||
|
m_from.insert(C, cons(mk_pair(D, f), *it1));
|
||||||
|
else if (it->second != f)
|
||||||
|
ios.get_diagnostic_channel() << "replacing the coercion from '" << C << "' to '" << D << "'\n";
|
||||||
|
}
|
||||||
auto it2 = m_to.find(D);
|
auto it2 = m_to.find(D);
|
||||||
if (!it2)
|
if (!it2)
|
||||||
m_to.insert(D, list<name>(C));
|
m_to.insert(D, list<name>(C));
|
||||||
|
@ -216,7 +222,8 @@ struct add_coercion_fn {
|
||||||
auto it = m_state.m_from.find(D);
|
auto it = m_state.m_from.find(D);
|
||||||
if (!it)
|
if (!it)
|
||||||
return;
|
return;
|
||||||
for (coercion_class E : *it) {
|
for (auto const & p : *it) {
|
||||||
|
coercion_class E = p.first;
|
||||||
coercion_info info = m_state.get_info(D, E);
|
coercion_info info = m_state.get_info(D, E);
|
||||||
// C >-> D >-> E
|
// C >-> D >-> E
|
||||||
add_coercion_trans(C, ls, f, f_type, num_args,
|
add_coercion_trans(C, ls, f, f_type, num_args,
|
||||||
|
@ -258,7 +265,7 @@ struct add_coercion_fn {
|
||||||
coercion_state operator()(name const & C, expr const & f, expr const & f_type,
|
coercion_state operator()(name const & C, expr const & f, expr const & f_type,
|
||||||
level_param_names const & ls, unsigned num_args, coercion_class const & cls) {
|
level_param_names const & ls, unsigned num_args, coercion_class const & cls) {
|
||||||
add_coercion(C, f, f_type, ls, num_args, cls);
|
add_coercion(C, f, f_type, ls, num_args, cls);
|
||||||
m_state.update_from_to(C, cls, m_ios);
|
m_state.update_from_to(C, cls, f, m_ios);
|
||||||
return m_state;
|
return m_state;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in a new issue