Skip to content

Commit 109ac95

Browse files
kim-emclaude
andauthored
fix: revert "set_library_suggestions makes auxiliary def (#11396)" (#11417)
This PR reverts #11396, which changed `set_library_suggestions` to create an auxiliary definition marked with `@[library_suggestions]`, rather than storing `Syntax` directly in the environment extension. It wasn't tested properly. Co-authored-by: Claude <[email protected]>
1 parent b19468f commit 109ac95

File tree

5 files changed

+102
-91
lines changed

5 files changed

+102
-91
lines changed

src/Lean/LibrarySuggestions/Basic.lean

Lines changed: 27 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -368,37 +368,38 @@ def currentFile : Selector := fun _ cfg => do
368368
| _ => continue
369369
return suggestions
370370

371-
builtin_initialize librarySuggestionsExt : SimplePersistentEnvExtension Name (Option Name) ←
371+
builtin_initialize librarySuggestionsExt : SimplePersistentEnvExtension Syntax (Option Syntax) ←
372372
registerSimplePersistentEnvExtension {
373-
addEntryFn := fun _ name => some name -- Last entry wins
373+
addEntryFn := fun _ stx => some stx -- Last entry wins
374374
addImportedFn := fun entries =>
375-
-- Take the last selector name from all imported modules
375+
-- Take the last selector syntax from all imported modules
376376
entries.foldl (init := none) fun acc moduleEntries =>
377-
moduleEntries.foldl (init := acc) fun _ name => some name
377+
moduleEntries.foldl (init := acc) fun _ stx => some stx
378378
}
379379

380-
/-- Attribute for registering library suggestions selectors. -/
381-
builtin_initialize librarySuggestionsAttr : TagAttribute ←
382-
registerTagAttribute `library_suggestions "library suggestions selector" fun declName => do
383-
let decl ← getConstInfo declName
384-
unless decl.type == mkConst ``Selector do
385-
throwError "declaration '{declName}' must have type `Selector`"
386-
modifyEnv fun env => librarySuggestionsExt.addEntry env declName
380+
/--
381+
Helper function to elaborate and evaluate selector syntax.
382+
This is shared by both validation (`elabSetLibrarySuggestions`) and retrieval (`getSelector`).
383+
-/
384+
def elabAndEvalSelector (stx : Syntax) : MetaM Selector :=
385+
Elab.Term.TermElabM.run' do
386+
let selectorTerm ← Elab.Term.elabTermEnsuringType stx (some (Expr.const ``Selector []))
387+
unsafe Meta.evalExpr Selector (Expr.const ``Selector []) selectorTerm
387388

388389
/--
389-
Get the currently registered library suggestions selector by looking up the stored declaration name.
390+
Get the currently registered library suggestions selector by evaluating the stored syntax.
390391
Returns `none` if no selector is registered or if evaluation fails.
392+
393+
Uses `Term.elabTermEnsuringType` to elaborate arbitrary syntax (not just identifiers).
391394
-/
392-
unsafe def getSelectorImpl : MetaM (Option Selector) := do
393-
let some declName := librarySuggestionsExt.getState (← getEnv) | return none
395+
def getSelector : MetaM (Option Selector) := do
396+
let some stx := librarySuggestionsExt.getState (← getEnv) | return none
394397
try
395-
evalConstCheck Selector ``Selector declName
398+
let selector ← elabAndEvalSelector stx
399+
return some selector
396400
catch _ =>
397401
return none
398402

399-
@[implemented_by getSelectorImpl]
400-
opaque getSelector : MetaM (Option Selector)
401-
402403
/-- Generate library suggestions for the given metavariable, using the currently registered library suggestions engine. -/
403404
def select (m : MVarId) (c : Config := {}) : MetaM (Array Suggestion) := do
404405
let some selector ← getSelector |
@@ -424,11 +425,14 @@ def elabSetLibrarySuggestions : CommandElab
424425
| `(command| set_library_suggestions $selector) => do
425426
if `Lean.LibrarySuggestions.Basic ∉ (← getEnv).header.moduleNames then
426427
logWarning "Add `import Lean.LibrarySuggestions.Basic` before using the `set_library_suggestions` command."
427-
-- Generate a fresh name for the selector definition
428-
let name ← liftMacroM <| Macro.addMacroScope `_librarySuggestions
429-
-- Elaborate the definition with the library_suggestions attribute
430-
-- Note: not private, to ensure visibility across module boundaries
431-
elabCommand (← `(@[library_suggestions] def $(mkIdent name) : Selector := $selector))
428+
-- Validate that the syntax can be elaborated (to catch errors early)
429+
liftTermElabM do
430+
try
431+
discard <| elabAndEvalSelector selector
432+
catch _ =>
433+
throwError "Failed to elaborate {selector} as a `MVarId → Config → MetaM (Array Suggestion)`."
434+
-- Store the syntax (not the evaluated Selector) for persistence
435+
modifyEnv fun env => librarySuggestionsExt.addEntry env selector
432436
| _ => throwUnsupportedSyntax
433437

434438
open Lean.Elab.Tactic in

stage0/src/stdlib_flags.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
#include "util/options.h"
22

3-
// stage0 update needed for grind_annotated command
3+
// stage0 update needed: revert library_suggestions aux def
44
namespace lean {
55
options get_default_options() {
66
options opts;

tests/lean/run/library_suggestions.lean

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@ has type
88
of sort `Type 1` but is expected to have type
99
Lean.LibrarySuggestions.Selector
1010
of sort `Type`
11+
---
12+
error: Failed to elaborate Nat as a `MVarId → Config → MetaM (Array Suggestion)`.
1113
-/
1214
#guard_msgs in
1315
set_library_suggestions Nat
Lines changed: 40 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -1,45 +1,47 @@
1-
-- This will be restored after an update-stage0
2-
-- import Lean.LibrarySuggestions
3-
-- import Lean.Meta.Basic
1+
import Lean.LibrarySuggestions
2+
import Lean.Meta.Basic
43

5-
-- /-!
6-
-- # Test that library suggestions persist across file boundaries
4+
/-!
5+
# Test that library suggestions persist across file boundaries
76
8-
-- This test verifies that the default library suggestion engine set in
9-
-- `Lean.LibrarySuggestions.Default` is correctly persisted when imported via `Lean.LibrarySuggestions`.
7+
This test verifies that the default library suggestion engine set in
8+
`Lean.LibrarySuggestions.Default` is correctly persisted when imported via `Lean.LibrarySuggestions`.
109
11-
-- We do NOT call `set_library_suggestions` in this file - the selector should
12-
-- already be set from importing Lean.LibrarySuggestions (which imports Default).
13-
-- -/
10+
We do NOT call `set_library_suggestions` in this file - the selector should
11+
already be set from importing Lean.LibrarySuggestions (which imports Default).
12+
-/
1413

15-
-- /--
16-
-- info: ✓ Selector registered in imported state
17-
-- ---
18-
-- info: ✓ getSelector succeeded
19-
-- -/
20-
-- #guard_msgs in
21-
-- open Lean Lean.LibrarySuggestions in
22-
-- run_cmd do
23-
-- -- Check if a selector is registered
24-
-- let hasSelector := (librarySuggestionsExt.getState (← getEnv)).isSome
25-
-- if hasSelector then
26-
-- Lean.logInfo "✓ Selector registered in imported state"
27-
-- -- Try to retrieve the selector using getSelector
28-
-- Elab.Command.liftTermElabM do
29-
-- let selector? ← getSelector
30-
-- match selector? with
31-
-- | none => Lean.logInfo " ❌ getSelector returned none"
32-
-- | some _ => Lean.logInfo " ✓ getSelector succeeded"
33-
-- else
34-
-- Lean.logInfo "❌ No selector registered in imported state!"
14+
/--
15+
info: ✓ Selector found in imported state: (Term.open
16+
"open"
17+
(Command.openSimple [`Lean.LibrarySuggestions])
18+
"in"
19+
(Term.app `sineQuaNonSelector.filterGrindAnnotated.intersperse [`currentFile]))
20+
---
21+
info: ✓ Successfully retrieved selector using getSelector!
22+
-/
23+
#guard_msgs in
24+
open Lean Lean.LibrarySuggestions in
25+
run_cmd do
26+
let stx? := librarySuggestionsExt.getState (← getEnv)
27+
match stx? with
28+
| none => Lean.logInfo "❌ No selector found in imported state!"
29+
| some stx =>
30+
Lean.logInfo s!"✓ Selector found in imported state: {stx}"
31+
-- Try to retrieve the selector using getSelector
32+
Elab.Command.liftTermElabM do
33+
let selector? ← getSelector
34+
match selector? with
35+
| none => Lean.logInfo " ❌ getSelector returned none"
36+
| some _ => Lean.logInfo " ✓ Successfully retrieved selector using getSelector!"
3537

36-
-- -- These examples should work with grind +suggestions but not grind alone
37-
-- -- (proving that the suggestions engine is active and helping)
38+
-- These examples should work with grind +suggestions but not grind alone
39+
-- (proving that the suggestions engine is active and helping)
3840

39-
-- example {x : Dyadic} {prec : Int} : x.roundDown prec ≤ x := by
40-
-- fail_if_success grind
41-
-- grind +suggestions
41+
example {x : Dyadic} {prec : Int} : x.roundDown prec ≤ x := by
42+
fail_if_success grind
43+
grind +suggestions
4244

43-
-- example {x : Dyadic} {prec : Int} : (x.roundUp prec).precision ≤ some prec := by
44-
-- fail_if_success grind
45-
-- grind +suggestions
45+
example {x : Dyadic} {prec : Int} : (x.roundUp prec).precision ≤ some prec := by
46+
fail_if_success grind
47+
grind +suggestions
Lines changed: 32 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,33 +1,36 @@
1-
-- This will be restored after an update-stage0
2-
-- import Lean
1+
module
2+
import Lean
33

4-
-- /-!
5-
-- # Test that library suggestions persist across file boundaries
4+
/-!
5+
# Test that library suggestions persist across file boundaries
66
7-
-- This test verifies that the default library suggestion engine set in
8-
-- `Lean.LibrarySuggestions.Default` is correctly persisted when imported via `Lean.LibrarySuggestions`.
7+
This test verifies that the default library suggestion engine set in
8+
`Lean.LibrarySuggestions.Default` is correctly persisted when imported via `Lean.LibrarySuggestions`.
99
10-
-- We do NOT call `set_library_suggestions` in this file - the selector should
11-
-- already be set from importing Lean.LibrarySuggestions (which imports Default).
12-
-- -/
10+
We do NOT call `set_library_suggestions` in this file - the selector should
11+
already be set from importing Lean.LibrarySuggestions (which imports Default).
12+
-/
1313

14-
-- /--
15-
-- info: ✓ Selector registered in imported state
16-
-- ---
17-
-- info: ✓ getSelector succeeded
18-
-- -/
19-
-- #guard_msgs in
20-
-- open Lean Lean.LibrarySuggestions in
21-
-- run_cmd do
22-
-- -- Check if a selector is registered
23-
-- let hasSelector := (librarySuggestionsExt.getState (← getEnv)).isSome
24-
-- if hasSelector then
25-
-- Lean.logInfo "✓ Selector registered in imported state"
26-
-- -- Try to retrieve the selector using getSelector
27-
-- Elab.Command.liftTermElabM do
28-
-- let selector? ← getSelector
29-
-- match selector? with
30-
-- | none => Lean.logInfo " ❌ getSelector returned none"
31-
-- | some _ => Lean.logInfo " ✓ getSelector succeeded"
32-
-- else
33-
-- Lean.logInfo "❌ No selector registered in imported state!"
14+
/--
15+
info: ✓ Selector found in imported state: (Term.open
16+
"open"
17+
(Command.openSimple [`Lean.LibrarySuggestions])
18+
"in"
19+
(Term.app `sineQuaNonSelector.filterGrindAnnotated.intersperse [`currentFile]))
20+
---
21+
info: ✓ Successfully retrieved selector using getSelector!
22+
-/
23+
#guard_msgs in
24+
open Lean Lean.LibrarySuggestions in
25+
run_cmd do
26+
let stx? := librarySuggestionsExt.getState (← getEnv)
27+
match stx? with
28+
| none => Lean.logInfo "❌ No selector found in imported state!"
29+
| some stx =>
30+
Lean.logInfo s!"✓ Selector found in imported state: {stx}"
31+
-- Try to retrieve the selector using getSelector
32+
Elab.Command.liftTermElabM do
33+
let selector? ← getSelector
34+
match selector? with
35+
| none => Lean.logInfo " ❌ getSelector returned none"
36+
| some _ => Lean.logInfo " ✓ Successfully retrieved selector using getSelector!"

0 commit comments

Comments
 (0)