Skip to content

Commit 8278568

Browse files
committed
Make toplevel privates package private
This is the only way that avoids tricky special cases. Also: Fix desugaring of toplevel definitions so that imports are visible in wrapper objects.
1 parent 44877bd commit 8278568

File tree

6 files changed

+46
-25
lines changed

6 files changed

+46
-25
lines changed

compiler/src/dotty/tools/dotc/ast/Desugar.scala

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1047,8 +1047,14 @@ object desugar {
10471047
else {
10481048
val sourceName = ctx.source.file.name.takeWhile(_ != '.')
10491049
val groupName = (sourceName ++ str.TOPLEVEL_SUFFIX).toTermName
1050-
val grouped = ModuleDef(groupName, Template(emptyConstructor, Nil, Nil, EmptyValDef, nestedStats))
1051-
cpy.PackageDef(pdef)(pdef.pid, grouped :: topStats)
1050+
val widenedStats = nestedStats.map {
1051+
case stat: MemberDef if stat.mods.is(Private) =>
1052+
stat.withMods((stat.mods &~ Private).withPrivateWithin(pdef.pid.name.toTypeName))
1053+
case stat =>
1054+
stat
1055+
}
1056+
val grouped = ModuleDef(groupName, Template(emptyConstructor, Nil, Nil, EmptyValDef, widenedStats))
1057+
cpy.PackageDef(pdef)(pdef.pid, topStats :+ grouped)
10521058
}
10531059
}
10541060

docs/docs/reference/dropped-features/package-objects.md

Lines changed: 1 addition & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -41,19 +41,4 @@ If a source file `src.scala` contains such toplevel definitions, they will be pu
4141
in a source file `src.scala`, it could be invoked from the command line using a command like `scala src$package`. Since the
4242
"program name" is mangled it is recommended to always put `main` methods in explicitly named objects.
4343

44-
### Private toplevel definitions
45-
46-
If a private toplevel definition is wrapped in a synthetic object, it is visible only
47-
in definitions in the same source file. By contrast, a package-private definition is visible in the whole containing package. Example:
48-
49-
```scala
50-
// file 1:
51-
package p
52-
private val x = 1
53-
private[p] val y = 2
54-
55-
// file 2:
56-
package p
57-
val xx = x // error: not found: x
58-
val yy = y // ok
59-
```
44+
**Note 3:** The notion of `private` is independent of whether a definition is wrapped or not. A `private` toplevel definition is always visible from everywhere in the enclosing package.

tests/neg/toplevel-privates/A.scala

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,14 @@
1-
package p
1+
package p22
22

33
private val x = 10
44

55
val y = x
66

7-
private[p] val xx = 10
7+
private[p22] val xx = 10
88

99
val yy = xx
1010

11-
private class C
11+
private class C {
12+
val z = x
13+
}
14+
Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,13 @@
1-
package p
1+
package q
22

3-
val x1 = x // error
3+
import p._
4+
5+
val x1 = x // error: not found
46

57
val y1 = y // ok
68

7-
val xx1 = xx // ok
9+
val xx1 = xx // error: not found
810

911
val yy1 = yy // ok
1012

11-
val c = new C // ok
13+
val c = new C // error: not found

tests/pos/toplevel-privates/A.scala

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
package p
2+
3+
private val x = 10
4+
5+
val y = x
6+
7+
private[p] val xx = 10
8+
9+
val yy = xx
10+
11+
private class C {
12+
val z = x
13+
}
14+
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
package p
2+
3+
val x1 = x
4+
5+
val y1 = y
6+
7+
val xx1 = xx
8+
9+
val yy1 = yy
10+
11+
val c = new C

0 commit comments

Comments
 (0)