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

2015-10-09 Thread via Digitalmars-d-bugs
https://issues.dlang.org/show_bug.cgi?id=15027

--- Comment #17 from Rainer Schuetze  ---
>auto isDir(Range)(ref Range input)

"auto ref" seems to work even better.

--


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

2015-10-09 Thread via Digitalmars-d-bugs
https://issues.dlang.org/show_bug.cgi?id=15027

--- Comment #16 from Rainer Schuetze  ---
Here is a version that overloads structs with alias this to a string range by
reference, avoiding the copy problem:

auto isDir(Range)(Range input)
if (isForwardRange!Range && isSomeChar!(ElementEncodingType!Range))
{
//...
}

auto isDir(Range)(ref Range input)
if (!(isForwardRange!Range && isSomeChar!(ElementEncodingType!Range))
&& is(StringTypeOf!Range))
{
return isDir(cast(StringTypeOf!Range) input);
}

--


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

2015-10-07 Thread via Digitalmars-d-bugs
https://issues.dlang.org/show_bug.cgi?id=15027

--- Comment #15 from Rainer Schuetze  ---
>Check this out:
>https://github.com/D-Programming-Language/phobos/pull/3694

This is pretty much the workaround given by Kenji above. It has the downside
that you have to copy the full DirEntry object to the stack as a function
argument. Not a big issue for DirEntry, but it can be pretty bad if the struct
has an expensive postblit or if it is disabled.

--


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

2015-10-07 Thread via Digitalmars-d-bugs
https://issues.dlang.org/show_bug.cgi?id=15027

--- Comment #14 from Walter Bright  ---
Check this out:

https://github.com/D-Programming-Language/phobos/pull/3694

--


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

2015-10-06 Thread via Digitalmars-d-bugs
https://issues.dlang.org/show_bug.cgi?id=15027

--- Comment #12 from Walter Bright  ---
(In reply to Martin Nowak from comment #10)
> (In reply to Walter Bright from comment #5)
> > Or, (2) can be accomplished by overloading isDir() to accept string
> > arguments. But this implies adding an overload to every function that
> > accepts an InputRange. This is out of the question.
> 
> What's the problem with that? It's rather good to precompile the common
> template instantiations into phobos.

The problem is that it pretty much doubles the number of functions in Phobos.
And means that everyone who writes a reusable library has to have double
functions.

--


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

2015-10-06 Thread via Digitalmars-d-bugs
https://issues.dlang.org/show_bug.cgi?id=15027

--- Comment #13 from Walter Bright  ---
(In reply to Rainer Schuetze from comment #8)
> It still fails, so instead of emitting an error message the compiler could
> change the type of the function arguments to the aliased type and retry
> deduction and constraint check. For multiple arguments with alias this, this
> could lead to a large number of possible combinations to try, though.

Given how overloading even now can lead to inexplicable seeming results, I view
such an additional layer of complexity as a looming disaster, especially with
the combinatorial aspect of it.

I have thought about something like:

struct foo(T : isInputRange) { ... }

where the constraint would become part of the type deduction logic, but that's
a major addition to the language, not something we can just throw in.

--


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

2015-10-06 Thread via Digitalmars-d-bugs
https://issues.dlang.org/show_bug.cgi?id=15027

--- Comment #8 from Rainer Schuetze  ---
> The trouble is that it fails in the constraint, not the type deduction part.

It still fails, so instead of emitting an error message the compiler could
change the type of the function arguments to the aliased type and retry
deduction and constraint check. For multiple arguments with alias this, this
could lead to a large number of possible combinations to try, though.

--


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

2015-10-06 Thread via Digitalmars-d-bugs
https://issues.dlang.org/show_bug.cgi?id=15027

Martin Nowak  changed:

   What|Removed |Added

 CC||rburn...@gmail.com

--- Comment #9 from Martin Nowak  ---
*** Issue 15057 has been marked as a duplicate of this issue. ***

--


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

2015-10-06 Thread via Digitalmars-d-bugs
https://issues.dlang.org/show_bug.cgi?id=15027

--- Comment #11 from Martin Nowak  ---
Slight variation of the bug where the aliased string is an lvalue, but cannot
be assigned.

cat > bug.d << CODE
struct InternedString
{
void opAssign(InternedString other)
{
this.data = other.data;
}

string data;
alias data this;
}

auto bug(InternedString s)
{
import std.file : exists;
return exists(s);
}
CODE

This breaks b/c some code in utf.d tries to `r = r[1 .. $]` slice an
InternedString.

--


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

2015-10-06 Thread via Digitalmars-d-bugs
https://issues.dlang.org/show_bug.cgi?id=15027

Martin Nowak  changed:

   What|Removed |Added

 CC||c...@dawg.eu

--- Comment #10 from Martin Nowak  ---
(In reply to Walter Bright from comment #5)
> Or, (2) can be accomplished by overloading isDir() to accept string
> arguments. But this implies adding an overload to every function that
> accepts an InputRange. This is out of the question.

What's the problem with that? It's rather good to precompile the common
template instantiations into phobos.

--


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

2015-10-05 Thread via Digitalmars-d-bugs
https://issues.dlang.org/show_bug.cgi?id=15027

--- Comment #6 from Rainer Schuetze  ---
> Leaving us with rewriting isDir(de) to isDir(de.name). 
> That seems to be the most practical solution.

While feasible in the case of dirEntry (though breaking existing code), it will
not help in the more general case, i.e. you cannot call a template function if
the alias this type matches the constraints, but the struct type does not.

Maybe template argument type deduction should just try the aliased type if the
struct type itself fails. Doesn't this fit with other rules regarding "alias
this"?

--


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

2015-10-05 Thread via Digitalmars-d-bugs
https://issues.dlang.org/show_bug.cgi?id=15027

--- Comment #7 from Walter Bright  ---
(In reply to Rainer Schuetze from comment #6)
> Maybe template argument type deduction should just try the aliased type if
> the struct type itself fails. Doesn't this fit with other rules regarding
> "alias this"?

The trouble is that it fails in the constraint, not the type deduction part.

--


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

2015-10-04 Thread via Digitalmars-d-bugs
https://issues.dlang.org/show_bug.cgi?id=15027

--- Comment #5 from Walter Bright  ---
I thought about this for quite a while. The bottom line is DirEntry is being
too clever in using alias this to wrap a string, and should simply stick with
DirEntry.name when the name is desired.

Rationale:

An InputRange, by its very nature, consumes its input. If DirEntry were made
into an InputRange, then it would consume the name and eventually the name
string will be empty.

DirEntry's alias this is returning a copy of its data, meaning that even if it
compiled as an InputRange, the popFront would never advance, as it would keep
getting reset every time.

So, the solution can only be one of:
1. DirEntry is an InputRange.
2. DirEntry is converted to an InputRange before passing to isDir().

The trouble with (1) is that DirEntry then becomes consumed, which would be
surprising behavior. (2) can be accomplished by not using alias this, but just
using de.name() directly.

Or, (2) can be accomplished by overloading isDir() to accept string arguments.
But this implies adding an overload to every function that accepts an
InputRange. This is out of the question.

Leaving us with rewriting isDir(de) to isDir(de.name). That seems to be the
most practical solution.

--


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

2015-10-02 Thread via Digitalmars-d-bugs
https://issues.dlang.org/show_bug.cgi?id=15027

Walter Bright  changed:

   What|Removed |Added

 CC||bugzi...@digitalmars.com

--- Comment #3 from Walter Bright  ---
(In reply to Rainer Schuetze from comment #2)
> The main problem is that DirEntry does not qualify as an InputRange, because
> the aliased property returns an rvalue. This cannot be passed to popFront
> through UFCS as it expectes a ref argument.

I think this is correct. If you remove the 'ref' from 'popFront', it works. It
also works if DirEntry is defined as:

string name;
alias name this;

i.e. then 'name' becomes an lvalue. popFront() cannot update an rvalue.

--


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

2015-10-02 Thread via Digitalmars-d-bugs
https://issues.dlang.org/show_bug.cgi?id=15027

--- Comment #4 from Walter Bright  ---
The trouble is InputRange has to modify the range.

A solution is to rewrite DirEntry.name from:
@property string name() const pure nothrow
{
return _name;
}
to:
string _name2;
@property ref string name() return const pure nothrow
{
_name2 = _name;
return _name2;
}
but there'll be trouble with that if there are two calls to name() within the
same expression and both try to modify through the ref.

--


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

2015-09-11 Thread via Digitalmars-d-bugs
https://issues.dlang.org/show_bug.cgi?id=15027

Vladimir Panteleev  changed:

   What|Removed |Added

 CC||thecybersha...@gmail.com
   See Also||https://issues.dlang.org/sh
   ||ow_bug.cgi?id=14765

--


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

2015-09-10 Thread via Digitalmars-d-bugs
https://issues.dlang.org/show_bug.cgi?id=15027

--- Comment #1 from Kenji Hara  ---
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.

--