diff options
author | Martin Odersky <odersky@gmail.com> | 2013-04-04 14:45:17 +0200 |
---|---|---|
committer | Martin Odersky <odersky@gmail.com> | 2013-04-04 14:45:17 +0200 |
commit | e8b9ef29f6e0a0ba4f0e51943c80ba2974b0e27e (patch) | |
tree | 91e3be26d625b7c55c0d81a18ba25446a0a347da | |
parent | 9cd15421432871b920d377af86e1cd1b3edb270e (diff) | |
download | dotty-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.
-rw-r--r-- | src/dotty/tools/dotc/core/Denotations.scala | 53 | ||||
-rw-r--r-- | src/dotty/tools/dotc/core/SymDenotations.scala | 22 |
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 |