Skip to content

DmdAnal: Recognise precise exceptions from case alternatives (#18086)

Sebastian Graf requested to merge wip/T18086 into master

Consider

m :: IO ()
m = do
  putStrLn "foo"
  error "bar"

m (from #18086 (closed)) always throws a (precise or imprecise) exception or diverges. Yet demand analysis infers <L,A> as demand signature instead of <L,A>x for it.

That's because the demand analyser sees putStrLn occuring in a case scrutinee and decides that it has to deferAfterPreciseException, because putStrLn throws a precise exception on some control flow paths. This will mask the botDiv Divergenceof the single case alt containing error to topDiv. Since putStrLn has topDiv itself, the final Divergence is topDiv.

This is easily fixed: deferAfterPreciseException works by lubing with the demand type of a virtual case branch denoting the precise exceptional control flow. We used nopDmdType before, but we can be more precise and use exnDmdType, which is nopDmdType with exnDiv.

Now the Divergence from the case alt will degrade botDiv to exnDiv instead of topDiv, which combines with the result from the scrutinee to exnDiv, and all is well.

Fixes #18086 (closed).

Edited by Sebastian Graf

Merge request reports