Why retain/release pair is not removed in this particular case?

Thanks a lot, @Karl ! With indices this particular issue is fixed, however I have another puzzle for you :grinning:

struct V {
    func take(a: Wrap) {
        a.a.stuff()
    }
}

class A {
    func stuff() { }
}

struct Wrap {
    let a: A
}

struct B {
    let a = A()
    var b = V()

    func d() {
        b.take(a: Wrap(a: self.a))
    }
}

var b = B()
b.d()

Godbolt

output.B.d() -> ():
        push    r13
        push    rbx
        push    rax
        mov     r13, rdi
        mov     rax, qword ptr [rdi]
        mov     rbx, qword ptr [rax + 56]
        call    swift_retain@PLT
        call    rbx
        mov     rdi, r13
        add     rsp, 8
        pop     rbx
        pop     r13
        jmp     swift_release@PLT

As far as I can tell, the issue is induced by Wrap struct. Again, I have managed to optimize it by declaring Wrap.a as Unmanaged<A> and using _withUnsafeGuaranteedRef to access A, but I am looking for "safe" solution.

In my program, Wrap is actually doing useful logic and Wrap.a is private.

PS. Enabling -enable-ossa-modules fixes this issue. Is there any other workarounds?
PPS. Looks similar to this thread to me.

1 Like