fixed bug 1000 and david pollaks problem wrt tupling

git-svn-id: http://lampsvn.epfl.ch/svn-repos/scala/scala/trunk@10323 5e8d7ff9-d8ef-0310-90f0-a4852d11357a
This commit is contained in:
odersky 2007-03-13 15:19:42 +00:00
parent 31536c6f45
commit fd423eb821
8 changed files with 83 additions and 14 deletions

View File

@ -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? */

View File

@ -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)
}

View File

@ -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

View File

@ -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
}
}

View File

@ -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

View File

@ -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] {}

View File

@ -0,0 +1 @@
Seq

View File

@ -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)))
}