diff options
-rw-r--r-- | src/compiler/scala/tools/nsc/transform/UnCurry.scala | 23 | ||||
-rw-r--r-- | test/files/run/typealias_overriding.check | 1 | ||||
-rw-r--r-- | test/files/run/typealias_overriding.scala | 23 |
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 |