Skip to content

Fix compatibility of Java with value classes #532

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 2 commits into from
May 4, 2015
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
9 changes: 9 additions & 0 deletions src/dotty/tools/dotc/core/SymDenotations.scala
Original file line number Diff line number Diff line change
Expand Up @@ -370,6 +370,15 @@ object SymDenotations {
final def isAnonymousModuleVal(implicit ctx: Context) =
this.symbol.is(ModuleVal) && (initial.asSymDenotation.name startsWith nme.ANON_CLASS)

/** Is this a companion class method or companion object method?
* These methods are generated by Symbols#synthesizeCompanionMethod
* and used in SymDenotations#companionClass and
* SymDenotations#companionModule .
*/
final def isCompanionMethod(implicit ctx: Context) =
name.toTermName == nme.COMPANION_CLASS_METHOD ||
name.toTermName == nme.COMPANION_MODULE_METHOD

/** Is symbol a primitive value class? */
def isPrimitiveValueClass(implicit ctx: Context) = defn.ScalaValueClasses contains symbol

Expand Down
13 changes: 8 additions & 5 deletions src/dotty/tools/dotc/core/TypeErasure.scala
Original file line number Diff line number Diff line change
Expand Up @@ -142,15 +142,18 @@ object TypeErasure {
* - For $asInstanceOf : [T]T
* - For $isInstanceOf : [T]Boolean
* - For all abstract types : = ?
* - For COMPANION_CLASS_METHOD : the erasure of their type with semiEraseVCs = false,
* this is needed to keep [[SymDenotation#companionClass]]
* working after erasure for value classes.
* - For companion methods : the erasure of their type with semiEraseVCs = false.
* The signature of these methods are used to keep a
* link between companions and should not be semi-erased.
* - For Java-defined symbols: : the erasure of their type with isJava = true,
* semiEraseVCs = false. Semi-erasure never happens in Java.
* - For all other symbols : the semi-erasure of their types, with
* isJava, isConstructor set according to symbol.
*/
def transformInfo(sym: Symbol, tp: Type)(implicit ctx: Context): Type = {
val semiEraseVCs = sym.name ne nme.COMPANION_CLASS_METHOD
val erase = erasureFn(sym is JavaDefined, semiEraseVCs, sym.isConstructor, wildcardOK = false)
val isJava = sym is JavaDefined
val semiEraseVCs = !isJava && !sym.isCompanionMethod
val erase = erasureFn(isJava, semiEraseVCs, sym.isConstructor, wildcardOK = false)

def eraseParamBounds(tp: PolyType): Type =
tp.derivedPolyType(
Expand Down
2 changes: 1 addition & 1 deletion src/dotty/tools/dotc/transform/ValueClasses.scala
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ object ValueClasses {
!d.isConstructor &&
!d.is(SuperAccessor) &&
!d.is(Macro) &&
!(d.name eq nme.COMPANION_MODULE_METHOD)
!d.isCompanionMethod

/** The member that of a derived value class that unboxes it. */
def valueClassUnbox(d: ClassDenotation)(implicit ctx: Context): Symbol =
Expand Down
7 changes: 7 additions & 0 deletions tests/pos/valueclasses/t9298/JUse.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package t9298;

class JUse {
public static Meter jm() {
return new Meter(2);
}
}
3 changes: 3 additions & 0 deletions tests/pos/valueclasses/t9298/Meter.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
package t9298

class Meter(val x: Int) extends AnyVal
9 changes: 9 additions & 0 deletions tests/pos/valueclasses/t9298/Use.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
// TODO: this should be a run test once we have run tests

package t9298

object Use {
def main(args: Array[String]): Unit = {
val x: Meter = JUse.jm
}
}