diff options
author | Adriaan Moors <adriaan.moors@epfl.ch> | 2009-11-12 16:56:33 +0000 |
---|---|---|
committer | Adriaan Moors <adriaan.moors@epfl.ch> | 2009-11-12 16:56:33 +0000 |
commit | e7bc7737c72dff381cfc93d2387a66565de1968b (patch) | |
tree | 826301c369d46c08795daa0cdef9995d82b3e642 /src | |
parent | fe1d0c7052279ddf9cacfd1a7160cbee5829a4cc (diff) | |
download | scala-e7bc7737c72dff381cfc93d2387a66565de1968b.tar.gz scala-e7bc7737c72dff381cfc93d2387a66565de1968b.tar.bz2 scala-e7bc7737c72dff381cfc93d2387a66565de1968b.zip |
fixed #2454
Diffstat (limited to 'src')
-rw-r--r-- | src/compiler/scala/tools/nsc/Settings.scala | 1 | ||||
-rw-r--r-- | src/compiler/scala/tools/nsc/symtab/Symbols.scala | 42 | ||||
-rw-r--r-- | src/compiler/scala/tools/nsc/symtab/Types.scala | 11 | ||||
-rw-r--r-- | src/compiler/scala/tools/nsc/typechecker/Infer.scala | 25 | ||||
-rw-r--r-- | src/compiler/scala/tools/nsc/typechecker/RefChecks.scala | 2 |
5 files changed, 54 insertions, 27 deletions
diff --git a/src/compiler/scala/tools/nsc/Settings.scala b/src/compiler/scala/tools/nsc/Settings.scala index 0f59d9a3d9..5db78420ec 100644 --- a/src/compiler/scala/tools/nsc/Settings.scala +++ b/src/compiler/scala/tools/nsc/Settings.scala @@ -836,7 +836,6 @@ trait ScalacSettings { val Ytyperdebug = BooleanSetting ("-Ytyper-debug", "Trace all type assignements") val Ypmatdebug = BooleanSetting ("-Ypmat-debug", "Trace all pattern matcher activity.") val Ytailrec = BooleanSetting ("-Ytailrecommend", "Alert methods which would be tail-recursive if private or final.") - val YhigherKindedRaw = BooleanSetting ("-Yhigher-kinded-raw", "(temporary!) Treat raw Java types as higher-kinded types.") val Yjenkins = BooleanSetting ("-Yjenkins-hashCodes", "Use jenkins hash algorithm for case class generated hashCodes.") // Warnings diff --git a/src/compiler/scala/tools/nsc/symtab/Symbols.scala b/src/compiler/scala/tools/nsc/symtab/Symbols.scala index 7e16d1dc9b..e4cbe159a1 100644 --- a/src/compiler/scala/tools/nsc/symtab/Symbols.scala +++ b/src/compiler/scala/tools/nsc/symtab/Symbols.scala @@ -885,6 +885,48 @@ trait Symbols { infos ne null } + /** Modify term symbol's type so that a raw type C is converted to an existential C[_] + * + * This is done in checkAccessible and overriding checks in refchecks + * We can't do this on class loading because it would result in infinite cycles. + */ + private var triedCooking: Boolean = false + final def cookJavaRawInfo() { + require(isTerm) + // println("cookJavaRawInfo: "+(rawname, triedCooking)) + + if(triedCooking) return else triedCooking = true // only try once... + + def cook(sym: Symbol) { + require(sym hasFlag JAVA) + // @M: I think this is more desirable, but Martin prefers to leave raw-types as-is as much as possible + // object rawToExistentialInJava extends TypeMap { + // def apply(tp: Type): Type = tp match { + // // any symbol that occurs in a java sig, not just java symbols + // // see http://lampsvn.epfl.ch/trac/scala/ticket/2454#comment:14 + // case TypeRef(pre, sym, List()) if !sym.typeParams.isEmpty => + // val eparams = typeParamsToExistentials(sym, sym.typeParams) + // existentialAbstraction(eparams, TypeRef(pre, sym, eparams map (_.tpe))) + // case _ => + // mapOver(tp) + // } + // } + val tpe1 = rawToExistential(sym.tpe) + // println("cooking: "+ sym +": "+ sym.tpe +" to "+ tpe1) + if (tpe1 ne sym.tpe) { + sym.setInfo(tpe1) + } + } + + if (hasFlag(JAVA)) + cook(this) + else if (hasFlag(OVERLOADED)) + for (sym2 <- alternatives) + if (sym2 hasFlag JAVA) + cook(sym2) + } + + /** The type constructor of a symbol is: * For a type symbol, the type corresponding to the symbol itself, * excluding parameters. diff --git a/src/compiler/scala/tools/nsc/symtab/Types.scala b/src/compiler/scala/tools/nsc/symtab/Types.scala index 9727f6aa5d..6145c4a0d7 100644 --- a/src/compiler/scala/tools/nsc/symtab/Types.scala +++ b/src/compiler/scala/tools/nsc/symtab/Types.scala @@ -1600,12 +1600,11 @@ A type's typeSymbol should never be inspected directly. override def typeConstructor = rawTypeRef(pre, sym, List()) - // (args.isEmpty && !typeParamsDirect.isEmpty) && !isRawType(this) - // check for isRawType: otherwise raw types are considered higher-kinded types during subtyping: - override def isHigherKinded - = (args.isEmpty && !typeParamsDirect.isEmpty) && (settings.YhigherKindedRaw.value || !isRaw(sym, args)) - // (args.isEmpty && !typeParamsDirect.isEmpty) && (phase.erasedTypes || !sym.hasFlag(JAVA)) - + // a reference (in a Scala program) to a type that has type parameters, but where the reference does not include type arguments + // note that it doesn't matter whether the symbol refers to a java or scala symbol, + // it does matter whether it occurs in java or scala code + // typerefs w/o type params that occur in java signatures/code are considered raw types, and are represented as existential types + override def isHigherKinded = (args.isEmpty && !typeParamsDirect.isEmpty) override def instantiateTypeParams(formals: List[Symbol], actuals: List[Type]): Type = if (isHigherKinded) { diff --git a/src/compiler/scala/tools/nsc/typechecker/Infer.scala b/src/compiler/scala/tools/nsc/typechecker/Infer.scala index 898ad238a1..0c3e34f8c5 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Infer.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Infer.scala @@ -356,6 +356,8 @@ trait Infer { context.unit.depends += sym.toplevelClass val sym1 = sym filter (alt => context.isAccessible(alt, pre, site.isInstanceOf[Super])) + // Console.println("check acc " + (sym, sym1) + ":" + (sym.tpe, sym1.tpe) + " from " + pre);//DEBUG + if (sym1 == NoSymbol) { if (settings.debug.value) { Console.println(context) @@ -364,26 +366,9 @@ trait Infer { } accessError("") } else { - // Modify symbol's type so that raw types C - // are converted to existentials C[T] forSome { type T }. - // We can't do this on class loading because it would result - // in infinite cycles. - def cook(sym: Symbol) { - val tpe1 = rawToExistential(sym.tpe) - if (tpe1 ne sym.tpe) { - if (settings.debug.value) println("cooked: "+sym+":"+sym.tpe) - sym.setInfo(tpe1) - } - } - if (sym1.isTerm) { - if (sym1 hasFlag JAVA) - cook(sym1) - else if (sym1 hasFlag OVERLOADED) - for (sym2 <- sym1.alternatives) - if (sym2 hasFlag JAVA) - cook(sym2) - } - //Console.println("check acc " + sym1 + ":" + sym1.tpe + " from " + pre);//DEBUG + if(sym1.isTerm) + sym1.cookJavaRawInfo() // xform java rawtypes into existentials + var owntype = try{ pre.memberType(sym1) } catch { diff --git a/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala b/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala index aaefab1f74..9b8be2aaec 100644 --- a/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala +++ b/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala @@ -370,6 +370,8 @@ abstract class RefChecks extends InfoTransform { kindErrors.toList.mkString("\n", ", ", "")) } } else if (other.isTerm) { + other.cookJavaRawInfo() // #2454 + if (!overridesType(self.memberInfo(member), self.memberInfo(other))) { // 8 overrideTypeError() explainTypes(self.memberInfo(member), self.memberInfo(other)) |