Commit 6a328506 authored by Ben Gamari's avatar Ben Gamari Committed by Ben Gamari

Model divergence of retry# as ThrowsExn, not Diverges

The demand signature of the retry# primop previously had a Diverges
result.  However, this caused the demand analyser to conclude that a
program of the shape,

    catchRetry# (... >> retry#)

would diverge. Of course, this is plainly wrong; catchRetry#'s sole
reason to exist is to "catch" the "exception" thrown by retry#. While
catchRetry#'s demand signature correctly had the ExnStr flag set on its
first argument, indicating that it should catch divergence, the logic
associated with this flag doesn't apply to Diverges results. This
resulted in #14171.

The solution here is to treat the divergence of retry# as an exception.
Namely, give it a result type of ThrowsExn rather than Diverges.

Updates stm submodule for tests.

Test Plan: Validate with T14171

Reviewers: simonpj, austin

Subscribers: rwbarton, thomie

GHC Trac Issues: #14171, #8091

Differential Revision:

(cherry picked from commit 10a1a478)
parent 18d66feb
......@@ -1437,6 +1437,7 @@ postProcessDmdType du@(JD { sd = ss }) (DmdType fv _ res_ty)
postProcessDmdResult :: Str () -> DmdResult -> DmdResult
postProcessDmdResult Lazy _ = topRes
postProcessDmdResult (Str ExnStr _) ThrowsExn = topRes -- Key point!
-- Note that only ThrowsExn results can be caught, not Diverges
postProcessDmdResult _ res = res
postProcessDmdEnv :: DmdShell -> DmdEnv -> DmdEnv
......@@ -2072,7 +2072,7 @@ primop AtomicallyOp "atomically#" GenPrimOp
out_of_line = True
has_side_effects = True
-- NB: retry#'s strictness information specifies it to return bottom.
-- NB: retry#'s strictness information specifies it to throw an exception
-- This lets the compiler perform some extra simplifications, since retry#
-- will technically never return.
......@@ -2082,10 +2082,13 @@ primop AtomicallyOp "atomically#" GenPrimOp
-- with:
-- retry# s1
-- where 'e' would be unreachable anyway. See Trac #8091.
-- Note that it *does not* return botRes as the "exception" that is throw may be
-- "caught" by catchRetry#. This mistake caused #14171.
primop RetryOp "retry#" GenPrimOp
State# RealWorld -> (# State# RealWorld, a #)
strictness = { \ _arity -> mkClosedStrictSig [topDmd] botRes }
strictness = { \ _arity -> mkClosedStrictSig [topDmd] exnRes }
out_of_line = True
has_side_effects = True
Subproject commit 9c3c3bb28834d1ba9574be7f887c8914afd4232c
Subproject commit b6e863e517bdcc3c5de1fbcb776a3fd7e6fe2103
Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment