digitalmars.D.learn - Why does templated interface function return something different than
- Timoses (33/33) Jul 18 2018 Why is the interface templated function not also returning the
- Timoses (4/37) Jul 18 2018 Sorry, I experimented a bit and forgot to change the topic to
- Steven Schveighoffer (26/65) Aug 02 2018 Looking at the AST, it appears that toImpl doesn't recognize what
Why is the interface templated function not also returning the class C toString return value "in C"?? interface iface { void toString(scope void delegate(const(char)[]) sink) const; final string convert() inout { import std.conv; // assert(std.conv.to!string(this) == "in C"); // fails! return std.conv.to!string(this); } final string convert2() const { import std.conv; assert(std.conv.to!string(this) == "in C"); return std.conv.to!string(this); } } class C : iface { void toString(scope void delegate(const(char)[]) sink) const { sink("in C"); } } void main () { iface i = new C(); import std.stdio; writeln(i.convert); // "app.C" writeln(i.convert2()); // "in C" } It seems like `inout` triggers some odd behaviour??
Jul 18 2018
On Wednesday, 18 July 2018 at 11:09:12 UTC, Timoses wrote:Why is the interface templated function not also returning the class C toString return value "in C"?? interface iface { void toString(scope void delegate(const(char)[]) sink) const; final string convert() inout { import std.conv; // assert(std.conv.to!string(this) == "in C"); // fails! return std.conv.to!string(this); } final string convert2() const { import std.conv; assert(std.conv.to!string(this) == "in C"); return std.conv.to!string(this); } } class C : iface { void toString(scope void delegate(const(char)[]) sink) const { sink("in C"); } } void main () { iface i = new C(); import std.stdio; writeln(i.convert); // "app.C" writeln(i.convert2()); // "in C" } It seems like `inout` triggers some odd behaviour??Sorry, I experimented a bit and forgot to change the topic to something more fitting, e.g. "Why does inout struct function return different results?"
Jul 18 2018
On 7/18/18 7:09 AM, Timoses wrote:Why is the interface templated function not also returning the class C toString return value "in C"?? interface iface { void toString(scope void delegate(const(char)[]) sink) const; final string convert() inout { import std.conv; // assert(std.conv.to!string(this) == "in C"); // fails! return std.conv.to!string(this); } final string convert2() const { import std.conv; assert(std.conv.to!string(this) == "in C"); return std.conv.to!string(this); } } class C : iface { void toString(scope void delegate(const(char)[]) sink) const { sink("in C"); } } void main () { iface i = new C(); import std.stdio; writeln(i.convert); // "app.C" writeln(i.convert2()); // "in C" } It seems like `inout` triggers some odd behaviour??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
Aug 02 2018
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. -SteveThanks for the insight. To me it sounds like std.conv `toImpl` doesn't properly handle inout types in this case.
Aug 06 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: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?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. -SteveThanks for the insight. To me it sounds like std.conv `toImpl` doesn't properly handle inout types in this case.
Aug 08 2018