[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