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.

Change History (1)

comment:1 Changed 3 years ago by goldfire

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 to MkCoercible.

Note: See TracTickets for help on using tickets.