digitalmars.D.bugs - [Issue 21228] New: OutputRange-based toString is silently ignored if
- d-bugmail puremagic.com (53/53) Sep 05 2020 https://issues.dlang.org/show_bug.cgi?id=21228
https://issues.dlang.org/show_bug.cgi?id=21228 Issue ID: 21228 Summary: OutputRange-based toString is silently ignored if isOutputRange is not imported Product: D Version: D2 Hardware: All OS: All Status: NEW Severity: normal Priority: P1 Component: dmd Assignee: nobody puremagic.com Reporter: joseph.wakeling webdrake.net The following minimal example shows the problematic behaviour. A struct is defined with a custom toString that follows the recommendations and examples in std.format. However, there is a bug in the code: the `isOutputRange` template check is used but never imported. ``` struct S { int n; void toString (Output) (ref Output output) if (isOutputRange!(Output, char)) { import std.format : formattedWrite; output.formattedWrite!"%s"(2 * this.n); } } void main () { import std.stdio : writeln; auto s = S(2); // should output `4` if output-range toString is used, // but will output `S(2)` if not writeln(s); } ``` This code compiles and runs fine, and produces the default struct formatting output: S(2) ... instead of the custom toString expected output: 4 ... so, the custom toString is being silently ignored. I assume the reason is that the `if (isOutputRange!(Output, char))` check evaluates to false because the `isOutputRange` symbol is not defined, so the toString implementation is never resolved. This is very unintuitive, as one would expect compilation to fail because of the undefined `isOutputRange` symbol. Given that this templated `toString` form is the standard recommendation for how to write custom string formatting, it seems important that user implementation bugs like the one above should be clearly exposed -- not silently elided as described here. --
Sep 05 2020