-
Simon Peyton Jones authored
------------------------------ Improve the demand analyser [case] ------------------------------ 1. In the Case case of dmdAnal, I dealt with the case binder in a way that was both clumsy and pessimistic. This commit fixes that: -- Figure out whether the demand on the case binder is used, and use -- that to set the scrut_dmd. This is utterly essential. -- Consider f x = case x of y { (a,b) -> k y a } -- If we just take scrut_demand = U(L,A), then we won't pass x to the -- worker, so the worker will rebuild -- x = (a, absent-error) -- and that'll crash. -- So at one stage I had: -- dead_case_bndr = isAbsentDmd (idNewDemandInfo case_bndr') -- keepity | dead_case_bndr = Drop -- | otherwise = Keep -- -- But then consider -- case x of y { (a,b) -> h y + a } -- where h : U(LL) -> T -- The above code would compute a Keep for x, since y is not Abs, which is silly -- The insight is, of course, that a demand on y is a demand on the -- scrutinee, so we need to `both` it with the scrut demand scrut_dmd = Seq Drop Now [idNewDemandInfo b | b <- bndrs', isId b] `both` idNewDemandInfo case_bndr' -- There used to be a special case for when -- ty == TyVarTy tv -- (a not-uncommon case) in which case the substitution was dropped. -- But the type-tidier changes the print-name of a type variable without -- changing the unique, and that led to a bug. Why? Pre-tidying, we had -- a type {Foo t}, where Foo is a one-method class. So Foo is really a newtype. -- And it happened that t was the type variable of the class. Post-tiding, 2. 'defer' can be simplified to 'lub Abs', reducing the number of places where things can go wrong. 3. Add comments
92fbaba6