[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