Opened 3 years ago
Last modified 3 years ago
#13798 new bug
Invalid transformation in simplOptExpr
Reported by: | simonpj | Owned by: | |
---|---|---|---|
Priority: | normal | Milestone: | |
Component: | Compiler | Version: | 8.0.1 |
Keywords: | Cc: | ||
Operating System: | Unknown/Multiple | Architecture: | Unknown/Multiple |
Type of failure: | None/Unknown | Test Case: | |
Blocked By: | Blocking: | ||
Related Tickets: | Differential Rev(s): | ||
Wiki Page: |
Description
Prior to this commit, CoreOpt.simple_opt_expr
transforms
case e of (b :: t1 ~# t2) DEFAULT -> rhs ==> rhs
That was plain wrong when e
diverges, or calls error
. Hence the commit.
But the commit does this
case Coercible_sc e of (b :: t1 ~# t2) DEFAULT -> rhs ==> rhs
narrowing the scope of the transformation to when the scrutinee is application of the Coercible superclass selector
Coercible_sc :: Coercible a b -> (a ~R# b)
Here's the code from CoreOpt
:
| isDeadBinder b , [(DEFAULT, _, rhs)] <- as , isCoercionType (varType b) , (Var fun, _args) <- collectArgs e , fun `hasKey` coercibleSCSelIdKey -- without this last check, we get #11230 = go rhs
But that's bizarrely ad-hoc. And, worse, it is flat-out wrong... what if e
diverges?
It's not actually hurting anyone right now, but what we should
really do is use exprOkForSpeculation
; and teach exprOkForSpeculation
how to deal with class-op selectors.
A related question, while your attention is on this code, is why the case-of-known-constructor optimization immediately above this code doesn't detect the
Coercible_sc
selector applied toMkCoercible
.