|
1 | | -package dotty.tools.dotc |
| 1 | +package dotty.tools |
| 2 | +package dotc |
2 | 3 | package transform |
3 | 4 |
|
4 | 5 | import core._ |
5 | | -import Flags._, Symbols._, Contexts._, Scopes._, Decorators._ |
| 6 | +import Flags._, Symbols._, Contexts._, Scopes._, Decorators._, Types.Type |
6 | 7 | import collection.mutable |
7 | 8 | import collection.immutable.BitSet |
8 | 9 | import scala.annotation.tailrec |
@@ -35,9 +36,9 @@ object OverridingPairs { |
35 | 36 | */ |
36 | 37 | protected def parents: Array[Symbol] = base.info.parents.toArray.map(_.typeSymbol) |
37 | 38 |
|
38 | | - /** Does `sym1` match `sym2` so that it qualifies as overriding. |
39 | | - * Types always match. Term symbols match if their membertypes |
40 | | - * relative to <base>.this do |
| 39 | + /** Does `sym1` match `sym2` so that it qualifies as overriding when both symbols are |
| 40 | + * seen as members of `self`? Types always match. Term symbols match if their membertypes |
| 41 | + * relative to `self` do. |
41 | 42 | */ |
42 | 43 | protected def matches(sym1: Symbol, sym2: Symbol): Boolean = |
43 | 44 | sym1.isType || sym1.asSeenFrom(self).matches(sym2.asSeenFrom(self)) |
@@ -85,11 +86,22 @@ object OverridingPairs { |
85 | 86 | then bits += i |
86 | 87 | subParents(bc) = bits |
87 | 88 |
|
88 | | - private def hasCommonParentAsSubclass(cls1: Symbol, cls2: Symbol): Boolean = |
89 | | - (subParents(cls1) intersect subParents(cls2)).nonEmpty |
| 89 | + /** Is the override of `sym1` and `sym2` already handled when checking |
| 90 | + * a parent of `self`? |
| 91 | + */ |
| 92 | + private def isHandledByParent(sym1: Symbol, sym2: Symbol): Boolean = |
| 93 | + val commonParents = subParents(sym1.owner).intersect(subParents(sym2.owner)) |
| 94 | + commonParents.nonEmpty |
| 95 | + && commonParents.exists(i => canBeHandledByParent(sym1, sym2, parents(i).thisType)) |
| 96 | + |
| 97 | + /** Can pair `sym1`/`sym2` be handled by parent `parentType` which is a common subtype |
| 98 | + * of both symbol's owners? Assumed to be true by default, but overridden in RefChecks. |
| 99 | + */ |
| 100 | + protected def canBeHandledByParent(sym1: Symbol, sym2: Symbol, parentType: Type): Boolean = |
| 101 | + true |
90 | 102 |
|
91 | 103 | /** The scope entries that have already been visited as overridden |
92 | | - * (maybe excluded because of hasCommonParentAsSubclass). |
| 104 | + * (maybe excluded because of already handled by a parent). |
93 | 105 | * These will not appear as overriding |
94 | 106 | */ |
95 | 107 | private val visited = util.HashSet[Symbol]() |
@@ -134,28 +146,22 @@ object OverridingPairs { |
134 | 146 | * overridden = overridden member of the pair, provided hasNext is true |
135 | 147 | */ |
136 | 148 | @tailrec final def next(): Unit = |
137 | | - if (nextEntry ne null) { |
| 149 | + if nextEntry != null then |
138 | 150 | nextEntry = decls.lookupNextEntry(nextEntry) |
139 | | - if (nextEntry ne null) |
140 | | - try { |
| 151 | + if nextEntry != null then |
| 152 | + try |
141 | 153 | overridden = nextEntry.sym |
142 | | - if (overriding.owner != overridden.owner && matches(overriding, overridden)) { |
| 154 | + if overriding.owner != overridden.owner && matches(overriding, overridden) then |
143 | 155 | visited += overridden |
144 | | - if (!hasCommonParentAsSubclass(overriding.owner, overridden.owner)) return |
145 | | - } |
146 | | - } |
147 | | - catch { |
148 | | - case ex: TypeError => |
149 | | - // See neg/i1750a for an example where a cyclic error can arise. |
150 | | - // The root cause in this example is an illegal "override" of an inner trait |
151 | | - report.error(ex, base.srcPos) |
152 | | - } |
153 | | - else { |
| 156 | + if !isHandledByParent(overriding, overridden) then return |
| 157 | + catch case ex: TypeError => |
| 158 | + // See neg/i1750a for an example where a cyclic error can arise. |
| 159 | + // The root cause in this example is an illegal "override" of an inner trait |
| 160 | + report.error(ex, base.srcPos) |
| 161 | + else |
154 | 162 | curEntry = curEntry.prev |
155 | 163 | nextOverriding() |
156 | | - } |
157 | 164 | next() |
158 | | - } |
159 | 165 |
|
160 | 166 | nextOverriding() |
161 | 167 | next() |
|
0 commit comments