summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/compiler/scala/tools/nsc/Global.scala5
-rw-r--r--src/compiler/scala/tools/nsc/Main.scala2
-rw-r--r--src/compiler/scala/tools/nsc/symtab/StdNames.scala1
-rw-r--r--src/compiler/scala/tools/nsc/symtab/Types.scala23
-rw-r--r--src/compiler/scala/tools/nsc/transform/Erasure.scala4
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/SyntheticMethods.scala17
-rw-r--r--test/files/neg/bug391.check16
-rw-r--r--test/files/neg/bug391.scala6
-rw-r--r--test/files/neg/bug588.check13
-rwxr-xr-xtest/files/neg/bug588.scala15
-rw-r--r--test/files/pos/bug422.scala17
-rw-r--r--test/files/run/bug428.check8
-rw-r--r--test/files/run/bug428.scala37
-rw-r--r--test/pending/neg/bug421.scala9
-rwxr-xr-xtest/pending/run/bug551.scala5
15 files changed, 171 insertions, 7 deletions
diff --git a/src/compiler/scala/tools/nsc/Global.scala b/src/compiler/scala/tools/nsc/Global.scala
index 4fd5404a91..da135674a1 100644
--- a/src/compiler/scala/tools/nsc/Global.scala
+++ b/src/compiler/scala/tools/nsc/Global.scala
@@ -343,6 +343,11 @@ class Global(val settings: Settings, val reporter: Reporter) extends SymbolTable
genJVM,
sampleTransform);
+ protected def insertBefore(c: SubComponent, cs: List[SubComponent], before: SubComponent): List[SubComponent] = cs match {
+ case List() => List(c)
+ case c1 :: cs1 => if (c1 == before) c :: cs else c1 :: insertBefore(c, cs1, before)
+ }
+
private var curRun: Run = NoRun;
override def currentRun: Run = curRun;
diff --git a/src/compiler/scala/tools/nsc/Main.scala b/src/compiler/scala/tools/nsc/Main.scala
index ff23178c4a..41345083e1 100644
--- a/src/compiler/scala/tools/nsc/Main.scala
+++ b/src/compiler/scala/tools/nsc/Main.scala
@@ -24,7 +24,7 @@ object Main extends Object with EvalLoop {
val versionMsg = PRODUCT + " " + VERSION + " -- " + COPYRIGHT
val prompt = "\nnsc> "
- private var reporter: ConsoleReporter = _
+ var reporter: ConsoleReporter = _
def error(msg: String): unit =
reporter.error(new Position(PRODUCT),
diff --git a/src/compiler/scala/tools/nsc/symtab/StdNames.scala b/src/compiler/scala/tools/nsc/symtab/StdNames.scala
index e841813272..1d64005f58 100644
--- a/src/compiler/scala/tools/nsc/symtab/StdNames.scala
+++ b/src/compiler/scala/tools/nsc/symtab/StdNames.scala
@@ -234,6 +234,7 @@ trait StdNames requires SymbolTable {
val elements = newTermName("elements");
val eq = newTermName("eq");
val equals_ = newTermName("equals");
+ val _equals = newTermName("_equals");
val ex = newTermName("ex");
val fail = newTermName("fail");
val false_ = newTermName("false");
diff --git a/src/compiler/scala/tools/nsc/symtab/Types.scala b/src/compiler/scala/tools/nsc/symtab/Types.scala
index 2702a42057..0b3c16e56d 100644
--- a/src/compiler/scala/tools/nsc/symtab/Types.scala
+++ b/src/compiler/scala/tools/nsc/symtab/Types.scala
@@ -979,6 +979,15 @@ trait Types requires SymbolTable {
} else sym
}
+ /** Convert a `super' prefix to a this-type if `sym' is abstract or final */
+ private def removeSuper(tp: Type, sym: Symbol): Type = tp match {
+ case SuperType(thistp, _) =>
+ if (sym.isFinal || sym.hasFlag(DEFERRED)) thistp
+ else tp
+ case _ =>
+ tp
+ }
+
/** The canonical creator for this-types */
def ThisType(sym: Symbol): Type =
if (phase.erasedTypes) sym.tpe else unique(new ThisType(sym) with UniqueType);
@@ -989,8 +998,12 @@ trait Types requires SymbolTable {
sym.tpe.resultType
else if (checkMalformedSwitch && !pre.isStable && !pre.isError)
throw new MalformedType(pre, sym.name.toString())
- else
- unique(new SingleType(pre, rebind(pre, sym)) with UniqueType)
+ else {
+ var sym1 = rebind(pre, sym)
+ val pre1 = removeSuper(pre, sym1)
+ if (pre1 ne pre) sym1 = rebind(pre1, sym1)
+ unique(new SingleType(pre1, sym1) with UniqueType)
+ }
}
/** The canonical creator for super-types */
@@ -1024,7 +1037,7 @@ trait Types requires SymbolTable {
/** The canonical creator for typerefs */
def typeRef(pre: Type, sym: Symbol, args: List[Type]): Type = {
- val sym1 = if (sym.isAbstractType) rebind(pre, sym) else sym;
+ var sym1 = if (sym.isAbstractType) rebind(pre, sym) else sym;
if (checkMalformedSwitch && sym1.isAbstractType && !pre.isStable && !pre.isError)
throw new MalformedType(pre, sym.nameString);
// if (sym1.hasFlag(LOCKED))
@@ -1039,7 +1052,9 @@ trait Types requires SymbolTable {
sym1.resetFlag(LOCKED);
result
} else {
- rawTypeRef(pre, sym1, args)
+ val pre1 = removeSuper(pre, sym1)
+ if ((pre1 ne pre) && sym1.isAbstractType) sym1 = rebind(pre1, sym1)
+ rawTypeRef(pre1, sym1, args)
}
}
diff --git a/src/compiler/scala/tools/nsc/transform/Erasure.scala b/src/compiler/scala/tools/nsc/transform/Erasure.scala
index 13d39c70e5..bb8ebb8cd4 100644
--- a/src/compiler/scala/tools/nsc/transform/Erasure.scala
+++ b/src/compiler/scala/tools/nsc/transform/Erasure.scala
@@ -392,7 +392,7 @@ abstract class Erasure extends AddInterfaces with typechecker.Analyzer {
* but their erased types are the same.
*/
private def checkNoDoubleDefs(root: Symbol): unit = {
- def doubleDefError(sym1: Symbol, sym2: Symbol) = {
+ def doubleDefError(sym1: Symbol, sym2: Symbol): unit = {
val tpe1 = atPhase(currentRun.refchecksPhase.next)(root.thisType.memberType(sym1));
val tpe2 = atPhase(currentRun.refchecksPhase.next)(root.thisType.memberType(sym2));
unit.error(
@@ -406,8 +406,10 @@ abstract class Erasure extends AddInterfaces with typechecker.Analyzer {
(if (sym2.owner == root) " at line " + Position.line(unit.source, sym2.pos) else sym2.locationString) +
"\nhave same type" +
(if (tpe1 =:= tpe2) "" else " after erasure: " + atPhase(phase.next)(sym1.tpe)))
+ sym2.setInfo(ErrorType)
}
+
val decls = root.info.decls;
var e = decls.elems;
while (e != null) {
diff --git a/src/compiler/scala/tools/nsc/typechecker/SyntheticMethods.scala b/src/compiler/scala/tools/nsc/typechecker/SyntheticMethods.scala
index 6b11c5818f..7f06291c7c 100644
--- a/src/compiler/scala/tools/nsc/typechecker/SyntheticMethods.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/SyntheticMethods.scala
@@ -86,6 +86,21 @@ trait SyntheticMethods requires Analyzer {
Apply(gen.mkAttributedRef(target), This(clazz) :: (vparamss.head map Ident))));
}
+ def equalsMethod: Tree = {
+ val target = getMember(ScalaRunTimeModule, nme._equals);
+ val method = syntheticMethod(
+ nme.equals_, 0, MethodType(target.tpe.paramTypes.tail, target.tpe.resultType));
+ typed(DefDef(method, vparamss =>
+ Apply(
+ Select(
+ TypeApply(
+ Select(Ident(vparamss.head.head), Any_isInstanceOf),
+ List(TypeTree(clazz.tpe))),
+ Boolean_and),
+ List(
+ Apply(gen.mkAttributedRef(target), This(clazz) :: (vparamss.head map Ident))))));
+ }
+
def isSerializable(clazz: Symbol): Boolean =
!clazz.getAttributes(definitions.SerializableAttr).isEmpty
@@ -169,7 +184,7 @@ trait SyntheticMethods requires Analyzer {
} else {
if (!hasImplementation(nme.hashCode_)) ts += forwardingMethod(nme.hashCode_);
if (!hasImplementation(nme.toString_)) ts += forwardingMethod(nme.toString_);
- if (!hasImplementation(nme.equals_)) ts += forwardingMethod(nme.equals_);
+ if (!hasImplementation(nme.equals_)) ts += equalsMethod //forwardingMethod(nme.equals_);
}
if (!hasImplementation(nme.caseElement)) ts += caseElementMethod;
if (!hasImplementation(nme.caseArity)) ts += caseArityMethod;
diff --git a/test/files/neg/bug391.check b/test/files/neg/bug391.check
new file mode 100644
index 0000000000..57b3f5d565
--- /dev/null
+++ b/test/files/neg/bug391.check
@@ -0,0 +1,16 @@
+bug391.scala:2 error: identifier expected but 'def' found.
+ def fun1(def x: Int): Int = x; // the "def x" is illegal
+ ^
+bug391.scala:3 error: ':' expected but '}' found.
+ def fun2(val x: Int): Int = x; // the "val x" is illegal
+ ^
+bug391.scala:4 error: illegal start of simple expression
+}
+^
+bug391.scala:6 error: identifier expected but 'def' found.
+class E(def x: Int); // the "def x" is illegal
+ ^
+bug391.scala:6 error: ':' expected but eof found.
+class E(def x: Int); // the "def x" is illegal
+ ^
+5 errors found
diff --git a/test/files/neg/bug391.scala b/test/files/neg/bug391.scala
new file mode 100644
index 0000000000..08c083baa5
--- /dev/null
+++ b/test/files/neg/bug391.scala
@@ -0,0 +1,6 @@
+trait C {
+ def fun1(def x: Int): Int = x; // the "def x" is illegal
+ def fun2(val x: Int): Int = x; // the "val x" is illegal
+}
+
+class E(def x: Int); // the "def x" is illegal
diff --git a/test/files/neg/bug588.check b/test/files/neg/bug588.check
new file mode 100644
index 0000000000..02a9b9c482
--- /dev/null
+++ b/test/files/neg/bug588.check
@@ -0,0 +1,13 @@
+/home/odersky/scala/test/files/pos/bug588.scala:3 error: double definition:
+method visit:((scala.Int) => java.lang.String)scala.Boolean and
+method visit:((scala.Int) => scala.Unit)scala.Boolean at line 2
+have same type after erasure: (scala.Function1)scala.Boolean
+ def visit(f: int => String): boolean
+ ^
+/home/odersky/scala/test/files/pos/bug588.scala:10 error: double definition:
+method f:(Test.this.TypeB)scala.Unit and
+method f:(Test.this.TypeA)scala.Unit at line 9
+have same type after erasure: (Test#TraitA)scala.Unit
+ def f(brac : TypeB) : Unit;
+ ^
+two errors found
diff --git a/test/files/neg/bug588.scala b/test/files/neg/bug588.scala
new file mode 100755
index 0000000000..bbb79ed79e
--- /dev/null
+++ b/test/files/neg/bug588.scala
@@ -0,0 +1,15 @@
+abstract class Test0 {
+ def visit(f: int => unit): boolean
+ def visit(f: int => String): boolean
+}
+trait Test {
+ type TypeA <: TraitA;
+ type TypeB <: TypeA with TraitB;
+
+ def f(node : TypeA) : Unit;
+ def f(brac : TypeB) : Unit;
+
+ trait TraitA;
+ trait TraitB;
+
+}
diff --git a/test/files/pos/bug422.scala b/test/files/pos/bug422.scala
new file mode 100644
index 0000000000..cb3ba279d4
--- /dev/null
+++ b/test/files/pos/bug422.scala
@@ -0,0 +1,17 @@
+import scala.util.regexp.WordExp;
+import scala.util.automata.WordBerrySethi;
+
+object BoolWordExp extends WordExp {
+ type _labelT = MyLabels;
+ type _regexpT = RegExp;
+ abstract class MyLabels extends Label ;
+ case class MyLabel(c:Char) extends MyLabels;
+}
+
+object MyTranslator extends WordBerrySethi {
+ override val lang = BoolWordExp;
+ import lang._;
+ override protected def seenLabel( r:RegExp, i:Int, label: _labelT ): Unit = {
+ super.seenLabel(r,i,label)
+ }
+}
diff --git a/test/files/run/bug428.check b/test/files/run/bug428.check
new file mode 100644
index 0000000000..21bef2f8d3
--- /dev/null
+++ b/test/files/run/bug428.check
@@ -0,0 +1,8 @@
+Foo 1: a = 0, b = 0, x = 0, y = 0
+Foo 2: a = 2, b = 0, x = 0, y = 0
+Foo 3: a = 2, b = 3, x = 0, y = 0
+Foo 4: a = 2, b = 3, x = 0, y = 0
+Foo 5: a = 2, b = 3, x = 0, y = 0
+Bar 1: a = 2, b = 3, x = 0, y = 0
+Bar 2: a = 2, b = 3, x = 5, y = 0
+Bar 3: a = 2, b = 3, x = 5, y = 7
diff --git a/test/files/run/bug428.scala b/test/files/run/bug428.scala
new file mode 100644
index 0000000000..34d99efd1f
--- /dev/null
+++ b/test/files/run/bug428.scala
@@ -0,0 +1,37 @@
+object Test {
+
+ abstract class Foo(_a: Int, _b: Int) {
+
+ Console.println("Foo 1: " + this);
+ val a: Int = _a;
+ Console.println("Foo 2: " + this);
+ val b: Int = { fun(); _b }
+ Console.println("Foo 3: " + this);
+ val x: Int;
+ Console.println("Foo 4: " + this);
+ val y: Int;
+ Console.println("Foo 5: " + this);
+
+
+ def fun(): Unit = ();
+
+ override def toString(): String =
+ "a = " + a + ", b = " + b + ", x = " + x + ", y = " + y;
+
+ }
+
+ class Bar(_a: Int, _b: Int, _x: Int, _y: Int) extends Foo(_a, _b) {
+
+ Console.println("Bar 1: " + this);
+ val x: Int = _x;
+ Console.println("Bar 2: " + this);
+ val y: Int = { fun(); _y }
+ Console.println("Bar 3: " + this);
+
+ }
+
+ def main (args: Array[String]): Unit = {
+ new Bar(2,3,5,7);
+ }
+
+}
diff --git a/test/pending/neg/bug421.scala b/test/pending/neg/bug421.scala
new file mode 100644
index 0000000000..bf7346f01a
--- /dev/null
+++ b/test/pending/neg/bug421.scala
@@ -0,0 +1,9 @@
+object foo {
+ case class Bar(a:String, b:Object, c:String*);
+
+
+ Bar("foo","meets","bar") match {
+ case Bar("foo",_*) => error("huh?");
+ }
+
+}
diff --git a/test/pending/run/bug551.scala b/test/pending/run/bug551.scala
new file mode 100755
index 0000000000..ffa36d7cb0
--- /dev/null
+++ b/test/pending/run/bug551.scala
@@ -0,0 +1,5 @@
+case class A(x: int)
+class B(x: int) extends A(x)
+object Test extends Application {
+ Console.println(A(1) == new B(1))
+}