Skip to content

A4: a fun interface method has no body - #10

Merged
milyin merged 1 commit into
docs/validation-umbrellafrom
step/a4-fun-signature
Aug 6, 2026
Merged

A4: a fun interface method has no body#10
milyin merged 1 commit into
docs/validation-umbrellafrom
step/a4-fun-signature

Conversation

@milyin

@milyin milyin commented Aug 6, 2026

Copy link
Copy Markdown
Owner

Fourth step of #6. Stacked on #9.

KtFunInterface::method was a full KtFun, which can carry a body, and
render_fun_interface rendered it verbatim — body included. A fun interface
must have exactly one abstract method, so that output had none at all:

fun interface Handler {
    fun run(v: Long): Boolean { return true }   // no abstract method -> error
}

KtFunSig is everything a KtFun has except a body and modifiers.
KtFunInterface::method holds one, so the shape is now unbuildable.

The type earns its keep twice

An abstract member is a signature, so KtFunSig is the natural way to
declare one:

KtClass::interface_("Codec").member(
    KtFunSig::new("encode")
        .param(KtParam::new("v", KtType::string()))
        .returns(KtType::byte_array()),
)

KtFunSig converts into KtFun (body None) and into KtDecl;
KtFun::signature() goes the other way. That last one replaces the
strip-the-body-and-modifiers helper a consumer would otherwise hand-write —
prebindgen-jni has exactly such a function today.

Rendering

KtFun and KtFunSig share one layout implementation through an internal
SigView, so the width-driven parameter breaking is factored out rather than
duplicated. Import collection splits too: a signature has no body, so only
parameter defaults can carry imports.

Verification

All 46 pre-existing tests pass untouched. Three added: the rendered
fun interface, a signature used as an interface member, and the
KtFun::signature() round trip. cargo clippy --all-targets clean.

Copilot AI left a comment

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.

🟢 Ready to approve

The changes consistently enforce Kotlin SAM constraints, update rendering/import collection paths accordingly, and add targeted tests for the new behavior.

This review doesn't count toward merge requirements. Sign up for the private preview to control whether Copilot approvals count.

Pull request overview

This PR strengthens the Kotlin declaration model by making fun interface (SAM) methods structurally unbuildable with bodies, introducing KtFunSig as a bodyless/modifierless function signature and reusing it for abstract-member rendering and import collection.

Changes:

  • Introduces KtFunSig and switches KtFunInterface::method from KtFun to KtFunSig to prevent bodied SAM methods.
  • Refactors rendering to share a single signature-layout implementation between KtFun and KtFunSig via SigView, and updates raw-import collection accordingly.
  • Adds tests covering fun interface rendering, using KtFunSig as an interface member, and KtFun::signature() round-tripping.
File summaries
File Description
src/model.rs Adds KtFunSig, updates KtFunInterface to store a signature, and adds KtFun::signature() conversion.
src/render.rs Adds shared signature rendering (SigView), adds render_fun_sig, and updates import collection for signature-only functions.
src/tests.rs Updates raw-import collection test for SAM signatures and adds 3 new tests for the new API/behavior.
src/lib.rs Re-exports KtFunSig as part of the public API surface.
Review details
  • Files reviewed: 4/4 changed files
  • Comments generated: 0
  • Review effort level: Lite

We're testing this review assessment. Please use 👍 or 👎 to tell us if it's correct.

@milyin milyin mentioned this pull request Aug 6, 2026
15 tasks
`KtFunInterface::method` was a full `KtFun`, which can carry a body, and
`render_fun_interface` rendered the method verbatim — body included. A
`fun interface` must have exactly one *abstract* method, so that output
had none at all and did not compile.

Introduce `KtFunSig`: everything a `KtFun` has except a body and
modifiers. `KtFunInterface::method` holds one, so a bodied SAM method is
unrepresentable.

The type earns its keep beyond that: an abstract member *is* a
signature. `KtFunSig` converts into `KtFun` (body `None`) and into
`KtDecl`, so an interface can declare `.member(KtFunSig::new(...))`
instead of reaching for a body-less `KtFun`; `KtFun::signature()` goes
the other way, replacing the strip-body-and-modifiers helper a consumer
would otherwise hand-write.

`KtFun` and `KtFunSig` share one layout implementation through an
internal `SigView`, so the width-driven parameter breaking is not
duplicated. All 46 pre-existing tests pass untouched.
@milyin
milyin force-pushed the step/a4-fun-signature branch from b3c8bd1 to ce48226 Compare August 6, 2026 11:40
@milyin
milyin force-pushed the step/a3-supertype-split branch from 42802fc to 808547c Compare August 6, 2026 11:40
@milyin
milyin changed the base branch from step/a3-supertype-split to docs/validation-umbrella August 6, 2026 11:40
@milyin
milyin merged commit 3a92330 into docs/validation-umbrella Aug 6, 2026
1 of 4 checks passed
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