aboutsummaryrefslogtreecommitdiff
path: root/src/dotty/tools
diff options
context:
space:
mode:
authorMartin Odersky <odersky@gmail.com>2013-04-04 14:45:17 +0200
committerMartin Odersky <odersky@gmail.com>2013-04-04 14:45:17 +0200
commite8b9ef29f6e0a0ba4f0e51943c80ba2974b0e27e (patch)
tree91e3be26d625b7c55c0d81a18ba25446a0a347da /src/dotty/tools
parent9cd15421432871b920d377af86e1cd1b3edb270e (diff)
downloaddotty-e8b9ef29f6e0a0ba4f0e51943c80ba2974b0e27e.tar.gz
dotty-e8b9ef29f6e0a0ba4f0e51943c80ba2974b0e27e.tar.bz2
dotty-e8b9ef29f6e0a0ba4f0e51943c80ba2974b0e27e.zip
Fxing cyclic references during findMember
1) Classes and alias type now take precedence over abstract types. 2) When computing members, parents are visited right to left, which corresponds to existing taking precedence over new in mergeDenot.
Diffstat (limited to 'src/dotty/tools')
-rw-r--r--src/dotty/tools/dotc/core/Denotations.scala53
-rw-r--r--src/dotty/tools/dotc/core/SymDenotations.scala22
2 files changed, 38 insertions, 37 deletions
diff --git a/src/dotty/tools/dotc/core/Denotations.scala b/src/dotty/tools/dotc/core/Denotations.scala
index c0fa46e31..9144cc2db 100644
--- a/src/dotty/tools/dotc/core/Denotations.scala
+++ b/src/dotty/tools/dotc/core/Denotations.scala
@@ -215,26 +215,28 @@ object Denotations {
}
case denot1: SingleDenotation =>
if (denot1 eq denot2) denot1
- else if (denot1.signature == denot2.signature) {
- /** Convert class info C to bounds C..C */
- def normalize(info: Type) =
- if (isType) info.bounds else info
+ else if (denot1.signature != denot2.signature) NoDenotation
+ else {
val sym1 = denot1.symbol
- val info1 = denot1.info
- val sym2 = denot2.symbol
- val info2 = denot2.info
- val sym1Eligible = sym1.isAsConcrete(sym2)
- val sym2Eligible = sym2.isAsConcrete(sym1)
- val bounds1 = normalize(info1)
- val bounds2 = normalize(info2)
-// if (sym2Eligible && bounds2 <:< bounds1) denot2
-// else if (sym1Eligible && bounds1 <:< bounds2) denot1
-// else
- new LazyJointRefDenotation(
- if (sym2Eligible) sym2 else sym1,
- bounds1 & bounds2,
- denot1.validFor & denot2.validFor)
- } else NoDenotation
+ if (sym1.isClass || sym1.isAliasType) denot1
+ else {
+ val sym2 = denot2.symbol
+ if (sym2.isClass || sym2.isAliasType) denot2
+ else {
+ // if sym1, sym2 exist, they are abstract types or term symbols
+ val info1 = denot1.info
+ val info2 = denot2.info
+ val sym1Eligible = sym1.isAsConcrete(sym2)
+ val sym2Eligible = sym2.isAsConcrete(sym1)
+ if (sym1Eligible && info1 <:< info2) denot1
+ else if (sym2Eligible && info2 <:< info1) denot2
+ else new JointRefDenotation(
+ if (sym2Eligible) sym2 else sym1,
+ info1 & info2,
+ denot1.validFor & denot2.validFor)
+ }
+ }
+ }
}
/** Form a choice between this denotation and that one.
@@ -472,6 +474,9 @@ object Denotations {
exists && signature == sig
final def filterDisjoint(denots: PreDenotation)(implicit ctx: Context): SingleDenotation =
if (denots.containsSig(signature)) NoDenotation else this
+ def disjointAsSeenFrom(denots: PreDenotation, pre: Type)(implicit ctx: Context): SingleDenotation =
+ if (signature == NotAMethod) filterDisjoint(denots).asSeenFrom(pre)
+ else asSeenFrom(pre).filterDisjoint(denots)
final def filterExcluded(excluded: FlagSet)(implicit ctx: Context): SingleDenotation =
if (excluded == EmptyFlags) this
else this match {
@@ -506,12 +511,6 @@ object Denotations {
override protected def newLikeThis(s: Symbol, i: Type): SingleDenotation = new JointRefDenotation(s, i, validFor)
}
- class LazyJointRefDenotation(val symbol: Symbol, infoFn: => Type, initValidFor: Period) extends SingleDenotation {
- validFor = initValidFor
- lazy val info = infoFn
- override protected def newLikeThis(s: Symbol, i: Type): SingleDenotation = new JointRefDenotation(s, i, validFor)
- }
-
class ErrorDenotation(implicit ctx: Context) extends SingleDenotation {
override def exists = false
val symbol = NoSymbol
@@ -547,6 +546,8 @@ object Denotations {
*/
def filterDisjoint(denots: PreDenotation)(implicit ctx: Context): PreDenotation
+ def disjointAsSeenFrom(denots: PreDenotation, pre: Type)(implicit ctx: Context): PreDenotation
+
/** Keep only those denotations in this group whose flags do not intersect
* with `excluded`.
*/
@@ -571,6 +572,8 @@ object Denotations {
(denots1 containsSig sig) || (denots2 containsSig sig)
def filterDisjoint(denots: PreDenotation)(implicit ctx: Context): PreDenotation =
derivedUnion(denots1 filterDisjoint denots, denots2 filterDisjoint denots)
+ def disjointAsSeenFrom(denots: PreDenotation, pre: Type)(implicit ctx: Context): PreDenotation =
+ derivedUnion(denots1.disjointAsSeenFrom(denots, pre), denots2.disjointAsSeenFrom(denots, pre))
def filterExcluded(excluded: FlagSet)(implicit ctx: Context): PreDenotation =
derivedUnion(denots1.filterExcluded(excluded), denots2.filterExcluded(excluded))
def asSeenFrom(pre: Type)(implicit ctx: Context): PreDenotation =
diff --git a/src/dotty/tools/dotc/core/SymDenotations.scala b/src/dotty/tools/dotc/core/SymDenotations.scala
index 3f0ad171a..1d806edc1 100644
--- a/src/dotty/tools/dotc/core/SymDenotations.scala
+++ b/src/dotty/tools/dotc/core/SymDenotations.scala
@@ -825,24 +825,22 @@ object SymDenotations {
println(s"$this.member($name), ownDenots = $ownDenots")
def collect(denots: PreDenotation, parents: List[TypeRef]): PreDenotation = parents match {
case p :: ps =>
- val denots1 = p.symbol.denot match {
+ val denots1 = collect(denots, ps)
+ p.symbol.denot match {
case parentd: ClassDenotation =>
if (debugTrace) { // DEBUG
val s1 = parentd.membersNamed(name)
val s2 = s1.filterExcluded(Private)
- val s3 = s2.asSeenFrom(thisType)
- val s4 = s3.filterDisjoint(ownDenots)
- println(s"$this.member($name) $s1 $s2 $s3 $s4")
+ val s3 = s2.disjointAsSeenFrom(ownDenots, thisType)
+ println(s"$this.member($name) $s1 $s2 $s3")
}
- denots union
+ denots1 union
parentd.membersNamed(name)
.filterExcluded(Private)
- .asSeenFrom(thisType)
- .filterDisjoint(ownDenots)
+ .disjointAsSeenFrom(ownDenots, thisType)
case _ =>
- denots
+ denots1
}
- collect(denots1, ps)
case _ =>
denots
}
@@ -895,7 +893,7 @@ object SymDenotations {
NoType
}
- ctx.traceIndented(s"$tp.baseType($this)") {
+ ctx.traceIndented(s"$tp.baseType($this) ${tp.typeSymbol.fullName} ${this.fullName}") {
if (symbol.isStatic) symbol.typeConstructor
else tp match {
case tp: CachedType =>
@@ -905,10 +903,10 @@ object SymDenotations {
}
var basetp = baseTypeCache get tp
if (basetp == null) {
- baseTypeCache.put(tp, NoType)
+ baseTypeCache.put(tp, NoPrefix)
basetp = computeBaseTypeOf(tp)
baseTypeCache.put(tp, basetp)
- } else if (basetp == NoType) {
+ } else if (basetp == NoPrefix) {
throw new CyclicReference(symbol)
}
basetp