Skip to content

Change order of override error checks #9187

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Jun 22, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 12 additions & 12 deletions compiler/src/dotty/tools/dotc/typer/RefChecks.scala
Original file line number Diff line number Diff line change
Expand Up @@ -143,9 +143,10 @@ object RefChecks {
*
* 1.1. M must have the same or stronger access privileges as O.
* 1.2. O must not be effectively final.
* 1.3. O is deferred, or M has `override` modifier.
* 1.4. If O is stable, then so is M.
* // @M: LIFTED 1.5. Neither M nor O are a parameterized type alias
* 1.3. If M or O are extension methods, they must both be extension methods.
* (Should be before the check for the need of `override` modifier.)
* 1.4. O is deferred, or M has `override` modifier.
* 1.5. If O is stable, then so is M.
* 1.6. If O is a type alias, then M is an alias of O.
* 1.7. If O is an abstract type then
* 1.7.1 either M is an abstract type, and M's bounds are sharper than O's bounds.
Expand All @@ -156,8 +157,7 @@ object RefChecks {
* 1.8.1 M's type is a subtype of O's type, or
* 1.8.2 M is of type []S, O is of type ()T and S <: T, or
* 1.8.3 M is of type ()S, O is of type []T and S <: T, or
* 1.9.1 If M is erased, O is erased. If O is erased, M is erased or inline.
* 1.9.2 If M or O are extension methods, they must both be extension methods.
* 1.9. If M is erased, O is erased. If O is erased, M is erased or inline.
* 1.10. If O is inline (and deferred, otherwise O would be final), M must be inline
* 1.11. If O is a Scala-2 macro, M must be a Scala-2 macro.
* 2. Check that only abstract classes have deferred members
Expand Down Expand Up @@ -343,6 +343,10 @@ object RefChecks {
overrideError("cannot be used here - classes can only override abstract types")
else if (other.isEffectivelyFinal) // (1.2)
overrideError(i"cannot override final member ${other.showLocated}")
else if (member.isAllOf(ExtensionMethod) && !other.isAllOf(ExtensionMethod)) // (1.3)
overrideError("is an extension method, cannot override a normal method")
else if (other.isAllOf(ExtensionMethod) && !member.isAllOf(ExtensionMethod)) // (1.3)
overrideError("is a normal method, cannot override an extension method")
else if (!other.is(Deferred) &&
!other.name.is(DefaultGetterName) &&
!member.isAnyOverride)
Expand Down Expand Up @@ -381,7 +385,7 @@ object RefChecks {
intersectionIsEmpty(member.extendedOverriddenSymbols, other.extendedOverriddenSymbols))
overrideError("cannot override a concrete member without a third member that's overridden by both " +
"(this rule is designed to prevent ``accidental overrides'')")
else if (other.isStableMember && !member.isStableMember) // (1.4)
else if (other.isStableMember && !member.isStableMember) // (1.5)
overrideError("needs to be a stable, immutable value")
else if (member.is(ModuleVal) && !other.isRealMethod && !other.isOneOf(Deferred | Lazy))
overrideError("may not override a concrete non-lazy value")
Expand All @@ -390,14 +394,10 @@ object RefChecks {
overrideError("may not override a non-lazy value")
else if (other.is(Lazy) && !other.isRealMethod && !member.is(Lazy))
overrideError("must be declared lazy to override a lazy value")
else if (member.is(Erased) && !other.is(Erased)) // (1.9.1)
else if (member.is(Erased) && !other.is(Erased)) // (1.9)
overrideError("is erased, cannot override non-erased member")
else if (other.is(Erased) && !member.isOneOf(Erased | Inline)) // (1.9.1)
else if (other.is(Erased) && !member.isOneOf(Erased | Inline)) // (1.9)
overrideError("is not erased, cannot override erased member")
else if (member.isAllOf(ExtensionMethod) && !other.isAllOf(ExtensionMethod)) // (1.9.2)
overrideError("is an extension method, cannot override a normal method")
else if (other.isAllOf(ExtensionMethod) && !member.isAllOf(ExtensionMethod)) // (1.9.2)
overrideError("is a normal method, cannot override an extension method")
else if other.is(Inline) && !member.is(Inline) then // (1.10)
overrideError("is not inline, cannot implement an inline method")
else if (other.isScala2Macro && !member.isScala2Macro) // (1.11)
Expand Down
10 changes: 10 additions & 0 deletions tests/neg/override-extension_normal-methods.check
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
-- Error: tests/neg/override-extension_normal-methods.scala:6:6 --------------------------------------------------------
6 | def m[T](x: T): String = "normal method" // error: normal method, cannot override an extension method. Also needs `override' modifier (but this error should be obfuscated).
| ^
| error overriding method m in trait A of type [T](t: T): String;
| method m of type [T](x: T): String is a normal method, cannot override an extension method
-- Error: tests/neg/override-extension_normal-methods.scala:14:6 -------------------------------------------------------
14 | def [T](t: T).m: String = "extrnsion method" // error: extension method, cannot override an normal method. Also needs `override' modifier (but this error should be obfuscated).
| ^
| error overriding method m in trait B of type [T](x: T): String;
| method m of type [T](t: T): String is an extension method, cannot override a normal method
15 changes: 15 additions & 0 deletions tests/neg/override-extension_normal-methods.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
trait A {
def [T](t: T).m: String = "extrnsion method"
}

trait AAA extends A {
def m[T](x: T): String = "normal method" // error: normal method, cannot override an extension method. Also needs `override' modifier (but this error should be obfuscated).
}

trait B {
def m[T](x: T): String = "normal method"
}

trait BBB extends B {
def [T](t: T).m: String = "extrnsion method" // error: extension method, cannot override an normal method. Also needs `override' modifier (but this error should be obfuscated).
}