Summary: Delegate .funcptr returns wrong type.
           Product: D
           Version: 2.025
          Platform: PC
        OS/Version: Windows
            Status: NEW
          Keywords: accepts-invalid, ice-on-valid-code, rejects-valid
          Severity: normal
          Priority: P2
         Component: DMD

The type of the function pointer returned by delegate.funptr appears to have
the same parameter list as the corresponding delegate.  This is incorrect,
since a function pointer in this form is useless for actually calling the
function in question.  The type of the function pointer should have the pointer
to whatever context is relevant added to its parameter list.

import std.stdio;

struct Foo {

    uint function() myFunPtr;
    uint i;

    uint myFun() {
        return i * 2;

void main() {
    Foo foo;
    foo.i = 2;
    auto someDelegate = &(foo.myFun);
    foo.myFunPtr = someDelegate.funcptr;  // Works.  Shouldn't.

    // Should be uint function(foo*).  Is uint function().

    /* Without this line of code, DMD outputs the assembly such that foo's this
     * pointer just happens to be in EAX.  This causes things to work, since
     * DMD passes the this pointer in EAX.  This line makes sure something else
     * gets written to EAX.*/
    uint fooRet = fooPtr();

    // Of course, this doesn't work because no this pointer is getting 
    // passed in.

auto fooPtr = &foo;  // Make call indirect so it can't be inlined.

uint foo() {
    return 1;

Also, the correct version of this code is rejected.  If I change the type of
Foo.myFunPtr to uint function(Foo*), I receive the following errors:

Assertion failure: 'tn->mod & MODinvariant || tn->mod & MODconst' on line 740
in file 'mtype.c'
test7.d(17): Error: cannot implicitly convert expression (*((&
someDelegate+4))) of type uint function() to uint function(Foo*)


Reply via email to