Matthew Pope
11/17/2023, 8:28 PM@RequiresOptIn annotation class Unsafe
to mark the unsafe functions, but I would like to have a custom annotation to opt in, such as annotation class SafeBecause(val reason: String)
so that (a) you can't opt in for a whole file or class, and (b) I can force someone to document how we know it is safe to use this function. I don't think there's any mechanism to do this right now.
I think there's a few approaches to this. All of them would require compiler support (I think).
1. Add a new field to RequiresOptIn
, so that we could define unsafe like this: @RequiresOptIn(optInWith = SafeBecause::class) annotation class Unsafe
. This actually fulfills the two requirements I had. Because you pick your own annotation to opt in, you can create one that only targets expressions, and you can have a mandatory "reason" field.
2. Introduce an OptsInto
annotation that is the complement of `RequiresOptIn`; that is to say, it annotates another annotation which can then be use instead of @OptIn
. For example @OptsInto(Unsafe::class) annotation class SafeBecause(val reason: String)
could be used instead of @OptIn(Unsafe::class)
. There is some nice symmetry to this, but it implies that it would be possible to create multiple annotations that would allow you to opt into a particular annotation. Would we have to add a rule that you can only create an OptsInto
for annotations that are defined in the same module?
3. Add a "reason" field to @OptIn
so that you can write @OptIn(Unsafe::class, "We already checked the precondition ...")
. This is probably the least invasive change, but it doesn't fulfill the goal of being able to limit the scope of opting in.
Thoughts?