Skip to content

Commit a13d02d

Browse files
committed
Fix #5857: handle qualified private/protected case class constructor
- apply inherits qualified private access modifiers - copy inherits qualified private/protected access modifiers
1 parent 4141bd2 commit a13d02d

File tree

4 files changed

+31
-5
lines changed

4 files changed

+31
-5
lines changed

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

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -499,7 +499,7 @@ object desugar {
499499
val copyRestParamss = derivedVparamss.tail.nestedMap(vparam =>
500500
cpy.ValDef(vparam)(rhs = EmptyTree))
501501
DefDef(nme.copy, derivedTparams, copyFirstParams :: copyRestParamss, TypeTree(), creatorExpr)
502-
.withFlags(Synthetic | constr1.mods.flags & copiedAccessFlags) :: Nil
502+
.withMods(Modifiers(Synthetic | constr1.mods.flags & copiedAccessFlags, constr1.mods.privateWithin)) :: Nil
503503
}
504504
}
505505

@@ -577,11 +577,16 @@ object desugar {
577577
else
578578
enumApplyResult(cdef, parents, derivedEnumParams, appliedRef(enumClassRef, derivedEnumParams))
579579

580+
def applyShouldInheritAccess = {
581+
val mods = constr1.mods
582+
mods.is(Private) || (!mods.is(Protected) && mods.hasPrivateWithin)
583+
}
584+
580585
val companionParent =
581586
if (constrTparams.nonEmpty ||
582587
constrVparamss.length > 1 ||
583588
mods.is(Abstract) ||
584-
constr.mods.is(Private)) anyRef
589+
applyShouldInheritAccess) anyRef
585590
else
586591
// todo: also use anyRef if constructor has a dependent method type (or rule that out)!
587592
(constrVparamss :\ (if (isEnumCase) applyResultTpt else classTypeRef)) (
@@ -592,8 +597,13 @@ object desugar {
592597
if (mods is Abstract) Nil
593598
else {
594599
val copiedFlagsMask = DefaultParameterized | (copiedAccessFlags & Private)
600+
val appMods = {
601+
val mods = Modifiers(Synthetic | constr1.mods.flags & copiedFlagsMask)
602+
if (applyShouldInheritAccess) mods.withPrivateWithin(constr1.mods.privateWithin)
603+
else mods
604+
}
595605
val app = DefDef(nme.apply, derivedTparams, derivedVparamss, applyResultTpt, widenedCreatorExpr)
596-
.withFlags(Synthetic | constr1.mods.flags & copiedFlagsMask)
606+
.withMods(appMods)
597607
app :: widenDefs
598608
}
599609
val unapplyMeth = {

compiler/src/dotty/tools/dotc/core/Comments.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -123,7 +123,7 @@ object Comments {
123123
tree match {
124124
case tree: untpd.DefDef =>
125125
val newName = ctx.freshNames.newName(tree.name, NameKinds.DocArtifactName)
126-
tree.copy(name = newName)
126+
untpd.cpy.DefDef(tree)(name = newName)
127127
case _ =>
128128
ctx.error(ProperDefinitionNotFound(), ctx.source.atSpan(codePos))
129129
tree

compiler/src/dotty/tools/dotc/printing/DecompilerPrinter.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ class DecompilerPrinter(_ctx: Context) extends RefinedPrinter(_ctx) {
7070
val bodyText = " {" ~~ toTextGlobal(impl.body, "\n") ~ "}"
7171
parentsText.provided(parents.nonEmpty) ~ bodyText
7272
}
73-
else super.toTextTemplate(impl.copy(parentsOrDerived = parents, preBody = body), ofNew)
73+
else super.toTextTemplate(untpd.cpy.Template(impl)(parents = parents, body = body), ofNew)
7474
}
7575

7676
override protected def typeApplyText[T >: Untyped](tree: TypeApply[T]): Text = {

tests/neg/i5857.scala

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
object qux {
2+
case class Foo private[qux] (a: Int)
3+
val foo0 = Foo(0) // ok
4+
val foo1 = foo0.copy(1) // ok
5+
6+
case class Bar protected[qux] (a: Int)
7+
val bar0 = Bar(0) // ok
8+
val bar1 = bar0.copy(1) // ok
9+
}
10+
11+
object Test {
12+
val foo2 = qux.Foo(2) // error
13+
val foo3 = qux.foo0.copy(3) // error
14+
val bar2 = qux.Bar(2) // ok
15+
val bar3 = qux.bar0.copy(3) // error
16+
}

0 commit comments

Comments
 (0)