X-Git-Url: http://git.megacz.com/?p=ghc-hetmet.git;a=blobdiff_plain;f=compiler%2Fiface%2FBuildTyCl.lhs;h=738a5e33bfcd9ff46e45160406f24bfe060e2e82;hp=707de1cbf73f1be46606d1c0cfacdc59cb135779;hb=215ce9f15215399ce30ae55c9521087847d78646;hpb=b1ab4b8a607addc4d097588db5761313c996a41f diff --git a/compiler/iface/BuildTyCl.lhs b/compiler/iface/BuildTyCl.lhs index 707de1c..738a5e3 100644 --- a/compiler/iface/BuildTyCl.lhs +++ b/compiler/iface/BuildTyCl.lhs @@ -7,29 +7,28 @@ module BuildTyCl ( buildSynTyCon, buildAlgTyCon, buildDataCon, buildClass, - mkAbstractTyConRhs, mkOpenDataTyConRhs, mkOpenNewTyConRhs, - mkNewTyConRhs, mkDataTyConRhs + mkAbstractTyConRhs, mkOpenDataTyConRhs, + mkNewTyConRhs, mkDataTyConRhs, setAssocFamilyPermutation ) where #include "HsVersions.h" import IfaceEnv -import TcRnMonad import DataCon import Var import VarSet -import TysWiredIn import BasicTypes import Name -import OccName import MkId import Class import TyCon import Type import Coercion -import Data.List +import TcRnMonad +import Util ( count ) +import Outputable \end{code} @@ -37,22 +36,23 @@ import Data.List ------------------------------------------------------ buildSynTyCon :: Name -> [TyVar] -> SynTyConRhs + -> Kind -- Kind of the RHS -> Maybe (TyCon, [Type]) -- family instance if applicable -> TcRnIf m n TyCon -buildSynTyCon tc_name tvs rhs@(OpenSynTyCon rhs_ki _) _ +buildSynTyCon tc_name tvs rhs@(OpenSynTyCon {}) rhs_kind _ = let - kind = mkArrowKinds (map tyVarKind tvs) rhs_ki + kind = mkArrowKinds (map tyVarKind tvs) rhs_kind in return $ mkSynTyCon tc_name kind tvs rhs NoParentTyCon -buildSynTyCon tc_name tvs rhs@(SynonymTyCon rhs_ty) mb_family +buildSynTyCon tc_name tvs rhs@(SynonymTyCon {}) rhs_kind mb_family = do { -- We need to tie a knot as the coercion of a data instance depends -- on the instance representation tycon and vice versa. ; tycon <- fixM (\ tycon_rec -> do { parent <- mkParentInfo mb_family tc_name tvs tycon_rec ; let { tycon = mkSynTyCon tc_name kind tvs rhs parent - ; kind = mkArrowKinds (map tyVarKind tvs) (typeKind rhs_ty) + ; kind = mkArrowKinds (map tyVarKind tvs) rhs_kind } ; return tycon }) @@ -76,9 +76,8 @@ buildAlgTyCon tc_name tvs stupid_theta rhs is_rec want_generics gadt_syn ; tycon <- fixM (\ tycon_rec -> do { parent <- mkParentInfo mb_family tc_name tvs tycon_rec ; let { tycon = mkAlgTyCon tc_name kind tvs stupid_theta rhs - fields parent is_rec want_generics gadt_syn - ; kind = mkArrowKinds (map tyVarKind tvs) liftedTypeKind - ; fields = mkTyConSelIds tycon rhs + parent is_rec want_generics gadt_syn + ; kind = mkArrowKinds (map tyVarKind tvs) liftedTypeKind } ; return tycon }) @@ -90,7 +89,7 @@ buildAlgTyCon tc_name tvs stupid_theta rhs is_rec want_generics gadt_syn -- -- (1) create a coercion that identifies the family instance type and the -- representation type from Step (1); ie, it is of the form --- `Co tvs :: F ts :=: R tvs', where `Co' is the name of the coercion, +-- `Co tvs :: F ts ~ R tvs', where `Co' is the name of the coercion, -- `F' the family tycon and `R' the (derived) representation tycon, -- and -- (2) produce a `TyConParent' value containing the parent and coercion @@ -115,14 +114,22 @@ mkAbstractTyConRhs :: AlgTyConRhs mkAbstractTyConRhs = AbstractTyCon mkOpenDataTyConRhs :: AlgTyConRhs -mkOpenDataTyConRhs = OpenTyCon Nothing False - -mkOpenNewTyConRhs :: AlgTyConRhs -mkOpenNewTyConRhs = OpenTyCon Nothing True +mkOpenDataTyConRhs = OpenTyCon Nothing mkDataTyConRhs :: [DataCon] -> AlgTyConRhs mkDataTyConRhs cons - = DataTyCon { data_cons = cons, is_enum = all isNullarySrcDataCon cons } + = DataTyCon { + data_cons = cons, + is_enum = -- We define datatypes with no constructors to not be + -- enumerations; this fixes trac #2578, Otherwise we + -- end up generating an empty table for + -- __closure_tbl + -- which is used by tagToEnum# to map Int# to constructors + -- in an enumeration. The empty table apparently upset + -- the linker. + not (null cons) && + all isNullarySrcDataCon cons + } mkNewTyConRhs :: Name -> TyCon -> DataCon -> TcRnIf m n AlgTyConRhs -- Monadic because it makes a Name for the coercion TyCon @@ -135,22 +142,29 @@ mkNewTyConRhs tycon_name tycon con = Just co_tycon | otherwise = Nothing + ; traceIf (text "mkNewTyConRhs" <+> ppr cocon_maybe) ; return (NewTyCon { data_con = con, nt_rhs = rhs_ty, nt_etad_rhs = (etad_tvs, etad_rhs), - nt_co = cocon_maybe, + nt_co = cocon_maybe } ) } -- Coreview looks through newtypes with a Nothing -- for nt_co, or uses explicit coercions otherwise - nt_rep = mkNewTyConRep tycon rhs_ty }) } where -- If all_coercions is True then we use coercions for all newtypes -- otherwise we use coercions for recursive newtypes and look through -- non-recursive newtypes all_coercions = True tvs = tyConTyVars tycon - rhs_ty = head (dataConInstOrigArgTys con (mkTyVarTys tvs)) + inst_con_ty = applyTys (dataConUserType con) (mkTyVarTys tvs) + rhs_ty = ASSERT( isFunTy inst_con_ty ) funArgTy inst_con_ty -- Instantiate the data con with the -- type variables from the tycon + -- NB: a newtype DataCon has a type that must look like + -- forall tvs. -> T tvs + -- Note that we *can't* use dataConInstOrigArgTys here because + -- the newtype arising from class Foo a => Bar a where {} + -- has a single argument (Foo a) that is a *type class*, so + -- dataConInstOrigArgTys returns []. etad_tvs :: [TyVar] -- Matched lazily, so that mkNewTypeCoercion can etad_rhs :: Type -- return a TyCon without pulling on rhs_ty @@ -168,58 +182,30 @@ mkNewTyConRhs tycon_name tycon con eta_reduce tvs ty = (reverse tvs, ty) -mkNewTyConRep :: TyCon -- The original type constructor - -> Type -- The arg type of its constructor - -> Type -- Chosen representation type --- The "representation type" is guaranteed not to be another newtype --- at the outermost level; but it might have newtypes in type arguments - --- Find the representation type for this newtype TyCon --- Remember that the representation type is the *ultimate* representation --- type, looking through other newtypes. --- --- splitTyConApp_maybe no longer looks through newtypes, so we must --- deal explicitly with this case --- --- The trick is to to deal correctly with recursive newtypes --- such as newtype T = MkT T - -mkNewTyConRep tc rhs_ty - | null (tyConDataCons tc) = unitTy - -- External Core programs can have newtypes with no data constructors - | otherwise = go [tc] rhs_ty - where - -- Invariant: tcs have been seen before - go tcs rep_ty - = case splitTyConApp_maybe rep_ty of - Just (tc, tys) - | tc `elem` tcs -> unitTy -- Recursive loop - | isNewTyCon tc -> - if isRecursiveTyCon tc then - go (tc:tcs) (substTyWith tvs tys rhs_ty) - else - substTyWith tvs tys rhs_ty - where - (tvs, rhs_ty) = newTyConRhs tc - - other -> rep_ty +setAssocFamilyPermutation :: [TyVar] -> TyThing -> TyThing +setAssocFamilyPermutation clas_tvs (ATyCon tc) + = ATyCon (setTyConArgPoss clas_tvs tc) +setAssocFamilyPermutation _clas_tvs other + = pprPanic "setAssocFamilyPermutation" (ppr other) + ------------------------------------------------------ buildDataCon :: Name -> Bool - -> [StrictnessMark] + -> [HsBang] -> [Name] -- Field labels -> [TyVar] -> [TyVar] -- Univ and ext -> [(TyVar,Type)] -- Equality spec -> ThetaType -- Does not include the "stupid theta" -- or the GADT equalities - -> [Type] -> TyCon + -> [Type] -> Type -- Argument and result types + -> TyCon -- Rep tycon -> TcRnIf m n DataCon -- A wrapper for DataCon.mkDataCon that -- a) makes the worker Id -- b) makes the wrapper Id if necessary, including -- allocating its unique (hence monadic) buildDataCon src_name declared_infix arg_stricts field_lbls - univ_tvs ex_tvs eq_spec ctxt arg_tys tycon + univ_tvs ex_tvs eq_spec ctxt arg_tys res_ty rep_tycon = do { wrap_name <- newImplicitBinder src_name mkDataConWrapperOcc ; work_name <- newImplicitBinder src_name mkDataConWorkerOcc -- This last one takes the name of the data constructor in the source @@ -227,21 +213,22 @@ buildDataCon src_name declared_infix arg_stricts field_lbls -- space, and puts it into the VarName name space ; let - stupid_ctxt = mkDataConStupidTheta tycon arg_tys univ_tvs + stupid_ctxt = mkDataConStupidTheta rep_tycon arg_tys univ_tvs data_con = mkDataCon src_name declared_infix arg_stricts field_lbls univ_tvs ex_tvs eq_spec ctxt - arg_tys tycon + arg_tys res_ty rep_tycon stupid_ctxt dc_ids dc_ids = mkDataConIds wrap_name work_name data_con - ; returnM data_con } + ; return data_con } -- The stupid context for a data constructor should be limited to -- the type variables mentioned in the arg_tys -- ToDo: Or functionally dependent on? -- This whole stupid theta thing is, well, stupid. +mkDataConStupidTheta :: TyCon -> [Type] -> [TyVar] -> [PredType] mkDataConStupidTheta tycon arg_tys univ_tvs | null stupid_theta = [] -- The common case | otherwise = filter in_arg_tys stupid_theta @@ -254,65 +241,82 @@ mkDataConStupidTheta tycon arg_tys univ_tvs arg_tyvars = tyVarsOfTypes arg_tys in_arg_tys pred = not $ isEmptyVarSet $ tyVarsOfPred pred `intersectVarSet` arg_tyvars - ------------------------------------------------------- -mkTyConSelIds :: TyCon -> AlgTyConRhs -> [Id] -mkTyConSelIds tycon rhs - = [ mkRecordSelId tycon fld - | fld <- nub (concatMap dataConFieldLabels (visibleDataCons rhs)) ] - -- We'll check later that fields with the same name - -- from different constructors have the same type. \end{code} ------------------------------------------------------ \begin{code} -buildClass :: Name -> [TyVar] -> ThetaType +buildClass :: Bool -- True <=> do not include unfoldings + -- on dict selectors + -- Used when importing a class without -O + -> Name -> [TyVar] -> ThetaType -> [FunDep TyVar] -- Functional dependencies -> [TyThing] -- Associated types -> [(Name, DefMeth, Type)] -- Method info -> RecFlag -- Info for type constructor -> TcRnIf m n Class -buildClass class_name tvs sc_theta fds ats sig_stuff tc_isrec - = do { tycon_name <- newImplicitBinder class_name mkClassTyConOcc +buildClass no_unf class_name tvs sc_theta fds ats sig_stuff tc_isrec + = do { traceIf (text "buildClass") + ; tycon_name <- newImplicitBinder class_name mkClassTyConOcc ; datacon_name <- newImplicitBinder class_name mkClassDataConOcc -- The class name is the 'parent' for this datacon, not its tycon, -- because one should import the class to get the binding for -- the datacon - ; sc_sel_names <- mapM (newImplicitBinder class_name . mkSuperDictSelOcc) - [1..length sc_theta] - -- We number off the superclass selectors, 1, 2, 3 etc so that we - -- can construct names for the selectors. Thus + + ; fixM (\ rec_clas -> do { -- Only name generation inside loop + + let { rec_tycon = classTyCon rec_clas + ; op_tys = [ty | (_,_,ty) <- sig_stuff] + ; op_names = [op | (op,_,_) <- sig_stuff] + ; op_items = [ (mkDictSelId no_unf op_name rec_clas, dm_info) + | (op_name, dm_info, _) <- sig_stuff ] } + -- Build the selector id and default method id + + ; let n_value_preds = count (not . isEqPred) sc_theta + all_value_preds = n_value_preds == length sc_theta + -- We only make selectors for the *value* superclasses, + -- not equality predicates + + ; sc_sel_names <- mapM (newImplicitBinder class_name . mkSuperDictSelOcc) + [1..n_value_preds] + ; let sc_sel_ids = [mkDictSelId no_unf sc_name rec_clas | sc_name <- sc_sel_names] + -- We number off the Dict superclass selectors, 1, 2, 3 etc so that we + -- can construct names for the selectors. Thus -- class (C a, C b) => D a b where ... -- gives superclass selectors -- D_sc1, D_sc2 -- (We used to call them D_C, but now we can have two different -- superclasses both called C!) - - ; fixM (\ rec_clas -> do { -- Only name generation inside loop - - let { rec_tycon = classTyCon rec_clas - ; op_tys = [ty | (_,_,ty) <- sig_stuff] - ; sc_tys = mkPredTys sc_theta - ; dict_component_tys = sc_tys ++ op_tys - ; sc_sel_ids = [mkDictSelId sc_name rec_clas | sc_name <- sc_sel_names] - ; op_items = [ (mkDictSelId op_name rec_clas, dm_info) - | (op_name, dm_info, _) <- sig_stuff ] } - -- Build the selector id and default method id + -- + + ; let use_newtype = (n_value_preds + length sig_stuff == 1) && all_value_preds + -- Use a newtype if the data constructor has + -- (a) exactly one value field + -- (b) no existential or equality-predicate fields + -- i.e. exactly one operation or superclass taken together + -- See note [Class newtypes and equality predicates] + + -- We play a bit fast and loose by treating the superclasses + -- as ordinary arguments. That means that in the case of + -- class C a => D a + -- we don't get a newtype with no arguments! + args = sc_sel_names ++ op_names + arg_tys = map mkPredTy sc_theta ++ op_tys ; dict_con <- buildDataCon datacon_name False -- Not declared infix - (map (const NotMarkedStrict) dict_component_tys) - [{- No labelled fields -}] + (map (const HsNoBang) args) + [{- No fields -}] tvs [{- no existentials -}] - [{- No equalities -}] [{-No context-}] - dict_component_tys + [{- No GADT equalities -}] [{- No theta -}] + arg_tys + (mkTyConApp rec_tycon (mkTyVarTys tvs)) rec_tycon - ; rhs <- case dict_component_tys of - [rep_ty] -> mkNewTyConRhs tycon_name rec_tycon dict_con - other -> return (mkDataTyConRhs [dict_con]) + ; rhs <- if use_newtype + then mkNewTyConRhs tycon_name rec_tycon dict_con + else return (mkDataTyConRhs [dict_con]) ; let { clas_kind = mkArrowKinds (map tyVarKind tvs) liftedTypeKind @@ -327,11 +331,29 @@ buildClass class_name tvs sc_theta fds ats sig_stuff tc_isrec -- newtype like a synonym, but that will lead to an infinite -- type] ; atTyCons = [tycon | ATyCon tycon <- ats] + + ; result = mkClass class_name tvs fds + sc_theta sc_sel_ids atTyCons + op_items tycon } - ; return (mkClass class_name tvs fds - sc_theta sc_sel_ids atTyCons op_items - tycon) + ; traceIf (text "buildClass" <+> ppr tycon) + ; return result })} \end{code} +Note [Class newtypes and equality predicates] +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +Consider + class (a ~ F b) => C a b where + op :: a -> b + +We cannot represent this by a newtype, even though it's not +existential, and there's only one value field, because we do +capture an equality predicate: + + data C a b where + MkC :: forall a b. (a ~ F b) => (a->b) -> C a b + +We need to access this equality predicate when we get passes a C +dictionary. See Trac #2238