Bug 9705 – property parameter-less template function not resolved in typeof

Status
RESOLVED
Resolution
INVALID
Severity
normal
Priority
P2
Component
dmd
Product
D
Version
D2
Platform
All
OS
All
Creation time
2013-03-12T11:44:14Z
Last change time
2020-03-21T03:56:39Z
Assigned to
No Owner
Creator
monarchdodra

Comments

Comment #0 by monarchdodra — 2013-03-12T11:44:14Z
There is a construct, where one defines a parameter template function, so that the compiler can infer its attributes. The problem is that when said function is a property, it doesn't mix with traits, because it fails the typeof blocks. Explanation: //---- import std.range; struct Infered { size_t length()(){return 0;} } void main() { Infered r; auto len = r.length; //OK static assert(hasLength!Infered); //Error: static assert (hasLength!(Infered)) is false static assert(is(typeof(r.length) : ulong)); //Error: static assert (is(typeof(r.length()()) : ulong)) is false pragma(msg, typeof(r.length).stringof); //Error: expression (r.length()()) has no type // while evaluating pragma(msg, (_error_).stringof) } //---- Such usage is very interesting for wrapper ranges, but they are the most vulnerable: Are concerned: hasLength. isForwardRange. isRandomAccessRange. One workaround is to make the call outside of the typeof, and store the result, and then test result itself eg is(typeof(len) : ulong)). Doing this would shuffle around a lot of code though, so I don't think it's worth doing it.
Comment #1 by b2.temp — 2017-12-21T01:32:02Z
The specs say that typeof(F) gets the function F return type only when it's marked @property. (https://dlang.org/spec/declaration.html#typeof, ยง4) When this rule is followed, the assertions are valid: ``` import std.range; struct Infered { size_t length()() @property {return 0;} } void main() { Infered r; auto len = r.length; //OK static assert(hasLength!Infered); //OK static assert(is(typeof(r.length) : ulong)); //OK pragma(msg, typeof(r.length).stringof); //OK } ```