lintAlt scrut_ty (DataAlt con, args, _, rhs) = do
    case splitTyConApp_maybe scrut_ty of
      Just (tycon, tys_applied) | isAlgTyCon tycon &&
                                  not (isNewTyCon tycon) -> do
         let
           cons    = tyConDataCons tycon
           arg_tys = dataConInstArgTys con tys_applied
                -- This does not work for existential constructors

         checkL (con `elem` cons) (mkAlgAltMsg2 scrut_ty con)
         checkL (length args == dataConRepArity con) (mkAlgAltMsg3 con args)
         when (isVanillaDataCon con) $
           mapM_ check (zipEqual "lintAlgAlt:stg" arg_tys args)
         return ()
      _ ->
         addErrL (mkAltMsg1 scrut_ty)

    addInScopeVars args $
         lintStgExpr rhs
  where
    check (ty, arg) = checkTys ty (idType arg) (mkAlgAltMsg4 ty arg)

    -- elem: yes, the elem-list here can sometimes be long-ish,
    -- but as it's use-once, probably not worth doing anything different
    -- We give it its own copy, so it isn't overloaded.
    elem _ []       = False
    elem x (y:ys)   = x==y || elem x ys

{-
************************************************************************
*                                                                      *
\subsection[lint-monad]{The Lint monad}
*                                                                      *
************************************************************************
-}
lintAlt scrut_ty (DataAlt con, args, _, rhs) = do
    case splitTyConApp_maybe scrut_ty of
      Just (tycon, tys_applied) | isAlgTyCon tycon &&
                                  not (isNewTyCon tycon) -> do
         let
           cons    = tyConDataCons tycon
           arg_tys = dataConInstArgTys con tys_applied
                -- This does not work for existential constructors

         checkL (con `elem` cons) (mkAlgAltMsg2 scrut_ty con)
         checkL (length args == dataConRepArity con) (mkAlgAltMsg3 con args)
         when (isVanillaDataCon con) $
           mapM_ check (zipEqual "lintAlgAlt:stg" arg_tys args)
         return ()
      _ ->
         addErrL (mkAltMsg1 scrut_ty)

    addInScopeVars args $
         lintStgExpr rhs
  where
    check (ty, arg) = checkTys ty (idType arg) (mkAlgAltMsg4 ty arg)

    -- elem: yes, the elem-list here can sometimes be long-ish,
    -- but as it's use-once, probably not worth doing anything different
    -- We give it its own copy, so it isn't overloaded.
    elem _ []       = False
    elem x (y:ys)   = x==y || elem x ys

{-
************************************************************************
*                                                                      *
\subsection[lint-monad]{The Lint monad}
*                                                                      *
************************************************************************
-}
lintAlt scrut_ty (DataAlt con, args, _, rhs) = do
    case splitTyConApp_maybe scrut_ty of
      Just (tycon, tys_applied) | isAlgTyCon tycon &&
                                  not (isNewTyCon tycon) -> do
         let
           cons    = tyConDataCons tycon
           arg_tys = dataConInstArgTys con tys_applied
                -- This does not work for existential constructors

         checkL (con `elem` cons) (mkAlgAltMsg2 scrut_ty con)
         checkL (length args == dataConRepArity con) (mkAlgAltMsg3 con args)
         when (isVanillaDataCon con) $
           mapM_ check (zipEqual "lintAlgAlt:stg" arg_tys args)
         return ()
      _ ->
         addErrL (mkAltMsg1 scrut_ty)

    addInScopeVars args $
         lintStgExpr rhs
  where
    check (ty, arg) = checkTys ty (idType arg) (mkAlgAltMsg4 ty arg)

    -- elem: yes, the elem-list here can sometimes be long-ish,
    -- but as it's use-once, probably not worth doing anything different
    -- We give it its own copy, so it isn't overloaded.
    elem _ []       = False
    elem x (y:ys)   = x==y || elem x ys

{-
************************************************************************
*                                                                      *
\subsection[lint-monad]{The Lint monad}
*                                                                      *
************************************************************************
-}