+Note [tagToEnum#]
+~~~~~~~~~~~~~~~~~
+Nasty check to ensure that tagToEnum# is applied to a type that is an
+enumeration TyCon. Unification may refine the type later, but this
+check won't see that, alas. It's crude but it works.
+
+Here's are two cases that should fail
+ f :: forall a. a
+ f = tagToEnum# 0 -- Can't do tagToEnum# at a type variable
+
+ g :: Int
+ g = tagToEnum# 0 -- Int is not an enumeration
+
+
+\begin{code}
+checkBadTagToEnumCall :: Id -> [TcType] -> TcM ()
+checkBadTagToEnumCall fun_id tys
+ | fun_id `hasKey` tagToEnumKey
+ = do { tys' <- zonkTcTypes tys
+ ; checkTc (ok tys') (tagToEnumError tys')
+ }
+ | otherwise -- Vastly common case
+ = return ()
+ where
+ ok [] = False
+ ok (ty:tys) = case tcSplitTyConApp_maybe ty of
+ Just (tc,_) -> isEnumerationTyCon tc
+ Nothing -> False
+
+tagToEnumError tys
+ = hang (ptext SLIT("Bad call to tagToEnum#") <+> at_type)
+ 2 (vcat [ptext SLIT("Specify the type by giving a type signature"),
+ ptext SLIT("e.g. (tagToEnum# x) :: Bool")])
+ where
+ at_type | null tys = empty -- Probably never happens
+ | otherwise = ptext SLIT("at type") <+> ppr (head tys)
+\end{code}
+