diff options
author | Martin Odersky <odersky@gmail.com> | 2009-02-15 16:43:36 +0000 |
---|---|---|
committer | Martin Odersky <odersky@gmail.com> | 2009-02-15 16:43:36 +0000 |
commit | 266df9f05ecd11e67166e57cc58236646f2f50bb (patch) | |
tree | 6325a682f6b0d2101928a8eca047477f09e2db57 | |
parent | f2032c958854476587f6e78668b16216a28dc9a8 (diff) | |
download | scala-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.scala | 7 | ||||
-rw-r--r-- | src/compiler/scala/tools/nsc/typechecker/Contexts.scala | 12 | ||||
-rw-r--r-- | src/compiler/scala/tools/nsc/typechecker/Namers.scala | 25 | ||||
-rw-r--r-- | test/files/pos/cyclics.scala | 7 |
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 + |