summaryrefslogtreecommitdiff
path: root/compiler/iface
diff options
context:
space:
mode:
authorSimon Peyton Jones <simonpj@microsoft.com>2015-05-11 23:19:14 +0100
committerSimon Peyton Jones <simonpj@microsoft.com>2015-05-18 13:44:15 +0100
commitffc21506894c7887d3620423aaf86bc6113a1071 (patch)
treec36353b98b3e5eeb9a257b39d95e56f441aa36da /compiler/iface
parent76024fdbad0f6daedd8757b974eace3314bd4eec (diff)
downloadhaskell-ffc21506894c7887d3620423aaf86bc6113a1071.tar.gz
Refactor tuple constraints
Make tuple constraints be handled by a perfectly ordinary type class, with the component constraints being the superclasses: class (c1, c2) => (c2, c2) This change was provoked by #10359 inability to re-use a given tuple constraint as a whole #9858 confusion between term tuples and constraint tuples but it's generally a very nice simplification. We get rid of - In Type, the TuplePred constructor of PredTree, and all the code that dealt with TuplePreds - In TcEvidence, the constructors EvTupleMk, EvTupleSel See Note [How tuples work] in TysWiredIn. Of course, nothing is ever entirely simple. This one proved quite fiddly. - I did quite a bit of renaming, which makes this patch touch a lot of modules. In partiuclar tupleCon -> tupleDataCon. - I made constraint tuples known-key rather than wired-in. This is different to boxed/unboxed tuples, but it proved awkward to have all the superclass selectors wired-in. Easier just to use the standard mechanims. - While I was fiddling with known-key names, I split the TH Name definitions out of DsMeta into a new module THNames. That meant that the known-key names can all be gathered in PrelInfo, without causing module loops. - I found that the parser was parsing an import item like T( .. ) as a *data constructor* T, and then using setRdrNameSpace to fix it. Stupid! So I changed the parser to parse a *type constructor* T, which means less use of setRdrNameSpace. I also improved setRdrNameSpace to behave better on Exact Names. Largely on priciple; I don't think it matters a lot. - When compiling a data type declaration for a wired-in thing like tuples (,), or lists, we don't really need to look at the declaration. We have the wired-in thing! And not doing so avoids having to line up the uniques for data constructor workers etc. See Note [Declarations for wired-in things] - I found that FunDeps.oclose wasn't taking superclasses into account; easily fixed. - Some error message refactoring for invalid constraints in TcValidity - Haddock needs to absorb the change too; so there is a submodule update
Diffstat (limited to 'compiler/iface')
-rw-r--r--compiler/iface/BinIface.hs16
-rw-r--r--compiler/iface/BuildTyCl.hs4
-rw-r--r--compiler/iface/IfaceSyn.hs9
-rw-r--r--compiler/iface/IfaceType.hs154
-rw-r--r--compiler/iface/TcIface.hs84
5 files changed, 161 insertions, 106 deletions
diff --git a/compiler/iface/BinIface.hs b/compiler/iface/BinIface.hs
index e99ad4d547..9d3ef75bec 100644
--- a/compiler/iface/BinIface.hs
+++ b/compiler/iface/BinIface.hs
@@ -24,7 +24,7 @@ import TcRnMonad
import TyCon
import ConLike
import DataCon (dataConName, dataConWorkId, dataConTyCon)
-import PrelInfo (wiredInThings, basicKnownKeyNames)
+import PrelInfo ( knownKeyNames )
import Id (idName, isDataConWorkId_maybe)
import TysWiredIn
import IfaceEnv
@@ -303,14 +303,11 @@ serialiseName bh name _ = do
knownKeyNamesMap :: UniqFM Name
knownKeyNamesMap = listToUFM_Directly [(nameUnique n, n) | n <- knownKeyNames]
- where
- knownKeyNames :: [Name]
- knownKeyNames = map getName wiredInThings ++ basicKnownKeyNames
-- See Note [Symbol table representation of names]
putName :: BinDictionary -> BinSymbolTable -> BinHandle -> Name -> IO ()
-putName _dict BinSymbolTable{
+putName _dict BinSymbolTable{
bin_symtab_map = symtab_map_ref,
bin_symtab_next = symtab_next } bh name
| name `elemUFM` knownKeyNamesMap
@@ -349,7 +346,7 @@ putTupleName_ bh tc tup_sort thing_tag
sort_tag = case tup_sort of
BoxedTuple -> 0
UnboxedTuple -> 1
- ConstraintTuple -> 2
+ ConstraintTuple -> pprPanic "putTupleName:ConstraintTuple" (ppr tc)
-- See Note [Symbol table representation of names]
getSymtabName :: NameCacheUpdater
@@ -370,11 +367,10 @@ getSymtabName _ncu _dict symtab bh = do
2 -> idName (dataConWorkId dc)
_ -> pprPanic "getSymtabName:unknown tuple thing" (ppr i)
where
- dc = tupleCon sort arity
+ dc = tupleDataCon sort arity
sort = case (i .&. 0x30000000) `shiftR` 28 of
- 0 -> BoxedTuple
- 1 -> UnboxedTuple
- 2 -> ConstraintTuple
+ 0 -> Boxed
+ 1 -> Unboxed
_ -> pprPanic "getSymtabName:unknown tuple sort" (ppr i)
thing_tag = (i .&. 0x0CFFFFFF) `shiftR` 26
arity = fromIntegral (i .&. 0x03FFFFFF)
diff --git a/compiler/iface/BuildTyCl.hs b/compiler/iface/BuildTyCl.hs
index 6e14700cfa..b6db5dc9ee 100644
--- a/compiler/iface/BuildTyCl.hs
+++ b/compiler/iface/BuildTyCl.hs
@@ -21,6 +21,7 @@ module BuildTyCl (
import IfaceEnv
import FamInstEnv( FamInstEnvs )
+import TysWiredIn( isCTupleTyConName )
import DataCon
import PatSyn
import Var
@@ -282,6 +283,9 @@ buildClass tycon_name tvs roles sc_theta fds at_items sig_stuff mindef tc_isrec
; rhs <- if use_newtype
then mkNewTyConRhs tycon_name rec_tycon dict_con
+ else if isCTupleTyConName tycon_name
+ then return (TupleTyCon { data_con = dict_con
+ , tup_sort = ConstraintTuple })
else return (mkDataTyConRhs [dict_con])
; let { clas_kind = mkPiKinds tvs constraintKind
diff --git a/compiler/iface/IfaceSyn.hs b/compiler/iface/IfaceSyn.hs
index 0838cb8468..c5aa1a521b 100644
--- a/compiler/iface/IfaceSyn.hs
+++ b/compiler/iface/IfaceSyn.hs
@@ -911,7 +911,7 @@ pprIfaceExpr _ (IfaceType ty) = char '@' <+> pprParendIfaceType ty
pprIfaceExpr _ (IfaceCo co) = text "@~" <+> pprParendIfaceCoercion co
pprIfaceExpr add_par app@(IfaceApp _ _) = add_par (pprIfaceApp app [])
-pprIfaceExpr _ (IfaceTuple c as) = tupleParens c (interpp'SP as)
+pprIfaceExpr _ (IfaceTuple c as) = tupleParens c (pprWithCommas ppr as)
pprIfaceExpr add_par i@(IfaceLam _ _)
= add_par (sep [char '\\' <+> sep (map pprIfaceLamBndr bndrs) <+> arrow,
@@ -1136,11 +1136,10 @@ freeNamesIfTcArgs ITC_Nil = emptyNameSet
freeNamesIfType :: IfaceType -> NameSet
freeNamesIfType (IfaceTyVar _) = emptyNameSet
freeNamesIfType (IfaceAppTy s t) = freeNamesIfType s &&& freeNamesIfType t
-freeNamesIfType (IfaceTyConApp tc ts) =
- freeNamesIfTc tc &&& freeNamesIfTcArgs ts
+freeNamesIfType (IfaceTyConApp tc ts) = freeNamesIfTc tc &&& freeNamesIfTcArgs ts
+freeNamesIfType (IfaceTupleTy _ _ ts) = freeNamesIfTcArgs ts
freeNamesIfType (IfaceLitTy _) = emptyNameSet
-freeNamesIfType (IfaceForAllTy tv t) =
- freeNamesIfTvBndr tv &&& freeNamesIfType t
+freeNamesIfType (IfaceForAllTy tv t) = freeNamesIfTvBndr tv &&& freeNamesIfType t
freeNamesIfType (IfaceFunTy s t) = freeNamesIfType s &&& freeNamesIfType t
freeNamesIfType (IfaceDFunTy s t) = freeNamesIfType s &&& freeNamesIfType t
diff --git a/compiler/iface/IfaceType.hs b/compiler/iface/IfaceType.hs
index dc3c5c5039..6dfff6e4e5 100644
--- a/compiler/iface/IfaceType.hs
+++ b/compiler/iface/IfaceType.hs
@@ -10,7 +10,8 @@ This module defines interface types and binders
module IfaceType (
IfExtName, IfLclName,
- IfaceType(..), IfacePredType, IfaceKind, IfaceTyCon(..), IfaceCoercion(..),
+ IfaceType(..), IfacePredType, IfaceKind, IfaceCoercion(..),
+ IfaceTyCon(..), IfaceTyConInfo(..),
IfaceTyLit(..), IfaceTcArgs(..),
IfaceContext, IfaceBndr(..), IfaceOneShot(..), IfaceLamBndr, IfaceTvBndr, IfaceIdBndr,
@@ -44,12 +45,12 @@ module IfaceType (
#include "HsVersions.h"
import Coercion
-import DataCon ( dataConTyCon )
+import DataCon ( isTupleDataCon )
import TcType
import DynFlags
import TypeRep
import Unique( hasKey )
-import Util ( filterOut, lengthIs, zipWithEqual )
+import Util ( filterOut, zipWithEqual )
import TyCon hiding ( pprPromotionQuote )
import CoAxiom
import Id
@@ -99,13 +100,19 @@ type IfaceKind = IfaceType
data IfaceType -- A kind of universal type, used for types and kinds
= IfaceTyVar IfLclName -- Type/coercion variable only, not tycon
+ | IfaceLitTy IfaceTyLit
| IfaceAppTy IfaceType IfaceType
| IfaceFunTy IfaceType IfaceType
| IfaceDFunTy IfaceType IfaceType
| IfaceForAllTy IfaceTvBndr IfaceType
+
| IfaceTyConApp IfaceTyCon IfaceTcArgs -- Not necessarily saturated
- -- Includes newtypes, synonyms, tuples
- | IfaceLitTy IfaceTyLit
+ -- Includes newtypes, synonyms
+
+ | IfaceTupleTy -- Saturated tuples (unsaturated ones use IfaceTyConApp)
+ TupleSort IfaceTyConInfo -- A bit like IfaceTyCon
+ IfaceTcArgs -- arity = length args
+ -- For promoted data cons, the kind args are omitted
type IfacePredType = IfaceType
type IfaceContext = [IfacePredType]
@@ -128,10 +135,14 @@ data IfaceTcArgs
-- coercion constructors, the lot.
-- We have to tag them in order to pretty print them
-- properly.
-data IfaceTyCon
- = IfaceTc { ifaceTyConName :: IfExtName }
- | IfacePromotedDataCon { ifaceTyConName :: IfExtName }
- | IfacePromotedTyCon { ifaceTyConName :: IfExtName }
+data IfaceTyCon = IfaceTyCon { ifaceTyConName :: IfExtName
+ , ifaceTyConInfo :: IfaceTyConInfo }
+
+data IfaceTyConInfo -- Used to guide pretty-printing
+ -- and to disambiguate D from 'D (they share a name)
+ = NoIfaceTyConInfo
+ | IfacePromotedDataCon
+ | IfacePromotedTyCon
data IfaceCoercion
= IfaceReflCo Role IfaceType
@@ -207,8 +218,9 @@ ifTyVarsOfType ty
IfaceForAllTy (var,t) ty
-> delOneFromUniqSet (ifTyVarsOfType ty) var `unionUniqSets`
ifTyVarsOfType t
- IfaceTyConApp _ args -> ifTyVarsOfArgs args
- IfaceLitTy _ -> emptyUniqSet
+ IfaceTyConApp _ args -> ifTyVarsOfArgs args
+ IfaceTupleTy _ _ args -> ifTyVarsOfArgs args
+ IfaceLitTy _ -> emptyUniqSet
ifTyVarsOfArgs :: IfaceTcArgs -> UniqSet IfLclName
ifTyVarsOfArgs args = argv emptyUniqSet args
@@ -238,6 +250,7 @@ substIfaceType env ty
go (IfaceDFunTy t1 t2) = IfaceDFunTy (go t1) (go t2)
go ty@(IfaceLitTy {}) = ty
go (IfaceTyConApp tc tys) = IfaceTyConApp tc (substIfaceTcArgs env tys)
+ go (IfaceTupleTy s i tys) = IfaceTupleTy s i (substIfaceTcArgs env tys)
go (IfaceForAllTy {}) = pprPanic "substIfaceType" (ppr ty)
substIfaceTcArgs :: IfaceTySubst -> IfaceTcArgs -> IfaceTcArgs
@@ -304,18 +317,6 @@ we want
************************************************************************
* *
- Functions over IFaceTyCon
-* *
-************************************************************************
--}
-
---isPromotedIfaceTyCon :: IfaceTyCon -> Bool
---isPromotedIfaceTyCon (IfacePromotedTyCon _) = True
---isPromotedIfaceTyCon _ = False
-
-{-
-************************************************************************
-* *
Pretty-printing
* *
************************************************************************
@@ -395,6 +396,7 @@ pprParendIfaceType = ppr_ty TyConPrec
ppr_ty :: TyPrec -> IfaceType -> SDoc
ppr_ty _ (IfaceTyVar tyvar) = ppr tyvar
ppr_ty ctxt_prec (IfaceTyConApp tc tys) = sdocWithDynFlags (pprTyTcApp ctxt_prec tc tys)
+ppr_ty _ (IfaceTupleTy s i tys) = pprTuple s i tys
ppr_ty _ (IfaceLitTy n) = ppr_tylit n
-- Function types
ppr_ty ctxt_prec (IfaceFunTy ty1 ty2)
@@ -521,10 +523,6 @@ ppr_iface_tc_app pp _ tc [ty]
n = ifaceTyConName tc
ppr_iface_tc_app pp ctxt_prec tc tys
- | Just (tup_sort, tup_args) <- is_tuple
- = pprPromotionQuote tc <>
- tupleParens tup_sort (sep (punctuate comma (map (pp TopPrec) tup_args)))
-
| not (isSymOcc (nameOccName tc_name))
= pprIfacePrefixApp ctxt_prec (ppr tc) (map (pp TyConPrec) tys)
@@ -540,22 +538,10 @@ ppr_iface_tc_app pp ctxt_prec tc tys
where
tc_name = ifaceTyConName tc
- is_tuple = case wiredInNameTyThing_maybe tc_name of
- Just (ATyCon tc)
- | Just sort <- tyConTuple_maybe tc
- , tyConArity tc == length tys
- -> Just (sort, tys)
-
- | Just dc <- isPromotedDataCon_maybe tc
- , let dc_tc = dataConTyCon dc
- , Just tup_sort <- tyConTuple_maybe dc_tc
- , let arity = tyConArity dc_tc
- ty_args = drop arity tys
- , ty_args `lengthIs` arity
- -> Just (tup_sort, ty_args)
-
- _ -> Nothing
-
+pprTuple :: TupleSort -> IfaceTyConInfo -> IfaceTcArgs -> SDoc
+pprTuple sort info args
+ = pprPromotionQuoteI info <>
+ tupleParens sort (pprWithCommas pprIfaceType (tcArgsIfaceTypes args))
ppr_tylit :: IfaceTyLit -> SDoc
ppr_tylit (IfaceNumTyLit n) = integer n
@@ -635,27 +621,34 @@ instance Outputable IfaceTyCon where
ppr tc = pprPromotionQuote tc <> ppr (ifaceTyConName tc)
pprPromotionQuote :: IfaceTyCon -> SDoc
-pprPromotionQuote (IfacePromotedDataCon _ ) = char '\''
-pprPromotionQuote (IfacePromotedTyCon _) = ifPprDebug (char '\'')
-pprPromotionQuote _ = empty
+pprPromotionQuote tc = pprPromotionQuoteI (ifaceTyConInfo tc)
+
+pprPromotionQuoteI :: IfaceTyConInfo -> SDoc
+pprPromotionQuoteI NoIfaceTyConInfo = empty
+pprPromotionQuoteI IfacePromotedDataCon = char '\''
+pprPromotionQuoteI IfacePromotedTyCon = ifPprDebug (char '\'')
instance Outputable IfaceCoercion where
ppr = pprIfaceCoercion
instance Binary IfaceTyCon where
- put_ bh tc =
- case tc of
- IfaceTc n -> putByte bh 0 >> put_ bh n
- IfacePromotedDataCon n -> putByte bh 1 >> put_ bh n
- IfacePromotedTyCon n -> putByte bh 2 >> put_ bh n
+ put_ bh (IfaceTyCon n i) = put_ bh n >> put_ bh i
+
+ get bh = do n <- get bh
+ i <- get bh
+ return (IfaceTyCon n i)
+
+instance Binary IfaceTyConInfo where
+ put_ bh NoIfaceTyConInfo = putByte bh 0
+ put_ bh IfacePromotedDataCon = putByte bh 1
+ put_ bh IfacePromotedTyCon = putByte bh 2
get bh =
- do tc <- getByte bh
- case tc of
- 0 -> get bh >>= return . IfaceTc
- 1 -> get bh >>= return . IfacePromotedDataCon
- 2 -> get bh >>= return . IfacePromotedTyCon
- _ -> panic ("get IfaceTyCon " ++ show tc)
+ do i <- getByte bh
+ case i of
+ 0 -> return NoIfaceTyConInfo
+ 1 -> return IfacePromotedDataCon
+ _ -> return IfacePromotedTyCon
instance Outputable IfaceTyLit where
ppr = ppr_tylit
@@ -729,9 +722,10 @@ instance Binary IfaceType where
put_ bh ah
put_ bh (IfaceTyConApp tc tys)
= do { putByte bh 5; put_ bh tc; put_ bh tys }
-
+ put_ bh (IfaceTupleTy s i tys)
+ = do { putByte bh 6; put_ bh s; put_ bh i; put_ bh tys }
put_ bh (IfaceLitTy n)
- = do { putByte bh 30; put_ bh n }
+ = do { putByte bh 7; put_ bh n }
get bh = do
h <- getByte bh
@@ -752,6 +746,8 @@ instance Binary IfaceType where
return (IfaceDFunTy ag ah)
5 -> do { tc <- get bh; tys <- get bh
; return (IfaceTyConApp tc tys) }
+ 6 -> do { s <- get bh; i <- get bh; tys <- get bh
+ ; return (IfaceTupleTy s i tys) }
30 -> do n <- get bh
return (IfaceLitTy n)
@@ -904,12 +900,32 @@ toIfaceType :: Type -> IfaceType
-- Synonyms are retained in the interface type
toIfaceType (TyVarTy tv) = IfaceTyVar (toIfaceTyVar tv)
toIfaceType (AppTy t1 t2) = IfaceAppTy (toIfaceType t1) (toIfaceType t2)
+toIfaceType (LitTy n) = IfaceLitTy (toIfaceTyLit n)
+toIfaceType (ForAllTy tv t) = IfaceForAllTy (toIfaceTvBndr tv) (toIfaceType t)
toIfaceType (FunTy t1 t2)
| isPredTy t1 = IfaceDFunTy (toIfaceType t1) (toIfaceType t2)
| otherwise = IfaceFunTy (toIfaceType t1) (toIfaceType t2)
-toIfaceType (TyConApp tc tys) = IfaceTyConApp (toIfaceTyCon tc) (toIfaceTcArgs tc tys)
-toIfaceType (LitTy n) = IfaceLitTy (toIfaceTyLit n)
-toIfaceType (ForAllTy tv t) = IfaceForAllTy (toIfaceTvBndr tv) (toIfaceType t)
+
+toIfaceType (TyConApp tc tys) -- Look for the three sorts of saturated tuple
+ | Just sort <- tyConTuple_maybe tc
+ , n_tys == arity
+ = IfaceTupleTy sort NoIfaceTyConInfo (toIfaceTcArgs tc tys)
+
+ | Just tc' <- isPromotedTyCon_maybe tc
+ , Just sort <- tyConTuple_maybe tc'
+ , n_tys == arity
+ = IfaceTupleTy sort IfacePromotedTyCon (toIfaceTcArgs tc tys)
+
+ | Just dc <- isPromotedDataCon_maybe tc
+ , isTupleDataCon dc
+ , n_tys == 2*arity
+ = IfaceTupleTy BoxedTuple IfacePromotedDataCon (toIfaceTcArgs tc (drop arity tys))
+
+ | otherwise
+ = IfaceTyConApp (toIfaceTyCon tc) (toIfaceTcArgs tc tys)
+ where
+ arity = tyConArity tc
+ n_tys = length tys
toIfaceTyVar :: TyVar -> FastString
toIfaceTyVar = occNameFS . getOccName
@@ -920,13 +936,17 @@ toIfaceCoVar = occNameFS . getOccName
----------------
toIfaceTyCon :: TyCon -> IfaceTyCon
toIfaceTyCon tc
- | isPromotedDataCon tc = IfacePromotedDataCon tc_name
- | isPromotedTyCon tc = IfacePromotedTyCon tc_name
- | otherwise = IfaceTc tc_name
- where tc_name = tyConName tc
+ = IfaceTyCon tc_name info
+ where
+ tc_name = tyConName tc
+ info | isPromotedDataCon tc = IfacePromotedDataCon
+ | isPromotedTyCon tc = IfacePromotedTyCon
+ | otherwise = NoIfaceTyConInfo
toIfaceTyCon_name :: Name -> IfaceTyCon
-toIfaceTyCon_name = IfaceTc
+toIfaceTyCon_name n = IfaceTyCon n NoIfaceTyConInfo
+ -- Used for the "rough-match" tycon stuff,
+ -- where pretty-printing is not an issue
toIfaceTyLit :: TyLit -> IfaceTyLit
toIfaceTyLit (NumTyLit x) = IfaceNumTyLit x
diff --git a/compiler/iface/TcIface.hs b/compiler/iface/TcIface.hs
index 1beae57cc7..2553643525 100644
--- a/compiler/iface/TcIface.hs
+++ b/compiler/iface/TcIface.hs
@@ -49,7 +49,7 @@ import DataCon
import PrelNames
import TysWiredIn
import TysPrim ( superKindTyConName )
-import BasicTypes ( strongLoopBreaker )
+import BasicTypes ( strongLoopBreaker, Arity, TupleSort(..), Boxity(..) )
import Literal
import qualified Var
import VarEnv
@@ -643,7 +643,7 @@ tcIfaceRule (IfaceRule {ifRuleName = name, ifActivation = act, ifRuleBndrs = bnd
-- or, even if it is (module loop, perhaps)
-- we'll just leave it in the non-local set
where
- -- This function *must* mirror exactly what Rules.topFreeName does
+ -- This function *must* mirror exactly what Rules.roughTopNames does
-- We could have stored the ru_rough field in the iface file
-- but that would be redundant, I think.
-- The only wrinkle is that we must not be deceived by
@@ -652,6 +652,7 @@ tcIfaceRule (IfaceRule {ifRuleName = name, ifActivation = act, ifRuleBndrs = bnd
-- to write them out in coreRuleToIfaceRule
ifTopFreeName :: IfaceExpr -> Maybe Name
ifTopFreeName (IfaceType (IfaceTyConApp tc _ )) = Just (ifaceTyConName tc)
+ ifTopFreeName (IfaceType (IfaceTupleTy s _ ts)) = Just (tupleTyConName s (length (tcArgsIfaceTypes ts)))
ifTopFreeName (IfaceApp f _) = ifTopFreeName f
ifTopFreeName (IfaceExt n) = Just n
ifTopFreeName _ = Nothing
@@ -805,7 +806,7 @@ tcIfaceVectInfo mod typeEnv (IfaceVectInfo
-- name is not a tycon => internal inconsistency
Just _ -> notATyConErr
-- tycon is external
- Nothing -> tcIfaceTyCon (IfaceTc name)
+ Nothing -> tcIfaceTyConByName name
}
notATyConErr = pprPanic "TcIface.tcIfaceVectInfo: not a tycon" (ppr name)
@@ -824,6 +825,7 @@ tcIfaceType (IfaceAppTy t1 t2) = do { t1' <- tcIfaceType t1; t2' <- tcIfaceT
tcIfaceType (IfaceLitTy l) = do { l1 <- tcIfaceTyLit l; return (LitTy l1) }
tcIfaceType (IfaceFunTy t1 t2) = tcIfaceTypeFun t1 t2
tcIfaceType (IfaceDFunTy t1 t2) = tcIfaceTypeFun t1 t2
+tcIfaceType (IfaceTupleTy s i tks) = tcIfaceTupleTy s i tks
tcIfaceType (IfaceTyConApp tc tks) = do { tc' <- tcIfaceTyCon tc
; tks' <- tcIfaceTcArgs tks
; return (mkTyConApp tc' tks') }
@@ -842,6 +844,34 @@ tcIfaceKind k = tcIfaceType k
tcIfaceKindFun :: IfaceKind -> IfaceKind -> IfL Type
tcIfaceKindFun t1 t2 = do { t1' <- tcIfaceKind t1; t2' <- tcIfaceKind t2; return (FunTy t1' t2') }
+tcIfaceTupleTy :: TupleSort -> IfaceTyConInfo -> IfaceTcArgs -> IfL Type
+tcIfaceTupleTy sort info args
+ = do { args' <- tcIfaceTcArgs args
+ ; let arity = length args'
+ ; base_tc <- tcTupleTyCon sort arity
+ ; case info of
+ NoIfaceTyConInfo
+ -> return (mkTyConApp base_tc args')
+
+ IfacePromotedTyCon
+ | Just tc <- promotableTyCon_maybe base_tc
+ -> return (mkTyConApp tc args')
+ | otherwise
+ -> panic "tcIfaceTupleTy" (ppr base_tc)
+
+ IfacePromotedDataCon
+ -> do { let tc = promoteDataCon (tyConSingleDataCon base_tc)
+ kind_args = map typeKind args'
+ ; return (mkTyConApp tc (kind_args ++ args')) } }
+
+tcTupleTyCon :: TupleSort -> Arity -> IfL TyCon
+tcTupleTyCon sort arity
+ = case sort of
+ ConstraintTuple -> do { thing <- tcIfaceGlobal (cTupleTyConName arity)
+ ; return (tyThingTyCon thing) }
+ BoxedTuple -> return (tupleTyCon Boxed arity)
+ UnboxedTuple -> return (tupleTyCon Unboxed arity)
+
tcIfaceTcArgs :: IfaceTcArgs -> IfL [Type]
tcIfaceTcArgs args
= case args of
@@ -942,15 +972,15 @@ tcIfaceExpr (IfaceFCall cc ty) = do
dflags <- getDynFlags
return (Var (mkFCallId dflags u cc ty'))
-tcIfaceExpr (IfaceTuple boxity args) = do
- args' <- mapM tcIfaceExpr args
- -- Put the missing type arguments back in
- let con_args = map (Type . exprType) args' ++ args'
- return (mkApps (Var con_id) con_args)
+tcIfaceExpr (IfaceTuple sort args)
+ = do { args' <- mapM tcIfaceExpr args
+ ; tc <- tcTupleTyCon sort arity
+ ; let con_args = map (Type . exprType) args' ++ args'
+ -- Put the missing type arguments back in
+ con_id = dataConWorkId (tyConSingleDataCon tc)
+ ; return (mkApps (Var con_id) con_args) }
where
arity = length args
- con_id = dataConWorkId (tupleCon boxity arity)
-
tcIfaceExpr (IfaceLam (bndr, os) body)
= bindIfaceBndr bndr $ \bndr' ->
@@ -1059,7 +1089,7 @@ tcIfaceLit :: Literal -> IfL Literal
-- so tcIfaceLit just fills in the type.
-- See Note [Integer literals] in Literal
tcIfaceLit (LitInteger i _)
- = do t <- tcIfaceTyCon (IfaceTc integerTyConName)
+ = do t <- tcIfaceTyConByName integerTyConName
return (mkLitInteger i (mkTyConTy t))
tcIfaceLit lit = return lit
@@ -1237,6 +1267,7 @@ tcIfaceGlobal name
-- sure the instances and RULES of this thing (particularly TyCon) are loaded
-- Imagine: f :: Double -> Double
= do { ifCheckWiredInThing thing; return thing }
+
| otherwise
= do { env <- getGblEnv
; case if_rec_types env of { -- Note [Tying the knot]
@@ -1279,20 +1310,25 @@ tcIfaceGlobal name
-- Because if M.hs also has M.hs-boot, M.T will *already be* in the HPT, but in its
-- emasculated form (e.g. lacking data constructors).
+tcIfaceTyConByName :: IfExtName -> IfL TyCon
+tcIfaceTyConByName name
+ = do { thing <- tcIfaceGlobal name
+ ; return (tyThingTyCon thing) }
+
tcIfaceTyCon :: IfaceTyCon -> IfL TyCon
-tcIfaceTyCon itc
- = do {
- ; thing <- tcIfaceGlobal (ifaceTyConName itc)
- ; case itc of
- IfaceTc _ -> return $ tyThingTyCon thing
- IfacePromotedDataCon _ -> return $ promoteDataCon $ tyThingDataCon thing
- IfacePromotedTyCon name ->
- let ktycon tc
- | isSuperKind (tyConKind tc) = return tc
- | Just prom_tc <- promotableTyCon_maybe tc = return prom_tc
- | otherwise = pprPanic "tcIfaceTyCon" (ppr name $$ ppr thing)
- in ktycon (tyThingTyCon thing)
- }
+tcIfaceTyCon (IfaceTyCon name info)
+ = do { thing <- tcIfaceGlobal name
+ ; case info of
+ NoIfaceTyConInfo -> return (tyThingTyCon thing)
+ IfacePromotedDataCon -> return (promoteDataCon (tyThingDataCon thing))
+ -- Same Name as its underlying DataCon
+ IfacePromotedTyCon -> return (promote_tc (tyThingTyCon thing)) }
+ -- Same Name as its underlying TyCon
+ where
+ promote_tc tc
+ | Just prom_tc <- promotableTyCon_maybe tc = prom_tc
+ | isSuperKind (tyConKind tc) = tc
+ | otherwise = pprPanic "tcIfaceTyCon" (ppr name $$ ppr tc)
tcIfaceCoAxiom :: Name -> IfL (CoAxiom Branched)
tcIfaceCoAxiom name = do { thing <- tcIfaceGlobal name