Thread overview
dmd 2.093.1: duplicate method definitions ignored altogether
Jan 05, 2021
kdevel
Jan 05, 2021
Paul Backus
Jan 05, 2021
kdevel
Jan 06, 2021
Jacob Carlborg
January 05, 2021
~~~tsnf.d
import std.stdio: writeln;

struct S {
   string s;
   string toString ()
   {
      return __PRETTY_FUNCTION__ ~ `: ` ~ s;
   }
   string toString () const // def #1
   {
      return __PRETTY_FUNCTION__ ~ `: ` ~ s;
   }
   const string toString () // def #2
   {
      return __PRETTY_FUNCTION__ ~ `: ` ~ s;
   }
}

void foo (T) (in ref T t) // fancy way of declaring t const
{
   writeln (t);
}

int main ()
{
   S s;
   writeln (s);
   foo (s);
   return 0;
}
~~~

$ dmd tsnf
$ ./tsnf
string tsnf.S.toString():
const(S)("")

expected output: none. The compiler should have rejected the code after the duplicate definition def #2. dmd 2.093.1 ignores both definitions instead. Is this a bug or a bug?
January 05, 2021
On Tuesday, 5 January 2021 at 02:02:39 UTC, kdevel wrote:
> expected output: none. The compiler should have rejected the code after the duplicate definition def #2. dmd 2.093.1 ignores both definitions instead. Is this a bug or a bug?

If you try to call .toString directly on a const(S), you get the following error:

onlineapp.d(27): Error: onlineapp.S.toString called with argument types () const matches both:
onlineapp.d(9):     onlineapp.S.toString() const
and:
onlineapp.d(13):     onlineapp.S.toString() const

The reason it is ignored when using writeln is that writeln uses __traits(compiles) to check whether it can call toString on a const(S). Since the call does not compile, it falls back to the default struct formatting code, which produces the output you saw in your example.
January 05, 2021
On Tuesday, 5 January 2021 at 03:36:47 UTC, Paul Backus wrote:
> On Tuesday, 5 January 2021 at 02:02:39 UTC, kdevel wrote:

[...]

> If you try to call .toString directly on a const(S), you get the following error:
>
> onlineapp.d(27): Error: onlineapp.S.toString called with argument types () const matches both:
> onlineapp.d(9):     onlineapp.S.toString() const
> and:
> onlineapp.d(13):     onlineapp.S.toString() const

Sure, but that's too late. IMHO the compiler should detect duplicate
definitions (probably concealing a program error) regardless whether
the method is called. There is a difference between calls which match
two or more functions and duplicate definitions. Isn't it?

Other compilers for other languages complain loud and clear:

```ddcpp.cc
template<typename T>
struct X {
   int foo ()
   {
      return 0;
   }
   int foo ()
   {
      return 0;
   }
};
```

result from clang++:

ddcpp.cc:7:8: error: class member cannot be redeclared
   int foo ()
       ^
ddcpp.cc:3:8: note: previous declaration is here
   int foo ()
       ^
ddcpp.cc:7:8: error: redefinition of 'foo'
   int foo ()
       ^
ddcpp.cc:3:8: note: previous definition is here
   int foo ()
       ^
2 errors generated.

January 06, 2021
On 2021-01-05 03:02, kdevel wrote:

> expected output: none. The compiler should have rejected the code after the duplicate definition def #2. dmd 2.093.1 ignores both definitions instead. Is this a bug or a bug?

DMD 2.095.0 now reports an error for this.

-- 
/Jacob Carlborg