module imports.link15194std;

// std.algorithm.setopts

/* setUnion template function is instantiated in module link15194 as root,
 * and linked into executable.
 *
 * - In "original case", due to link to typeid(const RBRange!(RBNode!int*)),
 *   unSpeculative should be called for the type of typeid operand.
 *
 * - In "additional case", typeid(const RBRange!(RBNode!int*)*) returns
 *   TypeInfo_Pointer instance. But later its 'next' field access will reference
 *   RBRange instance. Therefore typeid should also unSpeculative the bottom struct
 *   of operand type.
 */
version (A)
{
    // additional case

    TypeInfo setUnion(Rs...)(Rs )
    {
        return typeid(const Rs[0]*).next;

        // semanticTypeInfo should also unSpaculate TypePointer.next.
    }
}
else
{
    // original case

    struct SetUnion(Rs...)
    {
        pragma(msg, Rs);
        Rs r;

        // Rs[0] == RBRange!(RBNode!int*)
        // Rs[1] == int[]

        // size_t toHash() is implicitly generated by buildXtoHash.
        // And from that,
        //  typeid(const RBRange!(RBNode!int*))
        // and
        //  typeid(const int[])
        // are referenced to invoke TypeInfo.getHash().
    }

    SetUnion!(Rs) setUnion(Rs...)(Rs )
    {
        return typeof(return)();
    }
}

// std.container.rbtree

struct RBNode(V) {}

struct RBRange(N) {}

class RedBlackTree(Elem)
{
    alias Range = RBRange!(RBNode!Elem*);

    Range opSlice()
    {
        return Range();
    }
}
