Thread overview | |||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|
|
May 11, 2020 Bug? | ||||
---|---|---|---|---|
| ||||
Why doesn't it compile? ``` struct Range(R) { import std.array : empty, front, popFront; R range; bool empty() const { return range.empty; } auto front() const { return range.front; } void popFront() { range.popFront(); } } void main() { auto rng = Range!string("1234"); assert(rng.front == 1); } ``` onlineapp.d(11): Error: void has no value onlineapp.d(11): Error: incompatible types for (rng.front) == (1): void and int try here: https://run.dlang.io/is/Dg8Fpr If you move the import to the global scope, you will get a weird result: ``` import std.stdio; import std.array : empty, front, popFront; struct Range(R) { R range; bool empty() const { return range.empty; } auto front() const { return range.front; } void popFront() { range.popFront(); } } void main() { auto rng = Range!string("1234"); writefln("front: %s", rng.front); assert(rng.front == 1); } ``` front: 1 core.exception.AssertError@onlineapp.d(14): Assertion failure ---------------- ??:? _d_assertp [0x56107489bc75] onlineapp.d:14 _Dmain [0x561074889902] try here: https://run.dlang.io/is/arieKR WAT??? |
May 11, 2020 Re: Bug? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Jack Applegame | On Monday, 11 May 2020 at 12:20:06 UTC, Jack Applegame wrote:
> assert(rng.front == 1);
Damn! I made a typo. It must be:
assert(rng.front == '1')
So the second example works fine.
|
May 11, 2020 Re: Bug? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Jack Applegame | And the first example still doesn't compile: ``` struct Range(R) { import std.array : empty, front, popFront; R range; bool empty() const { return range.empty; } auto front() const { return range.front; } void popFront() { range.popFront(); } } void main() { auto rng = Range!string("1234"); assert(rng.front == '1'); } ``` onlineapp.d(11): Error: void has no value onlineapp.d(11): Error: incompatible types for (rng.front) == ('1'): void and char ``` |
May 11, 2020 Re: Bug? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Jack Applegame | On Monday, 11 May 2020 at 12:20:06 UTC, Jack Applegame wrote:
> If you move the import to the global scope
UFCS is only defined to work with global scope functions. A restricted import (module : symbol, symbols) puts things in local scope so ufcs doesn't apply.
(interestingly an unrestricted import does NOT do that, it keeps the functions in their original scope, so UFCS works if you locally `import std.range;` but not if you `import std.range : front, popFront, empty;`! lol. but this is... im pretty sure by design, it has been this way for ages.)
|
May 11, 2020 Re: Bug? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Adam D. Ruppe | On Monday, 11 May 2020 at 12:30:22 UTC, Adam D. Ruppe wrote:
> UFCS is only defined to work with global scope functions. A restricted import (module : symbol, symbols) puts things in local scope so ufcs doesn't apply.
But in this case the error should be displayed for lines 4 and 5, not 11.
Line 11 contains a call to a member function, not UFCS.
In addition, if you add the parentheses, then it works:
assert(rng.front() == '1');
|
May 11, 2020 Re: Bug? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Jack Applegame | On 5/11/20 8:44 AM, Jack Applegame wrote:
> On Monday, 11 May 2020 at 12:30:22 UTC, Adam D. Ruppe wrote:
>> UFCS is only defined to work with global scope functions. A restricted import (module : symbol, symbols) puts things in local scope so ufcs doesn't apply.
>
> But in this case the error should be displayed for lines 4 and 5, not 11.
> Line 11 contains a call to a member function, not UFCS.
>
> In addition, if you add the parentheses, then it works:
> assert(rng.front() == '1');
>
>
Yeah, this is definitely a bug. If I change the return type of front to dchar from auto, it still thinks it's returning void.
Calling things like popFront without parentheses has an error "rng.popFront has no effect".
Clearly something isn't connecting properly, it's almost like it's resolving to the function itself instead of calling it.
-Steve
|
May 11, 2020 Re: Bug? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Jack Applegame | On Monday, 11 May 2020 at 12:44:45 UTC, Jack Applegame wrote: > On Monday, 11 May 2020 at 12:30:22 UTC, Adam D. Ruppe wrote: >> UFCS is only defined to work with global scope functions. A restricted import (module : symbol, symbols) puts things in local scope so ufcs doesn't apply. > > But in this case the error should be displayed for lines 4 and 5, not 11. > Line 11 contains a call to a member function, not UFCS. > > In addition, if you add the parentheses, then it works: > assert(rng.front() == '1'); You're right, and it absolutely seems the call on lines 4 and 5 work correctly. Instead, the compiler is confused by the presence of two different overloads for front in Range!T, and doesn't attempt to call the one it can call. We get the exact same behavior here: struct S { int gun()(int i) { return 0; } alias fun = gun; int fun() { return 1; } } static assert(S().fun == 1); Filed here: https://issues.dlang.org/show_bug.cgi?id=20821 -- Simen |
May 11, 2020 Re: Bug? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Simen Kjærås | On Monday, 11 May 2020 at 13:12:37 UTC, Simen Kjærås wrote:
> Filed here: https://issues.dlang.org/show_bug.cgi?id=20821
Thanks.
|
May 11, 2020 Re: Bug? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Steven Schveighoffer | On Monday, 11 May 2020 at 13:06:59 UTC, Steven Schveighoffer wrote:
> Clearly something isn't connecting properly, it's almost like it's resolving to the function itself instead of calling it.
Since the imported front is also a local symbol the compiler probably thinks it is overloaded and not handling that right.....
|
Copyright © 1999-2021 by the D Language Foundation