Typechecker performance is *way* worse in 6.3

It might have been the case before but it's not necessarily the case now because all of the visible operators would go into an overload set so if some dependency of a framework you import makes their type Equatable which is also ExpressibleByBooleanLiteral that would cause more solving to happen. Some of the performance for things like this was supported by the hacks we had in the solver, the problem with these hacks is they make some code faster but other code slower or even reject some valid code because they are too aggressive. 6.3 was an effort to overhaul all that, so it's possible that we made some expressions slower that replied on the hacks before, but it opens us a path forward with more principled improvements. We made a post about this some time ago.

I think the type-checker is doing a "sensible" thing today because literals don't drive type-checking, calls do. In this expression we have an overload of / that accepts (Int, Int) -> Int and a lot of other ones that accept e.g. (Float, Float) -> Float, (Double, Double) -> Double, (CGFloat, CGFloat) -> CGFloat, (UInt{...}, UInt{...}) -> UInt{...}etc, all these types areExpressibleBy{Integer, FloatingPoint}Literal. Since 1and1.0are used together here in application of/there is clash because1s default type is Int but 1.0 is Double, there is no (Int, Double) -> ... overload so the solver ends up checking other overloads there and they all produce sub-optimal solutions because they are all are using non-default literals in some way, it's even worse for CGFloat because it's interchangeable with Double so now the solver needs to figure out how it's result used to avoid narrowing conversions.

2 Likes