Some places in the compiler assume arity of an `Id` is the same as the depth of its `StrictSig`
That assumption isn't always upheld; see Note [idArity varies independently of dmdTypeDepth] in DmdAnal.
Rather than assuming that indeed in all cases where we assume that idArity matches as an unchecked precondition, we should use functions like appIsBottom (appIsDeadEnd after !3014 (closed)). Here is an inexhaustive list of places in the code where we don't account for arity-DmdType-depth mismatches:
-
Id.isBottomingId: Just checksisBottomingSig, which doesn't do any arity checks. Probably useappIsBottom sig (idArity id)instead, or pass the arity to check toisBottomingId. This function probably poses the biggest "thread". -
Hs.Core.Utils.exprIsBottom(maybe alsoexprIsDeadEndafter !3014 (closed), you get the idea): In theVar idcase, it checks whetherisBottomingId idand then checks whether the number of incoming arguments is>= idArity id. I think it should compare to the DmdType depth instead. For example, DmdType depth might be 2 butidAritymight be 1. I don't know if there is such a scenario, but if there is, then it means chaos. -
Hs.Core.Utils.isCheapApp: Doesn't consider arity/n_val_argsat all. EvenNote [isCheapApp: bottoming functions]says that it's unclear why we have this special case. But I dug up 9be18ea4 and apparently, this check used to be in a function callednotRedex, that then got torn apart (407c11b8) intoisWorkFreeAppand theisBottomingIdcheck, leaving that Note behind. I think the gist is that a partial application is always a cheap app, and as soon as we saturate theStrictSig, we bottom out, which we also consider cheap in that it doesn't have to be shared. BUT: What if we hadn_val_args == idArity fn == 1, but theStrictSighad depth 2? Then certainly that application is not cheap! So this should also callappIsBottom (idStrictness fn) n_val_args. -
Hs.Core.Op.FloatOut.floatBind: Looks atisBottomingId, the eta-expands withidArity. Should probably callappIsBottom (idStrictness var) (idArity var). - Other usages in LiberateCase, Simplify, SetLevels
Edited by Sebastian Graf