Why is @InlineOnly internal?

I have some usecases, where @InlineOnly would be suitable…

What’s the reason it’s internal in the standart library? :frowning:

2 Likes

I think the argument I heard (maybe a year ago) was, that they aren’t sure that they don’t want to change those annotations and therefor have them internal.

There is a workaround though. You can define the annotation in your own project yourself.
You have to put it in the kotlin.internal package. That means you have to either use java to create the annotation or use the -Xallow-kotlin-package compiler argument.
I just have a project where I define annotations like that and import it in my personal projects.

1 Like

Are there any examples? :frowning_face:

I don’t know of any, but what you do is create a package kotlin.internal and add a file with

package kotlin.internal

/**
 * Specifies that this function should not be called directly without inlining
 */
@Target(AnnotationTarget.FUNCTION, AnnotationTarget.PROPERTY, AnnotationTarget.PROPERTY_GETTER, AnnotationTarget.PROPERTY_SETTER)
@Retention(AnnotationRetention.BINARY)
annotation class InlineOnly

This is just a copy from the kotlin repro. Then in gradle you add this to your buildfile

compileKotlin {
	kotlinOptions {
		freeCompilerArgs = ['-Xallow-kotlin-package']
	}
}

You can also add all the other internal annotations the standard library is using in this file. Just remember that there is no official support for this, so you should not rely on this too much.

1 Like

I understand that it’s a hack. But what’s wrong, if it allows to save 1 kilobyte of JAR? :rofl:

1 Like

I don’t think you will run into any problems with InlineOnly, but there are a few more annotations that change the way generic types work, I think ( I never used them). I would not rely on those in a production setting unless you really know what you are doing.

Can you elaborate on why @InlineOnly is required for that and just inline is not enough?

I have similar issue in my project.
There are methods which should be always inlined (similar to map, foreach from standard library). Currenlty I have inline keyword and InlineOnly annotation using hack above.

I am wondering does JvmSynthetic achieve same result (forbid calling from java) ?
Does inline keyword guarantee that method will always be inlined if called from kotlin?

@JvmSynthetic should effectively hide the function from the Java. IDE won’t show it to users and the compiler won’t allow to use it. But technically, the function is still there and can be called.

I don’t think so. Even @InlineOnly doesn’t guarantee this. In Kotlin, functions are first class citizens, we often pass them from place to place, so such truly-inline-only functions would have very limited uses.

1 Like

When a reference to an inline function is passed somewhere, it is inlined into the reference anonymous class. So in Kotlin/JVM, inline functions are always inlined when used from Kotlin, and the inline function declaration itself can be invoked only from Java unless it is inline-only.

1 Like