summaryrefslogtreecommitdiff
path: root/src/compiler
diff options
context:
space:
mode:
authorMartin Odersky <odersky@gmail.com>2007-04-30 11:48:45 +0000
committerMartin Odersky <odersky@gmail.com>2007-04-30 11:48:45 +0000
commit12a2b3b7ebd680b7a461209c505ccab82b86b66b (patch)
treed502b0c1364a45ae44e5937b95d300bfec6b50f5 /src/compiler
parentf9454ad5cebd35bf1bd9998521e1acf775513c11 (diff)
downloadscala-12a2b3b7ebd680b7a461209c505ccab82b86b66b.tar.gz
scala-12a2b3b7ebd680b7a461209c505ccab82b86b66b.tar.bz2
scala-12a2b3b7ebd680b7a461209c505ccab82b86b66b.zip
fixed bugs 1072, 1067, 1055, 997
Diffstat (limited to 'src/compiler')
-rw-r--r--src/compiler/scala/tools/nsc/ast/parser/Parsers.scala2
-rw-r--r--src/compiler/scala/tools/nsc/symtab/StdNames.scala1
-rw-r--r--src/compiler/scala/tools/nsc/symtab/Symbols.scala10
-rw-r--r--src/compiler/scala/tools/nsc/symtab/classfile/Pickler.scala14
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Infer.scala55
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/RefChecks.scala23
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Typers.scala15
7 files changed, 80 insertions, 40 deletions
diff --git a/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala b/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala
index c061b0c9fd..3c07de420d 100644
--- a/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala
+++ b/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala
@@ -1003,7 +1003,7 @@ trait Parsers {
stripParens(t)
}
if (!implicitParams.isEmpty)
- if (isWildcard(res)) savedImplicitParams = savedImplicitParams ::: implicitParams
+ if (isWildcard(res)) savedImplicitParams = implicitParams ::: savedImplicitParams
else res = Function(implicitParams.reverse, res)
implicitParams = savedImplicitParams
res
diff --git a/src/compiler/scala/tools/nsc/symtab/StdNames.scala b/src/compiler/scala/tools/nsc/symtab/StdNames.scala
index 2e36624dc4..63cddbbbc7 100644
--- a/src/compiler/scala/tools/nsc/symtab/StdNames.scala
+++ b/src/compiler/scala/tools/nsc/symtab/StdNames.scala
@@ -152,6 +152,7 @@ trait StdNames {
val ERROR = newTermName("<error>")
val ERRORtype = newTypeName("<error>")
+ val LOCALCHILD = newTypeName("<local child>")
val NOSYMBOL = newTermName("<none>")
val EMPTY = newTermName("")
diff --git a/src/compiler/scala/tools/nsc/symtab/Symbols.scala b/src/compiler/scala/tools/nsc/symtab/Symbols.scala
index 2e20ecc2e1..19f8773853 100644
--- a/src/compiler/scala/tools/nsc/symtab/Symbols.scala
+++ b/src/compiler/scala/tools/nsc/symtab/Symbols.scala
@@ -303,7 +303,7 @@ trait Symbols {
* A class is local, if
* - it is anonymous, or
* - its owner is a value
- * - it is defined within a local class214
+ * - it is defined within a local class
*/
final def isLocalClass: boolean =
isClass && (isAnonymousClass || isRefinementClass || isLocal ||
@@ -783,7 +783,7 @@ trait Symbols {
*/
def moduleClass: Symbol = NoSymbol
- /** The non-abstract, symbol whose type matches the type of this symbol
+ /** The non-private symbol whose type matches the type of this symbol
* in in given class.
*
* @param ofclazz The class containing the symbol's definition
@@ -793,6 +793,12 @@ trait Symbols {
ofclazz.info.nonPrivateDecl(name).filter(sym =>
!sym.isTerm || (site.memberType(this) matches site.memberType(sym)))
+ /** The non-private member of `site' whose type and name match the type of this symbol
+ */
+ final def matchingSymbol(site: Type): Symbol =
+ site.nonPrivateMember(name).filter(sym =>
+ !sym.isTerm || (site.memberType(this) matches site.memberType(sym)))
+
/** The symbol overridden by this symbol in given class `ofclazz' */
final def overriddenSymbol(ofclazz: Symbol): Symbol =
matchingSymbol(ofclazz, owner.thisType)
diff --git a/src/compiler/scala/tools/nsc/symtab/classfile/Pickler.scala b/src/compiler/scala/tools/nsc/symtab/classfile/Pickler.scala
index 145c86a6bd..f3f123cf1a 100644
--- a/src/compiler/scala/tools/nsc/symtab/classfile/Pickler.scala
+++ b/src/compiler/scala/tools/nsc/symtab/classfile/Pickler.scala
@@ -108,9 +108,17 @@ abstract class Pickler extends SubComponent {
if (sym.thisSym.tpe != sym.tpe)
putType(sym.typeOfThis);
putSymbol(sym.alias)
- if (!sym.children.isEmpty)
- putChildren(sym, sym.children.toList.sort((x, y) => x isLess y))
-
+ if (!sym.children.isEmpty) {
+ val (locals, globals) = sym.children.toList.partition(.isLocalClass)
+ val children =
+ if (locals.isEmpty) globals
+ else {
+ val localChildDummy = sym.newClass(sym.pos, nme.LOCALCHILD)
+ localChildDummy.setInfo(ClassInfoType(List(sym.tpe), EmptyScope, localChildDummy))
+ localChildDummy :: globals
+ }
+ putChildren(sym, children.sort((x, y) => x isLess y))
+ }
for (attr <- sym.attributes.reverse) {
if (attr.atp.symbol isNonBottomSubClass definitions.StaticAnnotationClass)
putAnnotation(sym, attr)
diff --git a/src/compiler/scala/tools/nsc/typechecker/Infer.scala b/src/compiler/scala/tools/nsc/typechecker/Infer.scala
index f119288d54..0cee1b1bba 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Infer.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Infer.scala
@@ -853,7 +853,8 @@ trait Infer {
tparam.variance != 0 || arg1 =:= arg2
} contains false)
}
- if (tp1.symbol.isClass && tp1.symbol.hasFlag(FINAL)) tp1 <:< tp2
+ if (tp1.symbol.isClass && tp1.symbol.hasFlag(FINAL))
+ tp1 <:< tp2 || isNumericValueClass(tp1.symbol) && isNumericValueClass(tp2.symbol)
else tp1.baseClasses forall (bc =>
tp2.closurePos(bc) < 0 || isConsistent(tp1.baseType(bc), tp2.baseType(bc)))
}
@@ -1167,34 +1168,36 @@ trait Infer {
* Otherwise, if there is no best alternative, error.
*/
def inferMethodAlternative(tree: Tree, undetparams: List[Symbol], argtpes: List[Type], pt: Type): unit = tree.tpe match {
- case OverloadedType(pre, alts) => tryTwice {
- if (settings.debug.value) log("infer method alt " + tree.symbol + " with alternatives " + (alts map pre.memberType) + ", argtpes = " + argtpes + ", pt = " + pt)
- val applicable = alts filter (alt => isApplicable(undetparams, pre.memberType(alt), argtpes, pt))
- def improves(sym1: Symbol, sym2: Symbol) = (
- sym2 == NoSymbol || sym2.isError ||
- specializes(pre.memberType(sym1), pre.memberType(sym2))
- )
- val best = ((NoSymbol: Symbol) /: applicable) ((best, alt) =>
- if (improves(alt, best)) alt else best)
- val competing = applicable dropWhile (alt => best == alt || improves(best, alt))
- if (best == NoSymbol) {
- if (pt == WildcardType) {
- errorTree(tree, applyErrorMsg(tree, " cannot be applied to ", argtpes, pt))
+ case OverloadedType(pre, alts) =>
+ tryTwice {
+ if (settings.debug.value) log("infer method alt " + tree.symbol + " with alternatives " + (alts map pre.memberType) + ", argtpes = " + argtpes + ", pt = " + pt)
+ val applicable = alts filter (alt => isApplicable(undetparams, pre.memberType(alt), argtpes, pt))
+ def improves(sym1: Symbol, sym2: Symbol) = (
+ sym2 == NoSymbol || sym2.isError ||
+ specializes(pre.memberType(sym1), pre.memberType(sym2))
+ )
+ val best = ((NoSymbol: Symbol) /: applicable) ((best, alt) =>
+ if (improves(alt, best)) alt else best)
+ val competing = applicable dropWhile (alt => best == alt || improves(best, alt))
+ if (best == NoSymbol) {
+ if (pt == WildcardType) {
+ errorTree(tree, applyErrorMsg(tree, " cannot be applied to ", argtpes, pt))
+ } else {
+ inferMethodAlternative(tree, undetparams, argtpes, WildcardType)
+ }
+ } else if (!competing.isEmpty) {
+ if (!(argtpes exists (.isErroneous)) && !pt.isErroneous)
+ context.ambiguousError(tree.pos, pre, best, competing.head,
+ "argument types " + argtpes.mkString("(", ",", ")") +
+ (if (pt == WildcardType) "" else " and expected result type " + pt))
+ setError(tree)
+ ()
} else {
- inferMethodAlternative(tree, undetparams, argtpes, WildcardType)
+ checkNotShadowed(tree.pos, pre, best, applicable)
+ tree.setSymbol(best).setType(pre.memberType(best))
}
- } else if (!competing.isEmpty) {
- if (!(argtpes exists (.isErroneous)) && !pt.isErroneous)
- context.ambiguousError(tree.pos, pre, best, competing.head,
- "argument types " + argtpes.mkString("(", ",", ")") +
- (if (pt == WildcardType) "" else " and expected result type " + pt))
- setError(tree)
- ()
- } else {
- checkNotShadowed(tree.pos, pre, best, applicable)
- tree.setSymbol(best).setType(pre.memberType(best))
}
- }
+ case _ =>
}
/** Try inference twice, once without views and once with views,
diff --git a/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala b/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala
index 8324aac2b0..a629f0c645 100644
--- a/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala
@@ -83,7 +83,9 @@ abstract class RefChecks extends InfoTransform {
* 1.8.2 M is of type []S, O is of type ()T and S <: T, or
* 1.8.3 M is of type ()S, O is of type []T and S <: T, or
* 2. Check that only abstract classes have deferred members
- * 3. Check that every member with an `override' modifier
+ * 3. Check that concrete classes do not have deferred definitions
+ * that are not implemented in a subclass.
+ * 4. Check that every member with an `override' modifier
* overrides some other member.
*/
private def checkAllOverrides(clazz: Symbol): unit = {
@@ -259,9 +261,26 @@ abstract class RefChecks extends InfoTransform {
" and overrides incomplete superclass member " + infoString(other)
else ""))
}
+ // 3. Check that concrete classes do not have deferred definitions
+ // that are not implemented in a subclass.
+ def checkNoAbstractDecls(bc: Symbol) {
+ for (val decl <- bc.info.decls.elements) {
+ if (decl hasFlag DEFERRED) {
+ val impl = decl.matchingSymbol(clazz.thisType)
+ if (impl == NoSymbol || (decl.owner isSubClass impl.owner)) {
+ abstractClassError(false, "there is a deferred declaration of "+infoString(decl)+
+ " which is not implemented in a subclass"+analyzer.varNotice(decl))
+ }
+ }
+ }
+ val parents = bc.info.parents
+ if (!parents.isEmpty && parents.head.symbol.hasFlag(ABSTRACT))
+ checkNoAbstractDecls(parents.head.symbol)
+ }
+ if (!(clazz hasFlag ABSTRACT)) checkNoAbstractDecls(clazz)
}
- // 3. Check that every defined member with an `override' modifier overrides some other member.
+ // 4. Check that every defined member with an `override' modifier overrides some other member.
for (val member <- clazz.info.decls.toList)
if ((member hasFlag (OVERRIDE | ABSOVERRIDE)) &&
(clazz.info.baseClasses.tail forall {
diff --git a/src/compiler/scala/tools/nsc/typechecker/Typers.scala b/src/compiler/scala/tools/nsc/typechecker/Typers.scala
index 980a0c51c3..f9f3fd2b67 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Typers.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Typers.scala
@@ -1620,17 +1620,20 @@ trait Typers requires Analyzer {
unapp),
List(arg))
}
- //Console.println("UNAPPLY2 "+fun+"/"+fun.tpe+" "+fun1untyped)
val fun1 = typed(fun1untyped)
if (fun1.tpe.isErroneous) setError(tree)
else {
val formals0 = unapplyTypeList(fun1.symbol, fun1.tpe)
val formals1 = formalTypes(formals0, args.length)
- val args1 = typedArgs(args, mode, formals0, formals1)
- if (!isFullyDefined(pt)) assert(false, tree+" ==> "+UnApply(fun1, args1)+", pt = "+pt)
- // restore old type (this will never work, but just pass typechecking)
- arg.tpe = oldArgType
- UnApply(fun1, args1) setPos tree.pos setType pt
+ if (formals1.length == args.length) {
+ val args1 = typedArgs(args, mode, formals0, formals1)
+ if (!isFullyDefined(pt)) assert(false, tree+" ==> "+UnApply(fun1, args1)+", pt = "+pt)
+ // restore old type (this will never work, but just pass typechecking)
+ arg.tpe = oldArgType
+ UnApply(fun1, args1) setPos tree.pos setType pt
+ } else {
+ errorTree(tree, "wrong number of arguments for "+treeSymTypeMsg(fun))
+ }
}
/* --- end unapply --- */