digitalmars.D.learn - Unexpected issue with std.format
- Saurabh Das (43/43) Feb 01 2020 I faced this issue while working with custom formatting for a
- Saurabh Das (2/5) Feb 01 2020 PS: Currently using DMD64 D Compiler v2.090.0
- Steven Schveighoffer (12/64) Feb 01 2020 Something very weird is happening.
- Saurabh Das (26/95) Feb 01 2020 Thanks for the lead. To exemplify Steve's observation:
I faced this issue while working with custom formatting for a struct. I have reduced the error down to this test program: import std.format, std.stdio, std.array; struct Test1 { void toString(W, C)(ref W w, scope const ref FormatSpec!C fmt) { pragma(msg, "Test1 function compiled with W=" ~ W.stringof); // formatValue(w, this, fmt); } } struct Test2 { void toString(W, C)(ref W w, scope const ref FormatSpec!C fmt) { pragma(msg, "Test2 function compiled with W=" ~ W.stringof); formatValue(w, this, fmt); } } void main() { Test1 t1; Test2 t2; Appender!string writer; auto ff = singleSpec("%s"); formatValue(writer, t1, ff); formatValue(writer, t2, ff); } When compiled, the output is: Test1 function compiled with W=S Test1 function compiled with W=Appender!string Test2 function compiled with W=S 1. Why was Test2 never compiled with W=Appender!string? 2. What is "S"? Essentially, my custom struct was not being formatted using the toString method that I had written. Reducing the issue, it seems like a call to formatValue with the same type caused the issue. If someone can explain what I am doing wrong here, it would really help a lot. Thanks, Saurabh
Feb 01 2020
On Saturday, 1 February 2020 at 13:39:34 UTC, Saurabh Das wrote:I faced this issue while working with custom formatting for a struct. I have reduced the error down to this test program: [...]PS: Currently using DMD64 D Compiler v2.090.0
Feb 01 2020
On 2/1/20 8:39 AM, Saurabh Das wrote:I faced this issue while working with custom formatting for a struct. I have reduced the error down to this test program: import std.format, std.stdio, std.array; struct Test1 { void toString(W, C)(ref W w, scope const ref FormatSpec!C fmt) { pragma(msg, "Test1 function compiled with W=" ~ W.stringof); // formatValue(w, this, fmt); } } struct Test2 { void toString(W, C)(ref W w, scope const ref FormatSpec!C fmt) { pragma(msg, "Test2 function compiled with W=" ~ W.stringof); formatValue(w, this, fmt); } } void main() { Test1 t1; Test2 t2; Appender!string writer; auto ff = singleSpec("%s"); formatValue(writer, t1, ff); formatValue(writer, t2, ff); } When compiled, the output is: Test1 function compiled with W=S Test1 function compiled with W=Appender!string Test2 function compiled with W=S 1. Why was Test2 never compiled with W=Appender!string? 2. What is "S"? Essentially, my custom struct was not being formatted using the toString method that I had written. Reducing the issue, it seems like a call to formatValue with the same type caused the issue. If someone can explain what I am doing wrong here, it would really help a lot. Thanks, SaurabhSomething very weird is happening. I switched to fullyQualifiedName!W, and I get *no output*. The "S" comes from hasToString here:https://github.com/dlang/phobos/blob/9fe5cd354f0166b11d32a5c1214932757d8e7eba/std/format.d#L3876-L3899 I tried copying the implementation to a local file, and as expected, I get customPutWriterFormatSpec for both types. But it's only calling one of them in the implementation. I think the only true way to diagnose this is to instrument std.format and see what it's doing with more pragma(msg) calls. Don't have the time right now. -Steve
Feb 01 2020
On Saturday, 1 February 2020 at 15:16:41 UTC, Steven Schveighoffer wrote:On 2/1/20 8:39 AM, Saurabh Das wrote:Thanks for the lead. To exemplify Steve's observation: import std.format, std.stdio, std.array, std.range; struct Test3 { void toString(W, C)(ref W w, scope const ref FormatSpec!C fmt) { import std.traits; pragma(msg, "A: Test2 function compiled with W=" ~ fullyQualifiedName!W.stringof); pragma(msg, "B: Test2 function compiled with W=" ~ W.stringof); } } void main() { Test3 t3; Appender!string writer; auto ff = singleSpec("%s"); formatValue(writer, t3, ff); } Gives an output during compilation: B: Test2 function compiled with W=S SaurabhI faced this issue while working with custom formatting for a struct. I have reduced the error down to this test program: import std.format, std.stdio, std.array; struct Test1 { void toString(W, C)(ref W w, scope const ref FormatSpec!C fmt) { pragma(msg, "Test1 function compiled with W=" ~ W.stringof); // formatValue(w, this, fmt); } } struct Test2 { void toString(W, C)(ref W w, scope const ref FormatSpec!C fmt) { pragma(msg, "Test2 function compiled with W=" ~ W.stringof); formatValue(w, this, fmt); } } void main() { Test1 t1; Test2 t2; Appender!string writer; auto ff = singleSpec("%s"); formatValue(writer, t1, ff); formatValue(writer, t2, ff); } When compiled, the output is: Test1 function compiled with W=S Test1 function compiled with W=Appender!string Test2 function compiled with W=S 1. Why was Test2 never compiled with W=Appender!string? 2. What is "S"? Essentially, my custom struct was not being formatted using the toString method that I had written. Reducing the issue, it seems like a call to formatValue with the same type caused the issue. If someone can explain what I am doing wrong here, it would really help a lot. Thanks, SaurabhSomething very weird is happening. I switched to fullyQualifiedName!W, and I get *no output*. The "S" comes from hasToString here:https://github.com/dlang/phobos/blob/9fe5cd354f0166b11d32a5c1214932757d8e7eba/std/format.d#L3876-L3899 I tried copying the implementation to a local file, and as expected, I get customPutWriterFormatSpec for both types. But it's only calling one of them in the implementation. I think the only true way to diagnose this is to instrument std.format and see what it's doing with more pragma(msg) calls. Don't have the time right now. -Steve
Feb 01 2020