www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.bugs - [Issue 4998] New: make IFTI use the template constraint when determining the type of literals

reply d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=4998

           Summary: make IFTI use the template constraint when determining
                    the type of literals
           Product: D
           Version: D2
          Platform: Other
        OS/Version: Linux
            Status: NEW
          Severity: enhancement
          Priority: P2
         Component: DMD
        AssignedTo: nobody puremagic.com
        ReportedBy: schveiguy yahoo.com



04:25:24 PDT ---
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.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
Oct 06 2010
parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=4998




06:35:08 PST ---
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
}

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
Nov 17 2011