checker.
\begin{code}
-{-# OPTIONS -w #-}
--- The above warning supression flag is a temporary kludge.
--- While working on this module you are encouraged to remove it and fix
--- any warnings in the module. See
--- http://hackage.haskell.org/trac/ghc/wiki/Commentary/CodingStyle#Warnings
--- for details
-
module TcHsSyn (
mkHsConApp, mkHsDictLet, mkHsApp,
hsLitType, hsLPatType, hsPatType,
mkHsAppTy, mkSimpleHsAlt,
- nlHsIntLit, mkVanillaTuplePat,
+ nlHsIntLit, mkVanillaTuplePat,
+ shortCutLit, hsOverLitName,
mkArbitraryType, -- Put this elsewhere?
import Id
import TcRnMonad
-import Type
+import PrelNames
import TcType
import TcMType
import TysPrim
import TysWiredIn
import TyCon
+import DataCon
import Name
import Var
import VarSet
import VarEnv
+import Literal
import BasicTypes
import Maybes
import Unique
import Util
import Bag
import Outputable
+import FastString
+\end{code}
+
+\begin{code}
+-- XXX
+thenM :: Monad a => a b -> (b -> a c) -> a c
+thenM = (>>=)
+
+thenM_ :: Monad a => a b -> a c -> a c
+thenM_ = (>>)
+
+returnM :: Monad m => a -> m a
+returnM = return
+
+mappM :: (Monad m) => (a -> m b) -> [a] -> m [b]
+mappM = mapM
\end{code}
hsLPatType :: OutPat Id -> Type
hsLPatType (L _ pat) = hsPatType pat
-hsPatType (ParPat pat) = hsLPatType pat
-hsPatType (WildPat ty) = ty
-hsPatType (VarPat var) = idType var
-hsPatType (VarPatOut var _) = idType var
-hsPatType (BangPat pat) = hsLPatType pat
-hsPatType (LazyPat pat) = hsLPatType pat
-hsPatType (LitPat lit) = hsLitType lit
-hsPatType (AsPat var pat) = idType (unLoc var)
-hsPatType (ViewPat expr pat ty) = ty
-hsPatType (ListPat _ ty) = mkListTy ty
-hsPatType (PArrPat _ ty) = mkPArrTy ty
-hsPatType (TuplePat pats box ty) = ty
-hsPatType (ConPatOut{ pat_ty = ty })= ty
-hsPatType (SigPatOut pat ty) = ty
-hsPatType (NPat lit _ _) = overLitType lit
-hsPatType (NPlusKPat id _ _ _) = idType (unLoc id)
-hsPatType (CoPat _ _ ty) = ty
+hsPatType :: Pat Id -> Type
+hsPatType (ParPat pat) = hsLPatType pat
+hsPatType (WildPat ty) = ty
+hsPatType (VarPat var) = idType var
+hsPatType (VarPatOut var _) = idType var
+hsPatType (BangPat pat) = hsLPatType pat
+hsPatType (LazyPat pat) = hsLPatType pat
+hsPatType (LitPat lit) = hsLitType lit
+hsPatType (AsPat var _) = idType (unLoc var)
+hsPatType (ViewPat _ _ ty) = ty
+hsPatType (ListPat _ ty) = mkListTy ty
+hsPatType (PArrPat _ ty) = mkPArrTy ty
+hsPatType (TuplePat _ _ ty) = ty
+hsPatType (ConPatOut { pat_ty = ty }) = ty
+hsPatType (SigPatOut _ ty) = ty
+hsPatType (NPat lit _ _) = overLitType lit
+hsPatType (NPlusKPat id _ _ _) = idType (unLoc id)
+hsPatType (CoPat _ _ ty) = ty
+hsPatType p = pprPanic "hsPatType" (ppr p)
hsLitType :: HsLit -> TcType
-hsLitType (HsChar c) = charTy
-hsLitType (HsCharPrim c) = charPrimTy
-hsLitType (HsString str) = stringTy
-hsLitType (HsStringPrim s) = addrPrimTy
-hsLitType (HsInt i) = intTy
-hsLitType (HsIntPrim i) = intPrimTy
-hsLitType (HsInteger i ty) = ty
-hsLitType (HsRat _ ty) = ty
-hsLitType (HsFloatPrim f) = floatPrimTy
-hsLitType (HsDoublePrim d) = doublePrimTy
+hsLitType (HsChar _) = charTy
+hsLitType (HsCharPrim _) = charPrimTy
+hsLitType (HsString _) = stringTy
+hsLitType (HsStringPrim _) = addrPrimTy
+hsLitType (HsInt _) = intTy
+hsLitType (HsIntPrim _) = intPrimTy
+hsLitType (HsWordPrim _) = wordPrimTy
+hsLitType (HsInteger _ ty) = ty
+hsLitType (HsRat _ ty) = ty
+hsLitType (HsFloatPrim _) = floatPrimTy
+hsLitType (HsDoublePrim _) = doublePrimTy
\end{code}
+Overloaded literals. Here mainly becuase it uses isIntTy etc
+
+\begin{code}
+shortCutLit :: OverLitVal -> TcType -> Maybe (HsExpr TcId)
+shortCutLit (HsIntegral i) ty
+ | isIntTy ty && inIntRange i = Just (HsLit (HsInt i))
+ | isWordTy ty && inWordRange i = Just (mkLit wordDataCon (HsWordPrim i))
+ | isIntegerTy ty = Just (HsLit (HsInteger i ty))
+ | otherwise = shortCutLit (HsFractional (fromInteger i)) ty
+ -- The 'otherwise' case is important
+ -- Consider (3 :: Float). Syntactically it looks like an IntLit,
+ -- so we'll call shortCutIntLit, but of course it's a float
+ -- This can make a big difference for programs with a lot of
+ -- literals, compiled without -O
+
+shortCutLit (HsFractional f) ty
+ | isFloatTy ty = Just (mkLit floatDataCon (HsFloatPrim f))
+ | isDoubleTy ty = Just (mkLit doubleDataCon (HsDoublePrim f))
+ | otherwise = Nothing
+
+shortCutLit (HsIsString s) ty
+ | isStringTy ty = Just (HsLit (HsString s))
+ | otherwise = Nothing
+
+mkLit :: DataCon -> HsLit -> HsExpr Id
+mkLit con lit = HsApp (nlHsVar (dataConWrapId con)) (nlHsLit lit)
+
+------------------------------
+hsOverLitName :: OverLitVal -> Name
+-- Get the canonical 'fromX' name for a particular OverLitVal
+hsOverLitName (HsIntegral {}) = fromIntegerName
+hsOverLitName (HsFractional {}) = fromRationalName
+hsOverLitName (HsIsString {}) = fromStringName
+\end{code}
%************************************************************************
%* *
-- Maps an Id to its zonked version; both have the same Name
-- Is only consulted lazily; hence knot-tying
+emptyZonkEnv :: ZonkEnv
emptyZonkEnv = ZonkEnv zonkTypeZapping emptyVarEnv
extendZonkEnv :: ZonkEnv -> [Id] -> ZonkEnv
--
-- Even without template splices, in module Main, the checking of
-- 'main' is done as a separate chunk.
-zonkIdOcc (ZonkEnv zonk_ty env) id
+zonkIdOcc (ZonkEnv _zonk_ty env) id
| isLocalVar id = lookupVarEnv env id `orElse` id
| otherwise = id
+zonkIdOccs :: ZonkEnv -> [TcId] -> [Id]
zonkIdOccs env ids = map (zonkIdOcc env) ids
-- zonkIdBndr is used *after* typechecking to get the Id's type
-- "Dictionary" binders can be coercion variables or dictionary variables
zonkDictBndrs env ids = mappM (zonkDictBndr env) ids
-zonkDictBndr env var | isTyVar var = return var
+zonkDictBndr :: ZonkEnv -> Var -> TcM Var
+zonkDictBndr env var | isTyVar var = zonkTyVarBndr env var
| otherwise = zonkIdBndr env var
zonkTopBndrs :: [TcId] -> TcM [Id]
zonkTopBndrs ids = zonkIdBndrs emptyZonkEnv ids
+
+-- Zonk the kind of a non-TC tyvar in case it is a coercion variable (their
+-- kind contains types).
+--
+zonkTyVarBndr :: ZonkEnv -> TyVar -> TcM TyVar
+zonkTyVarBndr env tv
+ | isCoVar tv
+ = do { kind <- zonkTcTypeToType env (tyVarKind tv)
+ ; return $ setTyVarKind tv kind
+ }
+ | otherwise = return tv
\end{code}
---------------------------------------------
zonkValBinds :: ZonkEnv -> HsValBinds TcId -> TcM (ZonkEnv, HsValBinds Id)
-zonkValBinds env bs@(ValBindsIn _ _)
- = panic "zonkValBinds" -- Not in typechecker output
+zonkValBinds _ (ValBindsIn _ _)
+ = panic "zonkValBinds" -- Not in typechecker output
zonkValBinds env (ValBindsOut binds sigs)
= do { (env1, new_binds) <- go env binds
; return (env1, ValBindsOut new_binds sigs) }
mapM zonk_prag prags `thenM` \ new_prags ->
returnM (tyvars, new_global, zonkIdOcc env local, new_prags)
zonk_prag prag@(L _ (InlinePrag {})) = return prag
- zonk_prag (L loc (SpecPrag expr ty ds inl))
+ zonk_prag (L loc (SpecPrag expr ty inl))
= do { expr' <- zonkExpr env expr
; ty' <- zonkTcTypeToType env ty
- ; let ds' = zonkIdOccs env ds
- ; return (L loc (SpecPrag expr' ty' ds' inl)) }
+ ; return (L loc (SpecPrag expr' ty' inl)) }
\end{code}
%************************************************************************
= zonkTcTypeToType env ty `thenM` \ new_ty ->
returnM (HsLit (HsRat f new_ty))
-zonkExpr env (HsLit lit)
+zonkExpr _ (HsLit lit)
= returnM (HsLit lit)
zonkExpr env (HsOverLit lit)
zonk_b (n,e) = zonkLExpr env e `thenM` \ e' ->
returnM (n,e')
-zonkExpr env (HsSpliceE s) = WARN( True, ppr s ) -- Should not happen
+zonkExpr _ (HsSpliceE s) = WARN( True, ppr s ) -- Should not happen
returnM (HsSpliceE s)
zonkExpr env (OpApp e1 op fixity e2)
= do { e' <- zonkLExpr env e
; return (ExprWithTySigOut e' ty) }
-zonkExpr env (ExprWithTySig _ _) = panic "zonkExpr env:ExprWithTySig"
+zonkExpr _ (ExprWithTySig _ _) = panic "zonkExpr env:ExprWithTySig"
zonkExpr env (ArithSeq expr info)
= zonkExpr env expr `thenM` \ new_expr ->
zonkExpr env1 expr `thenM` \ new_expr ->
return (HsWrap new_co_fn new_expr)
-zonkExpr env other = pprPanic "zonkExpr" (ppr other)
+zonkExpr _ expr = pprPanic "zonkExpr" (ppr expr)
zonkCmdTop :: ZonkEnv -> LHsCmdTop TcId -> TcM (LHsCmdTop Id)
zonkCmdTop env cmd = wrapLocM (zonk_cmd_top env) cmd
+zonk_cmd_top :: ZonkEnv -> HsCmdTop TcId -> TcM (HsCmdTop Id)
zonk_cmd_top env (HsCmdTop cmd stack_tys ty ids)
= zonkLExpr env cmd `thenM` \ new_cmd ->
zonkTcTypeToTypes env stack_tys `thenM` \ new_stack_tys ->
zonkCoFn env (WpCompose c1 c2) = do { (env1, c1') <- zonkCoFn env c1
; (env2, c2') <- zonkCoFn env1 c2
; return (env2, WpCompose c1' c2') }
-zonkCoFn env (WpCo co) = do { co' <- zonkTcTypeToType env co
- ; return (env, WpCo co') }
+zonkCoFn env (WpCast co) = do { co' <- zonkTcTypeToType env co
+ ; return (env, WpCast co') }
zonkCoFn env (WpLam id) = do { id' <- zonkDictBndr env id
; let env1 = extendZonkEnv1 env id'
; return (env1, WpLam id') }
zonkCoFn env (WpTyLam tv) = ASSERT( isImmutableTyVar tv )
- do { return (env, WpTyLam tv) }
-zonkCoFn env (WpApp id) = do { return (env, WpApp (zonkIdOcc env id)) }
+ do { tv' <- zonkTyVarBndr env tv
+ ; return (env, WpTyLam tv') }
+zonkCoFn env (WpApp v)
+ | isTcTyVar v = do { co <- zonkTcTyVar v
+ ; return (env, WpTyApp co) }
+ -- Yuk! A mutable coercion variable is a TcTyVar
+ -- not a CoVar, so don't use isCoVar!
+ -- Yuk! A WpApp can't hold the zonked type,
+ -- so we switch to WpTyApp
+ | otherwise = return (env, WpApp (zonkIdOcc env v))
zonkCoFn env (WpTyApp ty) = do { ty' <- zonkTcTypeToType env ty
; return (env, WpTyApp ty') }
zonkCoFn env (WpLet bs) = do { (env1, bs') <- zonkRecMonoBinds env bs
zonkDo :: ZonkEnv -> HsStmtContext Name -> HsStmtContext Name
-- Only used for 'do', so the only Ids are in a MDoExpr table
zonkDo env (MDoExpr tbl) = MDoExpr (mapSnd (zonkIdOcc env) tbl)
-zonkDo env do_or_lc = do_or_lc
+zonkDo _ do_or_lc = do_or_lc
-------------------------------------------------------------------------
zonkOverLit :: ZonkEnv -> HsOverLit TcId -> TcM (HsOverLit Id)
-zonkOverLit env ol =
- let
- zonkedStuff = do ty' <- zonkTcTypeToType env (overLitType ol)
- e' <- zonkExpr env (overLitExpr ol)
- return (e', ty')
- ru f (x, y) = return (f x y)
- in
- case ol of
- (HsIntegral i _ _) -> ru (HsIntegral i) =<< zonkedStuff
- (HsFractional r _ _) -> ru (HsFractional r) =<< zonkedStuff
- (HsIsString s _ _) -> ru (HsIsString s) =<< zonkedStuff
+zonkOverLit env lit@(OverLit { ol_witness = e, ol_type = ty })
+ = do { ty' <- zonkTcTypeToType env ty
+ ; e' <- zonkExpr env e
+ ; return (lit { ol_witness = e', ol_type = ty' }) }
-------------------------------------------------------------------------
zonkArithSeq :: ZonkEnv -> ArithSeqInfo TcId -> TcM (ArithSeqInfo Id)
; new_fail <- zonkExpr env fail_op
; return (env1, BindStmt new_pat new_expr new_bind new_fail) }
-zonkMaybeLExpr env Nothing = return Nothing
+zonkMaybeLExpr :: ZonkEnv -> Maybe (LHsExpr TcId) -> TcM (Maybe (LHsExpr Id))
+zonkMaybeLExpr _ Nothing = return Nothing
zonkMaybeLExpr env (Just e) = (zonkLExpr env e) >>= (return . Just)
; return (HsRecFields flds' dd) }
where
zonk_rbind fld
- = do { new_expr <- zonkLExpr env (hsRecFieldArg fld)
- ; return (fld { hsRecFieldArg = new_expr }) }
- -- Field selectors have declared types; hence no zonking
+ = do { new_id <- wrapLocM (zonkIdBndr env) (hsRecFieldId fld)
+ ; new_expr <- zonkLExpr env (hsRecFieldArg fld)
+ ; return (fld { hsRecFieldId = new_id, hsRecFieldArg = new_expr }) }
-------------------------------------------------------------------------
mapIPNameTc :: (a -> TcM b) -> IPName a -> TcM (IPName b)
-- to the right)
zonkPat env pat = wrapLocSndM (zonk_pat env) pat
+zonk_pat :: ZonkEnv -> Pat TcId -> TcM (ZonkEnv, Pat Id)
zonk_pat env (ParPat p)
= do { (env', p') <- zonkPat env p
; return (env', ParPat p') }
; ty' <- zonkTcTypeToType env'' ty
; return (env'', CoPat co_fn' (unLoc pat') ty') }
-zonk_pat env pat = pprPanic "zonk_pat" (ppr pat)
+zonk_pat _ pat = pprPanic "zonk_pat" (ppr pat)
---------------------------
+zonkConStuff :: ZonkEnv
+ -> HsConDetails (OutPat TcId) (HsRecFields id (OutPat TcId))
+ -> TcM (ZonkEnv,
+ HsConDetails (OutPat Id) (HsRecFields id (OutPat Id)))
zonkConStuff env (PrefixCon pats)
= do { (env', pats') <- zonkPats env pats
; return (env', PrefixCon pats') }
-- Field selectors have declared types; hence no zonking
---------------------------
+zonkPats :: ZonkEnv -> [OutPat TcId] -> TcM (ZonkEnv, [OutPat Id])
zonkPats env [] = return (env, [])
zonkPats env (pat:pats) = do { (env1, pat') <- zonkPat env pat
; (env', pats') <- zonkPats env1 pats
zonkForeignExports env ls = mappM (wrapLocM (zonkForeignExport env)) ls
zonkForeignExport :: ZonkEnv -> ForeignDecl TcId -> TcM (ForeignDecl Id)
-zonkForeignExport env (ForeignExport i hs_ty spec) =
+zonkForeignExport env (ForeignExport i _hs_ty spec) =
returnM (ForeignExport (fmap (zonkIdOcc env) i) undefined spec)
-zonkForeignExport env for_imp
+zonkForeignExport _ for_imp
= returnM for_imp -- Foreign imports don't need zonking
\end{code}
| isId (unLoc v) = wrapLocM (zonkIdBndr env) v
| otherwise = ASSERT( isImmutableTyVar (unLoc v) )
return v
+ zonk_bndr (RuleBndrSig {}) = panic "zonk_bndr RuleBndrSig"
\end{code}
-- to use when generating a warning
mkArbitraryType warn tv
| liftedTypeKind `isSubKind` kind -- The vastly common case
- = return anyPrimTy
- | eqKind kind (tyConKind anyPrimTyCon1) -- *->*
+ = return anyPrimTy
+ | eqKind kind (tyConKind anyPrimTyCon1) -- @*->*@
= return (mkTyConApp anyPrimTyCon1 []) -- No tuples this size
- | all isLiftedTypeKind args -- *-> ... ->*->*
+ | all isLiftedTypeKind args -- @*-> ... ->*->*@
, isLiftedTypeKind res -- Horrible hack to make less use
= return (mkTyConApp tup_tc []) -- of mkAnyPrimTyCon
| otherwise
(args,res) = splitKindFunTys kind
tup_tc = tupleTyCon Boxed (length args)
- msg = vcat [ hang (ptext SLIT("Inventing strangely-kinded Any TyCon"))
- 2 (ptext SLIT("of kind") <+> quotes (ppr kind))
- , nest 2 (ptext SLIT("from an instantiation of type variable") <+> quotes (ppr tv))
- , ptext SLIT("This warning can be suppressed by a type signature fixing") <+> quotes (ppr tv)
- , nest 2 (ptext SLIT("but is harmless without -O (and usually harmless anyway)."))
- , ptext SLIT("See http://hackage.haskell.org/trac/ghc/ticket/959 for details") ]
+ msg = vcat [ hang (ptext (sLit "Inventing strangely-kinded Any TyCon"))
+ 2 (ptext (sLit "of kind") <+> quotes (ppr kind))
+ , nest 2 (ptext (sLit "from an instantiation of type variable") <+> quotes (ppr tv))
+ , ptext (sLit "This warning can be suppressed by a type signature fixing") <+> quotes (ppr tv)
+ , nest 2 (ptext (sLit "but is harmless without -O (and usually harmless anyway)."))
+ , ptext (sLit "See http://hackage.haskell.org/trac/ghc/ticket/959 for details") ]
\end{code}