Skip to content

Commit

Permalink
fix: _root_ prefix in declarations
Browse files Browse the repository at this point in the history
closes #490
  • Loading branch information
leodemoura committed Jun 13, 2022
1 parent 3285869 commit 9ba5831
Show file tree
Hide file tree
Showing 6 changed files with 55 additions and 7 deletions.
16 changes: 13 additions & 3 deletions src/Lean/Elab/DeclModifiers.lean
Original file line number Diff line number Diff line change
Expand Up @@ -160,10 +160,20 @@ def checkIfShadowingStructureField (declName : Name) : m Unit := do
| _ => pure ()

def mkDeclName (currNamespace : Name) (modifiers : Modifiers) (shortName : Name) : m (Name × Name) := do
let name := (extractMacroScopes shortName).name
unless name.isAtomic || isFreshInstanceName name do
let mut shortName := shortName
let mut currNamespace := currNamespace
let view := extractMacroScopes shortName
let name := view.name
let isRootName := (`_root_).isPrefixOf name
if name == `_root_ then
throwError "invalid declaration name `_root_`, `_root_` is a prefix used to refer to the 'root' namespace"
unless name.isAtomic || isFreshInstanceName name || isRootName do
throwError "atomic identifier expected '{shortName}'"
let declName := currNamespace ++ shortName
let declName := if isRootName then { view with name := name.replacePrefix `_root_ Name.anonymous }.review else currNamespace ++ shortName
if isRootName then
let .str p s _ := name | throwError "invalid declaration name '{name}'"
shortName := Name.mkSimple s
currNamespace := p.replacePrefix `_root_ Name.anonymous
checkIfShadowingStructureField declName
let declName ← applyVisibility modifiers.visibility declName
match modifiers.visibility with
Expand Down
10 changes: 8 additions & 2 deletions src/Lean/Elab/Declaration.lean
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,12 @@ private def ensureValidNamespace (name : Name) : MacroM Unit := do
| Name.num _ .. => Macro.throwError s!"invalid namespace '{name}', it must not contain numeric parts"
| Name.anonymous => return ()

/- Auxiliary function for `expandDeclNamespace?` -/
/-- Auxiliary function for `expandDeclNamespace?` -/
private def expandDeclIdNamespace? (declId : Syntax) : MacroM (Option (Name × Syntax)) := do
let (id, _) := expandDeclIdCore declId
if (`_root_).isPrefixOf id then
ensureValidNamespace (id.replacePrefix `_root_ Name.anonymous)
return none
let scpView := extractMacroScopes id
match scpView.name with
| Name.str Name.anonymous _ _ => return none
Expand All @@ -41,7 +44,10 @@ private def expandDeclIdNamespace? (declId : Syntax) : MacroM (Option (Name × S
return some (pre, declId.setArg 0 id)
| _ => return none

/- given declarations such as `@[...] def Foo.Bla.f ...` return `some (Foo.Bla, @[...] def f ...)` -/
/--
Given declarations such as `@[...] def Foo.Bla.f ...` return `some (Foo.Bla, @[...] def f ...)`
Remark: if the id starts with `_root_`, we return `none`.
-/
private def expandDeclNamespace? (stx : Syntax) : MacroM (Option (Name × Syntax)) := do
if !stx.isOfKind `Lean.Parser.Command.declaration then
return none
Expand Down
2 changes: 1 addition & 1 deletion tests/lean/490.lean
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
namespace Foo
def _root_.bar := 1 -- Error
def _root_.bar := 1 -- ok
end Foo
1 change: 0 additions & 1 deletion tests/lean/490.lean.expected.out
Original file line number Diff line number Diff line change
@@ -1 +0,0 @@
490.lean:2:0-2:19: error: invalid namespace '_root_', '_root_' is a reserved namespace
22 changes: 22 additions & 0 deletions tests/lean/root.lean
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
-*- mode: compilation; default-directory: "~/projects/lean4/build/release/" -*-
Compilation started at Mon Jun 13 13:56:14

/home/leodemoura/.elan/bin/lean /home/leodemoura/projects/lean4/build/release/root.lean
Bla.f : Nat → Nat
/home/leodemoura/projects/lean4/build/release/root.lean:21:14: error: protected declarations must be in a namespace
/home/leodemoura/projects/lean4/build/release/root.lean:29:4: error: invalid declaration name `_root_`, `_root_` is a prefix used to refer to the 'root' namespace
/home/leodemoura/projects/lean4/build/release/root.lean:31:0: error: invalid namespace '_root_', '_root_' is a reserved namespace
/home/leodemoura/projects/lean4/build/release/root.lean:33:0: error: invalid namespace 'f._root_', '_root_' is a reserved namespace
/home/leodemoura/projects/lean4/build/release/root.lean:35:14: error: protected declarations must be in a namespace
/home/leodemoura/projects/lean4/build/release/root.lean:41:7: error: unknown identifier 'h'
/home/leodemoura/projects/lean4/build/release/root.lean:43:7: error: unknown identifier 'f'
f : Nat → Nat
_private.root.0.prv : Nat -> Nat
/home/leodemoura/projects/lean4/build/release/root.lean:90:48: error: unsolved goals
x : Nat
⊢ isEven (x + 1 + 1) = isEven x
/home/leodemoura/projects/lean4/build/release/root.lean:95:48: error: unsolved goals
x : Nat
⊢ isEven (x + 1 + 1) = isEven x

Compilation exited abnormally with code 1 at Mon Jun 13 13:56:14
11 changes: 11 additions & 0 deletions tests/lean/root.lean.expected.out
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
root.lean:1:0: error: expected command
root.lean:6:80: error: expected 'abbrev', 'axiom', 'builtin_initialize', 'class', 'constant', 'def', 'example', 'inductive', 'initialize', 'instance', 'structure' or 'theorem'
root.lean:7:0: error: expected identifier
root.lean:7:125: error: expected ':'
root.lean:8:0: error: expected identifier
root.lean:8:90: error: missing end of character literal
root.lean:9:0: error: expected identifier
root.lean:9:90: error: missing end of character literal
root.lean:10:0: error: expected identifier
root.lean:10:80: error: expected 'abbrev', 'axiom', 'builtin_initialize', 'class', 'constant', 'def', 'example', 'inductive', 'initialize', 'instance', 'structure' or 'theorem'
root.lean:11:0: error: expected identifier

0 comments on commit 9ba5831

Please sign in to comment.