diff options
author | Simon Peyton Jones <simonpj@microsoft.com> | 2017-08-23 13:55:33 +0100 |
---|---|---|
committer | Simon Peyton Jones <simonpj@microsoft.com> | 2017-08-24 14:39:29 +0100 |
commit | a211dca8236fb8c7ec632278f761121beeac1438 (patch) | |
tree | 7a86f779f7f0ea553ae428819690f3738b1d1822 /compiler | |
parent | 11657c4bdda391d4f21289e3412589a3c520ca2a (diff) | |
download | haskell-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.hs | 51 |
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 |