Skip to content

Commit de523b3

Browse files
committed
Avoid rechecking already handled pairs only if in same order
1 parent 6a90e5e commit de523b3

File tree

3 files changed

+18
-8
lines changed

3 files changed

+18
-8
lines changed

compiler/src/dotty/tools/dotc/transform/OverridingPairs.scala

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ object OverridingPairs {
3434
* pair has already been treated in a parent class.
3535
* This may be refined in subclasses. @see Bridges for a use case.
3636
*/
37-
protected def parents: Array[Symbol] = base.info.parents.toArray.map(_.typeSymbol)
37+
protected def parents: Array[Symbol] = base.info.parents.toArray.map(_.classSymbol)
3838

3939
/** Does `sym1` match `sym2` so that it qualifies as overriding when both symbols are
4040
* seen as members of `self`? Types always match. Term symbols match if their membertypes
@@ -92,13 +92,22 @@ object OverridingPairs {
9292
private def isHandledByParent(sym1: Symbol, sym2: Symbol): Boolean =
9393
val commonParents = subParents(sym1.owner).intersect(subParents(sym2.owner))
9494
commonParents.nonEmpty
95-
&& commonParents.exists(i => canBeHandledByParent(sym1, sym2, parents(i).thisType))
95+
&& commonParents.exists(i => canBeHandledByParent(sym1, sym2, parents(i)))
9696

9797
/** Can pair `sym1`/`sym2` be handled by parent `parentType` which is a common subtype
9898
* of both symbol's owners? Assumed to be true by default, but overridden in RefChecks.
9999
*/
100-
protected def canBeHandledByParent(sym1: Symbol, sym2: Symbol, parentType: Type): Boolean =
101-
true
100+
protected def canBeHandledByParent(sym1: Symbol, sym2: Symbol, parent: Symbol): Boolean =
101+
val owner1 = sym1.owner
102+
val owner2 = sym2.owner
103+
def precedesIn(bcs: List[ClassSymbol]): Boolean = (bcs: @unchecked) match
104+
case bc :: bcs1 =>
105+
if owner1 eq bc then true
106+
else if owner2 eq bc then false
107+
else precedesIn(bcs1)
108+
case _ =>
109+
false
110+
precedesIn(parent.asClass.baseClasses)
102111

103112
/** The scope entries that have already been visited as overridden
104113
* (maybe excluded because of already handled by a parent).

compiler/src/dotty/tools/dotc/typer/RefChecks.scala

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -514,9 +514,10 @@ object RefChecks {
514514

515515
// We can exclude pairs safely from checking only of they also matched in
516516
// the parent class. See neg/i12828.scala for an example where this matters.
517-
override def canBeHandledByParent(sym1: Symbol, sym2: Symbol, parentType: Type): Boolean =
518-
considerMatching(sym1, sym2, parentType)
519-
.showing(i"already handled ${sym1.showLocated}: ${sym1.asSeenFrom(parentType).signature}, ${sym2.showLocated}: ${sym2.asSeenFrom(parentType).signature} = $result", refcheck)
517+
override def canBeHandledByParent(sym1: Symbol, sym2: Symbol, parent: Symbol): Boolean =
518+
considerMatching(sym1, sym2, parent.thisType)
519+
.showing(i"already handled ${sym1.showLocated}: ${sym1.asSeenFrom(parent.thisType).signature}, ${sym2.showLocated}: ${sym2.asSeenFrom(parent.thisType).signature} = $result", refcheck)
520+
&& super.canBeHandledByParent(sym1, sym2, parent)
520521
end opc
521522

522523
while opc.hasNext do

tests/run/i5094.scala renamed to tests/neg/i5094.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ trait SOIO extends IO {
99
}
1010
trait SOSO extends SOIO with SO
1111
abstract class AS extends SO
12-
class L extends AS with SOSO
12+
class L extends AS with SOSO // error: cannot override final member
1313
object Test {
1414
def main(args: Array[String]): Unit = {
1515
new L

0 commit comments

Comments
 (0)