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?

Reply via email to