--Type checking base language declarations (the D structure)
module TiD where import Maybe(isJust) import Monad(unless) import HsDeclStruct import HsDeclUtil(unbang) import SrcLoc(srcLoc) import HasBaseStruct import TI hiding (Subst) import TiDkc --import TiDinst(tcSelFns) import TiE(tcDsLambda') import TiClassInst -- preserves class and instance declarations --import TiClassInst2(tcInstDecl) -- translates class and instance declarations --import HsExpStruct(EI) import HsPatStruct(PI) import HsIdent(mapHsIdent2) import MUtils(apFst,( # )) import SimpleGraphs(reachable') import PrettyPrint(Printable,pp) -- For debugging only: --import IOExts(trace) --mtrace s = trace s $ done mapVars f = map $ emap $ mapHsIdent2 f id instance (TypeVar i,ValueId i,DefinedNames i p,HasId i p,DeclInfo i ds) => DeclInfo i (Dinst i e p ds) where isUnrestricted expl d = case d of HsPatBind s p rhs ds -> expl && isJust (isVar p) _ -> True {- isTypeDecl d = case d of HsTypeDecl {} -> True HsNewTypeDecl {} -> True HsDataDecl {} -> True HsClassDecl {} -> True HsPrimitiveTypeDecl {} -> True _ -> False -} explicitlyTyped kenv tinfo ctx d = apFst (map addKind) $ case d of HsTypeDecl s tp t -> (tiType tp t,[]) HsNewTypeDecl s ctx tp cd drv -> (tiNewtype ctx tp, constrTypes ctx tp cd) HsDataDecl s ctx tp cds drv -> (tiData ctx tp, concatMap (constrTypes ctx tp) cds) HsClassDecl s c tp fdeps ds -> (tiClass kenv tinfo c tp fdeps ds,ms++dms) where ms =snd (explicitlyTyped kenv tinfo [tp] ds) dms = mapVars defaultName ms HsInstDecl s optn c tp ds -> ([],[]) HsDefaultDecl s t -> ([],[]) HsTypeSig s nms c t -> ([],[HsVar n:>:kuscheme kenv ((ctx++c):=>t)|n<-nms]) HsFunBind s matches -> ([],[]) HsPatBind s p rhs ds -> ([],[]) HsInfixDecl s fixity names -> ([],[]) HsPrimitiveTypeDecl s ctx tp -> (tiData ctx tp,[]) HsPrimitiveBind s nm tp -> ([],[HsVar nm:>:kupscheme kenv tp]) -- _ -> [] where addKind (c:>:tinfo) = c:>:(kind,tinfo) where [kind] = [k|c':>:k<-kenv,c'==c] constrTypes ctx tp con = case con of HsConDecl s evs ectx c bangts -> -- !!! [HsCon c :>: conT ectx (map unbang bangts)] HsRecDecl s evs ectx c fields -> -- !!! (HsCon c :>: conT ectx args): [HsVar f :>: kupscheme kenv (lhsT `hsTyFun` t)|(f,t)<-fs] where fs = [(f,t)|(fs,bt)<-fields,let t=unbang bt,f<-fs] args = map snd fs where conT ectx args = kuscheme kenv (ectx:=>funT (args++[lhsT])) lhsT = tp {- instance (Fresh i,TypeId i,Printable i, TypeCheck i e1 (Typed i e2), DefinedNames i p1,TypeCheck i p1 (Typed i p2), DefinedNames i ds1,Printable ds1,TypeCheckDecls i ds1 ds2, HasMethodSigs ds1,HasTypeAnnot i e2, HasBaseStruct d2 (Dinst i e2 p2 ds2),HasDef ds2 d2, -- Extra stuff for constructing field selector functions: HasDef ds1 d1,HasBaseStruct p1 (PI i p1), HasBaseStruct e1 (Einst i e1 p1 ds1), -- Extra stuff for translating class and instance declarations -- (using module TiClassInst2): ValueId i,HasId i e1,HasId i p1, HasBaseStruct d1 (Dinst i e1 p1 ds1),Printable d1, HasId i e2,HasId i p2,HasAbstr i d2,HasAbstr i ds2, HasBaseStruct e2 (Einst i e2 p2 ds2),DefinedNames i p2, --GetSigs i [Pred i] (Pred i) ds2,DeclInfo i ds2, MapDefinedNames i ds2, AddDeclsType i ds2) => TypeCheckDecl i (Dinst i e1 p1 ds1) ds2 where tcDecl = tcD -} tcD bs d = posContext' (srcLoc d) "(type check)" $ case d of HsTypeDecl s tp t -> retOne (hsTypeDecl s tp t) HsNewTypeDecl s ctx tp cd drv -> retOne (hsNewTypeDecl s ctx tp cd drv) HsDataDecl s ctx tp cds drv -> tcDataDecl d bs s ctx tp cds drv HsClassDecl s c tp fdeps ds -> tcClassDecl s c tp fdeps ds HsInstDecl s optn c tp ds -> tcInstDecl s optn c tp ds HsDefaultDecl s t -> retOne (hsDefaultDecl s t) HsTypeSig s nms c tp -> retOne (hsTypeSig s nms c tp) HsFunBind s matches -> oneDef # tcFunBind bs s matches HsPatBind s p rhs ds -> oneDef # tcPatBind bs s p rhs ds HsInfixDecl s fixity names -> retOne (hsInfixDecl s fixity names) HsPrimitiveTypeDecl s ctx tp -> retOne (hsPrimitiveTypeDecl s ctx tp) HsPrimitiveBind s nm tp -> oneDef # tcPrimBind bs s nm tp retOne = return . oneDef tcDataDecl d bs s ctx tp cds drv = retOne (hsDataDecl s ctx tp cds drv) {- do selfns <- tcSelFns [d] bs cds return (hsDataDecl s ctx tp cds drv `consDef` selfns) -} tcPrimBind bs s nm t = do t' <- varinst' bs nm t'=:=t return $ hsPrimitiveBind s nm t tcFunBind bs s matches@(HsMatch _ n _ _ _:_) = do ms :>: ts <- unzipTyped # mapM tcMatch matches t <- varinst' bs n mapM_ (t=:=) ts return $ hsFunBind s ms varinst' bs n = case [ t |HsVar x:>:t<-bs,x==n] of t:_ -> return t _ -> tfresh -- needed for selector functions generated in tcSelFns... --fail$"Type checker bug: no type introduced for: "++pp n tcMatch (HsMatch s n ps rhs ds) = do (ps',ds',rhs'):>:t <- tcDsLambda' ps ds rhs HsMatch s n ps' rhs' ds' >: t tcPatBind bs s p rhs ds = do p':>:tp <- extendts ((map (fmap mono) bs)) (tc p) (ds',rhs'):>:trhs <- tcDsRhs ds rhs tp=:=trhs return (hsPatBind s p' rhs' ds') tcDsRhs ds rhs = do ds':>:bs <- tcLocalDecls ds rhs':>:trhs <- extendts bs (tc rhs) (ds',rhs')>:trhs
Type synonyms may not be recursive (H98 report, section 4.2.2). This check has to be made before type checking, since recursive type synonyms can cause the current implementation of the type checker to loop!
checkTypeSynRec ds =
unless (null recsyns) $
declContext recsyns $
fail "Recursive type synonym"
where
recsyns = [syn|(syn,_)<-g,syn `elem` reachable' g [syn]]
g = [(i,free) | Just d@(HsTypeDecl s tp t)<-map basestruct ds,
let free=freeTypeNames t,
i<-definedTypeNames tp]
The superclass relation must be not be cyclic (H98 report, section 4.3.1). This check has to be made before type checking, since a cyclic superclass relation can cause the current implementation of the type checker to loop!
checkClassRec ds =
unless (null recclasses) $
declContext recclasses $
fail "The superclass relation must be not be cyclic"
where
recclasses = [c|(c,_)<-g,c `elem` reachable' g [c]]
g = [(i,free) | Just d@(HsClassDecl s ctx tp fdeps ds)<-map basestruct ds,
let free=freeTypeNames ctx,
i<-definedTypeNames tp]