X-Git-Url: http://git.megacz.com/?a=blobdiff_plain;f=ghc%2Fcompiler%2Ftypecheck%2FTcSplice.lhs;h=6a2c4d77f8513824be9e9a10a16bb6a3721a4393;hb=6e6f54693cb89f77701583a55dd39cd4d767c61b;hp=ba6891d17730858673960aac673bbfd1ea1a1792;hpb=0877011afd5886ee06df2e2723d631ff0686324f;p=ghc-hetmet.git diff --git a/ghc/compiler/typecheck/TcSplice.lhs b/ghc/compiler/typecheck/TcSplice.lhs index ba6891d..6a2c4d7 100644 --- a/ghc/compiler/typecheck/TcSplice.lhs +++ b/ghc/compiler/typecheck/TcSplice.lhs @@ -16,23 +16,25 @@ import TcRnDriver ( importSupportingDecls, tcTopSrcDecls ) import qualified Language.Haskell.THSyntax as Meta import HscTypes ( HscEnv(..), GhciMode(..), PersistentCompilerState(..), unQualInScope ) -import HsSyn ( HsBracket(..) ) +import HsSyn ( HsBracket(..), HsExpr(..) ) import Convert ( convertToHsExpr, convertToHsDecls ) import RnExpr ( rnExpr ) import RdrHsSyn ( RdrNameHsExpr, RdrNameHsDecl ) import RnHsSyn ( RenamedHsExpr ) -import TcExpr ( tcMonoExpr ) +import TcExpr ( tcCheckRho ) import TcHsSyn ( TcExpr, TypecheckedHsExpr, mkHsLet, zonkTopExpr ) -import TcSimplify ( tcSimplifyTop ) +import TcSimplify ( tcSimplifyTop, tcSimplifyBracket ) +import TcUnify ( unifyTauTy ) import TcType ( TcType, openTypeKind, mkAppTy ) -import TcEnv ( spliceOK, tcMetaTy ) +import TcEnv ( spliceOK, tcMetaTy, tcWithTempInstEnv, bracketOK ) import TcRnTypes ( TopEnv(..) ) -import TcMType ( newTyVarTy, zapToType ) +import TcMType ( newTyVarTy, zapToType, UserTypeCtxt(ExprSigCtxt) ) +import TcMonoType ( tcHsSigType ) import Name ( Name ) import TcRnMonad import TysWiredIn ( mkListTy ) -import DsMeta ( exprTyConName, declTyConName, decTyConName, qTyConName ) +import DsMeta ( exprTyConName, declTyConName, typeTyConName, decTyConName, qTyConName ) import ErrUtils (Message) import Outputable import Panic ( showException ) @@ -63,20 +65,55 @@ tcSpliceDecls e = pprPanic "Cant do tcSpliceDecls without GHCi" (ppr e) %************************************************************************ %* * -\subsection{Splicing an expression} +\subsection{Quoting an expression} %* * %************************************************************************ \begin{code} -tcBracket :: HsBracket Name -> TcM TcType -tcBracket (ExpBr expr) - = newTyVarTy openTypeKind `thenM` \ any_ty -> - tcMonoExpr expr any_ty `thenM_` +tcBracket :: HsBracket Name -> TcType -> TcM TcExpr +tcBracket brack res_ty + = getStage `thenM` \ level -> + case bracketOK level of { + Nothing -> failWithTc (illegalBracket level) ; + Just next_level -> + + -- Typecheck expr to make sure it is valid, + -- but throw away the results. We'll type check + -- it again when we actually use it. + newMutVar [] `thenM` \ pending_splices -> + getLIEVar `thenM` \ lie_var -> + + setStage (Brack next_level pending_splices lie_var) ( + getLIE (tc_bracket brack) + ) `thenM` \ (meta_ty, lie) -> + tcSimplifyBracket lie `thenM_` + + unifyTauTy res_ty meta_ty `thenM_` + + -- Return the original expression, not the type-decorated one + readMutVar pending_splices `thenM` \ pendings -> + returnM (HsBracketOut brack pendings) + } + +tc_bracket :: HsBracket Name -> TcM TcType +tc_bracket (ExpBr expr) + = newTyVarTy openTypeKind `thenM` \ any_ty -> + tcCheckRho expr any_ty `thenM_` tcMetaTy exprTyConName -- Result type is Expr (= Q Exp) -tcBracket (DecBr decls) - = tcTopSrcDecls decls `thenM_` +tc_bracket (TypBr typ) + = tcHsSigType ExprSigCtxt typ `thenM_` + tcMetaTy typeTyConName + -- Result type is Type (= Q Typ) + +tc_bracket (DecBr decls) + = tcWithTempInstEnv (tcTopSrcDecls decls) `thenM_` + -- Typecheck the declarations, dicarding any side effects + -- on the instance environment (which is in a mutable variable) + -- and the extended environment. We'll get all that stuff + -- later, when we splice it in + tcMetaTy decTyConName `thenM` \ decl_ty -> tcMetaTy qTyConName `thenM` \ q_ty -> returnM (mkAppTy q_ty (mkListTy decl_ty)) @@ -111,7 +148,7 @@ tcSpliceExpr name expr res_ty tcMetaTy exprTyConName `thenM` \ meta_exp_ty -> setStage (Splice next_level) ( setLIEVar lie_var $ - tcMonoExpr expr meta_exp_ty + tcCheckRho expr meta_exp_ty ) `thenM` \ expr' -> -- Write the pending splice into the bucket @@ -125,7 +162,7 @@ tcSpliceExpr name expr res_ty -- Note that we do not decrement the level (to -1) before -- typechecking the expression. For example: -- f x = $( ...$(g 3) ... ) --- The recursive call to tcMonoExpr will simply expand the +-- The recursive call to tcCheckRho will simply expand the -- inner escape before dealing with the outer one tcTopSplice expr res_ty @@ -151,10 +188,12 @@ tcTopSplice expr res_ty initRn SourceMode (rnExpr expr2) `thenM` \ (exp3, fvs) -> importSupportingDecls fvs `thenM` \ env -> - setGblEnv env (tcMonoExpr exp3 res_ty) + setGblEnv env (tcCheckRho exp3 res_ty) tcTopSpliceExpr :: RenamedHsExpr -> TcType -> TcM TypecheckedHsExpr +-- Type check an expression that is the body of a top-level splice +-- (the caller will compile and run it) tcTopSpliceExpr expr meta_ty = checkNoErrs $ -- checkNoErrs: must not try to run the thing -- if the type checker fails! @@ -162,7 +201,7 @@ tcTopSpliceExpr expr meta_ty setStage topSpliceStage $ -- Typecheck the expression - getLIE (tcMonoExpr expr meta_ty) `thenM` \ (expr', lie) -> + getLIE (tcCheckRho expr meta_ty) `thenM` \ (expr', lie) -> -- Solve the constraints tcSimplifyTop lie `thenM` \ const_binds -> @@ -362,6 +401,9 @@ showSplice what before after text "======>", nest 2 after])]) +illegalBracket level + = ptext SLIT("Illegal bracket at level") <+> ppr level + illegalSplice level = ptext SLIT("Illegal splice at level") <+> ppr level