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, typeKind,
20 tyVarsOfType, tyVarsOfTypes, coreView,
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 unify s subst ty1 ty2 = -- pprTrace "unify" (ppr subst <+> pprParendType ty1 <+> pprParendType ty2) $
162 unify_ s subst (rep s ty1) (rep s ty2)
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'
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
173 unify_ s subst (PredTy p1) (PredTy p2) = unify_pred s subst p1 p2
175 unify_ s subst t1@(TyConApp tyc1 tys1) t2@(TyConApp tyc2 tys2)
176 | tyc1 == tyc2 = unify_tys s subst tys1 tys2
178 unify_ s subst (FunTy ty1a ty1b) (FunTy ty2a ty2b)
179 = do { subst' <- unify s subst ty1a ty2a
180 ; unify s subst' ty1b ty2b }
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 }
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 }
196 unify_ s subst ty1 ty2 = failWith (misMatch ty1 ty2)
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
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')
212 unifySplitAppTy_maybe other = Nothing
214 ------------------------------
215 unify_tys s = unifyList (unify s)
217 unify_preds :: SrcFlag -> TvSubstEnv -> [PredType] -> [PredType] -> UM TvSubstEnv
218 unify_preds s = unifyList (unify_pred s)
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
226 go subst [] [] = return subst
227 go subst (x:xs) (y:ys) = do { subst' <- unifier subst x y
229 go subst _ _ = failWith (lengthMisMatch orig_xs orig_ys)
231 ------------------------------
232 uVar :: SrcFlag -- True, unifying source types, false core types.
234 -> TvSubstEnv -- An existing substitution to extend
235 -> TyVar -- Type variable to be unified
236 -> Type -- with this type
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
246 Nothing -> uUnrefined subst tv1 ty
249 uUnrefined :: TvSubstEnv -- An existing substitution to extend
250 -> TyVar -- Type variable to be unified
251 -> Type -- with this type
254 -- We know that tv1 isn't refined
255 uUnrefined subst tv1 ty2@(TyVarTy tv2)
256 | tv1 == tv2 -- Same, do nothing
259 -- Check to see whether tv2 is refined
260 | Just ty' <- lookupVarEnv subst tv2
261 = uUnrefined subst tv1 ty'
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
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
275 | k1 `isSubKind` k2 -- Must update tv2
276 = do { b2 <- tvBindFlag tv2
278 DontBindMe -> failWith (misMatch ty1 ty2)
279 other -> bindTv subst tv2 ty1
282 | k2 `isSubKind` k1 -- Must update tv1
283 = do { b1 <- tvBindFlag tv1
285 DontBindMe -> failWith (misMatch ty1 ty2)
286 other -> bindTv subst tv1 ty2
289 | otherwise = failWith (kindMisMatch tv1 ty2)
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...
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
307 = pprTrace "kind" (ppr tv1 <+> ppr k1 $$ ppr ty2 <+> ppr k2) $
308 failWith (kindMisMatch tv1 ty2)
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
318 = foldVarSet (unionVarSet . get) emptyVarSet tvs
320 get tv = case lookupVarEnv subst tv of
321 Nothing -> unitVarSet tv
322 Just ty -> substTvSet subst (tyVarsOfType ty)
324 bindTv subst tv ty = return (extendVarEnv subst tv ty)
327 %************************************************************************
331 %************************************************************************
334 data SrcFlag = Src | Core -- Unifying at the source level, or core level?
336 data BindFlag = BindMe | AvoidMe | DontBindMe
341 newtype UM a = UM { unUM :: (TyVar -> BindFlag)
342 -> MaybeErr a Message }
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)
351 initUM :: (TyVar -> BindFlag) -> UM a -> MaybeErr a Message
352 initUM badtvs um = unUM um badtvs
354 tvBindFlag :: TyVar -> UM BindFlag
355 tvBindFlag tv = UM (\tv_fn -> Succeeded (tv_fn tv))
357 failWith :: Message -> UM a
358 failWith msg = UM (\tv_fn -> Failed msg)
360 maybeErrToMaybe :: MaybeErr succ fail -> Maybe succ
361 maybeErrToMaybe (Succeeded a) = Just a
362 maybeErrToMaybe (Failed m) = Nothing
366 %************************************************************************
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.
373 %************************************************************************
377 = ptext SLIT("Can't match types") <+> quotes (ppr t1) <+>
378 ptext SLIT("and") <+> quotes (ppr t2)
380 lengthMisMatch tys1 tys2
381 = sep [ptext SLIT("Can't match unequal length lists"),
382 nest 2 (ppr tys1), nest 2 (ppr tys2) ]
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)]
391 = hang (ptext SLIT("Can't construct the infinite type"))
392 2 (ppr tv <+> equals <+> ppr ty)