fix: make sure error ranges for if tactic are correct (#10392)

This PR fixes an issue with the `if` tactic where errors were not placed
at the correct source ranges. It also adds some error recovery to avoid
additional errors about unsolved goals on the `if` token when the tactic
has incomplete syntax.

Closes #7972
This commit is contained in:
Kyle Miller 2025-09-15 09:40:11 -07:00 committed by GitHub
parent 32a4c88986
commit 0799e5c4e9
No known key found for this signature in database
GPG key ID: B5690EEEBB952194

View file

@ -24,14 +24,17 @@ private def expandIfThenElse
pure (⟨holeOrTacticSeq⟩, #[])
else if holeOrTacticSeq.isOfKind `Lean.Parser.Term.hole then
pure (← mkName, #[])
else if tk.isMissing then
pure (← `(sorry), #[])
else
let hole ← withFreshMacroScope mkName
let holeId := hole.raw[1]
let case ← (open TSyntax.Compat in `(tactic|
case $holeId:ident =>%$tk
-- annotate `then/else` with state after `case`
with_annotate_state $tk skip
$holeOrTacticSeq))
let holeId : Ident := ⟨hole.raw[1]⟩
let tacticSeq : TSyntax `Lean.Parser.Tactic.tacticSeq := ⟨holeOrTacticSeq⟩
-- Use `missing` for ref to ensure that the source range is the same as `holeOrTacticSeq`'s.
let tacticSeq : TSyntax `Lean.Parser.Tactic.tacticSeq ← MonadRef.withRef .missing `(tacticSeq|
with_annotate_state $tk skip
($tacticSeq))
let case ← withRef tk <| `(tactic| case $holeId:ident =>%$tk $tacticSeq:tacticSeq)
pure (hole, #[case])
let (posHole, posCase) ← mkCase thenTk pos `(?pos)
let (negHole, negCase) ← mkCase elseTk neg `(?neg)