summaryrefslogtreecommitdiff
path: root/compiler/rename/RnSplice.hs
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/rename/RnSplice.hs')
-rw-r--r--compiler/rename/RnSplice.hs308
1 files changed, 151 insertions, 157 deletions
diff --git a/compiler/rename/RnSplice.hs b/compiler/rename/RnSplice.hs
index 5306b6e800..5d12720e2c 100644
--- a/compiler/rename/RnSplice.hs
+++ b/compiler/rename/RnSplice.hs
@@ -19,37 +19,172 @@ import RdrName
import TcRnMonad
import Kind
-#ifdef GHCI
-import ErrUtils ( dumpIfSet_dyn_printer )
-import Control.Monad ( unless, when )
-import DynFlags
-import DsMeta ( decsQTyConName, expQTyConName, patQTyConName, typeQTyConName, liftName )
-import LoadIface ( loadInterfaceForName )
-import Module
import RnEnv
-import RnPat ( rnPat )
import RnSource ( rnSrcDecls, findSplice )
-import RnTypes ( rnLHsType )
-import PrelNames ( isUnboundName )
-import SrcLoc
-import TcEnv ( checkWellStaged, tcMetaTy )
-import Outputable
+import RnPat ( rnPat )
+import LoadIface ( loadInterfaceForName )
import BasicTypes ( TopLevelFlag, isTopLevel )
+import Outputable
+import Module
+import SrcLoc
+import DynFlags
import FastString
+import RnTypes ( rnLHsType )
+
+import Control.Monad ( unless, when )
+
+import {-# SOURCE #-} RnExpr ( rnLExpr )
+
+import PrelNames ( isUnboundName )
+import TcEnv ( checkWellStaged )
+import DsMeta ( liftName )
+
+#ifdef GHCI
+import ErrUtils ( dumpIfSet_dyn_printer )
+import DsMeta ( decsQTyConName, expQTyConName, patQTyConName, typeQTyConName, )
+import TcEnv ( tcMetaTy )
import Hooks
import Var ( Id )
import DsMeta ( quoteExpName, quotePatName, quoteDecName, quoteTypeName )
import Util
-import {-# SOURCE #-} RnExpr ( rnLExpr )
import {-# SOURCE #-} TcExpr ( tcMonoExpr )
import {-# SOURCE #-} TcSplice ( runMetaD, runMetaE, runMetaP, runMetaT, tcTopSpliceExpr )
#endif
-#ifndef GHCI
+{-
+************************************************************************
+* *
+ Template Haskell brackets
+* *
+************************************************************************
+-}
+
rnBracket :: HsExpr RdrName -> HsBracket RdrName -> RnM (HsExpr Name, FreeVars)
-rnBracket e _ = failTH e "Template Haskell bracket"
+rnBracket e br_body
+ = addErrCtxt (quotationCtxtDoc br_body) $
+ do { -- Check that Template Haskell is enabled and available
+ thEnabled <- xoptM Opt_TemplateHaskell
+ ; unless thEnabled $
+ failWith ( vcat [ ptext (sLit "Syntax error on") <+> ppr e
+ , ptext (sLit "Perhaps you intended to use TemplateHaskell") ] )
+
+ -- Check for nested brackets
+ ; cur_stage <- getStage
+ ; case cur_stage of
+ { Splice True -> checkTc (isTypedBracket br_body) illegalUntypedBracket
+ ; Splice False -> checkTc (not (isTypedBracket br_body)) illegalTypedBracket
+ ; Comp -> return ()
+ ; Brack {} -> failWithTc illegalBracket
+ }
+
+ -- Brackets are desugared to code that mentions the TH package
+ ; recordThUse
+
+ ; case isTypedBracket br_body of
+ True -> do { (body', fvs_e) <- setStage (Brack cur_stage RnPendingTyped) $
+ rn_bracket cur_stage br_body
+ ; return (HsBracket body', fvs_e) }
+
+ False -> do { ps_var <- newMutVar []
+ ; (body', fvs_e) <- setStage (Brack cur_stage (RnPendingUntyped ps_var)) $
+ rn_bracket cur_stage br_body
+ ; pendings <- readMutVar ps_var
+ ; return (HsRnBracketOut body' pendings, fvs_e) }
+ }
+
+rn_bracket :: ThStage -> HsBracket RdrName -> RnM (HsBracket Name, FreeVars)
+rn_bracket outer_stage br@(VarBr flg rdr_name)
+ = do { name <- lookupOccRn rdr_name
+ ; this_mod <- getModule
+
+ ; case flg of
+ { -- Type variables can be quoted in TH. See #5721.
+ False -> return ()
+ ; True | nameIsLocalOrFrom this_mod name ->
+ do { mb_bind_lvl <- lookupLocalOccThLvl_maybe name
+ ; case mb_bind_lvl of
+ { Nothing -> return () -- Can happen for data constructors,
+ -- but nothing needs to be done for them
+
+ ; Just (top_lvl, bind_lvl) -- See Note [Quoting names]
+ | isTopLevel top_lvl
+ -> when (isExternalName name) (keepAlive name)
+ | otherwise
+ -> do { traceRn (text "rn_bracket VarBr" <+> ppr name <+> ppr bind_lvl <+> ppr outer_stage)
+ ; checkTc (thLevel outer_stage + 1 == bind_lvl)
+ (quotedNameStageErr br) }
+ }
+ }
+ ; True | otherwise -> -- Imported thing
+ discardResult (loadInterfaceForName msg name)
+ -- Reason for loadInterface: deprecation checking
+ -- assumes that the home interface is loaded, and
+ -- this is the only way that is going to happen
+ }
+ ; return (VarBr flg name, unitFV name) }
+ where
+ msg = ptext (sLit "Need interface for Template Haskell quoted Name")
+
+rn_bracket _ (ExpBr e) = do { (e', fvs) <- rnLExpr e
+ ; return (ExpBr e', fvs) }
+
+rn_bracket _ (PatBr p) = rnPat ThPatQuote p $ \ p' -> return (PatBr p', emptyFVs)
+
+rn_bracket _ (TypBr t) = do { (t', fvs) <- rnLHsType TypBrCtx t
+ ; return (TypBr t', fvs) }
+
+rn_bracket _ (DecBrL decls)
+ = do { group <- groupDecls decls
+ ; gbl_env <- getGblEnv
+ ; let new_gbl_env = gbl_env { tcg_dus = emptyDUs }
+ -- The emptyDUs is so that we just collect uses for this
+ -- group alone in the call to rnSrcDecls below
+ ; (tcg_env, group') <- setGblEnv new_gbl_env $
+ rnSrcDecls Nothing group
+
+ -- Discard the tcg_env; it contains only extra info about fixity
+ ; traceRn (text "rn_bracket dec" <+> (ppr (tcg_dus tcg_env) $$
+ ppr (duUses (tcg_dus tcg_env))))
+ ; return (DecBrG group', duUses (tcg_dus tcg_env)) }
+ where
+ groupDecls :: [LHsDecl RdrName] -> RnM (HsGroup RdrName)
+ groupDecls decls
+ = do { (group, mb_splice) <- findSplice decls
+ ; case mb_splice of
+ { Nothing -> return group
+ ; Just (splice, rest) ->
+ do { group' <- groupDecls rest
+ ; let group'' = appendGroups group group'
+ ; return group'' { hs_splcds = noLoc splice : hs_splcds group' }
+ }
+ }}
+
+rn_bracket _ (DecBrG _) = panic "rn_bracket: unexpected DecBrG"
+
+rn_bracket _ (TExpBr e) = do { (e', fvs) <- rnLExpr e
+ ; return (TExpBr e', fvs) }
+
+quotationCtxtDoc :: HsBracket RdrName -> SDoc
+quotationCtxtDoc br_body
+ = hang (ptext (sLit "In the Template Haskell quotation"))
+ 2 (ppr br_body)
+
+illegalBracket :: SDoc
+illegalBracket = ptext (sLit "Template Haskell brackets cannot be nested (without intervening splices)")
+illegalTypedBracket :: SDoc
+illegalTypedBracket = ptext (sLit "Typed brackets may only appear in typed slices.")
+
+illegalUntypedBracket :: SDoc
+illegalUntypedBracket = ptext (sLit "Untyped brackets may only appear in untyped slices.")
+
+quotedNameStageErr :: HsBracket RdrName -> SDoc
+quotedNameStageErr br
+ = sep [ ptext (sLit "Stage error: the non-top-level quoted name") <+> ppr br
+ , ptext (sLit "must be used at the same stage at which is is bound")]
+
+#ifndef GHCI
rnTopSpliceDecls :: HsSplice RdrName -> RnM ([LHsDecl RdrName], FreeVars)
rnTopSpliceDecls e = failTH e "Template Haskell top splice"
@@ -363,120 +498,6 @@ Pat RdrName (the result of running a top-level splice) or a Pat Name
rnSplicePat.
-}
-{-
-************************************************************************
-* *
- Template Haskell brackets
-* *
-************************************************************************
--}
-
-rnBracket :: HsExpr RdrName -> HsBracket RdrName -> RnM (HsExpr Name, FreeVars)
-rnBracket e br_body
- = addErrCtxt (quotationCtxtDoc br_body) $
- do { -- Check that Template Haskell is enabled and available
- thEnabled <- xoptM Opt_TemplateHaskell
- ; unless thEnabled $
- failWith ( vcat [ ptext (sLit "Syntax error on") <+> ppr e
- , ptext (sLit "Perhaps you intended to use TemplateHaskell") ] )
- ; checkTH e "Template Haskell bracket"
-
- -- Check for nested brackets
- ; cur_stage <- getStage
- ; case cur_stage of
- { Splice True -> checkTc (isTypedBracket br_body) illegalUntypedBracket
- ; Splice False -> checkTc (not (isTypedBracket br_body)) illegalTypedBracket
- ; Comp -> return ()
- ; Brack {} -> failWithTc illegalBracket
- }
-
- -- Brackets are desugared to code that mentions the TH package
- ; recordThUse
-
- ; case isTypedBracket br_body of
- True -> do { (body', fvs_e) <- setStage (Brack cur_stage RnPendingTyped) $
- rn_bracket cur_stage br_body
- ; return (HsBracket body', fvs_e) }
-
- False -> do { ps_var <- newMutVar []
- ; (body', fvs_e) <- setStage (Brack cur_stage (RnPendingUntyped ps_var)) $
- rn_bracket cur_stage br_body
- ; pendings <- readMutVar ps_var
- ; return (HsRnBracketOut body' pendings, fvs_e) }
- }
-
-rn_bracket :: ThStage -> HsBracket RdrName -> RnM (HsBracket Name, FreeVars)
-rn_bracket outer_stage br@(VarBr flg rdr_name)
- = do { name <- lookupOccRn rdr_name
- ; this_mod <- getModule
-
- ; case flg of
- { -- Type variables can be quoted in TH. See #5721.
- False -> return ()
- ; True | nameIsLocalOrFrom this_mod name ->
- do { mb_bind_lvl <- lookupLocalOccThLvl_maybe name
- ; case mb_bind_lvl of
- { Nothing -> return () -- Can happen for data constructors,
- -- but nothing needs to be done for them
-
- ; Just (top_lvl, bind_lvl) -- See Note [Quoting names]
- | isTopLevel top_lvl
- -> when (isExternalName name) (keepAlive name)
- | otherwise
- -> do { traceRn (text "rn_bracket VarBr" <+> ppr name <+> ppr bind_lvl <+> ppr outer_stage)
- ; checkTc (thLevel outer_stage + 1 == bind_lvl)
- (quotedNameStageErr br) }
- }
- }
- ; True | otherwise -> -- Imported thing
- discardResult (loadInterfaceForName msg name)
- -- Reason for loadInterface: deprecation checking
- -- assumes that the home interface is loaded, and
- -- this is the only way that is going to happen
- }
- ; return (VarBr flg name, unitFV name) }
- where
- msg = ptext (sLit "Need interface for Template Haskell quoted Name")
-
-rn_bracket _ (ExpBr e) = do { (e', fvs) <- rnLExpr e
- ; return (ExpBr e', fvs) }
-
-rn_bracket _ (PatBr p) = rnPat ThPatQuote p $ \ p' -> return (PatBr p', emptyFVs)
-
-rn_bracket _ (TypBr t) = do { (t', fvs) <- rnLHsType TypBrCtx t
- ; return (TypBr t', fvs) }
-
-rn_bracket _ (DecBrL decls)
- = do { group <- groupDecls decls
- ; gbl_env <- getGblEnv
- ; let new_gbl_env = gbl_env { tcg_dus = emptyDUs }
- -- The emptyDUs is so that we just collect uses for this
- -- group alone in the call to rnSrcDecls below
- ; (tcg_env, group') <- setGblEnv new_gbl_env $
- rnSrcDecls Nothing group
-
- -- Discard the tcg_env; it contains only extra info about fixity
- ; traceRn (text "rn_bracket dec" <+> (ppr (tcg_dus tcg_env) $$
- ppr (duUses (tcg_dus tcg_env))))
- ; return (DecBrG group', duUses (tcg_dus tcg_env)) }
- where
- groupDecls :: [LHsDecl RdrName] -> RnM (HsGroup RdrName)
- groupDecls decls
- = do { (group, mb_splice) <- findSplice decls
- ; case mb_splice of
- { Nothing -> return group
- ; Just (splice, rest) ->
- do { group' <- groupDecls rest
- ; let group'' = appendGroups group group'
- ; return group'' { hs_splcds = noLoc splice : hs_splcds group' }
- }
- }}
-
-rn_bracket _ (DecBrG _) = panic "rn_bracket: unexpected DecBrG"
-
-rn_bracket _ (TExpBr e) = do { (e', fvs) <- rnLExpr e
- ; return (TExpBr e', fvs) }
-
spliceCtxt :: HsSplice RdrName -> SDoc
spliceCtxt splice
= hang (ptext (sLit "In the") <+> what) 2 (ppr splice)
@@ -533,31 +554,12 @@ traceSplice (SpliceInfo { spliceDescription = sd, spliceSource = mb_src
= vcat [ text "--" <+> ppr loc <> colon <+> text "Splicing" <+> text sd
, gen ]
-illegalBracket :: SDoc
-illegalBracket = ptext (sLit "Template Haskell brackets cannot be nested (without intervening splices)")
-
-illegalTypedBracket :: SDoc
-illegalTypedBracket = ptext (sLit "Typed brackets may only appear in typed slices.")
-
-illegalUntypedBracket :: SDoc
-illegalUntypedBracket = ptext (sLit "Untyped brackets may only appear in untyped slices.")
-
illegalTypedSplice :: SDoc
illegalTypedSplice = ptext (sLit "Typed splices may not appear in untyped brackets")
illegalUntypedSplice :: SDoc
illegalUntypedSplice = ptext (sLit "Untyped splices may not appear in typed brackets")
-quotedNameStageErr :: HsBracket RdrName -> SDoc
-quotedNameStageErr br
- = sep [ ptext (sLit "Stage error: the non-top-level quoted name") <+> ppr br
- , ptext (sLit "must be used at the same stage at which is is bound")]
-
-quotationCtxtDoc :: HsBracket RdrName -> SDoc
-quotationCtxtDoc br_body
- = hang (ptext (sLit "In the Template Haskell quotation"))
- 2 (ppr br_body)
-
-- spliceResultDoc :: OutputableBndr id => LHsExpr id -> SDoc
-- spliceResultDoc expr
-- = vcat [ hang (ptext (sLit "In the splice:"))
@@ -566,13 +568,6 @@ quotationCtxtDoc br_body
#endif
checkThLocalName :: Name -> RnM ()
-#ifndef GHCI /* GHCI and TH is off */
---------------------------------------
--- Check for cross-stage lifting
-checkThLocalName _name
- = return ()
-
-#else /* GHCI and TH is on */
checkThLocalName name
| isUnboundName name -- Do not report two errors for
= return () -- $(not_in_scope args)
@@ -638,7 +633,6 @@ check_cross_stage_lifting top_lvl name ps_var
-- Update the pending splices
; ps <- readMutVar ps_var
; writeMutVar ps_var (pend_splice : ps) }
-#endif /* GHCI */
{-
Note [Keeping things alive for Template Haskell]