diff options
author | Martin Odersky <odersky@gmail.com> | 2016-10-14 09:12:58 +0200 |
---|---|---|
committer | Martin Odersky <odersky@gmail.com> | 2016-10-14 09:16:37 +0200 |
commit | e82cb7cdb93306b5fccf6aeef0e087999f46a016 (patch) | |
tree | ea06fc1746220b1ae6864174dde02c7cd171b5fe | |
parent | dac5b931bcf8757070c8aa74571e52f3b4c6e5eb (diff) | |
download | dotty-e82cb7cdb93306b5fccf6aeef0e087999f46a016.tar.gz dotty-e82cb7cdb93306b5fccf6aeef0e087999f46a016.tar.bz2 dotty-e82cb7cdb93306b5fccf6aeef0e087999f46a016.zip |
Fix #1567: Widen private constructor in value class
Private or protected constructors of value classes need to be widenened
to public in order to enable boxing anywhere.
Technically we should also do something about qualified private constructors, but since we
want to get rid of them anyway it's urgent.
-rw-r--r-- | src/dotty/tools/dotc/transform/ExtensionMethods.scala | 20 | ||||
-rw-r--r-- | tests/pos/1567/PosZInt_1.scala | 6 | ||||
-rw-r--r-- | tests/pos/1567/Test_2.scala | 3 |
3 files changed, 24 insertions, 5 deletions
diff --git a/src/dotty/tools/dotc/transform/ExtensionMethods.scala b/src/dotty/tools/dotc/transform/ExtensionMethods.scala index 62a21198d..5ae4e8a54 100644 --- a/src/dotty/tools/dotc/transform/ExtensionMethods.scala +++ b/src/dotty/tools/dotc/transform/ExtensionMethods.scala @@ -32,6 +32,9 @@ import SymUtils._ * in [[ElimErasedValueType]]. * This is different from the implementation of value classes in Scala 2 * (see SIP-15) which uses `asInstanceOf` which does not typecheck. + * + * Finally, if the constructor of a value class is private pr protected + * it is widened to public. */ class ExtensionMethods extends MiniPhaseTransform with DenotTransformer with FullParameterization { thisTransformer => @@ -96,11 +99,18 @@ class ExtensionMethods extends MiniPhaseTransform with DenotTransformer with Ful case _ => moduleClassSym } - case ref: SymDenotation - if isMethodWithExtension(ref) && ref.hasAnnotation(defn.TailrecAnnot) => - val ref1 = ref.copySymDenotation() - ref1.removeAnnotation(defn.TailrecAnnot) - ref1 + case ref: SymDenotation => + if (isMethodWithExtension(ref) && ref.hasAnnotation(defn.TailrecAnnot)) { + val ref1 = ref.copySymDenotation() + ref1.removeAnnotation(defn.TailrecAnnot) + ref1 + } + else if (ref.isConstructor && isDerivedValueClass(ref.owner) && ref.is(AccessFlags)) { + val ref1 = ref.copySymDenotation() + ref1.resetFlag(AccessFlags) + ref1 + } + else ref case _ => ref } diff --git a/tests/pos/1567/PosZInt_1.scala b/tests/pos/1567/PosZInt_1.scala new file mode 100644 index 000000000..60b4061e6 --- /dev/null +++ b/tests/pos/1567/PosZInt_1.scala @@ -0,0 +1,6 @@ +final class PosZInt private (val value: Int) extends AnyVal + +object PosZInt { + def from(value: Int): Option[PosZInt] = + if (value >= 0) Some(new PosZInt(value)) else None +} diff --git a/tests/pos/1567/Test_2.scala b/tests/pos/1567/Test_2.scala new file mode 100644 index 000000000..db6ca7070 --- /dev/null +++ b/tests/pos/1567/Test_2.scala @@ -0,0 +1,3 @@ +object Test { + scala.util.Try(PosZInt.from(1).get) +} |