summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMartin Odersky <odersky@gmail.com>2007-03-13 15:19:42 +0000
committerMartin Odersky <odersky@gmail.com>2007-03-13 15:19:42 +0000
commit0eb18771918f5fd7659ad747126e97452c41c748 (patch)
treedab8e5556a917585027cacfdc0d18e73b983b38e
parentbc89afad4f7b7516b16037685a3b70a862858596 (diff)
downloadscala-0eb18771918f5fd7659ad747126e97452c41c748.tar.gz
scala-0eb18771918f5fd7659ad747126e97452c41c748.tar.bz2
scala-0eb18771918f5fd7659ad747126e97452c41c748.zip
fixed bug 1000 and david pollaks problem wrt tu...
fixed bug 1000 and david pollaks problem wrt tupling
-rw-r--r--src/compiler/scala/tools/nsc/symtab/Types.scala31
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Typers.scala6
-rw-r--r--test/files/neg/bug910.check6
-rw-r--r--test/files/neg/bug910.scala7
-rw-r--r--test/files/neg/bug987.check9
-rw-r--r--test/files/neg/bug987.scala25
-rw-r--r--test/files/run/bug995.check1
-rw-r--r--test/files/run/bug995.scala12
8 files changed, 83 insertions, 14 deletions
diff --git a/src/compiler/scala/tools/nsc/symtab/Types.scala b/src/compiler/scala/tools/nsc/symtab/Types.scala
index 546d650ce4..6bb3951eb6 100644
--- a/src/compiler/scala/tools/nsc/symtab/Types.scala
+++ b/src/compiler/scala/tools/nsc/symtab/Types.scala
@@ -303,7 +303,7 @@ trait Types requires SymbolTable {
* - Or phase.erasedTypes is false and both types are neither method nor
* poly types.
*/
- def matches(that: Type): boolean = matchesType(this, that)
+ def matches(that: Type): boolean = matchesType(this, that, !phase.erasedTypes)
/** The shortest sorted upwards closed array of types that contains
* this type as first element.
@@ -447,7 +447,7 @@ trait Types requires SymbolTable {
member.owner != sym.owner &&
!sym.hasFlag(PRIVATE) && {
if (self eq null) self = this.narrow;
- (self.memberType(member) matches self.memberType(sym))
+ matchesType(self.memberType(member), self.memberType(sym), true)
})) {
members = newScope(List(member, sym))
}
@@ -458,7 +458,7 @@ trait Types requires SymbolTable {
prevEntry.sym.owner != sym.owner &&
!sym.hasFlag(PRIVATE) && {
if (self eq null) self = this.narrow;
- (self.memberType(prevEntry.sym) matches self.memberType(sym))
+ matchesType(self.memberType(prevEntry.sym), self.memberType(sym), true)
})) {
prevEntry = members lookupNextEntry prevEntry
}
@@ -2294,23 +2294,28 @@ trait Types requires SymbolTable {
}
/** A function implementing <code>tp1</code> matches <code>tp2</code> */
- private def matchesType(tp1: Type, tp2: Type): boolean = (tp1, tp2) match {
+ private def matchesType(tp1: Type, tp2: Type, alwaysMatchSimple: boolean): boolean = (tp1, tp2) match {
case (MethodType(pts1, res1), MethodType(pts2, res2)) =>
- (matchingParams(pts1, pts2, tp2.isInstanceOf[JavaMethodType]) && (res1 matches res2) &&
- tp1.isInstanceOf[ImplicitMethodType] == tp2.isInstanceOf[ImplicitMethodType])
+ matchingParams(pts1, pts2, tp2.isInstanceOf[JavaMethodType]) &&
+ matchesType(res1, res2, alwaysMatchSimple) &&
+ tp1.isInstanceOf[ImplicitMethodType] == tp2.isInstanceOf[ImplicitMethodType]
case (PolyType(tparams1, res1), PolyType(tparams2, res2)) =>
- (tparams1.length == tparams2.length &&
- (res1 matches res2.substSym(tparams2, tparams1)))
- case (PolyType(List(), rtp1), MethodType(List(), rtp2)) => matchesType(rtp1, rtp2)
- case (MethodType(List(), rtp1), PolyType(List(), rtp2)) => matchesType(rtp1, rtp2)
- case (PolyType(List(), rtp1), _) => matchesType(rtp1, tp2)
- case (_, PolyType(List(), rtp2)) => matchesType(tp1, rtp2)
+ tparams1.length == tparams2.length &&
+ matchesType(res1, res2.substSym(tparams2, tparams1), alwaysMatchSimple)
+ case (PolyType(List(), rtp1), MethodType(List(), rtp2)) =>
+ matchesType(rtp1, rtp2, alwaysMatchSimple)
+ case (MethodType(List(), rtp1), PolyType(List(), rtp2)) =>
+ matchesType(rtp1, rtp2, alwaysMatchSimple)
+ case (PolyType(List(), rtp1), _) =>
+ matchesType(rtp1, tp2, alwaysMatchSimple)
+ case (_, PolyType(List(), rtp2)) =>
+ matchesType(tp1, rtp2, alwaysMatchSimple)
case (MethodType(_, _), _) => false
case (PolyType(_, _), _) => false
case (_, MethodType(_, _)) => false
case (_, PolyType(_, _)) => false
case _ =>
- !phase.erasedTypes || tp1 =:= tp2
+ alwaysMatchSimple || tp1 =:= tp2
}
/** Are <code>tps1</code> and <code>tps2</code> lists of pairwise equivalent types? */
diff --git a/src/compiler/scala/tools/nsc/typechecker/Typers.scala b/src/compiler/scala/tools/nsc/typechecker/Typers.scala
index 431d21f5f8..f8b8b423d2 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Typers.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Typers.scala
@@ -1411,7 +1411,11 @@ trait Typers requires Analyzer {
// preadapt symbol to number of arguments given
val argtypes = args map (arg => AllClass.tpe)
val pre = fun.symbol.tpe.prefix
- val sym = fun.symbol filter (alt => isApplicable(context.undetparams, pre.memberType(alt), argtypes, pt))
+ val sym = fun.symbol filter { alt =>
+ isApplicable(context.undetparams, pre.memberType(alt), argtypes, pt) &&
+ // eliminate functions that would result from tupling transforms
+ formalTypes(alt.tpe.paramTypes, argtypes.length).length == argtypes.length
+ }
if (sym != NoSymbol)
fun = adapt(fun setSymbol sym setType pre.memberType(sym), funMode(mode), WildcardType)
}
diff --git a/test/files/neg/bug910.check b/test/files/neg/bug910.check
new file mode 100644
index 0000000000..c52d7a87df
--- /dev/null
+++ b/test/files/neg/bug910.check
@@ -0,0 +1,6 @@
+bug910.scala:4: error: type mismatch;
+ found : scala.Seq[scala.Char]
+ required: scala.Seq[scala.Int]
+ val y: Seq[int] = rest
+ ^
+one error found
diff --git a/test/files/neg/bug910.scala b/test/files/neg/bug910.scala
new file mode 100644
index 0000000000..2f28ea408f
--- /dev/null
+++ b/test/files/neg/bug910.scala
@@ -0,0 +1,7 @@
+object RegExpTest1 extends Application {
+ def co(x: Seq[Char]) = x match {
+ case Seq('s','c','a','l','a', rest @ _*) =>
+ val y: Seq[int] = rest
+ y
+ }
+}
diff --git a/test/files/neg/bug987.check b/test/files/neg/bug987.check
new file mode 100644
index 0000000000..3e9c19217d
--- /dev/null
+++ b/test/files/neg/bug987.check
@@ -0,0 +1,9 @@
+bug987.scala:15: error: the type intersection B[D] with B[C] is malformed
+ --- because ---
+no common type instance of base types B[C] and B[D] exists
+class E extends D
+^
+bug987.scala:20: error: illegal cyclic reference involving class D
+class F extends D
+^
+two errors found
diff --git a/test/files/neg/bug987.scala b/test/files/neg/bug987.scala
new file mode 100644
index 0000000000..dcd3ce1d07
--- /dev/null
+++ b/test/files/neg/bug987.scala
@@ -0,0 +1,25 @@
+// tested using Scala compiler version 2.4.0-RC1 -- (c) 2002-2007 LAMP/EPFL
+
+// Many thanks to all at LAMP for the work that goes into Scala.
+
+
+class A {}
+
+trait B[T <: B[T]] requires T {}
+
+abstract class C extends A with B[C]
+{
+ protected val data: List[Int]
+}
+
+class E extends D
+{
+ val data = Nil
+}
+
+class F extends D
+{
+ val data = Nil
+}
+
+abstract class D extends C with B[D] {}
diff --git a/test/files/run/bug995.check b/test/files/run/bug995.check
new file mode 100644
index 0000000000..f0f0e34bb3
--- /dev/null
+++ b/test/files/run/bug995.check
@@ -0,0 +1 @@
+Seq
diff --git a/test/files/run/bug995.scala b/test/files/run/bug995.scala
new file mode 100644
index 0000000000..f7f75b6a02
--- /dev/null
+++ b/test/files/run/bug995.scala
@@ -0,0 +1,12 @@
+object Test extends Application {
+ def foo(v: Any): String = v match {
+ case s: Seq[_] =>
+ "Seq"
+ // see Burak's hack in object Seq.unapplySeq
+ //case a: AnyRef if runtime.ScalaRunTime.isArray(a) =>
+ // "Array"
+ case _ =>
+ v.toString
+ }
+ Console.println(foo(Array(0)))
+}