Template Haskell: support for INLINE and SPECIALISE pragmas
[ghc-hetmet.git] / compiler / hsSyn / Convert.lhs
index 6b1014e..60080ee 100644 (file)
@@ -6,15 +6,8 @@
 This module converts Template Haskell syntax into HsSyn
 
 \begin{code}
-{-# OPTIONS -fno-warn-incomplete-patterns #-}
--- The above warning supression flag is a temporary kludge.
--- While working on this module you are encouraged to remove it and fix
--- any warnings in the module. See
---     http://hackage.haskell.org/trac/ghc/wiki/Commentary/CodingStyle#Warnings
--- for details
-
 module Convert( convertToHsExpr, convertToPat, convertToHsDecls,
-                convertToHsType, thRdrName ) where
+                convertToHsType, thRdrNameGuesses ) where
 
 import HsSyn as Hs
 import qualified Class
@@ -27,11 +20,12 @@ import OccName
 import SrcLoc
 import Type
 import TysWiredIn
-import BasicTypes
+import BasicTypes as Hs
 import ForeignCall
 import Char
 import List
 import Unique
+import MonadUtils
 import ErrUtils
 import Bag
 import FastString
@@ -51,14 +45,14 @@ convertToHsDecls loc ds = initCvt loc (mapM cvtTop ds)
 convertToHsExpr :: SrcSpan -> TH.Exp -> Either Message (LHsExpr RdrName)
 convertToHsExpr loc e 
   = case initCvt loc (cvtl e) of
-       Left msg  -> Left (msg $$ (ptext (sLit "When converting TH expression")
+       Left msg  -> Left (msg $$ (ptext (sLit "When splicing TH expression:")
                                    <+> text (show e)))
        Right res -> Right res
 
 convertToPat :: SrcSpan -> TH.Pat -> Either Message (LPat RdrName)
 convertToPat loc e
   = case initCvt loc (cvtPat e) of
-        Left msg  -> Left (msg $$ (ptext (sLit "When converting TH pattern")
+        Left msg  -> Left (msg $$ (ptext (sLit "When splicing TH pattern:")
                                     <+> text (show e)))
         Right res -> Right res
 
@@ -107,15 +101,21 @@ wrapL (CvtM m) = CvtM (\loc -> case m loc of
 
 -------------------------------------------------------------------
 cvtTop :: TH.Dec -> CvtM (LHsDecl RdrName)
-cvtTop d@(TH.ValD _ _ _) = do { L loc d' <- cvtBind d; return (L loc $ Hs.ValD d') }
-cvtTop d@(TH.FunD _ _)   = do { L loc d' <- cvtBind d; return (L loc $ Hs.ValD d') }
-cvtTop (TH.SigD nm typ)  = do  { nm' <- vNameL nm
-                               ; ty' <- cvtType typ
-                               ; returnL $ Hs.SigD (TypeSig nm' ty') }
+cvtTop d@(TH.ValD _ _ _) 
+  = do { L loc d' <- cvtBind d
+       ; return (L loc $ Hs.ValD d') }
+
+cvtTop d@(TH.FunD _ _)   
+  = do { L loc d' <- cvtBind d
+       ; return (L loc $ Hs.ValD d') }
+
+cvtTop (TH.SigD nm typ)  
+  = do  { nm' <- vNameL nm
+       ; ty' <- cvtType typ
+       ; returnL $ Hs.SigD (TypeSig nm' ty') }
 
 cvtTop (TySynD tc tvs rhs)
-  = do { tc' <- tconNameL tc
-       ; tvs' <- cvtTvs tvs
+  = do { (_, tc', tvs', _) <- cvt_tycl_hdr [] tc tvs
        ; rhs' <- cvtType rhs
        ; returnL $ TyClD (TySynonym tc' tvs' Nothing rhs') }
 
@@ -125,7 +125,6 @@ cvtTop (DataD ctxt tc tvs constrs derivs)
        ; derivs' <- cvtDerivs derivs
        ; returnL $ TyClD (mkTyData DataType stuff Nothing cons' derivs') }
 
-
 cvtTop (NewtypeD ctxt tc tvs constr derivs)
   = do { stuff <- cvt_tycl_hdr ctxt tc tvs
        ; con' <- cvtConstr constr
@@ -135,32 +134,117 @@ cvtTop (NewtypeD ctxt tc tvs constr derivs)
 cvtTop (ClassD ctxt cl tvs fds decs)
   = do { (cxt', tc', tvs', _) <- cvt_tycl_hdr ctxt cl tvs
        ; fds'  <- mapM cvt_fundep fds
-       ; (binds', sigs') <- cvtBindsAndSigs decs
-       ; returnL $ TyClD $ mkClassDecl (cxt', tc', tvs') fds' sigs' binds' [] []
-                                                   -- no ATs or docs in TH ^^ ^^
+        ; let (ats, bind_sig_decs) = partition isFamilyD decs
+       ; (binds', sigs') <- cvtBindsAndSigs bind_sig_decs
+        ; ats' <- mapM cvtTop ats
+        ; let ats'' = map unTyClD ats'
+       ; returnL $ 
+            TyClD $ mkClassDecl (cxt', tc', tvs') fds' sigs' binds' ats'' []
+                                                       -- no docs in TH ^^
        }
-
-cvtTop (InstanceD tys ty decs)
-  = do         { (binds', sigs') <- cvtBindsAndSigs decs
-       ; ctxt' <- cvtContext tys
-       ; L loc pred' <- cvtPred ty
-       ; inst_ty' <- returnL $ mkImplicitHsForAllTy ctxt' (L loc (HsPredTy pred'))
-       ; returnL $ InstD (InstDecl inst_ty' binds' sigs' [])
-                                       -- no ATs in TH   ^^
+  where
+    isFamilyD (FamilyD _ _ _) = True
+    isFamilyD _               = False
+
+cvtTop (InstanceD ctxt ty decs)
+  = do         { let (ats, bind_sig_decs) = partition isFamInstD decs
+        ; (binds', sigs') <- cvtBindsAndSigs bind_sig_decs
+        ; ats' <- mapM cvtTop ats
+        ; let ats'' = map unTyClD ats'
+       ; ctxt' <- cvtContext ctxt
+       ; L loc pred' <- cvtPredTy ty
+       ; inst_ty' <- returnL $ 
+                        mkImplicitHsForAllTy ctxt' (L loc (HsPredTy pred'))
+       ; returnL $ InstD (InstDecl inst_ty' binds' sigs' ats'')
        }
+  where
+    isFamInstD (DataInstD _ _ _ _ _)    = True
+    isFamInstD (NewtypeInstD _ _ _ _ _) = True
+    isFamInstD (TySynInstD _ _ _)       = True
+    isFamInstD _                        = False
+
+cvtTop (ForeignD ford) 
+  = do { ford' <- cvtForD ford
+       ; returnL $ ForD ford' 
+       }
+
+cvtTop (PragmaD prag)
+  = do { prag' <- cvtPragmaD prag
+       ; returnL $ Hs.SigD prag'
+       }
+
+cvtTop (FamilyD flav tc tvs)
+  = do { (_, tc', tvs', _) <- cvt_tycl_hdr [] tc tvs
+       ; returnL $ TyClD (TyFamily (cvtFamFlavour flav) tc' tvs' Nothing)
+                                                                 -- FIXME: kinds
+       }
+  where
+    cvtFamFlavour TypeFam = TypeFamily
+    cvtFamFlavour DataFam = DataFamily
+
+cvtTop (DataInstD ctxt tc tys constrs derivs)
+  = do { stuff <- cvt_tyinst_hdr ctxt tc tys
+       ; cons' <- mapM cvtConstr constrs
+       ; derivs' <- cvtDerivs derivs
+       ; returnL $ TyClD (mkTyData DataType stuff Nothing cons' derivs') 
+       }
+
+cvtTop (NewtypeInstD ctxt tc tys constr derivs)
+  = do { stuff <- cvt_tyinst_hdr ctxt tc tys
+       ; con' <- cvtConstr constr
+       ; derivs' <- cvtDerivs derivs
+       ; returnL $ TyClD (mkTyData NewType stuff Nothing [con'] derivs') 
+       }
+
+cvtTop (TySynInstD tc tys rhs)
+  = do { (_, tc', tvs', tys') <- cvt_tyinst_hdr [] tc tys
+       ; rhs' <- cvtType rhs
+       ; returnL $ TyClD (TySynonym tc' tvs' tys' rhs') }
 
-cvtTop (ForeignD ford) = do { ford' <- cvtForD ford; returnL $ ForD ford' }
+-- FIXME: This projection is not nice, but to remove it, cvtTop should be 
+--        refactored.
+unTyClD :: LHsDecl a -> LTyClDecl a
+unTyClD (L l (TyClD d)) = L l d
+unTyClD _               = panic "Convert.unTyClD: internal error"
 
 cvt_tycl_hdr :: TH.Cxt -> TH.Name -> [TH.Name]
-             -> CvtM (LHsContext RdrName
-                     ,Located RdrName
-                     ,[LHsTyVarBndr RdrName]
-                     ,Maybe [LHsType RdrName])
+             -> CvtM ( LHsContext RdrName
+                     , Located RdrName
+                     , [LHsTyVarBndr RdrName]
+                     , Maybe [LHsType RdrName])
 cvt_tycl_hdr cxt tc tvs
-  = do { cxt' <- cvtContext cxt
-       ; tc'  <- tconNameL tc
-       ; tvs' <- cvtTvs tvs
-       ; return (cxt', tc', tvs', Nothing) }
+  = do { cxt' <- cvtContext cxt
+       ; tc'  <- tconNameL tc
+       ; tvs' <- cvtTvs tvs
+       ; return (cxt', tc', tvs', Nothing) 
+       }
+
+cvt_tyinst_hdr :: TH.Cxt -> TH.Name -> [TH.Type]
+               -> CvtM ( LHsContext RdrName
+                       , Located RdrName
+                       , [LHsTyVarBndr RdrName]
+                       , Maybe [LHsType RdrName])
+cvt_tyinst_hdr cxt tc tys
+  = do { cxt' <- cvtContext cxt
+       ; tc'  <- tconNameL tc
+       ; tvs  <- concatMapM collect tys
+       ; tvs' <- cvtTvs tvs
+       ; tys' <- mapM cvtType tys
+       ; return (cxt', tc', tvs', Just tys') 
+       }
+  where
+    collect (ForallT _ _ _) 
+      = failWith $ text "Forall type not allowed as type parameter"
+    collect (VarT tv)    = return [tv]
+    collect (ConT _)     = return []
+    collect (TupleT _)   = return []
+    collect ArrowT       = return []
+    collect ListT        = return []
+    collect (AppT t1 t2)
+      = do { tvs1 <- collect t1
+           ; tvs2 <- collect t2
+           ; return $ tvs1 ++ tvs2
+           }
 
 ---------------------------------------------------
 --     Data types
@@ -294,6 +378,35 @@ lex_ccall_impent xs = case span is_valid xs of
     where is_valid :: Char -> Bool
           is_valid c = isAscii c && (isAlphaNum c || c `elem` "._")
 
+------------------------------------------
+--              Pragmas
+------------------------------------------
+
+cvtPragmaD :: Pragma -> CvtM (Sig RdrName)
+cvtPragmaD (InlineP nm ispec)
+  = do { nm'    <- vNameL nm
+       ; return $ InlineSig nm' (cvtInlineSpec (Just ispec))
+       }
+cvtPragmaD (SpecialiseP nm ty opt_ispec)
+  = do { nm'    <- vNameL nm
+       ; ty'    <- cvtType ty
+       ; return $ SpecSig nm' ty' (cvtInlineSpec opt_ispec)
+       }
+
+cvtInlineSpec :: Maybe TH.InlineSpec -> Hs.InlineSpec
+cvtInlineSpec Nothing 
+  = defaultInlineSpec
+cvtInlineSpec (Just (TH.InlineSpec inline conlike opt_activation)) 
+  = mkInlineSpec opt_activation' matchinfo inline
+  where
+    matchinfo       = cvtRuleMatchInfo conlike
+    opt_activation' = fmap cvtActivation opt_activation
+
+    cvtRuleMatchInfo False = FunLike
+    cvtRuleMatchInfo True  = ConLike
+
+    cvtActivation (False, phase) = ActiveBefore phase
+    cvtActivation (True , phase) = ActiveAfter  phase
 
 ---------------------------------------------------
 --             Declarations
@@ -301,22 +414,32 @@ lex_ccall_impent xs = case span is_valid xs of
 
 cvtDecs :: [TH.Dec] -> CvtM (HsLocalBinds RdrName)
 cvtDecs [] = return EmptyLocalBinds
-cvtDecs ds = do { (binds,sigs) <- cvtBindsAndSigs ds
+cvtDecs ds = do { (binds, sigs) <- cvtBindsAndSigs ds
                ; return (HsValBinds (ValBindsIn binds sigs)) }
 
 cvtBindsAndSigs :: [TH.Dec] -> CvtM (Bag (LHsBind RdrName), [LSig RdrName])
 cvtBindsAndSigs ds 
-  = do { binds' <- mapM cvtBind binds; sigs' <- mapM cvtSig sigs
+  = do { binds' <- mapM cvtBind binds
+       ; sigs' <- mapM cvtSig sigs
        ; return (listToBag binds', sigs') }
   where 
     (sigs, binds) = partition is_sig ds
 
-    is_sig (TH.SigD _ _) = True
-    is_sig _             = False
+    is_sig (TH.SigD _ _)  = True
+    is_sig (TH.PragmaD _) = True
+    is_sig _              = False
 
 cvtSig :: TH.Dec -> CvtM (LSig RdrName)
 cvtSig (TH.SigD nm ty)
-  = do { nm' <- vNameL nm; ty' <- cvtType ty; returnL (Hs.TypeSig nm' ty') }
+  = do { nm' <- vNameL nm
+       ; ty' <- cvtType ty
+       ; returnL (Hs.TypeSig nm' ty') 
+       }
+cvtSig (TH.PragmaD prag)
+  = do { prag' <- cvtPragmaD prag
+       ; returnL prag'
+       }
+cvtSig _ = panic "Convert.cvtSig: Signature expected"
 
 cvtBind :: TH.Dec -> CvtM (LHsBind RdrName)
 -- Used only for declarations in a 'let/where' clause,
@@ -327,6 +450,11 @@ cvtBind (TH.ValD (TH.VarP s) body ds)
        ; returnL $ mkFunBind s' [cl'] }
 
 cvtBind (TH.FunD nm cls)
+  | null cls
+  = failWith (ptext (sLit "Function binding for")
+                   <+> quotes (text (TH.pprint nm))
+                   <+> ptext (sLit "has no equations"))
+  | otherwise
   = do { nm' <- vNameL nm
        ; cls' <- mapM cvtClause cls
        ; returnL $ mkFunBind nm' cls' }
@@ -371,7 +499,9 @@ cvtl e = wrapL (cvt e)
     cvt (CondE x y z)  = do { x' <- cvtl x; y' <- cvtl y; z' <- cvtl z
                            ; return $ HsIf x' y' z' }
     cvt (LetE ds e)    = do { ds' <- cvtDecs ds; e' <- cvtl e; return $ HsLet ds' e' }
-    cvt (CaseE e ms)   = do { e' <- cvtl e; ms' <- mapM cvtMatch ms
+    cvt (CaseE e ms)   
+       | null ms       = failWith (ptext (sLit "Case expression with no alternatives"))
+       | otherwise     = do { e' <- cvtl e; ms' <- mapM cvtMatch ms
                            ; return $ HsCase e' (mkMatchGroup ms') }
     cvt (DoE ss)       = cvtHsDo DoExpr ss
     cvt (CompE ss)     = cvtHsDo ListComp ss
@@ -381,9 +511,11 @@ cvtl e = wrapL (cvt e)
                                          ; e' <- returnL $ OpApp x' s' undefined y'
                                          ; return $ HsPar e' }
     cvt (InfixE Nothing  s (Just y)) = do { s' <- cvtl s; y' <- cvtl y
-                                         ; return $ SectionR s' y' }
+                                         ; sec <- returnL $ SectionR s' y'
+                                         ; return $ HsPar sec }
     cvt (InfixE (Just x) s Nothing ) = do { x' <- cvtl x; s' <- cvtl s
-                                         ; return $ SectionL x' s' }
+                                         ; sec <- returnL $ SectionL x' s'
+                                         ; return $ HsPar sec }
     cvt (InfixE Nothing  s Nothing ) = cvt s   -- Can I indicate this is an infix thing?
 
     cvt (SigE e t)      = do { e' <- cvtl e; t' <- cvtType t
@@ -412,9 +544,12 @@ cvtDD (FromThenToR x y z) = do { x' <- cvtl x; y' <- cvtl y; z' <- cvtl z; retur
 
 cvtHsDo :: HsStmtContext Name.Name -> [TH.Stmt] -> CvtM (HsExpr RdrName)
 cvtHsDo do_or_lc stmts
+  | null stmts = failWith (ptext (sLit "Empty stmt list in do-block"))
+  | otherwise
   = do { stmts' <- cvtStmts stmts
        ; let body = case last stmts' of
                        L _ (ExprStmt body _ _) -> body
+                        _                       -> panic "Malformed body"
        ; return $ HsDo do_or_lc (init stmts') body void }
 
 cvtStmts :: [TH.Stmt] -> CvtM [Hs.LStmt RdrName]
@@ -447,10 +582,17 @@ cvtpair (PatG gs,rhs)    = do { gs' <- cvtStmts gs; rhs' <- cvtl rhs
                              ; returnL $ GRHS gs' rhs' }
 
 cvtOverLit :: Lit -> CvtM (HsOverLit RdrName)
-cvtOverLit (IntegerL i)  = do { force i; return $ mkHsIntegral i placeHolderType}
-cvtOverLit (RationalL r) = do { force r; return $ mkHsFractional r placeHolderType}
-cvtOverLit (StringL s)   = do { let { s' = mkFastString s }; force s'; return $ mkHsIsString s' placeHolderType }
--- An Integer is like an an (overloaded) '3' in a Haskell source program
+cvtOverLit (IntegerL i)  
+  = do { force i; return $ mkHsIntegral i placeHolderType}
+cvtOverLit (RationalL r) 
+  = do { force r; return $ mkHsFractional r placeHolderType}
+cvtOverLit (StringL s)   
+  = do { let { s' = mkFastString s }
+       ; force s'
+       ; return $ mkHsIsString s' placeHolderType 
+       }
+cvtOverLit _ = panic "Convert.cvtOverLit: Unexpected overloaded literal"
+-- An Integer is like an (overloaded) '3' in a Haskell source program
 -- Similarly 3.5 for fractionals
 
 cvtLit :: Lit -> CvtM HsLit
@@ -459,7 +601,12 @@ cvtLit (WordPrimL w)   = do { force w; return $ HsWordPrim w }
 cvtLit (FloatPrimL f)  = do { force f; return $ HsFloatPrim f }
 cvtLit (DoublePrimL f) = do { force f; return $ HsDoublePrim f }
 cvtLit (CharL c)       = do { force c; return $ HsChar c }
-cvtLit (StringL s)     = do { let { s' = mkFastString s }; force s'; return $ HsString s' }
+cvtLit (StringL s)     
+  = do { let { s' = mkFastString s }
+       ; force s'
+       ; return $ HsString s' 
+       }
+cvtLit _ = panic "Convert.cvtLit: Unexpected literal"
 
 cvtPats :: [TH.Pat] -> CvtM [Hs.LPat RdrName]
 cvtPats pats = mapM cvtPat pats
@@ -502,16 +649,29 @@ cvtTvs tvs = mapM cvt_tv tvs
 cvt_tv :: TH.Name -> CvtM (LHsTyVarBndr RdrName)
 cvt_tv tv = do { tv' <- tName tv; returnL $ UserTyVar tv' }
 
-cvtContext :: Cxt -> CvtM (LHsContext RdrName)
+cvtContext :: TH.Cxt -> CvtM (LHsContext RdrName)
 cvtContext tys = do { preds' <- mapM cvtPred tys; returnL preds' }
 
-cvtPred :: TH.Type -> CvtM (LHsPred RdrName)
-cvtPred ty 
+cvtPred :: TH.Pred -> CvtM (LHsPred RdrName)
+cvtPred (TH.ClassP cla tys)
+  = do { cla' <- if isVarName cla then tName cla else tconName cla
+       ; tys' <- mapM cvtType tys
+       ; returnL $ HsClassP cla' tys'
+       }
+cvtPred (TH.EqualP ty1 ty2)
+  = do { ty1' <- cvtType ty1
+       ; ty2' <- cvtType ty2
+       ; returnL $ HsEqualP ty1' ty2'
+       }
+
+cvtPredTy :: TH.Type -> CvtM (LHsPred RdrName)
+cvtPredTy ty 
   = do { (head, tys') <- split_ty_app ty
        ; case head of
            ConT tc -> do { tc' <- tconName tc; returnL $ HsClassP tc' tys' }
            VarT tv -> do { tv' <- tName tv;    returnL $ HsClassP tv' tys' }
-           _       -> failWith (ptext (sLit "Malformed predicate") <+> text (TH.pprint ty)) }
+           _       -> failWith (ptext (sLit "Malformed predicate") <+> 
+                       text (TH.pprint ty)) }
 
 cvtType :: TH.Type -> CvtM (LHsType RdrName)
 cvtType ty = do { (head_ty, tys') <- split_ty_app ty
@@ -523,7 +683,9 @@ cvtType ty = do { (head_ty, tys') <- split_ty_app ty
                             | n == 1    -> failWith (ptext (sLit "Illegal 1-tuple type constructor"))
                             | otherwise -> mk_apps (HsTyVar (getRdrName (tupleTyCon Boxed n))) tys'
                    ArrowT | [x',y'] <- tys' -> returnL (HsFunTy x' y')
+                          | otherwise       -> mk_apps (HsTyVar (getRdrName funTyCon)) tys'
                    ListT  | [x']    <- tys' -> returnL (HsListTy x')
+                          | otherwise       -> mk_apps (HsTyVar (getRdrName listTyCon)) tys'
                    VarT nm -> do { nm' <- tName nm;    mk_apps (HsTyVar nm') tys' }
                    ConT nm -> do { nm' <- tconName nm; mk_apps (HsTyVar nm') tys' }
 
@@ -594,6 +756,14 @@ okOcc ns str@(c:_)
   | OccName.isVarNameSpace ns = startsVarId c || startsVarSym c
   | otherwise                = startsConId c || startsConSym c || str == "[]"
 
+-- Determine the name space of a name in a type
+--
+isVarName :: TH.Name -> Bool
+isVarName (TH.Name occ _)
+  = case TH.occString occ of
+      ""    -> False
+      (c:_) -> startsVarId c || startsVarSym c
+
 badOcc :: OccName.NameSpace -> String -> SDoc
 badOcc ctxt_ns occ 
   = ptext (sLit "Illegal") <+> pprNameSpace ctxt_ns
@@ -610,7 +780,7 @@ thRdrName :: OccName.NameSpace -> String -> TH.NameFlavour -> RdrName
 --      which will give confusing error messages later
 -- 
 -- The strict applications ensure that any buried exceptions get forced
-thRdrName _       occ (TH.NameG th_ns pkg mod) = (mkOrig $! (mkModule (mk_pkg pkg) (mk_mod mod))) $! (mk_occ (mk_ghc_ns th_ns) occ)
+thRdrName _       occ (TH.NameG th_ns pkg mod) = thOrigRdrName occ th_ns pkg mod
 thRdrName ctxt_ns occ (TH.NameL uniq)      = nameRdrName $! (((Name.mkInternalName $! (mk_uniq uniq)) $! (mk_occ ctxt_ns occ)) noSrcSpan)
 thRdrName ctxt_ns occ (TH.NameQ mod)       = (mkRdrQual  $! (mk_mod mod)) $! (mk_occ ctxt_ns occ)
 thRdrName ctxt_ns occ (TH.NameU uniq)      = mkRdrUnqual $! (mk_uniq_occ ctxt_ns occ uniq)
@@ -618,6 +788,21 @@ thRdrName ctxt_ns occ TH.NameS
   | Just name <- isBuiltInOcc ctxt_ns occ  = nameRdrName $! name
   | otherwise                             = mkRdrUnqual $! (mk_occ ctxt_ns occ)
 
+thOrigRdrName :: String -> TH.NameSpace -> PkgName -> ModName -> RdrName
+thOrigRdrName occ th_ns pkg mod = (mkOrig $! (mkModule (mk_pkg pkg) (mk_mod mod))) $! (mk_occ (mk_ghc_ns th_ns) occ)
+
+thRdrNameGuesses :: TH.Name -> [RdrName]
+thRdrNameGuesses (TH.Name occ flavour)
+  -- This special case for NameG ensures that we don't generate duplicates in the output list
+  | TH.NameG th_ns pkg mod <- flavour = [thOrigRdrName occ_str th_ns pkg mod]
+  | otherwise                         = [ thRdrName gns occ_str flavour
+                                       | gns <- guessed_nss]
+  where
+    -- guessed_ns are the name spaces guessed from looking at the TH name
+    guessed_nss | isLexCon (mkFastString occ_str) = [OccName.tcName,  OccName.dataName]
+               | otherwise                       = [OccName.varName, OccName.tvName]
+    occ_str = TH.occString occ
+
 isBuiltInOcc :: OccName.NameSpace -> String -> Maybe Name.Name
 -- Built in syntax isn't "in scope" so an Unqual RdrName won't do
 -- We must generate an Exact name, just as the parser does