summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAdriaan Moors <adriaan.moors@epfl.ch>2007-04-24 15:17:49 +0000
committerAdriaan Moors <adriaan.moors@epfl.ch>2007-04-24 15:17:49 +0000
commit1f5dfbd7a6ca915ceb8a5794be568cfab8f97e47 (patch)
tree9475fcff0a26e0d02469616e024f3a15c5c9d7c8
parente4c282d9ef2e068701dd2eecec84ed8af84ae9e5 (diff)
downloadscala-1f5dfbd7a6ca915ceb8a5794be568cfab8f97e47.tar.gz
scala-1f5dfbd7a6ca915ceb8a5794be568cfab8f97e47.tar.bz2
scala-1f5dfbd7a6ca915ceb8a5794be568cfab8f97e47.zip
fixed bug 1065
This was caused by the Uncurry phase not fully expanding alias types. More specifically, the argument&result types of anonymous functions (Function node) weren't normalized. Presumably other combinations weren't covered either. These should now be fixed.
-rw-r--r--src/compiler/scala/tools/nsc/transform/UnCurry.scala23
-rw-r--r--test/files/run/typealias_overriding.check1
-rw-r--r--test/files/run/typealias_overriding.scala23
3 files changed, 39 insertions, 8 deletions
diff --git a/src/compiler/scala/tools/nsc/transform/UnCurry.scala b/src/compiler/scala/tools/nsc/transform/UnCurry.scala
index e6f766ccfc..c0e29a55e1 100644
--- a/src/compiler/scala/tools/nsc/transform/UnCurry.scala
+++ b/src/compiler/scala/tools/nsc/transform/UnCurry.scala
@@ -43,8 +43,13 @@ abstract class UnCurry extends InfoTransform with TypingTransformers {
// ------ Type transformation --------------------------------------------------------
+//@MAT: uncurry and uncurryType fully expand type aliases in their input and output
+// note: don't normalize higher-kined types -- @M TODO: maybe split those uses of normalize?
+// OTOH, should be a problem as calls to normalize only occur on types with kind * in principle (in well-typed programs)
+ private def expandAlias(tp: Type): Type = if(!tp.isHigherKinded) tp.normalize else tp
+
private val uncurry: TypeMap = new TypeMap {
- def apply(tp: Type): Type = tp match {
+ def apply(tp0: Type): Type = {val tp=expandAlias(tp0); tp match {
case MethodType(formals, MethodType(formals1, restpe)) =>
apply(MethodType(formals ::: formals1, restpe))
case mt: ImplicitMethodType =>
@@ -55,34 +60,36 @@ abstract class UnCurry extends InfoTransform with TypingTransformers {
PolyType(tparams, apply(MethodType(List(), restpe)))
case TypeRef(pre, sym, List(arg1, arg2)) if (arg1.symbol == ByNameParamClass) =>
assert(sym == FunctionClass(1))
- apply(typeRef(pre, definitions.ByNameFunctionClass, List(arg1.typeArgs(0), arg2)))
+ apply(typeRef(pre, definitions.ByNameFunctionClass, List(expandAlias(arg1.typeArgs(0)), arg2)))
case TypeRef(pre, sym, List(arg)) if (sym == ByNameParamClass) =>
apply(functionType(List(), arg))
case TypeRef(pre, sym, args) if (sym == RepeatedParamClass) =>
apply(rawTypeRef(pre, SeqClass, args))
case _ =>
- mapOver(tp)
- }
+ expandAlias(mapOver(tp))
+ }}
}
private val uncurryType = new TypeMap {
- def apply(tp: Type): Type = tp match {
+ def apply(tp0: Type): Type = {val tp=expandAlias(tp0); tp match {
case ClassInfoType(parents, decls, clazz) =>
val parents1 = List.mapConserve(parents)(uncurry)
if (parents1 eq parents) tp
- else ClassInfoType(parents1, decls, clazz)
+ else ClassInfoType(parents1, decls, clazz) // @MAT normalize in decls??
case PolyType(_, _) =>
mapOver(tp)
case _ =>
tp
- }
+ }}
}
/** - return symbol's transformed type,
* - if symbol is a def parameter with transformed type T, return () => T
+ *
+ * @MAT: starting with this phase, the info of every symbol will be normalized
*/
def transformInfo(sym: Symbol, tp: Type): Type =
- if (sym.isType) uncurryType(tp.normalize) else uncurry(tp.normalize) // @MAT
+ if (sym.isType) uncurryType(tp) else uncurry(tp)
class UnCurryTransformer(unit: CompilationUnit) extends TypingTransformer(unit) {
diff --git a/test/files/run/typealias_overriding.check b/test/files/run/typealias_overriding.check
new file mode 100644
index 0000000000..2dc752a8c8
--- /dev/null
+++ b/test/files/run/typealias_overriding.check
@@ -0,0 +1 @@
+LinkedNode
diff --git a/test/files/run/typealias_overriding.scala b/test/files/run/typealias_overriding.scala
new file mode 100644
index 0000000000..03330498eb
--- /dev/null
+++ b/test/files/run/typealias_overriding.scala
@@ -0,0 +1,23 @@
+// this bug (http://scala-webapps.epfl.ch/bugtracking/bugs/displayItem.do?id=1065)
+// was caused by Uncurry not normalizing all the types
+// (more specifically the argument/return types of an anonymous Function)
+object Test extends Application {
+ trait AddRemove {
+ type TNode <: NodeImpl;
+ trait NodeImpl;
+
+ object removing {
+ type TNode = AddRemove.this.TNode;
+ def printNode(node: TNode, f: TNode => String) = Console.println(f(node))
+ }
+ }
+
+ class Linked extends AddRemove {
+ type TNode = Node // can also directly write `class Node extends super.NodeImpl' -- doesn't change the bug
+ class Node extends super.NodeImpl { override def toString = "LinkedNode" }
+
+ removing.printNode(new Node, (x: removing.TNode) => x.toString) // make inference explicit, doesn't affect the bug
+ }
+
+ new Linked
+} \ No newline at end of file