Skip to content

[Swift Export] KT-87947: Enable inheritance from abstract bases. - #7113

Open
glukianets wants to merge 1 commit into
masterfrom
rrn/rd/KT-87947-cross-language-inheritance-abstract-classes
Open

[Swift Export] KT-87947: Enable inheritance from abstract bases.#7113
glukianets wants to merge 1 commit into
masterfrom
rrn/rd/KT-87947-cross-language-inheritance-abstract-classes

Conversation

@glukianets

Copy link
Copy Markdown

Expose abstract base class constructors in swift.
Ignore calls to abstract class constructors in FIR for exported bridges
KT-86403: allocate kotlin counterpart objects for swift inheritance with the right TypeInfo from the start.

Expose abstract base class constructors in swift.
Ignore calls to abstract class constructors in FIR for exported bridges
KT-86403: allocate kotlin counterpart objects for swift inheritance with the right TypeInfo from the start.
@kotlin-safemerge

kotlin-safemerge Bot commented Jul 29, 2026

Copy link
Copy Markdown

Code Owners

RuleOwnersApproval
/​compiler/​fir/​
kotlin-frontend

UNASSIGNED
/​compiler/​ir/​backend.​native/​
kotlin-common-backend
kotlin-native
🔴
mMaxy
/​compiler/​ir/​ir.​inline/​
kotlin-common-backend

UNASSIGNED
/​kotlin-​native/​
kotlin-native
🔴
mMaxy
/​native/​swift/​anton-bannykh, glukianets, haitaka, mMaxy, rickclephas🔴
mMaxy
PR commands for maintainers
CommandDescriptionParameters
/safe-mergeRebase-merges with automatic fixup commit squashing--fixup Autosquash fixup commits (on by default)
/safe-squash-mergeSquash-merges with optional commit title/body override--title Title of the squashed commit
--message Body of the squashed commit
/dry-runRuns the test pipeline with changes rebased on latest master--retry Retry the CI run on failure
/test-publicTriggers the public test suite without rebasing on latest master
/test-privateTriggers the private test suite without rebasing on latest master
/codeownersTriggers code owners check and comment update
/fixupSquashes fixup commits and force pushes the branch
/cancel-coordinatorCancels the merge coordinator currently running for this branch

return expression
}

return IrDelegatingConstructorCallImpl(

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I feel like there should be tests for this PR?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry, I'm not really familiar with this codebase. Do I understand correctly, that we have moved this lovering to the first phase of the compiler? Does that mean, that for an abstract class to work in swift export - it declaration should be compiled to klib with a certain compiler?

If so - that would render all our 3rd party libraries that relies on abstract classes unusable with swift export, until theirs kills are republished with 2.5.0 compiler. Correct?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes to all.

The specific reason for this is that we have partial linkage check that locates every call to an abstract class constructor and replaces it with an error-node. This check was particularly hard to isolate and disable specifically for swift export. So instead I use an early phase to re-write our super calls to IrDelegatingConstructorCall - which PL accepts fine.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it possible to provide a human readable explanation as a reason to a failed build, when this is the case? Should we do that?

// Leave the second argument of [initInstance] as is.
super.visitConstructorCall(constructorCall)
// Leave the second argument of [initInstance] as is, but coerce its arguments.
super.visitFunctionAccess(constructorCall)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Shouldn't we preserve visitConstructorCall for the IrConstructorCall?

@@ -91,12 +90,7 @@ public class SirVisibilityCheckerImpl(
} else return@withSessions exported
}
is KaConstructorSymbol -> {
if ((ktSymbol.containingSymbol as? KaClassSymbol)?.modality?.isAbstract() != false) {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I bet that now you can instantiate a swift inheritor of a sealed base class, like so

// kt
sealed class A
class B: A()
// swift 
class C: A {}

let c: A = C()

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants