Skip to content

Value classes: add support for private[this] parameter #1112

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

Merged
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.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions src/dotty/tools/dotc/transform/Getters.scala
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import Constants._
import TreeTransforms._
import Flags._
import Decorators._
import ValueClasses._

/** Performs the following rewritings for fields of a class:
*
Expand All @@ -34,7 +35,7 @@ import Decorators._
*
* Omitted from the rewritings are
*
* - private[this] fields in non-trait classes
* - private[this] fields in classes (excluding traits, value classes)
* - fields generated for static modules (TODO: needed?)
* - parameters, static fields, and fields coming from Java
*
Expand All @@ -53,7 +54,7 @@ class Getters extends MiniPhaseTransform with SymTransformer { thisTransform =>
override def transformSym(d: SymDenotation)(implicit ctx: Context): SymDenotation = {
def noGetterNeeded =
d.is(NoGetterNeeded) ||
d.initial.asInstanceOf[SymDenotation].is(PrivateLocal) && !d.owner.is(Trait) && !d.is(Flags.Lazy) ||
d.initial.asInstanceOf[SymDenotation].is(PrivateLocal) && !d.owner.is(Trait) && !isDerivedValueClass(d.owner) && !d.is(Flags.Lazy) ||
d.is(Module) && d.isStatic ||
d.isSelfSym
if (d.isTerm && (d.is(Lazy) || d.owner.isClass) && d.info.isValueType && !noGetterNeeded) {
Expand Down
2 changes: 0 additions & 2 deletions src/dotty/tools/dotc/typer/RefChecks.scala
Original file line number Diff line number Diff line change
Expand Up @@ -715,8 +715,6 @@ object RefChecks {
case List(param) =>
if (param.is(Mutable))
ctx.error("value class parameter must not be a var", param.pos)
if (param.is(PrivateLocal))
ctx.error("value class parameter must not be private[this]", param.pos)
case _ =>
ctx.error("value class needs to have exactly one val parameter", clazz.pos)
}
Expand Down
2 changes: 1 addition & 1 deletion test/dotc/tests.scala
Original file line number Diff line number Diff line change
Expand Up @@ -186,7 +186,7 @@ class tests extends CompilerTest {
@Test def neg_validateRefchecks = compileFile(negDir, "validate-refchecks", xerrors = 2)
@Test def neg_skolemize = compileFile(negDir, "skolemize", xerrors = 2)
@Test def neg_nested_bounds = compileFile(negDir, "nested_bounds", xerrors = 1)
@Test def neg_valueClasses = compileFile(negDir, "valueClasses", xerrors = 4)
@Test def neg_valueClasses = compileFile(negDir, "valueClasses", xerrors = 2)

@Test def run_all = runFiles(runDir)

Expand Down
2 changes: 0 additions & 2 deletions tests/neg/valueClasses.scala
Original file line number Diff line number Diff line change
Expand Up @@ -6,5 +6,3 @@ class B1 {
class B2(x: Int) extends AnyVal // error: value class may not be a local class
}
}
class C(private[this] val u: Int) extends AnyVal // error: value class parameter must not be private[this]
class D(u: Int) extends AnyVal // error: value class parameter must not be private[this]
18 changes: 18 additions & 0 deletions tests/pos/valueclasses/privatethisparam.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package privatethisparam

class Meter[T](x: T) extends AnyVal {
def zero: T = x
}

class Meter2(private[this] val x: Int) extends AnyVal {
def foo = x
}

object Test {
def bar = new Meter2(42)
def useZero = new Meter(5).zero
def test: Unit = {
val m1 = new Meter(1)
m1.zero
}
}