www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.bugs - [Issue 11326] New: move functions are not properly constrained and work improperly with templated functions

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

           Summary: move functions are not properly constrained and work
                    improperly with templated functions
           Product: D
           Version: D2
          Platform: All
        OS/Version: All
            Status: NEW
          Severity: normal
          Priority: P2
         Component: Phobos
        AssignedTo: andrej.mitrovich gmail.com
        ReportedBy: andrej.mitrovich gmail.com


--- Comment #0 from Andrej Mitrovic <andrej.mitrovich gmail.com> 2013-10-22
11:16:43 PDT ---
-----
import std.range;

struct NotRange
{
    int moveAt(T)(T index) { return 0; }
}

struct Range
{
     property int front() { return 0; }
    void popFront() { }
     property bool empty() { return false; }

    int moveFront()() { assert(0); }  // never called because it's a template!
}

void main()
{
    NotRange nr;
    // Internal error:
    // std\range.d(6870): Error: template std.array.front does not match any
function template declaration. Candidates are:
    // nr.moveFront();

    Range r;
    moveFront(r);
}
-----

Problems:

- Non-range types are accepted, leading to internal Phobos errors.
- moveFront/moveBack/moveTo check for the presence of a move function via the
address operator -- e.g. "static if (is(typeof(&r.moveFront)))", which will
fail for templated functions.

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



--- Comment #1 from Andrej Mitrovic <andrej.mitrovich gmail.com> 2013-10-22
11:42:39 PDT ---
Ok as it turns out checking for template member functions is actually very
difficult. I don't think we have the proper traits to derive whether something
is a templated member function that can be called a certain way belonging to an
aggregate and **not** a UFCS function.

The problem is really this:

static if (is(typeof(r.moveFront)))

This will end up calling a UFCS function if there's no member function, that's
why the current implementation uses an address-of operator. We need to get rid
of these styles of tricks and implement proper introspection utilities, meaning
we have helper templates in Phobos or __traits() which can tell us:

- Does symbol "abc" exist for an aggregate
  -> We already have hasMember!()

- Is the symbol a function which can be called via "obj.abc()"
  -> Not easy to figure out. Just testing "obj.abc()" may end up calling a UFCS
function instead. And a simple "&obj.abc" doesn't work for templated functions
either (current situation).

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
Oct 22 2013