Skip to content

Commit 663df8f

Browse files
authored
feat: backward.privateInPublic option (#10807)
This PR introduces the `backward.privateInPublic` option to aid in porting projects to the module system by temporarily allowing access to private declarations from the public scope, even across modules. A warning will be generated by such accesses unless `backward.privateInPublic.warn` is disabled.
1 parent 428355c commit 663df8f

File tree

9 files changed

+114
-52
lines changed

9 files changed

+114
-52
lines changed

src/Lean/AddDecl.lean

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -128,7 +128,7 @@ def addDecl (decl : Declaration) (forceExpose := false) : CoreM Unit := do
128128
| .axiomDecl ax => pure (ax.name, .axiomInfo ax, .axiom)
129129
| _ => return (← doAdd)
130130

131-
if decl.getTopLevelNames.all isPrivateName then
131+
if decl.getTopLevelNames.all isPrivateName && !(← ResolveName.backward.privateInPublic.getM) then
132132
exportedInfo? := none
133133
else
134134
-- preserve original constant kind in extension if different from exported one

src/Lean/Data/Options.lean

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,9 @@ protected def get? [KVMap.Value α] (opts : Options) (opt : Lean.Option α) : Op
121121
protected def get [KVMap.Value α] (opts : Options) (opt : Lean.Option α) : α :=
122122
opts.get opt.name opt.defValue
123123

124+
protected def getM [Monad m] [MonadOptions m] [KVMap.Value α] (opt : Lean.Option α) : m α :=
125+
return opt.get (← getOptions)
126+
124127
protected def set [KVMap.Value α] (opts : Options) (opt : Lean.Option α) (val : α) : Options :=
125128
opts.set opt.name val
126129

src/Lean/Elab/App.lean

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1267,7 +1267,9 @@ private partial def findMethod? (structName fieldName : Name) : MetaM (Option (N
12671267
let find? structName' : MetaM (Option (Name × Name)) := do
12681268
let fullName := privateToUserName structName' ++ fieldName
12691269
-- We do not want to make use of the current namespace for resolution.
1270-
let candidates := ResolveName.resolveGlobalName (← getEnv) Name.anonymous (← getOpenDecls) fullName
1270+
let candidates :=
1271+
(← withTheReader Core.Context ({ · with currNamespace := .anonymous }) do
1272+
resolveGlobalName fullName)
12711273
|>.filter (fun (_, fieldList) => fieldList.isEmpty)
12721274
|>.map Prod.fst
12731275
match candidates with
@@ -1737,7 +1739,7 @@ where
17371739
-- Recall that the namespace for private declarations is non-private.
17381740
let fullName := privateToUserName declName ++ id
17391741
-- Resolve the name without making use of the current namespace, like in `findMethod?`.
1740-
let candidates := ResolveName.resolveGlobalName env Name.anonymous (← getOpenDecls) fullName
1742+
let candidates := ResolveName.resolveGlobalName env (← getOptions) Name.anonymous (← getOpenDecls) fullName
17411743
|>.filter (fun (_, fieldList) => fieldList.isEmpty)
17421744
|>.map Prod.fst
17431745
if !candidates.isEmpty then

src/Lean/Elab/Open.lean

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ instance : MonadResolveName (M (m := m)) where
3333
getCurrNamespace := return (← get).currNamespace
3434
getOpenDecls := return (← get).openDecls
3535

36-
def resolveId [MonadResolveName m] (ns : Name) (idStx : Syntax) : m Name := do
36+
def resolveId [MonadOptions m] [MonadResolveName m] (ns : Name) (idStx : Syntax) : m Name := do
3737
let declName := ns ++ idStx.getId
3838
if (← getEnv).contains declName then
3939
return declName
@@ -48,7 +48,7 @@ Uniquely resolves the identifier `idStx` in the provided namespaces `nss`.
4848
4949
If the identifier does not indicate a name in exactly one of the namespaces, an exception is thrown.
5050
-/
51-
def resolveNameUsingNamespacesCore [MonadResolveName m]
51+
def resolveNameUsingNamespacesCore [MonadOptions m] [MonadResolveName m]
5252
(nss : List Name) (idStx : Syntax) : m Name := do
5353
let mut exs := #[]
5454
let mut result := #[]
@@ -69,7 +69,7 @@ def resolveNameUsingNamespacesCore [MonadResolveName m]
6969
else
7070
withRef idStx do throwError "ambiguous identifier `{idStx.getId}`, possible interpretations: {result.map mkConst}"
7171

72-
def elabOpenDecl [MonadResolveName m] [MonadInfoTree m] (stx : TSyntax ``Parser.Command.openDecl) : m (List OpenDecl) := do
72+
def elabOpenDecl [MonadOptions m] [MonadResolveName m] [MonadInfoTree m] (stx : TSyntax ``Parser.Command.openDecl) : m (List OpenDecl) := do
7373
StateRefT'.run' (s := { openDecls := (← getOpenDecls), currNamespace := (← getCurrNamespace) }) do
7474
match stx with
7575
| `(Parser.Command.openDecl| $nss*) =>
@@ -108,7 +108,7 @@ def elabOpenDecl [MonadResolveName m] [MonadInfoTree m] (stx : TSyntax ``Parser.
108108
| _ => throwUnsupportedSyntax
109109
return (← get).openDecls
110110

111-
def resolveNameUsingNamespaces [MonadResolveName m] (nss : List Name) (idStx : Ident) : m Name := do
111+
def resolveNameUsingNamespaces [MonadOptions m] [MonadResolveName m] (nss : List Name) (idStx : Ident) : m Name := do
112112
StateRefT'.run' (s := { openDecls := (← getOpenDecls), currNamespace := (← getCurrNamespace) }) do
113113
resolveNameUsingNamespacesCore (m := M) nss idStx
114114

src/Lean/Elab/Term/TermElabM.lean

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1971,7 +1971,7 @@ where
19711971
let env ← getEnv
19721972
-- check for scope errors before trying auto implicits
19731973
if env.isExporting then
1974-
if let [(npriv, _)] ← withEnv (env.setExporting false) <| resolveGlobalName n then
1974+
if let [(npriv, _)] ← withEnv (env.setExporting false) <| resolveGlobalName (enableLog := false) n then
19751975
throwUnknownIdentifierAt (declHint := npriv) stx m!"Unknown identifier `{.ofConstName n}`"
19761976
if (← read).autoBoundImplicit &&
19771977
!(← read).autoBoundImplicitForbidden n &&

src/Lean/Elab/Util.lean

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -178,6 +178,7 @@ instance (m n) [MonadLift m n] [MonadQuotation n] [MonadMacroAdapter m] : MonadM
178178

179179
def liftMacroM [Monad m] [MonadMacroAdapter m] [MonadEnv m] [MonadRecDepth m] [MonadError m] [MonadResolveName m] [MonadTrace m] [MonadOptions m] [AddMessageContext m] [MonadLiftT IO m] (x : MacroM α) : m α := do
180180
let env ← getEnv
181+
let opts ← getOptions
181182
let currNamespace ← getCurrNamespace
182183
let openDecls ← getOpenDecls
183184
let methods := Macro.mkMethods {
@@ -189,7 +190,7 @@ def liftMacroM [Monad m] [MonadMacroAdapter m] [MonadEnv m] [MonadRecDepth m] [M
189190
hasDecl := fun declName => return env.contains declName
190191
getCurrNamespace := return currNamespace
191192
resolveNamespace := fun n => return ResolveName.resolveNamespace env currNamespace openDecls n
192-
resolveGlobalName := fun n => return ResolveName.resolveGlobalName env currNamespace openDecls n
193+
resolveGlobalName := fun n => return ResolveName.resolveGlobalName env opts currNamespace openDecls n
193194
}
194195
match x { methods := methods
195196
ref := ← getRef

src/Lean/Parser/Extension.lean

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -663,7 +663,7 @@ inductive ParserResolution where
663663
| alias (p : ParserAliasValue)
664664

665665
/-- Resolve the given parser name and return a list of candidates. -/
666-
def resolveParserNameCore (env : Environment) (currNamespace : Name)
666+
private def resolveParserNameCore (env : Environment) (opts : Options) (currNamespace : Name)
667667
(openDecls : List OpenDecl) (ident : Ident) : List ParserResolution := Id.run do
668668
let ⟨.ident (val := val) (preresolved := pre) ..⟩ := ident | return []
669669

@@ -684,7 +684,7 @@ def resolveParserNameCore (env : Environment) (currNamespace : Name)
684684
if isParserCategory env erased then
685685
return [.category erased]
686686

687-
let resolved ← ResolveName.resolveGlobalName env currNamespace openDecls val |>.filterMap fun
687+
let resolved ← ResolveName.resolveGlobalName env opts currNamespace openDecls val |>.filterMap fun
688688
| (name, []) => (isParser name).map fun isDescr => .parser name isDescr
689689
| _ => none
690690
unless resolved.isEmpty do
@@ -698,11 +698,11 @@ def resolveParserNameCore (env : Environment) (currNamespace : Name)
698698

699699
/-- Resolve the given parser name and return a list of candidates. -/
700700
def ParserContext.resolveParserName (ctx : ParserContext) (id : Ident) : List ParserResolution :=
701-
Parser.resolveParserNameCore ctx.env ctx.currNamespace ctx.openDecls id
701+
Parser.resolveParserNameCore ctx.env ctx.options ctx.currNamespace ctx.openDecls id
702702

703703
/-- Resolve the given parser name and return a list of candidates. -/
704704
def resolveParserName (id : Ident) : CoreM (List ParserResolution) :=
705-
return resolveParserNameCore (← getEnv) (← getCurrNamespace) (← getOpenDecls) id
705+
return resolveParserNameCore (← getEnv) (← getOptions) (← getCurrNamespace) (← getOpenDecls) id
706706

707707
def parserOfStackFn (offset : Nat) : ParserFn := fun ctx s => Id.run do
708708
let stack := s.stxStack

0 commit comments

Comments
 (0)