From 6aaf4a3d5e730b0ed12eed78ae0940693c37ed22 Mon Sep 17 00:00:00 2001 From: Martin Odersky Date: Thu, 11 Mar 2010 14:21:21 +0000 Subject: Closes #2940. --- src/compiler/scala/tools/nsc/symtab/Definitions.scala | 2 +- .../scala/tools/nsc/symtab/classfile/ClassfileParser.scala | 6 ++++-- src/compiler/scala/tools/nsc/transform/Erasure.scala | 14 +++++++------- src/compiler/scala/tools/nsc/typechecker/Implicits.scala | 2 +- 4 files changed, 13 insertions(+), 11 deletions(-) (limited to 'src/compiler') diff --git a/src/compiler/scala/tools/nsc/symtab/Definitions.scala b/src/compiler/scala/tools/nsc/symtab/Definitions.scala index 55bf1899a4..50f62f3092 100644 --- a/src/compiler/scala/tools/nsc/symtab/Definitions.scala +++ b/src/compiler/scala/tools/nsc/symtab/Definitions.scala @@ -349,7 +349,7 @@ trait Definitions extends reflect.generic.StandardDefinitions { def arrayType(arg: Type) = typeRef(ArrayClass.typeConstructor.prefix, ArrayClass, List(arg)) def ClassType(arg: Type) = - if (ClassClass.unsafeTypeParams.isEmpty || phase.erasedTypes) ClassClass.tpe + if (phase.erasedTypes) ClassClass.tpe else appliedType(ClassClass.tpe, List(arg)) // diff --git a/src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala b/src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala index 6412efd8a2..efc899743d 100644 --- a/src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala +++ b/src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala @@ -589,6 +589,8 @@ abstract class ClassfileParser { while (!isDelimiter(sig(index))) { index += 1 } sig.subName(start, index) } + def existentialType(tparams: List[Symbol], tp: Type): Type = + if (tparams.isEmpty) tp else ExistentialType(tparams, tp) def sig2type(tparams: Map[Name,Symbol], skiptvs: Boolean): Type = { val tag = sig(index); index += 1 tag match { @@ -637,14 +639,14 @@ abstract class ClassfileParser { } accept('>') assert(xs.length > 0) - existentialAbstraction(existentials.toList, TypeRef(pre, classSym, xs.toList)) + existentialType(existentials.toList, TypeRef(pre, classSym, xs.toList)) } else if (classSym.isMonomorphicType) { tp } else { // raw type - existentially quantify all type parameters val eparams = typeParamsToExistentials(classSym, classSym.unsafeTypeParams) val t = TypeRef(pre, classSym, eparams.map(_.tpe)) - val res = existentialAbstraction(eparams, t) + val res = existentialType(eparams, t) if (settings.debug.value && settings.verbose.value) println("raw type " + classSym + " -> " + res) res } diff --git a/src/compiler/scala/tools/nsc/transform/Erasure.scala b/src/compiler/scala/tools/nsc/transform/Erasure.scala index ba6ef7168b..feb21ec75e 100644 --- a/src/compiler/scala/tools/nsc/transform/Erasure.scala +++ b/src/compiler/scala/tools/nsc/transform/Erasure.scala @@ -117,15 +117,15 @@ abstract class Erasure extends AddInterfaces with typechecker.Analyzer with ast. */ val erasure = new TypeMap { - // Compute the erasure of the intersection type with given `parents` according to new spec. - private def intersectionErasure(parents: List[Type]): Type = - if (parents.isEmpty) erasedTypeRef(ObjectClass) - else apply { + // Compute the dominant part of the intersection type with given `parents` according to new spec. + def intersectionDominator(parents: List[Type]): Type = + if (parents.isEmpty) ObjectClass.tpe + else { val psyms = parents map (_.typeSymbol) if (psyms contains ArrayClass) { // treat arrays specially arrayType( - intersectionErasure( + intersectionDominator( parents filter (_.typeSymbol == ArrayClass) map (_.typeArgs.head))) } else { // implement new spec for erasure of refined types. @@ -152,7 +152,7 @@ abstract class Erasure extends AddInterfaces with typechecker.Analyzer with ast. else typeRef(apply(pre), sym, args map this) else if (sym == AnyClass || sym == AnyValClass || sym == SingletonClass) erasedTypeRef(ObjectClass) else if (sym == UnitClass) erasedTypeRef(BoxedUnitClass) - else if (sym.isRefinementClass) intersectionErasure(tp.parents) + else if (sym.isRefinementClass) apply(intersectionDominator(tp.parents)) else if (sym.isClass) typeRef(apply(rebindInnerClass(pre, sym)), sym, List()) // #2585 else apply(sym.info) // alias type or abstract type case PolyType(tparams, restpe) => @@ -169,7 +169,7 @@ abstract class Erasure extends AddInterfaces with typechecker.Analyzer with ast. else apply(restpe)) case RefinedType(parents, decls) => - intersectionErasure(parents) + apply(intersectionDominator(parents)) case AnnotatedType(_, atp, _) => apply(atp) case ClassInfoType(parents, decls, clazz) => diff --git a/src/compiler/scala/tools/nsc/typechecker/Implicits.scala b/src/compiler/scala/tools/nsc/typechecker/Implicits.scala index f464576979..92ce07cd9e 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Implicits.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Implicits.scala @@ -836,7 +836,7 @@ self: Analyzer => // refinement is not generated yet if (parents.length == 1) findManifest(parents.head) else if (full) manifestFactoryCall("intersectionType", tp, parents map (findSubManifest(_)): _*) - else mot(erasure.erasure(tp0)) + else mot(erasure.erasure.intersectionDominator(parents)) case ExistentialType(tparams, result) => existentialAbstraction(tparams, result) match { case ExistentialType(_, _) => mot(result) -- cgit v1.2.3