-
Notifications
You must be signed in to change notification settings - Fork 15
Fix the code which is stumbled on an old type inference problem of the Kotlin compiler #53
Conversation
…e Kotlin compiler Background. The old type inference has some problems with common super type calculation on Unit-returning lambdas. Namely, in one of the following cases, the old type inference runs "coercion to Unit": 1) If in the place where common super type calculation is required (e.g. "if", "when", "select" function), the first candidate was a lambda which returns Unit (explicitly or implicitly); 2) If in any of the branches there was an explicit specifying of the returned functional type, namely, Unit in the return position. This is the wrong behavior: type inference in such cases should still run common super type calculation. The new type inference behave correctly in such cases. Problem with the changing code. The problem appears when someone relies on the inferred type (for example, `() -> Unit`), although in the new inference, due to run of the common super type calculation, the type could be more common (for example, `() -> Any`). This is exactly what happened in the changing code: `cb(either)` returns `IOOf<Unit>` (and the branch returns `(Either<Throwable, A>) -> IOOf<Unit>`), but all the remaining branches return `(Either<Throwable, A>) -> Unit`, so we have `CST((Either<Throwable, A>) -> Unit, (Either<Throwable, A>) -> IOOf<Unit>) = (Either<Throwable, A>) -> Any`. In `IORunLoop.startCancelable` signature, we expect `(Either<Throwable, A>) -> Unit`, because now we have an error in the new type inference. The new type inference turning on. We are going to turn on the new type inference in Kotlin 1.4 by default. Therefore, now we are trying to test the compilation of large projects on Kotlin with the new inference. Nevertheless, sometimes errors are detected not in the new inference, but in the old one, which means that if someone uses a code that was erroneously compiled, such code will stop compiling. We try to warn of such cases (like this one).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hi @PetukhovVictor 👋
Thank you very much for the PR & contribution! Very happy to hear that Arrow was build of this effort to try compilation on large projects with the evolution of the language.
This fails because of arrow-kt/arrow-incubator#43. #54 will fix that in a sec. |
Thanks @1Jajen1 🎉 Thank you so much, @PetukhovVictor 🎉 |
Thanks for accepting the fix! We will report if we find any more problems on Arrow source code due to the difference in the behavior of the old type inference and new one. |
Awesome! Thank you @PetukhovVictor. |
It's still no available in OSS repository. It will be rerun when GitHub issues are solved 🙏 |
It's already available in OSS repository 🎉 |
Fix the code which is stumbled on an old type inference problem of the Kotlin compiler
Background.
The old type inference has some problems with common super type calculation on Unit-returning lambdas. Namely, in one of the following cases, the old type inference runs "coercion to Unit":
This is the wrong behavior: type inference in such cases should still run common super type calculation. The new type inference behave correctly in such cases.
Problem with the changing code.
The problem appears when someone relies on the inferred type (for example,
() -> Unit
), although in the new inference, due to run of the common super type calculation, the type could be more common (for example,() -> Any
). This is exactly what happened in the changing code:cb(either)
returnsIOOf<Unit>
(and the branch returns(Either<Throwable, A>) -> IOOf<Unit>
), but all the remaining branches return(Either<Throwable, A>) -> Unit
, so we haveCST((Either<Throwable, A>) -> Unit, (Either<Throwable, A>) -> IOOf<Unit>) = (Either<Throwable, A>) -> Any
. InIORunLoop.startCancelable
signature, we expect(Either<Throwable, A>) -> Unit
, because now we have an error in the new type inference.The new type inference turning on.
We are going to turn on the new type inference in Kotlin 1.4 by default. Therefore, now we are trying to test the compilation of large projects on Kotlin with the new inference. Nevertheless, sometimes errors are detected not in the new inference, but in the old one, which means that if someone uses a code that was erroneously compiled, such code will stop compiling. We try to warn of such cases (like this one).