diff options
-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 |