summaryrefslogtreecommitdiff
path: root/compiler
diff options
context:
space:
mode:
authorSimon Peyton Jones <simonpj@microsoft.com>2017-08-23 13:55:33 +0100
committerSimon Peyton Jones <simonpj@microsoft.com>2017-08-24 14:39:29 +0100
commita211dca8236fb8c7ec632278f761121beeac1438 (patch)
tree7a86f779f7f0ea553ae428819690f3738b1d1822 /compiler
parent11657c4bdda391d4f21289e3412589a3c520ca2a (diff)
downloadhaskell-a211dca8236fb8c7ec632278f761121beeac1438.tar.gz
Fix defer-out-of-scope-variables
In the hacky code in TcUnify.buildImplication we'd failed to account for -fdefer-out-of-scope-variables. See the new function TcUnify.implicationNeeded. Fixes Trac #14149
Diffstat (limited to 'compiler')
-rw-r--r--compiler/typecheck/TcUnify.hs51
1 files changed, 34 insertions, 17 deletions
diff --git a/compiler/typecheck/TcUnify.hs b/compiler/typecheck/TcUnify.hs
index 51366498fd..59f88693a4 100644
--- a/compiler/typecheck/TcUnify.hs
+++ b/compiler/typecheck/TcUnify.hs
@@ -1144,24 +1144,41 @@ buildImplication :: SkolemInfo
-> TcM result
-> TcM (Bag Implication, TcEvBinds, result)
buildImplication skol_info skol_tvs given thing_inside
- = do { tc_lvl <- getTcLevel
- ; deferred_type_errors <- goptM Opt_DeferTypeErrors <||>
- goptM Opt_DeferTypedHoles
- ; if null skol_tvs && null given && (not deferred_type_errors ||
- not (isTopTcLevel tc_lvl))
- then do { res <- thing_inside
- ; return (emptyBag, emptyTcEvBinds, res) }
- -- Fast path. We check every function argument with
- -- tcPolyExpr, which uses tcSkolemise and hence checkConstraints.
- -- But with the solver producing unlifted equalities, we need
- -- to have an EvBindsVar for them when they might be deferred to
- -- runtime. Otherwise, they end up as top-level unlifted bindings,
- -- which are verboten. See also Note [Deferred errors for coercion holes]
- -- in TcErrors.
+ = do { implication_needed <- implicationNeeded skol_tvs given
+
+ ; if implication_needed
+ then do { (tclvl, wanted, result) <- pushLevelAndCaptureConstraints thing_inside
+ ; (implics, ev_binds) <- buildImplicationFor tclvl skol_info skol_tvs given wanted
+ ; return (implics, ev_binds, result) }
+
+ else -- Fast path. We check every function argument with
+ -- tcPolyExpr, which uses tcSkolemise and hence checkConstraints.
+ -- So tihs fast path is well-exercised
+ do { res <- thing_inside
+ ; return (emptyBag, emptyTcEvBinds, res) } }
+
+implicationNeeded :: [TcTyVar] -> [EvVar] -> TcM Bool
+-- With the solver producing unlifted equalities, we need
+-- to have an EvBindsVar for them when they might be deferred to
+-- runtime. Otherwise, they end up as top-level unlifted bindings,
+-- which are verboten. See also Note [Deferred errors for coercion holes]
+-- in TcErrors. cf Trac #14149 for an exmample of what goes wrong.
+implicationNeeded skol_tvs given
+ | null skol_tvs
+ , null given
+ = -- Empty skolems and givens
+ do { tc_lvl <- getTcLevel
+ ; if not (isTopTcLevel tc_lvl) -- No implication needed if we are
+ then return False -- already inside an implication
else
- do { (tclvl, wanted, result) <- pushLevelAndCaptureConstraints thing_inside
- ; (implics, ev_binds) <- buildImplicationFor tclvl skol_info skol_tvs given wanted
- ; return (implics, ev_binds, result) }}
+ do { dflags <- getDynFlags -- If any deferral can happen,
+ -- we must build an implication
+ ; return (gopt Opt_DeferTypeErrors dflags ||
+ gopt Opt_DeferTypedHoles dflags ||
+ gopt Opt_DeferOutOfScopeVariables dflags) } }
+
+ | otherwise -- Non-empty skolems or givens
+ = return True -- Definitely need an implication
buildImplicationFor :: TcLevel -> SkolemInfo -> [TcTyVar]
-> [EvVar] -> WantedConstraints