Simon Peyton Jones pushed to branch wip/T27994 at Glasgow Haskell Compiler / GHC
Commits:
-
ed2fd53d
by Simon Peyton Jones at 2026-10-29T00:07:13+00:00
-
ecc5ab3d
by Simon Peyton Jones at 2026-10-29T00:07:13+00:00
11 changed files:
- compiler/GHC/Core/Coercion/Axiom.hs
- compiler/GHC/Core/Predicate.hs
- compiler/GHC/Core/TyCo/FVs.hs
- compiler/GHC/Core/TyCo/Subst.hs
- compiler/GHC/Core/Type.hs
- compiler/GHC/Core/Unify.hs
- compiler/GHC/Tc/Instance/Family.hs
- compiler/GHC/Tc/Solver/FunDeps.hs
- + testsuite/tests/typecheck/should_compile/T27994.hs
- + testsuite/tests/typecheck/should_compile/T27994a.hs
- testsuite/tests/typecheck/should_compile/all.T
Changes:
| ... | ... | @@ -277,8 +277,8 @@ data CoAxBranch |
| 277 | 277 | -- See Note [CoAxBranch type variables]
|
| 278 | 278 | , cab_eta_tvs :: [TyVar]
|
| 279 | 279 | -- ^ Eta-reduced tyvars
|
| 280 | - -- cab_tvs and cab_lhs may be eta-reduced; see
|
|
| 281 | - -- Note [Eta reduction for data families]
|
|
| 280 | + -- For a data family (only) cab_tvs and cab_lhs may be eta-reduced
|
|
| 281 | + -- See Note [Eta reduction for data families]
|
|
| 282 | 282 | , cab_cvs :: [CoVar]
|
| 283 | 283 | -- ^ Bound coercion variables
|
| 284 | 284 | -- Always empty, for now.
|
| ... | ... | @@ -286,8 +286,14 @@ data CoAxBranch |
| 286 | 286 | -- in GHC.Tc.TyCl
|
| 287 | 287 | , cab_roles :: [Role]
|
| 288 | 288 | -- ^ See Note [CoAxBranch roles]
|
| 289 | + |
|
| 289 | 290 | , cab_lhs :: [Type]
|
| 290 | 291 | -- ^ Type patterns to match against
|
| 292 | + -- For a data family `cab_lhs` may be shorter than the arity
|
|
| 293 | + -- of the data type
|
|
| 294 | + -- For a type family `cab_lhs` is exactly the family arity
|
|
| 295 | + -- See Note [Eta reduction for data families]
|
|
| 296 | + |
|
| 291 | 297 | , cab_rhs :: Type
|
| 292 | 298 | -- ^ Right-hand side of the equality
|
| 293 | 299 | -- See Note [CoAxioms are homogeneous]
|
| ... | ... | @@ -36,7 +36,7 @@ module GHC.Core.Predicate ( |
| 36 | 36 | |
| 37 | 37 | -- Equality left-hand sides
|
| 38 | 38 | CanEqLHS(..), canEqLHS_maybe, canTyFamEqLHS_maybe,
|
| 39 | - canEqLHSKind, canEqLHSType, eqCanEqLHS
|
|
| 39 | + canEqLHSKind, canEqLHSType, eqCanEqLHS, saturatedFamApp_maybe
|
|
| 40 | 40 | |
| 41 | 41 | ) where
|
| 42 | 42 | |
| ... | ... | @@ -61,6 +61,8 @@ import GHC.Utils.Misc |
| 61 | 61 | import GHC.Utils.Panic
|
| 62 | 62 | import GHC.Data.FastString
|
| 63 | 63 | |
| 64 | +import GHC.Exts( inline )
|
|
| 65 | + |
|
| 64 | 66 | |
| 65 | 67 | {- *********************************************************************
|
| 66 | 68 | * *
|
| ... | ... | @@ -700,7 +702,9 @@ types/kinds are fully settled and zonked. |
| 700 | 702 | -- See also Note [Ordering of implicit variables] in "GHC.Rename.HsType"
|
| 701 | 703 | |
| 702 | 704 | scopedSort :: [Var] -> [Var]
|
| 703 | -scopedSort = go [] []
|
|
| 705 | +scopedSort xs
|
|
| 706 | + | null xs = []
|
|
| 707 | + | otherwise = go [] [] xs
|
|
| 704 | 708 | where
|
| 705 | 709 | go :: [Var] -- already sorted, in reverse order
|
| 706 | 710 | -> [TyCoVarSet] -- each set contains all the variables which must be placed
|
| ... | ... | @@ -781,13 +785,19 @@ canEqLHS_maybe xi |
| 781 | 785 | | otherwise
|
| 782 | 786 | = canTyFamEqLHS_maybe xi
|
| 783 | 787 | |
| 784 | -canTyFamEqLHS_maybe :: Type -> Maybe CanEqLHS
|
|
| 785 | -canTyFamEqLHS_maybe xi
|
|
| 788 | +saturatedFamApp_maybe :: Type -> Maybe (TyCon,[Type])
|
|
| 789 | +saturatedFamApp_maybe xi
|
|
| 786 | 790 | | Just (tc, args) <- tcSplitTyConApp_maybe xi
|
| 787 | 791 | , isTypeFamilyTyCon tc
|
| 788 | 792 | , args `lengthIs` tyConArity tc
|
| 789 | - = Just $ TyFamLHS tc args
|
|
| 793 | + = Just (tc,args)
|
|
| 794 | + | otherwise
|
|
| 795 | + = Nothing
|
|
| 790 | 796 | |
| 797 | +canTyFamEqLHS_maybe :: Type -> Maybe CanEqLHS
|
|
| 798 | +canTyFamEqLHS_maybe xi
|
|
| 799 | + | Just (tc, args) <- inline saturatedFamApp_maybe xi
|
|
| 800 | + = Just $ TyFamLHS tc args
|
|
| 791 | 801 | | otherwise
|
| 792 | 802 | = Nothing
|
| 793 | 803 |
| ... | ... | @@ -1159,10 +1159,12 @@ nice tight loops. |
| 1159 | 1159 | {-# INLINE afvFolder #-} -- See Note [Any-free-var folder]
|
| 1160 | 1160 | afvFolder :: TyCoFolder (FV (BoundVars, TyCoVar -> Bool) DM.Any)
|
| 1161 | 1161 | -- 'afvFolder' is short for "any-free-var folder", good for checking
|
| 1162 | --- if any /deep/ free var of a type satisfies a predicate `check_fv`
|
|
| 1162 | +-- if any /shallow/ free var of a type satisfies a predicate `check_fv`
|
|
| 1163 | 1163 | -- The "env" of the (FV env Any) is a pair (bvs,pred) of
|
| 1164 | 1164 | -- the bound variables (which are definitely not free), and
|
| 1165 | 1165 | -- an "interesting var" predicate which the client supplies
|
| 1166 | +--
|
|
| 1167 | +-- You can get "deep" by supplying a predicate that also looks in the kind
|
|
| 1166 | 1168 | afvFolder = TyCoFolder { tcf_view = noView -- See Note [Free vars and synonyms]
|
| 1167 | 1169 | , tcf_tyvar = do_tcv
|
| 1168 | 1170 | , tcf_covar = do_tcv
|
| ... | ... | @@ -1173,8 +1175,7 @@ afvFolder = TyCoFolder { tcf_view = noView -- See Note [Free vars and synonyms] |
| 1173 | 1175 | -- Check the variable itself with check_fv,
|
| 1174 | 1176 | -- and check its kind (this is a deep folder)
|
| 1175 | 1177 | do_tcv tcv = MkFV $ \ (bvs,check_fv) ->
|
| 1176 | - Any (not (tcv `elemVarSet` bvs) &&
|
|
| 1177 | - (check_fv tcv || runAny check_fv (afv_type (varType tcv))))
|
|
| 1178 | + Any (not (tcv `elemVarSet` bvs) && check_fv tcv)
|
|
| 1178 | 1179 | do_hole hole = do_tcv (coHoleCoVar hole)
|
| 1179 | 1180 | |
| 1180 | 1181 | afv_type :: Type -> FV (BoundVars, TyVar -> Bool) DM.Any
|
| ... | ... | @@ -1186,16 +1187,32 @@ runAny :: (TyVar -> Bool) -> FV (BoundVars, TyCoVar -> Bool) DM.Any -> Bool |
| 1186 | 1187 | {-# INLINE runAny #-}
|
| 1187 | 1188 | runAny check_fv fvs = DM.getAny (runFV fvs (emptyVarSet, check_fv))
|
| 1188 | 1189 | |
| 1190 | +---------------------------------------------
|
|
| 1191 | +-- anyShallowFreeVarsOfType and friends look only for shallow free vars
|
|
| 1192 | +-- (Currently not needed, left here in case we need it one day)
|
|
| 1193 | +-- anyShallowFreeVarsOfType :: (TyCoVar -> Bool) -> Type -> Bool
|
|
| 1194 | +-- {-# INLINE anyShallowFreeVarsOfType #-}
|
|
| 1195 | +-- anyShallowFreeVarsOfType check_fv ty = runAny check_fv (afv_type ty)
|
|
| 1196 | + |
|
| 1197 | +---------------------------------------------
|
|
| 1198 | +-- anyFreeVarsOfType and friends look for deep free vars
|
|
| 1199 | + |
|
| 1200 | +deep_check :: (TyCoVar -> Bool) -> TyCoVar -> Bool
|
|
| 1201 | +-- This is inefficient because if one tyvar occurs many times
|
|
| 1202 | +-- in a type, it'll look in its kind at each occurrence. Boo.
|
|
| 1203 | +deep_check check_fv tcv = check_fv tcv || anyFreeVarsOfType check_fv (varType tcv)
|
|
| 1204 | + |
|
| 1189 | 1205 | anyFreeVarsOfType :: (TyCoVar -> Bool) -> Type -> Bool
|
| 1190 | 1206 | {-# INLINE anyFreeVarsOfType #-}
|
| 1191 | -anyFreeVarsOfType check_fv ty = runAny check_fv (afv_type ty)
|
|
| 1207 | +-- Looks deeply, into the kinds of the free vars
|
|
| 1208 | +anyFreeVarsOfType check_fv ty = runAny (deep_check check_fv) (afv_type ty)
|
|
| 1192 | 1209 | |
| 1193 | 1210 | anyFreeVarsOfTypes :: (TyCoVar -> Bool) -> [Type] -> Bool
|
| 1194 | 1211 | {-# INLINE anyFreeVarsOfTypes #-}
|
| 1195 | -anyFreeVarsOfTypes check_fv tys = runAny check_fv (afv_types tys)
|
|
| 1212 | +anyFreeVarsOfTypes check_fv tys = runAny (deep_check check_fv) (afv_types tys)
|
|
| 1196 | 1213 | |
| 1197 | 1214 | anyFreeVarsOfCo :: (TyCoVar -> Bool) -> Coercion -> Bool
|
| 1198 | -anyFreeVarsOfCo check_fv co = runAny check_fv (afv_co co)
|
|
| 1215 | +anyFreeVarsOfCo check_fv co = runAny (deep_check check_fv) (afv_co co)
|
|
| 1199 | 1216 | |
| 1200 | 1217 | noFreeVarsOfType :: Type -> Bool
|
| 1201 | 1218 | noFreeVarsOfType ty = not $ runAny (const True) (afv_type ty)
|
| ... | ... | @@ -1206,6 +1223,7 @@ noFreeVarsOfTypes tys = not $ runAny (const True) (afv_types tys) |
| 1206 | 1223 | noFreeVarsOfCo :: Coercion -> Bool
|
| 1207 | 1224 | noFreeVarsOfCo co = not $ runAny (const True) (afv_co co)
|
| 1208 | 1225 | |
| 1226 | + |
|
| 1209 | 1227 | {-
|
| 1210 | 1228 | ************************************************************************
|
| 1211 | 1229 | * *
|
| ... | ... | @@ -48,6 +48,8 @@ module GHC.Core.TyCo.Subst |
| 48 | 48 | substTyCoBndr,
|
| 49 | 49 | substVarBndrUsing,
|
| 50 | 50 | checkValidSubst, isValidTCvSubst,
|
| 51 | + |
|
| 52 | + deepSubstTy
|
|
| 51 | 53 | ) where
|
| 52 | 54 | |
| 53 | 55 | import GHC.Prelude
|
| ... | ... | @@ -775,9 +777,15 @@ substThetaUnchecked = substTysUnchecked |
| 775 | 777 | -- building no thunks. See Note [Specialising mappers] in GHC.Core.TyCo.Make
|
| 776 | 778 | type SubstM = StrictReaderT Subst StrictIdentity
|
| 777 | 779 | |
| 778 | -runSubstM :: SubstM a -> Subst -> a
|
|
| 779 | -runSubstM m subst = runStrictIdentity (runStrictReaderT m subst)
|
|
| 780 | +runSubstM :: forall a. (a -> SubstM a) -> Subst -> a -> a
|
|
| 780 | 781 | {-# INLINE runSubstM #-}
|
| 782 | +runSubstM tx subst x = runStrictIdentity (runStrictReaderT (tx x) subst)
|
|
| 783 | + |
|
| 784 | +subst_ty :: Subst -> Type -> Type
|
|
| 785 | +subst_co :: Subst -> Coercion -> Coercion
|
|
| 786 | +(subst_ty, subst_co)
|
|
| 787 | + = case mapTyCo substTyCoMapper of
|
|
| 788 | + (ms_ty, _, ms_co, _) -> (runSubstM ms_ty, runSubstM ms_co)
|
|
| 781 | 789 | |
| 782 | 790 | substTyCoMapper :: TyCoMapper SubstM
|
| 783 | 791 | substTyCoMapper
|
| ... | ... | @@ -785,8 +793,8 @@ substTyCoMapper |
| 785 | 793 | , tcm_covar = subst_cv
|
| 786 | 794 | , tcm_hole = subst_ch
|
| 787 | 795 | , tcm_tycobinder = tcv_bndr
|
| 788 | - , tcm_tcapp_ty = tcapp_ty
|
|
| 789 | - , tcm_tcapp_co = tcapp_co
|
|
| 796 | + , tcm_tcapp_ty = nopTcAppTy
|
|
| 797 | + , tcm_tcapp_co = nopTcAppCo
|
|
| 790 | 798 | }
|
| 791 | 799 | where
|
| 792 | 800 | subst_tv tv = StrictReaderT $ \subst -> return (substTyVar subst tv)
|
| ... | ... | @@ -802,23 +810,15 @@ substTyCoMapper |
| 802 | 810 | |
| 803 | 811 | -- Avoid allocation in this very
|
| 804 | 812 | -- common case (E.g. Int, LiftedRep etc)
|
| 805 | - tcapp_ty :: Type -> TyCon -> [Type] -> SubstM Type
|
|
| 806 | - tcapp_ty ty tc tys'
|
|
| 807 | - | null tys' = return ty
|
|
| 808 | - | otherwise = return (mkTyConApp tc tys')
|
|
| 809 | - tcapp_co :: Coercion -> Role -> TyCon -> [Coercion] -> SubstM Coercion
|
|
| 810 | - tcapp_co co r tc cos'
|
|
| 811 | - | null cos' = return co
|
|
| 812 | - | otherwise = return (mkTyConAppCo r tc cos')
|
|
| 813 | +nopTcAppTy :: Type -> TyCon -> [Type] -> SubstM Type
|
|
| 814 | +nopTcAppTy ty tc tys'
|
|
| 815 | + | null tys' = return ty
|
|
| 816 | + | otherwise = return (mkTyConApp tc tys')
|
|
| 813 | 817 | |
| 814 | -subst_ty :: Subst -> Type -> Type
|
|
| 815 | -subst_co :: Subst -> Coercion -> Coercion
|
|
| 816 | -(subst_ty, subst_co)
|
|
| 817 | - = case mapTyCo substTyCoMapper of
|
|
| 818 | - (ms_ty, _, ms_co, _) -> (run ms_ty, run ms_co)
|
|
| 819 | - where
|
|
| 820 | - run :: forall a. (a -> SubstM a) -> Subst -> a -> a
|
|
| 821 | - run ms subst x = runSubstM (ms x) subst
|
|
| 818 | +nopTcAppCo :: Coercion -> Role -> TyCon -> [Coercion] -> SubstM Coercion
|
|
| 819 | +nopTcAppCo co r tc cos'
|
|
| 820 | + | null cos' = return co
|
|
| 821 | + | otherwise = return (mkTyConAppCo r tc cos')
|
|
| 822 | 822 | |
| 823 | 823 | substTyVar :: Subst -> TyVar -> Type
|
| 824 | 824 | substTyVar (Subst _ _ tenv _) tv
|
| ... | ... | @@ -1019,3 +1019,75 @@ it is /very/ valuable to /keep/ it empty: |
| 1019 | 1019 | If the substitution is empty, this is a no-op -- but only if it
|
| 1020 | 1020 | is empty!
|
| 1021 | 1021 | -}
|
| 1022 | + |
|
| 1023 | + |
|
| 1024 | +{- **********************************************************************
|
|
| 1025 | +%* *
|
|
| 1026 | + Deep substitution
|
|
| 1027 | +%* *
|
|
| 1028 | +%********************************************************************* -}
|
|
| 1029 | + |
|
| 1030 | +{- Note [Deep substitution]
|
|
| 1031 | +~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
| 1032 | +Deep substitution applies the substitution to the /kinds/ of un-substituted
|
|
| 1033 | +type variables. Suppose the substitution is
|
|
| 1034 | + [ k :-> Type ]
|
|
| 1035 | +and we apply it to the type
|
|
| 1036 | + Proxy k (a :: k)
|
|
| 1037 | +Ordinary shallow substitution will give
|
|
| 1038 | + Proxy Type (a :: k)
|
|
| 1039 | +which is ill-kinded. Deep substitution will give
|
|
| 1040 | + Proxy Type (a :: Type)
|
|
| 1041 | + |
|
| 1042 | +Ordinary (shallow) substitution is usually fine, because we will substitute for
|
|
| 1043 | +`a` as well, but not always. In particular, the pure unifier in in GHC.Core.Unify
|
|
| 1044 | +uses `niFixSubst` to find a fixpoint, and we really don't want domain tyvars
|
|
| 1045 | +appearing in the range.See Note [Finding the substitution fixpoint].
|
|
| 1046 | + |
|
| 1047 | +Deep substitution risks being rather inefficient because it re-applies the
|
|
| 1048 | +subsitution to the kind at /each occurrence/ of a free variable. We could
|
|
| 1049 | +perhaps find the free vars, and build a re-kinding substitution, but that's a
|
|
| 1050 | +bit more complicated.
|
|
| 1051 | +-}
|
|
| 1052 | + |
|
| 1053 | +deepSubstTyCoMapper :: TyCoMapper SubstM
|
|
| 1054 | +deepSubstTyCoMapper
|
|
| 1055 | + = TyCoMapper { tcm_tyvar = subst_tv
|
|
| 1056 | + , tcm_covar = subst_cv
|
|
| 1057 | + , tcm_hole = subst_ch
|
|
| 1058 | + , tcm_tycobinder = tcv_bndr
|
|
| 1059 | + , tcm_tcapp_ty = nopTcAppTy
|
|
| 1060 | + , tcm_tcapp_co = nopTcAppCo
|
|
| 1061 | + }
|
|
| 1062 | + where
|
|
| 1063 | + subst_tv tv = StrictReaderT $ \subst -> return (deepSubstTyVar subst tv)
|
|
| 1064 | + subst_cv cv = StrictReaderT $ \subst -> return (deepSubstCoVar subst cv)
|
|
| 1065 | + subst_ch ch = StrictReaderT $ \subst -> return (deepSubstCoHole subst ch)
|
|
| 1066 | + |
|
| 1067 | + tcv_bndr :: TyCoVar -> ForAllTyFlag -> (TyCoVar -> SubstM r) -> SubstM r
|
|
| 1068 | + tcv_bndr tcv _vis k
|
|
| 1069 | + = StrictReaderT $ \subst ->
|
|
| 1070 | + let !(subst', tcv') = substVarBndrUsing deepSubstTy subst tcv
|
|
| 1071 | + in runStrictReaderT (k tcv') subst'
|
|
| 1072 | + |
|
| 1073 | +deepSubstTy :: Subst -> Type -> Type
|
|
| 1074 | +deepSubstTy = case mapTyCo deepSubstTyCoMapper of
|
|
| 1075 | + (subst_ty, _, _, _) -> runSubstM subst_ty
|
|
| 1076 | + |
|
| 1077 | +deepSubstTyVar :: Subst -> TyVar -> Type
|
|
| 1078 | +deepSubstTyVar subst@(Subst _ _ tenv _) tv
|
|
| 1079 | + = assert (isTyVar tv) $
|
|
| 1080 | + case lookupVarEnv tenv tv of
|
|
| 1081 | + Just ty -> ty
|
|
| 1082 | + Nothing -> TyVarTy (updateVarType (deepSubstTy subst) tv)
|
|
| 1083 | + |
|
| 1084 | +deepSubstCoVar :: Subst -> CoVar -> Coercion
|
|
| 1085 | +deepSubstCoVar subst@(Subst _ _ _ cenv) cv
|
|
| 1086 | + = case lookupVarEnv cenv cv of
|
|
| 1087 | + Just co -> co
|
|
| 1088 | + Nothing -> CoVarCo (updateVarType (deepSubstTy subst) cv)
|
|
| 1089 | + |
|
| 1090 | +deepSubstCoHole :: Subst -> CoercionHole -> Coercion
|
|
| 1091 | +-- See Note [Substituting in a coercion hole]
|
|
| 1092 | +deepSubstCoHole subst h@(CH { ch_co_var = cv })
|
|
| 1093 | + = HoleCo (h { ch_co_var = updateVarType (deepSubstTy subst) cv }) |
| ... | ... | @@ -483,7 +483,7 @@ expandTypeSynonyms ty |
| 483 | 483 | expandTypeSynonymsX :: Subst -> Type -> Type
|
| 484 | 484 | expandTypeSynonymsX
|
| 485 | 485 | = case mapTyCo expandTypeSynonymMapper of
|
| 486 | - (exp_ty, _, _, _) -> \subst ty -> runSubstM (exp_ty ty) subst
|
|
| 486 | + (exp_ty, _, _, _) -> runSubstM exp_ty
|
|
| 487 | 487 | |
| 488 | 488 | expandTypeSynonymMapper :: TyCoMapper SubstM
|
| 489 | 489 | -- Just like substitution, but treat TyConApp specially
|
| ... | ... | @@ -28,13 +28,12 @@ import GHC.Types.Var.Env |
| 28 | 28 | import GHC.Types.Var.Set
|
| 29 | 29 | import GHC.Core.Type hiding ( getTvSubstEnv )
|
| 30 | 30 | import GHC.Core.Coercion hiding ( getCvSubstEnv )
|
| 31 | -import GHC.Core.Predicate( scopedSort )
|
|
| 32 | 31 | import GHC.Core.TyCon
|
| 33 | 32 | import GHC.Core.Predicate( CanEqLHS(..), canEqLHS_maybe )
|
| 34 | 33 | import GHC.Core.TyCon.Env
|
| 35 | 34 | import GHC.Core.TyCo.Rep
|
| 36 | 35 | import GHC.Core.TyCo.Compare ( eqType, tcEqType, tcEqTyConAppArgs )
|
| 37 | -import GHC.Core.TyCo.Subst ( mkTvSubst )
|
|
| 36 | +import GHC.Core.TyCo.Subst ( mkTvSubst, deepSubstTy )
|
|
| 38 | 37 | import GHC.Core.Map.Type
|
| 39 | 38 | import GHC.Core.Multiplicity
|
| 40 | 39 | |
| ... | ... | @@ -1063,21 +1062,31 @@ During unification we use a TvSubstEnv/CvSubstEnv pair that is |
| 1063 | 1062 | |
| 1064 | 1063 | Note [Finding the substitution fixpoint]
|
| 1065 | 1064 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
| 1066 | -Finding the fixpoint of a non-idempotent substitution arising from a
|
|
| 1067 | -unification is much trickier than it looks, because of kinds. Consider
|
|
| 1065 | +We want an /idempotent/ substitution, so `niFixSubst` takes a non-idempotent
|
|
| 1066 | +one and composes it with itself until it becomes idempotent. Thus if the original
|
|
| 1067 | +is S0, we compute S1 = S0 o S0, S2 = S1 o S1, etc.
|
|
| 1068 | + |
|
| 1069 | +A variable chain v0 :-> v1 :-> ... :-> vm therefore takes about log2 m rounds,
|
|
| 1070 | +The unifier can build such. For example:
|
|
| 1071 | + (a, a, a, ..., a) ~ (x1, x2, x3, ..., xm)
|
|
| 1072 | +produces a :-> x1, x1 :-> x2, ..., x(m-1) :-> xm.
|
|
| 1073 | + |
|
| 1074 | +Finding the fixpoint is much trickier than it looks, because of kinds.
|
|
| 1075 | +Consider
|
|
| 1068 | 1076 | T k (H k (f:k)) ~ T * (g:*)
|
| 1069 | 1077 | If we unify, we get the substitution
|
| 1070 | 1078 | [ k -> *
|
| 1071 | 1079 | , g -> H k (f:k) ]
|
| 1080 | +This isn't idempotent: it mentions `k` in the range.
|
|
| 1081 | + |
|
| 1072 | 1082 | To make it idempotent we don't want to get just
|
| 1073 | 1083 | [ k -> *
|
| 1074 | 1084 | , g -> H * (f:k) ]
|
| 1075 | -We also want to substitute inside f's kind, to get
|
|
| 1076 | - [ k -> *
|
|
| 1077 | - , g -> H k (f:*) ]
|
|
| 1078 | -If we don't do this, we may apply the substitution to something,
|
|
| 1079 | -and get an ill-formed type, i.e. one where typeKind will fail.
|
|
| 1085 | +because (H * (f:k)) is itself ill-kinded, and `typeKind` will fail.
|
|
| 1080 | 1086 | This happened, for example, in #9106.
|
| 1087 | +So (yuckily) we must also substitute inside f's kind, to get
|
|
| 1088 | + [ k -> *
|
|
| 1089 | + , g -> H * (f:*) ]
|
|
| 1081 | 1090 | |
| 1082 | 1091 | It gets worse. In #14164 we wanted to take the fixpoint of
|
| 1083 | 1092 | this substitution
|
| ... | ... | @@ -1090,84 +1099,45 @@ the invocation of F! We don't have a function that recursively |
| 1090 | 1099 | applies substitutions inside the kinds of variable occurrences (and
|
| 1091 | 1100 | probably rightly so).
|
| 1092 | 1101 | |
| 1093 | -So, we work as follows:
|
|
| 1094 | - |
|
| 1095 | - 1. Start with the current substitution (which we are
|
|
| 1096 | - trying to fixpoint
|
|
| 1097 | - [ xs :-> F a (z :: a) (rest :: G a (z :: a))
|
|
| 1098 | - , a :-> b ]
|
|
| 1099 | - |
|
| 1100 | - 2. Take all the free vars of the range of the substitution:
|
|
| 1101 | - {a, z, rest, b}
|
|
| 1102 | - NB: the free variable finder closes over
|
|
| 1103 | - the kinds of variable occurrences
|
|
| 1104 | - |
|
| 1105 | - 3. If none are in the domain of the substitution, stop.
|
|
| 1106 | - We have found a fixpoint.
|
|
| 1107 | - |
|
| 1108 | - 4. Remove the variables that are bound by the substitution, leaving
|
|
| 1109 | - {z, rest, b}
|
|
| 1110 | - |
|
| 1111 | - 5. Do a topo-sort to put them in dependency order:
|
|
| 1112 | - [ b :: *, z :: a, rest :: G a z ]
|
|
| 1113 | - |
|
| 1114 | - 6. Apply the substitution left-to-right to the kinds of these
|
|
| 1115 | - tyvars, extending it each time with a new binding, so we
|
|
| 1116 | - finish up with
|
|
| 1117 | - [ xs :-> ..as before..
|
|
| 1118 | - , a :-> b
|
|
| 1119 | - , b :-> b :: *
|
|
| 1120 | - , z :-> z :: b
|
|
| 1121 | - , rest :-> rest :: G b (z :: b) ]
|
|
| 1122 | - Note that rest now has the right kind
|
|
| 1123 | - |
|
| 1124 | - 7. Apply this extended substitution (once) to the range of the
|
|
| 1125 | - /original/ substitution. (Note that the extended substitution
|
|
| 1126 | - would go on forever if you tried to find its fixpoint, because it
|
|
| 1127 | - maps z to z.)
|
|
| 1128 | - |
|
| 1129 | - 8. And go back to step 1
|
|
| 1130 | - |
|
| 1131 | -In Step 6 we use the free vars from Step 2 as the initial
|
|
| 1132 | -in-scope set, because all of those variables appear in the
|
|
| 1133 | -range of the substitution, so they must all be in the in-scope
|
|
| 1134 | -set. But NB that the type substitution engine does not look up
|
|
| 1135 | -variables in the in-scope set; it is used only to ensure no
|
|
| 1136 | -shadowing.
|
|
| 1102 | +Ugh! This whole thing is pretty horrible. But the solution is simple enough:
|
|
| 1103 | + |
|
| 1104 | + Use deep substitution (deepSubstTy)
|
|
| 1105 | + |
|
| 1106 | +(deepSubst `s` (Proxy k (a::k)) applies the substitution `s` not only to
|
|
| 1107 | +the occurrence of `k` in the argument of `Proxy`, but also to the `k` inside
|
|
| 1108 | +the kind of `a`. See Note [Deep substitution] in GHC.Core.TyCo.Subst.
|
|
| 1109 | + |
|
| 1110 | +So `niFixSubst` just applies the substitution /deeply/ to the types in its
|
|
| 1111 | +range, until we reach a fixed point. Easy!
|
|
| 1137 | 1112 | -}
|
| 1138 | 1113 | |
| 1139 | 1114 | niFixSubst :: InScopeSet -> TvSubstEnv -> Subst
|
| 1140 | 1115 | -- Find the idempotent fixed point of the non-idempotent substitution
|
| 1141 | 1116 | -- This is surprisingly tricky:
|
| 1142 | 1117 | -- see Note [Finding the substitution fixpoint]
|
| 1143 | --- ToDo: use laziness instead of iteration?
|
|
| 1144 | 1118 | niFixSubst in_scope tenv
|
| 1145 | - | not_fixpoint = niFixSubst in_scope (mapVarEnv (substTy subst) tenv)
|
|
| 1146 | - | otherwise = tenv_subst
|
|
| 1119 | + | isEmptyVarEnv tenv -- Fast path for common case
|
|
| 1120 | + = mkEmptySubst in_scope
|
|
| 1121 | + | otherwise
|
|
| 1122 | + = -- pprTrace "niFixSubst" (vcat [ text "In: " <+> ppr tenv
|
|
| 1123 | + -- , text "Out:" <+> ppr (S.getTvSubstEnv subst) ])
|
|
| 1124 | + subst
|
|
| 1147 | 1125 | where
|
| 1148 | - tenv_subst = mkTvSubst in_scope tenv -- This is our starting point
|
|
| 1149 | - |
|
| 1150 | - range_tvs :: [TyVar]
|
|
| 1151 | - range_tvs = nonDetVarSetElems $
|
|
| 1152 | - tyCoVarsOfTypes $
|
|
| 1153 | - nonDetEltsUFM tenv
|
|
| 1154 | - -- It's OK to use nonDetEltsUFM (twice) here because
|
|
| 1155 | - -- the order of range_tvs is immaterial
|
|
| 1156 | - |
|
| 1157 | - not_fixpoint = any in_domain range_tvs
|
|
| 1158 | - in_domain tv = tv `elemVarEnv` tenv
|
|
| 1159 | - |
|
| 1160 | - free_tvs = scopedSort (filterOut in_domain range_tvs)
|
|
| 1126 | + subst = niFixSubst' 1 in_scope tenv
|
|
| 1161 | 1127 | |
| 1162 | - -- See Note [Finding the substitution fixpoint], Step 6
|
|
| 1163 | - subst = foldl' add_free_tv tenv_subst free_tvs
|
|
| 1164 | - |
|
| 1165 | - add_free_tv :: Subst -> TyVar -> Subst
|
|
| 1166 | - add_free_tv subst tv
|
|
| 1167 | - | isTyVar tv = extendTvSubst subst tv (mkTyVarTy tv')
|
|
| 1168 | - | otherwise = subst -- Ignore free coercion variables
|
|
| 1169 | - where
|
|
| 1170 | - tv' = updateTyVarKind (substTy subst) tv
|
|
| 1128 | +niFixSubst' :: Int -> InScopeSet -> TvSubstEnv -> Subst
|
|
| 1129 | +niFixSubst' n in_scope tenv_orig
|
|
| 1130 | + | fixpoint_found = mkTvSubst in_scope tenv_orig
|
|
| 1131 | + | otherwise = niFixSubst' (n+1) in_scope tenv_new
|
|
| 1132 | + where
|
|
| 1133 | + in_dom tv = tv `elemVarEnv` tenv_orig
|
|
| 1134 | + tenv_new = mapVarEnv (deepSubstTy subst) tenv_orig
|
|
| 1135 | + subst = mkTvSubst in_scope tenv_orig
|
|
| 1136 | + |
|
| 1137 | + fixpoint_found = nonDetStrictFoldUFM and_fix True tenv_orig
|
|
| 1138 | + and_fix :: Type -> Bool -> Bool
|
|
| 1139 | + and_fix _ False = False
|
|
| 1140 | + and_fix ty _ = not (anyFreeVarsOfType in_dom ty)
|
|
| 1171 | 1141 | |
| 1172 | 1142 | {-
|
| 1173 | 1143 | ************************************************************************
|
| ... | ... | @@ -16,6 +16,7 @@ import GHC.Prelude |
| 16 | 16 | import GHC.Driver.DynFlags
|
| 17 | 17 | import GHC.Driver.Env
|
| 18 | 18 | |
| 19 | +import GHC.Core.Predicate( saturatedFamApp_maybe )
|
|
| 19 | 20 | import GHC.Core.FamInstEnv
|
| 20 | 21 | import GHC.Core.Coercion
|
| 21 | 22 | import GHC.Core.TyCon
|
| ... | ... | @@ -715,15 +716,9 @@ reportInjectivityErrors dflags fi_ax axiom inj |
| 715 | 716 | when wrong_bare_rhs $ reportBareVariableInRHSErr fam_tc bare_variables axiom
|
| 716 | 717 | |
| 717 | 718 | -- | Is type headed by a type family application?
|
| 718 | -isTFHeaded :: Type -> Bool
|
|
| 719 | 719 | -- See Note [Verifying injectivity annotation], case 3.
|
| 720 | -isTFHeaded ty | Just ty' <- coreView ty
|
|
| 721 | - = isTFHeaded ty'
|
|
| 722 | -isTFHeaded ty | (TyConApp tc args) <- ty
|
|
| 723 | - , isTypeFamilyTyCon tc
|
|
| 724 | - = args `lengthIs` tyConArity tc
|
|
| 725 | -isTFHeaded _ = False
|
|
| 726 | - |
|
| 720 | +isTFHeaded :: Type -> Bool
|
|
| 721 | +isTFHeaded ty = isJust (saturatedFamApp_maybe ty)
|
|
| 727 | 722 | |
| 728 | 723 | -- | If a RHS is a bare type variable return a set of LHS patterns that are not
|
| 729 | 724 | -- bare type variables.
|
| ... | ... | @@ -24,16 +24,16 @@ import GHC.Tc.Types.Constraint |
| 24 | 24 | import GHC.Core.FamInstEnv
|
| 25 | 25 | import GHC.Core.Coercion
|
| 26 | 26 | import GHC.Core.TyCo.Rep( Type(..) )
|
| 27 | -import GHC.Core.Predicate( EqRel(..) )
|
|
| 27 | +import GHC.Core.TyCo.Subst( deepSubstTy )
|
|
| 28 | +import GHC.Core.Predicate( EqRel(..), saturatedFamApp_maybe )
|
|
| 28 | 29 | import GHC.Core.TyCon
|
| 29 | 30 | import GHC.Core.Unify( AmIUnifying(..)
|
| 30 | 31 | , tcUnifyTysForInjectivity, typeListsAreApart )
|
| 31 | 32 | import GHC.Core.Coercion.Axiom
|
| 32 | -import GHC.Core.TyCo.Subst( elemSubst, extendTvSubstWithClone )
|
|
| 33 | 33 | |
| 34 | 34 | import GHC.Builtin.WiredIn.TypeLits( tryInteractTopFam, tryInteractInertFam )
|
| 35 | 35 | |
| 36 | -import GHC.Types.Var( TyVar, tyVarKind, setTyVarKind )
|
|
| 36 | +import GHC.Types.Var( tyVarKind )
|
|
| 37 | 37 | import GHC.Types.Var.Set
|
| 38 | 38 | import GHC.Types.Var.Env( mkInScopeSet )
|
| 39 | 39 | |
| ... | ... | @@ -57,7 +57,6 @@ Here is our plan for dealing with functional dependencies |
| 57 | 57 | * send the current constraint back to the start of the pipeline;
|
| 58 | 58 | it might now be soluble, and it probably isn't inert
|
| 59 | 59 | |
| 60 | - |
|
| 61 | 60 | * Once a unification is done, it can't be un-done. So we must be very careful
|
| 62 | 61 | not to threaten completeness by doing a unification when there might be
|
| 63 | 62 | another way to solve the constraint.
|
| ... | ... | @@ -613,6 +612,7 @@ tryFamEqFunDeps mode eqs_for_me fam_tc work_args |
| 613 | 612 | |
| 614 | 613 | mkTopFamEqFDs :: TyCon -> [TcType] -> EqCt -> SolverStage [FunDepEqns]
|
| 615 | 614 | mkTopFamEqFDs fam_tc work_args work_item
|
| 615 | + -- NB: work_args exactly saturate fam_tc
|
|
| 616 | 616 | | isOpenTypeFamilyTyCon fam_tc
|
| 617 | 617 | , Injective inj_flags <- tyConInjectivityInfo fam_tc
|
| 618 | 618 | = -- Open, injective type families
|
| ... | ... | @@ -709,24 +709,24 @@ getRelevantBranches ax work_args work_rhs |
| 709 | 709 | , cab_lhs = lhs_tys
|
| 710 | 710 | , cab_rhs = rhs_ty })
|
| 711 | 711 | | Just subst <- tcUnifyTysForInjectivity Unifying (rhs_ty:lhs_tys) work_tys
|
| 712 | - -- See (RW1)-(RW3) in Note [Relevance]
|
|
| 713 | - -- This is a pre-/unification/ check (not matching)
|
|
| 714 | - -- so `subst` can bind both `qtvs` and fvs(work_tys)
|
|
| 715 | - , let (subst',qtvs') = trim_qtvs subst qtvs
|
|
| 716 | - lhs_tys' = substTys subst' lhs_tys
|
|
| 717 | - rhs_ty' = substTy subst' rhs_ty
|
|
| 718 | - branch_tys' = rhs_ty' : lhs_tys'
|
|
| 712 | + -- See (RW1)-(RW3) in Note [Relevance]
|
|
| 713 | + , let lhs_tys' = map (deepSubstTy subst) lhs_tys
|
|
| 714 | + -- deepSubstTy: see (CF8) in Note [Exploiting closed type families]
|
|
| 719 | 715 | , noEarlierMatchCheck lhs_tys' branch -- See (RW4) in Note [Relevance]
|
| 720 | - = Just (FDEqns { fd_qtvs = qtvs'
|
|
| 721 | - , fd_eqs = zipWith Pair branch_tys' work_tys })
|
|
| 722 | - -- Do not apply the substition to `work_tys`;
|
|
| 723 | - -- See (CF7) in Note [Exploiting closed type families]
|
|
| 716 | + = -- Ignore the substitution, except for `noEarlierMatchCheck`
|
|
| 717 | + -- See (CF7) in Note [Exploiting closed type families]
|
|
| 718 | + Just (FDEqns { fd_qtvs = qtvs
|
|
| 719 | + , fd_eqs = zipWith Pair (rhs_ty:lhs_tys) work_tys })
|
|
| 720 | + -- Do not apply the substitution to `work_tys`;
|
|
| 721 | + -- See (CF9) in Note [Exploiting closed type families]
|
|
| 722 | + |
|
| 724 | 723 | | otherwise
|
| 725 | 724 | = Nothing
|
| 726 | 725 | |
| 727 | 726 | mkTopOpenFamEqFDs :: TyCon -> [Bool] -> [TcType] -> EqCt -> TcS [FunDepEqns]
|
| 728 | 727 | -- Implements (INJFAM:Wanted/top-open)
|
| 729 | 728 | -- See Note [Exploiting open type families]
|
| 729 | +-- NB: work_args exactly saturate fam_tc
|
|
| 730 | 730 | mkTopOpenFamEqFDs fam_tc inj_flags work_args (EqCt { eq_rhs = work_rhs })
|
| 731 | 731 | = do { fam_envs <- getFamInstEnvs
|
| 732 | 732 | ; let branches :: [CoAxBranch]
|
| ... | ... | @@ -738,12 +738,11 @@ mkTopOpenFamEqFDs fam_tc inj_flags work_args (EqCt { eq_rhs = work_rhs }) |
| 738 | 738 | do_one (CoAxBranch { cab_tvs = branch_qtvs
|
| 739 | 739 | , cab_lhs = branch_lhs_tys
|
| 740 | 740 | , cab_rhs = branch_rhs })
|
| 741 | - | Just subst <- tcUnifyTysForInjectivity Matching [branch_rhs] [work_rhs]
|
|
| 742 | - , let (subst', qtvs') = trim_qtvs subst branch_qtvs
|
|
| 743 | - branch_lhs_tys' = substTys subst' branch_lhs_tys
|
|
| 744 | - -- No need for an apartness check here; for open type families
|
|
| 745 | - -- there are no "preceding" equations
|
|
| 746 | - = Just (mkInjectivityFDEqn inj_flags qtvs' branch_lhs_tys' work_args)
|
|
| 741 | + | Just {} <- tcUnifyTysForInjectivity Matching [branch_rhs] [work_rhs]
|
|
| 742 | + -- No need for an apartness check here;
|
|
| 743 | + -- for open type families there are no "preceding" equations
|
|
| 744 | + -- Both branch_lhs_tys and work_args exactly saturate fam_tc
|
|
| 745 | + = Just (mkInjectivityFDEqn branch_qtvs inj_flags branch_lhs_tys work_args)
|
|
| 747 | 746 | |
| 748 | 747 | | otherwise
|
| 749 | 748 | = Nothing
|
| ... | ... | @@ -756,9 +755,9 @@ mkLocalFamEqFDs eqs_for_me fam_tc inj_flags work_args work_rhs |
| 756 | 755 | = do { let -- eqns_from_inerts: see (INJFAM:Wanted/other)
|
| 757 | 756 | eqns_from_inerts = mapMaybe do_one eqs_for_me
|
| 758 | 757 | -- eqns_from_self: see (INJFAM:Wanted/Self)
|
| 759 | - eqns_from_self = case tcSplitTyConApp_maybe work_rhs of
|
|
| 760 | - Just (tc,rhs_tys) | tc==fam_tc -> [mk_eqn rhs_tys]
|
|
| 761 | - _ -> []
|
|
| 758 | + eqns_from_self = case saturatedFamApp_maybe work_rhs of
|
|
| 759 | + Just (tc, rhs_tys) | fam_tc == tc -> [mk_eqn rhs_tys]
|
|
| 760 | + _ -> []
|
|
| 762 | 761 | |
| 763 | 762 | ; return (eqns_from_inerts ++ eqns_from_self) }
|
| 764 | 763 | where
|
| ... | ... | @@ -768,7 +767,10 @@ mkLocalFamEqFDs eqs_for_me fam_tc inj_flags work_args work_rhs |
| 768 | 767 | | otherwise = Nothing
|
| 769 | 768 | do_one _ = pprPanic "interactFunEq 2" (ppr fam_tc) -- TyVarLHS
|
| 770 | 769 | |
| 771 | - mk_eqn iargs = mkInjectivityFDEqn inj_flags [] work_args iargs
|
|
| 770 | + mk_eqn iargs = mkInjectivityFDEqn [] inj_flags work_args iargs
|
|
| 771 | + |
|
| 772 | + |
|
| 773 | +{- See Historical Note [trim_qtvs]
|
|
| 772 | 774 | |
| 773 | 775 | trim_qtvs :: Subst -> [TyVar] -> (Subst, [TyVar])
|
| 774 | 776 | -- Tricky stuff: see (OF1) in Note [Exploiting open type families]
|
| ... | ... | @@ -790,7 +792,7 @@ trim_qtvs unif_subst qtvs |
| 790 | 792 | subst' = extendTvSubstWithClone subst tv tv'
|
| 791 | 793 | -- extendTvSubstWithClone: see (OF1b) in
|
| 792 | 794 | -- Note [Exploiting open type families]
|
| 793 | - |
|
| 795 | +-}
|
|
| 794 | 796 | |
| 795 | 797 | -----------------------------------------
|
| 796 | 798 | -- Built-in type families
|
| ... | ... | @@ -883,15 +885,22 @@ mkLocalBuiltinFamEqFDs eqs_for_me fam_tc ops work_args work_rhs |
| 883 | 885 | ; return (eqns_from_inerts ++ eqns_from_self) }
|
| 884 | 886 | |
| 885 | 887 | --------------------
|
| 886 | -mkInjectivityFDEqn :: [Bool] -- Injectivity flags
|
|
| 887 | - -> [TcTyVar] -- Quantify these
|
|
| 888 | +mkInjectivityFDEqn :: [TcTyVar] -- Quantify these
|
|
| 889 | + -> [Bool] -- Injectivity flags
|
|
| 888 | 890 | -> [TcType] -> [TcType] -- Make these equal
|
| 889 | 891 | -> FunDepEqns
|
| 890 | 892 | -- When F s1 s2 s3 ~ F t1 t2 t3, and F has injectivity info [True,False,True]
|
| 891 | 893 | -- return the FDEqns { fd_eqs = [Pair s1 t1, Pair s3 t3] }
|
| 892 | --- The injectivity flags [Bool] will not all be False, but nothing goes wrong if they are
|
|
| 893 | -mkInjectivityFDEqn inj_args qtvs lhs_args rhs_args
|
|
| 894 | - = FDEqns { fd_qtvs = qtvs, fd_eqs = eqs }
|
|
| 894 | +-- The injectivity flags [Bool] will not all be False,
|
|
| 895 | +-- but nothing goes wrong if they are
|
|
| 896 | +mkInjectivityFDEqn qtvs inj_args lhs_args rhs_args
|
|
| 897 | + = assertPpr (let len = length inj_args in
|
|
| 898 | + len == length lhs_args && len == length rhs_args)
|
|
| 899 | + (vcat [ text "inj_args:" <+> ppr inj_args
|
|
| 900 | + , text "lhs_args:" <+> ppr lhs_args
|
|
| 901 | + , text "rhs_args:" <+> ppr rhs_args ]) $
|
|
| 902 | + -- Need inj_args lhs_args and rhs_args to be same length for zip3
|
|
| 903 | + FDEqns { fd_qtvs = qtvs, fd_eqs = eqs }
|
|
| 895 | 904 | where
|
| 896 | 905 | eqs = [ Pair lhs_arg rhs_arg
|
| 897 | 906 | | (True, lhs_arg, rhs_arg) <- zip3 inj_args lhs_args rhs_args ]
|
| ... | ... | @@ -1104,7 +1113,7 @@ the Injective Type Families paper. For open type families, suppose we have |
| 1104 | 1113 | |
| 1105 | 1114 | [W] F alpha ~ Int->Int
|
| 1106 | 1115 | |
| 1107 | -Then, since F has been checked as injective, and the RHS `a->a` (pre-)unifies
|
|
| 1116 | +Then, since F has been checked as injective, and the RHS `a->a` (pre-)matches
|
|
| 1108 | 1117 | with the `Int->Int` in the Wanted with substitution [a :-> Int], we can
|
| 1109 | 1118 | add a derived FunDepEqns
|
| 1110 | 1119 | FDEqns{ fd_qtvs = [], fd_eqs = [ [Int] ~ alpha ] }
|
| ... | ... | @@ -1119,7 +1128,7 @@ instance are bound by the pre-unification step. Suppose we have |
| 1119 | 1128 | |
| 1120 | 1129 | [W] F alpha ~ [ty]
|
| 1121 | 1130 | |
| 1122 | -Then, the RHS [G a] pre-unifies with the RHS of the Wanted, but with an
|
|
| 1131 | +Then, the RHS [G a] pre-matches with the RHS of the Wanted, but with an
|
|
| 1123 | 1132 | empty substitution, which does not fix `a`. So we get this FunDepEqns:
|
| 1124 | 1133 | FDEqns{ fd_qtvs = a, fd_eqs = [ Maybe a ~ alpha ] }
|
| 1125 | 1134 | (note the fd_qtvs=a) and thereby emit (via `instantiateFunDepEqns`)
|
| ... | ... | @@ -1133,36 +1142,44 @@ In general we have: |
| 1133 | 1142 | type instance forall qs. F t1 ... tn = rhs
|
| 1134 | 1143 | [W] F a1 ... an ~ b
|
| 1135 | 1144 | |
| 1136 | -Suppose `b` pre-unifies with `rhs`, with substitution `S` that binds
|
|
| 1137 | -some (but perhaps not all) of the `qs`. Lets say
|
|
| 1138 | - unbound_qs = qs \ dom(S)
|
|
| 1139 | - |
|
| 1140 | -Then we generate the FunDepEqs
|
|
| 1141 | - FDEqns{ fd_qtvs = unbound_qs
|
|
| 1142 | - , fd_eqs = [ S(t1) ~ S(a1), S(t3) ~ S(a3) ]
|
|
| 1143 | - |
|
| 1144 | -These 'fd_qtvs' are subsequently instantiated to fresh metavariables by
|
|
| 1145 | -'instantiateFunDepEqns'.
|
|
| 1146 | - |
|
| 1147 | -(OF1) The computation of `unbound_qs` is done by `trim_qtvs`, but we
|
|
| 1148 | - have to be careful. Suppose (OF1a)
|
|
| 1149 | - qs = [ k::*, a::k ]
|
|
| 1150 | - S = [ k :-> UnliftedType ]
|
|
| 1151 | - Then we want
|
|
| 1152 | - unbound_qs = [ a::UnliftedType ] -- Must apply S to q's kind!!
|
|
| 1153 | - |
|
| 1154 | - And (OF1b), although I'm not sure if this can acutally happen:
|
|
| 1155 | - qs = [ k::*, a::(k::*), b::(a::k) ]
|
|
| 1156 | - S = [ k :-> UnliftedType ]
|
|
| 1157 | - We want
|
|
| 1158 | - unbound_qs = [ a::UnliftedType, b::(a::UnliftedType) ]
|
|
| 1159 | - Note that the occurrence of `a` in b's kind should be replaced by the
|
|
| 1160 | - newly-kinded `a` not the original `a::k`.
|
|
| 1161 | - |
|
| 1162 | - This fancy footwork for `fd_qtvs` is done by `trim_qtvs`. It
|
|
| 1163 | - * Drops a quantified tyvar that /is/ matched
|
|
| 1164 | - * Substitutes in the kind of a quantified tyvar `a` that is /not/ matched
|
|
| 1165 | - * Adds the substitution [a::k :-> a::S(k)] to the substitution
|
|
| 1145 | +Suppose `b` pre-matches with `rhs`, with substitution `S`. We /ignore/
|
|
| 1146 | +`S` and simply generate the FunDepEqs
|
|
| 1147 | + FDEqns{ fd_qtvs = qs, fd_eqs = [ t1 ~ a1, t3 ~ a3 ]
|
|
| 1148 | +These 'fd_qtvs' are subsequently instantiated to fresh meta-variables by
|
|
| 1149 | +'instantiateFunDepEqns'. See Historical Note [trim_qtvs].
|
|
| 1150 | + |
|
| 1151 | +Historical Note [trim_qtvs]
|
|
| 1152 | +~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
| 1153 | +In Note [Exploiting open type families], we previously tried to make use of
|
|
| 1154 | +the matching substitution `S`, by defining
|
|
| 1155 | + unbound_qs = qs \ dom(S)
|
|
| 1156 | +so that we could make fresh meta-variables for only the unbound `qs`.
|
|
| 1157 | +But it turned out to be tricky. Suppose (TQ1)
|
|
| 1158 | + qs = [ k::*, a::k ]
|
|
| 1159 | + S = [ k :-> UnliftedType ]
|
|
| 1160 | +Then we want
|
|
| 1161 | + unbound_qs = [ a::UnliftedType ] -- Must apply S to q's kind!!
|
|
| 1162 | + |
|
| 1163 | +And (TQ2), although I'm not sure if this can actually happen:
|
|
| 1164 | + qs = [ k::*, a::(k::*), b::(a::k) ]
|
|
| 1165 | + S = [ k :-> UnliftedType ]
|
|
| 1166 | +We want
|
|
| 1167 | + unbound_qs = [ a::UnliftedType, b::(a::UnliftedType) ]
|
|
| 1168 | +Note that the occurrence of `a` in b's kind should be replaced by the
|
|
| 1169 | +newly-kinded `a` not the original `a::k`.
|
|
| 1170 | + |
|
| 1171 | +This fancy footwork for `fd_qtvs` used to be done by `trim_qtvs`. It
|
|
| 1172 | + * Drops a quantified tyvar that /is/ matched
|
|
| 1173 | + * Substitutes in the kind of a quantified tyvar `a` that is /not/ matched
|
|
| 1174 | + * Adds the substitution [a::k :-> a::S(k)] to the substitution
|
|
| 1175 | + |
|
| 1176 | +(TQ3) This was hard enough for open type type families, which use matching.
|
|
| 1177 | +But it was ridiculously hard for /closed/ type families which use pre-/unification/
|
|
| 1178 | +so that the substitution `S` has both meta-tyvars and instance-head tyvars in
|
|
| 1179 | +the range.
|
|
| 1180 | + |
|
| 1181 | +It's much easier to drop all this and just make fresh meta-tyvars for
|
|
| 1182 | +all the quantified type variables.
|
|
| 1166 | 1183 | |
| 1167 | 1184 | Note [Exploiting closed type families] see `mkTopClosedFamEqFDs`
|
| 1168 | 1185 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
| ... | ... | @@ -1194,9 +1211,6 @@ More precisely, here is the very clever Closed Family Fundep Algorithm (CFFA) |
| 1194 | 1211 | with fresh unification vars in lhs and rhs for the quantified variables of the
|
| 1195 | 1212 | equation.
|
| 1196 | 1213 | |
| 1197 | - Actually we take advantage of the substitution generated by the relevance
|
|
| 1198 | - check, see (CF7) below.
|
|
| 1199 | - |
|
| 1200 | 1214 | See Note [Relevance] for what "relevant" means.
|
| 1201 | 1215 | We need to take care about non-termination; see (CF3).
|
| 1202 | 1216 | |
| ... | ... | @@ -1391,26 +1405,59 @@ Key point: equations that are not relevant do not need to be considered for fund |
| 1391 | 1405 | (CF7) Relevance. When computing relevance in the Closed Family Fundep Algorithm,
|
| 1392 | 1406 | for [W] F wlhs1 wlhs2 ~ wrhs, against an equation F lhs1 lhs2 ~ rhs
|
| 1393 | 1407 | we get back a pre-unifying substitution S that makes the two as equal as poss.
|
| 1394 | - Then we use `trim_qtvs` in exactly the same way as in
|
|
| 1395 | - (OF1) of Note [Exploiting open type families], to generate qtvs' and S'
|
|
| 1396 | - Then we generate
|
|
| 1397 | - FDEqns { fd_qtvs = qtvs', fd_eqs [ S'(lhs1) ~ wlhs1
|
|
| 1398 | - , S'(lhs2) ~ wlhs2
|
|
| 1399 | - , S'(rhs) ~ wrhs ] }
|
|
| 1400 | - Notice that we do /not/ apply S' to wlhs/wrhs. These type contain unification
|
|
| 1401 | - variables that we must actually unify! Example
|
|
| 1408 | + This substitution can bind both /quantified/ type variables from the instance,
|
|
| 1409 | + and /unification variables/ from the solver. Moreover, both kind of type variable
|
|
| 1410 | + can appear in the range of the substitution.
|
|
| 1411 | + |
|
| 1412 | + That's pretty complicated, so we are very cautious about using the returned
|
|
| 1413 | + substitution. I had a long struggle (#27994) when we were previously trying to
|
|
| 1414 | + apply that returned substitution as an optimisation. But because type variables
|
|
| 1415 | + can occur in kinds, it was a losing battle -- I ended up with TyVars from the
|
|
| 1416 | + instance head escaping into the solver. Consider
|
|
| 1417 | + |
|
| 1418 | + type F :: forall k. k -> *
|
|
| 1419 | + type instance F k a where
|
|
| 1420 | + F (k->*) (b::k->*) = Int
|
|
| 1421 | + |
|
| 1422 | + [W] F kappa (alpha::kappa) ~ Int
|
|
| 1423 | + |
|
| 1424 | + We unify the Wanted with the equation to get the substitution
|
|
| 1425 | + [ kappa :-> k->*, b :-> alpha ]
|
|
| 1426 | + I tried using `trim_qtvs` (see Historical Note [trim_qtvs]) but my head hurt
|
|
| 1427 | + FAR too much: #27994 is an excellent example. I gave up and now just ignore
|
|
| 1428 | + the substitution, making a fresh meta-var for each quantified variable.
|
|
| 1429 | + |
|
| 1430 | +(CF8) When computing relevance (Note [Relevance] (R2)) we use `noEarlierMatch`
|
|
| 1431 | + on S(lhs). But we must use /deep/ substitution on LHS. Consider
|
|
| 1432 | + type family F (a :: k) r where
|
|
| 1433 | + F @Type (Maybe Bool) r = r -- B0
|
|
| 1434 | + F @Type ((f :: Type -> Type) Int) r = Bool -- B1
|
|
| 1435 | + F @k ((g :: Type -> k) Int) r = r -- B2
|
|
| 1436 | + |
|
| 1437 | + [W] F @Type alpha Char ~ Char
|
|
| 1438 | + The `tcUnifyTysForInjectivity` will return substitution
|
|
| 1439 | + [k :-> Type, r :-> Char, alpha :-> (g :: Type->Type) Int], with g unbound
|
|
| 1440 | + If we used `substTy` on the LHS-tys for B2 we'd get
|
|
| 1441 | + lhs_tys' = [Type, (g :: Type -> k) Int, Char]
|
|
| 1442 | + That's ill-kinded because of the free `k`; and (worse) when `noEarlierMatch` matches
|
|
| 1443 | + lhs_tys' against earlier equations, (B1) will fail to match. So (B2) will be
|
|
| 1444 | + judged relevant, even though it isn't. Bad, bad. Use deep substitution.
|
|
| 1445 | + |
|
| 1446 | +(CF9) Notice that, when generating the fundep equations for the solver to deal
|
|
| 1447 | + with, we do /not/ apply the pre-unifying substitution S. The types wlhs,wrhs
|
|
| 1448 | + contain meta-variables that we must actually unify! Example
|
|
| 1402 | 1449 | type family F a b where
|
| 1403 | 1450 | F [a] (Maybe b) = (a, G b)
|
| 1404 | 1451 | [W] F alpha beta ~ (Int, [gamma])
|
| 1405 | 1452 | Pre-unification gives [alpha :-> [a], beta :-> Maybe b, a :-> Int]
|
| 1406 | - This substitution eliminates the quantified variable `a` but not `b`, so we
|
|
| 1407 | - want this:
|
|
| 1408 | - FDEqns { fd_qtvs = [b], fd_eqs [ [Int] ~ alpha
|
|
| 1409 | - , Maybe b ~ beta
|
|
| 1410 | - , (Int,G b) ~ (Int, [gamma]) ] }
|
|
| 1411 | - |
|
| 1412 | - Notice also that by applying the substitution to the template but not to the
|
|
| 1413 | - Wanted, we uphold the `fd_eqs` invariant in `FDEqns` (see its data type decl)
|
|
| 1453 | + We don't want to substitute `alpha` away! In fact we just generate these eqns:
|
|
| 1454 | + FDEqns { fd_qtvs = [a,b], fd_eqs [ [a] ~ alpha
|
|
| 1455 | + , Maybe b ~ beta
|
|
| 1456 | + , (a, G b) ~ (Int, [gamma]) ] }
|
|
| 1457 | + with `fd_qtvs` being the quantified variables of the equation, the LHSs
|
|
| 1458 | + being the types from the equation and the RHSs being the types from the Wanted.
|
|
| 1459 | + Notice that we thereby uphold the `fd_eqs` invariant in `FDEqns` (see its data
|
|
| 1460 | + type decl).
|
|
| 1414 | 1461 | |
| 1415 | 1462 | Note [Cache-caused loops]
|
| 1416 | 1463 | ~~~~~~~~~~~~~~~~~~~~~~~~~
|
| ... | ... | @@ -1517,8 +1564,8 @@ instantiateFunDepEqns (FDEqns { fd_qtvs = qtvs, fd_eqs = eqs }) |
| 1517 | 1564 | rev_eqs = reverse eqs
|
| 1518 | 1565 | -- (reverse eqs): See Note [Reverse order of fundep equations]
|
| 1519 | 1566 | |
| 1520 | - -- The kinds of `qtvs` can have free variables, because of `trim_qtvs`
|
|
| 1521 | - -- Example: T27828b
|
|
| 1567 | + -- The kinds of `qtvs` can have free variables;
|
|
| 1568 | + -- in the FDEqns produced by GHC.Tc.Instance.FunDeps.improveFromInstEnv
|
|
| 1522 | 1569 | empty_subst = mkEmptySubst $ mkInScopeSet $
|
| 1523 | 1570 | tyCoVarsOfTypes (map tyVarKind qtvs)
|
| 1524 | 1571 |
| 1 | +{-# LANGUAGE AllowAmbiguousTypes #-}
|
|
| 2 | +{-# LANGUAGE DataKinds #-}
|
|
| 3 | +{-# LANGUAGE FunctionalDependencies #-}
|
|
| 4 | +{-# LANGUAGE GADTs #-}
|
|
| 5 | +{-# LANGUAGE TypeFamilies #-}
|
|
| 6 | +module T27994a (l2) where
|
|
| 7 | + |
|
| 8 | +import Data.Kind (Constraint, Type)
|
|
| 9 | + |
|
| 10 | +l1 :: [String]
|
|
| 11 | +l1 = ["hello", "world!"]
|
|
| 12 | + |
|
| 13 | +l2 :: [Int]
|
|
| 14 | +l2 = gmap (HCons length HNil) l1
|
|
| 15 | + |
|
| 16 | +-----
|
|
| 17 | + |
|
| 18 | +type HList :: [Type] -> Type
|
|
| 19 | +data HList p where
|
|
| 20 | + HNil :: HList '[]
|
|
| 21 | + HCons :: x -> HList xs -> HList (x:xs)
|
|
| 22 | + |
|
| 23 | +type ($$) :: k -> [Type] -> Type
|
|
| 24 | +type family s $$ p where
|
|
| 25 | + (s :: Type) $$ '[] = s
|
|
| 26 | + (s :: Type -> k) $$ (a:b) = s a $$ b
|
|
| 27 | + |
|
| 28 | +type Doms :: [Type] -> [Type]
|
|
| 29 | +type family Doms t where
|
|
| 30 | + Doms '[] = '[]
|
|
| 31 | + Doms ((a -> b) : t) = a : Doms t
|
|
| 32 | + |
|
| 33 | +type Codoms :: [Type] -> [Type]
|
|
| 34 | +type family Codoms t where
|
|
| 35 | + Codoms '[] = '[]
|
|
| 36 | + Codoms ((a -> b) : t) = b : Codoms t
|
|
| 37 | + |
|
| 38 | +type GMap :: k -> [Type] -> Constraint
|
|
| 39 | +class GMap (s :: k) t | t -> k where
|
|
| 40 | + gmap :: HList t -> s $$ Doms t -> s $$ Codoms t
|
|
| 41 | + |
|
| 42 | +instance GMap [] '[a -> b] where
|
|
| 43 | + gmap :: HList '[a -> b] -> [a] -> [b]
|
|
| 44 | + gmap (HCons f HNil) = go
|
|
| 45 | + where
|
|
| 46 | + go :: [a] -> [b]
|
|
| 47 | + go [] = []
|
|
| 48 | + go (x:xs) = f x : go xs |
| 1 | +{-# LANGUAGE DataKinds, TypeFamilies, PolyKinds, GADTs, AllowAmbiguousTypes #-}
|
|
| 2 | +module T27994 where
|
|
| 3 | + |
|
| 4 | +import Data.Kind (Type)
|
|
| 5 | +import Data.Proxy (Proxy)
|
|
| 6 | + |
|
| 7 | +type F :: forall{k}. k -> Type -> Type
|
|
| 8 | +type family F s x where
|
|
| 9 | + F (s :: Type -> k) (Proxy s) = Int
|
|
| 10 | + |
|
| 11 | +f :: forall k (s :: k) x. F s x -> x
|
|
| 12 | +f _ = undefined
|
|
| 13 | + |
|
| 14 | +g :: Proxy Maybe -> ()
|
|
| 15 | +g _ = ()
|
|
| 16 | + |
|
| 17 | +data T a where
|
|
| 18 | + MkT :: T Int
|
|
| 19 | + |
|
| 20 | +test :: T a -> ()
|
|
| 21 | +test t = (\y -> case t of MkT -> g y) (f (3 :: Int))
|
|
| 22 | + |
|
| 23 | +{- [W] F @k_azX (s_azY::k_azX) p_azN ~ Int
|
|
| 24 | + |
|
| 25 | +unify [*->k, s::*->k, Proxy @(*->k) (s::*->k), Int]
|
|
| 26 | + ~ [k_azX, s_azY::k_azX, p_azN, Int]
|
|
| 27 | + |
|
| 28 | + --> [ k_azX :-> (* -> k)
|
|
| 29 | + , s :-> s_azY::k_azX
|
|
| 30 | + , p_azN :-> Proxy @(*->k) (s::*->k) ]
|
|
| 31 | + |
|
| 32 | + fixpt --> [ k_azX :-> Type -> k
|
|
| 33 | + , s :-> s_azY::(Type -> k)
|
|
| 34 | + , p_azN :-> Proxy @(Type->k) (s::k_azX) ]
|
|
| 35 | + |
|
| 36 | +Generate a [W] for each pair
|
|
| 37 | + [W] k ~ k_azX
|
|
| 38 | + [W] s ~ s_azY
|
|
| 39 | + [W] Proxy s ~ p_azN
|
|
| 40 | + [W] Int ~ Int
|
|
| 41 | +As an opt (claim) apply subst first
|
|
| 42 | + [W] k_azX ~ k_azX
|
|
| 43 | + [W] s_azY ~ s_azY
|
|
| 44 | + [W] Proxy s_azY ~ p_azN
|
|
| 45 | + [W] Int ~ Int
|
|
| 46 | + |
|
| 47 | +-- [W] F @k_azX s_azY[tau] p_azN ~ Int
|
|
| 48 | +-- Want: fresh k' s'
|
|
| 49 | +-- [W] k' ~ k_azX
|
|
| 50 | +-- [W] s':k' ~ s_azY:k_azX
|
|
| 51 | +-- [W] Proxy s' ~ x
|
|
| 52 | +-}
|
|
| 53 | + |
| ... | ... | @@ -972,4 +972,6 @@ test('T27557', normal, compile, ['']) |
| 972 | 972 | test('T27664', normal, compile, [''])
|
| 973 | 973 | test('T27916', normal, compile, [''])
|
| 974 | 974 | test('T26543_orig', normal, compile, [''])
|
| 975 | +test('T27994', normal, compile, [''])
|
|
| 976 | +test('T27994a', normal, compile, [''])
|
|
| 975 | 977 |