Looking at the new contracts api, the KEEP states ...
# eap
a
Looking at the new contracts api, the KEEP states that the metadata and semantics are stable. I was hoping to be able to add some contracts to library code, and let consumers take advantage of them. But surprisingly it seems like
@ExperimentalContracts
is transitive, forcing callers to opt-in even if they don't declare any contracts themselves. Is there a way to get this to compile?
Copy code
@ExperimentalContracts inline fun <T> foo(block: () -> T): T {
  contract { callsInPlace(block, EXACTLY_ONCE) }
  return block()
}

fun main() {
  foo { } // error: this declaration is experimental and its usage must be marked with '@ExperimentalContracts'
}
m
That would be annoying. Have you actually tried building it as a library and depending on it, and this is merely a convenient example? Curious if it changes when published as a library because don’t the stdlib ones merely require the compiler option?
a
I haven't tried compiling it into a library. The fact the stdlib already makes use of the contracts is what made me think that this would be possible in the first place. Clearly, it's not a technical limitation.
m
Then I’d try creating the library, and depending on it. It’s possible that the compiler creates the ‘inheritance’ BECAUSE it’s all in one item, so that if you depend on ‘main’ in your consuming code, you have to opt-in to contracts as it transitively depends on contracts? Just a thought.
i
Whether to propagate the experimental status is up to you. For a non-propagating opt-in you can use
@UseExperimental(ExperimentalContracts::class)
annotation. More about it in the experimental annotations KEEP: https://github.com/Kotlin/KEEP/blob/master/proposals/experimental.md
a
Ah, I misunderstood that section when I read it. Thank you!