www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.bugs - [Issue 21270] New: RedBlackTree fails to instantiate with a type

https://issues.dlang.org/show_bug.cgi?id=21270

          Issue ID: 21270
           Summary: RedBlackTree fails to instantiate with a type with a
                    toString taking a  safe sink
           Product: D
           Version: D2
          Hardware: All
                OS: All
            Status: NEW
          Severity: major
          Priority: P1
         Component: phobos
          Assignee: nobody puremagic.com
          Reporter: andrej.mitrovich gmail.com

-----
import std.container;

void main ()
{
    static struct S
    {
        void toString (scope void delegate(const(char)[])  safe sink) const
 safe { }
        int opCmp (in S data) const { return 0; }
    }

    RedBlackTree!S tree;
}
-----

```
~/dev/d master * $ dmd test.d
/Library/D/dmd/src/phobos/std/format.d(4049): Error: function
test.main.S.toString(scope void delegate(const(char)[])  safe sink) const is
not callable using argument types (void delegate(scope const(char)[] s)
 system) const
/Library/D/dmd/src/phobos/std/format.d(4049):        cannot pass argument
__lambda4 of type void delegate(scope const(char)[] s)  system to parameter
scope void delegate(const(char)[])  safe sink
/Library/D/dmd/src/phobos/std/format.d(4430): Error: template instance
std.format.formatObject!(void delegate(const(char)[]), const(S), char) error
instantiating
/Library/D/dmd/src/phobos/std/format.d(1875):        instantiated from here:
formatValueImpl!(void delegate(const(char)[]), const(S), char)
/Library/D/dmd/src/phobos/std/format.d(3756):        instantiated from here:
formatValue!(void delegate(const(char)[]), const(S), char)
/Library/D/dmd/src/phobos/std/format.d(3505):        instantiated from here:
formatElement!(void delegate(const(char)[]), const(S), char)
/Library/D/dmd/src/phobos/std/format.d(4434):        ... (2 instantiations, -v
to show) ...
/Library/D/dmd/src/phobos/std/container/rbtree.d(1852):        instantiated
from here: formatValue!(void delegate(const(char)[]),
RBRange!(const(RBNode!(S))*), char)
test.d(11):        instantiated from here: RedBlackTree!(S, "a < b", false)
/Library/D/dmd/src/phobos/std/format.d(3533): Error: template instance
std.format.formatValue!(void delegate(const(char)[]), const(S), char) error
instantiating
/Library/D/dmd/src/phobos/std/format.d(4434):        instantiated from here:
formatRange!(void delegate(const(char)[]), RBRange!(const(RBNode!(S))*), char)
/Library/D/dmd/src/phobos/std/format.d(1875):        instantiated from here:
formatValueImpl!(void delegate(const(char)[]), RBRange!(const(RBNode!(S))*),
char)
/Library/D/dmd/src/phobos/std/container/rbtree.d(1852):        instantiated
from here: formatValue!(void delegate(const(char)[]),
RBRange!(const(RBNode!(S))*), char)
test.d(11):        instantiated from here: RedBlackTree!(S, "a < b", false)
```

The issue is this code in rbtree.d:

-----
/**
  Formats the RedBlackTree into a sink function. For more info see $(D
  std.format.formatValue). Note that this only is available when the
  element type can be formatted. Otherwise, the default toString from
  Object is used.
 */
static if (is(typeof((){FormatSpec!(char) fmt; formatValue((const(char)[]) {},
ConstRange.init, fmt);})))
{
    void toString(scope void delegate(const(char)[]) sink, scope const ref
FormatSpec!char fmt) const
    {
        sink("RedBlackTree(");
        sink.formatValue(this[], fmt);
        sink(")");
    }
}
-----

Making the delegate in `toString` not ` safe` avoids this error.

--
Sep 22 2020