summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMartin Odersky <odersky@gmail.com>2006-04-25 14:01:59 +0000
committerMartin Odersky <odersky@gmail.com>2006-04-25 14:01:59 +0000
commit88cd71a283f25b20414b1a22b9fded83692ffc14 (patch)
tree921d9a72ae56ac70d11ba1a58ee274cb8808a60d
parent8e1da29a68f7d494a89a1922e3b30e39b245da63 (diff)
downloadscala-88cd71a283f25b20414b1a22b9fded83692ffc14.tar.gz
scala-88cd71a283f25b20414b1a22b9fded83692ffc14.tar.bz2
scala-88cd71a283f25b20414b1a22b9fded83692ffc14.zip
-rw-r--r--src/compiler/scala/tools/nsc/symtab/Types.scala8
-rw-r--r--src/compiler/scala/tools/nsc/transform/Mixin.scala2
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Namers.scala6
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/RefChecks.scala6
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Typers.scala17
-rw-r--r--test/pending/pos/bug572.scala33
-rw-r--r--test/pending/pos/bug573.scala43
-rwxr-xr-xtest/pending/pos/foo.scala3
-rwxr-xr-xtest/pending/pos/gosh.scala44
-rw-r--r--test/pending/pos/moors.scala12
-rwxr-xr-xtest/pending/run/exc.scala10
-rwxr-xr-xtest/pending/run/exc1.scala10
-rwxr-xr-xtest/pending/run/exc2.scala12
13 files changed, 197 insertions, 9 deletions
diff --git a/src/compiler/scala/tools/nsc/symtab/Types.scala b/src/compiler/scala/tools/nsc/symtab/Types.scala
index 428bdb3ab6..883a45b8a2 100644
--- a/src/compiler/scala/tools/nsc/symtab/Types.scala
+++ b/src/compiler/scala/tools/nsc/symtab/Types.scala
@@ -201,7 +201,11 @@ trait Types requires SymbolTable {
def memberType(sym: Symbol): Type = {
sym.tpe match {
case OverloadedType(pre, alts) =>
- assert(this =:= pre);
+ val pre1 = pre match {
+ case ClassInfoType(_, _, clazz) => clazz.tpe
+ case _ => pre
+ }
+ assert(this =:= pre1);
sym.tpe
case _ =>
//System.out.println("" + this + ".memberType(" + sym +":" + sym.tpe +")");//DEBUG
@@ -2035,7 +2039,7 @@ trait Types requires SymbolTable {
/** Make symbol `sym' a member of scope `tp.decls' where `thistp' is the narrowed
* owner type of the scope */
- private def addMember(thistp: Type, tp: Type, sym: Symbol): unit = {
+ def addMember(thistp: Type, tp: Type, sym: Symbol): unit = {
if (settings.debug.value) log("add member " + sym);//debug
if (!(thistp specializes sym)) {
if (sym.isTerm)
diff --git a/src/compiler/scala/tools/nsc/transform/Mixin.scala b/src/compiler/scala/tools/nsc/transform/Mixin.scala
index c7f9f775fd..e8f36bf785 100644
--- a/src/compiler/scala/tools/nsc/transform/Mixin.scala
+++ b/src/compiler/scala/tools/nsc/transform/Mixin.scala
@@ -260,7 +260,7 @@ abstract class Mixin extends InfoTransform {
private def addNewDefs(clazz: Symbol, stats: List[Tree]): List[Tree] = {
val newDefs = new ListBuffer[Tree];
def addDef(pos: int, tree: Tree): unit = {
- if (settings.debug.value) log("add new def to " + clazz + ": " + tree);
+ if (settings.debug.value) System.out.println("add new def to " + clazz + ": " + tree);
newDefs += localTyper.typed {
atPos(pos) {
tree
diff --git a/src/compiler/scala/tools/nsc/typechecker/Namers.scala b/src/compiler/scala/tools/nsc/typechecker/Namers.scala
index 6c42012d18..a74c7f20b9 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Namers.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Namers.scala
@@ -22,8 +22,8 @@ trait Namers requires Analyzer {
class DeSkolemizeMap(tparams: List[Symbol]) extends TypeMap {
def apply(tp: Type): Type = tp match {
case TypeRef(pre, sym, args) =>
- val tparam = sym.deSkolemize;
- mapOver(
+ val tparam = sym.deSkolemize;
+ mapOver(
if (tparam == sym || !(tparams contains tparam)) tp
else rawTypeRef(NoPrefix, tparam, args))
case SingleType(pre, sym) if (sym.isThisSkolem) =>
@@ -551,6 +551,8 @@ trait Namers requires Analyzer {
"\nit should be omitted for abstract members");
if (sym.hasFlag(OVERRIDE | ABSOVERRIDE) && sym.isClass)
context.error(sym.pos, "`override' modifier not allowed for classes");
+ if (sym.hasFlag(OVERRIDE | ABSOVERRIDE) && sym.isConstructor)
+ context.error(sym.pos, "`override' modifier not allowed for constructors");
if (sym.hasFlag(ABSOVERRIDE) && !sym.owner.isTrait)
context.error(sym.pos, "`abstract override' modifier only allowed for members of traits");
if (sym.info.symbol == FunctionClass(0) &&
diff --git a/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala b/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala
index e88545992c..ea640cc661 100644
--- a/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala
@@ -175,7 +175,9 @@ abstract class RefChecks extends InfoTransform {
} else if (!(other hasFlag DEFERRED) && !(member hasFlag (OVERRIDE | ABSOVERRIDE))) { // (1.3)
overrideError("needs `override' modifier");
} else if ((other hasFlag ABSOVERRIDE) && other.isIncompleteIn(clazz) && !(member hasFlag ABSOVERRIDE)) {
- overrideError("needs `abstract override' modifiers");
+ overrideError("needs `abstract override' modifiers")
+ } else if ((member hasFlag (OVERRIDE | ABSOVERRIDE)) && (other hasFlag ACCESSOR) && other.accessed.isVariable) {
+ overrideError("cannot override a mutable variable")
} else if (other.isStable) {
if (!member.isStable) // (1.4)
overrideError("needs to be an immutable value")
@@ -558,7 +560,7 @@ abstract class RefChecks extends InfoTransform {
case TypeTree() =>
new TypeTraverser {
- def traverse(tp: Type) = tp match {
+ def traverse(tp: Type): TypeTraverser = tp match {
case TypeRef(pre, sym, args) => checkBounds(sym.typeParams, args); this
case _ => this
}
diff --git a/src/compiler/scala/tools/nsc/typechecker/Typers.scala b/src/compiler/scala/tools/nsc/typechecker/Typers.scala
index 8b151063db..5a150c3dcd 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Typers.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Typers.scala
@@ -846,6 +846,19 @@ trait Typers requires Analyzer {
copy.LabelDef(ldef, ldef.name, ldef.params, rhs1) setType restpe
}
+ def anonymousClassRefinement(clazz: Symbol): Type = {
+ val tp = refinedType(clazz.info.parents, clazz.owner)
+ val thistp = tp.symbol.thisType
+ for (val sym <- clazz.info.decls.toList) {
+ if (!sym.hasFlag(PRIVATE) && !sym.isClass && !sym.isConstructor &&
+ tp.nonPrivateMember(sym.name).filter(other =>
+ !other.isTerm || (thistp.memberType(other) matches thistp.memberType(sym)))
+ != NoSymbol)
+ addMember(thistp, tp, sym)
+ }
+ tp
+ }
+
def typedBlock(block: Block, mode: int, pt: Type): Block = {
namer.enterSyms(block.stats)
block.stats foreach enterLabelDef
@@ -854,9 +867,9 @@ trait Typers requires Analyzer {
val block1 = copy.Block(block, stats1, expr1)
.setType(if (treeInfo.isPureExpr(block)) expr1.tpe else expr1.tpe.deconst)
if (isFullyDefined(pt)) block1
- else { //todo: correct?
+ else {
if (block1.tpe.symbol.isAnonymousClass)
- block1 setType intersectionType(block1.tpe.parents, block1.tpe.symbol.owner)
+ block1 setType anonymousClassRefinement(block1.tpe.symbol)
checkNoEscaping.locals(context.scope, pt, block1)
}
}
diff --git a/test/pending/pos/bug572.scala b/test/pending/pos/bug572.scala
new file mode 100644
index 0000000000..3a69cde4a6
--- /dev/null
+++ b/test/pending/pos/bug572.scala
@@ -0,0 +1,33 @@
+package lampion.collections;
+
+object DirX {
+ abstract class Dir {
+ def reverse : Dir;
+ }
+ object BEFORE extends Dir {
+ def reverse = AFTER;
+ }
+ object AFTER extends Dir {
+ def reverse = BEFORE;
+ }
+}
+import DirX._;
+abstract class Linked {
+ type Node <: Node0;
+
+ abstract class Node0 {
+ var next : Node = _;
+ var prev : Node = _;
+
+ def get(dir : Dir) = if (dir == BEFORE) prev; else next;
+ private def set(dir : Dir, node : Node) =
+ if (dir == BEFORE) prev = node; else next = node;
+
+ def link(dir : Dir, node : Node) = {
+ assert(get(dir) == null);
+ assert(node.get(dir.reverse) == null);
+ set(dir, node);
+ node.set(dir.reverse(), node);
+ }
+ }
+}
diff --git a/test/pending/pos/bug573.scala b/test/pending/pos/bug573.scala
new file mode 100644
index 0000000000..b1b4f75098
--- /dev/null
+++ b/test/pending/pos/bug573.scala
@@ -0,0 +1,43 @@
+package lampion.collections;
+
+object DirX {
+ abstract class Dir {
+ def reverse : Dir;
+ }
+ object BEFORE extends Dir {
+ def reverse = AFTER;
+ }
+ object AFTER extends Dir {
+ def reverse = BEFORE;
+ }
+}
+
+import DirX._;
+
+abstract class Linked {
+ type Node <: Node0;
+
+ abstract class Node0 {
+ var next : Node = _;
+ var prev : Node = _;
+
+ def self : Node;
+
+ def get(dir : Dir) = if (dir == BEFORE) prev; else next;
+ private def set(dir : Dir, node : Node) =
+ if (dir == BEFORE) prev = node; else next = node;
+
+ def link(dir : Dir, node : Node) = {
+ assert(get(dir) == null);
+ assert(node.get(dir.reverse) == null);
+ set(dir, node);
+ node.set(dir.reverse, self);
+ }
+
+
+ def end(dir : Dir) : Node = {
+ if (get(dir) == null) this;
+ else get(dir).end(dir);
+ }
+ }
+}
diff --git a/test/pending/pos/foo.scala b/test/pending/pos/foo.scala
new file mode 100755
index 0000000000..8b45addbd5
--- /dev/null
+++ b/test/pending/pos/foo.scala
@@ -0,0 +1,3 @@
+object foo {
+ var x: String
+}
diff --git a/test/pending/pos/gosh.scala b/test/pending/pos/gosh.scala
new file mode 100755
index 0000000000..c4cd3df80b
--- /dev/null
+++ b/test/pending/pos/gosh.scala
@@ -0,0 +1,44 @@
+object ShapeTest extends Application {
+
+ class Point(x : int, y : int) {
+ override def toString() = "[" + x + "," + y + "]"
+ }
+
+ abstract class Shape {
+ def draw() : unit
+ }
+
+ class Line(s : Point, e : Point) extends Shape {
+ def draw() : unit = { Console.println("draw line " + s + "," + e) }
+ }
+
+ abstract class Foo {
+ type T <: Object
+
+ def show(o : T) : unit
+ def print() : unit = {Console.println("in Foo")}
+ }
+
+ abstract class ShapeFoo extends Foo {
+ type T <: Shape
+ def show(o : T) : unit = { o.draw() }
+ override def print() : unit = {Console.println("in ShapeFoo")}
+ }
+
+ class LineFoo extends ShapeFoo {
+ type T = Line
+ override def print() : unit = {Console.println("in LineFoo")}
+ }
+
+ val p1 = new Point(1,4)
+ val p2 = new Point(12, 28)
+
+ val l1 = new Line(p1, p2)
+
+
+ val l = new ShapeFoo{ // ** //
+ type T = Line // ** //
+ override def print() : unit = {Console.println("in LineFoo")} // ** //
+ }
+ l.show(l1) // ** //
+}
diff --git a/test/pending/pos/moors.scala b/test/pending/pos/moors.scala
new file mode 100644
index 0000000000..4f7346f57f
--- /dev/null
+++ b/test/pending/pos/moors.scala
@@ -0,0 +1,12 @@
+object Test {
+
+ implicit def foo2bar(foo :Foo) :Bar = foo.bar
+
+ class Foo(val bar :Bar) {
+ def testCoercion ={ val a: this.type = this; a.baz /* here, foo2bar is inferred by the compiler, as expected */}
+ def testCoercionThis = baz // --> error: not found: value baz
+ def testCoercionThis = (this: Foo).baz // --> error: value baz is not a member of Foo
+ }
+
+ class Bar { def baz = System.out.println("baz")}
+}
diff --git a/test/pending/run/exc.scala b/test/pending/run/exc.scala
new file mode 100755
index 0000000000..26f80412c0
--- /dev/null
+++ b/test/pending/run/exc.scala
@@ -0,0 +1,10 @@
+object exc1 extends Application {
+ def foo() = {
+ while (true) {
+ try {
+ } catch {
+ case ex: Exception =>
+ }
+ }
+ }
+}
diff --git a/test/pending/run/exc1.scala b/test/pending/run/exc1.scala
new file mode 100755
index 0000000000..48fc084dda
--- /dev/null
+++ b/test/pending/run/exc1.scala
@@ -0,0 +1,10 @@
+object exc1 extends Application {
+ def foo(): unit = {
+ while (true) {
+ try {
+ } catch {
+ case ex: Exception =>
+ }
+ }
+ }
+}
diff --git a/test/pending/run/exc2.scala b/test/pending/run/exc2.scala
new file mode 100755
index 0000000000..8adf9b4a37
--- /dev/null
+++ b/test/pending/run/exc2.scala
@@ -0,0 +1,12 @@
+object exc2 extends Application {
+ def foo() = {
+ while (true) {
+ try {
+ Console.println("foo")
+ } catch {
+ case ex: Exception =>
+ Console.println("bar")
+ }
+ }
+ }
+}