Bug 4998 – make IFTI use the template constraint when determining the type of literals

Status
NEW
Severity
enhancement
Priority
P4
Component
dmd
Product
D
Version
D2
Platform
Other
OS
Linux
Creation time
2010-10-06T04:25:24Z
Last change time
2024-12-13T17:53:41Z
Assigned to
No Owner
Creator
Steven Schveighoffer
Moved to GitHub: dmd#18306 →

Comments

Comment #0 by schveiguy — 2010-10-06T04:25:24Z
One of the annoyances of IFTI is that it interprets literals the same as auto does. This means, you cannot wrap functions that you don't know the argument types. A simple example: void foo(short s) {} void foo2(T)(T t) {foo(t);} void main() { foo(1); // ok foo2(1); // fail } This becomes very important with operators and opDispatch, since you use IFTI almost exclusively. What we really need is a way to direct IFTI to use a specific function to look up what a literal should be. Trying different types to build the function might be difficult, it might require several passes over the code, and conditional compilation based on type can make this very messy. However, we have a perfect place to direct IFTI -- the template constraint. It is evaluated before instantiation, so you have the right place to intercept it. What I'm proposing is, when a IFTI is evaluating a function, it should not assume a type for a literal until it evaluates the template constraint. If a clause in the template constraint is of the form: is(typeof(<some expression using T instance>)) Where T is automatically determined by IFTI from a literal, then the compiler will try to use all possible types for the literal to find the most suitable match. For instance, if the above code is written: void foo2(T)(T t) if(is(typeof(foo(t)))) {foo(t);} Then the compiler can appropriately instantiate foo2!short when called with foo2(1). This might be tricky, but I think it will work. As an alternative, we can add another "special" case for an is expression to better define what we want. Something like: void foo2(T, S...)(T t) if(is(foo(T) S == overload)) which says "If I was to call foo(t) where t is of type T (which could be a tuple or multiple types), evaluate to true if it can be done, and assign the parameter tuple that would be used to type S" Wrapping/intercepting calls for a type is very difficult to get right without this kind of thing, especially when you want to allow passing literals to a function.
Comment #1 by schveiguy — 2011-11-17T06:35:08Z
I will add that the simple example has a simpler solution, but the real problem (of wrapping arbitrary overload sets) is not solved that way. Reforming the example: void foo(short s) {} void foo(wstring s) {} void foo2(T)(T t) {foo(t);} void main() { foo(1); foo("hello"); foo2(1); // fails foo2("hello"); // fails }
Comment #2 by robert.schadek — 2024-12-13T17:53:41Z
THIS ISSUE HAS BEEN MOVED TO GITHUB https://github.com/dlang/dmd/issues/18306 DO NOT COMMENT HERE ANYMORE, NOBODY WILL SEE IT, THIS ISSUE HAS BEEN MOVED TO GITHUB