Skip to content

Commit ac6ae51

Browse files
authored
chore: minor module system fixes from batteries port (#10496)
1 parent fd4a8c5 commit ac6ae51

File tree

9 files changed

+34
-23
lines changed

9 files changed

+34
-23
lines changed

src/Lean/Compiler/LCNF/Visibility.lean

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -60,12 +60,14 @@ partial def markDeclPublicRec (phase : Phase) (decl : Decl) : CompilerM Unit :=
6060
partial def checkMeta (origDecl : Decl) : CompilerM Unit := do
6161
if !(← getEnv).header.isModule then
6262
return
63-
let isMeta := isMeta (← getEnv) origDecl.name
63+
let irPhases := getIRPhases (← getEnv) origDecl.name
64+
if irPhases == .all then
65+
return
6466
-- If the meta decl is public, we want to ensure it can only refer to public meta imports so that
6567
-- references to private imports cannot escape the current module. In particular, we check that
6668
-- decls with relevant global attrs are public (`Lean.ensureAttrDeclIsMeta`).
6769
let isPublic := !isPrivateName origDecl.name
68-
go isMeta isPublic origDecl |>.run' {}
70+
go (irPhases == .comptime) isPublic origDecl |>.run' {}
6971
where go (isMeta isPublic : Bool) (decl : Decl) : StateT NameSet CompilerM Unit := do
7072
decl.value.forCodeM fun code =>
7173
for ref in collectUsedDecls code do
@@ -129,9 +131,9 @@ partial def checkTemplateVisibility : Pass where
129131
-- indirectly via a public template-like, we do a recursive check when checking the latter.
130132
if !isPrivateName decl.name && (← decl.isTemplateLike) then
131133
let isMeta := isMeta (← getEnv) decl.name
132-
go isMeta decl decl |>.run' {}
134+
go decl decl |>.run' {}
133135
return decls
134-
where go (isMeta : Bool) (origDecl decl : Decl) : StateT NameSet CompilerM Unit := do
136+
where go (origDecl decl : Decl) : StateT NameSet CompilerM Unit := do
135137
decl.value.forCodeM fun code =>
136138
for ref in collectUsedDecls code do
137139
if (← get).contains ref then
@@ -140,7 +142,7 @@ where go (isMeta : Bool) (origDecl decl : Decl) : StateT NameSet CompilerM Unit
140142
if let some localDecl := baseExt.getState (← getEnv) |>.find? ref then
141143
-- check transitively through local decls
142144
if isPrivateName localDecl.name && (← localDecl.isTemplateLike) then
143-
go isMeta origDecl localDecl
145+
go origDecl localDecl
144146
else if let some modIdx := (← getEnv).getModuleIdxFor? ref then
145147
if (← getEnv).header.modules[modIdx]?.any (!·.isExported) then
146148
throwError "Cannot compile inline/specializing declaration `{.ofConstName origDecl.name}` as \

src/Lean/DocString/Formatter.lean

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ Authors: David Thrane Christiansen
77
module
88
prelude
99
public import Lean.PrettyPrinter.Formatter
10-
import Lean.DocString.Syntax
10+
import Lean.DocString.Parser
1111

1212

1313
namespace Lean.Doc.Parser
@@ -204,7 +204,7 @@ def formatMetadata : Formatter := do
204204
pushLine
205205
visitAtom .anonymous
206206
pushLine
207-
metadataContents.formatter
207+
Parser.metadataContents.formatter
208208
pushLine
209209
visitAtom .anonymous
210210

src/Lean/DocString/Parser.lean

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -804,7 +804,9 @@ Parses a line of text (that is, one or more inline elements).
804804
def textLine (allowNewlines := true) : ParserFn := many1Fn (inline { allowNewlines })
805805

806806
open Lean.Parser.Term in
807-
def metadataContents : Parser :=
807+
/-- A non-`meta` copy of `Lean.Doc.Syntax.metadataContents`. -/
808+
@[run_builtin_parser_attribute_hooks]
809+
public def metadataContents : Parser :=
808810
structInstFields (sepByIndent structInstField ", " (allowTrailingSep := true))
809811

810812
def withPercents : ParserFn → ParserFn := fun p =>

src/Lean/Elab/BuiltinCommand.lean

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -39,30 +39,31 @@ namespace Lean.Elab.Command
3939
| _ => throwErrorAt stx "unexpected module doc string{indentD <| stx}"
4040

4141
private def addScope (isNewNamespace : Bool) (header : String) (newNamespace : Name)
42-
(isNoncomputable isPublic : Bool := false) (attrs : List (TSyntax ``Parser.Term.attrInstance) := []) :
42+
(isNoncomputable isPublic isMeta : Bool := false) (attrs : List (TSyntax ``Parser.Term.attrInstance) := []) :
4343
CommandElabM Unit := do
4444
modify fun s => { s with
4545
env := s.env.registerNamespace newNamespace,
4646
scopes := { s.scopes.head! with
4747
header := header, currNamespace := newNamespace
4848
isNoncomputable := s.scopes.head!.isNoncomputable || isNoncomputable
4949
isPublic := s.scopes.head!.isPublic || isPublic
50+
isMeta := s.scopes.head!.isMeta || isMeta
5051
attrs := s.scopes.head!.attrs ++ attrs
5152
} :: s.scopes
5253
}
5354
pushScope
5455
if isNewNamespace then
5556
activateScoped newNamespace
5657

57-
private def addScopes (header : Name) (isNewNamespace : Bool) (isNoncomputable isPublic : Bool := false)
58+
private def addScopes (header : Name) (isNewNamespace : Bool) (isNoncomputable isPublic isMeta : Bool := false)
5859
(attrs : List (TSyntax ``Parser.Term.attrInstance) := []) : CommandElabM Unit :=
5960
go header
6061
where go
6162
| .anonymous => pure ()
6263
| .str p header => do
6364
go p
6465
let currNamespace ← getCurrNamespace
65-
addScope isNewNamespace header (if isNewNamespace then Name.mkStr currNamespace header else currNamespace) isNoncomputable isPublic attrs
66+
addScope isNewNamespace header (if isNewNamespace then Name.mkStr currNamespace header else currNamespace) isNoncomputable isPublic isMeta attrs
6667
| _ => throwError "invalid scope"
6768

6869
private def addNamespace (header : Name) : CommandElabM Unit :=
@@ -99,16 +100,16 @@ private def checkEndHeader : Name → List Scope → Option Name
99100

100101
@[builtin_command_elab «section»] def elabSection : CommandElab := fun stx => do
101102
match stx with
102-
| `(Parser.Command.section| $[@[expose%$expTk]]? $[public%$publicTk]? $[noncomputable%$ncTk]? section $(header?)?) =>
103+
| `(Parser.Command.section| $[@[expose%$expTk]]? $[public%$publicTk]? $[noncomputable%$ncTk]? $[meta%$metaTk]? section $(header?)?) =>
103104
-- TODO: allow more attributes?
104105
let attrs ← if expTk.isSome then
105106
pure [← `(Parser.Term.attrInstance| expose)]
106107
else
107108
pure []
108109
if let some header := header? then
109-
addScopes (isNewNamespace := false) (isNoncomputable := ncTk.isSome) (isPublic := publicTk.isSome) (attrs := attrs) header.getId
110+
addScopes (isNewNamespace := false) (isNoncomputable := ncTk.isSome) (isPublic := publicTk.isSome) (isMeta := metaTk.isSome) (attrs := attrs) header.getId
110111
else
111-
addScope (isNewNamespace := false) (isNoncomputable := ncTk.isSome) (isPublic := publicTk.isSome) (attrs := attrs) "" (← getCurrNamespace)
112+
addScope (isNewNamespace := false) (isNoncomputable := ncTk.isSome) (isPublic := publicTk.isSome) (isMeta := metaTk.isSome) (attrs := attrs) "" (← getCurrNamespace)
112113
| _ => throwUnsupportedSyntax
113114

114115
@[builtin_command_elab InternalSyntax.end_local_scope] def elabEndLocalScope : CommandElab := fun _ => do

src/Lean/Elab/Deriving/Basic.lean

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -164,9 +164,10 @@ def processDefDeriving (view : DerivingClassView) (decl : Expr) : TermElabM Unit
164164
let decl ← whnfCore decl
165165
let .const declName _ := decl.getAppFn
166166
| throwError "Failed to delta derive instance, expecting a term of the form `C ...` where `C` is a constant, given{indentExpr decl}"
167-
-- When the definition is private, the deriving handler will need access to the private scope,
168-
-- and we make sure to put the instance in the private scope.
169-
withoutExporting (when := isPrivateName declName) do
167+
let unexposed := (← getEnv).setExporting true |>.find? declName |>.all (!·.hasValue)
168+
-- When the definition body is private, the deriving handler will need access to the private scope,
169+
-- and the instance body will automatically be private as well.
170+
withoutExporting (when := unexposed) do
170171
let ConstantInfo.defnInfo info ← getConstInfo declName
171172
| throwError "Failed to delta derive instance, `{.ofConstName declName}` is not a definition."
172173
let value := info.value.beta decl.getAppArgs
@@ -264,7 +265,7 @@ def getOptDerivingClasses (optDeriving : Syntax) : CoreM (Array DerivingClassVie
264265

265266
def DerivingClassView.applyHandlers (view : DerivingClassView) (declNames : Array Name) : CommandElabM Unit := do
266267
let env ← getEnv
267-
withScope (fun sc => { sc with isMeta := declNames.all (isMeta env) }) do
268+
withScope (fun sc => { sc with isMeta := sc.isMeta || declNames.all (isMeta env) }) do
268269
withRef view.ref do
269270
applyDerivingHandlers (setExpose := view.hasExpose) (← liftCoreM <| view.getClassName) declNames
270271

src/Lean/Elab/MutualDef.lean

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1293,7 +1293,7 @@ where
12931293

12941294
withoutExporting (when :=
12951295
headers.all (fun header =>
1296-
header.modifiers.isMeta ||
1296+
header.modifiers.isMeta && !header.modifiers.attrs.any (·.name == `expose) ||
12971297
header.modifiers.attrs.any (·.name == `no_expose) ||
12981298
(!(header.kind == .def && sc.attrs.any (· matches `(attrInstance| expose))) &&
12991299
!header.modifiers.attrs.any (·.name == `expose) &&
@@ -1368,7 +1368,7 @@ where
13681368
and the parameters in the declaration, so for now we do not allow `classStx`
13691369
to refer to section variables that were not included.
13701370
-/
1371-
let info ← getConstInfo header.declName
1371+
let info ← withoutExporting <| getConstInfo header.declName
13721372
lambdaTelescope info.value! fun xs _ => do
13731373
let decl := mkAppN (.const header.declName (info.levelParams.map mkLevelParam)) xs
13741374
processDefDeriving view decl

src/Lean/Parser/Command.lean

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -264,7 +264,8 @@ def «structure» := leading_parser
264264
def sectionHeader := leading_parser
265265
optional ("@[" >> nonReservedSymbol "expose" >> "] ") >>
266266
optional ("public ") >>
267-
optional ("noncomputable ")
267+
optional ("noncomputable ") >>
268+
optional ("meta ")
268269
/--
269270
A `section`/`end` pair delimits the scope of `variable`, `include`, `open`, `set_option`, and `local`
270271
commands. Sections can be nested. `section <id>` provides a label to the section that has to appear

src/Lean/ParserCompiler.lean

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,10 @@ partial def compileParserExpr (e : Expr) : MetaM Expr := do
107107
name := c', levelParams := []
108108
type := ty, value := value, hints := ReducibilityHints.opaque, safety := DefinitionSafety.safe
109109
}
110+
-- usually `meta` is infered during compilation for auxiliary definitions, but as
111+
-- `ctx.combinatorAttr` may enforce correct use of the modifier, infer now.
112+
if isMeta (← getEnv) c then
113+
modifyEnv (addMeta · c')
110114
addAndCompile decl
111115
modifyEnv (ctx.combinatorAttr.setDeclFor · c c')
112116
if cinfo.type.isConst then

tests/lean/StxQuot.lean.expected.out

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,8 +34,8 @@ StxQuot.lean:19:15-19:16: error: unexpected token ']'; expected term
3434
"#[(Term.matchAlt \"|\" [[`[email protected]._hyg.1]] \"=>\" (num \"1\")), (Term.matchAlt \"|\" [[(Term.hole \"_\")]] \"=>\" (num \"2\"))]"
3535
"(Term.structInst\n \"{\"\n []\n (Term.structInstFields\n [(Term.structInstField\n (Term.structInstLVal `[email protected]._hyg.1 [])\n [[] [] (Term.structInstFieldDef \":=\" [] `[email protected]._hyg.1)])])\n (Term.optEllipsis [])\n [\":\" `[email protected]._hyg.1]\n \"}\")"
3636
"(Term.structInst\n \"{\"\n []\n (Term.structInstFields\n [(Term.structInstField\n (Term.structInstLVal `[email protected]._hyg.1 [])\n [[] [] (Term.structInstFieldDef \":=\" [] `[email protected]._hyg.1)])])\n (Term.optEllipsis [])\n []\n \"}\")"
37-
"(Command.section (Command.sectionHeader [] [] []) \"section\" [])"
38-
"(Command.section (Command.sectionHeader [] [] []) \"section\" [`[email protected]._hyg.1])"
37+
"(Command.section (Command.sectionHeader [] [] [] []) \"section\" [])"
38+
"(Command.section (Command.sectionHeader [] [] [] []) \"section\" [`[email protected]._hyg.1])"
3939
"(Term.match\n \"match\"\n []\n []\n [(Term.matchDiscr [] `[email protected]._hyg.1)]\n \"with\"\n (Term.matchAlts\n [(Term.matchAlt \"|\" [[`[email protected]._hyg.1]] \"=>\" `[email protected]._hyg.1)\n (Term.matchAlt\n \"|\"\n [[(«term_+_» `[email protected]._hyg.1 \"+\" (num \"1\"))]]\n \"=>\"\n («term_+_» `[email protected]._hyg.1 \"+\" (num \"1\")))]))"
4040
"(Term.match\n \"match\"\n []\n []\n [(Term.matchDiscr [] `[email protected]._hyg.1)]\n \"with\"\n (Term.matchAlts\n [(Term.matchAlt \"|\" [[`[email protected]._hyg.1]] \"=>\" `[email protected]._hyg.1)\n (Term.matchAlt\n \"|\"\n [[(«term_+_» `[email protected]._hyg.1 \"+\" (num \"1\"))]]\n \"=>\"\n («term_+_» `[email protected]._hyg.1 \"+\" (num \"1\")))]))"
4141

0 commit comments

Comments
 (0)