[Issue 21228] New: OutputRange-based toString is silently ignored if isOutputRange is not imported

d-bugmail at puremagic.com d-bugmail at puremagic.com
Sat Sep 5 19:13:13 UTC 2020


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 at puremagic.com
          Reporter: joseph.wakeling at 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.

--


More information about the Digitalmars-d-bugs mailing list