fix: where finally should enter the private scope (#10151)
This PR ensures `where finally` tactics can access private data under the module system even when the corresponding holes are in the public scope as long as all of them are of proposition types.
This commit is contained in:
parent
43dc9f45d1
commit
4d5fb31dfb
2 changed files with 39 additions and 3 deletions
|
|
@ -656,20 +656,44 @@ private def ExprWithHoles.getHoles (e : ExprWithHoles) : TermElabM (Array MVarId
|
|||
private def fillHolesFromWhereFinally (name : Name) (es : Array ExprWithHoles) (whereFinally : WhereFinallyView) : TermElabM PUnit := do
|
||||
if whereFinally.isNone then return
|
||||
let goals := (← es.mapM fun e => e.getHoles).flatten
|
||||
|
||||
-- Exit exporting context if entering proof(s), analogous to `Term.runTactic`.
|
||||
-- NOTE: when entering a proof/data mix, we must conservatively default to not changing the
|
||||
-- context.
|
||||
let wasExporting := (← getEnv).isExporting
|
||||
let isNoLongerExporting ← pure wasExporting <&&> goals.allM fun mvarId => do
|
||||
mvarId.withContext do
|
||||
isProp (← mvarId.getType)
|
||||
|
||||
let mut goals' := goals
|
||||
if isNoLongerExporting then
|
||||
goals' ← goals.mapM fun mvarId => do
|
||||
let mvarDecl ← getMVarDecl mvarId
|
||||
return (← mkFreshExprMVarAt mvarDecl.lctx mvarDecl.localInstances mvarDecl.type mvarDecl.kind mvarDecl.userName).mvarId!
|
||||
|
||||
withExporting (isExporting := wasExporting && !isNoLongerExporting) do
|
||||
Lean.Elab.Term.TermElabM.run' do
|
||||
Term.withDeclName name do
|
||||
withRef whereFinally.ref do
|
||||
unless goals.isEmpty do
|
||||
-- make info from `runTactic` available
|
||||
goals.forM fun goal => pushInfoTree (.hole goal)
|
||||
goals'.forM fun goal => pushInfoTree (.hole goal)
|
||||
-- assign goals
|
||||
let remainingGoals ← Tactic.run goals[0]! do
|
||||
Tactic.setGoals goals.toList
|
||||
let remainingGoals ← Tactic.run goals'[0]! do
|
||||
Tactic.setGoals goals'.toList
|
||||
Tactic.withTacticInfoContext whereFinally.ref do
|
||||
Tactic.evalTactic whereFinally.tactic
|
||||
-- complain if any goals remain
|
||||
unless remainingGoals.isEmpty do
|
||||
Term.reportUnsolvedGoals remainingGoals
|
||||
if isNoLongerExporting then
|
||||
for mvarId in goals, mvarId' in goals' do
|
||||
let mut e ← instantiateExprMVars (.mvar mvarId')
|
||||
if !e.isFVar then
|
||||
e ← mvarId'.withContext do
|
||||
withExporting (isExporting := wasExporting) do
|
||||
abstractProof e
|
||||
mvarId.assign e
|
||||
|
||||
namespace MutualClosure
|
||||
|
||||
|
|
|
|||
|
|
@ -1,3 +1,7 @@
|
|||
module
|
||||
|
||||
public section
|
||||
|
||||
example (i j : Nat) (xs : Array Nat) (hi : i < xs.size) (hj: j < xs.size) :=
|
||||
match i with
|
||||
| 0 => x
|
||||
|
|
@ -113,3 +117,11 @@ def hole_decreasing_does_not_exist (i : Nat) (xs : Array Nat) (h : i < xs.size)
|
|||
where finally
|
||||
case hole => exact h
|
||||
| decreasing => skip
|
||||
|
||||
/-! `where finally` should open a private scope. -/
|
||||
|
||||
private theorem priv : True := .intro
|
||||
|
||||
@[expose] def pub : True := ?_
|
||||
where finally
|
||||
exact priv
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue