X-Git-Url: http://git.megacz.com/?a=blobdiff_plain;f=compiler%2Ftypes%2FFamInstEnv.lhs;h=b8c82f862328f79e1e7a0af7fcfe43cf946002dc;hb=ecdc15ea7813c43a4d84b7c6554a13c06f210a7e;hp=b851ec1ee64d83c4ea8f27d159b5c0a738cc8f00;hpb=3a2b38084cfea1c88009c4d9236fa403bdda25b4;p=ghc-hetmet.git diff --git a/compiler/types/FamInstEnv.lhs b/compiler/types/FamInstEnv.lhs index b851ec1..b8c82f8 100644 --- a/compiler/types/FamInstEnv.lhs +++ b/compiler/types/FamInstEnv.lhs @@ -46,13 +46,19 @@ import Maybe \begin{code} data FamInst = FamInst { fi_fam :: Name -- Family name + -- INVARIANT: fi_fam = case tyConFamInst_maybe fi_tycon of + -- Just (tc, tys) -> tc -- Used for "rough matching"; same idea as for class instances , fi_tcs :: [Maybe Name] -- Top of type args + -- INVARIANT: fi_tcs = roughMatchTcs fi_tys -- Used for "proper matching"; ditto , fi_tvs :: TyVarSet -- Template tyvars for full match , fi_tys :: [Type] -- Full arg types + -- INVARIANT: fi_tvs = tyConTyVars fi_tycon + -- fi_tys = case tyConFamInst_maybe fi_tycon of + -- Just (_, tys) -> tys , fi_tycon :: TyCon -- Representation tycon } @@ -76,14 +82,13 @@ instance Outputable FamInst where 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}) = pprTyConSort <+> pprHead where - pprHead = parenSymOcc (getOccName fam) (ppr fam) <+> - sep (map pprParendType tys) + pprHead = pprTypeApp (parenSymOcc (getOccName fam) (ppr fam)) tys pprTyConSort | isDataTyCon tycon = ptext SLIT("data instance") | isNewTyCon tycon = ptext SLIT("newtype instance") | isSynTyCon tycon = ptext SLIT("type instance") @@ -188,61 +193,29 @@ extendFamInstEnv inst_env ins_item@(FamInst {fi_fam = cls_nm, fi_tcs = mb_tcs}) %* * %************************************************************************ -@lookupFamInstEnvExact@ looks up in a @FamInstEnv@ using an exact match. -This is used when we want the @TyCon@ of a particular family instance (e.g., -during deriving classes). +@lookupFamInstEnv@ looks up in a @FamInstEnv@, using a one-way match. +Multiple matches are only possible in case of type families (not data +families), and then, it doesn't matter which match we choose (as the +instances are guaranteed confluent). -\begin{code} -{- NOT NEEDED ANY MORE -lookupFamInstEnvExact :: (FamInstEnv -- External package inst-env - ,FamInstEnv) -- Home-package inst-env - -> TyCon -> [Type] -- What we are looking for - -> Maybe FamInst -lookupFamInstEnvExact (pkg_ie, home_ie) fam tys - = home_matches `mplus` pkg_matches - where - rough_tcs = roughMatchTcs tys - all_tvs = all isNothing rough_tcs - home_matches = lookup home_ie - pkg_matches = lookup pkg_ie +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 - -------------- - lookup env = case lookupUFM env fam of - Nothing -> Nothing -- No instances for this class - Just (FamIE insts has_tv_insts) - -- Short cut for common case: - -- The thing we are looking up is of form (C a - -- b c), and the FamIE has no instances of - -- that form, so don't bother to search - | all_tvs && not has_tv_insts -> Nothing - | otherwise -> find insts - - -------------- - find [] = Nothing - find (item@(FamInst { fi_tcs = mb_tcs, fi_tys = tpl_tys }) : rest) - -- Fast check for no match, uses the "rough match" fields - | instanceCantMatch rough_tcs mb_tcs - = find rest + data instance T [a] = .. - -- Proper check - | tcEqTypes tpl_tys tys - = Just item +desugared to - -- No match => try next - | otherwise - = find rest --} -\end{code} + data :R42T a = .. + coe :Co:R42T a :: T [a] ~ :R42T a -@lookupFamInstEnv@ looks up in a @FamInstEnv@, using a one-way match. -Multiple matches are only possible in case of type families (not data -families), and then, it doesn't matter which match we choose (as the -instances are guaranteed confluent). +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 @@ -272,7 +245,7 @@ lookupFamInstEnv (pkg_ie, home_ie) fam tys -- 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 @@ -291,7 +264,7 @@ indexed synonyms and we don't want to slow that down by needless unification. \begin{code} lookupFamInstEnvUnify :: (FamInstEnv, FamInstEnv) -> TyCon -> [Type] - -> [(TvSubst, FamInst)] + -> [(FamInstMatch)] lookupFamInstEnvUnify (pkg_ie, home_ie) fam tys = home_matches ++ pkg_matches where @@ -327,7 +300,9 @@ lookupFamInstEnvUnify (pkg_ie, home_ie) fam tys -- 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@.