toString() through interface
Steven Schveighoffer via Digitalmars-d-learn
digitalmars-d-learn at puremagic.com
Mon Apr 21 06:27:00 PDT 2014
On Sat, 19 Apr 2014 20:51:49 -0400, David Held <dmd at wyntrmute.com> wrote:
> On 4/19/2014 5:35 PM, David Held wrote:
>> interface Foo { }
>>
>> class Bar : Foo
>> {
>> override string toString() pure const { return "Bar"; }
>> }
>>
>> void main()
>> {
>> Foo foo = new Bar;
>> foo.toString();
>> }
>
> To make things more interesting, consider the call to toString() from
> inside a class (which is closer to my actual use case):
>
> class Baz
> {
> override string toString() pure const
> { return cast(Object)(foo).toString(); }
>
> Foo foo;
> }
>
> This really makes the compiler go bonkers:
>
> src\Bug.d(11): Error: pure nested function 'toString' cannot access
> mutable data 'foo'
> src\Bug.d(11): Error: pure nested function 'toString' cannot access
> mutable data 'foo'
> src\Bug.d(11): Error: no property 'toString' for type 'Bug.Foo'
> src\Bug.d(11): Error: pure nested function 'toString' cannot access
> mutable data 'foo'
> src\Bug.d(11): Error: need 'this' for 'foo' of type 'Bug.Foo'
>
> Apparently, DMD features "high-availability error reporting", because
> the first message might not be received by the programmer, so it writes
> it again, then gives you a different message, and writes it one more
> time, just in case there was a communication error or some other fault
> preventing you from receiving this important message about access to
> 'foo'.
>
> Again, the cast appears to do absolutely nothing, as the compiler
> insists on looking up toString() in Foo instead of Object. What is
> really peculiar is that message 1, 2, and 4 are complaining that
> Baz.toString() is not allowed to access foo because it is mutable. And
> yet, the 5th error message tells us how to fix it: just add 'this.':
>
> override string toString() pure const
> { return cast(Object)(this.foo).toString(); }
>
> Now we just get this:
>
> src\Bug.d(11): Error: no property 'toString' for type 'const(Foo)'
To explain what the compiler is having trouble with, you have to
understand precedence.
cast(Object) does not come before '.'
So what the compiler thinks you said is:
return cast(Object)(this.foo.toString());
Others have said how to fix it. I just wanted to point out why you need to
fix it that way.
-Steve
More information about the Digitalmars-d-learn
mailing list