package yamin
typealias Foo = () -> Unit
fun main() {
bar {
baz()
}
}
fun bar(foo: Foo) {
foo()
}
context(Foo)
fun baz() {
//
}
I tried to use a lambda type for the context of a function, which seems to be fine at this point but when I tried to call that function in that context, or at least what I think is that context I'm failing, and Kotlin's compiler is showing me this error for baz():
No required context receiver found: Cxt { context((yamin.Foo /* = () -> kotlin.Unit */)) public fun baz(): kotlin.Unit defined in yamin in file Main.kt[SimpleFunctionDescriptorImpl@7b5e305f] }
Maybe I misunderstood Kotlin's context receivers or I'm expecting something that it's not designed for. I just want to create a function that can only be called in certain context and in this example only in a certain lambda.
As it is right now, your
bazcan be called like this:By using
with, I bring an instance of() -> Unitinto the context, sosomeFoobecomes a context receiver with which I can callbaz. Inbaz, I can then access thissomeFooby usingthis@Foo. This is how context receivers are supposed to work.If you want
bazto only be able to be called inbar's lambda,bar's lambda needs to provide the context receiver using a receiver parameter, similar to howwith's lambda is declaredT.() -> R.I changed the actual context here to just an
object, because as far as I can see, there is nothing special aboutbar's lambda. Of course, if you want, you can make it provide extra information tobazby changingFooto a class that does contain data.Note that this does not prevent someone from doing:
It is quite hard to prevent against this without adding another layer outside of
bar, like:You can also do something simple like this prevents it from happening from outside the package: