Skip to content

Commit f914ff8

Browse files
committed
Better interop with non-capture-checked files for override checking
1 parent 11bddad commit f914ff8

File tree

2 files changed

+16
-4
lines changed

2 files changed

+16
-4
lines changed

compiler/src/dotty/tools/dotc/cc/CheckCaptures.scala

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -918,7 +918,7 @@ class CheckCaptures extends Recheck, SymTransformer:
918918
* But maybe we can then elide the check during the RefChecks phase under captureChecking?
919919
*/
920920
def checkOverrides = new TreeTraverser:
921-
class OverridingPairsCheckerCC(clazz: ClassSymbol, self: Type, srcPos: SrcPos)(using Context) extends OverridingPairsChecker(clazz, self) {
921+
class OverridingPairsCheckerCC(clazz: ClassSymbol, self: Type, srcPos: SrcPos)(using Context) extends OverridingPairsChecker(clazz, self):
922922
/** Check subtype with box adaptation.
923923
* This function is passed to RefChecks to check the compatibility of overriding pairs.
924924
* @param sym symbol of the field definition that is being checked
@@ -940,7 +940,11 @@ class CheckCaptures extends Recheck, SymTransformer:
940940
case _ => adapted
941941
finally curEnv = saved
942942
actual1 frozen_<:< expected1
943-
}
943+
944+
override def adjustOtherType(tp: Type, other: Symbol)(using Context): Type =
945+
handleBackwardsCompat(tp, other, initialVariance = 0)
946+
//.showing(i"adjust $other: $tp --> $result")
947+
end OverridingPairsCheckerCC
944948

945949
def traverse(t: Tree)(using Context) =
946950
t match

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

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -239,6 +239,11 @@ object RefChecks {
239239
// compatibility checking.
240240
def checkSubType(tp1: Type, tp2: Type)(using Context): Boolean = tp1 frozen_<:< tp2
241241

242+
/** A hook that allows to adjust the type of `other` before checking conformance.
243+
* Overridden in capture checking to handle non-capture checked superclasses leniently.
244+
*/
245+
def adjustOtherType(tp: Type, other: Symbol)(using Context): Type = tp
246+
242247
private val subtypeChecker: (Type, Type) => Context ?=> Boolean = this.checkSubType
243248

244249
def checkAll(checkOverride: ((Type, Type) => Context ?=> Boolean, Symbol, Symbol) => Unit) =
@@ -352,14 +357,18 @@ object RefChecks {
352357
&& atPhase(typerPhase):
353358
loop(member.info.paramInfoss, other.info.paramInfoss)
354359

360+
val checker =
361+
if makeOverridingPairsChecker == null then OverridingPairsChecker(clazz, self)
362+
else makeOverridingPairsChecker(clazz, self)
363+
355364
/* Check that all conditions for overriding `other` by `member`
356365
* of class `clazz` are met.
357366
*/
358367
def checkOverride(checkSubType: (Type, Type) => Context ?=> Boolean, member: Symbol, other: Symbol): Unit =
359368
def memberTp(self: Type) =
360369
if (member.isClass) TypeAlias(member.typeRef.EtaExpand(member.typeParams))
361370
else self.memberInfo(member)
362-
def otherTp(self: Type) = self.memberInfo(other)
371+
def otherTp(self: Type) = checker.adjustOtherType(self.memberInfo(other), other)
363372

364373
refcheck.println(i"check override ${infoString(member)} overriding ${infoString(other)}")
365374

@@ -564,7 +573,6 @@ object RefChecks {
564573
overrideDeprecation("", member, other, "removed or renamed")
565574
end checkOverride
566575

567-
val checker = if makeOverridingPairsChecker == null then OverridingPairsChecker(clazz, self) else makeOverridingPairsChecker(clazz, self)
568576
checker.checkAll(checkOverride)
569577
printMixinOverrideErrors()
570578

0 commit comments

Comments
 (0)