X-Git-Url: http://git.megacz.com/?a=blobdiff_plain;f=ghc%2Fcompiler%2Ftypecheck%2FTcSplice.lhs;h=31dfd3141aceab76bf17d4fea054de3cc8bc9aa3;hb=ff845ab59d1d465d874d3908fd0cdd61b8594da2;hp=b7b3c298b4147408cfc06afecd5f3ed9569b7ac2;hpb=1f5e55804b97d2b9a77207d568d602ba88d8855d;p=ghc-hetmet.git diff --git a/ghc/compiler/typecheck/TcSplice.lhs b/ghc/compiler/typecheck/TcSplice.lhs index b7b3c29..31dfd31 100644 --- a/ghc/compiler/typecheck/TcSplice.lhs +++ b/ghc/compiler/typecheck/TcSplice.lhs @@ -13,51 +13,62 @@ import TcRnDriver ( tcTopSrcDecls ) -- These imports are the reason that TcSplice -- is very high up the module hierarchy -import qualified Language.Haskell.TH.THSyntax as TH +import qualified Language.Haskell.TH as TH -- THSyntax gives access to internal functions and data types - -import HscTypes ( HscEnv(..) ) -import HsSyn ( HsBracket(..), HsExpr(..) ) -import Convert ( convertToHsExpr, convertToHsDecls ) -import RnExpr ( rnExpr ) -import RnEnv ( lookupFixityRn ) -import RdrHsSyn ( RdrNameHsExpr, RdrNameHsDecl ) -import RnHsSyn ( RenamedHsExpr ) +import qualified Language.Haskell.TH.Syntax as TH + +import HsSyn ( HsBracket(..), HsExpr(..), HsSplice(..), LHsExpr, LHsDecl, + HsType, LHsType ) +import Convert ( convertToHsExpr, convertToHsDecls, convertToHsType ) +import RnExpr ( rnLExpr ) +import RnEnv ( lookupFixityRn, lookupSrcOcc_maybe ) +import RdrName ( RdrName, mkRdrUnqual, lookupLocalRdrEnv ) +import RnTypes ( rnLHsType ) import TcExpr ( tcCheckRho, tcMonoExpr ) -import TcHsSyn ( TcExpr, TypecheckedHsExpr, mkHsLet, zonkTopExpr ) +import TcHsSyn ( mkHsLet, zonkTopLExpr ) import TcSimplify ( tcSimplifyTop, tcSimplifyBracket ) import TcUnify ( Expected, zapExpectedTo, zapExpectedType ) -import TcType ( TcType, openTypeKind, mkAppTy, tcSplitSigmaTy ) -import TcEnv ( spliceOK, tcMetaTy, bracketOK, tcLookup ) -import TcMType ( newTyVarTy, UserTypeCtxt(ExprSigCtxt), zonkTcType, zonkTcTyVar ) -import TcHsType ( tcHsSigType ) +import TcType ( TcType, TcKind, liftedTypeKind, mkAppTy, tcSplitSigmaTy ) +import TcEnv ( spliceOK, tcMetaTy, bracketOK ) +import TcMType ( newTyFlexiVarTy, newKindVar, UserTypeCtxt(ExprSigCtxt), zonkTcType, zonkTcTyVar ) +import TcHsType ( tcHsSigType, kcHsType ) +import TcIface ( tcImportDecl ) import TypeRep ( Type(..), PredType(..), TyThing(..) ) -- For reification -import Name ( Name, NamedThing(..), nameOccName, nameModule, isExternalName ) +import Name ( Name, NamedThing(..), nameOccName, nameModule, isExternalName, + mkInternalName, nameIsLocalOrFrom ) +import NameEnv ( lookupNameEnv ) +import HscTypes ( lookupType, ExternalPackageState(..) ) import OccName -import Var ( TyVar, idType ) +import Var ( Id, TyVar, idType ) import Module ( moduleUserString, mkModuleName ) import TcRnMonad import IfaceEnv ( lookupOrig ) - -import Class ( Class, classBigSig ) -import TyCon ( TyCon, tyConTheta, tyConTyVars, getSynTyConDefn, isSynTyCon, isNewTyCon, tyConDataCons ) +import Class ( Class, classExtraBigSig ) +import TyCon ( TyCon, AlgTyConRhs(..), tyConTyVars, getSynTyConDefn, + isSynTyCon, isNewTyCon, tyConDataCons, algTyConRhs ) import DataCon ( DataCon, dataConTyCon, dataConOrigArgTys, dataConStrictMarks, - dataConName, dataConFieldLabels, dataConWrapId ) + dataConName, dataConFieldLabels, dataConWrapId, dataConIsInfix, + isVanillaDataCon ) import Id ( idName, globalIdDetails ) import IdInfo ( GlobalIdDetails(..) ) import TysWiredIn ( mkListTy ) import DsMeta ( expQTyConName, typeQTyConName, decTyConName, qTyConName, nameTyConName ) import ErrUtils ( Message ) +import SrcLoc ( noLoc, unLoc, getLoc, noSrcLoc ) import Outputable -import Unique ( Unique, Uniquable(..), getKey ) -import IOEnv ( IOEnv ) +import Unique ( Unique, Uniquable(..), getKey, mkUniqueGrimily ) + import BasicTypes ( StrictnessMark(..), Fixity(..), FixityDirection(..) ) -import Module ( moduleUserString ) import Panic ( showException ) -import GHC.Base ( unsafeCoerce#, Int(..) ) -- Should have a better home in the module hierarchy -import Monad ( liftM ) import FastString ( LitString ) -import FastTypes ( iBox ) + +import GHC.Base ( unsafeCoerce#, Int#, Int(..) ) -- Should have a better home in the module hierarchy +import Monad ( liftM ) +import Maybes ( orElse ) + +#ifdef GHCI +import FastString ( mkFastString ) +#endif \end{code} @@ -68,12 +79,9 @@ import FastTypes ( iBox ) %************************************************************************ \begin{code} -tcSpliceDecls :: RenamedHsExpr -> TcM [RdrNameHsDecl] - -tcSpliceExpr :: Name - -> RenamedHsExpr - -> Expected TcType - -> TcM TcExpr +tcSpliceDecls :: LHsExpr Name -> TcM [LHsDecl RdrName] +tcSpliceExpr :: HsSplice Name -> Expected TcType -> TcM (HsExpr TcId) +kcSpliceType :: HsSplice Name -> TcM (HsType Name, TcKind) #ifndef GHCI tcSpliceExpr n e ty = pprPanic "Cant do tcSpliceExpr without GHCi" (ppr e) @@ -88,7 +96,7 @@ tcSpliceDecls e = pprPanic "Cant do tcSpliceDecls without GHCi" (ppr e) %************************************************************************ \begin{code} -tcBracket :: HsBracket Name -> Expected TcType -> TcM TcExpr +tcBracket :: HsBracket Name -> Expected TcType -> TcM (LHsExpr Id) tcBracket brack res_ty = getStage `thenM` \ level -> case bracketOK level of { @@ -98,6 +106,7 @@ tcBracket brack res_ty -- Typecheck expr to make sure it is valid, -- but throw away the results. We'll type check -- it again when we actually use it. + recordThUse `thenM_` newMutVar [] `thenM` \ pending_splices -> getLIEVar `thenM` \ lie_var -> @@ -111,7 +120,7 @@ tcBracket brack res_ty -- Return the original expression, not the type-decorated one readMutVar pending_splices `thenM` \ pendings -> - returnM (HsBracketOut brack pendings) + returnM (noLoc (HsBracketOut brack pendings)) } tc_bracket :: HsBracket Name -> TcM TcType @@ -120,8 +129,8 @@ tc_bracket (VarBr v) -- Result type is Var (not Q-monadic) tc_bracket (ExpBr expr) - = newTyVarTy openTypeKind `thenM` \ any_ty -> - tcCheckRho expr any_ty `thenM_` + = newTyFlexiVarTy liftedTypeKind `thenM` \ any_ty -> + tcCheckRho expr any_ty `thenM_` tcMetaTy expQTyConName -- Result type is Expr (= Q Exp) @@ -131,7 +140,7 @@ tc_bracket (TypBr typ) -- Result type is Type (= Q Typ) tc_bracket (DecBr decls) - = tcTopSrcDecls decls `thenM_` + = tcTopSrcDecls [{- no boot-names -}] decls `thenM_` -- Typecheck the declarations, dicarding the result -- We'll get all that stuff later, when we splice it in @@ -149,14 +158,16 @@ tc_bracket (DecBr decls) %************************************************************************ \begin{code} -tcSpliceExpr name expr res_ty - = getStage `thenM` \ level -> +tcSpliceExpr (HsSplice name expr) res_ty + = setSrcSpan (getLoc expr) $ + getStage `thenM` \ level -> case spliceOK level of { Nothing -> failWithTc (illegalSplice level) ; Just next_level -> case level of { - Comp -> tcTopSplice expr res_ty ; + Comp -> do { e <- tcTopSplice expr res_ty + ; returnM (unLoc e) } ; Brack _ ps_var lie_var -> -- A splice inside brackets @@ -165,7 +176,7 @@ tcSpliceExpr name expr res_ty -- Here (h 4) :: Q Exp -- but $(h 4) :: forall a.a i.e. anything! - zapExpectedType res_ty `thenM_` + zapExpectedType res_ty liftedTypeKind `thenM_` tcMetaTy expQTyConName `thenM` \ meta_exp_ty -> setStage (Splice next_level) ( setLIEVar lie_var $ @@ -186,6 +197,7 @@ tcSpliceExpr name expr res_ty -- The recursive call to tcMonoExpr will simply expand the -- inner escape before dealing with the outer one +tcTopSplice :: LHsExpr Name -> Expected TcType -> TcM (LHsExpr Id) tcTopSplice expr res_ty = tcMetaTy expQTyConName `thenM` \ meta_exp_ty -> @@ -199,40 +211,111 @@ tcTopSplice expr res_ty let -- simple_expr :: TH.Exp - expr2 :: RdrNameHsExpr + expr2 :: LHsExpr RdrName expr2 = convertToHsExpr simple_expr in traceTc (text "Got result" <+> ppr expr2) `thenM_` showSplice "expression" zonked_q_expr (ppr expr2) `thenM_` - rnExpr expr2 `thenM` \ (exp3, fvs) -> + + -- Rename it, but bale out if there are errors + -- otherwise the type checker just gives more spurious errors + checkNoErrs (rnLExpr expr2) `thenM` \ (exp3, fvs) -> tcMonoExpr exp3 res_ty -tcTopSpliceExpr :: RenamedHsExpr -> TcType -> TcM TypecheckedHsExpr +tcTopSpliceExpr :: LHsExpr Name -> TcType -> TcM (LHsExpr Id) -- 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! - setStage topSpliceStage $ + setStage topSpliceStage $ do - -- Typecheck the expression - getLIE (tcCheckRho expr meta_ty) `thenM` \ (expr', lie) -> + + do { recordThUse -- Record that TH is used (for pkg depdendency) + -- Typecheck the expression + ; (expr', lie) <- getLIE (tcCheckRho expr meta_ty) + -- Solve the constraints - tcSimplifyTop lie `thenM` \ const_binds -> + ; const_binds <- tcSimplifyTop lie -- And zonk it - zonkTopExpr (mkHsLet const_binds expr') + ; zonkTopLExpr (mkHsLet const_binds expr') } \end{code} %************************************************************************ %* * + Splicing a type +%* * +%************************************************************************ + +Very like splicing an expression, but we don't yet share code. + +\begin{code} +kcSpliceType (HsSplice name hs_expr) + = setSrcSpan (getLoc hs_expr) $ do + { level <- getStage + ; case spliceOK level of { + Nothing -> failWithTc (illegalSplice level) ; + Just next_level -> do + + { case level of { + Comp -> do { (t,k) <- kcTopSpliceType hs_expr + ; return (unLoc t, k) } ; + Brack _ ps_var lie_var -> do + + { -- A splice inside brackets + ; meta_ty <- tcMetaTy typeQTyConName + ; expr' <- setStage (Splice next_level) $ + setLIEVar lie_var $ + tcCheckRho hs_expr meta_ty + + -- Write the pending splice into the bucket + ; ps <- readMutVar ps_var + ; writeMutVar ps_var ((name,expr') : ps) + + -- e.g. [| Int -> $(h 4) |] + -- Here (h 4) :: Q Type + -- but $(h 4) :: forall a.a i.e. any kind + ; kind <- newKindVar + ; returnM (panic "kcSpliceType", kind) -- The returned type is ignored + }}}}} + +kcTopSpliceType :: LHsExpr Name -> TcM (LHsType Name, TcKind) +kcTopSpliceType expr + = do { meta_ty <- tcMetaTy typeQTyConName + + -- Typecheck the expression + ; zonked_q_expr <- tcTopSpliceExpr expr meta_ty + + -- Run the expression + ; traceTc (text "About to run" <+> ppr zonked_q_expr) + ; simple_ty <- runMetaT zonked_q_expr + + ; let -- simple_ty :: TH.Type + hs_ty2 :: LHsType RdrName + hs_ty2 = convertToHsType simple_ty + + ; traceTc (text "Got result" <+> ppr hs_ty2) + + ; showSplice "type" zonked_q_expr (ppr hs_ty2) + + -- Rename it, but bale out if there are errors + -- otherwise the type checker just gives more spurious errors + ; let doc = ptext SLIT("In the spliced type") <+> ppr hs_ty2 + ; hs_ty3 <- checkNoErrs (rnLHsType doc hs_ty2) + + ; kcHsType hs_ty3 } +\end{code} + +%************************************************************************ +%* * \subsection{Splicing an expression} %* * %************************************************************************ @@ -240,23 +323,22 @@ tcTopSpliceExpr expr meta_ty \begin{code} -- Always at top level tcSpliceDecls expr - = tcMetaTy decTyConName `thenM` \ meta_dec_ty -> - tcMetaTy qTyConName `thenM` \ meta_q_ty -> - let - list_q = mkAppTy meta_q_ty (mkListTy meta_dec_ty) - in - tcTopSpliceExpr expr list_q `thenM` \ zonked_q_expr -> - - -- Run the expression - traceTc (text "About to run" <+> ppr zonked_q_expr) `thenM_` - runMetaD zonked_q_expr `thenM` \ simple_expr -> - -- simple_expr :: [TH.Dec] - -- decls :: [RdrNameHsDecl] - handleErrors (convertToHsDecls simple_expr) `thenM` \ decls -> - traceTc (text "Got result" <+> vcat (map ppr decls)) `thenM_` - showSplice "declarations" - zonked_q_expr (vcat (map ppr decls)) `thenM_` - returnM decls + = do { meta_dec_ty <- tcMetaTy decTyConName + ; meta_q_ty <- tcMetaTy qTyConName + ; let list_q = mkAppTy meta_q_ty (mkListTy meta_dec_ty) + ; zonked_q_expr <- tcTopSpliceExpr expr list_q + + -- Run the expression + ; traceTc (text "About to run" <+> ppr zonked_q_expr) + ; simple_expr <- runMetaD zonked_q_expr + + -- simple_expr :: [TH.Dec] + -- decls :: [RdrNameHsDecl] + ; decls <- handleErrors (convertToHsDecls simple_expr) + ; traceTc (text "Got result" <+> vcat (map ppr decls)) + ; showSplice "declarations" + zonked_q_expr (vcat (map ppr decls)) + ; returnM decls } where handleErrors :: [Either a Message] -> TcM [a] handleErrors [] = return [] @@ -273,15 +355,19 @@ tcSpliceDecls expr %************************************************************************ \begin{code} -runMetaE :: TypecheckedHsExpr -- Of type (Q Exp) +runMetaE :: LHsExpr Id -- Of type (Q Exp) -> TcM TH.Exp -- Of type Exp runMetaE e = runMeta e -runMetaD :: TypecheckedHsExpr -- Of type Q [Dec] +runMetaT :: LHsExpr Id -- Of type (Q Type) + -> TcM TH.Type -- Of type Type +runMetaT e = runMeta e + +runMetaD :: LHsExpr Id -- Of type Q [Dec] -> TcM [TH.Dec] -- Of type [Dec] runMetaD e = runMeta e -runMeta :: TypecheckedHsExpr -- Of type X +runMeta :: LHsExpr Id -- Of type X -> TcM t -- Of type t runMeta expr = do { hsc_env <- getTopEnv @@ -333,9 +419,9 @@ instance TH.Quasi (IOEnv (Env TcGblEnv TcLclEnv)) where %************************************************************************ \begin{code} -showSplice :: String -> TypecheckedHsExpr -> SDoc -> TcM () +showSplice :: String -> LHsExpr Id -> SDoc -> TcM () showSplice what before after - = getSrcLocM `thenM` \ loc -> + = getSrcSpanM `thenM` \ loc -> traceSplice (vcat [ppr loc <> colon <+> text "Splicing" <+> text what, nest 2 (sep [nest 2 (ppr before), text "======>", @@ -360,18 +446,85 @@ illegalSplice level \begin{code} reify :: TH.Name -> TcM TH.Info -reify (TH.Name occ (TH.NameG th_ns mod)) - = do { name <- lookupOrig (mkModuleName (TH.modString mod)) - (OccName.mkOccName ghc_ns (TH.occString occ)) - ; thing <- tcLookup name +reify th_name + = do { name <- lookupThName th_name + ; thing <- tcLookupTh name + -- ToDo: this tcLookup could fail, which would give a + -- rather unhelpful error message ; reifyThing thing } + +lookupThName :: TH.Name -> TcM Name +lookupThName (TH.Name occ (TH.NameG th_ns mod)) + = lookupOrig (mkModuleName (TH.modString mod)) + (OccName.mkOccName ghc_ns (TH.occString occ)) where ghc_ns = case th_ns of TH.DataName -> dataName TH.TcClsName -> tcClsName TH.VarName -> varName +lookupThName th_name@(TH.Name occ TH.NameS) + = do { let rdr_name = mkRdrUnqual (OccName.mkOccFS ns occ_fs) + ; rdr_env <- getLocalRdrEnv + ; case lookupLocalRdrEnv rdr_env rdr_name of + Just name -> return name + Nothing -> do + { mb_name <- lookupSrcOcc_maybe rdr_name + ; case mb_name of + Just name -> return name ; + Nothing -> failWithTc (notInScope th_name) + }} + where + ns | isLexCon occ_fs = OccName.dataName + | otherwise = OccName.varName + occ_fs = mkFastString (TH.occString occ) + +lookupThName (TH.Name occ (TH.NameU uniq)) + = return (mkInternalName (mk_uniq uniq) (OccName.mkOccFS bogus_ns occ_fs) noSrcLoc) + where + occ_fs = mkFastString (TH.occString occ) + bogus_ns = OccName.varName -- Not yet recorded in the TH name + -- but only the unique matters + +tcLookupTh :: Name -> TcM TcTyThing +-- This is a specialised version of TcEnv.tcLookup; specialised mainly in that +-- it gives a reify-related error message on failure, whereas in the normal +-- tcLookup, failure is a bug. +tcLookupTh name + = do { (gbl_env, lcl_env) <- getEnvs + ; case lookupNameEnv (tcl_env lcl_env) name of + Just thing -> returnM thing + Nothing -> do + { if nameIsLocalOrFrom (tcg_mod gbl_env) name + then -- It's defined in this module + case lookupNameEnv (tcg_type_env gbl_env) name of + Just thing -> return (AGlobal thing) + Nothing -> failWithTc (notInEnv name) + + else do -- It's imported + { (eps,hpt) <- getEpsAndHpt + ; case lookupType hpt (eps_PTE eps) name of + Just thing -> return (AGlobal thing) + Nothing -> do { traceIf (text "tcLookupGlobal" <+> ppr name) + ; thing <- initIfaceTcRn (tcImportDecl name) + ; return (AGlobal thing) } + -- Imported names should always be findable; + -- if not, we fail hard in tcImportDecl + }}} + +mk_uniq :: Int# -> Unique +mk_uniq u = mkUniqueGrimily (I# u) + +notInScope :: TH.Name -> SDoc +notInScope th_name = quotes (text (TH.pprint th_name)) <+> + ptext SLIT("is not in scope at a reify") + -- Ugh! Rather an indirect way to display the name + +notInEnv :: Name -> SDoc +notInEnv name = quotes (ppr name) <+> + ptext SLIT("is not in the type environment at a reify") + ------------------------------ reifyThing :: TcTyThing -> TcM TH.Info -- The only reason this is monadic is for error reporting, @@ -415,37 +568,50 @@ reifyTyCon tc ; rhs' <- reifyType rhs ; return (TH.TySynD (reifyName tc) (reifyTyVars tvs) rhs') } - | isNewTyCon tc - = do { cxt <- reifyCxt (tyConTheta tc) - ; con <- reifyDataCon (head (tyConDataCons tc)) - ; return (TH.NewtypeD cxt (reifyName tc) (reifyTyVars (tyConTyVars tc)) - con [{- Don't know about deriving -}]) } - - | otherwise -- Algebraic - = do { cxt <- reifyCxt (tyConTheta tc) - ; cons <- mapM reifyDataCon (tyConDataCons tc) - ; return (TH.DataD cxt (reifyName tc) (reifyTyVars (tyConTyVars tc)) - cons [{- Don't know about deriving -}]) } +reifyTyCon tc + = case algTyConRhs tc of + NewTyCon data_con _ _ + -> do { con <- reifyDataCon data_con + ; return (TH.NewtypeD [] (reifyName tc) (reifyTyVars (tyConTyVars tc)) + con [{- Don't know about deriving -}]) } + + DataTyCon mb_cxt cons _ + -> do { cxt <- reifyCxt (mb_cxt `orElse` []) + ; cons <- mapM reifyDataCon (tyConDataCons tc) + ; return (TH.DataD cxt (reifyName tc) (reifyTyVars (tyConTyVars tc)) + cons [{- Don't know about deriving -}]) } reifyDataCon :: DataCon -> TcM TH.Con reifyDataCon dc + | isVanillaDataCon dc = do { arg_tys <- reifyTypes (dataConOrigArgTys dc) ; let stricts = map reifyStrict (dataConStrictMarks dc) fields = dataConFieldLabels dc - ; if null fields then - return (TH.NormalC (reifyName dc) (stricts `zip` arg_tys)) + name = reifyName dc + [a1,a2] = arg_tys + [s1,s2] = stricts + ; ASSERT( length arg_tys == length stricts ) + if not (null fields) then + return (TH.RecC name (zip3 (map reifyName fields) stricts arg_tys)) + else + if dataConIsInfix dc then + ASSERT( length arg_tys == 2 ) + return (TH.InfixC (s1,a1) name (s1,a2)) else - return (TH.RecC (reifyName dc) (zip3 (map reifyName fields) stricts arg_tys)) } - -- NB: we don't remember whether the constructor was declared in an infix way + return (TH.NormalC name (stricts `zip` arg_tys)) } + | otherwise + = failWithTc (ptext SLIT("Can't reify a non-Haskell-98 data constructor:") + <+> quotes (ppr dc)) ------------------------------ reifyClass :: Class -> TcM TH.Dec reifyClass cls = do { cxt <- reifyCxt theta ; ops <- mapM reify_op op_stuff - ; return (TH.ClassD cxt (reifyName cls) (reifyTyVars tvs) ops) } + ; return (TH.ClassD cxt (reifyName cls) (reifyTyVars tvs) fds' ops) } where - (tvs, theta, _, op_stuff) = classBigSig cls + (tvs, fds, theta, _, op_stuff) = classExtraBigSig cls + fds' = map reifyFunDep fds reify_op (op, _) = do { ty <- reifyType (idType op) ; return (TH.SigD (reifyName op) ty) } @@ -453,7 +619,6 @@ reifyClass cls reifyType :: TypeRep.Type -> TcM TH.Type reifyType (TyVarTy tv) = return (TH.VarT (reifyName tv)) reifyType (TyConApp tc tys) = reify_tc_app (reifyName tc) tys -reifyType (NewTcApp tc tys) = reify_tc_app (reifyName tc) tys reifyType (NoteTy _ ty) = reifyType ty reifyType (AppTy t1 t2) = do { [r1,r2] <- reifyTypes [t1,t2] ; return (r1 `TH.AppT` r2) } reifyType (FunTy t1 t2) = do { [r1,r2] <- reifyTypes [t1,t2] ; return (TH.ArrowT `TH.AppT` r1 `TH.AppT` r2) } @@ -465,6 +630,9 @@ reifyType ty@(ForAllTy _ _) = do { cxt' <- reifyCxt cxt; reifyTypes = mapM reifyType reifyCxt = mapM reifyPred +reifyFunDep :: ([TyVar], [TyVar]) -> TH.FunDep +reifyFunDep (xs, ys) = TH.FunDep (map reifyName xs) (map reifyName ys) + reifyTyVars :: [TyVar] -> [TH.Name] reifyTyVars = map reifyName @@ -513,4 +681,4 @@ noTH :: LitString -> SDoc -> TcM a noTH s d = failWithTc (hsep [ptext SLIT("Can't represent") <+> ptext s <+> ptext SLIT("in Template Haskell:"), nest 2 d]) -\end{code} \ No newline at end of file +\end{code}