diff options
author | Owen Stephens <owen@owenstephens.co.uk> | 2016-03-11 10:39:55 +0100 |
---|---|---|
committer | Ben Gamari <ben@smart-cactus.org> | 2016-03-11 13:20:18 +0100 |
commit | d48220eb7b2029ab90ea8185ac82b6bed51009ad (patch) | |
tree | 7bc94bcde1fa2441393ae047a3317a24ac2db605 /compiler/rename/RnSplice.hs | |
parent | f8056fca87e83fd37d3f2441f5cb0335e12e3aef (diff) | |
download | haskell-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.hs | 44 |
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) |