summaryrefslogtreecommitdiff
path: root/src/compiler/scala/tools/nsc/transform/ExtensionMethods.scala
diff options
context:
space:
mode:
authorMartin Odersky <odersky@gmail.com>2012-07-29 14:10:36 +0200
committerMartin Odersky <odersky@gmail.com>2012-07-29 14:10:45 +0200
commitdaf0953c1f5d76b468a75911f3f22162d631415c (patch)
tree715a6192f30e6383b2621e58ba027573c78713fb /src/compiler/scala/tools/nsc/transform/ExtensionMethods.scala
parent1f95d356ee69a442f98aedc024a1aa7e4672d20a (diff)
downloadscala-daf0953c1f5d76b468a75911f3f22162d631415c.tar.gz
scala-daf0953c1f5d76b468a75911f3f22162d631415c.tar.bz2
scala-daf0953c1f5d76b468a75911f3f22162d631415c.zip
Closes SI-5878
We need to impose an additional rule on value classes: They may not unbox directly or indirectly to themselves.
Diffstat (limited to 'src/compiler/scala/tools/nsc/transform/ExtensionMethods.scala')
-rw-r--r--src/compiler/scala/tools/nsc/transform/ExtensionMethods.scala13
1 files changed, 11 insertions, 2 deletions
diff --git a/src/compiler/scala/tools/nsc/transform/ExtensionMethods.scala b/src/compiler/scala/tools/nsc/transform/ExtensionMethods.scala
index 5f66cadbc9..e937589f54 100644
--- a/src/compiler/scala/tools/nsc/transform/ExtensionMethods.scala
+++ b/src/compiler/scala/tools/nsc/transform/ExtensionMethods.scala
@@ -78,13 +78,13 @@ abstract class ExtensionMethods extends Transform with TypingTransformers {
}
/** This method removes the `$this` argument from the parameter list a method.
- *
+ *
* A method may be a `PolyType`, in which case we tear out the `$this` and the class
* type params from its nested `MethodType`.
* It may be a `MethodType`, either with a curried parameter list in which the first argument
* is a `$this` - we just return the rest of the list.
* This means that the corresponding symbol was generated during `extmethods`.
- *
+ *
* It may also be a `MethodType` in which the `$this` does not appear in a curried parameter list.
* The curried lists disappear during `uncurry`, and the methods may be duplicated afterwards,
* for instance, during `specialize`.
@@ -105,6 +105,14 @@ abstract class ExtensionMethods extends Transform with TypingTransformers {
private val extensionDefs = mutable.Map[Symbol, mutable.ListBuffer[Tree]]()
+ def checkNonCyclic(pos: Position, seen: Set[Symbol], clazz: Symbol): Unit =
+ if (seen contains clazz)
+ unit.error(pos, "value class may not unbox to itself")
+ else {
+ val unboxed = erasure.underlyingOfValueClass(clazz).typeSymbol
+ if (unboxed.isDerivedValueClass) checkNonCyclic(pos, seen + clazz, unboxed)
+ }
+
def extensionMethInfo(extensionMeth: Symbol, origInfo: Type, clazz: Symbol): Type = {
var newTypeParams = cloneSymbolsAtOwner(clazz.typeParams, extensionMeth)
val thisParamType = appliedType(clazz.typeConstructor, newTypeParams map (_.tpeHK))
@@ -129,6 +137,7 @@ abstract class ExtensionMethods extends Transform with TypingTransformers {
tree match {
case Template(_, _, _) =>
if (currentOwner.isDerivedValueClass) {
+ checkNonCyclic(currentOwner.pos, Set(), currentOwner)
extensionDefs(currentOwner.companionModule) = new mutable.ListBuffer[Tree]
currentOwner.primaryConstructor.makeNotPrivate(NoSymbol)
super.transform(tree)