[Issue 15027] cannot pass arguments of type DirEntry to std.file functions

via Digitalmars-d-bugs digitalmars-d-bugs at puremagic.com
Thu Sep 10 20:49:58 PDT 2015


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

--- Comment #1 from Kenji Hara <k.hara.pg at gmail.com> ---
It's hard to resolve issue with current D language features.

Reduced case:
----
void popFront(T)(ref T[] a) { a = a[1..$]; }

enum bool isInputRange(R) = is(typeof(
{
    R r;
    r.popFront();
}));

struct DirEntry
{
    @property string name() { return ""; }
    alias name this;
}
pragma(msg, isInputRange!DirEntry); // prints 'false'
pragma(msg, isInputRange!(typeof(DirEntry.init.name))); // prints 'true'

bool isDir(R)(R r) if (isInputRange!R) { return true; }

void main()
{
    DirEntry de;
    bool c = isDir(de); // [A] cannot match!
}

At line [A], `isDir` template function tries to deduce R from the function
argument `de`. Although the type DirEntry matches R and deduction succeeds,
IFTI fails to satisfy the template constraint isInputRange!R.

What we need is R will be deduced to string, which is the type of alias this
expression `de.name`.
Sadly template constraint evaluation happens *after* the each template
parameter deductions succeeds. In other words, currently we have no way to
reject the match of R with DirEntry.

A workaround code would be something like:

bool isDir(Range)(Range range) if (isInputRange!Range ||
is(StringTypeOf!Range))
{
    static if (is(StringTypeOf!Range) && isAggregate!Range)
        alias R = StringTypeOf!Range;
    else
        alias R = Range;

    static bool isDirImpl(R r) { ... }

    return isDirImpl(range);
    // expect alias this expansion on function arguments
}

However, it requires redundant copy and destruction of DirEntry. So it would
not become a solution.

--


More information about the Digitalmars-d-bugs mailing list