Skip to content

Commit 2a59a24

Browse files
committed
refactor: move registration of namespaces on kernel add into elaborator
1 parent a9fd0d1 commit 2a59a24

File tree

3 files changed

+41
-39
lines changed

3 files changed

+41
-39
lines changed

src/Lean/AddDecl.lean

Lines changed: 35 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -22,26 +22,55 @@ def Kernel.Environment.addDecl (env : Environment) (opts : Options) (decl : Decl
2222
else
2323
addDeclCore env (Core.getMaxHeartbeats opts).toUSize decl cancelTk?
2424

25-
def Environment.addDecl (env : Environment) (opts : Options) (decl : Declaration)
25+
private def Environment.addDeclAux (env : Environment) (opts : Options) (decl : Declaration)
2626
(cancelTk? : Option IO.CancelToken := none) : Except Kernel.Exception Environment :=
2727
if debug.skipKernelTC.get opts then
2828
addDeclWithoutChecking env decl
2929
else
3030
addDeclCore env (Core.getMaxHeartbeats opts).toUSize decl cancelTk?
3131

32+
@[deprecated "use `Lean.addDecl` instead to ensure new namespaces are registered" (since := "2024-12-03")]
33+
def Environment.addDecl (env : Environment) (opts : Options) (decl : Declaration)
34+
(cancelTk? : Option IO.CancelToken := none) : Except Kernel.Exception Environment :=
35+
Environment.addDeclAux env opts decl cancelTk?
36+
37+
@[deprecated "use `Lean.addAndCompile` instead to ensure new namespaces are registered" (since := "2024-12-03")]
3238
def Environment.addAndCompile (env : Environment) (opts : Options) (decl : Declaration)
3339
(cancelTk? : Option IO.CancelToken := none) : Except Kernel.Exception Environment := do
34-
let env ← addDecl env opts decl cancelTk?
40+
let env ← addDeclAux env opts decl cancelTk?
3541
compileDecl env opts decl
3642

43+
private def isNamespaceName : Name → Bool
44+
| .str .anonymous _ => true
45+
| .str p _ => isNamespaceName p
46+
| _ => false
47+
48+
private def registerNamePrefixes (env : Environment) (name : Name) : Environment :=
49+
match name with
50+
| .str _ s =>
51+
if s.get 0 == '_' then
52+
-- Do not register namespaces that only contain internal declarations.
53+
env
54+
else
55+
go env name
56+
| _ => env
57+
where go env
58+
| .str p _ => if isNamespaceName p then go (env.registerNamespace p) p else env
59+
| _ => env
60+
3761
def addDecl (decl : Declaration) : CoreM Unit := do
3862
profileitM Exception "type checking" (← getOptions) do
39-
withTraceNode `Kernel (fun _ => return m!"typechecking declaration") do
63+
let mut env ← withTraceNode `Kernel (fun _ => return m!"typechecking declaration") do
4064
if !(← MonadLog.hasErrors) && decl.hasSorry then
4165
logWarning "declaration uses 'sorry'"
42-
match (← getEnv).addDecl (← getOptions) decl (← read).cancelTk? with
43-
| .ok env => setEnv env
44-
| .error ex => throwKernelException ex
66+
(← getEnv).addDeclAux (← getOptions) decl (← read).cancelTk? |> ofExceptKernelException
67+
68+
-- register namespaces for newly added constants; this used to be done by the kernel itself
69+
-- but that is incompatible with moving it to a separate task
70+
env := decl.getNames.foldl registerNamePrefixes env
71+
if let .inductDecl _ _ types _ := decl then
72+
env := types.foldl (registerNamePrefixes · <| ·.name ++ `rec) env
73+
setEnv env
4574

4675
def addAndCompile (decl : Declaration) : CoreM Unit := do
4776
addDecl decl

src/Lean/Environment.lean

Lines changed: 2 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1077,34 +1077,9 @@ def isNamespace (env : Environment) (n : Name) : Bool :=
10771077
def getNamespaceSet (env : Environment) : NameSSet :=
10781078
namespacesExt.getState env
10791079

1080-
private def isNamespaceName : Name → Bool
1081-
| .str .anonymous _ => true
1082-
| .str p _ => isNamespaceName p
1083-
| _ => false
1084-
1085-
private def registerNamePrefixes (env : Environment) (name : Name) : Environment :=
1086-
match name with
1087-
| .str _ s =>
1088-
if s.get 0 == '_' then
1089-
-- Do not register namespaces that only contain internal declarations.
1090-
env
1091-
else
1092-
go env name
1093-
| _ => env
1094-
where go env
1095-
| .str p _ => if isNamespaceName p then go (registerNamespace env p) p else env
1096-
| _ => env
1097-
10981080
@[export lean_elab_environment_update_base_after_kernel_add]
1099-
private def updateBaseAfterKernelAdd (env : Environment) (added : Declaration) (base : Kernel.Environment) : Environment := Id.run do
1100-
let mut env := { env with base }
1101-
env := added.getNames.foldl registerNamePrefixes env
1102-
if let .inductDecl _ _ types _ := added then
1103-
-- also register inductive type names as namespaces; this used to be done by the kernel itself
1104-
-- when adding e.g. the recursor but now that the environment extension API exists only for
1105-
-- `Lean.Environment`, we have to do it here
1106-
env := types.foldl (registerNamePrefixes · <| ·.name ++ `rec) env
1107-
env
1081+
private def updateBaseAfterKernelAdd (env : Environment) (base : Kernel.Environment) : Environment :=
1082+
{ env with base }
11081083

11091084
@[export lean_display_stats]
11101085
def displayStats (env : Environment) : IO Unit := do

src/library/elab_environment.cpp

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -11,19 +11,17 @@ Authors: Leonardo de Moura, Sebastian Ullrich
1111
#include "library/compiler/ir_interpreter.h"
1212

1313
namespace lean {
14-
/* updateBaseAfterKernelAdd (env : Environment) (added : Declaration) (base : Kernel.Environment) :
15-
Environment
14+
/* updateBaseAfterKernelAdd (env : Environment) (base : Kernel.Environment) : Environment
1615
17-
Updates an elab environment with a given kernel environment after the declaration `d` has been
18-
added to it. `d` is used to adjust further elab env data such as registering new namespaces.
16+
Updates an elab environment with a given kernel environment.
1917
2018
NOTE: Ideally this language switching would not be necessary and we could do all this in Lean
2119
only but the old code generator and `mk_projections` still need a C++ `elab_environment::add`. */
22-
extern "C" obj_res lean_elab_environment_update_base_after_kernel_add(obj_arg env, obj_arg d, obj_arg kenv);
20+
extern "C" obj_res lean_elab_environment_update_base_after_kernel_add(obj_arg env, obj_arg kenv);
2321

2422
elab_environment elab_environment::add(declaration const & d, bool check) const {
2523
environment kenv = to_kernel_env().add(d, check);
26-
return elab_environment(lean_elab_environment_update_base_after_kernel_add(this->to_obj_arg(), d.to_obj_arg(), kenv.to_obj_arg()));
24+
return elab_environment(lean_elab_environment_update_base_after_kernel_add(this->to_obj_arg(), kenv.to_obj_arg()));
2725
}
2826

2927
extern "C" LEAN_EXPORT object * lean_elab_add_decl(object * env, size_t max_heartbeat, object * decl,

0 commit comments

Comments
 (0)