Skip to content

Draft: DmdAnal: `catch#` may throw a precise exception (#20111)

Sebastian Graf requested to merge wip/T20111 into master

... if its argument might throw one.

In #20111, we saw how catch# hid a side-effect from DmdAnal in the action it wraps (printing to stdout). That happened in an infinite loop, so the whole looping function was detected to have bottoming divergence b instead of x.

Because the looping function looked to DmdAnal like any other function with divergence b, the Simplifier was allowed to then eval the diverging field of an argument eagerly, masking the infinite loop with the error from said field and thus not emitting the externally visible side-effect (printing to stdout) anymore.

The solution is for exprMayThrowPreciseException to recurse into the args of catch#. Same for other higher-order IO-like primops, like atomically#. We'd never say that putStrLn may not throw a precise exception, so we fix the particular regression in #20111.

But of course, #20111 begs the question of whether we might want to preserve other externally visible side-effects (e.g. in other threads or processes), too. The answer is yes, of course, but #17653 (closed) showed that doing so comes at the cost of regressing real-world code. We track that issue as #20121.

Regression test is T20111. Fixes #20111.

Edited by Andreas Klebinger

Merge request reports