Skip to content

Commit 9fe6658

Browse files
committed
fix(TacticAnalysis): include more CommandElabM state calling runTactic (#29505)
This PR fixes a few "unknown universe `v`" errors when running the tactic analysis framework on Mathlib. We need to move more state from the CommandElabM to the TermElabM that ends up running tactic code. Since we do essentially the same in a few places, bundle up all the state manipulation into a new function `runTacticCode`. Co-authored-by: Anne C.A. Baanen <vierkantor@vierkantor.com>
1 parent c2a2f49 commit 9fe6658

File tree

4 files changed

+43
-25
lines changed

4 files changed

+43
-25
lines changed

Mathlib/Lean/ContextInfo.lean

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ Released under Apache 2.0 license as described in the file LICENSE.
44
Authors: Anne Baanen
55
-/
66

7+
import Mathlib.Lean.Elab.Tactic.Meta
78
-- Import this linter explicitly to ensure that
89
-- this file has a valid copyright header and module docstring.
910
import Mathlib.Tactic.Linter.Header
@@ -77,4 +78,12 @@ def runTactic (ctx : ContextInfo) (i : TacticInfo) (goal : MVarId) (x : MVarId
7778
let goal ← Meta.mkFreshExprSyntheticOpaqueMVar type
7879
x goal.mvarId!
7980

81+
/-- Run tactic code, given by a piece of syntax, in the context of an infotree node. -/
82+
def runTacticCode (ctx : ContextInfo) (i : TacticInfo) (goal : MVarId) (code : Syntax) :
83+
CommandElabM (List MVarId) := do
84+
let termCtx ← liftTermElabM read
85+
let termState ← liftTermElabM get
86+
ctx.runTactic i goal fun goal =>
87+
Lean.Elab.runTactic' (ctx := termCtx) (s := termState) goal code
88+
8089
end Lean.Elab.ContextInfo

Mathlib/Tactic/TacticAnalysis.lean

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -285,9 +285,9 @@ def testTacticSeq (config : ComplexConfig) (tacticSeq : Array (TSyntax `tactic))
285285
let stx ← `(tactic| $(tacticSeq);*)
286286
-- TODO: support more than 1 goal. Probably by requiring all tests to succeed in a row
287287
if let [goal] := i.goalsBefore then
288-
let (oldGoals, oldHeartbeats) ← withHeartbeats <| ctxI.runTactic i goal fun goal => do
288+
let (oldGoals, oldHeartbeats) ← withHeartbeats <|
289289
try
290-
Lean.Elab.runTactic' goal stx
290+
ctxI.runTacticCode i goal stx
291291
catch e =>
292292
logWarningAt stx m!"original tactic '{stx}' failed: {e.toMessageData}"
293293
return [goal]

Mathlib/Tactic/TacticAnalysis/Declarations.lean

Lines changed: 17 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -117,14 +117,12 @@ def mergeWithGrind : TacticAnalysis.Config where
117117
if let #[(preCtx, preI), (_postCtx, postI)] := seq[0:2].array then
118118
if postI.stx.getKind == ``Lean.Parser.Tactic.grind then
119119
if let [goal] := preI.goalsBefore then
120-
preCtx.runTactic preI goal <| fun goal => do
121-
let tac := postI.stx
122-
let (goals, _) ← try
123-
Lean.Elab.runTactic goal tac
124-
catch _e =>
125-
pure ([goal], {})
126-
if goals.isEmpty then
127-
logWarningAt preI.stx m!"'{preI.stx}; grind' can be replaced with 'grind'"
120+
let goals ← try
121+
preCtx.runTacticCode preI goal postI.stx
122+
catch _e =>
123+
pure [goal]
124+
if goals.isEmpty then
125+
logWarningAt preI.stx m!"'{preI.stx}; grind' can be replaced with 'grind'"
128126

129127
/-- Suggest replacing a sequence of tactics with `grind` if that also solves the goal. -/
130128
register_option linter.tacticAnalysis.terminalToGrind : Bool := {
@@ -153,27 +151,23 @@ def terminalToGrind : TacticAnalysis.Config where
153151
-- closes the goal like it does in userspace.
154152
let suffix := ⟨i.stx⟩ :: replaced
155153
let seq ← `(tactic| $suffix.toArray;*)
156-
let (oldGoals, heartbeats) ← withHeartbeats <| ctx.runTactic i goal <| fun goal => do
157-
let (goals, _) ←
158-
try
159-
Lean.Elab.runTactic goal seq
160-
catch _e =>
161-
pure ([goal], {})
162-
return goals
154+
let (oldGoals, heartbeats) ← withHeartbeats <|
155+
try
156+
ctx.runTacticCode i goal seq
157+
catch _e =>
158+
pure [goal]
163159
if !oldGoals.isEmpty then
164160
logWarningAt i.stx m!"Original tactics failed to solve the goal: {seq}"
165161
oldHeartbeats := heartbeats
166162

167163
-- To check if `grind` can close the goal, run `grind` on the current goal
168164
-- and verify that no goals remain afterwards.
169-
let (newGoals, heartbeats) ← withHeartbeats <| ctx.runTactic i goal <| fun goal => do
170-
let tac ← `(tactic| grind)
171-
let (goals, _) ←
172-
try
173-
Lean.Elab.runTactic goal tac
174-
catch _e =>
175-
pure ([goal], {})
176-
return goals
165+
let tac ← `(tactic| grind)
166+
let (newGoals, heartbeats) ← withHeartbeats <|
167+
try
168+
ctx.runTacticCode i goal tac
169+
catch _e =>
170+
pure [goal]
177171
newHeartbeats := heartbeats
178172
if newGoals.isEmpty then
179173
success := true

MathlibTest/TacticAnalysis.lean

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,4 +58,19 @@ example : 1 + 1 = 2 := by
5858
have : 1 + 1 < 4 := by omega
5959
rfl
6060

61+
universe u v
62+
63+
-- This next example used to fail with `unknown universe level 'v'`.
64+
65+
/--
66+
warning: replace the proof with 'grind': let T : Type max u v := Sigma f;
67+
have : 1 + 1 = 2 := rfl;
68+
rfl
69+
-/
70+
#guard_msgs in
71+
example {α : Type u} (f : α → Type max u v) : 1 = 1 := by
72+
let T : Type max u v := Sigma f
73+
have : 1 + 1 = 2 := rfl -- Extra line to ensure the linter picks it up.
74+
rfl
75+
6176
end replaceWithGrind

0 commit comments

Comments
 (0)