February 05, 2020 [Issue 20561] New: Compiler silently ignores override on templated method if interface/base class defines it | ||||
---|---|---|---|---|
| ||||
https://issues.dlang.org/show_bug.cgi?id=20561 Issue ID: 20561 Summary: Compiler silently ignores override on templated method if interface/base class defines it Product: D Version: D2 Hardware: x86 OS: Mac OS X Status: NEW Keywords: accepts-invalid Severity: enhancement Priority: P1 Component: dmd Assignee: nobody@puremagic.com Reporter: pro.mathias.lang@gmail.com Code example: ``` class Channel (T) {} interface Scheduler { void spawn (T) (Channel!T chan); } class ThreadScheduler : Scheduler { override void spawn (T) (Channel!T chan) { } } void main () { Scheduler ths = new ThreadScheduler; ths.spawn(new Channel!int); } ``` This will lead to a link error with DMD 2.090.0: ``` Undefined symbols for architecture x86_64: "__D3bug9Scheduler__T5spawnTiZQjMFCQBf__T7ChannelTiZQlZv", referenced from: __Dmain in bug.o ld: symbol(s) not found for architecture x86_64 clang: error: linker command failed with exit code 1 (use -v to see invocation) Error: linker exited with status 1 ``` There are several problem here: 1) Having a templated method declaration without definition in an interface is odd. There can be a use case, e.g. for `extern` declarations, but those are marked as `extern`. But that's still open to discussion. 2) However, the `override void spawn` is completely wrong: the compiler should give the usual "Cannot override non-virtual method" error. Another example: ``` class Channel (T) {} interface Scheduler { void spawn (T) (Channel!T chan) { assert(0); } } class ThreadScheduler : Scheduler { override void spawn (T) (Channel!T chan) { } } void main () { Scheduler ths = new ThreadScheduler; ths.spawn(new Channel!int); } ``` This triggers the assertion, because `Scheduler.spawn` is called (as it should), however users would expect `ThreadScheduler.spawn` to be called. -- |
Copyright © 1999-2021 by the D Language Foundation