
Hi Richard, Nested casts can absolutely happen after the simple optimizer runs. Suppose we produce a desugared expression like: let { y = x `cast` co1 } in y `cast` co2 The simple optimizer will inline y, since it only appears once, so now we have a nested cast. Perhaps you mean you expect the casts to be merged when the simple optimizer gets to the Cast expression itself, but they aren’t, as it doesn’t use mkCast to reconstruct the result: -- from GHC.Core.SimpleOpt.simple_opt_expr go (Cast e co) | isReflCo co' = go e | otherwise = Cast (go e) co' I suppose a really simple fix would be to just use mkCast here instead of Cast, but that wouldn’t be completely satisfying, since the merged coercion wouldn’t be optimized. So you’d have to do something slightly more complicated to detect if the result of `go e` was a cast expression and combine the coercions before calling optCoercion. Whether or not doing that would be a good idea is precisely what I’m asking about. :) Alexis
On Apr 27, 2020, at 16:22, Richard Eisenberg
wrote: Hi Alexis,
Nested casts shouldn't happen. The mkCast function gets rid of them. Someone somewhere is forgetting to call it. If you have a concrete program that leads to nested casts, post a bug report. :)
Thanks! Richard