+ g :: Int
+ g = tagToEnum# 0 -- Int is not an enumeration
+
+We used to make this check in the type inference engine, but it's quite
+ugly to do so, because the delayed constraint solving means that we don't
+really know what's going on until the end. It's very much a corner case
+because we don't expect the user to call tagToEnum# at all; we merely
+generate calls in derived instances of Enum. So we compromise: a
+rewrite rule rewrites a bad instance of tagToEnum# to an error call,
+and emits a warning.
+
+\begin{code}
+tagToEnumRule :: IdUnfoldingFun -> [Expr CoreBndr] -> Maybe (Expr CoreBndr)
+-- If data T a = A | B | C
+-- then tag2Enum# (T ty) 2# --> B ty
+tagToEnumRule _ [Type ty, Lit (MachInt i)]
+ | Just (tycon, tc_args) <- splitTyConApp_maybe ty
+ , isEnumerationTyCon tycon
+ = case filter correct_tag (tyConDataCons_maybe tycon `orElse` []) of