summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorAleksandar Prokopec <axel22@gmail.com>2012-06-07 19:59:49 +0200
committerAleksandar Prokopec <axel22@gmail.com>2012-06-07 20:43:26 +0200
commitdab1d0361ff74a2e4500255beba65389f44f34cc (patch)
tree66a4857ade783e600de355ef8648767cbddf78f8 /src
parent6cdb6b0299cb917ac3df9e39aa932bacdc31faf9 (diff)
downloadscala-dab1d0361ff74a2e4500255beba65389f44f34cc.tar.gz
scala-dab1d0361ff74a2e4500255beba65389f44f34cc.tar.bz2
scala-dab1d0361ff74a2e4500255beba65389f44f34cc.zip
Fix SI-5853.
This solves two issues. First, up to now the newly generated symbols for normalized members were not being added to the declaration list of the owner during `specialize`. Now they are. Second, during `extmethods`, the extension methods generated get an additional curried parameter list for `$this`. Trouble was, after that, during `uncurry` and before `specialize`, these curried parameter lists were merged into one list. Specialization afterwards treats extension methods just like normal methods and generates new symbols without the curried parameter list. The `extensionMethod` now takes this into account by checking if the first parameter of a potential extension method has the name `$this`. Review by @dragos. Review by @odersky.
Diffstat (limited to 'src')
-rw-r--r--src/compiler/scala/tools/nsc/transform/ExtensionMethods.scala17
-rw-r--r--src/compiler/scala/tools/nsc/transform/SpecializeTypes.scala1
2 files changed, 17 insertions, 1 deletions
diff --git a/src/compiler/scala/tools/nsc/transform/ExtensionMethods.scala b/src/compiler/scala/tools/nsc/transform/ExtensionMethods.scala
index 8556cc9ddc..7e0b87dbe1 100644
--- a/src/compiler/scala/tools/nsc/transform/ExtensionMethods.scala
+++ b/src/compiler/scala/tools/nsc/transform/ExtensionMethods.scala
@@ -77,11 +77,26 @@ abstract class ExtensionMethods extends Transform with TypingTransformers {
matching.head
}
+ /** 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`.
+ * In this case, the first argument is `$this` and we just get rid of it.
+ */
private def normalize(stpe: Type, clazz: Symbol): Type = stpe match {
case PolyType(tparams, restpe) =>
GenPolyType(tparams dropRight clazz.typeParams.length, normalize(restpe.substSym(tparams takeRight clazz.typeParams.length, clazz.typeParams), clazz))
- case MethodType(tparams, restpe) =>
+ case MethodType(List(thiz), restpe) if thiz.name == nme.SELF =>
restpe
+ case MethodType(tparams, restpe) =>
+ MethodType(tparams.drop(1), restpe)
case _ =>
stpe
}
diff --git a/src/compiler/scala/tools/nsc/transform/SpecializeTypes.scala b/src/compiler/scala/tools/nsc/transform/SpecializeTypes.scala
index f2e109a5ad..60461a524b 100644
--- a/src/compiler/scala/tools/nsc/transform/SpecializeTypes.scala
+++ b/src/compiler/scala/tools/nsc/transform/SpecializeTypes.scala
@@ -821,6 +821,7 @@ abstract class SpecializeTypes extends InfoTransform with TypingTransformers {
debuglog("%s expands to %s in %s".format(sym, specMember.name.decode, pp(env)))
info(specMember) = NormalizedMember(sym)
overloads(sym) ::= Overload(specMember, env)
+ owner.info.decls.enter(specMember)
specMember
}
}