- tycon = mkAlgTyCon tycon_name tycon_kind tyvars ctxt argvrcs
- data_cons sel_ids flavour
- (rec_tycon tycon_name flavour) gen_info
-
- DataTyDetails ctxt data_cons sel_ids gen_info = lookupNameEnv_NF rec_details tycon_name
-
- tycon_kind = lookupNameEnv_NF kenv tycon_name
- tyvars = mkTyClTyVars tycon_kind tyvar_names
- argvrcs = lookupWithDefaultFM rec_vrcs bogusVrcs tycon
-
- -- Watch out! mkTyConApp asks whether the tycon is a NewType,
- -- so flavour has to be able to answer this question without consulting rec_details
- flavour = case data_or_new of
- NewType -> NewTyCon (mkNewTyConRep tycon)
- DataType | all_nullary data_cons -> EnumTyCon
- | otherwise -> DataTyCon
-
- all_nullary (DataCons cons) = all (null . dataConOrigArgTys) cons
- all_nullary other = False -- Safe choice for unknown data types
- -- NB (null . dataConOrigArgTys). It used to say isNullaryDataCon
- -- but that looks at the *representation* arity, and that in turn
- -- depends on deciding whether to unpack the args, and that
- -- depends on whether it's a data type or a newtype --- so
- -- in the recursive case we can get a loop. This version is simple!
-
-buildTyConOrClass rec_tycon kenv rec_vrcs rec_details
- (ForeignType {tcdName = tycon_name, tcdExtName = tycon_ext_name})
- = ATyCon (mkForeignTyCon tycon_name tycon_ext_name liftedTypeKind 0 [])
-
-buildTyConOrClass rec_tycon kenv rec_vrcs rec_details
- (ClassDecl {tcdName = class_name, tcdTyVars = tyvar_names, tcdFDs = fundeps} )
- = AClass clas
+ tc_fundep (tvs1, tvs2) = do { tvs1' <- mappM tcLookupTyVar tvs1 ;
+ ; tvs2' <- mappM tcLookupTyVar tvs2 ;
+ ; return (tvs1', tvs2') }
+
+
+tcTyClDecl1 calc_vrcs calc_isrec
+ (ForeignType {tcdLName = L _ tc_name, tcdExtName = tc_ext_name})
+ = returnM (ATyCon (mkForeignTyCon tc_name tc_ext_name liftedTypeKind 0 []))
+
+-----------------------------------
+tcConDecl :: Bool -- True <=> -funbox-strict_fields
+ -> NewOrData -> TyCon -> [TyVar]
+ -> ConDecl Name -> TcM DataCon
+
+tcConDecl unbox_strict NewType tycon tc_tvs -- Newtypes
+ (ConDecl name ex_tvs ex_ctxt details)
+ = ASSERT( null ex_tvs && null (unLoc ex_ctxt) )
+ do { let tc_datacon field_lbls arg_ty
+ = do { arg_ty' <- tcHsKindedType arg_ty -- No bang on newtype
+ ; buildDataCon (unLoc name) False {- Prefix -}
+ True {- Vanilla -} [NotMarkedStrict]
+ (map unLoc field_lbls)
+ tc_tvs [] [arg_ty']
+ tycon (mkTyVarTys tc_tvs) }
+ ; case details of
+ PrefixCon [arg_ty] -> tc_datacon [] arg_ty
+ RecCon [(field_lbl, arg_ty)] -> tc_datacon [field_lbl] arg_ty }
+
+tcConDecl unbox_strict DataType tycon tc_tvs -- Ordinary data types
+ (ConDecl name ex_tvs ex_ctxt details)
+ = tcTyVarBndrs ex_tvs $ \ ex_tvs' -> do
+ { ex_ctxt' <- tcHsKindedContext ex_ctxt
+ ; let
+ is_vanilla = null ex_tvs && null (unLoc ex_ctxt)
+ -- Vanilla iff no ex_tvs and no context
+
+ tc_datacon is_infix field_lbls btys
+ = do { let { bangs = map getBangStrictness btys }
+ ; arg_tys <- mappM tcHsBangType btys
+ ; buildDataCon (unLoc name) is_infix is_vanilla
+ (argStrictness unbox_strict tycon bangs arg_tys)
+ (map unLoc field_lbls)
+ (tc_tvs ++ ex_tvs')
+ ex_ctxt'
+ arg_tys
+ tycon (mkTyVarTys tc_tvs) }
+ ; case details of
+ PrefixCon btys -> tc_datacon False [] btys
+ InfixCon bty1 bty2 -> tc_datacon True [] [bty1,bty2]
+ RecCon fields -> do { checkTc is_vanilla (exRecConErr name)
+ ; let { (field_names, btys) = unzip fields }
+ ; tc_datacon False field_names btys } }
+
+tcConDecl unbox_strict DataType tycon tc_tvs -- GADTs
+ decl@(GadtDecl name con_ty)
+ = do { traceTc (text "tcConDecl" <+> ppr name)
+ ; (tvs, theta, bangs, arg_tys, tc, res_tys) <- tcLHsConSig con_ty
+
+ ; traceTc (text "tcConDecl1" <+> ppr name)
+ ; let -- Now dis-assemble the type, and check its form
+ is_vanilla = null theta && mkTyVarTys tvs `tcEqTypes` res_tys
+
+ -- Vanilla datacons guarantee to use the same
+ -- type variables as the parent tycon
+ (tvs', arg_tys', res_tys')
+ | is_vanilla = (tc_tvs, substTys subst arg_tys, substTys subst res_tys)
+ | otherwise = (tvs, arg_tys, res_tys)
+ subst = zipTopTvSubst tvs (mkTyVarTys tc_tvs)
+
+ ; traceTc (text "tcConDecl3" <+> ppr name)
+ ; buildDataCon (unLoc name) False {- Not infix -} is_vanilla
+ (argStrictness unbox_strict tycon bangs arg_tys)
+ [{- No field labels -}]
+ tvs' theta arg_tys' tycon res_tys' }
+
+-------------------
+tcStupidTheta :: LHsContext Name -> [LConDecl Name] -> TcM (Maybe ThetaType)
+-- For GADTs we don't allow a context on the data declaration
+-- whereas for standard Haskell style data declarations, we do
+tcStupidTheta ctxt (L _ (ConDecl _ _ _ _) : _)
+ = do { theta <- tcHsKindedContext ctxt; return (Just theta) }
+tcStupidTheta ctxt other -- Includes an empty constructor list
+ = ASSERT( null (unLoc ctxt) ) return Nothing
+
+-------------------
+argStrictness :: Bool -- True <=> -funbox-strict_fields
+ -> TyCon -> [HsBang]
+ -> [TcType] -> [StrictnessMark]
+argStrictness unbox_strict tycon bangs arg_tys
+ = ASSERT( length bangs == length arg_tys )
+ zipWith (chooseBoxingStrategy unbox_strict tycon) arg_tys bangs
+
+-- We attempt to unbox/unpack a strict field when either:
+-- (i) The field is marked '!!', or
+-- (ii) The field is marked '!', and the -funbox-strict-fields flag is on.
+
+chooseBoxingStrategy :: Bool -> TyCon -> TcType -> HsBang -> StrictnessMark
+chooseBoxingStrategy unbox_strict_fields tycon arg_ty bang
+ = case bang of
+ HsNoBang -> NotMarkedStrict
+ HsStrict | unbox_strict_fields && can_unbox -> MarkedUnboxed
+ HsUnbox | can_unbox -> MarkedUnboxed
+ other -> MarkedStrict