3 -- Matching and unification
4 matchTys, matchTyX, matchTysX,
7 tcRefineTys, tcMatchTys, tcMatchPreds, coreRefineTys,
13 #include "HsVersions.h"
15 import Var ( Var, TyVar, tyVarKind )
18 import Kind ( isSubKind )
19 import Type ( predTypeRep, newTypeRep, typeKind,
20 tyVarsOfType, tyVarsOfTypes,
21 TvSubstEnv, TvSubst(..), substTy )
22 import TypeRep ( Type(..), PredType(..), funTyCon )
23 import Util ( snocView )
24 import ErrUtils ( Message )
30 %************************************************************************
34 %************************************************************************
37 ----------------------------
38 tcRefineTys, tcMatchTys
39 :: [TyVar] -- Try to unify these
40 -> TvSubstEnv -- Not idempotent
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)
48 tcMatchTys ex_tvs subst tys1 tys2
49 = initUM (bindOnly (mkVarSet ex_tvs)) (unify_tys Src subst tys1 tys2)
52 :: [TyVar] -- Bind these
53 -> [PredType] -> [PredType]
55 tcMatchPreds tvs preds1 preds2
56 = maybeErrToMaybe $ initUM (bindOnly (mkVarSet tvs)) $
57 unify_preds Src emptyVarEnv preds1 preds2
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
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
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) }
83 ----------------------------
84 matchTys :: TyVarSet -- Template tyvars
87 -> Maybe TvSubstEnv -- Idempotent, because when matching
88 -- the range and domain are distinct
90 -- PRE-CONDITION for matching: template variables are not free in the target
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)
98 matchTyX :: TyVarSet -- Template tyvars
99 -> TvSubstEnv -- Idempotent substitution to extend
102 -> Maybe TvSubstEnv -- Idempotent
104 matchTyX tmpls env ty1 ty2
105 = ASSERT( not (intersectsVarSet tmpls (tyVarsOfType ty2)) )
106 maybeErrToMaybe $ initUM (bindOnly tmpls)
107 (unify Src env ty1 ty2)
109 matchTysX :: TyVarSet -- Template tyvars
110 -> TvSubstEnv -- Idempotent substitution to extend
111 -> [Type] -- Template
113 -> Maybe TvSubstEnv -- Idempotent
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)
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
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
132 ----------------------------
133 tryToBind, bindOnly :: TyVarSet -> TyVar -> BindFlag
134 tryToBind tv_set tv | tv `elemVarSet` tv_set = BindMe
135 | otherwise = AvoidMe
137 bindOnly tv_set tv | tv `elemVarSet` tv_set = BindMe
138 | otherwise = DontBindMe
140 emptyTvSubstEnv :: TvSubstEnv
141 emptyTvSubstEnv = emptyVarEnv
145 %************************************************************************
149 %************************************************************************
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
161 -- ToDo: remove debugging junk
162 unify s subst ty1 ty2 = -- pprTrace "unify" (ppr subst <+> pprParendType ty1 <+> pprParendType ty2) $
163 unify_ s subst ty1 ty2
165 -- Look through NoteTy in the obvious fashion
166 unify_ s subst (NoteTy _ ty1) ty2 = unify s subst ty1 ty2
167 unify_ s subst ty1 (NoteTy _ ty2) = unify s subst ty1 ty2
169 -- In Core mode, look through NewTcApps and Preds
170 unify_ Core subst (NewTcApp tc tys) ty2 = unify Core subst (newTypeRep tc tys) ty2
171 unify_ Core subst ty1 (NewTcApp tc tys) = unify Core subst ty1 (newTypeRep tc tys)
173 unify_ Core subst (PredTy p) ty2 = unify Core subst (predTypeRep p) ty2
174 unify_ Core subst ty1 (PredTy p) = unify Core subst ty1 (predTypeRep p)
176 -- From now on, any NewTcApps/Preds should be taken at face value
178 unify_ s subst (TyVarTy tv1) ty2 = uVar s False subst tv1 ty2
179 unify_ s subst ty1 (TyVarTy tv2) = uVar s True subst tv2 ty1
181 unify_ s subst (PredTy p1) (PredTy p2) = unify_pred s subst p1 p2
183 unify_ s subst t1@(TyConApp tyc1 tys1) t2@(TyConApp tyc2 tys2)
184 | tyc1 == tyc2 = unify_tys s subst tys1 tys2
185 unify_ Src subst t1@(NewTcApp tc1 tys1) t2@(NewTcApp tc2 tys2)
186 | tc1 == tc2 = unify_tys Src subst tys1 tys2
187 unify_ s subst (FunTy ty1a ty1b) (FunTy ty2a ty2b)
188 = do { subst' <- unify s subst ty1a ty2a
189 ; unify s subst' ty1b ty2b }
191 -- Applications need a bit of care!
192 -- They can match FunTy and TyConApp, so use splitAppTy_maybe
193 -- NB: we've already dealt with type variables and Notes,
194 -- so if one type is an App the other one jolly well better be too
195 unify_ s subst (AppTy ty1a ty1b) ty2
196 | Just (ty2a, ty2b) <- unifySplitAppTy_maybe ty2
197 = do { subst' <- unify s subst ty1a ty2a
198 ; unify s subst' ty1b ty2b }
200 unify_ s subst ty1 (AppTy ty2a ty2b)
201 | Just (ty1a, ty1b) <- unifySplitAppTy_maybe ty1
202 = do { subst' <- unify s subst ty1a ty2a
203 ; unify s subst' ty1b ty2b }
205 unify_ s subst ty1 ty2 = failWith (misMatch ty1 ty2)
207 ------------------------------
208 unify_pred s subst (ClassP c1 tys1) (ClassP c2 tys2)
209 | c1 == c2 = unify_tys s subst tys1 tys2
210 unify_pred s subst (IParam n1 t1) (IParam n2 t2)
211 | n1 == n2 = unify s subst t1 t2
213 ------------------------------
214 unifySplitAppTy_maybe :: Type -> Maybe (Type,Type)
215 -- NoteTy is already dealt with; take NewTcApps at face value
216 unifySplitAppTy_maybe (FunTy ty1 ty2) = Just (TyConApp funTyCon [ty1], ty2)
217 unifySplitAppTy_maybe (AppTy ty1 ty2) = Just (ty1, ty2)
218 unifySplitAppTy_maybe (TyConApp tc tys) = case snocView tys of
219 Just (tys', ty') -> Just (TyConApp tc tys', ty')
221 unifySplitAppTy_maybe (NewTcApp tc tys) = case snocView tys of
222 Just (tys', ty') -> Just (NewTcApp tc tys', ty')
224 unifySplitAppTy_maybe other = Nothing
226 ------------------------------
227 unify_tys s = unifyList (unify s)
229 unify_preds :: SrcFlag -> TvSubstEnv -> [PredType] -> [PredType] -> UM TvSubstEnv
230 unify_preds s = unifyList (unify_pred s)
232 unifyList :: Outputable a
233 => (TvSubstEnv -> a -> a -> UM TvSubstEnv)
234 -> TvSubstEnv -> [a] -> [a] -> UM TvSubstEnv
235 unifyList unifier subst orig_xs orig_ys
236 = go subst orig_xs orig_ys
238 go subst [] [] = return subst
239 go subst (x:xs) (y:ys) = do { subst' <- unifier subst x y
241 go subst _ _ = failWith (lengthMisMatch orig_xs orig_ys)
243 ------------------------------
244 uVar :: SrcFlag -- True, unifying source types, false core types.
246 -> TvSubstEnv -- An existing substitution to extend
247 -> TyVar -- Type variable to be unified
248 -> Type -- with this type
251 uVar s swap subst tv1 ty
252 = -- check to see whether tv1 is refined
253 case (lookupVarEnv subst tv1) of
254 -- yes, call back into unify'
255 Just ty' | swap -> unify s subst ty ty'
256 | otherwise -> unify s subst ty' ty
258 Nothing -> uUnrefined subst tv1 ty
261 uUnrefined :: TvSubstEnv -- An existing substitution to extend
262 -> TyVar -- Type variable to be unified
263 -> Type -- with this type
266 -- We know that tv1 isn't refined
267 uUnrefined subst tv1 ty2@(TyVarTy tv2)
268 | tv1 == tv2 -- Same, do nothing
271 -- Check to see whether tv2 is refined
272 | Just ty' <- lookupVarEnv subst tv2
273 = uUnrefined subst tv1 ty'
275 -- So both are unrefined; next, see if the kinds force the direction
276 | k1 == k2 -- Can update either; so check the bind-flags
277 = do { b1 <- tvBindFlag tv1
278 ; b2 <- tvBindFlag tv2
280 (DontBindMe, DontBindMe) -> failWith (misMatch ty1 ty2)
281 (DontBindMe, _) -> bindTv subst tv2 ty1
282 (BindMe, _) -> bindTv subst tv1 ty2
283 (AvoidMe, BindMe) -> bindTv subst tv2 ty1
284 (AvoidMe, _) -> bindTv subst tv1 ty2
287 | k1 `isSubKind` k2 -- Must update tv2
288 = do { b2 <- tvBindFlag tv2
290 DontBindMe -> failWith (misMatch ty1 ty2)
291 other -> bindTv subst tv2 ty1
294 | k2 `isSubKind` k1 -- Must update tv1
295 = do { b1 <- tvBindFlag tv1
297 DontBindMe -> failWith (misMatch ty1 ty2)
298 other -> bindTv subst tv1 ty2
301 | otherwise = failWith (kindMisMatch tv1 ty2)
307 uUnrefined subst tv1 ty2 -- ty2 is not a type variable
308 -- Do occurs check...
309 | tv1 `elemVarSet` substTvSet subst (tyVarsOfType ty2)
310 = failWith (occursCheck tv1 ty2)
311 -- And a kind check...
313 = do { b1 <- tvBindFlag tv1
314 ; case b1 of -- And check that tv1 is bindable
315 DontBindMe -> failWith (misMatch ty1 ty2)
316 other -> bindTv subst tv1 ty2
319 = pprTrace "kind" (ppr tv1 <+> ppr k1 $$ ppr ty2 <+> ppr k2) $
320 failWith (kindMisMatch tv1 ty2)
326 substTvSet :: TvSubstEnv -> TyVarSet -> TyVarSet
327 -- Apply the non-idempotent substitution to a set of type variables,
328 -- remembering that the substitution isn't necessarily idempotent
330 = foldVarSet (unionVarSet . get) emptyVarSet tvs
332 get tv = case lookupVarEnv subst tv of
333 Nothing -> unitVarSet tv
334 Just ty -> substTvSet subst (tyVarsOfType ty)
336 bindTv subst tv ty = return (extendVarEnv subst tv ty)
339 %************************************************************************
343 %************************************************************************
346 data SrcFlag = Src | Core -- Unifying at the source level, or core level?
348 data BindFlag = BindMe | AvoidMe | DontBindMe
353 newtype UM a = UM { unUM :: (TyVar -> BindFlag)
354 -> MaybeErr a Message }
356 instance Monad UM where
357 return a = UM (\tvs -> Succeeded a)
358 fail s = UM (\tvs -> Failed (text s))
359 m >>= k = UM (\tvs -> case unUM m tvs of
360 Failed err -> Failed err
361 Succeeded v -> unUM (k v) tvs)
363 initUM :: (TyVar -> BindFlag) -> UM a -> MaybeErr a Message
364 initUM badtvs um = unUM um badtvs
366 tvBindFlag :: TyVar -> UM BindFlag
367 tvBindFlag tv = UM (\tv_fn -> Succeeded (tv_fn tv))
369 failWith :: Message -> UM a
370 failWith msg = UM (\tv_fn -> Failed msg)
372 maybeErrToMaybe :: MaybeErr succ fail -> Maybe succ
373 maybeErrToMaybe (Succeeded a) = Just a
374 maybeErrToMaybe (Failed m) = Nothing
378 %************************************************************************
381 We go to a lot more trouble to tidy the types
382 in TcUnify. Maybe we'll end up having to do that
383 here too, but I'll leave it for now.
385 %************************************************************************
389 = ptext SLIT("Can't match types") <+> quotes (ppr t1) <+>
390 ptext SLIT("and") <+> quotes (ppr t2)
392 lengthMisMatch tys1 tys2
393 = sep [ptext SLIT("Can't match unequal length lists"),
394 nest 2 (ppr tys1), nest 2 (ppr tys2) ]
397 = vcat [ptext SLIT("Can't match kinds") <+> quotes (ppr (tyVarKind tv1)) <+>
398 ptext SLIT("and") <+> quotes (ppr (typeKind t2)),
399 ptext SLIT("when matching") <+> quotes (ppr tv1) <+>
400 ptext SLIT("with") <+> quotes (ppr t2)]
403 = hang (ptext SLIT("Can't construct the infinite type"))
404 2 (ppr tv <+> equals <+> ppr ty)