-mk_edges (TyD (TyData ctxt name _ condecls derivs _ _))
- = (uniqueOf name, set_to_bag (get_ctxt ctxt `unionUniqSets`
- get_cons condecls `unionUniqSets`
- get_deriv derivs))
-
-mk_edges (TyD (TyNew ctxt name _ condecl derivs _ _))
- = (uniqueOf name, set_to_bag (get_ctxt ctxt `unionUniqSets`
- get_con condecl `unionUniqSets`
- get_deriv derivs))
-
-mk_edges (TyD (TySynonym name _ rhs _))
- = (uniqueOf name, set_to_bag (get_ty rhs))
-
-mk_edges (ClD (ClassDecl ctxt name _ sigs _ _ _))
- = (uniqueOf name, set_to_bag (get_ctxt ctxt `unionUniqSets` get_sigs sigs))
-
-get_ctxt ctxt
- = unionManyUniqSets (map (set_name.fst) ctxt)
-
-get_deriv Nothing = emptyUniqSet
-get_deriv (Just clss) = unionManyUniqSets (map set_name clss)
-
-get_cons cons
- = unionManyUniqSets (map get_con cons)
-
-get_con (ConDecl _ btys _)
- = unionManyUniqSets (map get_bty btys)
-get_con (ConOpDecl bty1 _ bty2 _)
- = unionUniqSets (get_bty bty1) (get_bty bty2)
-get_con (NewConDecl _ ty _)
- = get_ty ty
-get_con (RecConDecl _ nbtys _)
- = unionManyUniqSets (map (get_bty.snd) nbtys)
-
-get_bty (Banged ty) = get_ty ty
-get_bty (Unbanged ty) = get_ty ty
-
-get_ty (MonoTyVar name)
- = if isTvOcc (nameOccName name) then emptyUniqSet else set_name name
-get_ty (MonoTyApp ty1 ty2)
- = unionUniqSets (get_ty ty1) (get_ty ty2)
-get_ty (MonoFunTy ty1 ty2)
- = unionUniqSets (get_ty ty1) (get_ty ty2)
-get_ty (MonoListTy tc ty)
- = set_name tc `unionUniqSets` get_ty ty
-get_ty (MonoTupleTy tc tys)
- = set_name tc `unionUniqSets` get_tys tys
-get_ty (HsForAllTy _ ctxt mty)
- = get_ctxt ctxt `unionUniqSets` get_ty mty
-get_ty other = panic "TcTyClsDecls:get_ty"
-
-get_tys tys
- = unionManyUniqSets (map get_ty tys)
-
-get_sigs sigs
- = unionManyUniqSets (map get_sig sigs)
- where
- get_sig (ClassOpSig _ ty _ _) = get_ty ty
- get_sig other = panic "TcTyClsDecls:get_sig"
-
-set_name name = unitUniqSet (uniqueOf name)
-
-set_to_bag set = listToBag (uniqSetToList set)
+tcSynDecls :: (Name -> ArgVrcs) -> [LTyClDecl Name] -> TcM [TyThing]
+tcSynDecls calc_vrcs [] = return []
+tcSynDecls calc_vrcs (decl : decls)
+ = do { syn_tc <- addLocM (tcSynDecl calc_vrcs) decl
+ ; syn_tcs <- tcExtendGlobalEnv [syn_tc] (tcSynDecls calc_vrcs decls)
+ ; return (syn_tc : syn_tcs) }
+
+tcSynDecl calc_vrcs
+ (TySynonym {tcdLName = L _ tc_name, tcdTyVars = tvs, tcdSynRhs = rhs_ty})
+ = tcTyVarBndrs tvs $ \ tvs' -> do
+ { traceTc (text "tcd1" <+> ppr tc_name)
+ ; rhs_ty' <- tcHsKindedType rhs_ty
+ ; return (ATyCon (buildSynTyCon tc_name tvs' rhs_ty' (calc_vrcs tc_name))) }
+
+--------------------
+tcTyClDecl :: (Name -> ArgVrcs) -> (Name -> RecFlag)
+ -> TyClDecl Name -> TcM TyThing
+
+tcTyClDecl calc_vrcs calc_isrec decl
+ = tcAddDeclCtxt decl (tcTyClDecl1 calc_vrcs calc_isrec decl)
+
+tcTyClDecl1 calc_vrcs calc_isrec
+ (TyData {tcdND = new_or_data, tcdCtxt = ctxt, tcdTyVars = tvs,
+ tcdLName = L _ tc_name, tcdCons = cons})
+ = tcTyVarBndrs tvs $ \ tvs' -> do
+ { ctxt' <- tcHsKindedContext ctxt
+ ; want_generic <- doptM Opt_Generics
+ ; tycon <- fixM (\ tycon -> do
+ { data_cons <- mappM (addLocM (tcConDecl new_or_data tycon tvs' ctxt')) cons
+ ; let tc_rhs = case new_or_data of
+ DataType -> mkDataTyConRhs data_cons
+ NewType -> ASSERT( isSingleton data_cons )
+ mkNewTyConRhs (head data_cons)
+ ; buildAlgTyCon tc_name tvs' ctxt'
+ tc_rhs arg_vrcs is_rec
+ (want_generic && canDoGenerics data_cons)
+ })
+ ; return (ATyCon tycon)
+ }
+ where
+ arg_vrcs = calc_vrcs tc_name
+ is_rec = calc_isrec tc_name
+
+tcTyClDecl1 calc_vrcs calc_isrec
+ (ClassDecl {tcdLName = L _ class_name, tcdTyVars = tvs,
+ tcdCtxt = ctxt, tcdMeths = meths,
+ tcdFDs = fundeps, tcdSigs = sigs} )
+ = tcTyVarBndrs tvs $ \ tvs' -> do
+ { ctxt' <- tcHsKindedContext ctxt
+ ; fds' <- mappM (addLocM tc_fundep) fundeps
+ ; sig_stuff <- tcClassSigs class_name sigs meths
+ ; clas <- fixM (\ clas ->
+ let -- This little knot is just so we can get
+ -- hold of the name of the class TyCon, which we
+ -- need to look up its recursiveness and variance
+ tycon_name = tyConName (classTyCon clas)
+ tc_isrec = calc_isrec tycon_name
+ tc_vrcs = calc_vrcs tycon_name
+ in
+ buildClass class_name tvs' ctxt' fds'
+ sig_stuff tc_isrec tc_vrcs)
+ ; return (AClass clas) }
+ where
+ 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 :: NewOrData -> TyCon -> [TyVar] -> ThetaType
+ -> ConDecl Name -> TcM DataCon
+
+tcConDecl new_or_data tycon tyvars ctxt
+ (ConDecl name ex_tvs ex_ctxt details)
+ = tcTyVarBndrs ex_tvs $ \ ex_tvs' -> do
+ { ex_ctxt' <- tcHsKindedContext ex_ctxt
+ ; unbox_strict <- doptM Opt_UnboxStrictFields
+ ; let
+ tc_datacon field_lbls btys
+ = do { let { ubtys = map unLoc btys }
+ ; arg_tys <- mappM (tcHsKindedType . getBangType) ubtys
+ ; buildDataCon (unLoc name)
+ (argStrictness unbox_strict tycon ubtys arg_tys)
+ (map unLoc field_lbls)
+ tyvars ctxt ex_tvs' ex_ctxt'
+ arg_tys tycon }
+ ; case details of
+ PrefixCon btys -> tc_datacon [] btys
+ InfixCon bty1 bty2 -> tc_datacon [] [bty1,bty2]
+ RecCon fields -> do { checkTc (null ex_tvs') (exRecConErr name)
+ ; let { (field_names, btys) = unzip fields }
+ ; tc_datacon field_names btys } }
+
+argStrictness :: Bool -- True <=> -funbox-strict_fields
+ -> TyCon -> [BangType Name]
+ -> [TcType] -> [StrictnessMark]
+argStrictness unbox_strict tycon btys arg_tys
+ = zipWith (chooseBoxingStrategy unbox_strict tycon)
+ arg_tys
+ (map getBangStrictness btys ++ repeat HsNoBang)
+
+-- 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
+ where
+ can_unbox = case splitTyConApp_maybe arg_ty of
+ Nothing -> False
+ Just (arg_tycon, _) -> not (isRecursiveTyCon tycon) &&
+ isProductTyCon arg_tycon