CLOVIS
07/23/2026, 5:03 PMinterface FooDsl
interface Foo {
fun foo(block: FooDsl.() -> Unit)
}
class SpecificDsl : FooDsl
abstract class Specific : Foo {
override fun foo(block: SpecificDsl.() -> Unit) {}
}
The intent is that Specific.foo 's argument's receiver is a subtype of the declared receiver. That should be sound: the method will provide to the lambda a receiver that is a subtype of what is declared in the parent interface, that's fine. However, I'm hitting the Kotlin limitation with invariant parameters:
'foo' overrides nothing.
I can kinda cheat that with an overload:
abstract class Specific : Foo {
@JvmName("fooSpecific")
fun foo(block: SpecificDsl.() -> Unit) {}
override fun foo(block: FooDsl.() -> Unit) {}
}
but it appears the compiler prefers calling the override rather than the new overload.
I cannot modify FooDsl and Foo . Is there a trick to making the specific overload more specific to the eyes of the compiler?Youssef Shoaib [MOD]
07/23/2026, 5:28 PMCLOVIS
07/23/2026, 5:29 PMYoussef Shoaib [MOD]
07/23/2026, 5:32 PMabstract class Specific : Foo {
@JvmName("fooSpecific")
fun foo(block: SpecificDsl.() -> Unit) {}
@Deprecated("", level = DeprecationLevel.HIDDEN)
override fun foo(block: FooDsl.() -> Unit) {}
}CLOVIS
07/23/2026, 5:33 PMCLOVIS
07/23/2026, 5:33 PMLowPriorityInOverloadResolution , but deprecation is definitely better