fix: infer_let in the kernel (#10476)
This PR fixes the dead `let` elimination code in the kernel's `infer_let` function. Closes #10475
This commit is contained in:
parent
4881c3042e
commit
72bb7cf364
2 changed files with 30 additions and 33 deletions
|
|
@ -195,33 +195,15 @@ expr type_checker::infer_app(expr const & e, bool infer_only) {
|
|||
}
|
||||
}
|
||||
|
||||
static void mark_used(unsigned n, expr const * fvars, expr const & b, bool * used) {
|
||||
if (!has_fvar(b)) return;
|
||||
for_each(b, [&](expr const & x) {
|
||||
if (!has_fvar(x)) return false;
|
||||
if (is_fvar(x)) {
|
||||
for (unsigned i = 0; i < n; i++) {
|
||||
if (fvar_name(fvars[i]) == fvar_name(x)) {
|
||||
used[i] = true;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
});
|
||||
}
|
||||
|
||||
expr type_checker::infer_let(expr const & _e, bool infer_only) {
|
||||
flet<local_ctx> save_lctx(m_lctx, m_lctx);
|
||||
buffer<expr> fvars;
|
||||
buffer<expr> vals;
|
||||
expr e = _e;
|
||||
while (is_let(e)) {
|
||||
expr type = instantiate_rev(let_type(e), fvars.size(), fvars.data());
|
||||
expr val = instantiate_rev(let_value(e), fvars.size(), fvars.data());
|
||||
expr fvar = m_lctx.mk_local_decl(m_st->m_ngen, let_name(e), type, val);
|
||||
fvars.push_back(fvar);
|
||||
vals.push_back(val);
|
||||
if (!infer_only) {
|
||||
ensure_sort_core(infer_type_core(type, infer_only), type);
|
||||
expr val_type = infer_type_core(val, infer_only);
|
||||
|
|
@ -233,21 +215,7 @@ expr type_checker::infer_let(expr const & _e, bool infer_only) {
|
|||
}
|
||||
expr r = infer_type_core(instantiate_rev(e, fvars.size(), fvars.data()), infer_only);
|
||||
r = cheap_beta_reduce(r); // use `cheap_beta_reduce` (to try) to reduce number of dependencies
|
||||
buffer<bool, 128> used;
|
||||
used.resize(fvars.size(), false);
|
||||
mark_used(fvars.size(), fvars.data(), r, used.data());
|
||||
unsigned i = fvars.size();
|
||||
while (i > 0) {
|
||||
--i;
|
||||
if (used[i])
|
||||
mark_used(i, fvars.data(), vals[i], used.data());
|
||||
}
|
||||
buffer<expr> used_fvars;
|
||||
for (unsigned i = 0; i < fvars.size(); i++) {
|
||||
if (used[i])
|
||||
used_fvars.push_back(fvars[i]);
|
||||
}
|
||||
return m_lctx.mk_pi(used_fvars, r);
|
||||
return m_lctx.mk_pi(fvars, r, true);
|
||||
}
|
||||
|
||||
expr type_checker::infer_proj(expr const & e, bool infer_only) {
|
||||
|
|
|
|||
29
tests/lean/run/10475.lean
Normal file
29
tests/lean/run/10475.lean
Normal file
|
|
@ -0,0 +1,29 @@
|
|||
import Lean
|
||||
open Lean
|
||||
|
||||
/--
|
||||
info: let y : Type := Prop;
|
||||
let x : y := True;
|
||||
p x
|
||||
---
|
||||
info: let y : Type := Prop;
|
||||
let x : y := True;
|
||||
x
|
||||
---
|
||||
info: let y : Type := Prop;
|
||||
y
|
||||
-/
|
||||
#guard_msgs in
|
||||
set_option pp.letVarTypes true in
|
||||
example (p : ∀ a, a) :
|
||||
(let y := Prop; let x : y := True; p x) = p True := by
|
||||
run_tac
|
||||
let env ← Lean.getEnv
|
||||
let lctx ← getLCtx
|
||||
let_expr Eq _ lhs _ := (← Elab.Tactic.getMainTarget) | unreachable!
|
||||
logInfo lhs
|
||||
let ty ← ofExceptKernelException <| Lean.Kernel.check env lctx lhs
|
||||
logInfo ty
|
||||
let sort ← ofExceptKernelException <| Lean.Kernel.check env lctx ty
|
||||
logInfo sort
|
||||
trivial
|
||||
Loading…
Add table
Reference in a new issue