@@ -237,9 +237,14 @@ object RefChecks {
237237 && inLinearizationOrder(sym1, sym2, parent)
238238 && ! sym2.is(AbsOverride )
239239
240- def checkAll (checkOverride : (Symbol , Symbol ) => Unit ) =
240+ // Checks the subtype relationship tp1 <:< tp2.
241+ // It is passed to the `checkOverride` operation in `checkAll`, to be used for
242+ // compatibility checking.
243+ def checkSubType (tp1 : Type , tp2 : Type )(using Context ): Boolean = tp1 frozen_<:< tp2
244+
245+ def checkAll (checkOverride : ((Type , Type ) => Context ?=> Boolean , Symbol , Symbol ) => Unit ) =
241246 while hasNext do
242- checkOverride(overriding, overridden)
247+ checkOverride(checkSubType, overriding, overridden)
243248 next()
244249
245250 // The OverridingPairs cursor does assume that concrete overrides abstract
@@ -253,7 +258,7 @@ object RefChecks {
253258 if dcl.is(Deferred ) then
254259 for other <- dcl.allOverriddenSymbols do
255260 if ! other.is(Deferred ) then
256- checkOverride(dcl, other)
261+ checkOverride(checkSubType, dcl, other)
257262 end checkAll
258263 end OverridingPairsChecker
259264
@@ -291,12 +296,10 @@ object RefChecks {
291296 * TODO This still needs to be cleaned up; the current version is a straight port of what was there
292297 * before, but it looks too complicated and method bodies are far too large.
293298 *
294- * @param isSubType A function used for checking the subtype relationship between
295- * two types `tp1` and `tp2` when checking the compatibility
296- * between overriding pairs, with possible adaptations applied
297- * (e.g. box adaptation in capture checking).
299+ * @param makeOverridePairsChecker A function for creating a OverridePairsChecker instance
300+ * from the class symbol and the self type
298301 */
299- def checkAllOverrides (clazz : ClassSymbol , isSubType : Context ?=> Symbol => ( Type , Type ) => Boolean = _ => (tp1, tp2) => tp1 frozen_ <:< tp2 )(using Context ): Unit = {
302+ def checkAllOverrides (clazz : ClassSymbol , makeOverridingPairsChecker : (( ClassSymbol , Type ) => Context ?=> OverridingPairsChecker ) | Null = null )(using Context ): Unit = {
300303 val self = clazz.thisType
301304 val upwardsSelf = upwardsThisType(clazz)
302305 var hasErrors = false
@@ -327,10 +330,17 @@ object RefChecks {
327330 def infoStringWithLocation (sym : Symbol ) =
328331 err.infoString(sym, self, showLocation = true )
329332
333+ def isInheritedAccessor (mbr : Symbol , other : Symbol ): Boolean =
334+ mbr.is(ParamAccessor )
335+ && {
336+ val next = ParamForwarding .inheritedAccessor(mbr)
337+ next == other || isInheritedAccessor(next, other)
338+ }
339+
330340 /* Check that all conditions for overriding `other` by `member`
331- * of class `clazz` are met.
332- */
333- def checkOverride (member : Symbol , other : Symbol ): Unit =
341+ * of class `clazz` are met.
342+ */
343+ def checkOverride (checkSubType : ( Type , Type ) => Context ?=> Boolean , member : Symbol , other : Symbol ): Unit =
334344 def memberTp (self : Type ) =
335345 if (member.isClass) TypeAlias (member.typeRef.EtaExpand (member.typeParams))
336346 else self.memberInfo(member)
@@ -350,7 +360,7 @@ object RefChecks {
350360 fallBack = warnOnMigration(
351361 overrideErrorMsg(" no longer has compatible type" ),
352362 (if (member.owner == clazz) member else clazz).srcPos, version = `3.0`),
353- isSubType = isSubType(member) )
363+ isSubType = checkSubType )
354364 catch case ex : MissingType =>
355365 // can happen when called with upwardsSelf as qualifier of memberTp and otherTp,
356366 // because in that case we might access types that are not members of the qualifier.
@@ -506,7 +516,7 @@ object RefChecks {
506516 else if (member.is(ModuleVal ) && ! other.isRealMethod && ! other.isOneOf(DeferredOrLazy ))
507517 overrideError(" may not override a concrete non-lazy value" )
508518 else if (member.is(Lazy , butNot = Module ) && ! other.isRealMethod && ! other.is(Lazy ) &&
509- ! warnOnMigration(overrideErrorMsg(" may not override a non-lazy value" ), member.srcPos, version = `3.0`))
519+ ! warnOnMigration(overrideErrorMsg(" may not override a non-lazy value" ), member.srcPos, version = `3.0`))
510520 overrideError(" may not override a non-lazy value" )
511521 else if (other.is(Lazy ) && ! other.isRealMethod && ! member.is(Lazy ))
512522 overrideError(" must be declared lazy to override a lazy value" )
@@ -539,14 +549,8 @@ object RefChecks {
539549 overrideDeprecation(" " , member, other, " removed or renamed" )
540550 end checkOverride
541551
542- def isInheritedAccessor (mbr : Symbol , other : Symbol ): Boolean =
543- mbr.is(ParamAccessor )
544- && {
545- val next = ParamForwarding .inheritedAccessor(mbr)
546- next == other || isInheritedAccessor(next, other)
547- }
548-
549- OverridingPairsChecker (clazz, self).checkAll(checkOverride)
552+ val checker = if makeOverridingPairsChecker == null then OverridingPairsChecker (clazz, self) else makeOverridingPairsChecker(clazz, self)
553+ checker.checkAll(checkOverride)
550554 printMixinOverrideErrors()
551555
552556 // Verifying a concrete class has nothing unimplemented.
0 commit comments