$NetBSD: patch-ag,v 1.1 2004/01/16 00:59:18 kristerw Exp $ --- src/compiler98/TypeUnify.hs.orig 20 Feb 2003 18:23:29 +++ src/compiler98/TypeUnify.hs 1 Apr 2003 13:54:36 @@ -3,7 +3,7 @@ -} module TypeUnify(unify,unifyr) where -import NT(NT(..),NewType(..),freeNT,strNT) +import NT(NT(..),NewType(..),freeNT,strNT,anyVarNT) import IdKind import TypeSubst import TypeUtil @@ -20,12 +20,12 @@ unify state phi (t1@(NTany tvn1),t2) = case applySubst phi tvn1 of - Nothing -> extend phi tvn1 (subst phi t2) + Nothing -> extendV state phi tvn1 (subst phi t2) Just phitvn -> unify state phi (phitvn,subst phi t2) unify state phi (t1@(NTvar tvn1),(NTany tvn2)) = case applySubst phi tvn2 of - Nothing -> extend phi tvn2 (subst phi t1) + Nothing -> extendV state phi tvn2 (subst phi t1) Just phitvn -> unify state phi (phitvn,subst phi t1) unify state phi (t1@(NTvar tvn1),t2) = @@ -35,7 +35,7 @@ unify state phi (t1@(NTcons _ _),t2@(NTany tvn2)) = case applySubst phi tvn2 of - Nothing -> extend phi tvn2 (subst phi t1) + Nothing -> extendV state phi tvn2 (subst phi t1) Just phitvn -> unify state phi (phitvn,subst phi t1) unify state phi (t1@(NTcons _ _),t2@(NTvar tvn2)) = @@ -81,13 +81,13 @@ unify state phi (t1@(NTapp ta1 tb1),t2@(NTany tvn2)) = -- strace ("unify(2) " ++ show t1 ++ " " ++ show t2) $ case applySubst phi tvn2 of - Nothing -> extend phi tvn2 (subst phi t1) + Nothing -> extendV state phi tvn2 (subst phi t1) Just phitvn -> unify state phi (phitvn,subst phi t1) unify state phi (t1@(NTapp ta1 tb1),t2@(NTvar tvn2)) = -- strace ("unify(3) " ++ show t1 ++ " " ++ show t2) $ case applySubst phi tvn2 of - Nothing -> extend phi tvn2 (subst phi t1) + Nothing -> extendV state phi tvn2 (subst phi t1) Just phitvn -> unify state phi (phitvn,subst phi t1) unify state phi (t1@(NTapp ta1 tb1),t2@(NTcons c2 ts2)) = @@ -130,7 +130,7 @@ unify state phi (t1@(NTexist e),t2@(NTany tvn2)) = -- strace ("unify exist " ++ show e ++ " any " ++ show tvn2) $ case applySubst phi tvn2 of - Nothing -> extend phi tvn2 (subst phi t1) + Nothing -> extendV state phi tvn2 (subst phi t1) Just phitvn -> unify state phi (phitvn,subst phi t1) unify state phi (t1@(NTexist e),t2@(NTvar tvn2)) = @@ -166,6 +166,8 @@ ------ +-- expand any type synonym at top, so that none is at top in result +expandAll :: IntState -> NT -> NT expandAll state t@(NTcons tcon ts) = case unifyExpand state tcon of Left _ -> t @@ -178,6 +180,15 @@ Right _ -> False Left _ -> True +-- expand all type synonyms, so that none is left in result +fullyExpand :: IntState -> NT -> NT +fullyExpand state t = + case expandAll state t of + NTstrict t -> NTstrict (fullyExpand state t) + NTapp t1 t2 -> NTapp (fullyExpand state t1) (fullyExpand state t2) + NTcons id ts -> NTcons id (map (fullyExpand state) ts) + t -> t + {- If tcon is a type synoym, then unifyExpand returns the depth and the definition body of the type synoym. @@ -205,27 +216,26 @@ expand (NewType free [] ctxs [nt]) ts = subst (list2Subst (zip free ts)) nt - +{- +Extends substitution by subtitution of `t' for `tvn'. +Performs occurrence check and assures that replacement of `tvn' is a type +variable, if `t' expands to a type variable. +-} extendV :: IntState -> AssocTree Id NT -> Id -> NT -> Either (AssocTree Id NT, String) (AssocTree Id NT) -extendV state phi tvn t@(NTcons c _) = - if unboxedIS state c then - Left (phi,"polymorphic type variable bound to unboxed data " ++ strIS state c) - else - extend phi tvn t extendV state phi tvn t = - extend phi tvn t + let t' = expandAll state t + in case anyVarNT t' of + Just tvn' -> if tvn' == tvn + then Right phi + else Right (addSubst phi tvn t') + Nothing -> + if tvn `elem` freeNT t' + then let t'' = fullyExpand state t' + -- expansion may have less free variables + in if tvn `elem` freeNT t'' + then Left (phi,"(type-variable occurrence check fails)") + else Right (addSubst phi tvn t'') + else Right (addSubst phi tvn t) -- do not expand unnecessarily -extend phi tvn t@(NTany tvn') = - if tvn' == tvn - then Right phi - else Right (addSubst phi tvn t) -extend phi tvn t@(NTvar tvn') = - if tvn' == tvn - then Right phi - else Right (addSubst phi tvn t) -extend phi tvn t | tvn `elem` freeNT t = - Left (phi,"(type-variable occurrence check fails)") -extend phi tvn t@(NTcons c _) = Right (addSubst phi tvn t) -extend phi tvn t = Right (addSubst phi tvn t)