summaryrefslogtreecommitdiff
path: root/compiler/rename/RnSplice.hs
diff options
context:
space:
mode:
authorOwen Stephens <owen@owenstephens.co.uk>2016-03-11 10:39:55 +0100
committerBen Gamari <ben@smart-cactus.org>2016-03-11 13:20:18 +0100
commitd48220eb7b2029ab90ea8185ac82b6bed51009ad (patch)
tree7bc94bcde1fa2441393ae047a3317a24ac2db605 /compiler/rename/RnSplice.hs
parentf8056fca87e83fd37d3f2441f5cb0335e12e3aef (diff)
downloadhaskell-d48220eb7b2029ab90ea8185ac82b6bed51009ad.tar.gz
Add Note [Running splices in the Renamer]
Reviewers: austin, goldfire, bgamari Reviewed By: goldfire, bgamari Subscribers: thomie Differential Revision: https://phabricator.haskell.org/D1985
Diffstat (limited to 'compiler/rename/RnSplice.hs')
-rw-r--r--compiler/rename/RnSplice.hs44
1 files changed, 43 insertions, 1 deletions
diff --git a/compiler/rename/RnSplice.hs b/compiler/rename/RnSplice.hs
index 9279be1570..b23621d1bd 100644
--- a/compiler/rename/RnSplice.hs
+++ b/compiler/rename/RnSplice.hs
@@ -402,12 +402,54 @@ rnSpliceExpr splice
; return (HsSpliceE rn_splice, lcl_names `plusFV` gbl_names) }
- | otherwise -- Run it here
+ | otherwise -- Run it here, see Note [Running splices in the Renamer]
= do { traceRn (text "rnSpliceExpr: untyped expression splice")
; rn_expr <- runRnSplice UntypedExpSplice runMetaE ppr rn_splice
; (lexpr3, fvs) <- checkNoErrs (rnLExpr rn_expr)
; return (HsPar lexpr3, fvs) }
+{- Note [Running splices in the Renamer]
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Splices used to be run in the typechecker, which led to (Trac #4364). Since the
+renamer must decide which expressions depend on which others, and it cannot
+reliably do this for arbitrary splices, we used to conservatively say that
+splices depend on all other expressions in scope. Unfortunately, this led to
+the problem of cyclic type declarations seen in (Trac #4364). Instead, by
+running splices in the renamer, we side-step the problem of determining
+dependencies: by the time the dependency analysis happens, any splices have
+already been run, and expression dependencies can be determined as usual.
+
+However, see (Trac #9813), for an example where we would like to run splices
+*after* performing dependency analysis (that is, after renaming). It would be
+desirable to typecheck "non-splicy" expressions (those expressions that do not
+contain splices directly or via dependence on an expression that does) before
+"splicy" expressions, such that types/expressions within the same declaration
+group would be available to `reify` calls, for example consider the following:
+
+> module M where
+> data D = C
+> f = 1
+> g = $(mapM reify ['f, 'D, ''C] ...)
+
+Compilation of this example fails since D/C/f are not in the type environment
+and thus cannot be reified as they have not been typechecked by the time the
+splice is renamed and thus run.
+
+These requirements are at odds: we do not want to run splices in the renamer as
+we wish to first determine dependencies and typecheck certain expressions,
+making them available to reify, but cannot accurately determine dependencies
+without running splices in the renamer!
+
+Indeed, the conclusion of (Trac #9813) was that it is not worth the complexity
+to try and
+ a) implement and maintain the code for renaming/typechecking non-splicy
+ expressions before splicy expressions,
+ b) explain to TH users which expressions are/not available to reify at any
+ given point.
+
+-}
+
----------------------
rnSpliceType :: HsSplice RdrName -> PostTc Name Kind
-> RnM (HsType Name, FreeVars)