Make overloading of inline functions smarter

It is a well known fact that functions can be only differentiated by arguments, but not by return type or type parameters.

Inline functions are by definition, well, inlined, so in theory such considerations shouldn’t apply.

Take this example:

inline fun tuple(): Pair<String, String> = "red" to "white"
inline fun tuple(): Triple<String, String, String> =  Triple("red", "green", "blue")


var x = "green" to "blue"
...
x = tuple()  // returns Pair("red", "white")

This doesn’t compile, but I see no good reason to disallow it. Same for type parameters:

class Pattern1<A>()
class Pattern2<A, B>()

inline fun <A> pattern() = Pattern1<A>()
inline fun <A, B> pattern() = Pattern2<A, B>()

val x = pattern<String, Int>() // returns Pattern2<String, Int>()

I think this behavior would be quite useful, especially in DSLs. Of course, it would make inline functions different from normal ones, but they already are in a number of ways (e.g. regarding reified generics or return behavior).

I don’t think it has anything to do with inline functions. It could be done for both inline and regular functions. JVM is fine with overloads that differ with the return type only. And even if we have exactly the same arguments and return types, so JVM can’t distinguish them, then this is a limitation of the underlying compiler target and shouldn’t generally affect Kotlin design. For such cases we have name mangling or @JvmName. So I don’t think this is not supported due to JVM limitations.

Also, your second example is actually supported by Kotlin and works exactly as you expect.

2 Likes

Thanks for the info, I saw this behavior but couldn’t reproduce it on another machine. Do you know by any chance in which version this feature was introduced?

Are you getting an error?

I know for JVM you’d need to use @JvmName to make the compiled names distinct (otherwise the JVM sees the same signature). Other platforms might be similar.

But in general, this isn’t a kotlin limitation. You can even have two foo<Bar>() functions as long as the generic types have different bounds.

2 Likes

I tried this, works great on the original machine. My MacBook still complains, but there must be something weird going on with its setup.

I changed the file in question, and would appreciate if you could have a look: