diff options
author | Simon Peyton Jones <simonpj@microsoft.com> | 2015-05-11 23:19:14 +0100 |
---|---|---|
committer | Simon Peyton Jones <simonpj@microsoft.com> | 2015-05-18 13:44:15 +0100 |
commit | ffc21506894c7887d3620423aaf86bc6113a1071 (patch) | |
tree | c36353b98b3e5eeb9a257b39d95e56f441aa36da /compiler/iface | |
parent | 76024fdbad0f6daedd8757b974eace3314bd4eec (diff) | |
download | haskell-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.hs | 16 | ||||
-rw-r--r-- | compiler/iface/BuildTyCl.hs | 4 | ||||
-rw-r--r-- | compiler/iface/IfaceSyn.hs | 9 | ||||
-rw-r--r-- | compiler/iface/IfaceType.hs | 154 | ||||
-rw-r--r-- | compiler/iface/TcIface.hs | 84 |
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 |