Skip to content

Commit 3f222ca

Browse files
authored
Merge pull request #2580 from dotty-staging/fix-#2390
Fix #2390: Use normal thisType as base for override checking
2 parents 0ef4f0b + ea3b7de commit 3f222ca

File tree

2 files changed

+31
-11
lines changed

2 files changed

+31
-11
lines changed

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

Lines changed: 20 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -151,7 +151,8 @@ object RefChecks {
151151
* before, but it looks too complicated and method bodies are far too large.
152152
*/
153153
private def checkAllOverrides(clazz: Symbol)(implicit ctx: Context): Unit = {
154-
val self = upwardsThisType(clazz)
154+
val self = clazz.thisType
155+
val upwardsSelf = upwardsThisType(clazz)
155156
var hasErrors = false
156157

157158
case class MixinOverrideError(member: Symbol, msg: String)
@@ -245,17 +246,24 @@ object RefChecks {
245246
(if (otherAccess == "") "public" else "at least " + otherAccess))
246247
}
247248

248-
def compatibleTypes =
249-
if (member.isType) { // intersection of bounds to refined types must be nonempty
250-
member.is(BaseTypeArg) ||
251-
(memberTp frozen_<:< otherTp) || {
252-
val jointBounds = (memberTp.bounds & otherTp.bounds).bounds
253-
jointBounds.lo frozen_<:< jointBounds.hi
249+
def compatibleTypes(memberTp: Type, otherTp: Type): Boolean =
250+
try
251+
if (member.isType) { // intersection of bounds to refined types must be nonempty
252+
member.is(BaseTypeArg) ||
253+
(memberTp frozen_<:< otherTp) || {
254+
val jointBounds = (memberTp.bounds & otherTp.bounds).bounds
255+
jointBounds.lo frozen_<:< jointBounds.hi
256+
}
254257
}
258+
else
259+
member.name.is(DefaultGetterName) || // default getters are not checked for compatibility
260+
memberTp.overrides(otherTp)
261+
catch {
262+
case ex: MissingType =>
263+
// can happen when called with upwardsSelf as qualifier of memberTp and otherTp,
264+
// because in that case we might access types that are not members of the qualifier.
265+
false
255266
}
256-
else
257-
member.name.is(DefaultGetterName) || // default getters are not checked for compatibility
258-
memberTp.overrides(otherTp)
259267

260268
//Console.println(infoString(member) + " overrides " + infoString(other) + " in " + clazz);//DEBUG
261269

@@ -356,7 +364,8 @@ object RefChecks {
356364
overrideError("cannot be used here - term macros cannot override abstract methods")
357365
} else if (other.is(Macro) && !member.is(Macro)) { // (1.10)
358366
overrideError("cannot be used here - only term macros can override term macros")
359-
} else if (!compatibleTypes) {
367+
} else if (!compatibleTypes(memberTp, otherTp) &&
368+
!compatibleTypes(upwardsSelf.memberInfo(member), upwardsSelf.memberInfo(other))) {
360369
overrideError("has incompatible type" + err.whyNoMatchStr(memberTp, otherTp))
361370
} else {
362371
checkOverrideDeprecated()

tests/pos/i2390.scala

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
trait TestSuite {
2+
trait NoArgTest
3+
}
4+
5+
trait TestSuiteMixin { self: TestSuite =>
6+
def foo(test: self.NoArgTest) = {}
7+
}
8+
9+
trait CancelAfterFailure extends TestSuiteMixin { self: TestSuite =>
10+
override def foo(test: self.NoArgTest) = {}
11+
}

0 commit comments

Comments
 (0)