www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.bugs - [Issue 20561] New: Compiler silently ignores override on templated

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.

--
Feb 04