{-# LANGUAGE CPP, GeneralizedNewtypeDeriving #-}
module Language.Haskell.TH.Desugar.Reify (
reifyWithLocals_maybe, reifyWithLocals, reifyWithWarning, reifyInDecs,
qReifyFixity, reifyFixity, reifyFixityWithLocals, reifyFixityInDecs,
getDataD, dataConNameToCon, dataConNameToDataName,
lookupValueNameWithLocals, lookupTypeNameWithLocals,
mkDataNameWithLocals, mkTypeNameWithLocals,
reifyNameSpace,
DsMonad(..), DsM, withLocalDeclarations
) where
import qualified Control.Monad.Fail as Fail
import Control.Monad.Reader
import Control.Monad.State
import Control.Monad.Writer
import Control.Monad.RWS
import Control.Monad.Trans.Instances ()
import qualified Data.Foldable as F
import Data.Function (on)
import Data.List
import Data.Maybe
#if __GLASGOW_HASKELL__ < 709
import Control.Applicative
#endif
import Language.Haskell.TH.Datatype
import Language.Haskell.TH.Instances ()
import Language.Haskell.TH.Syntax hiding ( lift )
import Language.Haskell.TH.Desugar.Util
reifyWithLocals_maybe :: DsMonad q => Name -> q (Maybe Info)
reifyWithLocals_maybe name = qRecover
(return . reifyInDecs name =<< localDeclarations)
(Just `fmap` qReify name)
reifyWithLocals :: DsMonad q => Name -> q Info
reifyWithLocals name = do
m_info <- reifyWithLocals_maybe name
case m_info of
Nothing -> reifyFail name
Just i -> return i
reifyWithWarning :: (Quasi q, Fail.MonadFail q) => Name -> q Info
reifyWithWarning name = qRecover (reifyFail name) (qReify name)
reifyFail :: Fail.MonadFail m => Name -> m a
reifyFail name =
Fail.fail $ "Looking up " ++ (show name) ++ " in the list of available " ++
"declarations failed.\nThis lookup fails if the declaration " ++
"referenced was made in the same Template\nHaskell splice as the use " ++
"of the declaration. If this is the case, put\nthe reference to " ++
"the declaration in a new splice."
getDataD :: DsMonad q
=> String
-> Name
-> q ([TyVarBndr], [Con])
getDataD err name = do
info <- reifyWithLocals name
dec <- case info of
TyConI dec -> return dec
_ -> badDeclaration
case dec of
#if __GLASGOW_HASKELL__ > 710
DataD _cxt _name tvbs mk cons _derivings -> go tvbs mk cons
NewtypeD _cxt _name tvbs mk con _derivings -> go tvbs mk [con]
#else
DataD _cxt _name tvbs cons _derivings -> go tvbs Nothing cons
NewtypeD _cxt _name tvbs con _derivings -> go tvbs Nothing [con]
#endif
_ -> badDeclaration
where
go tvbs mk cons = do
k <- maybe (pure (ConT typeKindName)) (runQ . resolveTypeSynonyms) mk
extra_tvbs <- mkExtraKindBindersGeneric unravelType KindedTV k
let all_tvbs = tvbs ++ extra_tvbs
return (all_tvbs, cons)
badDeclaration =
fail $ "The name (" ++ (show name) ++ ") refers to something " ++
"other than a datatype. " ++ err
dataConNameToDataName :: DsMonad q => Name -> q Name
dataConNameToDataName con_name = do
info <- reifyWithLocals con_name
case info of
#if __GLASGOW_HASKELL__ > 710
DataConI _name _type parent_name -> return parent_name
#else
DataConI _name _type parent_name _fixity -> return parent_name
#endif
_ -> fail $ "The name " ++ show con_name ++ " does not appear to be " ++
"a data constructor."
dataConNameToCon :: DsMonad q => Name -> q Con
dataConNameToCon con_name = do
type_name <- dataConNameToDataName con_name
(_, cons) <- getDataD "This seems to be an error in GHC." type_name
let m_con = find (any (con_name ==) . get_con_name) cons
case m_con of
Just con -> return con
Nothing -> impossible "Datatype does not contain one of its own constructors."
where
get_con_name (NormalC name _) = [name]
get_con_name (RecC name _) = [name]
get_con_name (InfixC _ name _) = [name]
get_con_name (ForallC _ _ con) = get_con_name con
#if __GLASGOW_HASKELL__ > 710
get_con_name (GadtC names _ _) = names
get_con_name (RecGadtC names _ _) = names
#endif
class (Quasi m, Fail.MonadFail m) => DsMonad m where
localDeclarations :: m [Dec]
instance DsMonad Q where
localDeclarations = return []
instance DsMonad IO where
localDeclarations = return []
newtype DsM q a = DsM (ReaderT [Dec] q a)
deriving ( Functor, Applicative, Monad, MonadTrans, Quasi, Fail.MonadFail
#if __GLASGOW_HASKELL__ >= 803
, MonadIO
#endif
)
instance (Quasi q, Fail.MonadFail q) => DsMonad (DsM q) where
localDeclarations = DsM ask
instance DsMonad m => DsMonad (ReaderT r m) where
localDeclarations = lift localDeclarations
instance DsMonad m => DsMonad (StateT s m) where
localDeclarations = lift localDeclarations
instance (DsMonad m, Monoid w) => DsMonad (WriterT w m) where
localDeclarations = lift localDeclarations
instance (DsMonad m, Monoid w) => DsMonad (RWST r w s m) where
localDeclarations = lift localDeclarations
withLocalDeclarations :: DsMonad q => [Dec] -> DsM q a -> q a
withLocalDeclarations new_decs (DsM x) = do
orig_decs <- localDeclarations
runReaderT x (orig_decs ++ new_decs)
reifyInDecs :: Name -> [Dec] -> Maybe Info
reifyInDecs n decs = snd `fmap` firstMatch (reifyInDec n decs) decs
reifyFixityInDecs :: Name -> [Dec] -> Maybe Fixity
reifyFixityInDecs n = firstMatch match_fixity
where
match_fixity (InfixD fixity n') | n `nameMatches` n' = Just fixity
match_fixity _ = Nothing
type Named a = (Name, a)
reifyInDec :: Name -> [Dec] -> Dec -> Maybe (Named Info)
reifyInDec n decs (FunD n' _) | n `nameMatches` n' = Just (n', mkVarI n decs)
reifyInDec n decs (ValD pat _ _)
| Just n' <- find (nameMatches n) (F.toList (extractBoundNamesPat pat)) = Just (n', mkVarI n decs)
#if __GLASGOW_HASKELL__ > 710
reifyInDec n _ dec@(DataD _ n' _ _ _ _) | n `nameMatches` n' = Just (n', TyConI dec)
reifyInDec n _ dec@(NewtypeD _ n' _ _ _ _) | n `nameMatches` n' = Just (n', TyConI dec)
#else
reifyInDec n _ dec@(DataD _ n' _ _ _) | n `nameMatches` n' = Just (n', TyConI dec)
reifyInDec n _ dec@(NewtypeD _ n' _ _ _) | n `nameMatches` n' = Just (n', TyConI dec)
#endif
reifyInDec n _ dec@(TySynD n' _ _) | n `nameMatches` n' = Just (n', TyConI dec)
reifyInDec n decs dec@(ClassD _ n' _ _ _) | n `nameMatches` n'
= Just (n', ClassI (quantifyClassDecMethods dec) (findInstances n decs))
reifyInDec n decs (ForeignD (ImportF _ _ _ n' ty)) | n `nameMatches` n'
= Just (n', mkVarITy n decs ty)
reifyInDec n decs (ForeignD (ExportF _ _ n' ty)) | n `nameMatches` n'
= Just (n', mkVarITy n decs ty)
#if __GLASGOW_HASKELL__ > 710
reifyInDec n decs dec@(OpenTypeFamilyD (TypeFamilyHead n' _ _ _)) | n `nameMatches` n'
= Just (n', FamilyI dec (findInstances n decs))
reifyInDec n decs dec@(DataFamilyD n' _ _) | n `nameMatches` n'
= Just (n', FamilyI dec (findInstances n decs))
reifyInDec n _ dec@(ClosedTypeFamilyD (TypeFamilyHead n' _ _ _) _) | n `nameMatches` n'
= Just (n', FamilyI dec [])
#else
reifyInDec n decs dec@(FamilyD _ n' _ _) | n `nameMatches` n'
= Just (n', FamilyI dec (findInstances n decs))
reifyInDec n _ dec@(ClosedTypeFamilyD n' _ _ _) | n `nameMatches` n'
= Just (n', FamilyI dec [])
#endif
#if __GLASGOW_HASKELL__ >= 801
reifyInDec n decs (PatSynD n' _ _ _) | n `nameMatches` n'
= Just (n', mkPatSynI n decs)
#endif
#if __GLASGOW_HASKELL__ > 710
reifyInDec n decs (DataD _ ty_name tvbs _mk cons _)
| Just info <- maybeReifyCon n decs ty_name (map tvbToTANormalWithSig tvbs) cons
= Just info
reifyInDec n decs (NewtypeD _ ty_name tvbs _mk con _)
| Just info <- maybeReifyCon n decs ty_name (map tvbToTANormalWithSig tvbs) [con]
= Just info
#else
reifyInDec n decs (DataD _ ty_name tvbs cons _)
| Just info <- maybeReifyCon n decs ty_name (map tvbToTANormalWithSig tvbs) cons
= Just info
reifyInDec n decs (NewtypeD _ ty_name tvbs con _)
| Just info <- maybeReifyCon n decs ty_name (map tvbToTANormalWithSig tvbs) [con]
= Just info
#endif
#if __GLASGOW_HASKELL__ > 710
reifyInDec n _decs (ClassD _ ty_name tvbs _ sub_decs)
| Just (n', ty) <- findType n sub_decs
= Just (n', ClassOpI n (quantifyClassMethodType ty_name tvbs True ty) ty_name)
#else
reifyInDec n decs (ClassD _ ty_name tvbs _ sub_decs)
| Just (n', ty) <- findType n sub_decs
= Just (n', ClassOpI n (quantifyClassMethodType ty_name tvbs True ty)
ty_name (fromMaybe defaultFixity $
reifyFixityInDecs n $ sub_decs ++ decs))
#endif
reifyInDec n decs (ClassD _ _ _ _ sub_decs)
| Just info <- firstMatch (reifyInDec n (sub_decs ++ decs)) sub_decs
= Just info
#if __GLASGOW_HASKELL__ >= 711
reifyInDec n decs (InstanceD _ _ _ sub_decs)
#else
reifyInDec n decs (InstanceD _ _ sub_decs)
#endif
| Just info <- firstMatch reify_in_instance sub_decs
= Just info
where
reify_in_instance dec@(DataInstD {}) = reifyInDec n (sub_decs ++ decs) dec
reify_in_instance dec@(NewtypeInstD {}) = reifyInDec n (sub_decs ++ decs) dec
reify_in_instance _ = Nothing
#if __GLASGOW_HASKELL__ >= 807
reifyInDec n decs (DataInstD _ _ lhs _ cons _)
| (ConT ty_name, tys) <- unfoldType lhs
, Just info <- maybeReifyCon n decs ty_name tys cons
= Just info
reifyInDec n decs (NewtypeInstD _ _ lhs _ con _)
| (ConT ty_name, tys) <- unfoldType lhs
, Just info <- maybeReifyCon n decs ty_name tys [con]
= Just info
#elif __GLASGOW_HASKELL__ > 710
reifyInDec n decs (DataInstD _ ty_name tys _ cons _)
| Just info <- maybeReifyCon n decs ty_name (map TANormal tys) cons
= Just info
reifyInDec n decs (NewtypeInstD _ ty_name tys _ con _)
| Just info <- maybeReifyCon n decs ty_name (map TANormal tys) [con]
= Just info
#else
reifyInDec n decs (DataInstD _ ty_name tys cons _)
| Just info <- maybeReifyCon n decs ty_name (map TANormal tys) cons
= Just info
reifyInDec n decs (NewtypeInstD _ ty_name tys con _)
| Just info <- maybeReifyCon n decs ty_name (map TANormal tys) [con]
= Just info
#endif
reifyInDec _ _ _ = Nothing
maybeReifyCon :: Name -> [Dec] -> Name -> [TypeArg] -> [Con] -> Maybe (Named Info)
#if __GLASGOW_HASKELL__ > 710
maybeReifyCon n _decs ty_name ty_args cons
| Just (n', con) <- findCon n cons
= Just (n', DataConI n (maybeForallT tvbs [] $ con_to_type con) ty_name)
#else
maybeReifyCon n decs ty_name ty_args cons
| Just (n', con) <- findCon n cons
= Just (n', DataConI n (maybeForallT tvbs [] $ con_to_type con)
ty_name fixity)
#endif
| Just (n', ty) <- findRecSelector n cons
#if __GLASGOW_HASKELL__ > 710
= Just (n', VarI n (maybeForallT tvbs [] $ mkArrows [result_ty] ty) Nothing)
#else
= Just (n', VarI n (maybeForallT tvbs [] $ mkArrows [result_ty] ty) Nothing fixity)
#endif
where
result_ty = applyType (ConT ty_name) (map unSigTypeArg ty_args)
con_to_type (NormalC _ stys) = mkArrows (map snd stys) result_ty
con_to_type (RecC _ vstys) = mkArrows (map thdOf3 vstys) result_ty
con_to_type (InfixC t1 _ t2) = mkArrows (map snd [t1, t2]) result_ty
con_to_type (ForallC bndrs cxt c) = ForallT bndrs cxt (con_to_type c)
#if __GLASGOW_HASKELL__ > 710
con_to_type (GadtC _ stys rty) = mkArrows (map snd stys) rty
con_to_type (RecGadtC _ vstys rty) = mkArrows (map thdOf3 vstys) rty
#endif
#if __GLASGOW_HASKELL__ < 711
fixity = fromMaybe defaultFixity $ reifyFixityInDecs n decs
#endif
tvbs = freeVariablesWellScoped $ map probablyWrongUnTypeArg ty_args
maybeReifyCon _ _ _ _ _ = Nothing
mkVarI :: Name -> [Dec] -> Info
mkVarI n decs = mkVarITy n decs (maybe (no_type n) snd $ findType n decs)
mkVarITy :: Name -> [Dec] -> Type -> Info
#if __GLASGOW_HASKELL__ > 710
mkVarITy n _decs ty = VarI n ty Nothing
#else
mkVarITy n decs ty = VarI n ty Nothing (fromMaybe defaultFixity $
reifyFixityInDecs n decs)
#endif
findType :: Name -> [Dec] -> Maybe (Named Type)
findType n = firstMatch match_type
where
match_type (SigD n' ty) | n `nameMatches` n' = Just (n', ty)
match_type _ = Nothing
#if __GLASGOW_HASKELL__ >= 801
mkPatSynI :: Name -> [Dec] -> Info
mkPatSynI n decs = PatSynI n (fromMaybe (no_type n) $ findPatSynType n decs)
findPatSynType :: Name -> [Dec] -> Maybe PatSynType
findPatSynType n = firstMatch match_pat_syn_type
where
match_pat_syn_type (PatSynSigD n' psty) | n `nameMatches` n' = Just psty
match_pat_syn_type _ = Nothing
#endif
no_type :: Name -> Type
no_type n = error $ "No type information found in local declaration for "
++ show n
findInstances :: Name -> [Dec] -> [Dec]
findInstances n = map stripInstanceDec . concatMap match_instance
where
#if __GLASGOW_HASKELL__ >= 711
match_instance d@(InstanceD _ _ ty _)
#else
match_instance d@(InstanceD _ ty _)
#endif
| ConT n' <- ty_head ty
, n `nameMatches` n' = [d]
#if __GLASGOW_HASKELL__ >= 807
match_instance (DataInstD ctxt _ lhs mk cons derivs)
| ConT n' <- ty_head lhs
, n `nameMatches` n' = [d]
where
mtvbs = rejig_data_inst_tvbs ctxt lhs mk
d = DataInstD ctxt mtvbs lhs mk cons derivs
match_instance (NewtypeInstD ctxt _ lhs mk con derivs)
| ConT n' <- ty_head lhs
, n `nameMatches` n' = [d]
where
mtvbs = rejig_data_inst_tvbs ctxt lhs mk
d = NewtypeInstD ctxt mtvbs lhs mk con derivs
#elif __GLASGOW_HASKELL__ > 710
match_instance d@(DataInstD _ n' _ _ _ _) | n `nameMatches` n' = [d]
match_instance d@(NewtypeInstD _ n' _ _ _ _) | n `nameMatches` n' = [d]
#else
match_instance d@(DataInstD _ n' _ _ _) | n `nameMatches` n' = [d]
match_instance d@(NewtypeInstD _ n' _ _ _) | n `nameMatches` n' = [d]
#endif
#if __GLASGOW_HASKELL__ >= 807
match_instance (TySynInstD (TySynEqn _ lhs rhs))
| ConT n' <- ty_head lhs
, n `nameMatches` n' = [d]
where
mtvbs = rejig_tvbs [lhs, rhs]
d = TySynInstD (TySynEqn mtvbs lhs rhs)
#else
match_instance d@(TySynInstD n' _) | n `nameMatches` n' = [d]
#endif
#if __GLASGOW_HASKELL__ >= 711
match_instance (InstanceD _ _ _ decs)
#else
match_instance (InstanceD _ _ decs)
#endif
= concatMap match_instance decs
match_instance _ = []
#if __GLASGOW_HASKELL__ >= 807
rejig_tvbs :: [Type] -> Maybe [TyVarBndr]
rejig_tvbs ts =
let tvbs = freeVariablesWellScoped ts
in if null tvbs
then Nothing
else Just tvbs
rejig_data_inst_tvbs :: Cxt -> Type -> Maybe Kind -> Maybe [TyVarBndr]
rejig_data_inst_tvbs cxt lhs mk =
rejig_tvbs $ cxt ++ [lhs] ++ maybeToList mk
#endif
ty_head = fst . unfoldType
quantifyClassDecMethods :: Dec -> Dec
quantifyClassDecMethods (ClassD cxt cls_name cls_tvbs fds sub_decs)
= ClassD cxt cls_name cls_tvbs fds sub_decs'
where
sub_decs' = mapMaybe go sub_decs
go (SigD n ty) =
Just $ SigD n
$ quantifyClassMethodType cls_name cls_tvbs prepend_cls ty
#if __GLASGOW_HASKELL__ > 710
go d@(OpenTypeFamilyD {}) = Just d
go d@(DataFamilyD {}) = Just d
#endif
go _ = Nothing
prepend_cls :: Bool
#if __GLASGOW_HASKELL__ >= 807
prepend_cls = False
#else
prepend_cls = True
#endif
quantifyClassDecMethods dec = dec
quantifyClassMethodType
:: Name
-> [TyVarBndr]
-> Bool
-> Type
-> Type
quantifyClassMethodType cls_name cls_tvbs prepend meth_ty =
add_cls_cxt quantified_meth_ty
where
add_cls_cxt :: Type -> Type
add_cls_cxt
| prepend = ForallT all_cls_tvbs cls_cxt
| otherwise = id
cls_cxt :: Cxt
#if __GLASGOW_HASKELL__ < 709
cls_cxt = [ClassP cls_name (map tvbToType cls_tvbs)]
#else
cls_cxt = [foldl AppT (ConT cls_name) (map tvbToType cls_tvbs)]
#endif
quantified_meth_ty :: Type
quantified_meth_ty
| null meth_tvbs
= meth_ty
| ForallT meth_tvbs' meth_ctxt meth_tau <- meth_ty
= ForallT (meth_tvbs ++ meth_tvbs') meth_ctxt meth_tau
| otherwise
= ForallT meth_tvbs [] meth_ty
meth_tvbs :: [TyVarBndr]
meth_tvbs = deleteFirstsBy ((==) `on` tvName)
(freeVariablesWellScoped [meth_ty]) all_cls_tvbs
all_cls_tvbs :: [TyVarBndr]
all_cls_tvbs = freeVariablesWellScoped $ map tvbToTypeWithSig cls_tvbs
stripInstanceDec :: Dec -> Dec
#if __GLASGOW_HASKELL__ >= 711
stripInstanceDec (InstanceD over cxt ty _) = InstanceD over cxt ty []
#else
stripInstanceDec (InstanceD cxt ty _) = InstanceD cxt ty []
#endif
stripInstanceDec dec = dec
mkArrows :: [Type] -> Type -> Type
mkArrows [] res_ty = res_ty
mkArrows (t:ts) res_ty = AppT (AppT ArrowT t) $ mkArrows ts res_ty
maybeForallT :: [TyVarBndr] -> Cxt -> Type -> Type
maybeForallT tvbs cxt ty
| null tvbs && null cxt = ty
| ForallT tvbs2 cxt2 ty2 <- ty = ForallT (tvbs ++ tvbs2) (cxt ++ cxt2) ty2
| otherwise = ForallT tvbs cxt ty
findCon :: Name -> [Con] -> Maybe (Named Con)
findCon n = firstMatch match_con
where
match_con :: Con -> Maybe (Named Con)
match_con con =
case con of
NormalC n' _ | n `nameMatches` n' -> Just (n', con)
RecC n' _ | n `nameMatches` n' -> Just (n', con)
InfixC _ n' _ | n `nameMatches` n' -> Just (n', con)
ForallC _ _ c -> case match_con c of
Just (n', _) -> Just (n', con)
Nothing -> Nothing
#if __GLASGOW_HASKELL__ > 710
GadtC nms _ _ -> gadt_case con nms
RecGadtC nms _ _ -> gadt_case con nms
#endif
_ -> Nothing
#if __GLASGOW_HASKELL__ > 710
gadt_case :: Con -> [Name] -> Maybe (Named Con)
gadt_case con nms = case find (n `nameMatches`) nms of
Just n' -> Just (n', con)
Nothing -> Nothing
#endif
findRecSelector :: Name -> [Con] -> Maybe (Named Type)
findRecSelector n = firstMatch match_con
where
match_con (RecC _ vstys) = firstMatch match_rec_sel vstys
#if __GLASGOW_HASKELL__ >= 800
match_con (RecGadtC _ vstys _) = firstMatch match_rec_sel vstys
#endif
match_con (ForallC _ _ c) = match_con c
match_con _ = Nothing
match_rec_sel (n', _, ty) | n `nameMatches` n' = Just (n', ty)
match_rec_sel _ = Nothing
#if __GLASGOW_HASKELL__ < 711
qReifyFixity :: Quasi m => Name -> m (Maybe Fixity)
qReifyFixity name = do
info <- qReify name
return $ case info of
ClassOpI _ _ _ fixity -> Just fixity
DataConI _ _ _ fixity -> Just fixity
VarI _ _ _ fixity -> Just fixity
_ -> Nothing
reifyFixity :: Name -> Q (Maybe Fixity)
reifyFixity = qReifyFixity
#endif
reifyFixityWithLocals :: DsMonad q => Name -> q (Maybe Fixity)
reifyFixityWithLocals name = qRecover
(return . reifyFixityInDecs name =<< localDeclarations)
(qReifyFixity name)
lookupValueNameWithLocals :: DsMonad q => String -> q (Maybe Name)
lookupValueNameWithLocals = lookupNameWithLocals False
lookupTypeNameWithLocals :: DsMonad q => String -> q (Maybe Name)
lookupTypeNameWithLocals = lookupNameWithLocals True
lookupNameWithLocals :: DsMonad q => Bool -> String -> q (Maybe Name)
lookupNameWithLocals ns s = do
mb_name <- qLookupName ns s
case mb_name of
j_name@(Just{}) -> return j_name
Nothing -> consult_locals
where
built_name = mkName s
consult_locals = do
decs <- localDeclarations
let mb_infos = map (reifyInDec built_name decs) decs
infos = catMaybes mb_infos
return $ firstMatch (if ns then find_type_name
else find_value_name) infos
find_type_name, find_value_name :: Named Info -> Maybe Name
find_type_name (n, info) =
case infoNameSpace info of
TcClsName -> Just n
VarName -> Nothing
DataName -> Nothing
find_value_name (n, info) =
case infoNameSpace info of
VarName -> Just n
DataName -> Just n
TcClsName -> Nothing
mkDataNameWithLocals :: DsMonad q => String -> q Name
mkDataNameWithLocals = mkNameWith lookupValueNameWithLocals mkNameG_d
mkTypeNameWithLocals :: DsMonad q => String -> q Name
mkTypeNameWithLocals = mkNameWith lookupTypeNameWithLocals mkNameG_tc
reifyNameSpace :: DsMonad q => Name -> q (Maybe NameSpace)
reifyNameSpace n@(Name _ nf) =
case nf of
NameG ns _ _ -> pure $ Just ns
_ -> do mb_info <- reifyWithLocals_maybe n
pure $ fmap infoNameSpace mb_info
infoNameSpace :: Info -> NameSpace
infoNameSpace info =
case info of
ClassI{} -> TcClsName
TyConI{} -> TcClsName
FamilyI{} -> TcClsName
PrimTyConI{} -> TcClsName
TyVarI{} -> TcClsName
ClassOpI{} -> VarName
VarI{} -> VarName
DataConI{} -> DataName
#if __GLASGOW_HASKELL__ >= 801
PatSynI{} -> DataName
#endif