[project @ 2004-10-01 13:42:04 by simonpj]
[ghc-hetmet.git] / ghc / compiler / types / Unify.lhs
1 \begin{code}
2 module Unify ( 
3         -- Matching and unification
4         matchTys, matchTyX, matchTysX,
5         unifyTys, unifyTysX,
6
7         tcRefineTys, tcMatchTys, tcMatchPreds, coreRefineTys,
8
9         -- Re-export
10         MaybeErr(..)
11    ) where
12
13 #include "HsVersions.h"
14
15 import Var              ( Var, TyVar, tyVarKind )
16 import VarEnv
17 import VarSet
18 import Kind             ( isSubKind )
19 import Type             ( predTypeRep, typeKind, 
20                           tyVarsOfType, tyVarsOfTypes, coreView,
21                           TvSubstEnv, TvSubst(..), substTy )
22 import TypeRep          ( Type(..), PredType(..), funTyCon )
23 import Util             ( snocView )
24 import ErrUtils         ( Message )
25 import Outputable
26 import Maybes
27 \end{code}
28
29
30 %************************************************************************
31 %*                                                                      *
32                 External interface
33 %*                                                                      *
34 %************************************************************************
35
36 \begin{code}
37 ----------------------------
38 tcRefineTys, tcMatchTys 
39         :: [TyVar]                      -- Try to unify these
40         -> TvSubstEnv                   -- Not idempotent
41         -> [Type] -> [Type]
42         -> MaybeErr TvSubstEnv Message  -- Not idempotent
43 -- This one is used by the type checker.  Neither the input nor result
44 -- substitition is idempotent
45 tcRefineTys ex_tvs subst tys1 tys2
46   = initUM (tryToBind (mkVarSet ex_tvs)) (unify_tys Src subst tys1 tys2)
47
48 tcMatchTys ex_tvs subst tys1 tys2
49   = initUM (bindOnly (mkVarSet ex_tvs)) (unify_tys Src subst tys1 tys2)
50
51 tcMatchPreds
52         :: [TyVar]                      -- Bind these
53         -> [PredType] -> [PredType]
54         -> Maybe TvSubstEnv
55 tcMatchPreds tvs preds1 preds2
56   = maybeErrToMaybe $ initUM (bindOnly (mkVarSet tvs)) $
57     unify_preds Src emptyVarEnv preds1 preds2
58
59 ----------------------------
60 coreRefineTys :: [TyVar]        -- Try to unify these
61               -> TvSubst        -- A full-blown apply-once substitition
62               -> Type           -- A fixed point of the incoming substitution
63               -> Type
64               -> Maybe TvSubstEnv       -- In-scope set is unaffected
65 -- Used by Core Lint and the simplifier.  Takes a full apply-once substitution.
66 -- The incoming substitution's in-scope set should mention all the variables free 
67 -- in the incoming types
68 coreRefineTys ex_tvs subst@(TvSubst in_scope orig_env) ty1 ty2
69   = maybeErrToMaybe $ initUM (tryToBind (mkVarSet ex_tvs)) $
70     do  {       -- Apply the input substitution; nothing int ty2
71           let ty1' = substTy subst ty1  
72                 -- Run the unifier, starting with an empty env
73         ; extra_env <- unify Src emptyTvSubstEnv ty1' ty2
74
75                 -- Find the fixed point of the resulting non-idempotent
76                 -- substitution, and apply it to the 
77         ; let extra_subst     = TvSubst in_scope extra_env_fixpt
78               extra_env_fixpt = mapVarEnv (substTy extra_subst) extra_env
79               orig_env'       = mapVarEnv (substTy extra_subst) orig_env
80         ; return (orig_env' `plusVarEnv` extra_env_fixpt) }
81     
82
83 ----------------------------
84 matchTys :: TyVarSet            -- Template tyvars
85          -> [Type]              -- Template
86          -> [Type]              -- Target
87          -> Maybe TvSubstEnv    -- Idempotent, because when matching
88                                 --      the range and domain are distinct
89
90 -- PRE-CONDITION for matching: template variables are not free in the target
91
92 matchTys tmpls tys1 tys2
93   = ASSERT2( not (intersectsVarSet tmpls (tyVarsOfTypes tys2)),
94              ppr tmpls $$ ppr tys1 $$ ppr tys2 )
95     maybeErrToMaybe $ initUM (bindOnly tmpls)
96                              (unify_tys Src emptyTvSubstEnv tys1 tys2)
97
98 matchTyX :: TyVarSet            -- Template tyvars
99          -> TvSubstEnv          -- Idempotent substitution to extend
100          -> Type                -- Template
101          -> Type                -- Target
102          -> Maybe TvSubstEnv    -- Idempotent
103
104 matchTyX tmpls env ty1 ty2
105   = ASSERT( not (intersectsVarSet tmpls (tyVarsOfType ty2)) )
106     maybeErrToMaybe $ initUM (bindOnly tmpls)
107                              (unify Src env ty1 ty2)
108
109 matchTysX :: TyVarSet           -- Template tyvars
110           -> TvSubstEnv         -- Idempotent substitution to extend
111           -> [Type]             -- Template
112           -> [Type]             -- Target
113           -> Maybe TvSubstEnv   -- Idempotent
114
115 matchTysX tmpls env tys1 tys2
116   = ASSERT( not (intersectsVarSet tmpls (tyVarsOfTypes tys2)) )
117     maybeErrToMaybe $ initUM (bindOnly tmpls) 
118                              (unify_tys Src env tys1 tys2)
119
120
121 ----------------------------
122 unifyTys :: TyVarSet -> [Type] -> [Type] -> Maybe TvSubstEnv
123 unifyTys bind_these tys1 tys2
124   = maybeErrToMaybe $ initUM (bindOnly bind_these) $
125     unify_tys Src emptyTvSubstEnv tys1 tys2
126
127 unifyTysX :: TyVarSet -> TvSubstEnv -> [Type] -> [Type] -> Maybe TvSubstEnv
128 unifyTysX bind_these subst tys1 tys2
129   = maybeErrToMaybe $ initUM (bindOnly bind_these) $
130     unify_tys Src subst tys1 tys2
131
132 ----------------------------
133 tryToBind, bindOnly :: TyVarSet -> TyVar -> BindFlag
134 tryToBind tv_set tv | tv `elemVarSet` tv_set = BindMe
135                     | otherwise              = AvoidMe
136
137 bindOnly tv_set tv | tv `elemVarSet` tv_set = BindMe
138                    | otherwise              = DontBindMe
139
140 emptyTvSubstEnv :: TvSubstEnv
141 emptyTvSubstEnv = emptyVarEnv
142 \end{code}
143
144
145 %************************************************************************
146 %*                                                                      *
147                 The workhorse
148 %*                                                                      *
149 %************************************************************************
150
151 \begin{code}
152 unify :: SrcFlag                -- True, unifying source types, false core types.
153       -> TvSubstEnv             -- An existing substitution to extend
154       -> Type -> Type           -- Types to be unified
155       -> UM TvSubstEnv          -- Just the extended substitution, 
156                                 -- Nothing if unification failed
157 -- We do not require the incoming substitution to be idempotent,
158 -- nor guarantee that the outgoing one is.  That's fixed up by
159 -- the wrappers.
160
161 unify s subst ty1 ty2 = -- pprTrace "unify" (ppr subst <+> pprParendType ty1 <+> pprParendType ty2) $
162                         unify_ s subst (rep s ty1) (rep s ty2)
163
164 rep :: SrcFlag -> Type -> Type  -- Strip off the clutter
165 rep Src (NoteTy _ ty)                 = rep Src  ty
166 rep Core ty | Just ty' <- coreView ty = rep Core ty'
167 rep s    ty                           = ty
168
169 -- in unify_, any NewTcApps/Preds should be taken at face value
170 unify_ s subst (TyVarTy tv1) ty2  = uVar s False subst tv1 ty2
171 unify_ s subst ty1 (TyVarTy tv2)  = uVar s True  subst tv2 ty1
172
173 unify_ s subst (PredTy p1) (PredTy p2) = unify_pred s subst p1 p2
174
175 unify_ s subst t1@(TyConApp tyc1 tys1) t2@(TyConApp tyc2 tys2) 
176   | tyc1 == tyc2 = unify_tys s subst tys1 tys2
177
178 unify_ s subst (FunTy ty1a ty1b) (FunTy ty2a ty2b) 
179   = do { subst' <- unify s subst ty1a ty2a
180        ; unify s subst' ty1b ty2b }
181
182         -- Applications need a bit of care!
183         -- They can match FunTy and TyConApp, so use splitAppTy_maybe
184         -- NB: we've already dealt with type variables and Notes,
185         -- so if one type is an App the other one jolly well better be too
186 unify_ s subst (AppTy ty1a ty1b) ty2
187   | Just (ty2a, ty2b) <- unifySplitAppTy_maybe ty2
188   = do  { subst' <- unify s subst ty1a ty2a
189         ; unify s subst' ty1b ty2b }
190
191 unify_ s subst ty1 (AppTy ty2a ty2b)
192   | Just (ty1a, ty1b) <- unifySplitAppTy_maybe ty1
193   = do  { subst' <- unify s subst ty1a ty2a
194         ; unify s subst' ty1b ty2b }
195
196 unify_ s subst ty1 ty2 = failWith (misMatch ty1 ty2)
197
198 ------------------------------
199 unify_pred s subst (ClassP c1 tys1) (ClassP c2 tys2)
200   | c1 == c2 = unify_tys s subst tys1 tys2
201 unify_pred s subst (IParam n1 t1) (IParam n2 t2)
202   | n1 == n2 = unify s subst t1 t2
203  
204 ------------------------------
205 unifySplitAppTy_maybe :: Type -> Maybe (Type,Type)
206 -- NoteTy is already dealt with; take NewTcApps at face value
207 unifySplitAppTy_maybe (FunTy ty1 ty2)   = Just (TyConApp funTyCon [ty1], ty2)
208 unifySplitAppTy_maybe (AppTy ty1 ty2)   = Just (ty1, ty2)
209 unifySplitAppTy_maybe (TyConApp tc tys) = case snocView tys of
210                                                 Just (tys', ty') -> Just (TyConApp tc tys', ty')
211                                                 Nothing          -> Nothing
212 unifySplitAppTy_maybe other = Nothing
213
214 ------------------------------
215 unify_tys s   = unifyList (unify s)
216
217 unify_preds :: SrcFlag -> TvSubstEnv -> [PredType] -> [PredType] -> UM TvSubstEnv
218 unify_preds s = unifyList (unify_pred s)
219
220 unifyList :: Outputable a 
221           => (TvSubstEnv -> a -> a -> UM TvSubstEnv)
222           -> TvSubstEnv -> [a] -> [a] -> UM TvSubstEnv
223 unifyList unifier subst orig_xs orig_ys
224   = go subst orig_xs orig_ys
225   where
226     go subst []     []     = return subst
227     go subst (x:xs) (y:ys) = do { subst' <- unifier subst x y
228                                 ; go subst' xs ys }
229     go subst _      _      = failWith (lengthMisMatch orig_xs orig_ys)
230
231 ------------------------------
232 uVar :: SrcFlag         -- True, unifying source types, false core types.
233      -> Bool            -- Swapped
234      -> TvSubstEnv      -- An existing substitution to extend
235      -> TyVar           -- Type variable to be unified
236      -> Type            -- with this type
237      -> UM TvSubstEnv
238
239 uVar s swap subst tv1 ty
240  = -- check to see whether tv1 is refined
241    case (lookupVarEnv subst tv1) of
242      -- yes, call back into unify'
243      Just ty' | swap      -> unify s subst ty ty' 
244               | otherwise -> unify s subst ty' ty
245      -- No, continue
246      Nothing          -> uUnrefined subst tv1 ty
247
248
249 uUnrefined :: TvSubstEnv          -- An existing substitution to extend
250            -> TyVar               -- Type variable to be unified
251            -> Type                -- with this type
252            -> UM TvSubstEnv
253
254 -- We know that tv1 isn't refined
255 uUnrefined subst tv1 ty2@(TyVarTy tv2)
256   | tv1 == tv2    -- Same, do nothing
257   = return subst
258
259     -- Check to see whether tv2 is refined
260   | Just ty' <- lookupVarEnv subst tv2
261   = uUnrefined subst tv1 ty'
262
263   -- So both are unrefined; next, see if the kinds force the direction
264   | k1 == k2    -- Can update either; so check the bind-flags
265   = do  { b1 <- tvBindFlag tv1
266         ; b2 <- tvBindFlag tv2
267         ; case (b1,b2) of
268             (DontBindMe, DontBindMe) -> failWith (misMatch ty1 ty2)
269             (DontBindMe, _)          -> bindTv subst tv2 ty1
270             (BindMe, _)              -> bindTv subst tv1 ty2
271             (AvoidMe, BindMe)        -> bindTv subst tv2 ty1
272             (AvoidMe, _)             -> bindTv subst tv1 ty2
273         }
274
275   | k1 `isSubKind` k2   -- Must update tv2
276   = do  { b2 <- tvBindFlag tv2
277         ; case b2 of
278             DontBindMe -> failWith (misMatch ty1 ty2)
279             other      -> bindTv subst tv2 ty1
280         }
281
282   | k2 `isSubKind` k1   -- Must update tv1
283   = do  { b1 <- tvBindFlag tv1
284         ; case b1 of
285             DontBindMe -> failWith (misMatch ty1 ty2)
286             other      -> bindTv subst tv1 ty2
287         }
288
289   | otherwise = failWith (kindMisMatch tv1 ty2)
290   where
291     ty1 = TyVarTy tv1
292     k1 = tyVarKind tv1
293     k2 = tyVarKind tv2
294
295 uUnrefined subst tv1 ty2        -- ty2 is not a type variable
296         -- Do occurs check...
297   | tv1 `elemVarSet` substTvSet subst (tyVarsOfType ty2)
298   = failWith (occursCheck tv1 ty2)
299         -- And a kind check...
300   | k2 `isSubKind` k1
301   = do  { b1 <- tvBindFlag tv1
302         ; case b1 of            -- And  check that tv1 is bindable
303             DontBindMe -> failWith (misMatch ty1 ty2)
304             other      -> bindTv subst tv1 ty2
305         }
306   | otherwise
307   = pprTrace "kind" (ppr tv1 <+> ppr k1 $$ ppr ty2 <+> ppr k2) $
308     failWith (kindMisMatch tv1 ty2)
309   where
310     ty1 = TyVarTy tv1
311     k1 = tyVarKind tv1
312     k2 = typeKind ty2
313
314 substTvSet :: TvSubstEnv -> TyVarSet -> TyVarSet
315 -- Apply the non-idempotent substitution to a set of type variables,
316 -- remembering that the substitution isn't necessarily idempotent
317 substTvSet subst tvs
318   = foldVarSet (unionVarSet . get) emptyVarSet tvs
319   where
320     get tv = case lookupVarEnv subst tv of
321                 Nothing -> unitVarSet tv
322                 Just ty -> substTvSet subst (tyVarsOfType ty)
323
324 bindTv subst tv ty = return (extendVarEnv subst tv ty)
325 \end{code}
326
327 %************************************************************************
328 %*                                                                      *
329                 Unification monad
330 %*                                                                      *
331 %************************************************************************
332
333 \begin{code}
334 data SrcFlag = Src | Core       -- Unifying at the source level, or core level?
335
336 data BindFlag = BindMe | AvoidMe | DontBindMe
337
338 isCore Core = True
339 isCore Src  = False
340
341 newtype UM a = UM { unUM :: (TyVar -> BindFlag)
342                          -> MaybeErr a Message }
343
344 instance Monad UM where
345   return a = UM (\tvs -> Succeeded a)
346   fail s   = UM (\tvs -> Failed (text s))
347   m >>= k  = UM (\tvs -> case unUM m tvs of
348                            Failed err -> Failed err
349                            Succeeded v  -> unUM (k v) tvs)
350
351 initUM :: (TyVar -> BindFlag) -> UM a -> MaybeErr a Message
352 initUM badtvs um = unUM um badtvs
353
354 tvBindFlag :: TyVar -> UM BindFlag
355 tvBindFlag tv = UM (\tv_fn -> Succeeded (tv_fn tv))
356
357 failWith :: Message -> UM a
358 failWith msg = UM (\tv_fn -> Failed msg)
359
360 maybeErrToMaybe :: MaybeErr succ fail -> Maybe succ
361 maybeErrToMaybe (Succeeded a) = Just a
362 maybeErrToMaybe (Failed m)    = Nothing
363 \end{code}
364
365
366 %************************************************************************
367 %*                                                                      *
368                 Error reporting
369         We go to a lot more trouble to tidy the types
370         in TcUnify.  Maybe we'll end up having to do that
371         here too, but I'll leave it for now.
372 %*                                                                      *
373 %************************************************************************
374
375 \begin{code}
376 misMatch t1 t2
377   = ptext SLIT("Can't match types") <+> quotes (ppr t1) <+> 
378     ptext SLIT("and") <+> quotes (ppr t2)
379
380 lengthMisMatch tys1 tys2
381   = sep [ptext SLIT("Can't match unequal length lists"), 
382          nest 2 (ppr tys1), nest 2 (ppr tys2) ]
383
384 kindMisMatch tv1 t2
385   = vcat [ptext SLIT("Can't match kinds") <+> quotes (ppr (tyVarKind tv1)) <+> 
386             ptext SLIT("and") <+> quotes (ppr (typeKind t2)),
387           ptext SLIT("when matching") <+> quotes (ppr tv1) <+> 
388                 ptext SLIT("with") <+> quotes (ppr t2)]
389
390 occursCheck tv ty
391   = hang (ptext SLIT("Can't construct the infinite type"))
392        2 (ppr tv <+> equals <+> ppr ty)
393 \end{code}