Why does templated interface function return something different than final function?

Timoses timosesu at gmail.com
Wed Aug 8 14:45:24 UTC 2018


On Monday, 6 August 2018 at 14:27:01 UTC, Timoses wrote:
> On Thursday, 2 August 2018 at 20:35:57 UTC, Steven 
> Schveighoffer wrote:
>>
>> Looking at the AST, it appears that toImpl doesn't recognize 
>> what inout(iface) is:
>>
>> toImpl!(string, inout(iface))
>> {
>> 	@system string toImpl(ref inout(iface) value)
>> 	{
>> 		import std.array : appender;
>> 		import std.format : FormatSpec, formatValue;
>> 		Appender!string w = appender();
>> 		FormatSpec!char f = FormatSpec;
>> 		formatValue(w, value, f);
>> 		return w.data();
>> 	}
>>
>> }
>>
>> Vs. the nice neat call for const(iface)
>>
>> toImpl!(string, const(iface))
>> {
>> 	@system string toImpl(const(iface) value)
>> 	{
>> 		return toStr(value);
>> 	}
>>
>> }
>>
>> Note the ref there, too. This means it can't cast to const. I 
>> wonder if that's an issue.
>>
>> -Steve
>
> Thanks for the insight. To me it sounds like std.conv `toImpl` 
> doesn't properly handle inout types in this case.

Well, my "workaround" now is to simply cast the inout type to 
const before passing to std.conv.to ...


I've experimented a bit more and compiled it a bit together.

     import std.stdio;
     import std.conv : to;

     interface I
     {
         void toString(scope void delegate(const(char)[]) sink) 
const;

         final void printI()
         {
             writeln(this.to!string); // this is class A
         }
         final void printIinout() inout
         {
             writeln(this.to!string); // app.A
         }
     }

     class A : I
     {
         void print()
         {
             writeln(this.to!string); // this is class A
         }
         // Compilation error
         // std\format.d(3890,13): Error: template instance 
`std.format.formatObject!(Appender!string, inout(A), char)` does 
not match template declaration `formatObject(Writer, T, Char)(ref 
Writer w, ref T val, ref const FormatSpec!Char f) if 
(hasToString!(T, Char))`
         /*void printinout() inout
         {
             writeln(this.to!string);
         }*/
         override void toString(scope void delegate(const(char)[]) 
sink) const
         {
             sink("this is class A");
         }
     }

     unittest
     {
         I i = new A();
         i.printI();
         i.printIinout();

         A a = new A();
         a.print();
         //a.printinout();
     }

It seems inconsistent to me. What do you think? Should I open a 
bug report for this?
Also the compilation error should not occur, should it?


More information about the Digitalmars-d-learn mailing list