diff --git a/compiler/deSugar/DsMeta.hs b/compiler/deSugar/DsMeta.hs index 8d701af329346d27633c66cbcfc694c982c7f562..d833baf1ebb6b2848d0a58972b64f90a32151c47 100644 --- a/compiler/deSugar/DsMeta.hs +++ b/compiler/deSugar/DsMeta.hs @@ -302,7 +302,7 @@ repDataDefn tc bndrs opt_tys tv_names _cs -> failWithDs (ptext (sLit "Multiple constructors for newtype:") <+> pprQuotedList - (con_names $ unLoc $ head cons)) + (getConNames $ unLoc $ head cons)) } DataType -> do { consL <- concatMapM (repC tv_names) cons ; cons1 <- coreList conQTyConName consL @@ -623,26 +623,54 @@ repAnnProv ModuleAnnProvenance ------------------------------------------------------- repC :: [Name] -> LConDecl Name -> DsM [Core TH.ConQ] -repC _ (L _ (ConDecl { con_names = con, con_qvars = con_tvs, con_cxt = L _ [] - , con_details = details, con_res = ResTyH98 })) - | null (hsQTvBndrs con_tvs) - = do { con1 <- mapM lookupLOcc con -- See Note [Binders and occurrences] - ; mapM (\c -> repConstr c details) con1 } - -repC tvs (L _ (ConDecl { con_names = cons - , con_qvars = con_tvs, con_cxt = L _ ctxt - , con_details = details - , con_res = res_ty })) - = do { (eq_ctxt, con_tv_subst) <- mkGadtCtxt tvs res_ty +repC _ (L _ (ConDeclH98 { con_name = con + , con_qvars = Nothing, con_cxt = Nothing + , con_details = details })) + = do { con1 <- lookupLOcc con + -- See Note [Binders and occurrences] + ; mapM (\c -> repConstr c details) [con1] } + +repC _ (L _ (ConDeclH98 { con_name = con + , con_qvars = mcon_tvs, con_cxt = mcxt + , con_details = details })) + = do { let (eq_ctxt, con_tv_subst) = ([], []) + ; let con_tvs = fromMaybe (HsQTvs [] []) mcon_tvs + ; let ctxt = unLoc $ fromMaybe (noLoc []) mcxt ; let ex_tvs = HsQTvs { hsq_kvs = filterOut (in_subst con_tv_subst) (hsq_kvs con_tvs) , hsq_tvs = filterOut (in_subst con_tv_subst . hsLTyVarName) (hsq_tvs con_tvs) } - ; binds <- mapM dupBinder con_tv_subst + ; let binds = [] ; b <- dsExtendMetaEnv (mkNameEnv binds) $ -- Binds some of the con_tvs addTyVarBinds ex_tvs $ \ ex_bndrs -> -- Binds the remaining con_tvs - do { cons1 <- mapM lookupLOcc cons -- See Note [Binders and occurrences] - ; c' <- mapM (\c -> repConstr c details) cons1 + do { con1 <- lookupLOcc con -- See Note [Binders and occurrences] + ; c' <- repConstr con1 details ; ctxt' <- repContext (eq_ctxt ++ ctxt) + ; if (null (hsq_kvs ex_tvs) && null (hsq_tvs ex_tvs) + && null (eq_ctxt ++ ctxt)) + then return c' + else rep2 forallCName ([unC ex_bndrs, unC ctxt'] ++ [unC c']) } + ; return [b] + } +repC tvs (L _ (ConDeclGADT { con_names = cons + , con_type = res_ty@(HsIB { hsib_kvs = con_kvs + , hsib_tvs = con_tvns })})) + = do { (eq_ctxt, con_tv_subst) <- mkGadtCtxt tvs res_ty + ; let con_tvs = map (noLoc . UserTyVar . noLoc) con_tvns + ; let ex_tvs + = HsQTvs { hsq_kvs = filterOut (in_subst con_tv_subst) con_kvs + , hsq_tvs = filterOut + (in_subst con_tv_subst . hsLTyVarName) + con_tvs } + + ; binds <- mapM dupBinder con_tv_subst + ; b <- dsExtendMetaEnv (mkNameEnv binds) $ -- Binds some of the con_tvs + addTyVarBinds ex_tvs $ \ ex_bndrs -> -- Binds the remaining con_tvs + do { cons1 <- mapM lookupLOcc cons -- See Note [Binders and occurrences] + ; let (details,res_ty',_,_) = gadtDeclDetails res_ty + ; let doc = ptext (sLit "In the constructor for ") <+> ppr (head cons) + ; (hs_details,_res_ty) <- update_con_result doc details res_ty' + ; c' <- mapM (\c -> repConstr c hs_details) cons1 + ; ctxt' <- repContext eq_ctxt ; rep2 forallCName ([unC ex_bndrs, unC ctxt'] ++ (map unC c')) } ; return [b] } @@ -651,8 +679,37 @@ in_subst :: [(Name,Name)] -> Name -> Bool in_subst [] _ = False in_subst ((n',_):ns) n = n==n' || in_subst ns n +update_con_result :: SDoc + -> HsConDetails (LHsType Name) (Located [LConDeclField Name]) + -- Original details + -> LHsType Name -- The original result type + -> DsM (HsConDetails (LHsType Name) (Located [LConDeclField Name]), + LHsType Name) +update_con_result doc details ty + = do { let (arg_tys, res_ty) = splitHsFunType ty + -- We can finally split it up, + -- now the renamer has dealt with fixities + -- See Note [Sorting out the result type] in RdrHsSyn + + ; case details of + InfixCon {} -> pprPanic "update_con_result" (ppr ty) + -- See Note [Sorting out the result type] in RdrHsSyn + + RecCon {} -> do { unless (null arg_tys) + (failWithDs (badRecResTy doc)) + -- AZ: This error used to be reported during + -- renaming, will now be reported in type + -- checking. Is this a problem? + ; return (details, res_ty) } + + PrefixCon {} -> return (PrefixCon arg_tys, res_ty)} + where + badRecResTy :: SDoc -> SDoc + badRecResTy ctxt = ctxt <+> + ptext (sLit "Malformed constructor signature") + mkGadtCtxt :: [Name] -- Tyvars of the data type - -> ResType (LHsType Name) + -> LHsSigType Name -> DsM (HsContext Name, [(Name,Name)]) -- Given a data type in GADT syntax, figure out the equality -- context, so that we can represent it with an explicit @@ -666,16 +723,16 @@ mkGadtCtxt :: [Name] -- Tyvars of the data type -- (b~[e], c~e), [d->a] -- -- This function is fiddly, but not really hard -mkGadtCtxt _ ResTyH98 - = return ([], []) -mkGadtCtxt data_tvs (ResTyGADT _ res_ty) - | Just (_, tys) <- hsTyGetAppHead_maybe res_ty +mkGadtCtxt data_tvs res_ty + | Just (_, tys) <- hsTyGetAppHead_maybe ty , data_tvs `equalLength` tys = return (go [] [] (data_tvs `zip` tys)) | otherwise = failWithDs (ptext (sLit "Malformed constructor result type:") <+> ppr res_ty) where + (_,ty',_,_) = gadtDeclDetails res_ty + (_arg_tys,ty) = splitHsFunType ty' go cxt subst [] = (cxt, subst) go cxt subst ((data_tv, ty) : rest) | Just con_tv <- is_hs_tyvar ty @@ -692,7 +749,6 @@ mkGadtCtxt data_tvs (ResTyGADT _ res_ty) is_hs_tyvar (L _ (HsParTy ty)) = is_hs_tyvar ty is_hs_tyvar _ = Nothing - repBangTy :: LBangType Name -> DsM (Core (TH.StrictTypeQ)) repBangTy ty = do MkC s <- rep2 str [] diff --git a/compiler/hsSyn/Convert.hs b/compiler/hsSyn/Convert.hs index 1fc4f09ad9481cc6b75560f0ea1cec173f14b5c8..4decbe12bb573bffc6610bace150c81afee3878c 100644 --- a/compiler/hsSyn/Convert.hs +++ b/compiler/hsSyn/Convert.hs @@ -45,7 +45,7 @@ import Control.Applicative (Applicative(..)) import Data.Char ( chr ) import Data.Word ( Word8 ) -import Data.Maybe( catMaybes ) +import Data.Maybe( catMaybes, fromMaybe ) import Language.Haskell.TH as TH hiding (sigP) import Language.Haskell.TH.Syntax as TH @@ -423,13 +423,13 @@ cvtConstr (NormalC c strtys) = do { c' <- cNameL c ; cxt' <- returnL [] ; tys' <- mapM cvt_arg strtys - ; returnL $ mkSimpleConDecl c' Nothing cxt' (PrefixCon tys') } + ; returnL $ mkConDeclH98 c' Nothing cxt' (PrefixCon tys') } cvtConstr (RecC c varstrtys) = do { c' <- cNameL c ; cxt' <- returnL [] ; args' <- mapM cvt_id_arg varstrtys - ; returnL $ mkSimpleConDecl c' Nothing cxt' + ; returnL $ mkConDeclH98 c' Nothing cxt' (RecCon (noLoc args')) } cvtConstr (InfixC st1 c st2) @@ -437,15 +437,23 @@ cvtConstr (InfixC st1 c st2) ; cxt' <- returnL [] ; st1' <- cvt_arg st1 ; st2' <- cvt_arg st2 - ; returnL $ mkSimpleConDecl c' Nothing cxt' (InfixCon st1' st2') } + ; returnL $ mkConDeclH98 c' Nothing cxt' (InfixCon st1' st2') } cvtConstr (ForallC tvs ctxt con) = do { tvs' <- cvtTvs tvs ; L loc ctxt' <- cvtContext ctxt ; L _ con' <- cvtConstr con - ; returnL $ con' { con_qvars = mkHsQTvs (hsQTvBndrs tvs' ++ hsQTvBndrs (con_qvars con')) - , con_explicit = True - , con_cxt = L loc (ctxt' ++ (unLoc $ con_cxt con')) } } + ; let qvars = case (tvs,con_qvars con') of + ([],Nothing) -> Nothing + _ -> + Just $ mkHsQTvs (hsQTvBndrs tvs' ++ + hsQTvBndrs (fromMaybe (HsQTvs PlaceHolder []) + (con_qvars con'))) + ; returnL $ con' { con_qvars = qvars + , con_cxt = Just $ + L loc (ctxt' ++ + unLoc (fromMaybe (noLoc []) + (con_cxt con'))) } } cvt_arg :: (TH.Strict, TH.Type) -> CvtM (LHsType RdrName) cvt_arg (NotStrict, ty) = cvtType ty diff --git a/compiler/hsSyn/HsDecls.hs b/compiler/hsSyn/HsDecls.hs index b8612ed2be4c4398d7fc7c0166a11e3a00fd19ff..48348cc2e1c6254171254a8a4c3b0df2cc375849 100644 --- a/compiler/hsSyn/HsDecls.hs +++ b/compiler/hsSyn/HsDecls.hs @@ -60,8 +60,11 @@ module HsDecls ( noForeignImportCoercionYet, noForeignExportCoercionYet, CImportSpec(..), -- ** Data-constructor declarations - ConDecl(..), LConDecl, ResType(..), + ConDecl(..), LConDecl, HsConDeclDetails, hsConDeclArgTys, + getConNames, + getConDetails, + gadtDeclDetails, -- ** Document comments DocDecl(..), LDocDecl, docDeclDoc, -- ** Deprecations @@ -106,6 +109,7 @@ import SrcLoc import FastString import Bag +import Data.Maybe ( fromMaybe ) import Data.Data hiding (TyCon,Fixity) #if __GLASGOW_HASKELL__ < 709 import Data.Foldable ( Foldable ) @@ -956,9 +960,9 @@ data HsDataDefn name -- The payload of a data type defn -- ^ Data constructors -- -- For @data T a = T1 | T2 a@ - -- the 'LConDecl's all have 'ResTyH98'. + -- the 'LConDecl's all have 'ConDeclH98'. -- For @data T a where { T1 :: T a }@ - -- the 'LConDecls' all have 'ResTyGADT'. + -- the 'LConDecls' all have 'ConDeclGADT'. dd_derivs :: HsDeriving name -- ^ Optional 'deriving' claues @@ -1020,71 +1024,64 @@ type LConDecl name = Located (ConDecl name) -- For details on above see note [Api annotations] in ApiAnnotation data ConDecl name - = ConDecl - { con_names :: [Located name] - -- ^ Constructor names. This is used for the DataCon itself, and for - -- the user-callable wrapper Id. - -- It is a list to deal with GADT constructors of the form - -- T1, T2, T3 :: <payload> - - , con_explicit :: Bool - -- ^ Is there an user-written forall? - -- For ResTyH98, "explicit" means something like: - -- data T = forall a. MkT { x :: a -> a } - -- For ResTyGADT, "explicit" means something like - -- data T where { MkT :: forall a. <blah> } - - , con_qvars :: LHsQTyVars name - -- ^ Type variables. Depending on 'con_res' this describes the - -- following entities - -- - -- - ResTyH98: the constructor's *existential* type variables + = ConDeclGADT + { con_names :: [Located name] + , con_type :: LHsSigType name + -- ^ The type after the ‘::’ + , con_doc :: Maybe LHsDocString + -- ^ A possible Haddock comment. + } + + | ConDeclH98 + { con_name :: Located name + + , con_qvars :: Maybe (LHsQTyVars name) + -- User-written forall (if any), and its implicit + -- kind variables + -- Non-Nothing needs -XExistentialQuantification -- e.g. data T a = forall b. MkT b (b->a) -- con_qvars = {b} - -- - -- - ResTyGADT: *all* the constructor's quantified type variables - -- e.g. data T a where - -- MkT :: forall a b. b -> (b->a) -> T a - -- con_qvars = {a,b} - -- - -- If con_explicit is False, then con_qvars is irrelevant - -- until after renaming. - , con_cxt :: LHsContext name - -- ^ The context. This /does not/ include the \"stupid theta\" which - -- lives only in the 'TyData' decl. + , con_cxt :: Maybe (LHsContext name) + -- ^ User-written context (if any) - , con_details :: HsConDeclDetails name - -- ^ The main payload + , con_details :: HsConDeclDetails name + -- ^ Arguments - , con_res :: ResType (LHsType name) - -- ^ Result type of the constructor - - , con_doc :: Maybe LHsDocString - -- ^ A possible Haddock comment. - } deriving (Typeable) + , con_doc :: Maybe LHsDocString + -- ^ A possible Haddock comment. + } deriving (Typeable) deriving instance (DataId name) => Data (ConDecl name) type HsConDeclDetails name = HsConDetails (LBangType name) (Located [LConDeclField name]) +getConNames :: ConDecl name -> [Located name] +getConNames ConDeclH98 {con_name = name} = [name] +getConNames ConDeclGADT {con_names = names} = names + +getConDetails :: ConDecl name -> HsConDeclDetails name +getConDetails ConDeclH98 {con_details = details} = details +getConDetails ConDeclGADT {con_type = ty } = details + where + (details,_,_,_) = gadtDeclDetails ty + +gadtDeclDetails :: LHsSigType name + -> (HsConDeclDetails name,LHsType name,LHsContext name,[LHsTyVarBndr name]) +gadtDeclDetails HsIB {hsib_body = lbody_ty} = (details,res_ty,cxt,tvs) + where + (tvs, cxt, tau) = splitLHsSigmaTy lbody_ty + (details, res_ty) -- See Note [Sorting out the result type] + = case tau of + L _ (HsFunTy (L l (HsRecTy flds)) res_ty) + -> (RecCon (L l flds), res_ty) + _other -> (PrefixCon [], tau) + hsConDeclArgTys :: HsConDeclDetails name -> [LBangType name] hsConDeclArgTys (PrefixCon tys) = tys hsConDeclArgTys (InfixCon ty1 ty2) = [ty1,ty2] hsConDeclArgTys (RecCon flds) = map (cd_fld_type . unLoc) (unLoc flds) -data ResType ty - = ResTyH98 -- Constructor was declared using Haskell 98 syntax - | ResTyGADT SrcSpan ty -- Constructor was declared using GADT-style syntax, - -- and here is its result type, and the SrcSpan - -- of the original sigtype, for API Annotations - deriving (Data, Typeable) - -instance Outputable ty => Outputable (ResType ty) where - -- Debugging only - ppr ResTyH98 = ptext (sLit "ResTyH98") - ppr (ResTyGADT _ ty) = ptext (sLit "ResTyGADT") <+> ppr ty - pp_data_defn :: OutputableBndr name => (HsContext name -> SDoc) -- Printing the header -> HsDataDefn name @@ -1115,7 +1112,7 @@ instance Outputable NewOrData where ppr DataType = ptext (sLit "data") pp_condecls :: OutputableBndr name => [LConDecl name] -> SDoc -pp_condecls cs@(L _ ConDecl{ con_res = ResTyGADT _ _ } : _) -- In GADT syntax +pp_condecls cs@(L _ ConDeclGADT{} : _) -- In GADT syntax = hang (ptext (sLit "where")) 2 (vcat (map ppr cs)) pp_condecls cs -- In H98 syntax = equals <+> sep (punctuate (ptext (sLit " |")) (map ppr cs)) @@ -1124,50 +1121,27 @@ instance (OutputableBndr name) => Outputable (ConDecl name) where ppr = pprConDecl pprConDecl :: OutputableBndr name => ConDecl name -> SDoc -pprConDecl (ConDecl { con_names = [L _ con] -- NB: non-GADT means 1 con - , con_explicit = expl, con_qvars = tvs - , con_cxt = cxt, con_details = details - , con_res = ResTyH98, con_doc = doc }) - = sep [ppr_mbDoc doc, ppr_con_forall expl tvs cxt, ppr_details details] +pprConDecl (ConDeclH98 { con_name = L _ con + , con_qvars = mtvs + , con_cxt = mcxt + , con_details = details + , con_doc = doc }) + = sep [ppr_mbDoc doc, pprHsForAll tvs cxt, ppr_details details] where ppr_details (InfixCon t1 t2) = hsep [ppr t1, pprInfixOcc con, ppr t2] ppr_details (PrefixCon tys) = hsep (pprPrefixOcc con : map (pprParendHsType . unLoc) tys) ppr_details (RecCon fields) = pprPrefixOcc con <+> pprConDeclFields (unLoc fields) + tvs = case mtvs of + Nothing -> [] + Just (HsQTvs _ tvs) -> tvs -pprConDecl (ConDecl { con_names = cons, con_explicit = expl, con_qvars = tvs - , con_cxt = cxt, con_details = PrefixCon arg_tys - , con_res = ResTyGADT _ res_ty, con_doc = doc }) - = ppr_mbDoc doc <+> ppr_con_names cons <+> dcolon <+> - sep [ppr_con_forall expl tvs cxt, ppr (foldr mk_fun_ty res_ty arg_tys)] - where - mk_fun_ty a b = noLoc (HsFunTy a b) + cxt = fromMaybe (noLoc []) mcxt -pprConDecl (ConDecl { con_names = cons, con_explicit = expl, con_qvars = tvs - , con_cxt = cxt, con_details = RecCon fields - , con_res = ResTyGADT _ res_ty, con_doc = doc }) +pprConDecl (ConDeclGADT { con_names = cons, con_type = res_ty, con_doc = doc }) = sep [ppr_mbDoc doc <+> ppr_con_names cons <+> dcolon - <+> ppr_con_forall expl tvs cxt, - pprConDeclFields (unLoc fields) <+> arrow <+> ppr res_ty] - -pprConDecl decl@(ConDecl { con_details = InfixCon ty1 ty2, con_res = ResTyGADT {} }) - = pprConDecl (decl { con_details = PrefixCon [ty1,ty2] }) - -- In GADT syntax we don't allow infix constructors - -- so if we ever trip over one (albeit I can't see how that - -- can happen) print it like a prefix one - --- this fallthrough would happen with a non-GADT-syntax ConDecl with more --- than one constructor, which should indeed be impossible -pprConDecl (ConDecl { con_names = cons }) = pprPanic "pprConDecl" (ppr cons) - -ppr_con_forall :: OutputableBndr name => Bool -> LHsQTyVars name - -> LHsContext name -> SDoc -ppr_con_forall explicit_forall qtvs (L _ ctxt) - | explicit_forall - = pprHsForAllTvs (hsQTvBndrs qtvs) <+> pprHsContext ctxt - | otherwise - = pprHsContext ctxt + <+> ppr res_ty] ppr_con_names :: (OutputableBndr name) => [Located name] -> SDoc ppr_con_names = pprWithCommas (pprPrefixOcc . unLoc) diff --git a/compiler/hsSyn/HsLit.hs b/compiler/hsSyn/HsLit.hs index e890b3bd9319c39c19e6c6c76d32604d426ddbf3..b929f867610d600ab3e51069eaba69a1306072c7 100644 --- a/compiler/hsSyn/HsLit.hs +++ b/compiler/hsSyn/HsLit.hs @@ -195,4 +195,3 @@ pmPprHsLit (HsInteger _ i _) = integer i pmPprHsLit (HsRat f _) = ppr f pmPprHsLit (HsFloatPrim f) = ppr f pmPprHsLit (HsDoublePrim d) = ppr d - diff --git a/compiler/hsSyn/HsTypes.hs b/compiler/hsSyn/HsTypes.hs index cd8f20342c7cf6dfe1ea33339208b637bd951f62..5546a918432f1620e2e84ec143c0bdba17d64c40 100644 --- a/compiler/hsSyn/HsTypes.hs +++ b/compiler/hsSyn/HsTypes.hs @@ -137,7 +137,7 @@ See also Note [Kind and type-variable binders] in RnTypes Note [HsType binders] ~~~~~~~~~~~~~~~~~~~~~ -The system fr recording type and kind-variable binders in HsTypes +The system for recording type and kind-variable binders in HsTypes is a bit complicated. Here's how it works. * In a HsType, @@ -146,7 +146,7 @@ is a bit complicated. Here's how it works. HsQualTy reprsents an /explicit, user-written/ context e.g. (Eq a, Show a) => ... The context can be empty if that's what the user wrote - These constructors reprsents what the user wrote, no more + These constructors represent what the user wrote, no more and no less. * HsTyVarBndr describes a quantified type variable written by the diff --git a/compiler/hsSyn/HsUtils.hs b/compiler/hsSyn/HsUtils.hs index 19996fd0f171b367df6fdb83db0681f6e39b84ba..ca3cae5260eddafaeda712fbd5084cffd4391ef7 100644 --- a/compiler/hsSyn/HsUtils.hs +++ b/compiler/hsSyn/HsUtils.hs @@ -953,14 +953,32 @@ hsConDeclsBinders cons = go id cons case r of -- remove only the first occurrence of any seen field in order to -- avoid circumventing detection of duplicate fields (#9156) - L loc (ConDecl { con_names = names, con_details = RecCon flds }) -> - (map (L loc . unLoc) names ++ ns, r' ++ fs) + L loc (ConDeclGADT { con_names = names + , con_type = HsIB { hsib_body = res_ty}}) -> + case tau of + L _ (HsFunTy (L _ (HsRecTy flds)) _res_ty) + -> (map (L loc . unLoc) names ++ ns, r' ++ fs) + where r' = remSeen (concatMap (cd_fld_names . unLoc) + flds) + remSeen' + = foldr (.) remSeen + [deleteBy ((==) `on` + rdrNameFieldOcc . unLoc) v + | v <- r'] + (ns, fs) = go remSeen' rs + _other -> (map (L loc . unLoc) names ++ ns, fs) + where (ns, fs) = go remSeen rs + where + (_tvs, _cxt, tau) = splitLHsSigmaTy res_ty + L loc (ConDeclH98 { con_name = name + , con_details = RecCon flds }) -> + ([L loc (unLoc name)] ++ ns, r' ++ fs) where r' = remSeen (concatMap (cd_fld_names . unLoc) (unLoc flds)) remSeen' = foldr (.) remSeen [deleteBy ((==) `on` rdrNameFieldOcc . unLoc) v | v <- r'] (ns, fs) = go remSeen' rs - L loc (ConDecl { con_names = names }) -> - (map (L loc . unLoc) names ++ ns, fs) + L loc (ConDeclH98 { con_name = name }) -> + ([L loc (unLoc name)] ++ ns, fs) where (ns, fs) = go remSeen rs {- diff --git a/compiler/parser/Parser.y b/compiler/parser/Parser.y index fb5c8dbd45ccb61efc8448c7524ff46361508578..bbde989293dd7606232fde250126450c2f62711d 100644 --- a/compiler/parser/Parser.y +++ b/compiler/parser/Parser.y @@ -1895,10 +1895,9 @@ gadt_constr_with_doc gadt_constr :: { LConDecl RdrName } -- see Note [Difference in parsing GADT and data constructors] -- Returns a list because of: C,D :: ty - : con_list '::' ctype - {% do { let { (anns,gadtDecl) = mkGadtDecl (unLoc $1) $3 } - ; ams (sLL $1 $> gadtDecl) - (mu AnnDcolon $2:anns) } } + : con_list '::' sigtype + {% ams (sLL $1 $> (mkGadtDecl (unLoc $1) (mkLHsSigType $3))) + [mu AnnDcolon $2] } {- Note [Difference in parsing GADT and data constructors] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -1925,13 +1924,13 @@ constrs1 :: { Located [LConDecl RdrName] } constr :: { LConDecl RdrName } : maybe_docnext forall context '=>' constr_stuff maybe_docprev {% ams (let (con,details) = unLoc $5 in - addConDoc (L (comb4 $2 $3 $4 $5) (mkSimpleConDecl con + addConDoc (L (comb4 $2 $3 $4 $5) (mkConDeclH98 con (snd $ unLoc $2) $3 details)) ($1 `mplus` $6)) (mu AnnDarrow $4:(fst $ unLoc $2)) } | maybe_docnext forall constr_stuff maybe_docprev {% ams ( let (con,details) = unLoc $3 in - addConDoc (L (comb2 $2 $3) (mkSimpleConDecl con + addConDoc (L (comb2 $2 $3) (mkConDeclH98 con (snd $ unLoc $2) (noLoc []) details)) ($1 `mplus` $4)) (fst $ unLoc $2) } @@ -2671,7 +2670,6 @@ stmtlist :: { Located ([AddAnn],[LStmt RdrName (LHsExpr RdrName)]) } -- here, because we need too much lookahead if we see do { e ; } -- So we use BodyStmts throughout, and switch the last one over -- in ParseUtils.checkDo instead --- AZ: TODO check that we can retrieve multiple semis. stmts :: { Located ([AddAnn],[LStmt RdrName (LHsExpr RdrName)]) } : stmts ';' stmt {% if null (snd $ unLoc $1) diff --git a/compiler/parser/RdrHsSyn.hs b/compiler/parser/RdrHsSyn.hs index 4b744fe69a56e900cbad75d972639363359d630c..53e6184491e547a180b87efb338abc905aa79502 100644 --- a/compiler/parser/RdrHsSyn.hs +++ b/compiler/parser/RdrHsSyn.hs @@ -35,7 +35,7 @@ module RdrHsSyn ( mkExport, mkExtName, -- RdrName -> CLabelString mkGadtDecl, -- [Located RdrName] -> LHsType RdrName -> ConDecl RdrName - mkSimpleConDecl, + mkConDeclH98, mkATDefault, -- Bunch of functions in the parser monad for @@ -487,58 +487,25 @@ mkPatSynMatchGroup (L _ patsyn_name) (L _ decls) = text "pattern synonym 'where' clause must bind the pattern synonym's name" <+> quotes (ppr patsyn_name) $$ ppr decl -mkSimpleConDecl :: Located RdrName -> Maybe [LHsTyVarBndr RdrName] +mkConDeclH98 :: Located RdrName -> Maybe [LHsTyVarBndr RdrName] -> LHsContext RdrName -> HsConDeclDetails RdrName -> ConDecl RdrName -mkSimpleConDecl name mb_forall cxt details - = ConDecl { con_names = [name] - , con_explicit = explicit - , con_qvars = qvars - , con_cxt = cxt - , con_details = details - , con_res = ResTyH98 - , con_doc = Nothing } - where - (explicit, qvars) = case mb_forall of - Nothing -> (False, mkHsQTvs []) - Just tvs -> (True, mkHsQTvs tvs) +mkConDeclH98 name mb_forall cxt details + = ConDeclH98 { con_name = name + , con_qvars = fmap mkHsQTvs mb_forall + , con_cxt = Just cxt + -- AZ:TODO: when can cxt be Nothing? + -- remembering that () is a valid context. + , con_details = details + , con_doc = Nothing } mkGadtDecl :: [Located RdrName] - -> LHsType RdrName -- Always a HsForAllTy - -> ([AddAnn], ConDecl RdrName) -mkGadtDecl names ty = ([], mkGadtDecl' names ty) - -mkGadtDecl' :: [Located RdrName] - -> LHsType RdrName - -> ConDecl RdrName --- We allow C,D :: ty --- and expand it as if it had been --- C :: ty; D :: ty --- (Just like type signatures in general.) - -mkGadtDecl' names lbody_ty@(L loc body_ty) - = mk_gadt_con names - where - (tvs, cxt, tau) = splitLHsSigmaTy lbody_ty - (details, res_ty) -- See Note [Sorting out the result type] - = case tau of - L _ (HsFunTy (L l (HsRecTy flds)) res_ty) - -> (RecCon (L l flds), res_ty) - _other -> (PrefixCon [], tau) - - explicit = case body_ty of - HsForAllTy {} -> True - _ -> False - - mk_gadt_con names - = ConDecl { con_names = names - , con_explicit = explicit - , con_qvars = mkHsQTvs tvs - , con_cxt = cxt - , con_details = details - , con_res = ResTyGADT loc res_ty - , con_doc = Nothing } + -> LHsSigType RdrName -- Always a HsForAllTy + -> ConDecl RdrName +mkGadtDecl names ty = ConDeclGADT { con_names = names + , con_type = ty + , con_doc = Nothing } tyConToDataCon :: SrcSpan -> RdrName -> P (Located RdrName) tyConToDataCon loc tc @@ -639,19 +606,19 @@ really doesn't matter! -- | Note [Sorting out the result type] -- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ --- In a GADT declaration which is not a record, we put the whole constr --- type into the ResTyGADT for now; the renamer will unravel it once it --- has sorted out operator fixities. Consider for example +-- In a GADT declaration which is not a record, we put the whole constr type +-- into the res_ty for a ConDeclGADT for now; the renamer will unravel it once +-- it has sorted out operator fixities. Consider for example -- C :: a :*: b -> a :*: b -> a :+: b -- Initially this type will parse as -- a :*: (b -> (a :*: (b -> (a :+: b)))) - +-- -- so it's hard to split up the arguments until we've done the precedence -- resolution (in the renamer) On the other hand, for a record -- { x,y :: Int } -> a :*: b -- there is no doubt. AND we need to sort records out so that -- we can bring x,y into scope. So: --- * For PrefixCon we keep all the args in the ResTyGADT +-- * For PrefixCon we keep all the args in the res_ty -- * For RecCon we do not checkTyVarsP :: SDoc -> SDoc -> Located RdrName -> [LHsType RdrName] -> P (LHsQTyVars RdrName) diff --git a/compiler/rename/RnEnv.hs b/compiler/rename/RnEnv.hs index 57b427b0def7bcbb403be3e506b2b98791ec25e2..42a159f3d4d462684be9eba1eeeec722206511cf 100644 --- a/compiler/rename/RnEnv.hs +++ b/compiler/rename/RnEnv.hs @@ -2123,6 +2123,8 @@ checkTupSize tup_size ************************************************************************ -} +-- AZ:TODO: Change these all to be Name instead of RdrName. +-- Merge TcType.UserTypeContext in to it. data HsDocContext = TypeSigCtx SDoc | PatCtx @@ -2135,7 +2137,7 @@ data HsDocContext | TySynCtx (Located RdrName) | TyFamilyCtx (Located RdrName) | FamPatCtx (Located RdrName) -- The patterns of a type/data family instance - | ConDeclCtx [Located RdrName] + | ConDeclCtx [Located Name] | ClassDeclCtx (Located RdrName) | ExprWithTySigCtx | TypBrCtx diff --git a/compiler/rename/RnNames.hs b/compiler/rename/RnNames.hs index b0b79f55e687b57eba1430325caba09a07574871..c673ac3729accc55180bd30a6b932ab627efa975 100644 --- a/compiler/rename/RnNames.hs +++ b/compiler/rename/RnNames.hs @@ -610,11 +610,22 @@ getLocalNonValBinders fixity_env mk_fld_env :: HsDataDefn RdrName -> [Name] -> [FieldLabel] -> [(Name, [FieldLabel])] mk_fld_env d names flds = concatMap find_con_flds (dd_cons d) where - find_con_flds (L _ (ConDecl { con_names = rdrs + find_con_flds (L _ (ConDeclH98 { con_name = rdrs , con_details = RecCon cdflds })) = map (\ (L _ rdr) -> ( find_con_name rdr , concatMap find_con_decl_flds (unLoc cdflds))) + [rdrs] -- AZ:TODO remove map + find_con_flds (L _ (ConDeclGADT + { con_names = rdrs + , con_type = (HsIB { hsib_body = res_ty})})) + = map (\ (L _ rdr) -> ( find_con_name rdr + , concatMap find_con_decl_flds cdflds)) rdrs + where + (_tvs, _cxt, tau) = splitLHsSigmaTy res_ty + cdflds = case tau of + L _ (HsFunTy (L _ (HsRecTy flds)) _) -> flds + _ -> [] find_con_flds _ = [] find_con_name rdr diff --git a/compiler/rename/RnSource.hs b/compiler/rename/RnSource.hs index 2fbbea41790d5eee22e80593fd8e8ee1f122b804..dafae7cf5f9b7f56e4aa73d4459c04fced22fb2c 100644 --- a/compiler/rename/RnSource.hs +++ b/compiler/rename/RnSource.hs @@ -1242,8 +1242,8 @@ rnDataDefn doc (HsDataDefn { dd_ND = new_or_data, dd_cType = cType } where h98_style = case condecls of -- Note [Stupid theta] - L _ (ConDecl { con_res = ResTyGADT {} }) : _ -> False - _ -> True + L _ (ConDeclGADT {}) : _ -> False + _ -> True rn_derivs Nothing = return (Nothing, emptyFVs) @@ -1454,7 +1454,7 @@ depAnalTyClDecls ds_w_fvs DataDecl { tcdLName = L _ data_name , tcdDataDefn = HsDataDefn { dd_cons = cons } } -> do L _ dc <- cons - return $ zip (map unLoc $ con_names dc) (repeat data_name) + return $ zip (map unLoc $ getConNames dc) (repeat data_name) _ -> [] {- @@ -1506,29 +1506,6 @@ modules), we get better error messages, too. \subsection{Support code for type/data declarations} * * ********************************************************* - -Note [Quantification in data constructor declarations] -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -Four cases, afer renaming - * ResTyH98 - - data T a = forall b. MkT { x :: b -> a } - The 'b' is explicitly declared; - con_qvars = [b] - - - data T a = MkT { x :: a -> b } - Do *not* implicitly quantify over 'b'; it is - simply out of scope. con_qvars = [] - - * ResTyGADT - - data T a where { MkT :: forall b. (b -> a) -> T a } - con_qvars = [a,b] - - - data T a where { MkT :: (b -> a) -> T a } - con_qvars = [a,b], by implicit quantification - of the type signature - It is uncomfortable that we add implicitly-bound - type variables to the HsQTyVars, which usually - only has explicitly-bound type variables -} --------------- @@ -1543,75 +1520,61 @@ rnConDecls :: [LConDecl RdrName] -> RnM ([LConDecl Name], FreeVars) rnConDecls = mapFvRn (wrapLocFstM rnConDecl) rnConDecl :: ConDecl RdrName -> RnM (ConDecl Name, FreeVars) -rnConDecl decl@(ConDecl { con_names = names, con_qvars = qtvs - , con_cxt = lcxt@(L loc cxt), con_details = details - , con_res = res_ty, con_doc = mb_doc - , con_explicit = explicit }) - = do { mapM_ (addLocM checkConName) names - ; new_names <- mapM lookupLocatedTopBndrRn names +rnConDecl decl@(ConDeclH98 { con_name = name, con_qvars = qtvs + , con_cxt = mcxt, con_details = details + , con_doc = mb_doc }) + = do { _ <- addLocM checkConName name + ; new_name <- lookupLocatedTopBndrRn name + ; let doc = ConDeclCtx [new_name] ; mb_doc' <- rnMbLHsDoc mb_doc - ; let (kvs, qtvs') = get_con_qtvs qtvs (hsConDeclArgTys details) res_ty + ; let (kvs, qtvs') = get_con_qtvs qtvs (hsConDeclArgTys details) ; bindHsQTyVars doc Nothing kvs qtvs' $ \new_tyvars -> do - { (new_context, fvs1) <- rnContext doc lcxt - ; (new_details, fvs2) <- rnConDeclDetails (unLoc $ head new_names) doc details - ; (new_details', new_res_ty, fvs3) - <- rnConResult doc (map unLoc new_names) new_details res_ty - ; traceRn (text "rnConDecl" <+> ppr names <+> vcat + { (new_context, fvs1) <- case mcxt of + Nothing -> return (Nothing,emptyFVs) + Just lcxt -> do { (lctx',fvs) <- rnContext doc lcxt + ; return (Just lctx',fvs) } + ; (new_details, fvs2) <- rnConDeclDetails (unLoc new_name) doc details + ; let (new_details',fvs3) = (new_details,emptyFVs) + ; traceRn (text "rnConDecl" <+> ppr name <+> vcat [ text "free_kvs:" <+> ppr kvs , text "qtvs:" <+> ppr qtvs , text "qtvs':" <+> ppr qtvs' ]) ; let all_fvs = fvs1 `plusFV` fvs2 `plusFV` fvs3 ; warnUnusedForAlls (inHsDocContext doc) (hsQTvBndrs new_tyvars) all_fvs - ; return (decl { con_names = new_names, con_qvars = new_tyvars + ; let new_tyvars' = case qtvs of + Nothing -> Nothing + Just _ -> Just new_tyvars + ; return (decl { con_name = new_name, con_qvars = new_tyvars' , con_cxt = new_context, con_details = new_details' - , con_res = new_res_ty, con_doc = mb_doc' }, + , con_doc = mb_doc' }, all_fvs) }} where - doc = ConDeclCtx names + cxt = maybe [] unLoc mcxt get_rdr_tvs tys = extractHsTysRdrTyVars (cxt ++ tys) - get_con_qtvs :: LHsQTyVars RdrName -> [LHsType RdrName] - -> ResType (LHsType RdrName) + get_con_qtvs :: Maybe (LHsQTyVars RdrName) -> [LHsType RdrName] -> ([RdrName], LHsQTyVars RdrName) - get_con_qtvs qtvs arg_tys ResTyH98 - | explicit -- data T = forall a. MkT (a -> a) - = (free_kvs, qtvs) - | otherwise -- data T = MkT (a -> a) + get_con_qtvs Nothing _arg_tys = ([], mkHsQTvs []) + get_con_qtvs (Just qtvs) arg_tys + = (free_kvs, qtvs) where (free_kvs, _) = get_rdr_tvs arg_tys - get_con_qtvs qtvs arg_tys (ResTyGADT _ ty) - | explicit -- data T x where { MkT :: forall a. a -> T a } - = (free_kvs, qtvs) - | otherwise -- data T x where { MkT :: a -> T a } - = (free_kvs, mkHsQTvs (userHsTyVarBndrs loc free_tvs)) - where - (free_kvs, free_tvs) = get_rdr_tvs (ty : arg_tys) - -rnConResult :: HsDocContext -> [Name] - -> HsConDetails (LHsType Name) (Located [LConDeclField Name]) - -> ResType (LHsType RdrName) - -> RnM (HsConDetails (LHsType Name) (Located [LConDeclField Name]), - ResType (LHsType Name), FreeVars) -rnConResult _ _ details ResTyH98 = return (details, ResTyH98, emptyFVs) -rnConResult doc _con details (ResTyGADT ls ty) - = do { (ty', fvs) <- rnLHsType doc ty - ; let (arg_tys, res_ty) = splitHsFunType ty' - -- We can finally split it up, - -- now the renamer has dealt with fixities - -- See Note [Sorting out the result type] in RdrHsSyn - - ; case details of - InfixCon {} -> pprPanic "rnConResult" (ppr ty) - -- See Note [Sorting out the result type] in RdrHsSyn - - RecCon {} -> do { unless (null arg_tys) - (addErr (badRecResTy doc)) - ; return (details, ResTyGADT ls res_ty, fvs) } - - PrefixCon {} -> return (PrefixCon arg_tys, ResTyGADT ls res_ty, fvs)} +rnConDecl decl@(ConDeclGADT { con_names = names, con_type = ty + , con_doc = mb_doc }) + = do { mapM_ (addLocM checkConName) names + ; new_names <- mapM lookupLocatedTopBndrRn names + ; let doc = ConDeclCtx new_names + ; mb_doc' <- rnMbLHsDoc mb_doc + + ; (ty', fvs) <- rnHsSigType doc ty + ; traceRn (text "rnConDecl" <+> ppr names <+> vcat + [ text "fvs:" <+> ppr fvs ]) + ; return (decl { con_names = new_names, con_type = ty' + , con_doc = mb_doc' }, + fvs) } rnConDeclDetails :: Name @@ -1635,9 +1598,6 @@ rnConDeclDetails con doc (RecCon (L l fields)) ; return (RecCon (L l new_fields), fvs) } ------------------------------------------------- -badRecResTy :: HsDocContext -> SDoc -badRecResTy ctxt = withHsDocContext ctxt $ - ptext (sLit "Malformed constructor signature") -- | Brings pattern synonym names and also pattern synonym selectors -- from record pattern synonyms into scope. diff --git a/compiler/rename/RnTypes.hs b/compiler/rename/RnTypes.hs index 49b707c3708a9115f64ca8efc587ddf7a4942995..b716ee07210971c6242f4c9ab2605fd60a2e5ea2 100644 --- a/compiler/rename/RnTypes.hs +++ b/compiler/rename/RnTypes.hs @@ -363,6 +363,14 @@ rnHsTyKi _ doc (HsBangTy b ty) = do { (ty', fvs) <- rnLHsType doc ty ; return (HsBangTy b ty', fvs) } +rnHsTyKi _ doc@(ConDeclCtx names) (HsRecTy flds) + = do { + -- AZ:reviewers: is there a monadic version of concatMap? + flss <- mapM (lookupConstructorFields . unLoc) names + ; let fls = concat flss + ; (flds', fvs) <- rnConDeclFields fls doc flds + ; return (HsRecTy flds', fvs) } + rnHsTyKi _ doc ty@(HsRecTy flds) = do { addErr (hang (ptext (sLit "Record syntax is illegal here:")) 2 (ppr ty)) @@ -1200,14 +1208,18 @@ extractDataDefnKindVars (HsDataDefn { dd_ctxt = ctxt, dd_kindSig = ksig extract_mb (extract_sig_tys . unLoc) derivs $ foldr (extract_con . unLoc) ([],[]) cons where - extract_con (ConDecl { con_res = ResTyGADT {} }) acc = acc - extract_con (ConDecl { con_res = ResTyH98, con_qvars = qvs - , con_cxt = ctxt, con_details = details }) acc - = extract_hs_tv_bndrs (hsQTvBndrs qvs) acc $ - extract_lctxt ctxt $ + extract_con (ConDeclGADT { }) acc = acc + extract_con (ConDeclH98 { con_qvars = qvs + , con_cxt = ctxt, con_details = details }) acc + = extract_hs_tv_bndrs (maybe [] hsQTvBndrs qvs) acc $ + extract_mlctxt ctxt $ extract_ltys (hsConDeclArgTys details) ([],[]) +extract_mlctxt :: Maybe (LHsContext RdrName) -> FreeKiTyVars -> FreeKiTyVars +extract_mlctxt Nothing = mempty +extract_mlctxt (Just ctxt) = extract_lctxt ctxt + extract_lctxt :: LHsContext RdrName -> FreeKiTyVars -> FreeKiTyVars extract_lctxt ctxt = extract_ltys (unLoc ctxt) diff --git a/compiler/typecheck/TcHsType.hs b/compiler/typecheck/TcHsType.hs index c0fef87334bc717866a0cd228219bd8beec0246f..2b671463cd845f9b6a9fad3368d1f6aaee152cf1 100644 --- a/compiler/typecheck/TcHsType.hs +++ b/compiler/typecheck/TcHsType.hs @@ -9,7 +9,7 @@ module TcHsType ( -- Type signatures - kcClassSigType, tcClassSigType, + kcHsSigType, tcClassSigType, tcHsSigType, tcHsSigWcType, zonkSigType, zonkAndCheckValidity, funsSigCtxt, addSigCtxt, @@ -183,8 +183,8 @@ tcHsSigWcType :: UserTypeCtxt -> LHsSigWcType Name -> TcM Type -- alrady checked this, so we can simply ignore it. tcHsSigWcType ctxt sig_ty = tcHsSigType ctxt (dropWildCards sig_ty) -kcClassSigType :: [Located Name] -> LHsSigType Name -> TcM () -kcClassSigType names (HsIB { hsib_body = hs_ty +kcHsSigType :: [Located Name] -> LHsSigType Name -> TcM () +kcHsSigType names (HsIB { hsib_body = hs_ty , hsib_kvs = sig_kvs , hsib_tvs = sig_tvs }) = addSigCtxt (funsSigCtxt names) hs_ty $ @@ -387,9 +387,10 @@ tc_hs_type ty@(HsBangTy {}) _ -- other kinds of bangs are not (eg ((!Maybe) Int)). These kinds of -- bangs are invalid, so fail. (#7210) = failWithTc (ptext (sLit "Unexpected strictness annotation:") <+> ppr ty) -tc_hs_type (HsRecTy _) _ = panic "tc_hs_type: record" -- Unwrapped by con decls +tc_hs_type ty@(HsRecTy _) _ -- Record types (which only show up temporarily in constructor -- signatures) should have been removed by now + = failWithTc (ptext (sLit "Record syntax is illegal here:") <+> ppr ty) ---------- Functions and applications tc_hs_type hs_ty@(HsTyVar (L _ name)) exp_kind diff --git a/compiler/typecheck/TcRnDriver.hs b/compiler/typecheck/TcRnDriver.hs index ee95bb5594f3238442467fac455ddb8fce44b418..27b807455a2c7b9ddc2ea3ea29323a695aa97fac 100644 --- a/compiler/typecheck/TcRnDriver.hs +++ b/compiler/typecheck/TcRnDriver.hs @@ -1444,7 +1444,7 @@ tcTyClsInstDecls tycl_decls inst_decls deriv_decls get_fi_cons :: DataFamInstDecl Name -> [Name] get_fi_cons (DataFamInstDecl { dfid_defn = HsDataDefn { dd_cons = cons } }) - = map unLoc $ concatMap (con_names . unLoc) cons + = map unLoc $ concatMap (getConNames . unLoc) cons {- Note [AFamDataCon: not promoting data family constructors] diff --git a/compiler/typecheck/TcTyClsDecls.hs b/compiler/typecheck/TcTyClsDecls.hs index a2b6a6386e9f0b0437c8c5842f9ecec7e59dcd4a..1cb71d61825daec0d85f554d781e52dcdb320a27 100644 --- a/compiler/typecheck/TcTyClsDecls.hs +++ b/compiler/typecheck/TcTyClsDecls.hs @@ -67,6 +67,7 @@ import BasicTypes import Control.Monad import Data.List +import Data.Monoid ( mempty ) {- ************************************************************************ @@ -381,7 +382,7 @@ getInitialKind decl@(DataDecl { tcdLName = L _ name ; return (res_k, ()) } ; let main_pr = (name, AThing decl_kind) inner_prs = [ (unLoc con, APromotionErr RecDataConPE) - | L _ con' <- cons, con <- con_names con' ] + | L _ con' <- cons, con <- getConNames con' ] ; return (main_pr : inner_prs) } getInitialKind (FamDecl { tcdFam = decl }) @@ -480,7 +481,7 @@ kcTyClDecl (ClassDecl { tcdLName = L _ name, tcdTyVars = hs_tvs do { _ <- tcHsContext ctxt ; mapM_ (wrapLocM kc_sig) sigs } where - kc_sig (ClassOpSig _ nms op_ty) = kcClassSigType nms op_ty + kc_sig (ClassOpSig _ nms op_ty) = kcHsSigType nms op_ty kc_sig _ = return () -- closed type families look at their equations, but other families don't @@ -495,20 +496,25 @@ kcTyClDecl (FamDecl {}) = return () ------------------- kcConDecl :: ConDecl Name -> TcM () -kcConDecl (ConDecl { con_names = names, con_qvars = ex_tvs - , con_cxt = ex_ctxt, con_details = details - , con_res = res }) - = addErrCtxt (dataConCtxtName names) $ +kcConDecl (ConDeclH98 { con_name = name, con_qvars = ex_tvs + , con_cxt = ex_ctxt, con_details = details }) + = addErrCtxt (dataConCtxtName [name]) $ -- the 'False' says that the existentials don't have a CUSK, as the -- concept doesn't really apply here. We just need to bring the variables -- into scope! - do { _ <- kcHsTyVarBndrs False ex_tvs $ - do { _ <- tcHsContext ex_ctxt + do { _ <- kcHsTyVarBndrs False ((fromMaybe (HsQTvs mempty []) ex_tvs)) $ + do { _ <- tcHsContext (fromMaybe (noLoc []) ex_ctxt) ; mapM_ (tcHsOpenType . getBangType) (hsConDeclArgTys details) - ; _ <- tcConRes res ; return (panic "kcConDecl", ()) } ; return () } +kcConDecl (ConDeclGADT { con_names = names + , con_type = ty }) + = addErrCtxt (dataConCtxtName names) $ + do { _ <- tcGadtSigType (ppr names) (unLoc $ head names) ty + ; return () } + + {- Note [Recursion and promoting data constructors] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -1241,8 +1247,8 @@ dataDeclChecks tc_name new_or_data stupid_theta cons ----------------------------------- consUseGadtSyntax :: [LConDecl a] -> Bool -consUseGadtSyntax (L _ (ConDecl { con_res = ResTyGADT _ _ }) : _) = True -consUseGadtSyntax _ = False +consUseGadtSyntax (L _ (ConDeclGADT { }) : _) = True +consUseGadtSyntax _ = False -- All constructors have same shape ----------------------------------- @@ -1261,41 +1267,72 @@ tcConDecl :: NewOrData -> TcM [DataCon] tcConDecl new_or_data is_prom rep_tycon tmpl_tvs res_tmpl - (ConDecl { con_names = names - , con_qvars = hs_tvs, con_cxt = hs_ctxt - , con_details = hs_details, con_res = hs_res_ty }) - = addErrCtxt (dataConCtxtName names) $ - do { traceTc "tcConDecl 1" (ppr names) - ; (ctxt, arg_tys, res_ty, field_lbls, stricts) - <- tcHsQTyVars hs_tvs $ \ _ -> - do { traceTc "tcConDecl" (ppr names <+> text "tvs:" <+> ppr hs_tvs) - ; ctxt <- tcHsContext hs_ctxt + (ConDeclH98 { con_name = name + , con_qvars = hs_tvs, con_cxt = hs_ctxt + , con_details = hs_details }) + = addErrCtxt (dataConCtxtName [name]) $ + do { traceTc "tcConDecl 1" (ppr name) + ; (ctxt, arg_tys, field_lbls, stricts) + <- tcHsQTyVars (fromMaybe (HsQTvs [] []) hs_tvs) $ \ _ -> + do { traceTc "tcConDecl" (ppr name <+> text "tvs:" <+> ppr hs_tvs) + ; ctxt <- tcHsContext (fromMaybe (noLoc []) hs_ctxt) ; btys <- tcConArgs new_or_data hs_details - ; res_ty <- tcConRes hs_res_ty - ; field_lbls <- lookupConstructorFields (unLoc $ head names) + ; field_lbls <- lookupConstructorFields (unLoc name) ; let (arg_tys, stricts) = unzip btys - ; return (ctxt, arg_tys, res_ty, field_lbls, stricts) + ; return (ctxt, arg_tys, field_lbls, stricts) } - -- Generalise the kind variables (returning quantified TcKindVars) - -- and quantify the type variables (substituting their kinds) - -- REMEMBER: 'tkvs' are: - -- ResTyH98: the *existential* type variables only - -- ResTyGADT: *all* the quantified type variables - -- c.f. the comment on con_qvars in HsDecls - ; tkvs <- case res_ty of - ResTyH98 -> quantifyTyVars (mkVarSet tmpl_tvs) - (tyVarsOfTypes (ctxt++arg_tys)) - ResTyGADT _ res_ty -> quantifyTyVars emptyVarSet - (tyVarsOfTypes (res_ty:ctxt++arg_tys)) + ; tkvs <- quantifyTyVars (mkVarSet tmpl_tvs) + (tyVarsOfTypes (ctxt++arg_tys)) -- Zonk to Types ; (ze, qtkvs) <- zonkTyBndrsX emptyZonkEnv tkvs ; arg_tys <- zonkTcTypeToTypes ze arg_tys ; ctxt <- zonkTcTypeToTypes ze ctxt - ; res_ty <- case res_ty of - ResTyH98 -> return ResTyH98 - ResTyGADT ls ty -> ResTyGADT ls <$> zonkTcTypeToType ze ty + + ; let (univ_tvs, ex_tvs, eq_preds) = (tmpl_tvs, qtkvs, []) + -- AZ:TODO: Is this comment needed here for ConDeclH98? + -- NB: this is a /lazy/ binding, so we pass four thunks to buildDataCon + -- without yet forcing the guards in rejigConRes + -- See Note [Checking GADT return types] + + ; fam_envs <- tcGetFamInstEnvs + + -- Can't print univ_tvs, arg_tys etc, because we are inside the knot here + ; traceTc "tcConDecl 2" (ppr name $$ ppr field_lbls) + ; let + buildOneDataCon (L _ name) = do + { is_infix <- tcConIsInfixH98 name hs_details + ; rep_nm <- newTyConRepName name + + ; buildDataCon fam_envs name is_infix + (if is_prom then Promoted rep_nm else NotPromoted) + -- Must be lazy in is_prom because it is knot-tied + stricts Nothing field_lbls + univ_tvs ex_tvs eq_preds ctxt arg_tys + res_tmpl rep_tycon + -- NB: we put data_tc, the type constructor gotten from the + -- constructor type signature into the data constructor; + -- that way checkValidDataCon can complain if it's wrong. + } + ; traceTc "tcConDecl 2" (ppr name) + ; mapM buildOneDataCon [name] + } + +tcConDecl _new_or_data is_prom rep_tycon tmpl_tvs res_tmpl + (ConDeclGADT { con_names = names, con_type = ty }) + = addErrCtxt (dataConCtxtName names) $ + do { traceTc "tcConDecl 1" (ppr names) + ; (ctxt, stricts, field_lbls, arg_tys, res_ty,hs_details) + <- tcGadtSigType (ppr names) (unLoc $ head names) ty + ; tkvs <- quantifyTyVars emptyVarSet + (tyVarsOfTypes (res_ty:ctxt++arg_tys)) + + -- Zonk to Types + ; (ze, qtkvs) <- zonkTyBndrsX emptyZonkEnv tkvs + ; arg_tys <- zonkTcTypeToTypes ze arg_tys + ; ctxt <- zonkTcTypeToTypes ze ctxt + ; res_ty <- zonkTcTypeToType ze res_ty ; let (univ_tvs, ex_tvs, eq_preds, res_ty') = rejigConRes tmpl_tvs res_tmpl qtkvs res_ty -- NB: this is a /lazy/ binding, so we pass four thunks to buildDataCon @@ -1308,7 +1345,7 @@ tcConDecl new_or_data is_prom rep_tycon tmpl_tvs res_tmpl ; traceTc "tcConDecl 2" (ppr names $$ ppr field_lbls) ; let buildOneDataCon (L _ name) = do - { is_infix <- tcConIsInfix name hs_details res_ty + { is_infix <- tcConIsInfixGADT name hs_details ; rep_nm <- newTyConRepName name ; buildDataCon fam_envs name is_infix @@ -1326,19 +1363,72 @@ tcConDecl new_or_data is_prom rep_tycon tmpl_tvs res_tmpl } -tcConIsInfix :: Name +tcGadtSigType :: SDoc -> Name -> LHsSigType Name + -> TcM ([PredType],[HsSrcBang], [FieldLabel], [Type], Type + ,HsConDetails (LHsType Name) (Located [LConDeclField Name])) +tcGadtSigType doc name ty@(HsIB { hsib_kvs = kvs, hsib_tvs = tvs}) + = do { let (hs_details',res_ty',cxt,gtvs) = gadtDeclDetails ty + ; (hs_details,res_ty) <- tcUpdateConResult doc hs_details' res_ty' + ; let hs_tvs = HsQTvs { hsq_kvs = kvs + , hsq_tvs = gtvs ++ + map (noLoc . UserTyVar . noLoc) tvs } + ; (ctxt, arg_tys, res_ty, field_lbls, stricts) + <- tcHsQTyVars hs_tvs $ \ _ -> + do { ctxt <- tcHsContext cxt + ; btys <- tcConArgs DataType hs_details + ; ty' <- tcHsLiftedType res_ty + ; field_lbls <- lookupConstructorFields name + ; let (arg_tys, stricts) = unzip btys + ; return (ctxt, arg_tys, ty', field_lbls, stricts) + } + ; return (ctxt,stricts,field_lbls,arg_tys,res_ty,hs_details) + } + +tcUpdateConResult :: SDoc + -> HsConDetails (LHsType Name) (Located [LConDeclField Name]) + -- Original details + -> LHsType Name -- The original result type + -> TcM (HsConDetails (LHsType Name) (Located [LConDeclField Name]), + LHsType Name) +tcUpdateConResult doc details ty + = do { let (arg_tys, res_ty) = splitHsFunType ty + -- We can finally split it up, + -- now the renamer has dealt with fixities + -- See Note [Sorting out the result type] in RdrHsSyn + + ; case details of + InfixCon {} -> pprPanic "tcUpdateConResult" (ppr ty) + -- See Note [Sorting out the result type] in RdrHsSyn + + RecCon {} -> do { unless (null arg_tys) + (failWithTc (badRecResTy doc)) + -- AZ: This error used to be reported during + -- renaming, will now be reported in type + -- checking. Is this a problem? + ; return (details, res_ty) } + + PrefixCon {} -> return (PrefixCon arg_tys, res_ty)} + where + badRecResTy :: SDoc -> SDoc + badRecResTy ctxt = ctxt <+> + ptext (sLit "Malformed constructor signature") + +tcConIsInfixH98 :: Name -> HsConDetails (LHsType Name) (Located [LConDeclField Name]) - -> ResType Type -> TcM Bool -tcConIsInfix _ details ResTyH98 +tcConIsInfixH98 _ details = case details of InfixCon {} -> return True _ -> return False -tcConIsInfix con details (ResTyGADT _ _) + +tcConIsInfixGADT :: Name + -> HsConDetails (LHsType Name) (Located [LConDeclField Name]) + -> TcM Bool +tcConIsInfixGADT con details = case details of InfixCon {} -> return True RecCon {} -> return False - PrefixCon arg_tys -- See Note [Infix GADT cons] + PrefixCon arg_tys -- See Note [Infix GADT constructors] | isSymOcc (getOccName con) , [_ty1,_ty2] <- arg_tys -> do { fix_env <- getFixityEnv @@ -1372,11 +1462,6 @@ tcConArg new_or_data bty ; traceTc "tcConArg 2" (ppr bty) ; return (arg_ty, getBangStrictness bty) } -tcConRes :: ResType (LHsType Name) -> TcM (ResType Type) -tcConRes ResTyH98 = return ResTyH98 -tcConRes (ResTyGADT ls res_ty) = do { res_ty' <- tcHsLiftedType res_ty - ; return (ResTyGADT ls res_ty') } - {- Note [Infix GADT constructors] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -1432,7 +1517,7 @@ rejigConRes :: [TyVar] -> Type -- Template for result type; e.g. -- data instance T [a] b c = ... -- gives template ([a,b,c], T [a] b c) -> [TyVar] -- where MkT :: forall x y z. ... - -> ResType Type + -> Type -- res_ty -> ([TyVar], -- Universal [TyVar], -- Existential (distinct OccNames from univs) [(TyVar,Type)], -- Equality predicates @@ -1440,13 +1525,7 @@ rejigConRes :: [TyVar] -> Type -- Template for result type; e.g. -- We don't check that the TyCon given in the ResTy is -- the same as the parent tycon, because checkValidDataCon will do it -rejigConRes tmpl_tvs res_ty dc_tvs ResTyH98 - = (tmpl_tvs, dc_tvs, [], res_ty) - -- In H98 syntax the dc_tvs are the existential ones - -- data T a b c = forall d e. MkT ... - -- The universals {a,b,c} are tc_tvs, and the existentials {d,e} are dc_tvs - -rejigConRes tmpl_tvs res_tmpl dc_tvs (ResTyGADT _ res_ty) +rejigConRes tmpl_tvs res_tmpl dc_tvs res_ty -- E.g. data T [a] b c where -- MkT :: forall x y z. T [(x,y)] z z -- The {a,b,c} are the tmpl_tvs, and the {x,y,z} are the dc_tvs @@ -1499,7 +1578,7 @@ data SList s as where We call tcResultType with tmpl_tvs = [(k :: BOX), (s :: k -> *), (as :: List k)] res_tmpl = SList k s as - res_ty = ResTyGADT (SList k1 (s1 :: k1 -> *) (Nil k1)) + res_ty = (SList k1 (s1 :: k1 -> *) (Nil k1)) We get subst: k -> k1 diff --git a/testsuite/tests/ghc-api/annotations/T10399.stdout b/testsuite/tests/ghc-api/annotations/T10399.stdout index 58a4093aaeb2aeb7bd16cf176d6dd2349e5c1ce1..612ecfd734b823e0325f0b1f38548629ab2f443f 100644 --- a/testsuite/tests/ghc-api/annotations/T10399.stdout +++ b/testsuite/tests/ghc-api/annotations/T10399.stdout @@ -44,9 +44,7 @@ ((Test10399.hs:15:45-46,AnnBang), [Test10399.hs:15:45]), ((Test10399.hs:15:45-46,AnnRarrow), [Test10399.hs:15:48-49]), ((Test10399.hs:15:45-64,AnnRarrow), [Test10399.hs:15:48-49]), -((Test10399.hs:(16,5)-(17,69),AnnCloseP), [Test10399.hs:17:69]), ((Test10399.hs:(16,5)-(17,69),AnnDcolon), [Test10399.hs:16:12-13]), -((Test10399.hs:(16,5)-(17,69),AnnOpenP), [Test10399.hs:16:27]), ((Test10399.hs:(16,15)-(17,69),AnnDot), [Test10399.hs:16:25]), ((Test10399.hs:(16,15)-(17,69),AnnForall), [Test10399.hs:16:15-20]), ((Test10399.hs:(16,27)-(17,69),AnnCloseP), [Test10399.hs:17:69]), diff --git a/testsuite/tests/ghc-api/annotations/all.T b/testsuite/tests/ghc-api/annotations/all.T index 4104bceebf41680fbf17ff9b73c002610fa81488..c7c8542a11f7ef77d12eb977bde905bfcc61a2cd 100644 --- a/testsuite/tests/ghc-api/annotations/all.T +++ b/testsuite/tests/ghc-api/annotations/all.T @@ -16,7 +16,7 @@ test('T10358', normal, run_command, ['$MAKE -s --no-print-directory T10358' test('T10278', normal, run_command, ['$MAKE -s --no-print-directory T10278']) test('T10354', normal, run_command, ['$MAKE -s --no-print-directory T10354']) test('T10396', normal, run_command, ['$MAKE -s --no-print-directory T10396']) -test('T10399', expect_broken(11028), run_command, ['$MAKE -s --no-print-directory T10399']) +test('T10399', normal, run_command, ['$MAKE -s --no-print-directory T10399']) test('T10313', normal, run_command, ['$MAKE -s --no-print-directory T10313']) test('T11018', normal, run_command, ['$MAKE -s --no-print-directory T11018']) test('bundle-export', normal, run_command, ['$MAKE -s --no-print-directory bundle-export']) diff --git a/testsuite/tests/ghc-api/landmines/landmines.stdout b/testsuite/tests/ghc-api/landmines/landmines.stdout index db0b651dfa0904624c469438f27a64713a0d037e..551b2cf8d7b47f7494db917d20f2bffeae0b6d32 100644 --- a/testsuite/tests/ghc-api/landmines/landmines.stdout +++ b/testsuite/tests/ghc-api/landmines/landmines.stdout @@ -1,4 +1,4 @@ (12,12,7) -(66,62,0) +(63,63,0) (13,13,7) (10,10,7) diff --git a/testsuite/tests/rename/should_compile/T5331.stderr b/testsuite/tests/rename/should_compile/T5331.stderr index 13249b0e17851d69094585f97410f736ade1d82c..965e15a9b48ffed43710e79e65a9b90149a36d40 100644 --- a/testsuite/tests/rename/should_compile/T5331.stderr +++ b/testsuite/tests/rename/should_compile/T5331.stderr @@ -5,7 +5,7 @@ T5331.hs:8:17: warning: T5331.hs:11:16: warning: Unused quantified type variable ‘a’ - In the definition of data constructor ‘W1’ + In the type ‘forall a. W’ T5331.hs:13:13: warning: Unused quantified type variable ‘a’ diff --git a/testsuite/tests/rename/should_fail/T7943.stderr b/testsuite/tests/rename/should_fail/T7943.stderr index 8594a25e2f783960c7887ca6fc7bc7cd4da754fe..c6bf7ae9b5daf4ba27874322d7e59d9e63d8d3fb 100644 --- a/testsuite/tests/rename/should_fail/T7943.stderr +++ b/testsuite/tests/rename/should_fail/T7943.stderr @@ -1,2 +1,6 @@ -T7943.hs:4:22: Record syntax is illegal here: {bar :: String} +T7943.hs:4:22: + Record syntax is illegal here: {bar :: String} + In the type ‘{bar :: String}’ + In the definition of data constructor ‘B’ + In the data declaration for ‘Foo’ \ No newline at end of file diff --git a/utils/haddock b/utils/haddock index a6deefad581cbeb62048826bc1d626c41a0dd56c..222954753de7a8a3708baff1d75a4b7c3a675f4b 160000 --- a/utils/haddock +++ b/utils/haddock @@ -1 +1 @@ -Subproject commit a6deefad581cbeb62048826bc1d626c41a0dd56c +Subproject commit 222954753de7a8a3708baff1d75a4b7c3a675f4b