Skip to content

Commit

Permalink
Constructor companion gets privateWithin (#22627)
Browse files Browse the repository at this point in the history
Follow-up to #22560 
Fixes #22626 

When creating a companion for a constructor proxy, the companion is
`protected` if the class is. Now it also receives the `privateWithin`
boundary of the class, for `protected[p]`.
  • Loading branch information
odersky authored Feb 21, 2025
2 parents 595c5d7 + eea481f commit 28fa050
Show file tree
Hide file tree
Showing 9 changed files with 99 additions and 8 deletions.
5 changes: 3 additions & 2 deletions compiler/src/dotty/tools/dotc/core/NamerOps.scala
Original file line number Diff line number Diff line change
Expand Up @@ -183,8 +183,9 @@ object NamerOps:
cls.owner, cls.name.toTermName,
flags, flags,
constructorCompanionCompleter(cls),
coord = cls.coord,
compUnitInfo = cls.compUnitInfo)
cls.privateWithin,
cls.coord,
cls.compUnitInfo)
companion.moduleClass.registerCompanion(cls)
cls.registerCompanion(companion.moduleClass)
companion
Expand Down
22 changes: 16 additions & 6 deletions tests/neg/i18545.check
Original file line number Diff line number Diff line change
@@ -1,16 +1,26 @@
-- [E173] Reference Error: tests/neg/i18545.scala:13:20 ----------------------------------------------------------------
13 | def test: IOLocal.IOLocalImpl[Int] = // error
-- [E173] Reference Error: tests/neg/i18545.scala:16:20 ----------------------------------------------------------------
16 | def test: IOLocal.IOLocalImpl[Int] = // error
| ^^^^^^^^^^^^^^^^^^^
|class IOLocalImpl cannot be accessed as a member of iolib.IOLocal.type from the top-level definitions in package tests.
| private[IOLocal] class IOLocalImpl can only be accessed from object IOLocal in package iolib.
-- [E173] Reference Error: tests/neg/i18545.scala:14:24 ----------------------------------------------------------------
14 | IOLocal.IOLocalImpl.apply(42) // error
-- [E173] Reference Error: tests/neg/i18545.scala:17:24 ----------------------------------------------------------------
17 | IOLocal.IOLocalImpl.apply(42) // error
| ^^^^^^^^^^^^^^^^^^^^^^^^^
|method apply cannot be accessed as a member of iolib.IOLocal.IOLocalImpl.type from the top-level definitions in package tests.
| private[IOLocal] method apply can only be accessed from object IOLocal in package iolib.
-- [E050] Type Error: tests/neg/i18545.scala:15:22 ---------------------------------------------------------------------
15 | def test2 = IOLocal.IOLocalImpl(42) // error
-- [E050] Type Error: tests/neg/i18545.scala:18:22 ---------------------------------------------------------------------
18 | def test2 = IOLocal.IOLocalImpl(42) // error
| ^^^^^^^^^^^^^^^^^^^
| object IOLocalImpl in object IOLocal does not take parameters
|
| longer explanation available when compiling with `-explain`
-- [E173] Reference Error: tests/neg/i18545.scala:19:22 ----------------------------------------------------------------
19 | def test3 = IOLocal.AltIOLocalImpl.apply(42) // error
| ^^^^^^^^^^^^^^^^^^^^^^
|object AltIOLocalImpl cannot be accessed as a member of iolib.IOLocal.type from the top-level definitions in package tests.
| private[IOLocal] object AltIOLocalImpl can only be accessed from object IOLocal in package iolib.
-- [E173] Reference Error: tests/neg/i18545.scala:20:22 ----------------------------------------------------------------
20 | def test4 = IOLocal.AltIOLocalImpl(42) // error
| ^^^^^^^^^^^^^^^^^^^^^^
|object AltIOLocalImpl cannot be accessed as a member of iolib.IOLocal.type from the top-level definitions in package tests.
| private[IOLocal] object AltIOLocalImpl can only be accessed from object IOLocal in package iolib.
5 changes: 5 additions & 0 deletions tests/neg/i18545.scala
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,14 @@ package iolib:
def apply[A](default: A): IO[IOLocal[A]] = IO(new IOLocalImpl(default))

private[IOLocal] final class IOLocalImpl[A](default: A) extends IOLocal[A]
object IOLocalImpl

private[IOLocal] final class AltIOLocalImpl[A](default: A) extends IOLocal[A]

package tests:
import iolib.IOLocal
def test: IOLocal.IOLocalImpl[Int] = // error
IOLocal.IOLocalImpl.apply(42) // error
def test2 = IOLocal.IOLocalImpl(42) // error
def test3 = IOLocal.AltIOLocalImpl.apply(42) // error
def test4 = IOLocal.AltIOLocalImpl(42) // error
2 changes: 2 additions & 0 deletions tests/neg/i22560b.scala
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,9 @@ package p:
private[p] class C(i: Int) // ctor proxy gets privateWithin of class
private[p] class D(i: Int)
object D
private class E(i: Int)

package q:
def f() = p.C(42) // error
def g() = p.D(42) // error
def h() = p.E(42) // error
11 changes: 11 additions & 0 deletions tests/neg/i22560c/client_2.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@

package i22560:
val alpha = C.D() // error

class Test extends Enumeration:
val Hearts = Val(27) // error
val Diamonds = Val() // error

package q:
def f() = p.C(42) // error
def g() = p.D(42) // error
16 changes: 16 additions & 0 deletions tests/neg/i22560c/lib_1.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@

package i22560:

object C:
protected class D

class Enumeration:
protected class Val(i: Int):
def this() = this(42)
object Val

package p:
private[p] class C(i: Int) // companion gets privateWithin of class
private[p] class D(i: Int) // ctor proxy gets privateWithin of class
object D

10 changes: 10 additions & 0 deletions tests/pos/i22560.scala
Original file line number Diff line number Diff line change
Expand Up @@ -20,3 +20,13 @@ package companioned:
class Test extends Enumeration:
val Hearts = Val(27)
val Diamonds = Val()

package p:

package internal:

protected[p] class P(i : Int)
private[p] class Q(i : Int)

def f = internal.P(42)
def g = internal.Q(42)
17 changes: 17 additions & 0 deletions tests/pos/i22560b/client_2.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@

package companionless:

class Test extends Enumeration:
val Hearts = Val(27)
val Diamonds = Val()


package companioned:

class Test extends Enumeration:
val Hearts = Val(27)
val Diamonds = Val()

package p:

def f = internal.P(42)
19 changes: 19 additions & 0 deletions tests/pos/i22560b/lib_1.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@

package companionless:

class Enumeration:
protected class Val(i: Int):
def this() = this(42)

package companioned:

class Enumeration:
protected class Val(i: Int):
def this() = this(42)
protected object Val

package p:

package internal:

protected[p] class P(i : Int)

0 comments on commit 28fa050

Please sign in to comment.