summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMartin Odersky <odersky@gmail.com>2008-05-21 17:32:29 +0000
committerMartin Odersky <odersky@gmail.com>2008-05-21 17:32:29 +0000
commit96b80791737efd952383aba56ba69440e861647d (patch)
tree6df772e7a2d73ef0f934a18733486e06447d96c9
parentb7efa99768e14c03df810b129f979ba61aba8e87 (diff)
downloadscala-96b80791737efd952383aba56ba69440e861647d.tar.gz
scala-96b80791737efd952383aba56ba69440e861647d.tar.bz2
scala-96b80791737efd952383aba56ba69440e861647d.zip
added tests; fixed #903; made Predef.Map covari...
added tests; fixed #903; made Predef.Map covariant in second parameter.
-rw-r--r--src/compiler/scala/tools/nsc/ast/parser/Parsers.scala10
-rw-r--r--src/compiler/scala/tools/nsc/symtab/StdNames.scala20
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Typers.scala5
-rw-r--r--src/library/scala/Predef.scala2
-rw-r--r--test/files/neg/t0903.check7
-rw-r--r--test/files/neg/t0903.scala5
-rw-r--r--test/files/pos/t0786.scala29
-rw-r--r--test/files/pos/t0904.scala17
-rw-r--r--test/files/run/t0677.scala6
9 files changed, 90 insertions, 11 deletions
diff --git a/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala b/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala
index b6da9f9b1d..340f403f9f 100644
--- a/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala
+++ b/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala
@@ -446,15 +446,11 @@ trait Parsers extends NewScanners with MarkupParsers {
if (operator eq nme.ERROR) -1
else {
val firstCh = operator(0)
- if (operator(operator.length - 1) == '=' &&
- firstCh != '<' &&
- firstCh != '>' &&
- firstCh != '=' &&
- firstCh != '!')
- 0
- else if (((firstCh >= 'A') && (firstCh <= 'Z')) ||
+ if (((firstCh >= 'A') && (firstCh <= 'Z')) ||
((firstCh >= 'a') && (firstCh <= 'z')))
1
+ else if (nme.isOpAssignmentName(operator))
+ 0
else
firstCh match {
case '|' => 2
diff --git a/src/compiler/scala/tools/nsc/symtab/StdNames.scala b/src/compiler/scala/tools/nsc/symtab/StdNames.scala
index 824323f20a..7ddc641f6f 100644
--- a/src/compiler/scala/tools/nsc/symtab/StdNames.scala
+++ b/src/compiler/scala/tools/nsc/symtab/StdNames.scala
@@ -97,7 +97,19 @@ trait StdNames {
def isSetterName(name: Name) = name.endsWith(SETTER_SUFFIX)
def isLocalDummyName(name: Name) = name.startsWith(LOCALDUMMY_PREFIX)
def isOpAssignmentName(name: Name) =
- name.endsWith(nme.EQL) && name != nme.EQ && !name.endsWith(nme.USCOREEQL)
+ name(name.length - 1) == '=' &&
+ isOperatorCharacter(name(0)) &&
+ name != EQraw && name != NEraw && name != LEraw && name != GEraw
+
+ def isOperatorCharacter(c: Char) = c match {
+ case '~' | '!' | '@' | '#' | '%' |
+ '^' | '*' | '+' | '-' | '<' |
+ '>' | '?' | ':' | '=' | '&' |
+ '|' | '\\'| '/' => true
+ case _ =>
+ val chtp = Character.getType(c)
+ chtp == Character.MATH_SYMBOL || chtp == Character.OTHER_SYMBOL
+ }
/** If `name' is an expandedName, the original name. Otherwise `name' itself.
* @see Symbol.expandedName
@@ -373,6 +385,12 @@ trait StdNames {
val UNARY_- = encode("unary_-")
val UNARY_! = encode("unary_!")
+ // unencoded comparisons
+ val EQraw = newTermName("==")
+ val NEraw = newTermName("!=")
+ val LEraw = newTermName("<=")
+ val GEraw = newTermName(">=")
+
// value-conversion methods
val toByte = newTermName("toByte")
val toShort = newTermName("toShort")
diff --git a/src/compiler/scala/tools/nsc/typechecker/Typers.scala b/src/compiler/scala/tools/nsc/typechecker/Typers.scala
index eb12867ea9..71a6ceeb34 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Typers.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Typers.scala
@@ -2595,12 +2595,13 @@ trait Typers { self: Analyzer =>
case ex: TypeError =>
fun match {
case Select(qual, name)
- if (mode & PATTERNmode) == 0 && nme.isOpAssignmentName(name) =>
+ if (mode & PATTERNmode) == 0 && nme.isOpAssignmentName(name.decode) =>
val qual1 = typedQualifier(qual)
if (treeInfo.isVariableOrGetter(qual1)) {
convertToAssignment(fun, qual1, name, args, ex)
} else {
- reportTypeError(fun.pos, ex)
+ if (qual1.symbol.isValue) error(tree.pos, "reassignment to val")
+ else reportTypeError(fun.pos, ex)
setError(tree)
}
case _ =>
diff --git a/src/library/scala/Predef.scala b/src/library/scala/Predef.scala
index 39d71c3d94..4567f039fe 100644
--- a/src/library/scala/Predef.scala
+++ b/src/library/scala/Predef.scala
@@ -65,7 +65,7 @@ object Predef {
type Function[-A, +B] = Function1[A, B]
- type Map[A, B] = collection.immutable.Map[A, B]
+ type Map[A, +B] = collection.immutable.Map[A, B]
type Set[A] = collection.immutable.Set[A]
val Map = collection.immutable.Map
diff --git a/test/files/neg/t0903.check b/test/files/neg/t0903.check
new file mode 100644
index 0000000000..db4cd94d2c
--- /dev/null
+++ b/test/files/neg/t0903.check
@@ -0,0 +1,7 @@
+t0903.scala:3: error: reassignment to val
+ x += 1
+ ^
+t0903.scala:4: error: reassignment to val
+ x = 2
+ ^
+two errors found
diff --git a/test/files/neg/t0903.scala b/test/files/neg/t0903.scala
new file mode 100644
index 0000000000..cf8abce97a
--- /dev/null
+++ b/test/files/neg/t0903.scala
@@ -0,0 +1,5 @@
+object Test {
+ val x = 1
+ x += 1
+ x = 2
+}
diff --git a/test/files/pos/t0786.scala b/test/files/pos/t0786.scala
new file mode 100644
index 0000000000..d23cdb741b
--- /dev/null
+++ b/test/files/pos/t0786.scala
@@ -0,0 +1,29 @@
+object ImplicitProblem {
+ class M[T]
+
+ def nullval[T] = null.asInstanceOf[T];
+
+ trait Rep[T] {
+ def eval: int
+ }
+
+ implicit def toRep0(n: int) = new Rep[int] {
+ def eval = 0
+ }
+
+ implicit def toRepN[T](n: M[T])(implicit f: T => Rep[T]) = new Rep[M[T]] {
+ def eval = f(nullval[T]).eval + 1
+ }
+
+ def depth[T <% Rep[T]](n: T) = n.eval
+
+ def main(args: Array[String]) {
+ println(depth(nullval[M[int]])) // (1) this works
+ println(nullval[M[int]].eval) // (2) this works
+
+ type m = M[int]
+ println(depth(nullval[m])) // (3) this doesn't compile on 2.7.RC1
+ println(nullval[m].eval) // (4) this works
+ }
+
+}
diff --git a/test/files/pos/t0904.scala b/test/files/pos/t0904.scala
new file mode 100644
index 0000000000..28ad30fc2d
--- /dev/null
+++ b/test/files/pos/t0904.scala
@@ -0,0 +1,17 @@
+trait A {
+ def apply(x: Int): Int
+ def update(x: Int, y: Int): Unit
+}
+
+trait B extends A
+
+abstract class Foo {
+ val a: A = null
+ val b: B = null
+
+ a(0) = 1
+ b(0) = 1
+
+ a(0) += 1
+ b(0) += 1 // this one does not type check.
+}
diff --git a/test/files/run/t0677.scala b/test/files/run/t0677.scala
new file mode 100644
index 0000000000..7978e3d142
--- /dev/null
+++ b/test/files/run/t0677.scala
@@ -0,0 +1,6 @@
+object Test extends Application {
+ class X[T] { val a = new Array[Array[T]](3,4) }
+ val x = new X[String]
+ x.a(1)(2) = "hello"
+ assert(x.a(1)(2) == "hello")
+}