Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Restrict visibility of copy and apply #5472

Merged
merged 4 commits into from Nov 21, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
8 changes: 4 additions & 4 deletions compiler/src/dotty/tools/dotc/ast/Desugar.scala
Expand Up @@ -430,6 +430,8 @@ object desugar {
// new C[Ts](paramss)
lazy val creatorExpr = New(classTypeRef, constrVparamss nestedMap refOfDef)

val copiedAccessFlags = if (ctx.scala2Setting) EmptyFlags else AccessFlags

// Methods to add to a case class C[..](p1: T1, ..., pN: Tn)(moreParams)
// def _1: T1 = this.p1
// ...
Expand Down Expand Up @@ -469,7 +471,7 @@ object desugar {
val copyRestParamss = derivedVparamss.tail.nestedMap(vparam =>
cpy.ValDef(vparam)(rhs = EmptyTree))
DefDef(nme.copy, derivedTparams, copyFirstParams :: copyRestParamss, TypeTree(), creatorExpr)
.withMods(synthetic) :: Nil
.withFlags(Synthetic | constr1.mods.flags & copiedAccessFlags) :: Nil
}
}

Expand Down Expand Up @@ -574,7 +576,7 @@ object desugar {
if (mods is Abstract) Nil
else
DefDef(nme.apply, derivedTparams, derivedVparamss, applyResultTpt, widenedCreatorExpr)
.withFlags(Synthetic | (constr1.mods.flags & DefaultParameterized)) :: widenDefs
.withFlags(Synthetic | constr1.mods.flags & (DefaultParameterized | copiedAccessFlags)) :: widenDefs
val unapplyMeth = {
val unapplyParam = makeSyntheticParameter(tpt = classTypeRef)
val unapplyRHS = if (arity == 0) Literal(Constant(true)) else Ident(unapplyParam.name)
Expand Down Expand Up @@ -658,8 +660,6 @@ object desugar {
flatTree(cdef1 :: companions ::: implicitWrappers)
}

val AccessOrSynthetic: FlagSet = AccessFlags | Synthetic

/** Expand
*
* object name extends parents { self => body }
Expand Down
5 changes: 5 additions & 0 deletions compiler/src/dotty/tools/dotc/core/TypeOps.scala
Expand Up @@ -327,6 +327,11 @@ trait TypeOps { this: Context => // TODO: Make standalone object.
}
scala2Mode
}

/** Is option -language:Scala2 set?
* This test is used when we are too early in the pipeline to consider imports.
*/
def scala2Setting = ctx.settings.language.value.contains(nme.Scala2.toString)
}

object TypeOps {
Expand Down
Expand Up @@ -22,7 +22,7 @@ object Interactive {
import ast.tpd._

object Include {
case class Set private (val bits: Int) extends AnyVal {
case class Set private[Include] (val bits: Int) extends AnyVal {
def | (that: Set): Set = Set(bits | that.bits)
def except(that: Set): Set = Set(bits & ~that.bits)

Expand Down
2 changes: 1 addition & 1 deletion compiler/src/dotty/tools/dotc/parsing/Scanners.scala
Expand Up @@ -242,7 +242,7 @@ object Scanners {

// Scala 2 compatibility

val isScala2Mode: Boolean = ctx.settings.language.value.contains(nme.Scala2.toString)
val isScala2Mode: Boolean = ctx.scala2Setting

/** Cannot use ctx.featureEnabled because accessing the context would force too much */
def testScala2Mode(msg: String, pos: Position = Position(offset)): Boolean = {
Expand Down
10 changes: 10 additions & 0 deletions tests/neg/private-case-class-constr.scala
@@ -0,0 +1,10 @@
case class Nat private (value: Int)
object Nat {
def apply(value: Int, disable: Boolean): Option[Nat] =
if (value < 0 || disable) None else Some(new Nat(value))
}
object Test {
val n1o = Nat(2) // error
val n2o = Nat(2, false) // ok
for (n <- n2o) yield n.copy() // error
}
2 changes: 1 addition & 1 deletion tests/pos/i4564.scala
Expand Up @@ -51,7 +51,7 @@ class BaseNCP[T] {
}

object NoClashPoly extends BaseNCP[Boolean]
case class NoClashPoly private(x: Int)
case class NoClashPoly (x: Int)


class BaseCP[T] {
Expand Down