2 % (c) The AQUA Project, Glasgow University, 1996-1998
4 \section[TcTyDecls]{Typecheck type declarations}
7 module TcTyDecls ( tcTyDecl1, kcConDetails ) where
9 #include "HsVersions.h"
11 import HsSyn ( TyClDecl(..), ConDecl(..), ConDetails(..),
12 getBangType, getBangStrictness, conDetailsTys
14 import RnHsSyn ( RenamedTyClDecl, RenamedConDecl, RenamedContext )
15 import BasicTypes ( NewOrData(..), RecFlag, isRec )
17 import TcMonoType ( tcHsRecType, tcHsTyVars, tcRecTheta,
18 kcHsContext, kcHsSigType, kcHsLiftedSigType
20 import TcEnv ( tcExtendTyVarEnv,
21 tcLookupTyCon, tcLookupRecId,
22 TyThingDetails(..), RecTcEnv
24 import TcType ( tcEqType, tyVarsOfTypes, tyVarsOfPred, Type, ThetaType )
27 import DataCon ( DataCon, mkDataCon, dataConFieldLabels )
28 import MkId ( mkDataConId, mkDataConWrapId, mkRecordSelId )
31 import Name ( Name, NamedThing(..) )
33 import TyCon ( TyCon, tyConTyVars )
34 import VarSet ( intersectVarSet, isEmptyVarSet )
35 import PrelNames ( unpackCStringName, unpackCStringUtf8Name )
36 import ListSetOps ( equivClasses )
39 %************************************************************************
41 \subsection{Type checking}
43 %************************************************************************
46 tcTyDecl1 :: RecFlag -> RecTcEnv -> RenamedTyClDecl -> TcM (Name, TyThingDetails)
47 tcTyDecl1 is_rec unf_env (TySynonym {tcdName = tycon_name, tcdSynRhs = rhs})
48 = tcLookupTyCon tycon_name `thenNF_Tc` \ tycon ->
49 tcExtendTyVarEnv (tyConTyVars tycon) $
50 tcHsRecType is_rec rhs `thenTc` \ rhs_ty ->
51 -- Note tcHsRecType not tcHsRecSigType; we allow type synonyms
52 -- that aren't types; e.g. type List = []
54 -- If the RHS mentions tyvars that aren't in scope, we'll
55 -- quantify over them:
57 -- will become type T = forall a. a->a
59 -- With gla-exts that's right, but for H98 we should complain.
60 -- We can now do that here without falling into
61 -- a black hole, we still do it in rnDecl (TySynonym case)
63 returnTc (tycon_name, SynTyDetails rhs_ty)
65 tcTyDecl1 is_rec unf_env (TyData {tcdND = new_or_data, tcdCtxt = context,
66 tcdName = tycon_name, tcdCons = con_decls})
67 = tcLookupTyCon tycon_name `thenNF_Tc` \ tycon ->
69 tyvars = tyConTyVars tycon
71 tcExtendTyVarEnv tyvars $
73 -- Typecheck the pieces
74 tcRecTheta is_rec context `thenTc` \ ctxt ->
75 mapTc (tcConDecl is_rec new_or_data tycon tyvars ctxt) con_decls `thenTc` \ data_cons ->
76 tcRecordSelectors is_rec unf_env tycon data_cons `thenTc` \ sel_ids ->
77 returnTc (tycon_name, DataTyDetails ctxt data_cons sel_ids)
79 tcTyDecl1 is_rec unf_env (ForeignType {tcdName = tycon_name})
80 = returnTc (tycon_name, ForeignTyDetails)
84 %************************************************************************
86 \subsection{Kind and type check constructors}
88 %************************************************************************
91 kcConDetails :: NewOrData -> RenamedContext -> ConDetails Name -> TcM ()
92 kcConDetails new_or_data ex_ctxt details
93 = kcHsContext ex_ctxt `thenTc_`
94 mapTc_ kc_sig_type (conDetailsTys details)
96 kc_sig_type = case new_or_data of
97 DataType -> kcHsSigType
98 NewType -> kcHsLiftedSigType
99 -- Can't allow an unlifted type here, because we're effectively
100 -- going to remove the constructor while coercing it to a lifted type.
103 tcConDecl :: RecFlag -> NewOrData -> TyCon -> [TyVar] -> ThetaType -> RenamedConDecl -> TcM DataCon
105 tcConDecl is_rec new_or_data tycon tyvars ctxt (ConDecl name wkr_name ex_tvs ex_ctxt details src_loc)
106 = tcAddSrcLoc src_loc $
107 tcHsTyVars ex_tvs (kcConDetails new_or_data ex_ctxt details) $ \ ex_tyvars ->
108 tcRecTheta is_rec ex_ctxt `thenTc` \ ex_theta ->
110 VanillaCon btys -> tc_datacon ex_tyvars ex_theta btys
111 InfixCon bty1 bty2 -> tc_datacon ex_tyvars ex_theta [bty1,bty2]
112 RecCon fields -> tc_rec_con ex_tyvars ex_theta fields
114 tc_datacon ex_tyvars ex_theta btys
116 arg_stricts = map getBangStrictness btys
117 tys = map getBangType btys
119 mapTc (tcHsRecType is_rec) tys `thenTc` \ arg_tys ->
120 mk_data_con ex_tyvars ex_theta arg_stricts arg_tys []
122 tc_rec_con ex_tyvars ex_theta fields
123 = checkTc (null ex_tyvars) (exRecConErr name) `thenTc_`
124 mapTc tc_field (fields `zip` allFieldLabelTags) `thenTc` \ field_labels_s ->
126 field_labels = concat field_labels_s
127 arg_stricts = [str | (ns, bty) <- fields,
128 let str = getBangStrictness bty,
129 n <- ns -- One for each. E.g x,y,z :: !Int
132 mk_data_con ex_tyvars ex_theta arg_stricts
133 (map fieldLabelType field_labels) field_labels
135 tc_field ((field_label_names, bty), tag)
136 = tcHsRecType is_rec (getBangType bty) `thenTc` \ field_ty ->
137 returnTc [mkFieldLabel (getName name) tycon field_ty tag | name <- field_label_names]
139 mk_data_con ex_tyvars ex_theta arg_stricts arg_tys fields
141 data_con = mkDataCon name arg_stricts fields
142 tyvars (thinContext arg_tys ctxt)
145 tycon data_con_id data_con_wrap_id
147 data_con_id = mkDataConId wkr_name data_con
148 data_con_wrap_id = mkDataConWrapId data_con
152 -- The context for a data constructor should be limited to
153 -- the type variables mentioned in the arg_tys
154 thinContext arg_tys ctxt
155 = filter in_arg_tys ctxt
157 arg_tyvars = tyVarsOfTypes arg_tys
158 in_arg_tys pred = not $ isEmptyVarSet $
159 tyVarsOfPred pred `intersectVarSet` arg_tyvars
163 %************************************************************************
165 \subsection{Record selectors}
167 %************************************************************************
170 tcRecordSelectors is_rec unf_env tycon data_cons
171 -- Omit the check that the fields have consistent types if
172 -- the group is recursive; TcTyClsDecls.tcGroup will repeat
173 -- with NonRecursive once we have tied the knot
174 | isRec is_rec = returnTc sel_ids
175 | otherwise = mapTc check groups `thenTc_`
178 fields = [ field | con <- data_cons
179 , field <- dataConFieldLabels con ]
181 -- groups is list of fields that share a common name
182 groups = equivClasses cmp_name fields
183 cmp_name field1 field2 = fieldLabelName field1 `compare` fieldLabelName field2
185 sel_ids = [ mkRecordSelId tycon field unpack_id unpackUtf8_id
186 | (field : _) <- groups ]
188 check fields@(first_field_label : other_fields)
189 -- These fields all have the same name, but are from
190 -- different constructors in the data type
191 = -- Check that all the fields in the group have the same type
192 -- NB: this check assumes that all the constructors of a given
193 -- data type use the same type variables
194 checkTc (all (tcEqType field_ty) other_tys) (fieldTypeMisMatch field_name)
196 field_ty = fieldLabelType first_field_label
197 field_name = fieldLabelName first_field_label
198 other_tys = map fieldLabelType other_fields
200 unpack_id = tcLookupRecId unf_env unpackCStringName
201 unpackUtf8_id = tcLookupRecId unf_env unpackCStringUtf8Name
206 %************************************************************************
208 \subsection{Errors and contexts}
210 %************************************************************************
214 fieldTypeMisMatch field_name
215 = sep [ptext SLIT("Different constructors give different types for field"), quotes (ppr field_name)]
218 = ptext SLIT("Can't combine named fields with locally-quantified type variables")
220 (ptext SLIT("In the declaration of data constructor") <+> ppr name)