[commit: ghc] master: Fix defer-out-of-scope-variables (a211dca)

git at git.haskell.org git at git.haskell.org
Thu Aug 24 13:40:02 UTC 2017


Repository : ssh://git@git.haskell.org/ghc

On branch  : master
Link       : http://ghc.haskell.org/trac/ghc/changeset/a211dca8236fb8c7ec632278f761121beeac1438/ghc

>---------------------------------------------------------------

commit a211dca8236fb8c7ec632278f761121beeac1438
Author: Simon Peyton Jones <simonpj at microsoft.com>
Date:   Wed Aug 23 13:55:33 2017 +0100

    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


>---------------------------------------------------------------

a211dca8236fb8c7ec632278f761121beeac1438
 compiler/typecheck/TcUnify.hs                      | 51 ++++++++++++++--------
 testsuite/tests/typecheck/should_compile/T14149.hs |  8 ++++
 .../tests/typecheck/should_compile/T14149.stderr   |  3 ++
 testsuite/tests/typecheck/should_compile/all.T     |  1 +
 4 files changed, 46 insertions(+), 17 deletions(-)

diff --git a/compiler/typecheck/TcUnify.hs b/compiler/typecheck/TcUnify.hs
index 5136649..59f8869 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
diff --git a/testsuite/tests/typecheck/should_compile/T14149.hs b/testsuite/tests/typecheck/should_compile/T14149.hs
new file mode 100644
index 0000000..c23d415
--- /dev/null
+++ b/testsuite/tests/typecheck/should_compile/T14149.hs
@@ -0,0 +1,8 @@
+{-# OPTIONS_GHC -fdefer-out-of-scope-variables #-}
+
+module Foo where
+
+import Data.Coerce
+
+f :: Bool
+f = coerce (k :: Int)
diff --git a/testsuite/tests/typecheck/should_compile/T14149.stderr b/testsuite/tests/typecheck/should_compile/T14149.stderr
new file mode 100644
index 0000000..5e5306e
--- /dev/null
+++ b/testsuite/tests/typecheck/should_compile/T14149.stderr
@@ -0,0 +1,3 @@
+
+T14149.hs:8:13: warning: [-Wdeferred-out-of-scope-variables (in -Wdefault)]
+    Variable not in scope: k :: Int
diff --git a/testsuite/tests/typecheck/should_compile/all.T b/testsuite/tests/typecheck/should_compile/all.T
index f522b74..13a2719 100644
--- a/testsuite/tests/typecheck/should_compile/all.T
+++ b/testsuite/tests/typecheck/should_compile/all.T
@@ -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, [''])



More information about the ghc-commits mailing list