-
Notifications
You must be signed in to change notification settings - Fork 1.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Very long compilation with one missing implicit #19320
Comments
It takes almost 3 minutes to compile and get:
|
A bit more minimized: //> using dep "org.typelevel::cats-effect:3.5.2"
//> using dep "org.typelevel::log4cats-slf4j:2.6.0"
//> using scala "3.3.1"
import cats.effect.kernel.Sync
import cats.effect.IO
import org.typelevel.log4cats.Logger
import org.typelevel.log4cats.slf4j.Slf4jLogger
class Bot[F[_]: Logger]() {}
object HelloWorld {
implicit def logger[F[_]: Sync]: Logger[F] = Slf4jLogger.getLogger[F]
//implicit val logger: Logger[IO] = Slf4jLogger.getLogger[IO]
def main(args: Array[String]): Unit =
new Bot()
} The above takes a minute or more to compile before failing with the originally reported error. Uncommenting the implicit val logger: Logger[IO] = Slf4jLogger.getLogger[IO] And commenting out the //implicit def logger[F[_]: Sync]: Logger[F] = Slf4jLogger.getLogger[F] The failed compilation then produces a different error:
|
I think another minimization would be:
The big problem here is that if we want to get completions on |
What I find weird here is that we continue looking for an implicit while the type is actually an error and doesn't exist. Could we forgo the implicit search if the type is an error? |
Yes, that sounds reasonable. We do some implicit searching to give user's suggestions and advice, but we can make that more conditional. Including, perhaps, an IDE specific way to avoid it. |
Which type is an error? The implicit it searched for was
just shows where the implicit search was unsuccessful, it is the result of the implicit search, not the input. Why does it take so long? I have no idea, but generally one should find the issue with the implicits in the library one imports. Maybe we can give a configurable timeout for implicit search to avoid this situation. |
I think it's easier to see it in the last example:
where Concurren is missing the t. When run via
Those imports are a bit much when I look at them, but this is a typical scenario with cats. This came up in one of the RockTheJVM courses, so I assume this might cause a lot of headaches to a larger number of users.
Would help the interactive scenario for sure, but I am not sure if this fixes the overall problem. |
I believe the issue is that the F parameter is less constrained than expected since there is a syntax error in the context bound. Then the system tries to find an implicit for an unconstrained One thing we could maybe do is if there is an error in a subtype bound or context bound we mark the bound type parameter as "tainted". Then we would immediately return error for every implicit search of a type containing that parameter. to generalize this, if we have an implicit parameter for type T which is ill-formed, we'd also mark all type parameters appearing in T as tainted. |
There's a good chance this will fix #19320. My problem is that without a lot of added boilerplate I cannot test it, since it's hard to have at the same time external dependencies and ad-hoc instrumentation in the compiler. But what I could observe from the minimized example, it searches for a conversion of `Concurrent[F[_]]` to `NoType` and that must have caused the blowup. In any case, the change makes obvious sense, so let's add that and see whether it improves things.
Compiler version
3.3.1
and3.4.0-RC1
both.Minimized code
Output
Output is correct, but it takes a very long time to compile.
Expectation
File compiled and returns an error about a missing implicit.
The text was updated successfully, but these errors were encountered: