Skip to content

Commit e8b0217

Browse files
committed
Introduce cmdEnv? context field
1 parent 074516d commit e8b0217

File tree

4 files changed

+25
-14
lines changed

4 files changed

+25
-14
lines changed

src/Lean/Elab/Command.lean

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -377,7 +377,8 @@ private def mkInfoTree (elaborator : Name) (stx : Syntax) (trees : PersistentArr
377377
let scope := s.scopes.head!
378378
let tree := InfoTree.node (Info.ofCommandInfo { elaborator, stx }) trees
379379
let ctx := PartialContextInfo.commandCtx {
380-
env := s.env, fileMap := ctx.fileMap, mctx := {}, currNamespace := scope.currNamespace,
380+
env := s.env, cmdEnv? := some s.env, fileMap := ctx.fileMap, mctx := {},
381+
currNamespace := scope.currNamespace,
381382
openDecls := scope.openDecls, options := scope.opts, ngen := s.ngen
382383
}
383384
return InfoTree.context ctx tree

src/Lean/Elab/InfoTree/Main.lean

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ def PartialContextInfo.mergeIntoOuter?
5252
| .autoImplicitCtx _, none =>
5353
panic! "Unexpected incomplete InfoTree context info."
5454
| .commandCtx innerInfo, some outer =>
55-
some { outer with toCommandContextInfo := innerInfo }
55+
some { outer with toCommandContextInfo := { innerInfo with cmdEnv? := outer.cmdEnv? <|> innerInfo.cmdEnv? } }
5656
| .parentDeclCtx innerParentDecl, some outer =>
5757
some { outer with parentDecl? := innerParentDecl }
5858
| .autoImplicitCtx innerAutoImplicits, some outer =>

src/Lean/Elab/InfoTree/Types.lean

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,12 +18,23 @@ public section
1818
namespace Lean.Elab
1919

2020
/--
21-
Context after executing `liftTermElabM`.
21+
Context at the `CommandElabM/TermElabM` level. Created by `elabCommand` at the top level and then
22+
nestedly when relevant fields are affected (e.g. just before discarding the `mctx` when exiting from
23+
`TermElabM`).
24+
2225
Note that the term information collected during elaboration may contain metavariables, and their
2326
assignments are stored at `mctx`.
2427
-/
2528
structure CommandContextInfo where
2629
env : Environment
30+
/--
31+
Final environment at the end of `elabCommand`; empty for nested contexts. This environment can be
32+
used to access information about the fully-elaborated current declaration such as declaration
33+
ranges. It may not be a strict superset of `env` in case of backtracking, so `env` should be
34+
preferred to access information about the elaboration context at the time this context object was
35+
created.
36+
-/
37+
cmdEnv? : Option Environment := none
2738
fileMap : FileMap
2839
mctx : MetavarContext := {}
2940
options : Options := {}

src/Lean/Server/References.lean

Lines changed: 10 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -85,17 +85,16 @@ def addRef (i : RefInfo) (ref : Reference) : RefInfo :=
8585
def toLspRefInfo (i : RefInfo) : BaseIO Lsp.RefInfo := do
8686
let refToRefInfoLocation (ref : Reference) : BaseIO RefInfo.Location := do
8787
let parentDeclName? := ref.ci.parentDecl?
88-
let .ok parentDeclRanges? ← EIO.toBaseIO <| ref.ci.runCoreM do
89-
let some parentDeclName := parentDeclName?
90-
| return none
91-
-- Use `local` as it avoids unnecessary blocking, which is especially important when called
92-
-- from the snapshot reporter. Specifically, if `ref` is from a tactic of an async theorem,
93-
-- `parentDeclName` will not be available in the current environment and we would block only
94-
-- to return `none` in the end anyway. At the end of elaboration, we rerun this function on
95-
-- the full info tree with the main environment, so the access will succeed immediately.
96-
return declRangeExt.find? (asyncMode := .local) (← getEnv) parentDeclName
97-
-- we only use `CoreM` to get access to a `MonadEnv`, but these are currently all `IO`
98-
| unreachable!
88+
let parentDeclRanges? : Option DeclarationRanges := do
89+
-- Use final command env that has decl ranges for current declaration as well
90+
let cmdEnv ← ref.ci.cmdEnv?
91+
let parentDeclName ← parentDeclName?
92+
-- Use `local` as it avoids unnecessary blocking, which is especially important when called
93+
-- from the snapshot reporter. Specifically, if `ref` is from a tactic of an async theorem,
94+
-- `parentDeclName` will not be available in the current environment and we would block only
95+
-- to return `none` in the end anyway. At the end of elaboration, we rerun this function on
96+
-- the full info tree with the main environment, so the access will succeed immediately.
97+
declRangeExt.find? (asyncMode := .local) cmdEnv parentDeclName
9998
return {
10099
range := ref.range
101100
parentDecl? := do

0 commit comments

Comments
 (0)