diff options
author | Jan Stolarek <jan.stolarek@p.lodz.pl> | 2015-09-08 19:19:44 +0200 |
---|---|---|
committer | Jan Stolarek <jan.stolarek@p.lodz.pl> | 2015-10-16 20:15:44 +0200 |
commit | 75492e7467ff962f2f2e29e5c8b2c588c94ae8a7 (patch) | |
tree | 8ed0f57f12dbb5c73b0f0d1d1994aef5dd89cea0 /compiler/rename/RnSplice.hs | |
parent | b1884b0e62f62e3c0859515c4137124ab0c9560e (diff) | |
download | haskell-75492e7467ff962f2f2e29e5c8b2c588c94ae8a7.tar.gz |
Add typed holes support in Template Haskell.
Fixes #10267. Typed holes in typed Template Haskell currently don't work.
See #10945 and #10946.
Diffstat (limited to 'compiler/rename/RnSplice.hs')
-rw-r--r-- | compiler/rename/RnSplice.hs | 75 |
1 files changed, 48 insertions, 27 deletions
diff --git a/compiler/rename/RnSplice.hs b/compiler/rename/RnSplice.hs index 073ddaa121..b78d4c7aa9 100644 --- a/compiler/rename/RnSplice.hs +++ b/compiler/rename/RnSplice.hs @@ -27,7 +27,6 @@ import Outputable import Module import SrcLoc import DynFlags -import FastString import RnTypes ( rnLHsType ) import Control.Monad ( unless, when ) @@ -39,6 +38,7 @@ import TcEnv ( checkWellStaged ) import THNames ( liftName ) #ifdef GHCI +import FastString import ErrUtils ( dumpIfSet_dyn_printer ) import TcEnv ( tcMetaTy ) import Hooks @@ -66,29 +66,36 @@ rnBracket e 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") ] ) + failWith ( vcat + [ text "Syntax error on" <+> ppr e + , text "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 + { Splice Typed -> checkTc (isTypedBracket br_body) + illegalUntypedBracket + ; Splice Untyped -> 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 + True -> do { traceRn (text "Renaming typed TH bracket") + ; (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 + False -> do { traceRn (text "Renaming untyped TH bracket") + ; 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) } } @@ -157,22 +164,26 @@ rn_bracket _ (TExpBr e) = do { (e', fvs) <- rnLExpr e quotationCtxtDoc :: HsBracket RdrName -> SDoc quotationCtxtDoc br_body - = hang (ptext (sLit "In the Template Haskell quotation")) + = hang (text "In the Template Haskell quotation") 2 (ppr br_body) illegalBracket :: SDoc -illegalBracket = ptext (sLit "Template Haskell brackets cannot be nested (without intervening splices)") +illegalBracket = + text "Template Haskell brackets cannot be nested" <+> + text "(without intervening splices)" illegalTypedBracket :: SDoc -illegalTypedBracket = ptext (sLit "Typed brackets may only appear in typed slices.") +illegalTypedBracket = + text "Typed brackets may only appear in typed splices." illegalUntypedBracket :: SDoc -illegalUntypedBracket = ptext (sLit "Untyped brackets may only appear in untyped slices.") +illegalUntypedBracket = + text "Untyped brackets may only appear in untyped splices." 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")] + = sep [ text "Stage error: the non-top-level quoted name" <+> ppr br + , text "must be used at the same stage at which is is bound" ] #ifndef GHCI rnTopSpliceDecls :: HsSplice RdrName -> RnM ([LHsDecl RdrName], FreeVars) @@ -253,7 +264,7 @@ rnSpliceGen run_splice pend_splice splice ; return (result, fvs) } _ -> do { (splice', fvs1) <- checkNoErrs $ - setStage (Splice is_typed_splice) $ + setStage (Splice splice_type) $ rnSplice splice -- checkNoErrs: don't attempt to run the splice if -- renaming it failed; otherwise we get a cascade of @@ -262,6 +273,9 @@ rnSpliceGen run_splice pend_splice splice ; return (result, fvs1 `plusFV` fvs2) } } where is_typed_splice = isTypedSplice splice + splice_type = if is_typed_splice + then Typed + else Untyped ------------------ runRnSplice :: UntypedSpliceFlavour @@ -280,7 +294,7 @@ runRnSplice flavour run_meta ppr_res splice -- Typecheck the expression ; meta_exp_ty <- tcMetaTy meta_ty_name - ; zonked_q_expr <- tcTopSpliceExpr False $ + ; zonked_q_expr <- tcTopSpliceExpr Untyped $ tcMonoExpr the_expr meta_exp_ty -- Run the expression @@ -396,7 +410,8 @@ rnSpliceExpr splice run_expr_splice rn_splice | isTypedSplice rn_splice -- Run it later, in the type checker = do { -- Ugh! See Note [Splices] above - lcl_rdr <- getLocalRdrEnv + traceRn (text "rnSpliceExpr: typed expression splice") + ; lcl_rdr <- getLocalRdrEnv ; gbl_rdr <- getGlobalRdrEnv ; let gbl_names = mkNameSet [gre_name gre | gre <- globalRdrEnvElts gbl_rdr , isLocalGRE gre] @@ -405,7 +420,8 @@ rnSpliceExpr splice ; return (HsSpliceE rn_splice, lcl_names `plusFV` gbl_names) } | otherwise -- Run it here - = do { rn_expr <- runRnSplice UntypedExpSplice runMetaE ppr rn_splice + = 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) } @@ -419,7 +435,8 @@ rnSpliceType splice k = (makePending UntypedTypeSplice rn_splice, HsSpliceTy rn_splice k) run_type_splice rn_splice - = do { hs_ty2 <- runRnSplice UntypedTypeSplice runMetaT ppr rn_splice + = do { traceRn (text "rnSpliceType: untyped type splice") + ; hs_ty2 <- runRnSplice UntypedTypeSplice runMetaT ppr rn_splice ; (hs_ty3, fvs) <- do { let doc = SpliceTypeCtx hs_ty2 ; checkValidPartialTypeSplice doc hs_ty2 -- See Note [Partial Type Splices] @@ -497,7 +514,8 @@ rnSplicePat splice = (makePending UntypedPatSplice rn_splice, Right (SplicePat rn_splice)) run_pat_splice rn_splice - = do { pat <- runRnSplice UntypedPatSplice runMetaP ppr rn_splice + = do { traceRn (text "rnSplicePat: untyped pattern splice") + ; pat <- runRnSplice UntypedPatSplice runMetaP ppr rn_splice ; return (Left (ParPat pat), emptyFVs) } -- Wrap the result of the quasi-quoter in parens so that we don't -- lose the outermost location set by runQuasiQuote (#7918) @@ -515,8 +533,9 @@ rnSpliceDecl (SpliceDecl (L loc splice) flg) rnTopSpliceDecls :: HsSplice RdrName -> RnM ([LHsDecl RdrName], FreeVars) -- Declaration splice at the very top level of the module rnTopSpliceDecls splice - = do { (rn_splice, fvs) <- setStage (Splice False) $ + = do { (rn_splice, fvs) <- setStage (Splice Untyped) $ rnSplice splice + ; traceRn (text "rnTopSpliceDecls: untyped declaration splice") ; decls <- runRnSplice UntypedDeclSplice runMetaD ppr_decls rn_splice ; return (decls,fvs) } where @@ -538,8 +557,10 @@ the CpsRn monad. The problem is that if we're renaming a splice within a bracket, we *don't* want to run the splice now. We really do just want to rename it to an HsSplice Name. Of course, then we can't know what variables -are bound within the splice, so pattern splices within brackets aren't -all that useful. +are bound within the splice. So we accept any unbound variables and +rename them again when the bracket is spliced in. If a variable is brought +into scope by a pattern splice all is fine. If it is not then an error is +reported. In any case, when we're done in rnSplicePat, we'll either have a Pat RdrName (the result of running a top-level splice) or a Pat Name |