fix: protected

- `protected` outside of a namespace is an error.
- Fix `protected` in recursive definitions.

cc @Kha
This commit is contained in:
Leonardo de Moura 2020-09-14 13:09:04 -07:00
parent 7c0216595e
commit 163b0a7a3f
3 changed files with 81 additions and 6 deletions

View file

@ -123,12 +123,18 @@ match visibility with
checkNotAlreadyDeclared declName;
pure declName
def mkDeclName (currNamespace : Name) (modifiers : Modifiers) (atomicName : Name) : m Name := do
let name := (extractMacroScopes atomicName).name;
def mkDeclName (currNamespace : Name) (modifiers : Modifiers) (shortName : Name) : m (Name × Name) := do
let name := (extractMacroScopes shortName).name;
unless (name.isAtomic || isFreshInstanceName name) $
throwError ("atomic identifier expected '" ++ atomicName ++ "'");
let declName := currNamespace ++ atomicName;
applyVisibility modifiers.visibility declName
throwError ("atomic identifier expected '" ++ shortName ++ "'");
let declName := currNamespace ++ shortName;
declName ← applyVisibility modifiers.visibility declName;
match modifiers.visibility with
| Visibility.protected =>
match currNamespace with
| Name.str _ s _ => pure (declName, mkNameSimple s ++ shortName)
| _ => throwError ("protected declarations must be in a namespace")
| _ => pure (declName, shortName)
/-
`declId` is of the form
@ -167,7 +173,7 @@ levelNames ←
pure (id :: levelNames))
currLevelNames
};
declName ← withRef declId $ mkDeclName currNamespace modifiers shortName;
(declName, shortName) ← withRef declId $ mkDeclName currNamespace modifiers shortName;
pure { shortName := shortName, declName := declName, levelNames := levelNames }
end Methods

View file

@ -21,3 +21,43 @@ open Bla
open Bla.Foo
#check y -- error unknown identifier `y`
#check z
protected def x := 0 -- Error
protected partial def Foo.f (x : Nat) :=
if x > 0 then f (x-1) * 2 else 1 -- Error
protected partial def Bla.f (x : Nat) :=
if x > 0 then Bla.f (x-1) * 2 else 1
#eval Bla.f 3
namespace Foo
protected partial def g (x : Nat) :=
if x > 0 then g (x-1) * 2 else 1 -- error
end Foo
namespace Bla
protected partial def g (x : Nat) :=
if x > 0 then Bla.g (x-1) * 2 else 1
#eval g 3 -- error
#eval Bla.g 3
end Bla
def S (σ : Type) (m : Type → Type) (α : Type) :=
σ → m (α × σ)
namespace S
variables {σ : Type} {m : Type → Type} [Monad m] {α : Type}
protected def pure (a : α) : S σ m α :=
fun s => pure (a, s) -- This `pure` is the top-level one. The `pure` being defined here is called `S.pure`.
end S

View file

@ -5,3 +5,32 @@ Bla.Foo.y : Nat
protected.lean:22:7: error: unknown identifier 'y'
(sorryAx ?m.67) : ?m.67
Bla.Foo.z : Nat
protected.lean:25:14: error: protected declarations must be in a namespace
protected.lean:28:14: error: unknown identifier 'f'
with resulting expansion
HasMul.mul._@._internal._hyg.0 f (x-1) 2
while expanding
f (x-1) * 2
while expanding
if x > 0 then f (x-1) * 2 else 1
while expanding
protected partial def Foo.f (x : Nat) :=
if x > 0 then f (x-1) * 2 else 1
8
protected.lean:38:14: error: unknown identifier 'g'
with resulting expansion
HasMul.mul._@._internal._hyg.0 g (x-1) 2
while expanding
g (x-1) * 2
while expanding
if x > 0 then g (x-1) * 2 else 1
protected.lean:47:6: error: unknown identifier 'g'
protected.lean:47:0: error: application type mismatch
Lean.runEval (sorryAx ?m.781)
argument
(sorryAx ?m.781)
has type
?m.781
but is expected to have type
?m.783
8