-- Used for "rough matching"; same idea as for class instances
, fi_tcs :: [Maybe Name] -- Top of type args
- -- INVARIANT: fi_tcs = roughMatchTcs is_tys
+ -- INVARIANT: fi_tcs = roughMatchTcs fi_tys
-- Used for "proper matching"; ditto
, fi_tvs :: TyVarSet -- Template tyvars for full match
pprFamInst :: FamInst -> SDoc
pprFamInst famInst
= hang (pprFamInstHdr famInst)
- 2 (ptext SLIT("--") <+> (pprDefnLoc (getSrcLoc famInst)))
+ 2 (ptext SLIT("--") <+> (pprDefnLoc (getSrcSpan famInst)))
pprFamInstHdr :: FamInst -> SDoc
pprFamInstHdr (FamInst {fi_fam = fam, fi_tys = tys, fi_tycon = tycon})
families), and then, it doesn't matter which match we choose (as the
instances are guaranteed confluent).
+We return the matching family instances and the type instance at which it
+matches. For example, if we lookup 'T [Int]' and have a family instance
+
+ data instance T [a] = ..
+
+desugared to
+
+ data :R42T a = ..
+ coe :Co:R42T a :: T [a] ~ :R42T a
+
+we return the matching instance '(FamInst{.., fi_tycon = :R42T}, Int)'.
+
\begin{code}
+type FamInstMatch = (FamInst, [Type]) -- Matching type instance
+
lookupFamInstEnv :: FamInstEnvs
-> TyCon -> [Type] -- What we are looking for
- -> [(TvSubst, FamInst)] -- Successful matches
+ -> [FamInstMatch] -- Successful matches
lookupFamInstEnv (pkg_ie, home_ie) fam tys
= home_matches ++ pkg_matches
where
-- Proper check
| Just subst <- tcMatchTys tpl_tvs tpl_tys tys
- = (subst, item) : find rest
+ = (item, substTyVars subst (tyConTyVars tycon)) : find rest
-- No match => try next
| otherwise
\begin{code}
lookupFamInstEnvUnify :: (FamInstEnv, FamInstEnv) -> TyCon -> [Type]
- -> [(TvSubst, FamInst)]
+ -> [(FamInstMatch)]
lookupFamInstEnvUnify (pkg_ie, home_ie) fam tys
= home_matches ++ pkg_matches
where
-- Unification will break badly if the variables overlap
-- They shouldn't because we allocate separate uniques for them
case tcUnifyTys bind_fn tpl_tys tys of
- Just subst -> (subst, item) : find rest
+ Just subst -> let rep_tys = substTyVars subst (tyConTyVars tycon)
+ in
+ (item, rep_tys) : find rest
Nothing -> find rest
-- See explanation at @InstEnv.bind_fn@.