summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMartin Odersky <odersky@gmail.com>2009-02-15 16:43:36 +0000
committerMartin Odersky <odersky@gmail.com>2009-02-15 16:43:36 +0000
commit266df9f05ecd11e67166e57cc58236646f2f50bb (patch)
tree6325a682f6b0d2101928a8eca047477f09e2db57
parentf2032c958854476587f6e78668b16216a28dc9a8 (diff)
downloadscala-266df9f05ecd11e67166e57cc58236646f2f50bb.tar.gz
scala-266df9f05ecd11e67166e57cc58236646f2f50bb.tar.bz2
scala-266df9f05ecd11e67166e57cc58236646f2f50bb.zip
Fixed an ambiguity problem with implcits, and a...
Fixed an ambiguity problem with implcits, and a spurious cyclic reference error mentioned by Jorge. Tightened overriding checks (test case is new collection libraries).
-rw-r--r--src/compiler/scala/tools/nsc/transform/OverridingPairs.scala7
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Contexts.scala12
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Namers.scala25
-rw-r--r--test/files/pos/cyclics.scala7
4 files changed, 39 insertions, 12 deletions
diff --git a/src/compiler/scala/tools/nsc/transform/OverridingPairs.scala b/src/compiler/scala/tools/nsc/transform/OverridingPairs.scala
index 9266515057..8f8d6a5bea 100644
--- a/src/compiler/scala/tools/nsc/transform/OverridingPairs.scala
+++ b/src/compiler/scala/tools/nsc/transform/OverridingPairs.scala
@@ -117,6 +117,7 @@ abstract class OverridingPairs {
* i = index(p)
* j = index(b)
* p isSubClass b
+ * p.baseType(b) == self.baseType(b)
*/
private val subParents = new Array[BitSet](size)
@@ -124,7 +125,11 @@ abstract class OverridingPairs {
subParents(i) = new BitSet(size);
for (p <- parents) {
val pIndex = index(p.typeSymbol)
- for (bc <- p.baseClasses) include(subParents(index(bc)), pIndex)
+ for (bc <- p.baseClasses)
+ if (p.baseType(bc) =:= self.baseType(bc))
+ include(subParents(index(bc)), pIndex)
+ else if (settings.debug.value)
+ log("SKIPPING "+p+" -> "+p.baseType(bc)+" / "+self.baseType(bc)+" from "+base)
}
}
diff --git a/src/compiler/scala/tools/nsc/typechecker/Contexts.scala b/src/compiler/scala/tools/nsc/typechecker/Contexts.scala
index 18f221fab9..213bbf173a 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Contexts.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Contexts.scala
@@ -630,6 +630,18 @@ trait Contexts { self: Analyzer =>
if (tpeCache eq null) tpeCache = pre.memberType(sym)
tpeCache
}
+ override def equals(other: Any) = other match {
+ case that: ImplicitInfo =>
+ if (this eq NoImplicitInfo) that eq this
+ else
+ this.name == that.name &&
+ this.pre =:= that.pre &&
+ this.sym == that.sym
+ case _ =>
+ false
+ }
+ override def hashCode =
+ name.hashCode + pre.hashCode + sym.hashCode
override def toString = "ImplicitInfo(" + name + "," + pre + "," + sym + ")"
}
diff --git a/src/compiler/scala/tools/nsc/typechecker/Namers.scala b/src/compiler/scala/tools/nsc/typechecker/Namers.scala
index f3fe615e80..6e648371ea 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Namers.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Namers.scala
@@ -27,17 +27,20 @@ trait Namers { self: Analyzer =>
* 2. The skolem is a method parameter which appears in parameter `tparams'
*/
class DeSkolemizeMap(tparams: List[Symbol]) extends TypeMap {
- def apply(tp: Type): Type = tp match {
- case TypeRef(pre, sym, args)
- if (sym.isTypeSkolem && (tparams contains sym.deSkolemize)) =>
- mapOver(rawTypeRef(NoPrefix, sym.deSkolemize, args))
- case PolyType(tparams1, restpe) =>
- new DeSkolemizeMap(tparams1 ::: tparams).mapOver(tp)
- case ClassInfoType(parents, decls, clazz) =>
- val parents1 = List.mapConserve(parents)(this)
+ def apply(tp: Type): Type = if (tparams.isEmpty) tp
+ else {
+ tp match {
+ case TypeRef(pre, sym, args)
+ if (sym.isTypeSkolem && (tparams contains sym.deSkolemize)) =>
+ mapOver(rawTypeRef(NoPrefix, sym.deSkolemize, args))
+ case PolyType(tparams1, restpe) =>
+ new DeSkolemizeMap(tparams1 ::: tparams).mapOver(tp)
+ case ClassInfoType(parents, decls, clazz) =>
+ val parents1 = List.mapConserve(parents)(this)
if (parents1 eq parents) tp else ClassInfoType(parents1, decls, clazz)
- case _ =>
- mapOver(tp)
+ case _ =>
+ mapOver(tp)
+ }
}
}
private class NormalNamer(context : Context) extends Namer(context)
@@ -415,7 +418,7 @@ trait Namers { self: Analyzer =>
// --- Lazy Type Assignment --------------------------------------------------
def typeCompleter(tree: Tree) = mkTypeCompleter(tree) { sym =>
- if (settings.debug.value) log("defining " + sym + Flags.flagsToString(sym.flags));
+ if (settings.debug.value) log("defining " + sym + Flags.flagsToString(sym.flags)+sym.locationString)
val tp = typeSig(tree)
tp match {
case TypeBounds(lo, hi) =>
diff --git a/test/files/pos/cyclics.scala b/test/files/pos/cyclics.scala
new file mode 100644
index 0000000000..69092ce7ab
--- /dev/null
+++ b/test/files/pos/cyclics.scala
@@ -0,0 +1,7 @@
+trait Param[T]
+trait Abs { type T }
+trait Cyclic1[A <: Param[A]] // works
+trait Cyclic2[A <: Abs { type T <: A }] // fails
+trait Cyclic3 { type A <: Abs { type T = A } } // fails
+trait Cyclic4 { type A <: Param[A] } // works
+