diff options
-rw-r--r-- | src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala | 109 | ||||
-rw-r--r-- | src/compiler/scala/tools/nsc/typechecker/RefChecks.scala | 3 | ||||
-rw-r--r-- | src/compiler/scala/tools/nsc/typechecker/Typers.scala | 10 | ||||
-rw-r--r-- | test/files/neg/bug1241.check | 2 | ||||
-rw-r--r-- | test/files/neg/t0204.check | 4 | ||||
-rw-r--r-- | test/files/neg/t0218.check | 6 | ||||
-rw-r--r-- | test/files/pos/bug812.scala | 2 | ||||
-rw-r--r-- | test/files/pos/michel4.scala | 4 | ||||
-rw-r--r-- | test/files/pos/t0231.scala | 2 |
9 files changed, 83 insertions, 59 deletions
diff --git a/src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala b/src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala index 5bff9d070f..991808bad0 100644 --- a/src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala +++ b/src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala @@ -472,51 +472,62 @@ abstract class ClassfileParser { case SHORT_TAG => definitions.ShortClass.tpe case VOID_TAG => definitions.UnitClass.tpe case BOOL_TAG => definitions.BooleanClass.tpe - case 'L' => { - val classSym = classNameToSymbol(subName(c => c == ';' || c == '<')) - assert(!classSym.hasFlag(OVERLOADED), classSym.alternatives) - val existentials = new ListBuffer[Symbol]() - val tpe: Type = if (sig(index) == '<') { - accept('<') - val xs = new ListBuffer[Type]() - var i = 0 - while (sig(index) != '>') { - sig(index) match { - case variance @ ('+' | '-' | '*') => - index += 1 - val bounds = variance match { - case '+' => mkTypeBounds(definitions.AllClass.tpe, - sig2type(tparams)) - case '-' => mkTypeBounds(sig2type(tparams), - definitions.AnyClass.tpe) - case '*' => mkTypeBounds(definitions.AllClass.tpe, - definitions.AnyClass.tpe) - } - val newtparam = makeExistential("?"+i, sym, bounds) - existentials += newtparam - xs += newtparam.tpe - i += 1 - case _ => - xs += sig2type(tparams) + case 'L' => + def processClassType(tp: Type): Type = { + val classSym = tp.typeSymbol + val existentials = new ListBuffer[Symbol]() + if (sig(index) == '<') { + accept('<') + val xs = new ListBuffer[Type]() + var i = 0 + while (sig(index) != '>') { + sig(index) match { + case variance @ ('+' | '-' | '*') => + index += 1 + val bounds = variance match { + case '+' => mkTypeBounds(definitions.AllClass.tpe, + sig2type(tparams)) + case '-' => mkTypeBounds(sig2type(tparams), + definitions.AnyClass.tpe) + case '*' => mkTypeBounds(definitions.AllClass.tpe, + definitions.AnyClass.tpe) + } + val newtparam = makeExistential("?"+i, sym, bounds) + existentials += newtparam + xs += newtparam.tpe + i += 1 + case _ => + xs += sig2type(tparams) + } } + accept('>') + assert(xs.length > 0) + existentialAbstraction(existentials.toList, + appliedType(tp, xs.toList)) + } else if (classSym.isMonomorphicType) { + tp + } else { + // raw type - existentially quantify all type parameters + val eparams = typeParamsToExistentials(classSym, classSym.unsafeTypeParams) + val t = appliedType(classSym.typeConstructor, eparams.map(_.tpe)) + val res = existentialAbstraction(eparams, t) + if (settings.debug.value && settings.verbose.value) println("raw type " + classSym + " -> " + res) + res } - accept('>') - assert(xs.length > 0) - existentialAbstraction(existentials.toList, - appliedType(classSym.tpe, xs.toList)) } - else if (classSym.isMonomorphicType) classSym.tpe - else { - // raw type - existentially quantify all type parameters - val eparams = typeParamsToExistentials(classSym, classSym.unsafeTypeParams) - val t = appliedType(classSym.typeConstructor, eparams.map(_.tpe)) - val res = existentialAbstraction(eparams, t) - if (settings.debug.value && settings.verbose.value) println("raw type " + classSym + " -> " + res) - res + val classSym = classNameToSymbol(subName(c => c == ';' || c == '<')) + assert(!classSym.hasFlag(OVERLOADED), classSym.alternatives) + var tpe = processClassType(classSym.tpe) + while (sig(index) == '.') { + accept('.') + val name = subName(c => c == ';' || c == '.').toTypeName + val clazz = tpe.typeSymbol.info.member(name) + assert(clazz.isClass, + tpe.typeSymbol.linkedModuleOfClass.moduleClass.info+" "+tpe+" . "+name+"/"+tpe.typeSymbol.info.decls) + tpe = processClassType(clazz.tpe) } accept(';') tpe - } case ARRAY_TAG => while ('0' <= sig(index) && sig(index) <= '9') index += 1 appliedType(definitions.ArrayClass.tpe, List(sig2type(tparams))) @@ -719,6 +730,16 @@ abstract class ClassfileParser { } } + def makeInnerAlias(outer: Symbol, name: Name, iclazz: Symbol, scope: Scope): Symbol = { + var innerAlias = scope.lookup(name) + if (!innerAlias.isAliasType) { + innerAlias = outer.newAliasType(NoPosition, name).setFlag(JAVA) + .setInfo(new LazyAliasType(iclazz)) + scope.enter(innerAlias) + } + innerAlias + } + def parseInnerClasses() { for (i <- 0 until in.nextChar) { val innerIndex = in.nextChar @@ -728,11 +749,11 @@ abstract class ClassfileParser { if (innerIndex != 0 && outerIndex != 0 && nameIndex != 0 && (jflags & (JAVA_ACC_PUBLIC | JAVA_ACC_PROTECTED)) != 0 && pool.getClassSymbol(outerIndex) == sym) { - val innerAlias = getOwner(jflags) - .newAliasType(NoPosition, pool.getName(nameIndex).toTypeName) - .setFlag(JAVA) - .setInfo(new LazyAliasType(pool.getClassSymbol(innerIndex))) - getScope(jflags).enter(innerAlias) + makeInnerAlias( + getOwner(jflags), + pool.getName(nameIndex).toTypeName, + pool.getClassSymbol(innerIndex), + getScope(jflags)) if ((jflags & JAVA_ACC_STATIC) != 0) { val innerVal = staticModule.newValue(NoPosition, pool.getName(nameIndex).toTermName) diff --git a/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala b/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala index a689aa6fd5..de1f3f3119 100644 --- a/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala +++ b/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala @@ -538,7 +538,8 @@ abstract class RefChecks extends InfoTransform { !(receiver isSubClass actual)) nonSensible("", false) else if ((receiver hasFlag FINAL) && hasObjectEquals && !isValueClass(receiver) && - !(receiver isSubClass actual) && receiver != AllRefClass && actual != AllRefClass) + !(receiver isSubClass actual) && receiver != AllRefClass && actual != AllRefClass && + (name == nme.EQ || name == nme.LE)) nonSensible("non-null ", false) else if ((isNew(qual) || isNew(args.head)) && hasObjectEquals) nonSensibleWarning("a fresh object", false) diff --git a/src/compiler/scala/tools/nsc/typechecker/Typers.scala b/src/compiler/scala/tools/nsc/typechecker/Typers.scala index 41a96d3e5c..290d603282 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Typers.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Typers.scala @@ -237,10 +237,12 @@ trait Typers { self: Analyzer => else errorTree(tree, "stable identifier required, but " + tree + " found.") /** Check that `tpt' refers to a non-refinement class type */ - def checkClassType(tpt: Tree) { + def checkClassType(tpt: Tree, existentialOK: Boolean) { def check(tpe: Type): Unit = tpe.normalize match { case TypeRef(_, sym, _) if sym.isClass && !sym.isRefinementClass => ; + case ErrorType => ; case PolyType(_, restpe) => check(restpe) + case ExistentialType(_, restpe) if existentialOK => check(restpe) case t => error(tpt.pos, "class type required but "+t+" found") } check(tpt.tpe) @@ -956,7 +958,7 @@ trait Typers { self: Analyzer => def validateParentClass(parent: Tree, superclazz: Symbol) { if (!parent.tpe.isError) { val psym = parent.tpe.typeSymbol.initialize - checkClassType(parent) + checkClassType(parent, false) if (psym != superclazz) { if (psym.isTrait) { val ps = psym.info.parents @@ -2301,7 +2303,7 @@ trait Typers { self: Analyzer => def typedNew(tpt: Tree) = { var tpt1 = typedTypeConstructor(tpt) - checkClassType(tpt1) + checkClassType(tpt1, false) if (tpt1.hasSymbol && !tpt1.symbol.typeParams.isEmpty) { context.undetparams = cloneSymbols(tpt1.symbol.typeParams) tpt1 = TypeTree() @@ -2381,7 +2383,7 @@ trait Typers { self: Analyzer => val targs = args map (_.tpe) checkBounds(tree.pos, NoPrefix, NoSymbol, tparams, targs, "") if (fun.symbol == Predef_classOf) { - checkClassType(args.head) + checkClassType(args.head, true) Literal(Constant(targs.head)) setPos tree.pos setType Predef_classOfType(targs.head) // @M: targs.head.normalize is not necessary --> toTypeKind eventually normalizes the type } else { diff --git a/test/files/neg/bug1241.check b/test/files/neg/bug1241.check index b846270c1b..48c86cabb7 100644 --- a/test/files/neg/bug1241.check +++ b/test/files/neg/bug1241.check @@ -1,4 +1,4 @@ -bug1241.scala:5: error: class type required +bug1241.scala:5: error: class type required but AnyRef{def hello(): Unit} found val x4 = new T { def hello() { println("4") } } // error! ^ one error found diff --git a/test/files/neg/t0204.check b/test/files/neg/t0204.check index ffa13e3df7..27b88d21d2 100644 --- a/test/files/neg/t0204.check +++ b/test/files/neg/t0204.check @@ -1,4 +1,4 @@ -t0204.scala:4: error: class type required - trait C extends B +t0204.scala:4: error: class type required but Program.A{type T = String} found + trait C extends B
^ one error found diff --git a/test/files/neg/t0218.check b/test/files/neg/t0218.check index 0f74da6ad6..c7a6d952b9 100644 --- a/test/files/neg/t0218.check +++ b/test/files/neg/t0218.check @@ -1,4 +1,4 @@ -t0218.scala:10: error: type P is abstract; cannot be instantiated - List(new PP) - ^ +t0218.scala:10: error: class type required but APQ.this.P found + List(new PP)
+ ^ one error found diff --git a/test/files/pos/bug812.scala b/test/files/pos/bug812.scala index ccbe6db5ce..1c9c923b6c 100644 --- a/test/files/pos/bug812.scala +++ b/test/files/pos/bug812.scala @@ -2,6 +2,6 @@ package test; import scala.{Application => Main}; class Test extends Main { import test.{Test => Hello} - super[Application].executionStart; + super[Application].main(Array("test")); private[Test] def xxx = 10; } diff --git a/test/files/pos/michel4.scala b/test/files/pos/michel4.scala index 2390be5d26..ce9de29a2e 100644 --- a/test/files/pos/michel4.scala +++ b/test/files/pos/michel4.scala @@ -1,7 +1,7 @@ class A() { - val f : Int = 2 + def f : Int = 2 } class B() extends A() { override val f : Int = super.f -}
\ No newline at end of file +} diff --git a/test/files/pos/t0231.scala b/test/files/pos/t0231.scala index 83d89dccb9..895e780421 100644 --- a/test/files/pos/t0231.scala +++ b/test/files/pos/t0231.scala @@ -1,5 +1,5 @@ class Foo { - object aaa { + def aaa { println("a") } } |