lean4-htt/tests/server_interactive
Joachim Breitner 2229b077d6
feat: empty by runs try? to suggest a proof (#13430)
This PR makes an empty `by` block run `try?` in the background and
surface its suggestions, while still producing the usual unsolved-goals
diagnostic. The implicit `try?` is informational only — it does not
change elaboration behavior beyond emitting messages. Behaviour is
controlled by a new option `tactic.tryOnEmptyBy`, disabled by default
for now; set it to `true` to opt in. The default may flip in a future
release.

Behaviour summary, when the option is enabled:
* The empty `by` reports unsolved goals immediately, before the
(possibly slow) `try?` has finished.
* The `try?` work is spawned as an asynchronous snapshot task
(`Term.wrapAsyncAsSnapshot` + `Core.logSnapshotTask`), so subsequent
elaboration is not blocked and the suggestions arrive when ready.
* `try?` is gated on its parser infrastructure being available, so
working on the prelude (before `Init.Try` is imported) keeps the regular
empty-`by` behaviour.
* No effect when the empty `by` appears inside a backtracking combinator
(e.g. `first | exact (by) | …`) or when `try?` finds no applicable
suggestion.

Implementation notes:
* `elabEmptyByAsTry` (in `Lean.Elab.Tactic.Try`) is registered as a
second `@[builtin_term_elab byTactic]`, alongside the existing
`elabByTactic` in `Lean.Elab.BuiltinTerm`. The gate
`shouldElabEmptyByAsTry` is checked in both elaborators so the
empty-`by` path takes the `try?` route while non-empty `by` follows the
regular path. The body shared between them is factored as
`elabByTacticCore`. The two-elaborator setup avoids a circular module
dependency between `BuiltinTerm.lean` and `Tactic/Try.lean`; an inline
comment in `Try.lean` explains this.
* A latent bug from #13229 is fixed along the way: `evalSepTactics`
returned at the very top for an empty tactic sequence without resolving
the `tacSnap` promise that `MutualDef.mkTacTask` sets up for `:= by …`
bodies. The dangling promise was harmless in typical use because the
cmd's cancellation token would fire shortly after elaboration and drop
it, but with a slow async snapshot task in the same command (as the
implicit `try?` here) the language-server info-tree walk would block on
it and the editor's Messages view would only update once the task
finished. Resolved at the early-return in `evalSepTactics`.
* The test infrastructure in `Lean.Server.Test.Cancel` gains a
label-keyed `testTasksRef` registry plus `mkTestTask` /
`wait_for_test_task`. The pre-existing `block_until_cancelled` is
reimplemented on top of `mkTestTask` and the redundant
`blockUntilCancelledOnce` ref is removed.

Tests:
* `tests/elab/tryOnEmptyBy.lean`, `tests/elab/try_prelude.lean` —
feature behaviour and prelude gating.
* `tests/server_interactive/cancellation_empty_by.lean` — verifies that
on document re-elaboration `cancelRec` reaches the empty-`by` snapshot's
cancel token registered with `Core.logSnapshotTask`. A
`[try_suggestion]` generator wires the outer cancel token's `onSet` to
resolve a `mkTestTask "T_outer"` promise, and the candidate
`wait_for_test_task "T_outer"` waits on it. If `cancelTk? := none` is
passed to `Core.logSnapshotTask`, `cancelRec` cannot reach the token,
the wait blocks, and the runner times out. If `cancelTk? := none` is
also passed to `wrapAsyncAsSnapshot`, no `onSet` resolver is registered,
the promise drops without resolution, and `wait_for_test_task` surfaces
a `"task dropped"` diagnostic on stderr.
* `tests/server_interactive/cancellation_try_plain.lean` — verifies
cancellation of plain `try?` (no `=>`) when its `[try_suggestion]`
candidate runs synchronously inside `expandUserTactic`, by chaining
through `wait_for_cancel_once_async`'s shared promise. Breaking
`SnapshotTask.cancelRec` to skip walking children causes a runner
timeout.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-05-11 06:31:42 +00:00
..
533.lean
533.lean.out.expected
863.lean
863.lean.out.expected
1018unknowMVarIssue.lean
1018unknowMVarIssue.lean.out.expected
1031.lean
1265.lean
1265.lean.out.expected
1403.lean
1403.lean.out.expected
1525.lean
1659.lean
1659.lean.out.expected
2058.lean
2058.lean.out.expected feat: server-side support for incremental diagnostics (#13260) 2026-04-21 12:48:15 +00:00
2881.lean
2881.lean.out.expected
4078.lean
4078.lean.out.expected
4880.lean
4880.lean.out.expected feat: server-side support for incremental diagnostics (#13260) 2026-04-21 12:48:15 +00:00
5659.lean
5659.lean.out.expected feat: server-side support for incremental diagnostics (#13260) 2026-04-21 12:48:15 +00:00
6594.lean
6594.lean.out.expected fix: filter assigned metavariables before computing apply subgoal tags (#13476) 2026-04-19 14:31:49 +00:00
10898.lean
10898.lean.out.expected
amb.lean
amb.lean.out.expected
anonHyp.lean
anonHyp.lean.out.expected
autoBoundIssue.lean
autoBoundIssue.lean.out.expected
builtinCodeactions.lean
builtinCodeactions.lean.out.expected
cancellation.lean
cancellation.lean.out.expected feat: server-side support for incremental diagnostics (#13260) 2026-04-21 12:48:15 +00:00
cancellation_empty_by.lean feat: empty by runs try? to suggest a proof (#13430) 2026-05-11 06:31:42 +00:00
cancellation_empty_by.lean.out.expected feat: empty by runs try? to suggest a proof (#13430) 2026-05-11 06:31:42 +00:00
cancellation_par.lean test: simplify cancellation_par test infrastructure (#13663) 2026-05-06 19:10:35 +00:00
cancellation_par.lean.out.expected test: simplify cancellation_par test infrastructure (#13663) 2026-05-06 19:10:35 +00:00
cancellation_try_plain.lean feat: empty by runs try? to suggest a proof (#13430) 2026-05-11 06:31:42 +00:00
cancellation_try_plain.lean.out.expected feat: empty by runs try? to suggest a proof (#13430) 2026-05-11 06:31:42 +00:00
catHover.lean
catHover.lean.out.expected
codeaction.lean
codeaction.lean.out.expected
codeActions.lean
codeActions.lean.out.expected
compHeader.lean chore: migrate more tests to new test suite (#12809) 2026-03-06 16:52:01 +00:00
compHeader.lean.out.expected
completion.lean
completion.lean.out.expected
completion2.lean
completion2.lean.out.expected
completion3.lean
completion3.lean.out.expected
completion4.lean
completion4.lean.out.expected
completion5.lean
completion5.lean.out.expected
completion6.lean
completion6.lean.out.expected
completion7.lean
completion7.lean.out.expected
completionAtPrint.lean
completionAtPrint.lean.out.expected
completionBracketedDot.lean
completionBracketedDot.lean.out.expected
completionCheck.lean
completionCheck.lean.out.expected
completionDanglingDot.lean
completionDanglingDot.lean.out.expected
completionDeprecation.lean
completionDeprecation.lean.out.expected
completionEmptyBy.lean fix: tactic completion in empty by blocks (#13348) 2026-04-15 08:39:55 +00:00
completionEmptyBy.lean.out.expected fix: tactic completion in empty by blocks (#13348) 2026-04-15 08:39:55 +00:00
completionEmptyByBracketed.lean fix: tactic completion in empty by blocks (#13348) 2026-04-15 08:39:55 +00:00
completionEmptyByBracketed.lean.out.expected fix: tactic completion in empty by blocks (#13348) 2026-04-15 08:39:55 +00:00
completionEndSection.lean
completionEndSection.lean.out.expected chore: migrate more tests to new test suite (#12809) 2026-03-06 16:52:01 +00:00
completionEOF.lean
completionEOF.lean.out.expected
completionFallback.lean
completionFallback.lean.out.expected
completionFromExpectedType.lean
completionFromExpectedType.lean.out.expected
completionIStr.lean
completionIStr.lean.out.expected
completionOpenNamespaces.lean
completionOpenNamespaces.lean.out.expected
completionOption.lean
completionOption.lean.out.expected chore: migrate more tests to new test suite (#12809) 2026-03-06 16:52:01 +00:00
completionPrefixIssue.lean
completionPrefixIssue.lean.out.expected
completionPrivateTypes.lean
completionPrivateTypes.lean.out.expected
completionPrv.lean
completionPrv.lean.out.expected
completionStructureInstance.lean chore: migrate more tests to new test suite (#12809) 2026-03-06 16:52:01 +00:00
completionStructureInstance.lean.out.expected
completionTactics.lean fix: tactic completion in empty by blocks (#13348) 2026-04-15 08:39:55 +00:00
completionTactics.lean.out.expected fix: tactic completion in empty by blocks (#13348) 2026-04-15 08:39:55 +00:00
compNamespace.lean chore: migrate more tests to new test suite (#12809) 2026-03-06 16:52:01 +00:00
compNamespace.lean.out.expected
definition.lean
definition.lean.out.expected
Diff.lean
Diff.lean.out.expected feat: update RPC wire format (#12905) 2026-03-13 23:46:16 +00:00
discrsIssue.lean chore: migrate more tests to new test suite (#12809) 2026-03-06 16:52:01 +00:00
discrsIssue.lean.out.expected
docstringLinksExamples.lean
docstringLinksExamples.lean.out.expected
documentSymbols.lean
documentSymbols.lean.out.expected
dotIdCompletion.lean
dotIdCompletion.lean.out.expected
dottedIdentNotation.lean
dottedIdentNotation.lean.out.expected
editAfterError.lean
editAfterError.lean.out.expected feat: server-side support for incremental diagnostics (#13260) 2026-04-21 12:48:15 +00:00
editCompletion.lean
editCompletion.lean.out.expected
errorExplanationInteractive.lean
errorExplanationInteractive.lean.out.expected
expectedTypeAsGoal.lean
expectedTypeAsGoal.lean.out.expected
explicitAppInstHole.lean
explicitAppInstHole.lean.out.expected
findReferences.lean
findReferences.lean.out.expected
foldingRange.lean chore: migrate more tests to new test suite (#12809) 2026-03-06 16:52:01 +00:00
foldingRange.lean.out.expected
fvarIdCollision.lean
fvarIdCollision.lean.out.expected
ghostGoals.lean
ghostGoals.lean.out.expected
goalEOF.lean
goalEOF.lean.out.expected
goalIssue.lean
goalIssue.lean.out.expected
goalsAccomplished.lean
goalsAccomplished.lean.out.expected feat: server-side support for incremental diagnostics (#13260) 2026-04-21 12:48:15 +00:00
goTo.lean
goTo.lean.out.expected
goTo2.lean
goTo2.lean.out.expected
guardMsgsCodeAction.lean
guardMsgsCodeAction.lean.out.expected
haveInfo.lean
haveInfo.lean.out.expected feat: server-side support for incremental diagnostics (#13260) 2026-04-21 12:48:15 +00:00
highlight.lean
highlight.lean.out.expected
highlightMatches.lean
highlightMatches.lean.out.expected feat: server-side support for incremental diagnostics (#13260) 2026-04-21 12:48:15 +00:00
hover.lean fix: preserve symbol hover for fun_induction function target (#13678) 2026-05-07 12:09:36 +00:00
hover.lean.out.expected fix: preserve symbol hover for fun_induction function target (#13678) 2026-05-07 12:09:36 +00:00
hoverAt.lean
hoverAt.lean.out.expected
hoverBinderUnderscore.lean
hoverBinderUnderscore.lean.out.expected
hoverDoForIn.lean fix: add term info for for loop variables in new do elaborator (#13399) 2026-04-13 20:29:55 +00:00
hoverDoForIn.lean.out.expected fix: add term info for for loop variables in new do elaborator (#13399) 2026-04-13 20:29:55 +00:00
hoverDot.lean
hoverDot.lean.out.expected
hoverException.lean
hoverException.lean.out.expected
hoverMatch.lean
hoverMatch.lean.out.expected
hoverTacticExt.lean
hoverTacticExt.lean.out.expected
importCompletion.lean
importCompletion.lean.out.expected
incomingCallHierarchy.lean
incomingCallHierarchy.lean.out.expected
incomingCallHierarchyWhere.lean
incomingCallHierarchyWhere.lean.out.expected
incrementalCombinator.lean
incrementalCombinator.lean.out.expected feat: server-side support for incremental diagnostics (#13260) 2026-04-21 12:48:15 +00:00
incrementalCommand.lean
incrementalCommand.lean.out.expected feat: server-side support for incremental diagnostics (#13260) 2026-04-21 12:48:15 +00:00
incrementalInduction.lean
incrementalInduction.lean.out.expected feat: server-side support for incremental diagnostics (#13260) 2026-04-21 12:48:15 +00:00
incrementalMutual.lean
incrementalMutual.lean.out.expected feat: server-side support for incremental diagnostics (#13260) 2026-04-21 12:48:15 +00:00
incrementalTactic.lean
incrementalTactic.lean.out.expected feat: server-side support for incremental diagnostics (#13260) 2026-04-21 12:48:15 +00:00
infoIssues.lean
infoIssues.lean.out.expected
inlayHints.lean
inlayHints.lean.out.expected feat: server-side support for incremental diagnostics (#13260) 2026-04-21 12:48:15 +00:00
interactiveDiagnostics.lean chore: migrate more tests to new test suite (#12809) 2026-03-06 16:52:01 +00:00
interactiveDiagnostics.lean.out.expected feat: server-side support for incremental diagnostics (#13260) 2026-04-21 12:48:15 +00:00
interactiveGoalGoToLoc.lean
interactiveGoalGoToLoc.lean.out.expected feat: update RPC wire format (#12905) 2026-03-13 23:46:16 +00:00
interactiveGoalPopups.lean
interactiveGoalPopups.lean.out.expected feat: update RPC wire format (#12905) 2026-03-13 23:46:16 +00:00
interactiveTermGoals.lean
interactiveTermGoals.lean.out.expected feat: update RPC wire format (#12905) 2026-03-13 23:46:16 +00:00
interactiveTraces.lean
interactiveTraces.lean.out.expected feat: server-side support for incremental diagnostics (#13260) 2026-04-21 12:48:15 +00:00
internalNamesIssue.lean
internalNamesIssue.lean.out.expected
inWordCompletion.lean
inWordCompletion.lean.out.expected
isRflParallel.lean
issue4527.lean
issue4527.lean.out.expected feat: server-side support for incremental diagnostics (#13260) 2026-04-21 12:48:15 +00:00
issue5021.lean
issue5021.lean.out.expected
issue5597.lean
issue5597.lean.out.expected
jumpMutual.lean
jumpMutual.lean.out.expected
keywordCompletion.lean
keywordCompletion.lean.out.expected
lean3HoverIssue.lean
lean3HoverIssue.lean.out.expected
macroGoalIssue.lean
macroGoalIssue.lean.out.expected
match.lean
match.lean.out.expected
matchPatternHover.lean
matchPatternHover.lean.out.expected chore: migrate more tests to new test suite (#12809) 2026-03-06 16:52:01 +00:00
matchStxCompletion.lean
matchStxCompletion.lean.out.expected
moduleHierarchyImports.lean
moduleHierarchyImports.lean.out.expected
outgoingCallHierarchy.lean
outgoingCallHierarchy.lean.out.expected
partialNamespace.lean
partialNamespace.lean.out.expected
plainGoal.lean feat: require indentation in commands, allow empty tactic sequences (#13229) 2026-04-08 14:05:47 +00:00
plainGoal.lean.out.expected feat: require indentation in commands, allow empty tactic sequences (#13229) 2026-04-08 14:05:47 +00:00
plainGoalEmptyBy.lean feat: require indentation in commands, allow empty tactic sequences (#13229) 2026-04-08 14:05:47 +00:00
plainGoalEmptyBy.lean.out.expected feat: require indentation in commands, allow empty tactic sequences (#13229) 2026-04-08 14:05:47 +00:00
plainTermGoal.lean
plainTermGoal.lean.out.expected
ppShowLetValues.lean
ppShowLetValues.lean.out.expected
rename.lean
rename.lean.out.expected
run_test.lean
run_test.sh chore: check test output before exit code in piles (#12947) 2026-03-17 16:34:21 +00:00
rwElabConst.lean
rwElabConst.lean.out.expected
semanticTokens.lean
semanticTokens.lean.out.expected feat: server-side support for incremental diagnostics (#13260) 2026-04-21 12:48:15 +00:00
semanticTokensVersoDocs.lean
semanticTokensVersoDocs.lean.out.expected feat: server-side support for incremental diagnostics (#13260) 2026-04-21 12:48:15 +00:00
signatureHelp.lean
signatureHelp.lean.out.expected
stdOutput.lean
strInterpSynthError.lean
strInterpSynthError.lean.out.expected feat: server-side support for incremental diagnostics (#13260) 2026-04-21 12:48:15 +00:00
structInstFieldHints.lean
structInstFieldHints.lean.out.expected
structNameParentProj.lean
structNameParentProj.lean.out.expected
tacticInduction.lean
tacticInduction.lean.out.expected
terminationBySuggestion.lean
terminationBySuggestion.lean.out.expected
travellingCompletions.lean
travellingCompletions.lean.out.expected
tryThisCodeAction.lean
tryThisCodeAction.lean.out.expected
unknownIdentifierCodeActions.lean
unknownIdentifierCodeActions.lean.out.expected
unterminatedDocComment.lean
unterminatedDocComment.lean.out.expected feat: server-side support for incremental diagnostics (#13260) 2026-04-21 12:48:15 +00:00
userWidget.lean feat: update RPC wire format (#12905) 2026-03-13 23:46:16 +00:00
userWidget.lean.out.expected
workspaceSymbols.lean
workspaceSymbols.lean.out.expected