import Maybes ( catMaybes )
import Name ( getSrcLoc )
import ErrUtils ( ErrMsg, Message, addErrLocHdrLine, pprBagOfErrors, dontAddErrLoc )
-import Type ( mkFunTys, splitFunTys, splitAlgTyConApp_maybe, splitTyConApp_maybe,
+import Type ( mkFunTys, splitFunTys, splitTyConApp_maybe,
isUnLiftedType, isTyVarTy, splitForAllTys, Type
)
-import TyCon ( TyCon )
-import Util ( zipEqual )
+import TyCon ( TyCon, isAlgTyCon, isNewTyCon, tyConDataCons )
+import Util ( zipEqual, equalLength )
import Outputable
infixr 9 `thenL`, `thenL_`, `thenMaybeL`, `thenMaybeL_`
check ty = checkTys first_ty ty (mkCaseAltMsg alts)
lintAlgAlt scrut_ty (con, args, _, rhs)
- = (case splitAlgTyConApp_maybe scrut_ty of
- Nothing ->
- addErrL (mkAlgAltMsg1 scrut_ty)
- Just (tycon, tys_applied, cons) ->
+ = (case splitTyConApp_maybe scrut_ty of
+ Just (tycon, tys_applied) | isAlgTyCon tycon &&
+ not (isNewTyCon tycon) ->
let
+ cons = tyConDataCons tycon
arg_tys = dataConArgTys con tys_applied
-- This almost certainly does not work for existential constructors
in
checkL (con `elem` cons) (mkAlgAltMsg2 scrut_ty con) `thenL_`
- checkL (length arg_tys == length args) (mkAlgAltMsg3 con args)
+ checkL (equalLength arg_tys args) (mkAlgAltMsg3 con args)
`thenL_`
mapL check (zipEqual "lintAlgAlt:stg" arg_tys args) `thenL_`
returnL ()
+ other ->
+ addErrL (mkAlgAltMsg1 scrut_ty)
) `thenL_`
addInScopeVars args (
lintStgExpr rhs
checkFunApp fun_ty arg_tys msg loc scope errs
= cfa res_ty expected_arg_tys arg_tys
where
- (_, de_forall_ty) = splitForAllTys fun_ty
+ (_, de_forall_ty) = splitForAllTys fun_ty
(expected_arg_tys, res_ty) = splitFunTys de_forall_ty
cfa res_ty expected [] -- Args have run out; that's fine