www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.bugs - [Issue 21228] New: OutputRange-based toString is silently ignored if


          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

This code compiles and runs fine, and produces the default struct formatting


... instead of the custom toString expected output:


... 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