Commit a211dca8 authored by Simon Peyton Jones's avatar Simon Peyton Jones
Browse files

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
parent 11657c4b
......@@ -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
......
{-# OPTIONS_GHC -fdefer-out-of-scope-variables #-}
module Foo where
import Data.Coerce
f :: Bool
f = coerce (k :: Int)
T14149.hs:8:13: warning: [-Wdeferred-out-of-scope-variables (in -Wdefault)]
Variable not in scope: k :: Int
......@@ -571,3 +571,4 @@ test('T13881', normal, compile, [''])
test('T13915a', normal, multimod_compile, ['T13915a', '-v0'])
test('T13915b', normal, compile, [''])
test('T13984', normal, compile, [''])
test('T14149', normal, compile, [''])
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment