Skip to content

Commit 0f8eef5

Browse files
fix: Elaborate the source body in getFileEnv (#456)
* fix: getFileEnv elaborates the file body, not just imports `getFileEnv` ran only `processHeaderCore`, so the returned environment held the file's imports but none of its own definitions. As a result `ix compile foo.lean` produced an env without foo's constants, and `--only-const <name>` over the resulting `.ixe` could not resolve any name defined in the source file (e.g. `myReflEq` in MinimalDefs). Run the body through `IO.processCommands` (as `runFrontend` does) so the environment includes the file's definitions. Also fixes `ix validate` and `ix ingress`, which share `getFileEnv`. * test: guard that getFileEnv loads the file body, not just imports Adds `Tests.Ix.EnvBody`, run in the default suite: it loads the existing `Tests/Ix/Fixtures/Export.lean` fixture via `getFileEnv` and asserts its body definition (`inductive MyNat`) is present, alongside an imported constant (`Nat`). The body assertion is red under the header-only regression and green with the body-elaboration fix.
1 parent 62e0a0f commit 0f8eef5

3 files changed

Lines changed: 48 additions & 1 deletion

File tree

Ix/Meta.lean

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,15 @@ def getFileEnv (path : FilePath) : IO Environment := do
4141
if messages.hasErrors then
4242
throw $ IO.userError $ "\n\n".intercalate $
4343
(← messages.toList.mapM (·.toString)).map (String.trimAscii · |>.toString)
44-
return env
44+
-- Elaborate the file body too, so the env contains the file's own
45+
-- definitions and not just its imports.
46+
let env := env.setMainModule default
47+
let s ← IO.processCommands inputCtx parserState (Command.mkState env messages)
48+
let cmdMessages := s.commandState.messages
49+
if cmdMessages.hasErrors then
50+
throw $ IO.userError $ "\n\n".intercalate $
51+
(← cmdMessages.toList.mapM (·.toString)).map (String.trimAscii · |>.toString)
52+
return s.commandState.env
4553

4654
/-- Captures the current module and its imports at compile time. -/
4755
elab "this_file!" : term => do

Tests/Ix/EnvBody.lean

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
/-
2+
Regression guard: `getFileEnv` must load a file's own definitions (its body),
3+
not only its imports.
4+
5+
`getFileEnv` previously ran only `processHeaderCore`, so the environment it
6+
returned held the file's imports but none of its own constants — meaning
7+
`ix compile`/`validate`/`ingress` emitted an env missing the file's definitions.
8+
This loads an existing fixture (`Export.lean`, which defines `inductive MyNat`)
9+
and asserts that body definition is present, alongside an imported constant.
10+
-/
11+
12+
module
13+
14+
public import Ix.Meta
15+
public import LSpec
16+
public import Lean
17+
18+
open LSpec
19+
20+
namespace Tests.Ix.EnvBody
21+
22+
/-- Path is relative to the repository root, which is the working directory when
23+
`lake test` runs the `IxTests` executable. -/
24+
def fixturePath : System.FilePath := "Tests/Ix/Fixtures/Export.lean"
25+
26+
public def suite : IO LSpec.TestSeq := do
27+
let env ← getFileEnv fixturePath
28+
pure $
29+
LSpec.test "getFileEnv includes the file body (not just imports)"
30+
((env.constants.find? `MyNat).isSome)
31+
++ LSpec.test "getFileEnv still includes imports"
32+
((env.constants.find? `Nat).isSome)
33+
34+
end Tests.Ix.EnvBody

Tests/Main.lean

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ import Tests.Keccak
2727
import Tests.MultiStark
2828
import Tests.Cli
2929
import Tests.ShardMap
30+
import Tests.Ix.EnvBody
3031
import Ix.Common
3132
import Ix.Meta
3233
import Ix.IxVM
@@ -144,6 +145,10 @@ def main (args : List String) : IO UInt32 := do
144145
let primaryArgs := if runIgnored || includeIgnored then [] else filterArgs
145146
let primaryResult ← LSpec.lspecIO primarySuites primaryArgs
146147
if primaryResult != 0 then return primaryResult
148+
-- getFileEnv body-inclusion regression guard (IO: loads a fixture file)
149+
let envBodySeq ← Tests.Ix.EnvBody.suite
150+
let envBodyResult ← LSpec.lspecIO (.ofList [("getfileenv-body", [envBodySeq])]) primaryArgs
151+
if envBodyResult != 0 then return envBodyResult
147152

148153
-- Run ignored tests when --ignored or --include-ignored is specified
149154
if runIgnored || includeIgnored then

0 commit comments

Comments
 (0)