Getting bound method when method is overidding a generic method from superclass

The following code compiles in Swift 4.0.2 but then has a runtime crash, while it causes a compiler crash when trying to validate the SIL in later Swift snapshots. Can someone explain to me what's going on and why this is not permitted, or why this isn't given a diagnostic error?

class Parent<E: Numeric> {
    let base: E

    init(base: E) {
        self.base = base
    }
    
    func doThing(with n: E, thing: (E) -> E) -> E {
        return thing(base + n)
    }
}

class Child : Parent<Int> {
    override func doThing(with n: Int, thing: (Int) -> Int) -> Int {
        return thing(base + n)
    }
}

let child = Child(base: 2)
let childDoThing = child.doThing(with:thing:)

print(childDoThing(4, -)) // Runtime crash in Swift 4.0.2

The compiler crashes with:

SIL verification failed: convert_function cannot change function ABI
  Different return value conventions
  @callee_guaranteed (@in Int, @owned @noescape @callee_guaranteed (@in Int) -> @out Int) -> @out Int
  @callee_guaranteed (Int, @owned @noescape @callee_guaranteed (Int) -> Int) -> Int

...

1.	While silgen emitCurryThunk SIL function "@_T07testing5ChildC7doThingS2i4with_S2ic5thingtFTc".
 for 'doThing(with:thing:)' at /Users/erik/Projects/xcode/testing/testing/main.swift:14:14
2.	While verifying SIL function "@_T07testing5ChildC7doThingS2i4with_S2ic5thingtFTc".
 for 'doThing(with:thing:)' at /Users/erikProjects/xcode/testing/testing/main.swift:14:14

Looks like a compiler bug regarding thunks for calling conventions.

Perhaps @dabrahams knows more.

Yeah it seems like a bug to me. Also sounds similar to another issue I saw on JIRA but I can't for the life of me find that ticket. I don't think they were the exact same case, but it was a similar issue.

Ah yes, this is a known issue reported by @Slava_Pestov [SR-4425] SIL verifier failure when partially applying method that's overridden in a concrete subclass of a generic class · Issue #47002 · apple/swift · GitHub

Moving to development category since this is a bug. I've started looking at this but this is my first time looking into the compiler, so I'm still learning the architecture and SIL. But am I wrong in guessing this has something to do with this todo? From my naive probing, it looks like it's getting confused as to what the conventions of the thunk should be.

@Slava_Pestov Is there any insight you can offer here? I kind of hit a wall and put this on hold, but I'm starting to look at this again.

You're absolutely right that this FIXME is where the problem lies. Instead of emitting a convert_function SIL instruction directly, which we can only do when the conversion is ABI-compatible, we need to call transformValue(), which compares AST types and emits a thunk if necessary. The details are tricky because it's not convenient to get the AST types in question here, which is why I didn't figure it out when I looked at it most recently. I didn't spend long on it though.

If you come up with something let me know and I'll review your PR!

@Slava_Pestov It's been awhile, but I've finally had some time to circle back to this. I'm working on some changes that seem to be fixing the issue.

Here's a gist that takes you to the new curry thunk with my changes. (also has the main.swift attached for reference). I should hopefully be able to cleanup my changes for a PR sometime this weekend.