February 02, 2021
https://d.godbolt.org/z/r8Gj1b

Very odd results, or at least they seem odd to me. Lambdas being treated differently to nested functions, behaviour being different depending on whether there is a `pragma(inline, false)` function to forward to? Also, different behaviour depending on whether the `pragma(inline, false)` is inside or outside the function!

I ran in to this in a more significant chunk of code where a lambda wasn't being inlined as expected, what's here is a simple example case.

pragma(inline, false)
int foo1() {
    alias bar = (int s) => s;
    return bar(3);
}

version (TryThisToo) {} else
int foo5() {
    pragma(inline, false);
    alias bar = (int s) => s;
    return bar(3);
}

int foo2() {
    alias bar = (int s) => s;
    return bar(3);
}

pragma(inline, false)
int foo3() {
    int bar(int s) { return s; }
    return bar(3);
}

int foo4() {
    int bar(int s) { return s; }
    return bar(3);
}

All asm done with gdc 10.2 -O3

If we define TryThisToo we get

pure nothrow @nogc @safe int example.foo3().bar(int).constprop.0:
.LFB18:
.LVL0:
        mov     eax, 3
        ret
.LFE18:
pure nothrow @nogc @safe int example.foo1().__lambda1(int):
.LVL1:
.LFB1:
        mov     eax, edi
        ret
.LFE1:
int example.foo1():
.LFB0:
        mov     edi, 3
        call    pure nothrow @nogc @safe int example.foo1().__lambda1(int)
.LVL2:
        ret
.LFE0:
int example.foo2():
.LFB2:
        mov     eax, 3
        ret
.LFE2:
pure nothrow @nogc @safe int example.foo2().__lambda1(int):
.LFB15:
        jmp     pure nothrow @nogc @safe int example.foo1().__lambda1(int)
.LFE15:
int example.foo3():
.LFB4:
        call    pure nothrow @nogc @safe int example.foo3().bar(int).constprop.0
.LVL3:
        ret
.LFE4:
int example.foo4():
.LFB17:
        mov     eax, 3
        ret
.LFE17:


I we don't define it, we instead get:


pure nothrow @nogc @safe int example.foo3().bar(int).constprop.0:
.LFB24:
.LVL0:
        mov     eax, 3
        ret
.LFE24:
pure nothrow @nogc @safe int example.foo1().__lambda1(int):
.LVL1:
.LFB1:
        mov     eax, edi
        ret
.LFE1:
int example.foo1():
.LFB0:
        mov     edi, 3
        call    pure nothrow @nogc @safe int example.foo1().__lambda1(int)
.LVL2:
        ret
.LFE0:
int example.foo5():
.LFB2:
        mov     eax, 3
        ret
.LFE2:
pure nothrow @nogc @safe int example.foo5().__lambda1(int):
.LFB17:
        jmp     pure nothrow @nogc @safe int example.foo1().__lambda1(int)
.LFE17:
int example.foo2():
.LFB21:
        jmp     int example.foo5()
.LFE21:
pure nothrow @nogc @safe int example.foo2().__lambda1(int):
.LFB19:
        jmp     pure nothrow @nogc @safe int example.foo1().__lambda1(int)
.LFE19:
int example.foo3():
.LFB6:
        call    pure nothrow @nogc @safe int example.foo3().bar(int).constprop.0
.LVL3:
        ret
.LFE6:
int example.foo4():
.LFB23:
        jmp     int example.foo5()
.LFE23:
February 02, 2021
On Tuesday, 2 February 2021 at 20:42:38 UTC, John Colvin wrote:
> https://d.godbolt.org/z/r8Gj1b
>
> Very odd results, or at least they seem odd to me. Lambdas being treated differently to nested functions, behaviour being different depending on whether there is a `pragma(inline, false)` function to forward to? Also, different behaviour depending on whether the `pragma(inline, false)` is inside or outside the function!
>
> [...]

see also https://github.com/ldc-developers/ldc/issues/3652