summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMatthew Pickering <matthewtpickering@gmail.com>2019-02-03 11:46:28 +0000
committerBen Gamari <ben@smart-cactus.org>2019-02-20 14:28:55 -0500
commitac37ab795fbe7a07894ce1d6b0fe9863c0e29135 (patch)
treec0654c4bf8cd81b9dc74d1bc2e8c6171d3dc0808
parenta53b2f45bd1c73a43b4df938790b177bc1ebf80d (diff)
downloadhaskell-ac37ab795fbe7a07894ce1d6b0fe9863c0e29135.tar.gz
Capture and simplify constraints arising from running typed splices
This fixes a regression caused by #15471 where splicing in a trivial program such as `[|| return () ||]` would fail as the dictionary for `return` would never get bound in the module containing the splice. Arguably this is symptomatic of a major problem affecting TTH where we serialise renamed asts and then retype check them. The reference to the dictionary should be fully determined at the quote site so that splicing doesn't have to solve any implicits at all. It's a coincidence this works due to coherence but see #15863 and #15865 for examples where things do go very wrong. Fixes #16195 (cherry picked from commit a48753bdbc99cda36890e851950f5b79e1c3b2b2)
-rw-r--r--compiler/typecheck/TcSplice.hs11
-rw-r--r--testsuite/tests/th/T16195.hs15
-rw-r--r--testsuite/tests/th/T16195A.hs13
-rw-r--r--testsuite/tests/th/all.T1
4 files changed, 37 insertions, 3 deletions
diff --git a/compiler/typecheck/TcSplice.hs b/compiler/typecheck/TcSplice.hs
index 1bb844a77f..73a9e9e1df 100644
--- a/compiler/typecheck/TcSplice.hs
+++ b/compiler/typecheck/TcSplice.hs
@@ -525,9 +525,14 @@ runTopSplice (DelayedSplice lcl_env orig_expr res_ty q_expr)
-- Rename and typecheck the spliced-in expression,
-- making sure it has type res_ty
-- These steps should never fail; this is a *typed* splice
- ; addErrCtxt (spliceResultDoc zonked_q_expr) $ do
- { (exp3, _fvs) <- rnLExpr expr2
- ; unLoc <$> tcMonoExpr exp3 (mkCheckExpType zonked_ty)} }
+ ; (res, wcs) <-
+ captureConstraints $
+ addErrCtxt (spliceResultDoc zonked_q_expr) $ do
+ { (exp3, _fvs) <- rnLExpr expr2
+ ; tcMonoExpr exp3 (mkCheckExpType zonked_ty)}
+ ; ev <- simplifyTop wcs
+ ; return $ unLoc (mkHsDictLet (EvBinds ev) res)
+ }
{-
diff --git a/testsuite/tests/th/T16195.hs b/testsuite/tests/th/T16195.hs
new file mode 100644
index 0000000000..70e936548d
--- /dev/null
+++ b/testsuite/tests/th/T16195.hs
@@ -0,0 +1,15 @@
+{-# LANGUAGE TemplateHaskell #-}
+module T16195 where
+
+import T16195A
+
+main2 :: IO ()
+main2 = return ()
+
+main :: IO ()
+main = $$foo
+
+main3 :: IO ()
+main3 = putStrLn ($$showC $$unitC)
+
+
diff --git a/testsuite/tests/th/T16195A.hs b/testsuite/tests/th/T16195A.hs
new file mode 100644
index 0000000000..b79aff77af
--- /dev/null
+++ b/testsuite/tests/th/T16195A.hs
@@ -0,0 +1,13 @@
+{-# LANGUAGE TemplateHaskell #-}
+module T16195A where
+
+import Language.Haskell.TH
+
+foo :: Q (TExp (IO ()))
+foo = [|| return () ||]
+
+showC :: Q (TExp (() -> String))
+showC = [|| show ||]
+
+unitC :: Q (TExp ())
+unitC = [|| () ||]
diff --git a/testsuite/tests/th/all.T b/testsuite/tests/th/all.T
index b93673c138..4d95e20c85 100644
--- a/testsuite/tests/th/all.T
+++ b/testsuite/tests/th/all.T
@@ -469,3 +469,4 @@ test('T16133', normal, compile_fail, [''])
test('T15471', normal, multimod_compile, ['T15471.hs', '-v0'])
test('T16180', when(opsys('darwin'), expect_broken(16218)), compile_and_run, [''])
test('T16183', normal, compile, ['-v0 -ddump-splices -dsuppress-uniques'])
+test('T16195', normal, multimod_compile, ['T16195.hs', '-v0'])