Skip to content

Check for unimplemented abstract override members #11007

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
Jan 7, 2021
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
1 change: 1 addition & 0 deletions compiler/src/dotty/tools/dotc/core/Flags.scala
Original file line number Diff line number Diff line change
Expand Up @@ -530,6 +530,7 @@ object Flags {

// ------- Other flag sets -------------------------------------

val NotConcrete: FlagSet = AbsOverride | Deferred
val AbstractFinal: FlagSet = Abstract | Final
val AbstractOverride: FlagSet = Abstract | Override
val AbstractSealed: FlagSet = Abstract | Sealed
Expand Down
10 changes: 7 additions & 3 deletions compiler/src/dotty/tools/dotc/typer/RefChecks.scala
Original file line number Diff line number Diff line change
Expand Up @@ -524,10 +524,10 @@ object RefChecks {

def isImplemented(mbr: Symbol) =
val mbrType = clazz.thisType.memberInfo(mbr)
extension (sym: Symbol) def isConcrete = sym.exists && !sym.is(Deferred)
def isConcrete(sym: Symbol) = sym.exists && !sym.isOneOf(NotConcrete)
clazz.nonPrivateMembersNamed(mbr.name)
.filterWithPredicate(
impl => impl.symbol.isConcrete && mbrType.matchesLoosely(impl.info))
impl => isConcrete(impl.symbol) && mbrType.matchesLoosely(impl.info))
.exists

/** The term symbols in this class and its baseclasses that are
Expand Down Expand Up @@ -641,7 +641,11 @@ object RefChecks {

undefined(s"\n(Note that ${pa.show} does not match ${pc.show}$addendum)")
case xs =>
undefined(s"\n(The class implements a member with a different type: ${concrete.showDcl})")
undefined(
if concrete.symbol.is(AbsOverride) then
s"\n(The class implements ${concrete.showDcl} but that definition still needs an implementation)"
else
s"\n(The class implements a member with a different type: ${concrete.showDcl})")
}
case Nil =>
undefined("")
Expand Down
5 changes: 5 additions & 0 deletions tests/neg/i9329.check
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
-- Error: tests/neg/i9329.scala:8:6 ------------------------------------------------------------------------------------
8 |class GrandSon extends Son // error
| ^
| class GrandSon needs to be abstract, since def name: => String is not defined
| (The class implements abstract override def name: => String but that definition still needs an implementation)
8 changes: 8 additions & 0 deletions tests/neg/i9329.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
trait Parent {
def name: String
}
trait Son extends Parent {
abstract override def name = ""
def parentName = super.name
}
class GrandSon extends Son // error