{-# LANGUAGE CPP, LambdaCase, TupleSections, PatternSynonyms, ViewPatterns, MultiWayIf #-}
module GHC.HsToCore.PmCheck.Oracle (
DsM, tracePm, mkPmId,
Delta, initDeltas, lookupRefuts, lookupSolution,
PmCt(PmTyCt), PmCts, pattern PmVarCt, pattern PmCoreCt,
pattern PmConCt, pattern PmNotConCt, pattern PmBotCt,
pattern PmNotBotCt,
addPmCts,
canDiverge,
provideEvidence
) where
#include "HsVersions.h"
import GHC.Prelude
import GHC.HsToCore.PmCheck.Types
import GHC.Driver.Session
import GHC.Utils.Outputable
import GHC.Utils.Error
import GHC.Utils.Misc
import GHC.Data.Bag
import GHC.Types.Unique.Set
import GHC.Types.Unique.DSet
import GHC.Types.Unique
import GHC.Types.Id
import GHC.Types.Var.Env
import GHC.Types.Unique.DFM
import GHC.Types.Var (EvVar)
import GHC.Types.Name
import GHC.Core
import GHC.Core.FVs (exprFreeVars)
import GHC.Core.Map
import GHC.Core.SimpleOpt (simpleOptExpr, exprIsConApp_maybe)
import GHC.Core.Utils (exprType)
import GHC.Core.Make (mkListExpr, mkCharExpr)
import GHC.Types.Unique.Supply
import GHC.Data.FastString
import GHC.Types.SrcLoc
import GHC.Data.Maybe
import GHC.Core.ConLike
import GHC.Core.DataCon
import GHC.Core.PatSyn
import GHC.Core.TyCon
import GHC.Builtin.Types
import GHC.Builtin.Types.Prim (tYPETyCon)
import GHC.Core.TyCo.Rep
import GHC.Core.Type
import GHC.Tc.Solver (tcNormalise, tcCheckSatisfiability)
import GHC.Core.Unify (tcMatchTy)
import GHC.Tc.Types (completeMatchConLikes)
import GHC.Core.Coercion
import GHC.Utils.Monad hiding (foldlM)
import GHC.HsToCore.Monad hiding (foldlM)
import GHC.Tc.Instance.Family
import GHC.Core.FamInstEnv
import Control.Monad (guard, mzero, when)
import Control.Monad.Trans.Class (lift)
import Control.Monad.Trans.State.Strict
import Data.Bifunctor (second)
import Data.Either (partitionEithers)
import Data.Foldable (foldlM, minimumBy, toList)
import Data.List (find)
import qualified Data.List.NonEmpty as NonEmpty
import Data.Ord (comparing)
import qualified Data.Semigroup as Semigroup
import Data.Tuple (swap)
tracePm :: String -> SDoc -> DsM ()
tracePm :: String -> SDoc -> DsM ()
tracePm String
herald SDoc
doc = do
DynFlags
dflags <- IOEnv (Env DsGblEnv DsLclEnv) DynFlags
forall (m :: * -> *). HasDynFlags m => m DynFlags
getDynFlags
PrintUnqualified
printer <- DsM PrintUnqualified
mkPrintUnqualifiedDs
IO () -> DsM ()
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO () -> DsM ()) -> IO () -> DsM ()
forall a b. (a -> b) -> a -> b
$ PrintUnqualified
-> DynFlags -> DumpFlag -> String -> DumpFormat -> SDoc -> IO ()
dumpIfSet_dyn_printer PrintUnqualified
printer DynFlags
dflags
DumpFlag
Opt_D_dump_ec_trace String
"" DumpFormat
FormatText (String -> SDoc
text String
herald SDoc -> SDoc -> SDoc
$$ (Int -> SDoc -> SDoc
nest Int
2 SDoc
doc))
{-# INLINE tracePm #-}
mkPmId :: Type -> DsM Id
mkPmId :: Type -> DsM Id
mkPmId Type
ty = IOEnv (Env DsGblEnv DsLclEnv) Unique
forall (m :: * -> *). MonadUnique m => m Unique
getUniqueM IOEnv (Env DsGblEnv DsLclEnv) Unique
-> (Unique -> DsM Id) -> DsM Id
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \Unique
unique ->
let occname :: OccName
occname = FastString -> OccName
mkVarOccFS (FastString -> OccName) -> FastString -> OccName
forall a b. (a -> b) -> a -> b
$ String -> FastString
fsLit String
"pm"
name :: Name
name = Unique -> OccName -> SrcSpan -> Name
mkInternalName Unique
unique OccName
occname SrcSpan
noSrcSpan
in Id -> DsM Id
forall (m :: * -> *) a. Monad m => a -> m a
return (Name -> Type -> Type -> Id
mkLocalIdOrCoVar Name
name Type
Many Type
ty)
markMatched :: ConLike -> PossibleMatches -> PossibleMatches
markMatched :: ConLike -> PossibleMatches -> PossibleMatches
markMatched ConLike
_ PossibleMatches
NoPM = PossibleMatches
NoPM
markMatched ConLike
con (PM NonEmpty ConLikeSet
ms) = NonEmpty ConLikeSet -> PossibleMatches
PM (ConLike -> ConLikeSet -> ConLikeSet
del_one_con ConLike
con (ConLikeSet -> ConLikeSet)
-> NonEmpty ConLikeSet -> NonEmpty ConLikeSet
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> NonEmpty ConLikeSet
ms)
where
del_one_con :: ConLike -> ConLikeSet -> ConLikeSet
del_one_con = (ConLikeSet -> ConLike -> ConLikeSet)
-> ConLike -> ConLikeSet -> ConLikeSet
forall a b c. (a -> b -> c) -> b -> a -> c
flip ConLikeSet -> ConLike -> ConLikeSet
forall a. Uniquable a => UniqDSet a -> a -> UniqDSet a
delOneFromUniqDSet
mkOneConFull :: [Type] -> ConLike -> DsM ([TyVar], [Id], Bag TyCt, [Type])
mkOneConFull :: [Type] -> ConLike -> DsM ([Id], [Id], Bag Type, [Type])
mkOneConFull [Type]
arg_tys ConLike
con = do
let ([Id]
univ_tvs, [Id]
ex_tvs, [EqSpec]
eq_spec, [Type]
thetas, [Type]
_req_theta, [Scaled Type]
field_tys, Type
_con_res_ty)
= ConLike
-> ([Id], [Id], [EqSpec], [Type], [Type], [Scaled Type], Type)
conLikeFullSig ConLike
con
let subst_univ :: TCvSubst
subst_univ = [Id] -> [Type] -> TCvSubst
HasDebugCallStack => [Id] -> [Type] -> TCvSubst
zipTvSubst [Id]
univ_tvs [Type]
arg_tys
(TCvSubst
subst, [Id]
_) <- TCvSubst -> [Id] -> UniqSupply -> (TCvSubst, [Id])
cloneTyVarBndrs TCvSubst
subst_univ [Id]
ex_tvs (UniqSupply -> (TCvSubst, [Id]))
-> IOEnv (Env DsGblEnv DsLclEnv) UniqSupply
-> IOEnv (Env DsGblEnv DsLclEnv) (TCvSubst, [Id])
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> IOEnv (Env DsGblEnv DsLclEnv) UniqSupply
forall (m :: * -> *). MonadUnique m => m UniqSupply
getUniqueSupplyM
let field_tys' :: [Type]
field_tys' = HasCallStack => TCvSubst -> [Type] -> [Type]
TCvSubst -> [Type] -> [Type]
substTys TCvSubst
subst ([Type] -> [Type]) -> [Type] -> [Type]
forall a b. (a -> b) -> a -> b
$ (Scaled Type -> Type) -> [Scaled Type] -> [Type]
forall a b. (a -> b) -> [a] -> [b]
map Scaled Type -> Type
forall a. Scaled a -> a
scaledThing [Scaled Type]
field_tys
[Id]
vars <- (Type -> DsM Id) -> [Type] -> IOEnv (Env DsGblEnv DsLclEnv) [Id]
forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
mapM Type -> DsM Id
mkPmId [Type]
field_tys'
let ty_cs :: [Type]
ty_cs = HasCallStack => TCvSubst -> [Type] -> [Type]
TCvSubst -> [Type] -> [Type]
substTheta TCvSubst
subst ([EqSpec] -> [Type]
eqSpecPreds [EqSpec]
eq_spec [Type] -> [Type] -> [Type]
forall a. [a] -> [a] -> [a]
++ [Type]
thetas)
let arg_is_strict :: [Bool]
arg_is_strict
| RealDataCon DataCon
dc <- ConLike
con
, TyCon -> Bool
isNewTyCon (DataCon -> TyCon
dataConTyCon DataCon
dc)
= [Bool
True]
| Bool
otherwise
= (HsImplBang -> Bool) -> [HsImplBang] -> [Bool]
forall a b. (a -> b) -> [a] -> [b]
map HsImplBang -> Bool
isBanged ([HsImplBang] -> [Bool]) -> [HsImplBang] -> [Bool]
forall a b. (a -> b) -> a -> b
$ ConLike -> [HsImplBang]
conLikeImplBangs ConLike
con
strict_arg_tys :: [Type]
strict_arg_tys = [Bool] -> [Type] -> [Type]
forall a. [Bool] -> [a] -> [a]
filterByList [Bool]
arg_is_strict [Type]
field_tys'
([Id], [Id], Bag Type, [Type])
-> DsM ([Id], [Id], Bag Type, [Type])
forall (m :: * -> *) a. Monad m => a -> m a
return ([Id]
ex_tvs, [Id]
vars, [Type] -> Bag Type
forall a. [a] -> Bag a
listToBag [Type]
ty_cs, [Type]
strict_arg_tys)
newtype SatisfiabilityCheck = SC (Delta -> DsM (Maybe Delta))
runSatisfiabilityCheck :: Delta -> SatisfiabilityCheck -> DsM (Maybe Delta)
runSatisfiabilityCheck :: Delta -> SatisfiabilityCheck -> DsM (Maybe Delta)
runSatisfiabilityCheck Delta
delta (SC Delta -> DsM (Maybe Delta)
chk) = Delta -> DsM (Maybe Delta)
chk Delta
delta
instance Semigroup SatisfiabilityCheck where
SC Delta -> DsM (Maybe Delta)
a <> :: SatisfiabilityCheck -> SatisfiabilityCheck -> SatisfiabilityCheck
<> SC Delta -> DsM (Maybe Delta)
b = (Delta -> DsM (Maybe Delta)) -> SatisfiabilityCheck
SC Delta -> DsM (Maybe Delta)
c
where
c :: Delta -> DsM (Maybe Delta)
c Delta
delta = Delta -> DsM (Maybe Delta)
a Delta
delta DsM (Maybe Delta)
-> (Maybe Delta -> DsM (Maybe Delta)) -> DsM (Maybe Delta)
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \case
Maybe Delta
Nothing -> Maybe Delta -> DsM (Maybe Delta)
forall (f :: * -> *) a. Applicative f => a -> f a
pure Maybe Delta
forall a. Maybe a
Nothing
Just Delta
delta' -> Delta -> DsM (Maybe Delta)
b Delta
delta'
instance Monoid SatisfiabilityCheck where
mempty :: SatisfiabilityCheck
mempty = (Delta -> DsM (Maybe Delta)) -> SatisfiabilityCheck
SC (Maybe Delta -> DsM (Maybe Delta)
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Maybe Delta -> DsM (Maybe Delta))
-> (Delta -> Maybe Delta) -> Delta -> DsM (Maybe Delta)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Delta -> Maybe Delta
forall a. a -> Maybe a
Just)
pmIsSatisfiable
:: Delta
-> Bag TyCt
-> Bag TmCt
-> [Type]
-> DsM (Maybe Delta)
pmIsSatisfiable :: Delta -> Bag Type -> Bag TmCt -> [Type] -> DsM (Maybe Delta)
pmIsSatisfiable Delta
amb_cs Bag Type
new_ty_cs Bag TmCt
new_tm_cs [Type]
strict_arg_tys =
Delta -> SatisfiabilityCheck -> DsM (Maybe Delta)
runSatisfiabilityCheck Delta
amb_cs (SatisfiabilityCheck -> DsM (Maybe Delta))
-> SatisfiabilityCheck -> DsM (Maybe Delta)
forall a b. (a -> b) -> a -> b
$ [SatisfiabilityCheck] -> SatisfiabilityCheck
forall a. Monoid a => [a] -> a
mconcat
[ Bool -> Bag Type -> SatisfiabilityCheck
tyIsSatisfiable Bool
True Bag Type
new_ty_cs
, Bag TmCt -> SatisfiabilityCheck
tmIsSatisfiable Bag TmCt
new_tm_cs
, RecTcChecker -> [Type] -> SatisfiabilityCheck
tysAreNonVoid RecTcChecker
initRecTc [Type]
strict_arg_tys
]
data TopNormaliseTypeResult
= NoChange Type
| NormalisedByConstraints Type
| HadRedexes Type [(Type, DataCon, Type)] Type
normalisedSourceType :: TopNormaliseTypeResult -> Type
normalisedSourceType :: TopNormaliseTypeResult -> Type
normalisedSourceType (NoChange Type
ty) = Type
ty
normalisedSourceType (NormalisedByConstraints Type
ty) = Type
ty
normalisedSourceType (HadRedexes Type
ty [(Type, DataCon, Type)]
_ Type
_) = Type
ty
tntrGuts :: TopNormaliseTypeResult -> (Type, [(Type, DataCon, Type)], Type)
tntrGuts :: TopNormaliseTypeResult -> (Type, [(Type, DataCon, Type)], Type)
tntrGuts (NoChange Type
ty) = (Type
ty, [], Type
ty)
tntrGuts (NormalisedByConstraints Type
ty) = (Type
ty, [], Type
ty)
tntrGuts (HadRedexes Type
src_ty [(Type, DataCon, Type)]
ds Type
core_ty) = (Type
src_ty, [(Type, DataCon, Type)]
ds, Type
core_ty)
instance Outputable TopNormaliseTypeResult where
ppr :: TopNormaliseTypeResult -> SDoc
ppr (NoChange Type
ty) = String -> SDoc
text String
"NoChange" SDoc -> SDoc -> SDoc
<+> Type -> SDoc
forall a. Outputable a => a -> SDoc
ppr Type
ty
ppr (NormalisedByConstraints Type
ty) = String -> SDoc
text String
"NormalisedByConstraints" SDoc -> SDoc -> SDoc
<+> Type -> SDoc
forall a. Outputable a => a -> SDoc
ppr Type
ty
ppr (HadRedexes Type
src_ty [(Type, DataCon, Type)]
ds Type
core_ty) = String -> SDoc
text String
"HadRedexes" SDoc -> SDoc -> SDoc
<+> SDoc -> SDoc
braces SDoc
fields
where
fields :: SDoc
fields = [SDoc] -> SDoc
fsep (SDoc -> [SDoc] -> [SDoc]
punctuate SDoc
comma [ String -> SDoc
text String
"src_ty =" SDoc -> SDoc -> SDoc
<+> Type -> SDoc
forall a. Outputable a => a -> SDoc
ppr Type
src_ty
, String -> SDoc
text String
"newtype_dcs =" SDoc -> SDoc -> SDoc
<+> [(Type, DataCon, Type)] -> SDoc
forall a. Outputable a => a -> SDoc
ppr [(Type, DataCon, Type)]
ds
, String -> SDoc
text String
"core_ty =" SDoc -> SDoc -> SDoc
<+> Type -> SDoc
forall a. Outputable a => a -> SDoc
ppr Type
core_ty ])
pmTopNormaliseType :: TyState -> Type -> DsM TopNormaliseTypeResult
pmTopNormaliseType :: TyState -> Type -> DsM TopNormaliseTypeResult
pmTopNormaliseType (TySt Bag Id
inert) Type
typ
= do FamInstEnvs
env <- DsM FamInstEnvs
dsGetFamInstEnvs
(Messages
_, Maybe Type
mb_typ') <- TcM Type -> DsM (Messages, Maybe Type)
forall a. TcM a -> DsM (Messages, Maybe a)
initTcDsForSolver (TcM Type -> DsM (Messages, Maybe Type))
-> TcM Type -> DsM (Messages, Maybe Type)
forall a b. (a -> b) -> a -> b
$ Bag Id -> Type -> TcM Type
tcNormalise Bag Id
inert Type
typ
let typ' :: Type
typ' = Type -> Maybe Type -> Type
forall a. a -> Maybe a -> a
fromMaybe Type
typ Maybe Type
mb_typ'
TopNormaliseTypeResult -> DsM TopNormaliseTypeResult
forall (f :: * -> *) a. Applicative f => a -> f a
pure (TopNormaliseTypeResult -> DsM TopNormaliseTypeResult)
-> TopNormaliseTypeResult -> DsM TopNormaliseTypeResult
forall a b. (a -> b) -> a -> b
$ case NormaliseStepper
([Type] -> [Type],
[(Type, DataCon, Type)] -> [(Type, DataCon, Type)])
-> (([Type] -> [Type],
[(Type, DataCon, Type)] -> [(Type, DataCon, Type)])
-> ([Type] -> [Type],
[(Type, DataCon, Type)] -> [(Type, DataCon, Type)])
-> ([Type] -> [Type],
[(Type, DataCon, Type)] -> [(Type, DataCon, Type)]))
-> Type
-> Maybe
(([Type] -> [Type],
[(Type, DataCon, Type)] -> [(Type, DataCon, Type)]),
Type)
forall ev.
NormaliseStepper ev -> (ev -> ev -> ev) -> Type -> Maybe (ev, Type)
topNormaliseTypeX (FamInstEnvs
-> NormaliseStepper
([Type] -> [Type],
[(Type, DataCon, Type)] -> [(Type, DataCon, Type)])
stepper FamInstEnvs
env) ([Type] -> [Type],
[(Type, DataCon, Type)] -> [(Type, DataCon, Type)])
-> ([Type] -> [Type],
[(Type, DataCon, Type)] -> [(Type, DataCon, Type)])
-> ([Type] -> [Type],
[(Type, DataCon, Type)] -> [(Type, DataCon, Type)])
forall {b} {c} {b} {c} {a} {a}.
(b -> c, b -> c) -> (a -> b, a -> b) -> (a -> c, a -> c)
comb Type
typ' of
Maybe
(([Type] -> [Type],
[(Type, DataCon, Type)] -> [(Type, DataCon, Type)]),
Type)
Nothing
| Maybe Type
Nothing <- Maybe Type
mb_typ' -> Type -> TopNormaliseTypeResult
NoChange Type
typ
| Bool
otherwise -> Type -> TopNormaliseTypeResult
NormalisedByConstraints Type
typ'
Just (([Type] -> [Type]
ty_f,[(Type, DataCon, Type)] -> [(Type, DataCon, Type)]
tm_f), Type
ty) -> Type -> [(Type, DataCon, Type)] -> Type -> TopNormaliseTypeResult
HadRedexes Type
src_ty [(Type, DataCon, Type)]
newtype_dcs Type
core_ty
where
src_ty :: Type
src_ty = Type -> [Type] -> Type
eq_src_ty Type
ty (Type
typ' Type -> [Type] -> [Type]
forall a. a -> [a] -> [a]
: [Type] -> [Type]
ty_f [Type
ty])
newtype_dcs :: [(Type, DataCon, Type)]
newtype_dcs = [(Type, DataCon, Type)] -> [(Type, DataCon, Type)]
tm_f []
core_ty :: Type
core_ty = Type
ty
where
eq_src_ty :: Type -> [Type] -> Type
eq_src_ty :: Type -> [Type] -> Type
eq_src_ty Type
ty [Type]
tys = Type -> (Type -> Type) -> Maybe Type -> Type
forall b a. b -> (a -> b) -> Maybe a -> b
maybe Type
ty Type -> Type
forall a. a -> a
id ((Type -> Bool) -> [Type] -> Maybe Type
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Maybe a
find Type -> Bool
is_closed_or_data_family [Type]
tys)
is_closed_or_data_family :: Type -> Bool
is_closed_or_data_family :: Type -> Bool
is_closed_or_data_family Type
ty = Type -> Bool
pmIsClosedType Type
ty Bool -> Bool -> Bool
|| Type -> Bool
isDataFamilyAppType Type
ty
comb :: (b -> c, b -> c) -> (a -> b, a -> b) -> (a -> c, a -> c)
comb (b -> c
tyf1, b -> c
tmf1) (a -> b
tyf2, a -> b
tmf2) = (b -> c
tyf1 (b -> c) -> (a -> b) -> a -> c
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> b
tyf2, b -> c
tmf1 (b -> c) -> (a -> b) -> a -> c
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> b
tmf2)
stepper :: FamInstEnvs
-> NormaliseStepper
([Type] -> [Type],
[(Type, DataCon, Type)] -> [(Type, DataCon, Type)])
stepper FamInstEnvs
env = NormaliseStepper
([Type] -> [Type],
[(Type, DataCon, Type)] -> [(Type, DataCon, Type)])
newTypeStepper NormaliseStepper
([Type] -> [Type],
[(Type, DataCon, Type)] -> [(Type, DataCon, Type)])
-> NormaliseStepper
([Type] -> [Type],
[(Type, DataCon, Type)] -> [(Type, DataCon, Type)])
-> NormaliseStepper
([Type] -> [Type],
[(Type, DataCon, Type)] -> [(Type, DataCon, Type)])
forall ev.
NormaliseStepper ev -> NormaliseStepper ev -> NormaliseStepper ev
`composeSteppers` FamInstEnvs
-> NormaliseStepper
([Type] -> [Type],
[(Type, DataCon, Type)] -> [(Type, DataCon, Type)])
forall a.
FamInstEnvs -> NormaliseStepper ([Type] -> [Type], a -> a)
tyFamStepper FamInstEnvs
env
newTypeStepper :: NormaliseStepper ([Type] -> [Type],[(Type, DataCon, Type)] -> [(Type, DataCon, Type)])
newTypeStepper :: NormaliseStepper
([Type] -> [Type],
[(Type, DataCon, Type)] -> [(Type, DataCon, Type)])
newTypeStepper RecTcChecker
rec_nts TyCon
tc [Type]
tys
| Just (Type
ty', Coercion
_co) <- TyCon -> [Type] -> Maybe (Type, Coercion)
instNewTyCon_maybe TyCon
tc [Type]
tys
, let orig_ty :: Type
orig_ty = TyCon -> [Type] -> Type
TyConApp TyCon
tc [Type]
tys
= case RecTcChecker -> TyCon -> Maybe RecTcChecker
checkRecTc RecTcChecker
rec_nts TyCon
tc of
Just RecTcChecker
rec_nts' -> let tyf :: [Type] -> [Type]
tyf = (Type
orig_tyType -> [Type] -> [Type]
forall a. a -> [a] -> [a]
:)
tmf :: [(Type, DataCon, Type)] -> [(Type, DataCon, Type)]
tmf = ((Type
orig_ty, TyCon -> DataCon
tyConSingleDataCon TyCon
tc, Type
ty')(Type, DataCon, Type)
-> [(Type, DataCon, Type)] -> [(Type, DataCon, Type)]
forall a. a -> [a] -> [a]
:)
in RecTcChecker
-> Type
-> ([Type] -> [Type],
[(Type, DataCon, Type)] -> [(Type, DataCon, Type)])
-> NormaliseStepResult
([Type] -> [Type],
[(Type, DataCon, Type)] -> [(Type, DataCon, Type)])
forall ev. RecTcChecker -> Type -> ev -> NormaliseStepResult ev
NS_Step RecTcChecker
rec_nts' Type
ty' ([Type] -> [Type]
tyf, [(Type, DataCon, Type)] -> [(Type, DataCon, Type)]
tmf)
Maybe RecTcChecker
Nothing -> NormaliseStepResult
([Type] -> [Type],
[(Type, DataCon, Type)] -> [(Type, DataCon, Type)])
forall ev. NormaliseStepResult ev
NS_Abort
| Bool
otherwise
= NormaliseStepResult
([Type] -> [Type],
[(Type, DataCon, Type)] -> [(Type, DataCon, Type)])
forall ev. NormaliseStepResult ev
NS_Done
tyFamStepper :: FamInstEnvs -> NormaliseStepper ([Type] -> [Type], a -> a)
tyFamStepper :: forall a.
FamInstEnvs -> NormaliseStepper ([Type] -> [Type], a -> a)
tyFamStepper FamInstEnvs
env RecTcChecker
rec_nts TyCon
tc [Type]
tys
= case FamInstEnvs -> TyCon -> [Type] -> Maybe (Coercion, Type, Coercion)
topReduceTyFamApp_maybe FamInstEnvs
env TyCon
tc [Type]
tys of
Just (Coercion
_, Type
rhs, Coercion
_) -> RecTcChecker
-> Type
-> ([Type] -> [Type], a -> a)
-> NormaliseStepResult ([Type] -> [Type], a -> a)
forall ev. RecTcChecker -> Type -> ev -> NormaliseStepResult ev
NS_Step RecTcChecker
rec_nts Type
rhs ((Type
rhsType -> [Type] -> [Type]
forall a. a -> [a] -> [a]
:), a -> a
forall a. a -> a
id)
Maybe (Coercion, Type, Coercion)
_ -> NormaliseStepResult ([Type] -> [Type], a -> a)
forall ev. NormaliseStepResult ev
NS_Done
pmIsClosedType :: Type -> Bool
pmIsClosedType :: Type -> Bool
pmIsClosedType Type
ty
= case HasDebugCallStack => Type -> Maybe (TyCon, [Type])
Type -> Maybe (TyCon, [Type])
splitTyConApp_maybe Type
ty of
Just (TyCon
tc, [Type]
ty_args)
| TyCon -> Bool
is_algebraic_like TyCon
tc Bool -> Bool -> Bool
&& Bool -> Bool
not (TyCon -> Bool
isFamilyTyCon TyCon
tc)
-> ASSERT2( ty_args `lengthIs` tyConArity tc, ppr ty ) True
Maybe (TyCon, [Type])
_other -> Bool
False
where
is_algebraic_like :: TyCon -> Bool
is_algebraic_like :: TyCon -> Bool
is_algebraic_like TyCon
tc = TyCon -> Bool
isAlgTyCon TyCon
tc Bool -> Bool -> Bool
|| TyCon
tc TyCon -> TyCon -> Bool
forall a. Eq a => a -> a -> Bool
== TyCon
tYPETyCon
nameTyCt :: PredType -> DsM EvVar
nameTyCt :: Type -> DsM Id
nameTyCt Type
pred_ty = do
Unique
unique <- IOEnv (Env DsGblEnv DsLclEnv) Unique
forall (m :: * -> *). MonadUnique m => m Unique
getUniqueM
let occname :: OccName
occname = FastString -> OccName
mkVarOccFS (String -> FastString
fsLit (String
"pm_"String -> String -> String
forall a. [a] -> [a] -> [a]
++Unique -> String
forall a. Show a => a -> String
show Unique
unique))
idname :: Name
idname = Unique -> OccName -> SrcSpan -> Name
mkInternalName Unique
unique OccName
occname SrcSpan
noSrcSpan
Id -> DsM Id
forall (m :: * -> *) a. Monad m => a -> m a
return (Name -> Type -> Type -> Id
mkLocalIdOrCoVar Name
idname Type
Many Type
pred_ty)
tyOracle :: TyState -> Bag PredType -> DsM (Maybe TyState)
tyOracle :: TyState -> Bag Type -> DsM (Maybe TyState)
tyOracle (TySt Bag Id
inert) Bag Type
cts
= do { Bag Id
evs <- (Type -> DsM Id)
-> Bag Type -> IOEnv (Env DsGblEnv DsLclEnv) (Bag Id)
forall (t :: * -> *) (f :: * -> *) a b.
(Traversable t, Applicative f) =>
(a -> f b) -> t a -> f (t b)
traverse Type -> DsM Id
nameTyCt Bag Type
cts
; let new_inert :: Bag Id
new_inert = Bag Id
inert Bag Id -> Bag Id -> Bag Id
forall a. Bag a -> Bag a -> Bag a
`unionBags` Bag Id
evs
; String -> SDoc -> DsM ()
tracePm String
"tyOracle" (Bag Type -> SDoc
forall a. Outputable a => a -> SDoc
ppr Bag Type
cts)
; ((WarningMessages
_warns, WarningMessages
errs), Maybe Bool
res) <- TcM Bool -> DsM (Messages, Maybe Bool)
forall a. TcM a -> DsM (Messages, Maybe a)
initTcDsForSolver (TcM Bool -> DsM (Messages, Maybe Bool))
-> TcM Bool -> DsM (Messages, Maybe Bool)
forall a b. (a -> b) -> a -> b
$ Bag Id -> TcM Bool
tcCheckSatisfiability Bag Id
new_inert
; case Maybe Bool
res of
Just Bool
True -> Maybe TyState -> DsM (Maybe TyState)
forall (m :: * -> *) a. Monad m => a -> m a
return (TyState -> Maybe TyState
forall a. a -> Maybe a
Just (Bag Id -> TyState
TySt Bag Id
new_inert))
Just Bool
False -> Maybe TyState -> DsM (Maybe TyState)
forall (m :: * -> *) a. Monad m => a -> m a
return Maybe TyState
forall a. Maybe a
Nothing
Maybe Bool
Nothing -> String -> SDoc -> DsM (Maybe TyState)
forall a. HasCallStack => String -> SDoc -> a
pprPanic String
"tyOracle" ([SDoc] -> SDoc
vcat ([SDoc] -> SDoc) -> [SDoc] -> SDoc
forall a b. (a -> b) -> a -> b
$ WarningMessages -> [SDoc]
pprErrMsgBagWithLoc WarningMessages
errs) }
tyIsSatisfiable :: Bool -> Bag PredType -> SatisfiabilityCheck
tyIsSatisfiable :: Bool -> Bag Type -> SatisfiabilityCheck
tyIsSatisfiable Bool
recheck_complete_sets Bag Type
new_ty_cs = (Delta -> DsM (Maybe Delta)) -> SatisfiabilityCheck
SC ((Delta -> DsM (Maybe Delta)) -> SatisfiabilityCheck)
-> (Delta -> DsM (Maybe Delta)) -> SatisfiabilityCheck
forall a b. (a -> b) -> a -> b
$ \Delta
delta ->
if Bag Type -> Bool
forall a. Bag a -> Bool
isEmptyBag Bag Type
new_ty_cs
then Maybe Delta -> DsM (Maybe Delta)
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Delta -> Maybe Delta
forall a. a -> Maybe a
Just Delta
delta)
else TyState -> Bag Type -> DsM (Maybe TyState)
tyOracle (Delta -> TyState
delta_ty_st Delta
delta) Bag Type
new_ty_cs DsM (Maybe TyState)
-> (Maybe TyState -> DsM (Maybe Delta)) -> DsM (Maybe Delta)
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \case
Maybe TyState
Nothing -> Maybe Delta -> DsM (Maybe Delta)
forall (f :: * -> *) a. Applicative f => a -> f a
pure Maybe Delta
forall a. Maybe a
Nothing
Just TyState
ty_st' -> do
let delta' :: Delta
delta' = Delta
delta{ delta_ty_st :: TyState
delta_ty_st = TyState
ty_st' }
if Bool
recheck_complete_sets
then Delta -> DsM (Maybe Delta)
ensureAllPossibleMatchesInhabited Delta
delta'
else Maybe Delta -> DsM (Maybe Delta)
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Delta -> Maybe Delta
forall a. a -> Maybe a
Just Delta
delta')
tmIsSatisfiable :: Bag TmCt -> SatisfiabilityCheck
tmIsSatisfiable :: Bag TmCt -> SatisfiabilityCheck
tmIsSatisfiable Bag TmCt
new_tm_cs = (Delta -> DsM (Maybe Delta)) -> SatisfiabilityCheck
SC ((Delta -> DsM (Maybe Delta)) -> SatisfiabilityCheck)
-> (Delta -> DsM (Maybe Delta)) -> SatisfiabilityCheck
forall a b. (a -> b) -> a -> b
$ \Delta
delta -> MaybeT DsM Delta -> DsM (Maybe Delta)
forall (m :: * -> *) a. MaybeT m a -> m (Maybe a)
runMaybeT (MaybeT DsM Delta -> DsM (Maybe Delta))
-> MaybeT DsM Delta -> DsM (Maybe Delta)
forall a b. (a -> b) -> a -> b
$ (Delta -> TmCt -> MaybeT DsM Delta)
-> Delta -> Bag TmCt -> MaybeT DsM Delta
forall (t :: * -> *) (m :: * -> *) b a.
(Foldable t, Monad m) =>
(b -> a -> m b) -> b -> t a -> m b
foldlM Delta -> TmCt -> MaybeT DsM Delta
addTmCt Delta
delta Bag TmCt
new_tm_cs
emptyVarInfo :: Id -> VarInfo
emptyVarInfo :: Id -> VarInfo
emptyVarInfo Id
x = Type
-> [(PmAltCon, [Id], [Id])]
-> PmAltConSet
-> PossibleMatches
-> VarInfo
VI (Id -> Type
idType Id
x) [] PmAltConSet
emptyPmAltConSet PossibleMatches
NoPM
lookupVarInfo :: TmState -> Id -> VarInfo
lookupVarInfo :: TmState -> Id -> VarInfo
lookupVarInfo (TmSt SharedDIdEnv VarInfo
env CoreMap Id
_) Id
x = VarInfo -> Maybe VarInfo -> VarInfo
forall a. a -> Maybe a -> a
fromMaybe (Id -> VarInfo
emptyVarInfo Id
x) (SharedDIdEnv VarInfo -> Id -> Maybe VarInfo
forall a. SharedDIdEnv a -> Id -> Maybe a
lookupSDIE SharedDIdEnv VarInfo
env Id
x)
initPossibleMatches :: TyState -> VarInfo -> DsM VarInfo
initPossibleMatches :: TyState -> VarInfo -> DsM VarInfo
initPossibleMatches TyState
ty_st vi :: VarInfo
vi@VI{ vi_ty :: VarInfo -> Type
vi_ty = Type
ty, vi_cache :: VarInfo -> PossibleMatches
vi_cache = PossibleMatches
NoPM } = do
TopNormaliseTypeResult
res <- TyState -> Type -> DsM TopNormaliseTypeResult
pmTopNormaliseType TyState
ty_st Type
ty
let ty' :: Type
ty' = TopNormaliseTypeResult -> Type
normalisedSourceType TopNormaliseTypeResult
res
case HasDebugCallStack => Type -> Maybe (TyCon, [Type])
Type -> Maybe (TyCon, [Type])
splitTyConApp_maybe Type
ty' of
Maybe (TyCon, [Type])
Nothing -> VarInfo -> DsM VarInfo
forall (f :: * -> *) a. Applicative f => a -> f a
pure VarInfo
vi{ vi_ty :: Type
vi_ty = Type
ty' }
Just (TyCon
tc, [Type
_])
| TyCon
tc TyCon -> TyCon -> Bool
forall a. Eq a => a -> a -> Bool
== TyCon
tYPETyCon
-> VarInfo -> DsM VarInfo
forall (f :: * -> *) a. Applicative f => a -> f a
pure VarInfo
vi{ vi_ty :: Type
vi_ty = Type
ty', vi_cache :: PossibleMatches
vi_cache = NonEmpty ConLikeSet -> PossibleMatches
PM (ConLikeSet -> NonEmpty ConLikeSet
forall (f :: * -> *) a. Applicative f => a -> f a
pure ConLikeSet
forall a. UniqDSet a
emptyUniqDSet) }
Just (TyCon
tc, [Type]
tc_args) -> do
(TyCon
tc_rep, TyCon
tc_fam) <- case TyCon -> Maybe (TyCon, [Type])
tyConFamInst_maybe TyCon
tc of
Just (TyCon
tc_fam, [Type]
_) -> (TyCon, TyCon) -> IOEnv (Env DsGblEnv DsLclEnv) (TyCon, TyCon)
forall (f :: * -> *) a. Applicative f => a -> f a
pure (TyCon
tc, TyCon
tc_fam)
Maybe (TyCon, [Type])
Nothing -> do
FamInstEnvs
env <- DsM FamInstEnvs
dsGetFamInstEnvs
let (TyCon
tc_rep, [Type]
_tc_rep_args, Coercion
_co) = FamInstEnvs -> TyCon -> [Type] -> (TyCon, [Type], Coercion)
tcLookupDataFamInst FamInstEnvs
env TyCon
tc [Type]
tc_args
(TyCon, TyCon) -> IOEnv (Env DsGblEnv DsLclEnv) (TyCon, TyCon)
forall (f :: * -> *) a. Applicative f => a -> f a
pure (TyCon
tc_rep, TyCon
tc)
let mb_rdcs :: Maybe [ConLike]
mb_rdcs = (DataCon -> ConLike) -> [DataCon] -> [ConLike]
forall a b. (a -> b) -> [a] -> [b]
map DataCon -> ConLike
RealDataCon ([DataCon] -> [ConLike]) -> Maybe [DataCon] -> Maybe [ConLike]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> TyCon -> Maybe [DataCon]
tyConDataCons_maybe TyCon
tc_rep
let rdcs :: [[ConLike]]
rdcs = Maybe [ConLike] -> [[ConLike]]
forall a. Maybe a -> [a]
maybeToList Maybe [ConLike]
mb_rdcs
[CompleteMatch]
pragmas <- TyCon -> DsM [CompleteMatch]
dsGetCompleteMatches TyCon
tc_fam
let fams :: CompleteMatch -> IOEnv (Env DsGblEnv DsLclEnv) [ConLike]
fams = (Name -> IOEnv (Env DsGblEnv DsLclEnv) ConLike)
-> [Name] -> IOEnv (Env DsGblEnv DsLclEnv) [ConLike]
forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
mapM Name -> IOEnv (Env DsGblEnv DsLclEnv) ConLike
dsLookupConLike ([Name] -> IOEnv (Env DsGblEnv DsLclEnv) [ConLike])
-> (CompleteMatch -> [Name])
-> CompleteMatch
-> IOEnv (Env DsGblEnv DsLclEnv) [ConLike]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. CompleteMatch -> [Name]
completeMatchConLikes
[[ConLike]]
pscs <- (CompleteMatch -> IOEnv (Env DsGblEnv DsLclEnv) [ConLike])
-> [CompleteMatch] -> IOEnv (Env DsGblEnv DsLclEnv) [[ConLike]]
forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
mapM CompleteMatch -> IOEnv (Env DsGblEnv DsLclEnv) [ConLike]
fams [CompleteMatch]
pragmas
case [[ConLike]] -> Maybe (NonEmpty [ConLike])
forall a. [a] -> Maybe (NonEmpty a)
NonEmpty.nonEmpty ([[ConLike]]
rdcs [[ConLike]] -> [[ConLike]] -> [[ConLike]]
forall a. [a] -> [a] -> [a]
++ [[ConLike]]
pscs) of
Maybe (NonEmpty [ConLike])
Nothing -> VarInfo -> DsM VarInfo
forall (f :: * -> *) a. Applicative f => a -> f a
pure VarInfo
vi{ vi_ty :: Type
vi_ty = Type
ty' }
Just NonEmpty [ConLike]
cs -> VarInfo -> DsM VarInfo
forall (f :: * -> *) a. Applicative f => a -> f a
pure VarInfo
vi{ vi_ty :: Type
vi_ty = Type
ty', vi_cache :: PossibleMatches
vi_cache = NonEmpty ConLikeSet -> PossibleMatches
PM ([ConLike] -> ConLikeSet
forall a. Uniquable a => [a] -> UniqDSet a
mkUniqDSet ([ConLike] -> ConLikeSet)
-> NonEmpty [ConLike] -> NonEmpty ConLikeSet
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> NonEmpty [ConLike]
cs) }
initPossibleMatches TyState
_ VarInfo
vi = VarInfo -> DsM VarInfo
forall (f :: * -> *) a. Applicative f => a -> f a
pure VarInfo
vi
initLookupVarInfo :: Delta -> Id -> DsM VarInfo
initLookupVarInfo :: Delta -> Id -> DsM VarInfo
initLookupVarInfo MkDelta{ delta_tm_st :: Delta -> TmState
delta_tm_st = TmState
ts, delta_ty_st :: Delta -> TyState
delta_ty_st = TyState
ty_st } Id
x
= TyState -> VarInfo -> DsM VarInfo
initPossibleMatches TyState
ty_st (TmState -> Id -> VarInfo
lookupVarInfo TmState
ts Id
x)
canDiverge :: Delta -> Id -> Bool
canDiverge :: Delta -> Id -> Bool
canDiverge delta :: Delta
delta@MkDelta{ delta_tm_st :: Delta -> TmState
delta_tm_st = TmState
ts } Id
x
| VI Type
_ [(PmAltCon, [Id], [Id])]
pos PmAltConSet
neg PossibleMatches
_ <- TmState -> Id -> VarInfo
lookupVarInfo TmState
ts Id
x
= PmAltConSet -> Bool
isEmptyPmAltConSet PmAltConSet
neg Bool -> Bool -> Bool
&& ((PmAltCon, [Id], [Id]) -> Bool)
-> [(PmAltCon, [Id], [Id])] -> Bool
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
all (PmAltCon, [Id], [Id]) -> Bool
forall {b}. (PmAltCon, b, [Id]) -> Bool
pos_can_diverge [(PmAltCon, [Id], [Id])]
pos
where
pos_can_diverge :: (PmAltCon, b, [Id]) -> Bool
pos_can_diverge (PmAltConLike (RealDataCon DataCon
dc), b
_, [Id
y])
| TyCon -> Bool
isNewTyCon (DataCon -> TyCon
dataConTyCon DataCon
dc) = Delta -> Id -> Bool
canDiverge Delta
delta Id
y
pos_can_diverge (PmAltCon, b, [Id])
_ = Bool
False
lookupRefuts :: Uniquable k => Delta -> k -> [PmAltCon]
lookupRefuts :: forall k. Uniquable k => Delta -> k -> [PmAltCon]
lookupRefuts MkDelta{ delta_tm_st :: Delta -> TmState
delta_tm_st = ts :: TmState
ts@(TmSt (SDIE DIdEnv (Shared VarInfo)
env) CoreMap Id
_) } k
k =
case DIdEnv (Shared VarInfo) -> Unique -> Maybe (Shared VarInfo)
forall key elt. UniqDFM key elt -> Unique -> Maybe elt
lookupUDFM_Directly DIdEnv (Shared VarInfo)
env (k -> Unique
forall a. Uniquable a => a -> Unique
getUnique k
k) of
Maybe (Shared VarInfo)
Nothing -> []
Just (Indirect Id
y) -> PmAltConSet -> [PmAltCon]
pmAltConSetElems (VarInfo -> PmAltConSet
vi_neg (TmState -> Id -> VarInfo
lookupVarInfo TmState
ts Id
y))
Just (Entry VarInfo
vi) -> PmAltConSet -> [PmAltCon]
pmAltConSetElems (VarInfo -> PmAltConSet
vi_neg VarInfo
vi)
isDataConSolution :: (PmAltCon, [TyVar], [Id]) -> Bool
isDataConSolution :: (PmAltCon, [Id], [Id]) -> Bool
isDataConSolution (PmAltConLike (RealDataCon DataCon
_), [Id]
_, [Id]
_) = Bool
True
isDataConSolution (PmAltCon, [Id], [Id])
_ = Bool
False
lookupSolution :: Delta -> Id -> Maybe (PmAltCon, [TyVar], [Id])
lookupSolution :: Delta -> Id -> Maybe (PmAltCon, [Id], [Id])
lookupSolution Delta
delta Id
x = case VarInfo -> [(PmAltCon, [Id], [Id])]
vi_pos (TmState -> Id -> VarInfo
lookupVarInfo (Delta -> TmState
delta_tm_st Delta
delta) Id
x) of
[] -> Maybe (PmAltCon, [Id], [Id])
forall a. Maybe a
Nothing
[(PmAltCon, [Id], [Id])]
pos
| Just (PmAltCon, [Id], [Id])
sol <- ((PmAltCon, [Id], [Id]) -> Bool)
-> [(PmAltCon, [Id], [Id])] -> Maybe (PmAltCon, [Id], [Id])
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Maybe a
find (PmAltCon, [Id], [Id]) -> Bool
isDataConSolution [(PmAltCon, [Id], [Id])]
pos -> (PmAltCon, [Id], [Id]) -> Maybe (PmAltCon, [Id], [Id])
forall a. a -> Maybe a
Just (PmAltCon, [Id], [Id])
sol
| Bool
otherwise -> (PmAltCon, [Id], [Id]) -> Maybe (PmAltCon, [Id], [Id])
forall a. a -> Maybe a
Just ([(PmAltCon, [Id], [Id])] -> (PmAltCon, [Id], [Id])
forall a. [a] -> a
head [(PmAltCon, [Id], [Id])]
pos)
data TmCt
= TmVarCt !Id !Id
| TmCoreCt !Id !CoreExpr
| TmConCt !Id !PmAltCon ![TyVar] ![Id]
| TmNotConCt !Id !PmAltCon
| TmBotCt !Id
| TmNotBotCt !Id
instance Outputable TmCt where
ppr :: TmCt -> SDoc
ppr (TmVarCt Id
x Id
y) = Id -> SDoc
forall a. Outputable a => a -> SDoc
ppr Id
x SDoc -> SDoc -> SDoc
<+> Char -> SDoc
char Char
'~' SDoc -> SDoc -> SDoc
<+> Id -> SDoc
forall a. Outputable a => a -> SDoc
ppr Id
y
ppr (TmCoreCt Id
x CoreExpr
e) = Id -> SDoc
forall a. Outputable a => a -> SDoc
ppr Id
x SDoc -> SDoc -> SDoc
<+> Char -> SDoc
char Char
'~' SDoc -> SDoc -> SDoc
<+> CoreExpr -> SDoc
forall a. Outputable a => a -> SDoc
ppr CoreExpr
e
ppr (TmConCt Id
x PmAltCon
con [Id]
tvs [Id]
args) = Id -> SDoc
forall a. Outputable a => a -> SDoc
ppr Id
x SDoc -> SDoc -> SDoc
<+> Char -> SDoc
char Char
'~' SDoc -> SDoc -> SDoc
<+> [SDoc] -> SDoc
hsep (PmAltCon -> SDoc
forall a. Outputable a => a -> SDoc
ppr PmAltCon
con SDoc -> [SDoc] -> [SDoc]
forall a. a -> [a] -> [a]
: [SDoc]
pp_tvs [SDoc] -> [SDoc] -> [SDoc]
forall a. [a] -> [a] -> [a]
++ [SDoc]
pp_args)
where
pp_tvs :: [SDoc]
pp_tvs = (Id -> SDoc) -> [Id] -> [SDoc]
forall a b. (a -> b) -> [a] -> [b]
map ((SDoc -> SDoc -> SDoc
<> Char -> SDoc
char Char
'@') (SDoc -> SDoc) -> (Id -> SDoc) -> Id -> SDoc
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Id -> SDoc
forall a. Outputable a => a -> SDoc
ppr) [Id]
tvs
pp_args :: [SDoc]
pp_args = (Id -> SDoc) -> [Id] -> [SDoc]
forall a b. (a -> b) -> [a] -> [b]
map Id -> SDoc
forall a. Outputable a => a -> SDoc
ppr [Id]
args
ppr (TmNotConCt Id
x PmAltCon
con) = Id -> SDoc
forall a. Outputable a => a -> SDoc
ppr Id
x SDoc -> SDoc -> SDoc
<+> String -> SDoc
text String
"/~" SDoc -> SDoc -> SDoc
<+> PmAltCon -> SDoc
forall a. Outputable a => a -> SDoc
ppr PmAltCon
con
ppr (TmBotCt Id
x) = Id -> SDoc
forall a. Outputable a => a -> SDoc
ppr Id
x SDoc -> SDoc -> SDoc
<+> String -> SDoc
text String
"~ ⊥"
ppr (TmNotBotCt Id
x) = Id -> SDoc
forall a. Outputable a => a -> SDoc
ppr Id
x SDoc -> SDoc -> SDoc
<+> String -> SDoc
text String
"/~ ⊥"
type TyCt = PredType
data PmCt
= PmTyCt !TyCt
| PmTmCt !TmCt
type PmCts = Bag PmCt
pattern PmVarCt :: Id -> Id -> PmCt
pattern $mPmVarCt :: forall {r}. PmCt -> (Id -> Id -> r) -> (Void# -> r) -> r
$bPmVarCt :: Id -> Id -> PmCt
PmVarCt x y = PmTmCt (TmVarCt x y)
pattern PmCoreCt :: Id -> CoreExpr -> PmCt
pattern $mPmCoreCt :: forall {r}. PmCt -> (Id -> CoreExpr -> r) -> (Void# -> r) -> r
$bPmCoreCt :: Id -> CoreExpr -> PmCt
PmCoreCt x e = PmTmCt (TmCoreCt x e)
pattern PmConCt :: Id -> PmAltCon -> [TyVar] -> [Id] -> PmCt
pattern $mPmConCt :: forall {r}.
PmCt -> (Id -> PmAltCon -> [Id] -> [Id] -> r) -> (Void# -> r) -> r
$bPmConCt :: Id -> PmAltCon -> [Id] -> [Id] -> PmCt
PmConCt x con tvs args = PmTmCt (TmConCt x con tvs args)
pattern PmNotConCt :: Id -> PmAltCon -> PmCt
pattern $mPmNotConCt :: forall {r}. PmCt -> (Id -> PmAltCon -> r) -> (Void# -> r) -> r
$bPmNotConCt :: Id -> PmAltCon -> PmCt
PmNotConCt x con = PmTmCt (TmNotConCt x con)
pattern PmBotCt :: Id -> PmCt
pattern $mPmBotCt :: forall {r}. PmCt -> (Id -> r) -> (Void# -> r) -> r
$bPmBotCt :: Id -> PmCt
PmBotCt x = PmTmCt (TmBotCt x)
pattern PmNotBotCt :: Id -> PmCt
pattern $mPmNotBotCt :: forall {r}. PmCt -> (Id -> r) -> (Void# -> r) -> r
$bPmNotBotCt :: Id -> PmCt
PmNotBotCt x = PmTmCt (TmNotBotCt x)
{-# COMPLETE PmTyCt, PmVarCt, PmCoreCt, PmConCt, PmNotConCt, PmBotCt, PmNotBotCt #-}
instance Outputable PmCt where
ppr :: PmCt -> SDoc
ppr (PmTyCt Type
pred_ty) = Type -> SDoc
forall a. Outputable a => a -> SDoc
ppr Type
pred_ty
ppr (PmTmCt TmCt
tm_ct) = TmCt -> SDoc
forall a. Outputable a => a -> SDoc
ppr TmCt
tm_ct
addPmCts :: Delta -> PmCts -> DsM (Maybe Delta)
addPmCts :: Delta -> PmCts -> DsM (Maybe Delta)
addPmCts Delta
delta PmCts
cts = do
let ([Type]
ty_cts, [TmCt]
tm_cts) = PmCts -> ([Type], [TmCt])
partitionTyTmCts PmCts
cts
Delta -> SatisfiabilityCheck -> DsM (Maybe Delta)
runSatisfiabilityCheck Delta
delta (SatisfiabilityCheck -> DsM (Maybe Delta))
-> SatisfiabilityCheck -> DsM (Maybe Delta)
forall a b. (a -> b) -> a -> b
$ [SatisfiabilityCheck] -> SatisfiabilityCheck
forall a. Monoid a => [a] -> a
mconcat
[ Bool -> Bag Type -> SatisfiabilityCheck
tyIsSatisfiable Bool
True ([Type] -> Bag Type
forall a. [a] -> Bag a
listToBag [Type]
ty_cts)
, Bag TmCt -> SatisfiabilityCheck
tmIsSatisfiable ([TmCt] -> Bag TmCt
forall a. [a] -> Bag a
listToBag [TmCt]
tm_cts)
]
partitionTyTmCts :: PmCts -> ([TyCt], [TmCt])
partitionTyTmCts :: PmCts -> ([Type], [TmCt])
partitionTyTmCts = [Either Type TmCt] -> ([Type], [TmCt])
forall a b. [Either a b] -> ([a], [b])
partitionEithers ([Either Type TmCt] -> ([Type], [TmCt]))
-> (PmCts -> [Either Type TmCt]) -> PmCts -> ([Type], [TmCt])
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (PmCt -> Either Type TmCt) -> [PmCt] -> [Either Type TmCt]
forall a b. (a -> b) -> [a] -> [b]
map PmCt -> Either Type TmCt
to_either ([PmCt] -> [Either Type TmCt])
-> (PmCts -> [PmCt]) -> PmCts -> [Either Type TmCt]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. PmCts -> [PmCt]
forall (t :: * -> *) a. Foldable t => t a -> [a]
toList
where
to_either :: PmCt -> Either Type TmCt
to_either (PmTyCt Type
pred_ty) = Type -> Either Type TmCt
forall a b. a -> Either a b
Left Type
pred_ty
to_either (PmTmCt TmCt
tm_ct) = TmCt -> Either Type TmCt
forall a b. b -> Either a b
Right TmCt
tm_ct
addTmCt :: Delta -> TmCt -> MaybeT DsM Delta
addTmCt :: Delta -> TmCt -> MaybeT DsM Delta
addTmCt Delta
delta (TmVarCt Id
x Id
y) = Delta -> Id -> Id -> MaybeT DsM Delta
addVarCt Delta
delta Id
x Id
y
addTmCt Delta
delta (TmCoreCt Id
x CoreExpr
e) = Delta -> Id -> CoreExpr -> MaybeT DsM Delta
addCoreCt Delta
delta Id
x CoreExpr
e
addTmCt Delta
delta (TmConCt Id
x PmAltCon
con [Id]
tvs [Id]
args) = Delta -> Id -> PmAltCon -> [Id] -> [Id] -> MaybeT DsM Delta
addConCt Delta
delta Id
x PmAltCon
con [Id]
tvs [Id]
args
addTmCt Delta
delta (TmNotConCt Id
x PmAltCon
con) = Delta -> Id -> PmAltCon -> MaybeT DsM Delta
addNotConCt Delta
delta Id
x PmAltCon
con
addTmCt Delta
delta (TmBotCt Id
x) = Delta -> Id -> MaybeT DsM Delta
addBotCt Delta
delta Id
x
addTmCt Delta
delta (TmNotBotCt Id
x) = Delta -> Id -> MaybeT DsM Delta
addNotBotCt Delta
delta Id
x
addBotCt :: Delta -> Id -> MaybeT DsM Delta
addBotCt :: Delta -> Id -> MaybeT DsM Delta
addBotCt Delta
delta Id
x
| Delta -> Id -> Bool
canDiverge Delta
delta Id
x = Delta -> MaybeT DsM Delta
forall (f :: * -> *) a. Applicative f => a -> f a
pure Delta
delta
| Bool
otherwise = MaybeT DsM Delta
forall (m :: * -> *) a. MonadPlus m => m a
mzero
addNotConCt :: Delta -> Id -> PmAltCon -> MaybeT DsM Delta
addNotConCt :: Delta -> Id -> PmAltCon -> MaybeT DsM Delta
addNotConCt delta :: Delta
delta@MkDelta{ delta_tm_st :: Delta -> TmState
delta_tm_st = TmSt SharedDIdEnv VarInfo
env CoreMap Id
reps } Id
x PmAltCon
nalt = do
vi :: VarInfo
vi@(VI Type
_ [(PmAltCon, [Id], [Id])]
pos PmAltConSet
neg PossibleMatches
pm) <- DsM VarInfo -> MaybeT DsM VarInfo
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (Delta -> Id -> DsM VarInfo
initLookupVarInfo Delta
delta Id
x)
let contradicts :: PmAltCon -> (PmAltCon, b, c) -> Bool
contradicts PmAltCon
nalt (PmAltCon
cl, b
_tvs, c
_args) = PmAltCon -> PmAltCon -> PmEquality
eqPmAltCon PmAltCon
cl PmAltCon
nalt PmEquality -> PmEquality -> Bool
forall a. Eq a => a -> a -> Bool
== PmEquality
Equal
Bool -> MaybeT DsM ()
forall (f :: * -> *). Alternative f => Bool -> f ()
guard (Bool -> Bool
not (((PmAltCon, [Id], [Id]) -> Bool)
-> [(PmAltCon, [Id], [Id])] -> Bool
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
any (PmAltCon -> (PmAltCon, [Id], [Id]) -> Bool
forall {b} {c}. PmAltCon -> (PmAltCon, b, c) -> Bool
contradicts PmAltCon
nalt) [(PmAltCon, [Id], [Id])]
pos))
let implies :: PmAltCon -> (PmAltCon, b, c) -> Bool
implies PmAltCon
nalt (PmAltCon
cl, b
_tvs, c
_args) = PmAltCon -> PmAltCon -> PmEquality
eqPmAltCon PmAltCon
cl PmAltCon
nalt PmEquality -> PmEquality -> Bool
forall a. Eq a => a -> a -> Bool
== PmEquality
Disjoint
let neg' :: PmAltConSet
neg'
| ((PmAltCon, [Id], [Id]) -> Bool)
-> [(PmAltCon, [Id], [Id])] -> Bool
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
any (PmAltCon -> (PmAltCon, [Id], [Id]) -> Bool
forall {b} {c}. PmAltCon -> (PmAltCon, b, c) -> Bool
implies PmAltCon
nalt) [(PmAltCon, [Id], [Id])]
pos = PmAltConSet
neg
| PmAltCon -> Bool
hasRequiredTheta PmAltCon
nalt = PmAltConSet
neg
| Bool
otherwise = PmAltConSet -> PmAltCon -> PmAltConSet
extendPmAltConSet PmAltConSet
neg PmAltCon
nalt
let vi_ext :: VarInfo
vi_ext = VarInfo
vi{ vi_neg :: PmAltConSet
vi_neg = PmAltConSet
neg' }
VarInfo
vi' <- case PmAltCon
nalt of
PmAltConLike ConLike
cl
-> IOEnv (Env DsGblEnv DsLclEnv) (Maybe VarInfo) -> MaybeT DsM VarInfo
forall (m :: * -> *) a. m (Maybe a) -> MaybeT m a
MaybeT (Delta -> VarInfo -> IOEnv (Env DsGblEnv DsLclEnv) (Maybe VarInfo)
ensureInhabited Delta
delta VarInfo
vi_ext{ vi_cache :: PossibleMatches
vi_cache = ConLike -> PossibleMatches -> PossibleMatches
markMatched ConLike
cl PossibleMatches
pm })
PmAltCon
_ -> VarInfo -> MaybeT DsM VarInfo
forall (f :: * -> *) a. Applicative f => a -> f a
pure VarInfo
vi_ext
Delta -> MaybeT DsM Delta
forall (f :: * -> *) a. Applicative f => a -> f a
pure Delta
delta{ delta_tm_st :: TmState
delta_tm_st = SharedDIdEnv VarInfo -> CoreMap Id -> TmState
TmSt (SharedDIdEnv VarInfo -> Id -> VarInfo -> SharedDIdEnv VarInfo
forall a. SharedDIdEnv a -> Id -> a -> SharedDIdEnv a
setEntrySDIE SharedDIdEnv VarInfo
env Id
x VarInfo
vi') CoreMap Id
reps }
hasRequiredTheta :: PmAltCon -> Bool
hasRequiredTheta :: PmAltCon -> Bool
hasRequiredTheta (PmAltConLike ConLike
cl) = [Type] -> Bool
forall a. [a] -> Bool
notNull [Type]
req_theta
where
([Id]
_,[Id]
_,[EqSpec]
_,[Type]
_,[Type]
req_theta,[Scaled Type]
_,Type
_) = ConLike
-> ([Id], [Id], [EqSpec], [Type], [Type], [Scaled Type], Type)
conLikeFullSig ConLike
cl
hasRequiredTheta PmAltCon
_ = Bool
False
guessConLikeUnivTyArgsFromResTy :: FamInstEnvs -> Type -> ConLike -> Maybe [Type]
guessConLikeUnivTyArgsFromResTy :: FamInstEnvs -> Type -> ConLike -> Maybe [Type]
guessConLikeUnivTyArgsFromResTy FamInstEnvs
env Type
res_ty (RealDataCon DataCon
_) = do
(TyCon
tc, [Type]
tc_args) <- HasDebugCallStack => Type -> Maybe (TyCon, [Type])
Type -> Maybe (TyCon, [Type])
splitTyConApp_maybe Type
res_ty
let (TyCon
_, [Type]
tc_args', Coercion
_) = FamInstEnvs -> TyCon -> [Type] -> (TyCon, [Type], Coercion)
tcLookupDataFamInst FamInstEnvs
env TyCon
tc [Type]
tc_args
[Type] -> Maybe [Type]
forall a. a -> Maybe a
Just [Type]
tc_args'
guessConLikeUnivTyArgsFromResTy FamInstEnvs
_ Type
res_ty (PatSynCon PatSyn
ps) = do
let ([Id]
univ_tvs,[Type]
_,[Id]
_,[Type]
_,[Scaled Type]
_,Type
con_res_ty) = PatSyn -> ([Id], [Type], [Id], [Type], [Scaled Type], Type)
patSynSig PatSyn
ps
TCvSubst
subst <- Type -> Type -> Maybe TCvSubst
tcMatchTy Type
con_res_ty Type
res_ty
(Id -> Maybe Type) -> [Id] -> Maybe [Type]
forall (t :: * -> *) (f :: * -> *) a b.
(Traversable t, Applicative f) =>
(a -> f b) -> t a -> f (t b)
traverse (TCvSubst -> Id -> Maybe Type
lookupTyVar TCvSubst
subst) [Id]
univ_tvs
addNotBotCt :: Delta -> Id -> MaybeT DsM Delta
addNotBotCt :: Delta -> Id -> MaybeT DsM Delta
addNotBotCt delta :: Delta
delta@MkDelta{ delta_tm_st :: Delta -> TmState
delta_tm_st = TmSt SharedDIdEnv VarInfo
env CoreMap Id
reps } Id
x = do
VarInfo
vi <- DsM VarInfo -> MaybeT DsM VarInfo
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (DsM VarInfo -> MaybeT DsM VarInfo)
-> DsM VarInfo -> MaybeT DsM VarInfo
forall a b. (a -> b) -> a -> b
$ Delta -> Id -> DsM VarInfo
initLookupVarInfo Delta
delta Id
x
VarInfo
vi' <- IOEnv (Env DsGblEnv DsLclEnv) (Maybe VarInfo) -> MaybeT DsM VarInfo
forall (m :: * -> *) a. m (Maybe a) -> MaybeT m a
MaybeT (IOEnv (Env DsGblEnv DsLclEnv) (Maybe VarInfo)
-> MaybeT DsM VarInfo)
-> IOEnv (Env DsGblEnv DsLclEnv) (Maybe VarInfo)
-> MaybeT DsM VarInfo
forall a b. (a -> b) -> a -> b
$ Delta -> VarInfo -> IOEnv (Env DsGblEnv DsLclEnv) (Maybe VarInfo)
ensureInhabited Delta
delta VarInfo
vi
Delta -> MaybeT DsM Delta
forall (f :: * -> *) a. Applicative f => a -> f a
pure Delta
delta{ delta_tm_st :: TmState
delta_tm_st = SharedDIdEnv VarInfo -> CoreMap Id -> TmState
TmSt (SharedDIdEnv VarInfo -> Id -> VarInfo -> SharedDIdEnv VarInfo
forall a. SharedDIdEnv a -> Id -> a -> SharedDIdEnv a
setEntrySDIE SharedDIdEnv VarInfo
env Id
x VarInfo
vi') CoreMap Id
reps}
ensureInhabited :: Delta -> VarInfo -> DsM (Maybe VarInfo)
ensureInhabited :: Delta -> VarInfo -> IOEnv (Env DsGblEnv DsLclEnv) (Maybe VarInfo)
ensureInhabited Delta
delta VarInfo
vi = (PossibleMatches -> VarInfo)
-> Maybe PossibleMatches -> Maybe VarInfo
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (VarInfo -> PossibleMatches -> VarInfo
set_cache VarInfo
vi) (Maybe PossibleMatches -> Maybe VarInfo)
-> IOEnv (Env DsGblEnv DsLclEnv) (Maybe PossibleMatches)
-> IOEnv (Env DsGblEnv DsLclEnv) (Maybe VarInfo)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> PossibleMatches
-> IOEnv (Env DsGblEnv DsLclEnv) (Maybe PossibleMatches)
test (VarInfo -> PossibleMatches
vi_cache VarInfo
vi)
where
set_cache :: VarInfo -> PossibleMatches -> VarInfo
set_cache VarInfo
vi PossibleMatches
cache = VarInfo
vi { vi_cache :: PossibleMatches
vi_cache = PossibleMatches
cache }
test :: PossibleMatches
-> IOEnv (Env DsGblEnv DsLclEnv) (Maybe PossibleMatches)
test PossibleMatches
NoPM = Maybe PossibleMatches
-> IOEnv (Env DsGblEnv DsLclEnv) (Maybe PossibleMatches)
forall (f :: * -> *) a. Applicative f => a -> f a
pure (PossibleMatches -> Maybe PossibleMatches
forall a. a -> Maybe a
Just PossibleMatches
NoPM)
test (PM NonEmpty ConLikeSet
ms) = MaybeT DsM PossibleMatches
-> IOEnv (Env DsGblEnv DsLclEnv) (Maybe PossibleMatches)
forall (m :: * -> *) a. MaybeT m a -> m (Maybe a)
runMaybeT (NonEmpty ConLikeSet -> PossibleMatches
PM (NonEmpty ConLikeSet -> PossibleMatches)
-> MaybeT DsM (NonEmpty ConLikeSet) -> MaybeT DsM PossibleMatches
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (ConLikeSet -> MaybeT DsM ConLikeSet)
-> NonEmpty ConLikeSet -> MaybeT DsM (NonEmpty ConLikeSet)
forall (t :: * -> *) (f :: * -> *) a b.
(Traversable t, Applicative f) =>
(a -> f b) -> t a -> f (t b)
traverse ConLikeSet -> MaybeT DsM ConLikeSet
one_set NonEmpty ConLikeSet
ms)
one_set :: ConLikeSet -> MaybeT DsM ConLikeSet
one_set ConLikeSet
cs = ConLikeSet -> [ConLike] -> MaybeT DsM ConLikeSet
find_one_inh ConLikeSet
cs (ConLikeSet -> [ConLike]
forall a. UniqDSet a -> [a]
uniqDSetToList ConLikeSet
cs)
find_one_inh :: ConLikeSet -> [ConLike] -> MaybeT DsM ConLikeSet
find_one_inh :: ConLikeSet -> [ConLike] -> MaybeT DsM ConLikeSet
find_one_inh ConLikeSet
_ [] = MaybeT DsM ConLikeSet
forall (m :: * -> *) a. MonadPlus m => m a
mzero
find_one_inh ConLikeSet
cs (ConLike
con:[ConLike]
cons) = IOEnv (Env DsGblEnv DsLclEnv) Bool -> MaybeT DsM Bool
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (ConLike -> IOEnv (Env DsGblEnv DsLclEnv) Bool
inh_test ConLike
con) MaybeT DsM Bool
-> (Bool -> MaybeT DsM ConLikeSet) -> MaybeT DsM ConLikeSet
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \case
Bool
True -> ConLikeSet -> MaybeT DsM ConLikeSet
forall (f :: * -> *) a. Applicative f => a -> f a
pure ConLikeSet
cs
Bool
False -> ConLikeSet -> [ConLike] -> MaybeT DsM ConLikeSet
find_one_inh (ConLikeSet -> ConLike -> ConLikeSet
forall a. Uniquable a => UniqDSet a -> a -> UniqDSet a
delOneFromUniqDSet ConLikeSet
cs ConLike
con) [ConLike]
cons
inh_test :: ConLike -> DsM Bool
inh_test :: ConLike -> IOEnv (Env DsGblEnv DsLclEnv) Bool
inh_test ConLike
con = do
FamInstEnvs
env <- DsM FamInstEnvs
dsGetFamInstEnvs
case FamInstEnvs -> Type -> ConLike -> Maybe [Type]
guessConLikeUnivTyArgsFromResTy FamInstEnvs
env (VarInfo -> Type
vi_ty VarInfo
vi) ConLike
con of
Maybe [Type]
Nothing -> Bool -> IOEnv (Env DsGblEnv DsLclEnv) Bool
forall (f :: * -> *) a. Applicative f => a -> f a
pure Bool
True
Just [Type]
arg_tys -> do
([Id]
_tvs, [Id]
_vars, Bag Type
ty_cs, [Type]
strict_arg_tys) <- [Type] -> ConLike -> DsM ([Id], [Id], Bag Type, [Type])
mkOneConFull [Type]
arg_tys ConLike
con
String -> SDoc -> DsM ()
tracePm String
"inh_test" (ConLike -> SDoc
forall a. Outputable a => a -> SDoc
ppr ConLike
con SDoc -> SDoc -> SDoc
$$ Bag Type -> SDoc
forall a. Outputable a => a -> SDoc
ppr Bag Type
ty_cs)
(Maybe Delta -> Bool)
-> DsM (Maybe Delta) -> IOEnv (Env DsGblEnv DsLclEnv) Bool
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap Maybe Delta -> Bool
forall a. Maybe a -> Bool
isJust (DsM (Maybe Delta) -> IOEnv (Env DsGblEnv DsLclEnv) Bool)
-> (SatisfiabilityCheck -> DsM (Maybe Delta))
-> SatisfiabilityCheck
-> IOEnv (Env DsGblEnv DsLclEnv) Bool
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Delta -> SatisfiabilityCheck -> DsM (Maybe Delta)
runSatisfiabilityCheck Delta
delta (SatisfiabilityCheck -> IOEnv (Env DsGblEnv DsLclEnv) Bool)
-> SatisfiabilityCheck -> IOEnv (Env DsGblEnv DsLclEnv) Bool
forall a b. (a -> b) -> a -> b
$ [SatisfiabilityCheck] -> SatisfiabilityCheck
forall a. Monoid a => [a] -> a
mconcat
[ Bool -> Bag Type -> SatisfiabilityCheck
tyIsSatisfiable Bool
False Bag Type
ty_cs
, RecTcChecker -> [Type] -> SatisfiabilityCheck
tysAreNonVoid RecTcChecker
initRecTc [Type]
strict_arg_tys
]
ensureAllPossibleMatchesInhabited :: Delta -> DsM (Maybe Delta)
ensureAllPossibleMatchesInhabited :: Delta -> DsM (Maybe Delta)
ensureAllPossibleMatchesInhabited delta :: Delta
delta@MkDelta{ delta_tm_st :: Delta -> TmState
delta_tm_st = TmSt SharedDIdEnv VarInfo
env CoreMap Id
reps }
= MaybeT DsM Delta -> DsM (Maybe Delta)
forall (m :: * -> *) a. MaybeT m a -> m (Maybe a)
runMaybeT (Delta -> SharedDIdEnv VarInfo -> Delta
set_tm_cs_env Delta
delta (SharedDIdEnv VarInfo -> Delta)
-> MaybeT DsM (SharedDIdEnv VarInfo) -> MaybeT DsM Delta
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (VarInfo -> MaybeT DsM VarInfo)
-> SharedDIdEnv VarInfo -> MaybeT DsM (SharedDIdEnv VarInfo)
forall a b (f :: * -> *).
Applicative f =>
(a -> f b) -> SharedDIdEnv a -> f (SharedDIdEnv b)
traverseSDIE VarInfo -> MaybeT DsM VarInfo
go SharedDIdEnv VarInfo
env)
where
set_tm_cs_env :: Delta -> SharedDIdEnv VarInfo -> Delta
set_tm_cs_env Delta
delta SharedDIdEnv VarInfo
env = Delta
delta{ delta_tm_st :: TmState
delta_tm_st = SharedDIdEnv VarInfo -> CoreMap Id -> TmState
TmSt SharedDIdEnv VarInfo
env CoreMap Id
reps }
go :: VarInfo -> MaybeT DsM VarInfo
go VarInfo
vi = IOEnv (Env DsGblEnv DsLclEnv) (Maybe VarInfo) -> MaybeT DsM VarInfo
forall (m :: * -> *) a. m (Maybe a) -> MaybeT m a
MaybeT (Delta -> VarInfo -> IOEnv (Env DsGblEnv DsLclEnv) (Maybe VarInfo)
ensureInhabited Delta
delta VarInfo
vi)
addVarCt :: Delta -> Id -> Id -> MaybeT DsM Delta
addVarCt :: Delta -> Id -> Id -> MaybeT DsM Delta
addVarCt delta :: Delta
delta@MkDelta{ delta_tm_st :: Delta -> TmState
delta_tm_st = TmSt SharedDIdEnv VarInfo
env CoreMap Id
_ } Id
x Id
y
| SharedDIdEnv VarInfo -> Id -> Id -> Bool
forall a. SharedDIdEnv a -> Id -> Id -> Bool
sameRepresentativeSDIE SharedDIdEnv VarInfo
env Id
x Id
y = Delta -> MaybeT DsM Delta
forall (f :: * -> *) a. Applicative f => a -> f a
pure Delta
delta
| Bool
otherwise = Delta -> Id -> Id -> MaybeT DsM Delta
equate Delta
delta Id
x Id
y
equate :: Delta -> Id -> Id -> MaybeT DsM Delta
equate :: Delta -> Id -> Id -> MaybeT DsM Delta
equate delta :: Delta
delta@MkDelta{ delta_tm_st :: Delta -> TmState
delta_tm_st = TmSt SharedDIdEnv VarInfo
env CoreMap Id
reps } Id
x Id
y
= ASSERT( not (sameRepresentativeSDIE env x y) )
case (SharedDIdEnv VarInfo -> Id -> Maybe VarInfo
forall a. SharedDIdEnv a -> Id -> Maybe a
lookupSDIE SharedDIdEnv VarInfo
env Id
x, SharedDIdEnv VarInfo -> Id -> Maybe VarInfo
forall a. SharedDIdEnv a -> Id -> Maybe a
lookupSDIE SharedDIdEnv VarInfo
env Id
y) of
(Maybe VarInfo
Nothing, Maybe VarInfo
_) -> Delta -> MaybeT DsM Delta
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Delta
delta{ delta_tm_st :: TmState
delta_tm_st = SharedDIdEnv VarInfo -> CoreMap Id -> TmState
TmSt (SharedDIdEnv VarInfo -> Id -> Id -> SharedDIdEnv VarInfo
forall a. SharedDIdEnv a -> Id -> Id -> SharedDIdEnv a
setIndirectSDIE SharedDIdEnv VarInfo
env Id
x Id
y) CoreMap Id
reps })
(Maybe VarInfo
_, Maybe VarInfo
Nothing) -> Delta -> MaybeT DsM Delta
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Delta
delta{ delta_tm_st :: TmState
delta_tm_st = SharedDIdEnv VarInfo -> CoreMap Id -> TmState
TmSt (SharedDIdEnv VarInfo -> Id -> Id -> SharedDIdEnv VarInfo
forall a. SharedDIdEnv a -> Id -> Id -> SharedDIdEnv a
setIndirectSDIE SharedDIdEnv VarInfo
env Id
y Id
x) CoreMap Id
reps })
(Just VarInfo
vi_x, Just VarInfo
vi_y) -> do
MASSERT2( vi_ty vi_x `eqType` vi_ty vi_y, text "Not same type" )
let env_ind :: SharedDIdEnv VarInfo
env_ind = SharedDIdEnv VarInfo -> Id -> Id -> SharedDIdEnv VarInfo
forall a. SharedDIdEnv a -> Id -> Id -> SharedDIdEnv a
setIndirectSDIE SharedDIdEnv VarInfo
env Id
x Id
y
let env_refs :: SharedDIdEnv VarInfo
env_refs = SharedDIdEnv VarInfo -> Id -> VarInfo -> SharedDIdEnv VarInfo
forall a. SharedDIdEnv a -> Id -> a -> SharedDIdEnv a
setEntrySDIE SharedDIdEnv VarInfo
env_ind Id
y VarInfo
vi_y
let delta_refs :: Delta
delta_refs = Delta
delta{ delta_tm_st :: TmState
delta_tm_st = SharedDIdEnv VarInfo -> CoreMap Id -> TmState
TmSt SharedDIdEnv VarInfo
env_refs CoreMap Id
reps }
let add_fact :: Delta -> (PmAltCon, [Id], [Id]) -> MaybeT DsM Delta
add_fact Delta
delta (PmAltCon
cl, [Id]
tvs, [Id]
args) = Delta -> Id -> PmAltCon -> [Id] -> [Id] -> MaybeT DsM Delta
addConCt Delta
delta Id
y PmAltCon
cl [Id]
tvs [Id]
args
Delta
delta_pos <- (Delta -> (PmAltCon, [Id], [Id]) -> MaybeT DsM Delta)
-> Delta -> [(PmAltCon, [Id], [Id])] -> MaybeT DsM Delta
forall (t :: * -> *) (m :: * -> *) b a.
(Foldable t, Monad m) =>
(b -> a -> m b) -> b -> t a -> m b
foldlM Delta -> (PmAltCon, [Id], [Id]) -> MaybeT DsM Delta
add_fact Delta
delta_refs (VarInfo -> [(PmAltCon, [Id], [Id])]
vi_pos VarInfo
vi_x)
let add_refut :: Delta -> PmAltCon -> MaybeT DsM Delta
add_refut Delta
delta PmAltCon
nalt = Delta -> Id -> PmAltCon -> MaybeT DsM Delta
addNotConCt Delta
delta Id
y PmAltCon
nalt
Delta
delta_neg <- (Delta -> PmAltCon -> MaybeT DsM Delta)
-> Delta -> [PmAltCon] -> MaybeT DsM Delta
forall (t :: * -> *) (m :: * -> *) b a.
(Foldable t, Monad m) =>
(b -> a -> m b) -> b -> t a -> m b
foldlM Delta -> PmAltCon -> MaybeT DsM Delta
add_refut Delta
delta_pos (PmAltConSet -> [PmAltCon]
pmAltConSetElems (VarInfo -> PmAltConSet
vi_neg VarInfo
vi_x))
Delta -> MaybeT DsM Delta
forall (f :: * -> *) a. Applicative f => a -> f a
pure Delta
delta_neg
addConCt :: Delta -> Id -> PmAltCon -> [TyVar] -> [Id] -> MaybeT DsM Delta
addConCt :: Delta -> Id -> PmAltCon -> [Id] -> [Id] -> MaybeT DsM Delta
addConCt delta :: Delta
delta@MkDelta{ delta_tm_st :: Delta -> TmState
delta_tm_st = TmSt SharedDIdEnv VarInfo
env CoreMap Id
reps } Id
x PmAltCon
alt [Id]
tvs [Id]
args = do
VI Type
ty [(PmAltCon, [Id], [Id])]
pos PmAltConSet
neg PossibleMatches
cache <- DsM VarInfo -> MaybeT DsM VarInfo
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (Delta -> Id -> DsM VarInfo
initLookupVarInfo Delta
delta Id
x)
Bool -> MaybeT DsM ()
forall (f :: * -> *). Alternative f => Bool -> f ()
guard (Bool -> Bool
not (PmAltCon -> PmAltConSet -> Bool
elemPmAltConSet PmAltCon
alt PmAltConSet
neg))
Bool -> MaybeT DsM ()
forall (f :: * -> *). Alternative f => Bool -> f ()
guard (((PmAltCon, [Id], [Id]) -> Bool)
-> [(PmAltCon, [Id], [Id])] -> Bool
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
all ((PmEquality -> PmEquality -> Bool
forall a. Eq a => a -> a -> Bool
/= PmEquality
Disjoint) (PmEquality -> Bool)
-> ((PmAltCon, [Id], [Id]) -> PmEquality)
-> (PmAltCon, [Id], [Id])
-> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. PmAltCon -> PmAltCon -> PmEquality
eqPmAltCon PmAltCon
alt (PmAltCon -> PmEquality)
-> ((PmAltCon, [Id], [Id]) -> PmAltCon)
-> (PmAltCon, [Id], [Id])
-> PmEquality
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (PmAltCon, [Id], [Id]) -> PmAltCon
forall a b c. (a, b, c) -> a
fstOf3) [(PmAltCon, [Id], [Id])]
pos)
case ((PmAltCon, [Id], [Id]) -> Bool)
-> [(PmAltCon, [Id], [Id])] -> Maybe (PmAltCon, [Id], [Id])
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Maybe a
find ((PmEquality -> PmEquality -> Bool
forall a. Eq a => a -> a -> Bool
== PmEquality
Equal) (PmEquality -> Bool)
-> ((PmAltCon, [Id], [Id]) -> PmEquality)
-> (PmAltCon, [Id], [Id])
-> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. PmAltCon -> PmAltCon -> PmEquality
eqPmAltCon PmAltCon
alt (PmAltCon -> PmEquality)
-> ((PmAltCon, [Id], [Id]) -> PmAltCon)
-> (PmAltCon, [Id], [Id])
-> PmEquality
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (PmAltCon, [Id], [Id]) -> PmAltCon
forall a b c. (a, b, c) -> a
fstOf3) [(PmAltCon, [Id], [Id])]
pos of
Just (PmAltCon
_con, [Id]
other_tvs, [Id]
other_args) -> do
let ty_cts :: [PmCt]
ty_cts = [Type] -> [Type] -> [PmCt]
equateTys ((Id -> Type) -> [Id] -> [Type]
forall a b. (a -> b) -> [a] -> [b]
map Id -> Type
mkTyVarTy [Id]
tvs) ((Id -> Type) -> [Id] -> [Type]
forall a b. (a -> b) -> [a] -> [b]
map Id -> Type
mkTyVarTy [Id]
other_tvs)
Bool -> MaybeT DsM () -> MaybeT DsM ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when ([Id] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [Id]
args Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
/= [Id] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [Id]
other_args) (MaybeT DsM () -> MaybeT DsM ()) -> MaybeT DsM () -> MaybeT DsM ()
forall a b. (a -> b) -> a -> b
$
DsM () -> MaybeT DsM ()
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (DsM () -> MaybeT DsM ()) -> DsM () -> MaybeT DsM ()
forall a b. (a -> b) -> a -> b
$ String -> SDoc -> DsM ()
tracePm String
"error" (Id -> SDoc
forall a. Outputable a => a -> SDoc
ppr Id
x SDoc -> SDoc -> SDoc
<+> PmAltCon -> SDoc
forall a. Outputable a => a -> SDoc
ppr PmAltCon
alt SDoc -> SDoc -> SDoc
<+> [Id] -> SDoc
forall a. Outputable a => a -> SDoc
ppr [Id]
args SDoc -> SDoc -> SDoc
<+> [Id] -> SDoc
forall a. Outputable a => a -> SDoc
ppr [Id]
other_args)
let tm_cts :: [PmCt]
tm_cts = String -> (Id -> Id -> PmCt) -> [Id] -> [Id] -> [PmCt]
forall a b c. String -> (a -> b -> c) -> [a] -> [b] -> [c]
zipWithEqual String
"addConCt" Id -> Id -> PmCt
PmVarCt [Id]
args [Id]
other_args
DsM (Maybe Delta) -> MaybeT DsM Delta
forall (m :: * -> *) a. m (Maybe a) -> MaybeT m a
MaybeT (DsM (Maybe Delta) -> MaybeT DsM Delta)
-> DsM (Maybe Delta) -> MaybeT DsM Delta
forall a b. (a -> b) -> a -> b
$ Delta -> PmCts -> DsM (Maybe Delta)
addPmCts Delta
delta ([PmCt] -> PmCts
forall a. [a] -> Bag a
listToBag [PmCt]
ty_cts PmCts -> PmCts -> PmCts
forall a. Bag a -> Bag a -> Bag a
`unionBags` [PmCt] -> PmCts
forall a. [a] -> Bag a
listToBag [PmCt]
tm_cts)
Maybe (PmAltCon, [Id], [Id])
Nothing -> do
let pos' :: [(PmAltCon, [Id], [Id])]
pos' = (PmAltCon
alt, [Id]
tvs, [Id]
args)(PmAltCon, [Id], [Id])
-> [(PmAltCon, [Id], [Id])] -> [(PmAltCon, [Id], [Id])]
forall a. a -> [a] -> [a]
:[(PmAltCon, [Id], [Id])]
pos
Delta -> MaybeT DsM Delta
forall (f :: * -> *) a. Applicative f => a -> f a
pure Delta
delta{ delta_tm_st :: TmState
delta_tm_st = SharedDIdEnv VarInfo -> CoreMap Id -> TmState
TmSt (SharedDIdEnv VarInfo -> Id -> VarInfo -> SharedDIdEnv VarInfo
forall a. SharedDIdEnv a -> Id -> a -> SharedDIdEnv a
setEntrySDIE SharedDIdEnv VarInfo
env Id
x (Type
-> [(PmAltCon, [Id], [Id])]
-> PmAltConSet
-> PossibleMatches
-> VarInfo
VI Type
ty [(PmAltCon, [Id], [Id])]
pos' PmAltConSet
neg PossibleMatches
cache)) CoreMap Id
reps}
equateTys :: [Type] -> [Type] -> [PmCt]
equateTys :: [Type] -> [Type] -> [PmCt]
equateTys [Type]
ts [Type]
us =
[ Type -> PmCt
PmTyCt (Type -> Type -> Type
mkPrimEqPred Type
t Type
u)
| (Type
t, Type
u) <- String -> [Type] -> [Type] -> [(Type, Type)]
forall a b. String -> [a] -> [b] -> [(a, b)]
zipEqual String
"equateTys" [Type]
ts [Type]
us
, Bool -> Bool
not (Type -> Type -> Bool
eqType Type
t Type
u)
]
data InhabitationCandidate =
InhabitationCandidate
{ InhabitationCandidate -> PmCts
ic_cs :: PmCts
, InhabitationCandidate -> [Type]
ic_strict_arg_tys :: [Type]
}
instance Outputable InhabitationCandidate where
ppr :: InhabitationCandidate -> SDoc
ppr (InhabitationCandidate PmCts
cs [Type]
strict_arg_tys) =
String -> SDoc
text String
"InhabitationCandidate" SDoc -> SDoc -> SDoc
<+>
[SDoc] -> SDoc
vcat [ String -> SDoc
text String
"ic_cs =" SDoc -> SDoc -> SDoc
<+> PmCts -> SDoc
forall a. Outputable a => a -> SDoc
ppr PmCts
cs
, String -> SDoc
text String
"ic_strict_arg_tys =" SDoc -> SDoc -> SDoc
<+> [Type] -> SDoc
forall a. Outputable a => a -> SDoc
ppr [Type]
strict_arg_tys ]
mkInhabitationCandidate :: Id -> DataCon -> DsM InhabitationCandidate
mkInhabitationCandidate :: Id -> DataCon -> DsM InhabitationCandidate
mkInhabitationCandidate Id
x DataCon
dc = do
let cl :: ConLike
cl = DataCon -> ConLike
RealDataCon DataCon
dc
let tc_args :: [Type]
tc_args = Type -> [Type]
tyConAppArgs (Id -> Type
idType Id
x)
([Id]
ty_vars, [Id]
arg_vars, Bag Type
ty_cs, [Type]
strict_arg_tys) <- [Type] -> ConLike -> DsM ([Id], [Id], Bag Type, [Type])
mkOneConFull [Type]
tc_args ConLike
cl
InhabitationCandidate -> DsM InhabitationCandidate
forall (f :: * -> *) a. Applicative f => a -> f a
pure InhabitationCandidate :: PmCts -> [Type] -> InhabitationCandidate
InhabitationCandidate
{ ic_cs :: PmCts
ic_cs = Type -> PmCt
PmTyCt (Type -> PmCt) -> Bag Type -> PmCts
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Bag Type
ty_cs PmCts -> PmCt -> PmCts
forall a. Bag a -> a -> Bag a
`snocBag` Id -> PmAltCon -> [Id] -> [Id] -> PmCt
PmConCt Id
x (ConLike -> PmAltCon
PmAltConLike ConLike
cl) [Id]
ty_vars [Id]
arg_vars
, ic_strict_arg_tys :: [Type]
ic_strict_arg_tys = [Type]
strict_arg_tys
}
inhabitationCandidates :: Delta -> Type
-> DsM (Either Type (TyCon, Id, [InhabitationCandidate]))
inhabitationCandidates :: Delta
-> Type -> DsM (Either Type (TyCon, Id, [InhabitationCandidate]))
inhabitationCandidates MkDelta{ delta_ty_st :: Delta -> TyState
delta_ty_st = TyState
ty_st } Type
ty = do
TyState -> Type -> DsM TopNormaliseTypeResult
pmTopNormaliseType TyState
ty_st Type
ty DsM TopNormaliseTypeResult
-> (TopNormaliseTypeResult
-> DsM (Either Type (TyCon, Id, [InhabitationCandidate])))
-> DsM (Either Type (TyCon, Id, [InhabitationCandidate]))
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \case
NoChange Type
_ -> Type
-> Type
-> [(Type, DataCon, Type)]
-> DsM (Either Type (TyCon, Id, [InhabitationCandidate]))
alts_to_check Type
ty Type
ty []
NormalisedByConstraints Type
ty' -> Type
-> Type
-> [(Type, DataCon, Type)]
-> DsM (Either Type (TyCon, Id, [InhabitationCandidate]))
alts_to_check Type
ty' Type
ty' []
HadRedexes Type
src_ty [(Type, DataCon, Type)]
dcs Type
core_ty -> Type
-> Type
-> [(Type, DataCon, Type)]
-> DsM (Either Type (TyCon, Id, [InhabitationCandidate]))
alts_to_check Type
src_ty Type
core_ty [(Type, DataCon, Type)]
dcs
where
build_newtype :: (Type, DataCon, Type) -> Id -> DsM (Id, PmCt)
build_newtype :: (Type, DataCon, Type) -> Id -> DsM (Id, PmCt)
build_newtype (Type
ty, DataCon
dc, Type
_arg_ty) Id
x = do
Id
y <- Type -> DsM Id
mkPmId Type
ty
(Id, PmCt) -> DsM (Id, PmCt)
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Id
y, Id -> PmAltCon -> [Id] -> [Id] -> PmCt
PmConCt Id
y (ConLike -> PmAltCon
PmAltConLike (DataCon -> ConLike
RealDataCon DataCon
dc)) [] [Id
x])
build_newtypes :: Id -> [(Type, DataCon, Type)] -> DsM (Id, [PmCt])
build_newtypes :: Id -> [(Type, DataCon, Type)] -> DsM (Id, [PmCt])
build_newtypes Id
x = ((Type, DataCon, Type) -> (Id, [PmCt]) -> DsM (Id, [PmCt]))
-> (Id, [PmCt]) -> [(Type, DataCon, Type)] -> DsM (Id, [PmCt])
forall (t :: * -> *) (m :: * -> *) a b.
(Foldable t, Monad m) =>
(a -> b -> m b) -> b -> t a -> m b
foldrM (\(Type, DataCon, Type)
dc (Id
x, [PmCt]
cts) -> (Type, DataCon, Type) -> Id -> [PmCt] -> DsM (Id, [PmCt])
go (Type, DataCon, Type)
dc Id
x [PmCt]
cts) (Id
x, [])
where
go :: (Type, DataCon, Type) -> Id -> [PmCt] -> DsM (Id, [PmCt])
go (Type, DataCon, Type)
dc Id
x [PmCt]
cts = (PmCt -> [PmCt]) -> (Id, PmCt) -> (Id, [PmCt])
forall (p :: * -> * -> *) b c a.
Bifunctor p =>
(b -> c) -> p a b -> p a c
second (PmCt -> [PmCt] -> [PmCt]
forall a. a -> [a] -> [a]
:[PmCt]
cts) ((Id, PmCt) -> (Id, [PmCt])) -> DsM (Id, PmCt) -> DsM (Id, [PmCt])
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (Type, DataCon, Type) -> Id -> DsM (Id, PmCt)
build_newtype (Type, DataCon, Type)
dc Id
x
alts_to_check :: Type -> Type -> [(Type, DataCon, Type)]
-> DsM (Either Type (TyCon, Id, [InhabitationCandidate]))
alts_to_check :: Type
-> Type
-> [(Type, DataCon, Type)]
-> DsM (Either Type (TyCon, Id, [InhabitationCandidate]))
alts_to_check Type
src_ty Type
core_ty [(Type, DataCon, Type)]
dcs = case HasDebugCallStack => Type -> Maybe (TyCon, [Type])
Type -> Maybe (TyCon, [Type])
splitTyConApp_maybe Type
core_ty of
Just (TyCon
tc, [Type]
_)
| TyCon -> Bool
isTyConTriviallyInhabited TyCon
tc
-> case [(Type, DataCon, Type)]
dcs of
[] -> Either Type (TyCon, Id, [InhabitationCandidate])
-> DsM (Either Type (TyCon, Id, [InhabitationCandidate]))
forall (m :: * -> *) a. Monad m => a -> m a
return (Type -> Either Type (TyCon, Id, [InhabitationCandidate])
forall a b. a -> Either a b
Left Type
src_ty)
((Type, DataCon, Type)
_:[(Type, DataCon, Type)]
_) -> do Id
inner <- Type -> DsM Id
mkPmId Type
core_ty
(Id
outer, [PmCt]
new_tm_cts) <- Id -> [(Type, DataCon, Type)] -> DsM (Id, [PmCt])
build_newtypes Id
inner [(Type, DataCon, Type)]
dcs
Either Type (TyCon, Id, [InhabitationCandidate])
-> DsM (Either Type (TyCon, Id, [InhabitationCandidate]))
forall (m :: * -> *) a. Monad m => a -> m a
return (Either Type (TyCon, Id, [InhabitationCandidate])
-> DsM (Either Type (TyCon, Id, [InhabitationCandidate])))
-> Either Type (TyCon, Id, [InhabitationCandidate])
-> DsM (Either Type (TyCon, Id, [InhabitationCandidate]))
forall a b. (a -> b) -> a -> b
$ (TyCon, Id, [InhabitationCandidate])
-> Either Type (TyCon, Id, [InhabitationCandidate])
forall a b. b -> Either a b
Right (TyCon
tc, Id
outer, [InhabitationCandidate :: PmCts -> [Type] -> InhabitationCandidate
InhabitationCandidate
{ ic_cs :: PmCts
ic_cs = [PmCt] -> PmCts
forall a. [a] -> Bag a
listToBag [PmCt]
new_tm_cts
, ic_strict_arg_tys :: [Type]
ic_strict_arg_tys = [] }])
| Type -> Bool
pmIsClosedType Type
core_ty Bool -> Bool -> Bool
&& Bool -> Bool
not (TyCon -> Bool
isAbstractTyCon TyCon
tc)
-> do
Id
inner <- Type -> DsM Id
mkPmId Type
core_ty
[InhabitationCandidate]
alts <- (DataCon -> DsM InhabitationCandidate)
-> [DataCon]
-> IOEnv (Env DsGblEnv DsLclEnv) [InhabitationCandidate]
forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
mapM (Id -> DataCon -> DsM InhabitationCandidate
mkInhabitationCandidate Id
inner) (TyCon -> [DataCon]
tyConDataCons TyCon
tc)
(Id
outer, [PmCt]
new_cts) <- Id -> [(Type, DataCon, Type)] -> DsM (Id, [PmCt])
build_newtypes Id
inner [(Type, DataCon, Type)]
dcs
let wrap_dcs :: InhabitationCandidate -> InhabitationCandidate
wrap_dcs InhabitationCandidate
alt = InhabitationCandidate
alt{ ic_cs :: PmCts
ic_cs = [PmCt] -> PmCts
forall a. [a] -> Bag a
listToBag [PmCt]
new_cts PmCts -> PmCts -> PmCts
forall a. Bag a -> Bag a -> Bag a
`unionBags` InhabitationCandidate -> PmCts
ic_cs InhabitationCandidate
alt}
Either Type (TyCon, Id, [InhabitationCandidate])
-> DsM (Either Type (TyCon, Id, [InhabitationCandidate]))
forall (m :: * -> *) a. Monad m => a -> m a
return (Either Type (TyCon, Id, [InhabitationCandidate])
-> DsM (Either Type (TyCon, Id, [InhabitationCandidate])))
-> Either Type (TyCon, Id, [InhabitationCandidate])
-> DsM (Either Type (TyCon, Id, [InhabitationCandidate]))
forall a b. (a -> b) -> a -> b
$ (TyCon, Id, [InhabitationCandidate])
-> Either Type (TyCon, Id, [InhabitationCandidate])
forall a b. b -> Either a b
Right (TyCon
tc, Id
outer, (InhabitationCandidate -> InhabitationCandidate)
-> [InhabitationCandidate] -> [InhabitationCandidate]
forall a b. (a -> b) -> [a] -> [b]
map InhabitationCandidate -> InhabitationCandidate
wrap_dcs [InhabitationCandidate]
alts)
Maybe (TyCon, [Type])
_other -> Either Type (TyCon, Id, [InhabitationCandidate])
-> DsM (Either Type (TyCon, Id, [InhabitationCandidate]))
forall (m :: * -> *) a. Monad m => a -> m a
return (Type -> Either Type (TyCon, Id, [InhabitationCandidate])
forall a b. a -> Either a b
Left Type
src_ty)
triviallyInhabitedTyCons :: UniqSet TyCon
triviallyInhabitedTyCons :: UniqSet TyCon
triviallyInhabitedTyCons = [TyCon] -> UniqSet TyCon
forall a. Uniquable a => [a] -> UniqSet a
mkUniqSet [
TyCon
charTyCon, TyCon
doubleTyCon, TyCon
floatTyCon, TyCon
intTyCon, TyCon
wordTyCon, TyCon
word8TyCon
]
isTyConTriviallyInhabited :: TyCon -> Bool
isTyConTriviallyInhabited :: TyCon -> Bool
isTyConTriviallyInhabited TyCon
tc = TyCon -> UniqSet TyCon -> Bool
forall a. Uniquable a => a -> UniqSet a -> Bool
elementOfUniqSet TyCon
tc UniqSet TyCon
triviallyInhabitedTyCons
tysAreNonVoid :: RecTcChecker -> [Type] -> SatisfiabilityCheck
tysAreNonVoid :: RecTcChecker -> [Type] -> SatisfiabilityCheck
tysAreNonVoid RecTcChecker
rec_env [Type]
strict_arg_tys = (Delta -> DsM (Maybe Delta)) -> SatisfiabilityCheck
SC ((Delta -> DsM (Maybe Delta)) -> SatisfiabilityCheck)
-> (Delta -> DsM (Maybe Delta)) -> SatisfiabilityCheck
forall a b. (a -> b) -> a -> b
$ \Delta
delta -> do
Bool
all_non_void <- RecTcChecker
-> Delta -> [Type] -> IOEnv (Env DsGblEnv DsLclEnv) Bool
checkAllNonVoid RecTcChecker
rec_env Delta
delta [Type]
strict_arg_tys
Maybe Delta -> DsM (Maybe Delta)
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Maybe Delta -> DsM (Maybe Delta))
-> Maybe Delta -> DsM (Maybe Delta)
forall a b. (a -> b) -> a -> b
$ if Bool
all_non_void
then Delta -> Maybe Delta
forall a. a -> Maybe a
Just Delta
delta
else Maybe Delta
forall a. Maybe a
Nothing
checkAllNonVoid :: RecTcChecker -> Delta -> [Type] -> DsM Bool
checkAllNonVoid :: RecTcChecker
-> Delta -> [Type] -> IOEnv (Env DsGblEnv DsLclEnv) Bool
checkAllNonVoid RecTcChecker
rec_ts Delta
amb_cs [Type]
strict_arg_tys = do
let definitely_inhabited :: Type -> IOEnv (Env DsGblEnv DsLclEnv) Bool
definitely_inhabited = TyState -> Type -> IOEnv (Env DsGblEnv DsLclEnv) Bool
definitelyInhabitedType (Delta -> TyState
delta_ty_st Delta
amb_cs)
[Type]
tys_to_check <- (Type -> IOEnv (Env DsGblEnv DsLclEnv) Bool)
-> [Type] -> IOEnv (Env DsGblEnv DsLclEnv) [Type]
forall (m :: * -> *) a.
Applicative m =>
(a -> m Bool) -> [a] -> m [a]
filterOutM Type -> IOEnv (Env DsGblEnv DsLclEnv) Bool
definitely_inhabited [Type]
strict_arg_tys
let rec_max_bound :: Int
rec_max_bound | [Type]
tys_to_check [Type] -> Int -> Bool
forall a. [a] -> Int -> Bool
`lengthExceeds` Int
1
= Int
1
| Bool
otherwise
= Int
3
rec_ts' :: RecTcChecker
rec_ts' = Int -> RecTcChecker -> RecTcChecker
setRecTcMaxBound Int
rec_max_bound RecTcChecker
rec_ts
(Type -> IOEnv (Env DsGblEnv DsLclEnv) Bool)
-> [Type] -> IOEnv (Env DsGblEnv DsLclEnv) Bool
forall (m :: * -> *) a. Monad m => (a -> m Bool) -> [a] -> m Bool
allM (RecTcChecker -> Delta -> Type -> IOEnv (Env DsGblEnv DsLclEnv) Bool
nonVoid RecTcChecker
rec_ts' Delta
amb_cs) [Type]
tys_to_check
nonVoid
:: RecTcChecker
-> Delta
-> Type
-> DsM Bool
nonVoid :: RecTcChecker -> Delta -> Type -> IOEnv (Env DsGblEnv DsLclEnv) Bool
nonVoid RecTcChecker
rec_ts Delta
amb_cs Type
strict_arg_ty = do
Either Type (TyCon, Id, [InhabitationCandidate])
mb_cands <- Delta
-> Type -> DsM (Either Type (TyCon, Id, [InhabitationCandidate]))
inhabitationCandidates Delta
amb_cs Type
strict_arg_ty
case Either Type (TyCon, Id, [InhabitationCandidate])
mb_cands of
Right (TyCon
tc, Id
_, [InhabitationCandidate]
cands)
| Just RecTcChecker
rec_ts' <- RecTcChecker -> TyCon -> Maybe RecTcChecker
checkRecTc RecTcChecker
rec_ts TyCon
tc
-> (InhabitationCandidate -> IOEnv (Env DsGblEnv DsLclEnv) Bool)
-> [InhabitationCandidate] -> IOEnv (Env DsGblEnv DsLclEnv) Bool
forall (m :: * -> *) a. Monad m => (a -> m Bool) -> [a] -> m Bool
anyM (RecTcChecker
-> Delta
-> InhabitationCandidate
-> IOEnv (Env DsGblEnv DsLclEnv) Bool
cand_is_inhabitable RecTcChecker
rec_ts' Delta
amb_cs) [InhabitationCandidate]
cands
Either Type (TyCon, Id, [InhabitationCandidate])
_ -> Bool -> IOEnv (Env DsGblEnv DsLclEnv) Bool
forall (f :: * -> *) a. Applicative f => a -> f a
pure Bool
True
where
cand_is_inhabitable :: RecTcChecker -> Delta
-> InhabitationCandidate -> DsM Bool
cand_is_inhabitable :: RecTcChecker
-> Delta
-> InhabitationCandidate
-> IOEnv (Env DsGblEnv DsLclEnv) Bool
cand_is_inhabitable RecTcChecker
rec_ts Delta
amb_cs
(InhabitationCandidate{ ic_cs :: InhabitationCandidate -> PmCts
ic_cs = PmCts
new_cs
, ic_strict_arg_tys :: InhabitationCandidate -> [Type]
ic_strict_arg_tys = [Type]
new_strict_arg_tys }) = do
let ([Type]
new_ty_cs, [TmCt]
new_tm_cs) = PmCts -> ([Type], [TmCt])
partitionTyTmCts PmCts
new_cs
(Maybe Delta -> Bool)
-> DsM (Maybe Delta) -> IOEnv (Env DsGblEnv DsLclEnv) Bool
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap Maybe Delta -> Bool
forall a. Maybe a -> Bool
isJust (DsM (Maybe Delta) -> IOEnv (Env DsGblEnv DsLclEnv) Bool)
-> DsM (Maybe Delta) -> IOEnv (Env DsGblEnv DsLclEnv) Bool
forall a b. (a -> b) -> a -> b
$ Delta -> SatisfiabilityCheck -> DsM (Maybe Delta)
runSatisfiabilityCheck Delta
amb_cs (SatisfiabilityCheck -> DsM (Maybe Delta))
-> SatisfiabilityCheck -> DsM (Maybe Delta)
forall a b. (a -> b) -> a -> b
$ [SatisfiabilityCheck] -> SatisfiabilityCheck
forall a. Monoid a => [a] -> a
mconcat
[ Bool -> Bag Type -> SatisfiabilityCheck
tyIsSatisfiable Bool
False ([Type] -> Bag Type
forall a. [a] -> Bag a
listToBag [Type]
new_ty_cs)
, Bag TmCt -> SatisfiabilityCheck
tmIsSatisfiable ([TmCt] -> Bag TmCt
forall a. [a] -> Bag a
listToBag [TmCt]
new_tm_cs)
, RecTcChecker -> [Type] -> SatisfiabilityCheck
tysAreNonVoid RecTcChecker
rec_ts [Type]
new_strict_arg_tys
]
definitelyInhabitedType :: TyState -> Type -> DsM Bool
definitelyInhabitedType :: TyState -> Type -> IOEnv (Env DsGblEnv DsLclEnv) Bool
definitelyInhabitedType TyState
ty_st Type
ty = do
TopNormaliseTypeResult
res <- TyState -> Type -> DsM TopNormaliseTypeResult
pmTopNormaliseType TyState
ty_st Type
ty
Bool -> IOEnv (Env DsGblEnv DsLclEnv) Bool
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Bool -> IOEnv (Env DsGblEnv DsLclEnv) Bool)
-> Bool -> IOEnv (Env DsGblEnv DsLclEnv) Bool
forall a b. (a -> b) -> a -> b
$ case TopNormaliseTypeResult
res of
HadRedexes Type
_ [(Type, DataCon, Type)]
cons Type
_ -> ((Type, DataCon, Type) -> Bool) -> [(Type, DataCon, Type)] -> Bool
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
any (Type, DataCon, Type) -> Bool
meets_criteria [(Type, DataCon, Type)]
cons
TopNormaliseTypeResult
_ -> Bool
False
where
meets_criteria :: (Type, DataCon, Type) -> Bool
meets_criteria :: (Type, DataCon, Type) -> Bool
meets_criteria (Type
_, DataCon
con, Type
_) =
[EqSpec] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null (DataCon -> [EqSpec]
dataConEqSpec DataCon
con) Bool -> Bool -> Bool
&&
[HsImplBang] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null (DataCon -> [HsImplBang]
dataConImplBangs DataCon
con)
provideEvidence :: [Id] -> Int -> Delta -> DsM [Delta]
provideEvidence :: [Id] -> Int -> Delta -> DsM [Delta]
provideEvidence = [Id] -> Int -> Delta -> DsM [Delta]
go
where
go :: [Id] -> Int -> Delta -> DsM [Delta]
go [Id]
_ Int
0 Delta
_ = [Delta] -> DsM [Delta]
forall (f :: * -> *) a. Applicative f => a -> f a
pure []
go [] Int
_ Delta
delta = [Delta] -> DsM [Delta]
forall (f :: * -> *) a. Applicative f => a -> f a
pure [Delta
delta]
go (Id
x:[Id]
xs) Int
n Delta
delta = do
String -> SDoc -> DsM ()
tracePm String
"provideEvidence" (Id -> SDoc
forall a. Outputable a => a -> SDoc
ppr Id
x SDoc -> SDoc -> SDoc
$$ [Id] -> SDoc
forall a. Outputable a => a -> SDoc
ppr [Id]
xs SDoc -> SDoc -> SDoc
$$ Delta -> SDoc
forall a. Outputable a => a -> SDoc
ppr Delta
delta SDoc -> SDoc -> SDoc
$$ Int -> SDoc
forall a. Outputable a => a -> SDoc
ppr Int
n)
VI Type
_ [(PmAltCon, [Id], [Id])]
pos PmAltConSet
neg PossibleMatches
_ <- Delta -> Id -> DsM VarInfo
initLookupVarInfo Delta
delta Id
x
case [(PmAltCon, [Id], [Id])]
pos of
(PmAltCon, [Id], [Id])
_:[(PmAltCon, [Id], [Id])]
_ -> do
let arg_vas :: [Id]
arg_vas = ((PmAltCon, [Id], [Id]) -> [Id])
-> [(PmAltCon, [Id], [Id])] -> [Id]
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap (\(PmAltCon
_cl, [Id]
_tvs, [Id]
args) -> [Id]
args) [(PmAltCon, [Id], [Id])]
pos
[Id] -> Int -> Delta -> DsM [Delta]
go ([Id]
arg_vas [Id] -> [Id] -> [Id]
forall a. [a] -> [a] -> [a]
++ [Id]
xs) Int
n Delta
delta
[]
| [PmLit] -> Bool
forall a. [a] -> Bool
notNull [ PmLit
l | PmAltLit PmLit
l <- PmAltConSet -> [PmAltCon]
pmAltConSetElems PmAltConSet
neg ]
-> [Id] -> Int -> Delta -> DsM [Delta]
go [Id]
xs Int
n Delta
delta
[] -> Id -> [Id] -> Int -> Delta -> DsM [Delta]
try_instantiate Id
x [Id]
xs Int
n Delta
delta
try_instantiate :: Id -> [Id] -> Int -> Delta -> DsM [Delta]
try_instantiate :: Id -> [Id] -> Int -> Delta -> DsM [Delta]
try_instantiate Id
x [Id]
xs Int
n Delta
delta = do
(Type
_src_ty, [(Type, DataCon, Type)]
dcs, Type
core_ty) <- TopNormaliseTypeResult -> (Type, [(Type, DataCon, Type)], Type)
tntrGuts (TopNormaliseTypeResult -> (Type, [(Type, DataCon, Type)], Type))
-> DsM TopNormaliseTypeResult
-> IOEnv
(Env DsGblEnv DsLclEnv) (Type, [(Type, DataCon, Type)], Type)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> TyState -> Type -> DsM TopNormaliseTypeResult
pmTopNormaliseType (Delta -> TyState
delta_ty_st Delta
delta) (Id -> Type
idType Id
x)
let build_newtype :: (Id, Delta) -> (a, DataCon, Type) -> MaybeT DsM (Id, Delta)
build_newtype (Id
x, Delta
delta) (a
_ty, DataCon
dc, Type
arg_ty) = do
Id
y <- DsM Id -> MaybeT DsM Id
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (DsM Id -> MaybeT DsM Id) -> DsM Id -> MaybeT DsM Id
forall a b. (a -> b) -> a -> b
$ Type -> DsM Id
mkPmId Type
arg_ty
Delta
delta' <- Delta -> Id -> PmAltCon -> [Id] -> [Id] -> MaybeT DsM Delta
addConCt Delta
delta Id
x (ConLike -> PmAltCon
PmAltConLike (DataCon -> ConLike
RealDataCon DataCon
dc)) [] [Id
y]
(Id, Delta) -> MaybeT DsM (Id, Delta)
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Id
y, Delta
delta')
MaybeT DsM (Id, Delta)
-> IOEnv (Env DsGblEnv DsLclEnv) (Maybe (Id, Delta))
forall (m :: * -> *) a. MaybeT m a -> m (Maybe a)
runMaybeT (((Id, Delta) -> (Type, DataCon, Type) -> MaybeT DsM (Id, Delta))
-> (Id, Delta) -> [(Type, DataCon, Type)] -> MaybeT DsM (Id, Delta)
forall (t :: * -> *) (m :: * -> *) b a.
(Foldable t, Monad m) =>
(b -> a -> m b) -> b -> t a -> m b
foldlM (Id, Delta) -> (Type, DataCon, Type) -> MaybeT DsM (Id, Delta)
forall {a}.
(Id, Delta) -> (a, DataCon, Type) -> MaybeT DsM (Id, Delta)
build_newtype (Id
x, Delta
delta) [(Type, DataCon, Type)]
dcs) IOEnv (Env DsGblEnv DsLclEnv) (Maybe (Id, Delta))
-> (Maybe (Id, Delta) -> DsM [Delta]) -> DsM [Delta]
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \case
Maybe (Id, Delta)
Nothing -> [Delta] -> DsM [Delta]
forall (f :: * -> *) a. Applicative f => a -> f a
pure []
Just (Id
y, Delta
newty_delta) -> do
PossibleMatches
pm <- VarInfo -> PossibleMatches
vi_cache (VarInfo -> PossibleMatches)
-> DsM VarInfo -> IOEnv (Env DsGblEnv DsLclEnv) PossibleMatches
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Delta -> Id -> DsM VarInfo
initLookupVarInfo Delta
newty_delta Id
y
Maybe ConLikeSet
mb_cls <- Delta -> PossibleMatches -> DsM (Maybe ConLikeSet)
pickMinimalCompleteSet Delta
newty_delta PossibleMatches
pm
case ConLikeSet -> [ConLike]
forall a. UniqDSet a -> [a]
uniqDSetToList (ConLikeSet -> [ConLike]) -> Maybe ConLikeSet -> Maybe [ConLike]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Maybe ConLikeSet
mb_cls of
Just cls :: [ConLike]
cls@(ConLike
_:[ConLike]
_) -> Id -> Type -> [Id] -> Int -> Delta -> [ConLike] -> DsM [Delta]
instantiate_cons Id
y Type
core_ty [Id]
xs Int
n Delta
newty_delta [ConLike]
cls
Just [] | Bool -> Bool
not (Delta -> Id -> Bool
canDiverge Delta
newty_delta Id
y) -> [Delta] -> DsM [Delta]
forall (f :: * -> *) a. Applicative f => a -> f a
pure []
Maybe [ConLike]
_ -> [Id] -> Int -> Delta -> DsM [Delta]
go [Id]
xs Int
n Delta
newty_delta
instantiate_cons :: Id -> Type -> [Id] -> Int -> Delta -> [ConLike] -> DsM [Delta]
instantiate_cons :: Id -> Type -> [Id] -> Int -> Delta -> [ConLike] -> DsM [Delta]
instantiate_cons Id
_ Type
_ [Id]
_ Int
_ Delta
_ [] = [Delta] -> DsM [Delta]
forall (f :: * -> *) a. Applicative f => a -> f a
pure []
instantiate_cons Id
_ Type
_ [Id]
_ Int
0 Delta
_ [ConLike]
_ = [Delta] -> DsM [Delta]
forall (f :: * -> *) a. Applicative f => a -> f a
pure []
instantiate_cons Id
_ Type
ty [Id]
xs Int
n Delta
delta [ConLike]
_
| ((TyCon, [Type]) -> Bool) -> Maybe (TyCon, [Type]) -> Maybe Bool
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (TyCon -> Bool
isTyConTriviallyInhabited (TyCon -> Bool)
-> ((TyCon, [Type]) -> TyCon) -> (TyCon, [Type]) -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (TyCon, [Type]) -> TyCon
forall a b. (a, b) -> a
fst) (HasDebugCallStack => Type -> Maybe (TyCon, [Type])
Type -> Maybe (TyCon, [Type])
splitTyConApp_maybe Type
ty) Maybe Bool -> Maybe Bool -> Bool
forall a. Eq a => a -> a -> Bool
== Bool -> Maybe Bool
forall a. a -> Maybe a
Just Bool
True
= [Id] -> Int -> Delta -> DsM [Delta]
go [Id]
xs Int
n Delta
delta
instantiate_cons Id
x Type
ty [Id]
xs Int
n Delta
delta (ConLike
cl:[ConLike]
cls) = do
FamInstEnvs
env <- DsM FamInstEnvs
dsGetFamInstEnvs
case FamInstEnvs -> Type -> ConLike -> Maybe [Type]
guessConLikeUnivTyArgsFromResTy FamInstEnvs
env Type
ty ConLike
cl of
Maybe [Type]
Nothing -> [Delta] -> DsM [Delta]
forall (f :: * -> *) a. Applicative f => a -> f a
pure [Delta
delta]
Just [Type]
arg_tys -> do
([Id]
tvs, [Id]
arg_vars, Bag Type
new_ty_cs, [Type]
strict_arg_tys) <- [Type] -> ConLike -> DsM ([Id], [Id], Bag Type, [Type])
mkOneConFull [Type]
arg_tys ConLike
cl
let new_tm_cs :: Bag TmCt
new_tm_cs = TmCt -> Bag TmCt
forall a. a -> Bag a
unitBag (Id -> PmAltCon -> [Id] -> [Id] -> TmCt
TmConCt Id
x (ConLike -> PmAltCon
PmAltConLike ConLike
cl) [Id]
tvs [Id]
arg_vars)
Maybe Delta
mb_delta <- Delta -> Bag Type -> Bag TmCt -> [Type] -> DsM (Maybe Delta)
pmIsSatisfiable Delta
delta Bag Type
new_ty_cs Bag TmCt
new_tm_cs [Type]
strict_arg_tys
String -> SDoc -> DsM ()
tracePm String
"instantiate_cons" ([SDoc] -> SDoc
vcat [ Id -> SDoc
forall a. Outputable a => a -> SDoc
ppr Id
x
, Type -> SDoc
forall a. Outputable a => a -> SDoc
ppr (Id -> Type
idType Id
x)
, Type -> SDoc
forall a. Outputable a => a -> SDoc
ppr Type
ty
, ConLike -> SDoc
forall a. Outputable a => a -> SDoc
ppr ConLike
cl
, [Type] -> SDoc
forall a. Outputable a => a -> SDoc
ppr [Type]
arg_tys
, Bag TmCt -> SDoc
forall a. Outputable a => a -> SDoc
ppr Bag TmCt
new_tm_cs
, Bag Type -> SDoc
forall a. Outputable a => a -> SDoc
ppr Bag Type
new_ty_cs
, [Type] -> SDoc
forall a. Outputable a => a -> SDoc
ppr [Type]
strict_arg_tys
, Delta -> SDoc
forall a. Outputable a => a -> SDoc
ppr Delta
delta
, Maybe Delta -> SDoc
forall a. Outputable a => a -> SDoc
ppr Maybe Delta
mb_delta
, Int -> SDoc
forall a. Outputable a => a -> SDoc
ppr Int
n ])
[Delta]
con_deltas <- case Maybe Delta
mb_delta of
Maybe Delta
Nothing -> [Delta] -> DsM [Delta]
forall (f :: * -> *) a. Applicative f => a -> f a
pure []
Just Delta
delta' -> [Id] -> Int -> Delta -> DsM [Delta]
go [Id]
xs Int
n Delta
delta'
[Delta]
other_cons_deltas <- Id -> Type -> [Id] -> Int -> Delta -> [ConLike] -> DsM [Delta]
instantiate_cons Id
x Type
ty [Id]
xs (Int
n Int -> Int -> Int
forall a. Num a => a -> a -> a
- [Delta] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [Delta]
con_deltas) Delta
delta [ConLike]
cls
[Delta] -> DsM [Delta]
forall (f :: * -> *) a. Applicative f => a -> f a
pure ([Delta]
con_deltas [Delta] -> [Delta] -> [Delta]
forall a. [a] -> [a] -> [a]
++ [Delta]
other_cons_deltas)
pickMinimalCompleteSet :: Delta -> PossibleMatches -> DsM (Maybe ConLikeSet)
pickMinimalCompleteSet :: Delta -> PossibleMatches -> DsM (Maybe ConLikeSet)
pickMinimalCompleteSet Delta
_ PossibleMatches
NoPM = Maybe ConLikeSet -> DsM (Maybe ConLikeSet)
forall (f :: * -> *) a. Applicative f => a -> f a
pure Maybe ConLikeSet
forall a. Maybe a
Nothing
pickMinimalCompleteSet Delta
_ (PM NonEmpty ConLikeSet
clss) = do
String -> SDoc -> DsM ()
tracePm String
"pickMinimalCompleteSet" ([ConLikeSet] -> SDoc
forall a. Outputable a => a -> SDoc
ppr ([ConLikeSet] -> SDoc) -> [ConLikeSet] -> SDoc
forall a b. (a -> b) -> a -> b
$ NonEmpty ConLikeSet -> [ConLikeSet]
forall a. NonEmpty a -> [a]
NonEmpty.toList NonEmpty ConLikeSet
clss)
Maybe ConLikeSet -> DsM (Maybe ConLikeSet)
forall (f :: * -> *) a. Applicative f => a -> f a
pure (ConLikeSet -> Maybe ConLikeSet
forall a. a -> Maybe a
Just ((ConLikeSet -> ConLikeSet -> Ordering)
-> NonEmpty ConLikeSet -> ConLikeSet
forall (t :: * -> *) a.
Foldable t =>
(a -> a -> Ordering) -> t a -> a
minimumBy ((ConLikeSet -> Int) -> ConLikeSet -> ConLikeSet -> Ordering
forall a b. Ord a => (b -> a) -> b -> b -> Ordering
comparing ConLikeSet -> Int
forall a. UniqDSet a -> Int
sizeUniqDSet) NonEmpty ConLikeSet
clss))
representCoreExpr :: Delta -> CoreExpr -> DsM (Delta, Id)
representCoreExpr :: Delta -> CoreExpr -> DsM (Delta, Id)
representCoreExpr delta :: Delta
delta@MkDelta{ delta_tm_st :: Delta -> TmState
delta_tm_st = ts :: TmState
ts@TmSt{ ts_reps :: TmState -> CoreMap Id
ts_reps = CoreMap Id
reps } } CoreExpr
e
| Just Id
rep <- CoreMap Id -> CoreExpr -> Maybe Id
forall a. CoreMap a -> CoreExpr -> Maybe a
lookupCoreMap CoreMap Id
reps CoreExpr
e = (Delta, Id) -> DsM (Delta, Id)
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Delta
delta, Id
rep)
| Bool
otherwise = do
Id
rep <- Type -> DsM Id
mkPmId (CoreExpr -> Type
exprType CoreExpr
e)
let reps' :: CoreMap Id
reps' = CoreMap Id -> CoreExpr -> Id -> CoreMap Id
forall a. CoreMap a -> CoreExpr -> a -> CoreMap a
extendCoreMap CoreMap Id
reps CoreExpr
e Id
rep
let delta' :: Delta
delta' = Delta
delta{ delta_tm_st :: TmState
delta_tm_st = TmState
ts{ ts_reps :: CoreMap Id
ts_reps = CoreMap Id
reps' } }
(Delta, Id) -> DsM (Delta, Id)
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Delta
delta', Id
rep)
addCoreCt :: Delta -> Id -> CoreExpr -> MaybeT DsM Delta
addCoreCt :: Delta -> Id -> CoreExpr -> MaybeT DsM Delta
addCoreCt Delta
delta Id
x CoreExpr
e = do
DynFlags
dflags <- MaybeT DsM DynFlags
forall (m :: * -> *). HasDynFlags m => m DynFlags
getDynFlags
let e' :: CoreExpr
e' = HasDebugCallStack => DynFlags -> CoreExpr -> CoreExpr
DynFlags -> CoreExpr -> CoreExpr
simpleOptExpr DynFlags
dflags CoreExpr
e
DsM () -> MaybeT DsM ()
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (DsM () -> MaybeT DsM ()) -> DsM () -> MaybeT DsM ()
forall a b. (a -> b) -> a -> b
$ String -> SDoc -> DsM ()
tracePm String
"addCoreCt" (Id -> SDoc
forall a. Outputable a => a -> SDoc
ppr Id
x SDoc -> SDoc -> SDoc
$$ CoreExpr -> SDoc
forall a. Outputable a => a -> SDoc
ppr CoreExpr
e SDoc -> SDoc -> SDoc
$$ CoreExpr -> SDoc
forall a. Outputable a => a -> SDoc
ppr CoreExpr
e')
StateT Delta (MaybeT DsM) () -> Delta -> MaybeT DsM Delta
forall (m :: * -> *) s a. Monad m => StateT s m a -> s -> m s
execStateT (Id -> CoreExpr -> StateT Delta (MaybeT DsM) ()
core_expr Id
x CoreExpr
e') Delta
delta
where
core_expr :: Id -> CoreExpr -> StateT Delta (MaybeT DsM) ()
core_expr :: Id -> CoreExpr -> StateT Delta (MaybeT DsM) ()
core_expr Id
x (Cast CoreExpr
e Coercion
_co) = Id -> CoreExpr -> StateT Delta (MaybeT DsM) ()
core_expr Id
x CoreExpr
e
core_expr Id
x (Tick Tickish Id
_t CoreExpr
e) = Id -> CoreExpr -> StateT Delta (MaybeT DsM) ()
core_expr Id
x CoreExpr
e
core_expr Id
x CoreExpr
e
| Just (PmLit -> Maybe FastString
pmLitAsStringLit -> Just FastString
s) <- CoreExpr -> Maybe PmLit
coreExprAsPmLit CoreExpr
e
, Type
expr_ty Type -> Type -> Bool
`eqType` Type
stringTy
= case FastString -> String
unpackFS FastString
s of
[] -> Id
-> InScopeSet
-> DataCon
-> [CoreExpr]
-> StateT Delta (MaybeT DsM) ()
data_con_app Id
x InScopeSet
emptyInScopeSet DataCon
nilDataCon []
String
s' -> Id -> CoreExpr -> StateT Delta (MaybeT DsM) ()
core_expr Id
x (Type -> [CoreExpr] -> CoreExpr
mkListExpr Type
charTy ((Char -> CoreExpr) -> String -> [CoreExpr]
forall a b. (a -> b) -> [a] -> [b]
map Char -> CoreExpr
mkCharExpr String
s'))
| Just PmLit
lit <- CoreExpr -> Maybe PmLit
coreExprAsPmLit CoreExpr
e
= Id -> PmLit -> StateT Delta (MaybeT DsM) ()
pm_lit Id
x PmLit
lit
| Just (InScopeSet
in_scope, _empty_floats :: [FloatBind]
_empty_floats@[], DataCon
dc, [Type]
_arg_tys, [CoreExpr]
args)
<- InScopeEnv
-> CoreExpr
-> Maybe (InScopeSet, [FloatBind], DataCon, [Type], [CoreExpr])
HasDebugCallStack =>
InScopeEnv
-> CoreExpr
-> Maybe (InScopeSet, [FloatBind], DataCon, [Type], [CoreExpr])
exprIsConApp_maybe InScopeEnv
forall {b}. (InScopeSet, b -> Unfolding)
in_scope_env CoreExpr
e
= Id
-> InScopeSet
-> DataCon
-> [CoreExpr]
-> StateT Delta (MaybeT DsM) ()
data_con_app Id
x InScopeSet
in_scope DataCon
dc [CoreExpr]
args
| Var Id
y <- CoreExpr
e, Maybe DataCon
Nothing <- Id -> Maybe DataCon
isDataConId_maybe Id
x
= (Delta -> MaybeT DsM Delta) -> StateT Delta (MaybeT DsM) ()
forall (m :: * -> *) s. Monad m => (s -> m s) -> StateT s m ()
modifyT (\Delta
delta -> Delta -> Id -> Id -> MaybeT DsM Delta
addVarCt Delta
delta Id
x Id
y)
| Bool
otherwise
= Id -> CoreExpr -> StateT Delta (MaybeT DsM) ()
equate_with_similar_expr Id
x CoreExpr
e
where
expr_ty :: Type
expr_ty = CoreExpr -> Type
exprType CoreExpr
e
expr_in_scope :: InScopeSet
expr_in_scope = VarSet -> InScopeSet
mkInScopeSet (CoreExpr -> VarSet
exprFreeVars CoreExpr
e)
in_scope_env :: (InScopeSet, b -> Unfolding)
in_scope_env = (InScopeSet
expr_in_scope, Unfolding -> b -> Unfolding
forall a b. a -> b -> a
const Unfolding
NoUnfolding)
equate_with_similar_expr :: Id -> CoreExpr -> StateT Delta (MaybeT DsM) ()
equate_with_similar_expr :: Id -> CoreExpr -> StateT Delta (MaybeT DsM) ()
equate_with_similar_expr Id
x CoreExpr
e = do
Id
rep <- (Delta -> MaybeT DsM (Id, Delta)) -> StateT Delta (MaybeT DsM) Id
forall s (m :: * -> *) a. (s -> m (a, s)) -> StateT s m a
StateT ((Delta -> MaybeT DsM (Id, Delta)) -> StateT Delta (MaybeT DsM) Id)
-> (Delta -> MaybeT DsM (Id, Delta))
-> StateT Delta (MaybeT DsM) Id
forall a b. (a -> b) -> a -> b
$ \Delta
delta -> (Delta, Id) -> (Id, Delta)
forall a b. (a, b) -> (b, a)
swap ((Delta, Id) -> (Id, Delta))
-> MaybeT DsM (Delta, Id) -> MaybeT DsM (Id, Delta)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> DsM (Delta, Id) -> MaybeT DsM (Delta, Id)
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (Delta -> CoreExpr -> DsM (Delta, Id)
representCoreExpr Delta
delta CoreExpr
e)
(Delta -> MaybeT DsM Delta) -> StateT Delta (MaybeT DsM) ()
forall (m :: * -> *) s. Monad m => (s -> m s) -> StateT s m ()
modifyT (\Delta
delta -> Delta -> Id -> Id -> MaybeT DsM Delta
addVarCt Delta
delta Id
x Id
rep)
bind_expr :: CoreExpr -> StateT Delta (MaybeT DsM) Id
bind_expr :: CoreExpr -> StateT Delta (MaybeT DsM) Id
bind_expr CoreExpr
e = do
Id
x <- MaybeT DsM Id -> StateT Delta (MaybeT DsM) Id
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (DsM Id -> MaybeT DsM Id
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (Type -> DsM Id
mkPmId (CoreExpr -> Type
exprType CoreExpr
e)))
Id -> CoreExpr -> StateT Delta (MaybeT DsM) ()
core_expr Id
x CoreExpr
e
Id -> StateT Delta (MaybeT DsM) Id
forall (f :: * -> *) a. Applicative f => a -> f a
pure Id
x
data_con_app :: Id -> InScopeSet -> DataCon -> [CoreExpr] -> StateT Delta (MaybeT DsM) ()
data_con_app :: Id
-> InScopeSet
-> DataCon
-> [CoreExpr]
-> StateT Delta (MaybeT DsM) ()
data_con_app Id
x InScopeSet
in_scope DataCon
dc [CoreExpr]
args = do
let dc_ex_tvs :: [Id]
dc_ex_tvs = DataCon -> [Id]
dataConExTyCoVars DataCon
dc
arty :: Int
arty = DataCon -> Int
dataConSourceArity DataCon
dc
([CoreExpr]
ex_ty_args, [CoreExpr]
val_args) = [Id] -> [CoreExpr] -> ([CoreExpr], [CoreExpr])
forall b a. [b] -> [a] -> ([a], [a])
splitAtList [Id]
dc_ex_tvs [CoreExpr]
args
ex_tys :: [Type]
ex_tys = (CoreExpr -> Type) -> [CoreExpr] -> [Type]
forall a b. (a -> b) -> [a] -> [b]
map CoreExpr -> Type
exprToType [CoreExpr]
ex_ty_args
vis_args :: [CoreExpr]
vis_args = [CoreExpr] -> [CoreExpr]
forall a. [a] -> [a]
reverse ([CoreExpr] -> [CoreExpr]) -> [CoreExpr] -> [CoreExpr]
forall a b. (a -> b) -> a -> b
$ Int -> [CoreExpr] -> [CoreExpr]
forall a. Int -> [a] -> [a]
take Int
arty ([CoreExpr] -> [CoreExpr]) -> [CoreExpr] -> [CoreExpr]
forall a b. (a -> b) -> a -> b
$ [CoreExpr] -> [CoreExpr]
forall a. [a] -> [a]
reverse [CoreExpr]
val_args
UniqSupply
uniq_supply <- MaybeT DsM UniqSupply -> StateT Delta (MaybeT DsM) UniqSupply
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (MaybeT DsM UniqSupply -> StateT Delta (MaybeT DsM) UniqSupply)
-> MaybeT DsM UniqSupply -> StateT Delta (MaybeT DsM) UniqSupply
forall a b. (a -> b) -> a -> b
$ IOEnv (Env DsGblEnv DsLclEnv) UniqSupply -> MaybeT DsM UniqSupply
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (IOEnv (Env DsGblEnv DsLclEnv) UniqSupply -> MaybeT DsM UniqSupply)
-> IOEnv (Env DsGblEnv DsLclEnv) UniqSupply
-> MaybeT DsM UniqSupply
forall a b. (a -> b) -> a -> b
$ IOEnv (Env DsGblEnv DsLclEnv) UniqSupply
forall (m :: * -> *). MonadUnique m => m UniqSupply
getUniqueSupplyM
let (TCvSubst
_, [Id]
ex_tvs) = TCvSubst -> [Id] -> UniqSupply -> (TCvSubst, [Id])
cloneTyVarBndrs (InScopeSet -> TCvSubst
mkEmptyTCvSubst InScopeSet
in_scope) [Id]
dc_ex_tvs UniqSupply
uniq_supply
ty_cts :: [PmCt]
ty_cts = [Type] -> [Type] -> [PmCt]
equateTys ((Id -> Type) -> [Id] -> [Type]
forall a b. (a -> b) -> [a] -> [b]
map Id -> Type
mkTyVarTy [Id]
ex_tvs) [Type]
ex_tys
(Delta -> MaybeT DsM Delta) -> StateT Delta (MaybeT DsM) ()
forall (m :: * -> *) s. Monad m => (s -> m s) -> StateT s m ()
modifyT ((Delta -> MaybeT DsM Delta) -> StateT Delta (MaybeT DsM) ())
-> (Delta -> MaybeT DsM Delta) -> StateT Delta (MaybeT DsM) ()
forall a b. (a -> b) -> a -> b
$ \Delta
delta -> DsM (Maybe Delta) -> MaybeT DsM Delta
forall (m :: * -> *) a. m (Maybe a) -> MaybeT m a
MaybeT (DsM (Maybe Delta) -> MaybeT DsM Delta)
-> DsM (Maybe Delta) -> MaybeT DsM Delta
forall a b. (a -> b) -> a -> b
$ Delta -> PmCts -> DsM (Maybe Delta)
addPmCts Delta
delta ([PmCt] -> PmCts
forall a. [a] -> Bag a
listToBag [PmCt]
ty_cts)
[Id]
arg_ids <- (CoreExpr -> StateT Delta (MaybeT DsM) Id)
-> [CoreExpr] -> StateT Delta (MaybeT DsM) [Id]
forall (t :: * -> *) (f :: * -> *) a b.
(Traversable t, Applicative f) =>
(a -> f b) -> t a -> f (t b)
traverse CoreExpr -> StateT Delta (MaybeT DsM) Id
bind_expr [CoreExpr]
vis_args
Id -> PmAltCon -> [Id] -> [Id] -> StateT Delta (MaybeT DsM) ()
pm_alt_con_app Id
x (ConLike -> PmAltCon
PmAltConLike (DataCon -> ConLike
RealDataCon DataCon
dc)) [Id]
ex_tvs [Id]
arg_ids
pm_lit :: Id -> PmLit -> StateT Delta (MaybeT DsM) ()
pm_lit :: Id -> PmLit -> StateT Delta (MaybeT DsM) ()
pm_lit Id
x PmLit
lit = Id -> PmAltCon -> [Id] -> [Id] -> StateT Delta (MaybeT DsM) ()
pm_alt_con_app Id
x (PmLit -> PmAltCon
PmAltLit PmLit
lit) [] []
pm_alt_con_app :: Id -> PmAltCon -> [TyVar] -> [Id] -> StateT Delta (MaybeT DsM) ()
pm_alt_con_app :: Id -> PmAltCon -> [Id] -> [Id] -> StateT Delta (MaybeT DsM) ()
pm_alt_con_app Id
x PmAltCon
con [Id]
tvs [Id]
args = (Delta -> MaybeT DsM Delta) -> StateT Delta (MaybeT DsM) ()
forall (m :: * -> *) s. Monad m => (s -> m s) -> StateT s m ()
modifyT ((Delta -> MaybeT DsM Delta) -> StateT Delta (MaybeT DsM) ())
-> (Delta -> MaybeT DsM Delta) -> StateT Delta (MaybeT DsM) ()
forall a b. (a -> b) -> a -> b
$ \Delta
delta -> Delta -> Id -> PmAltCon -> [Id] -> [Id] -> MaybeT DsM Delta
addConCt Delta
delta Id
x PmAltCon
con [Id]
tvs [Id]
args
modifyT :: Monad m => (s -> m s) -> StateT s m ()
modifyT :: forall (m :: * -> *) s. Monad m => (s -> m s) -> StateT s m ()
modifyT s -> m s
f = (s -> m ((), s)) -> StateT s m ()
forall s (m :: * -> *) a. (s -> m (a, s)) -> StateT s m a
StateT ((s -> m ((), s)) -> StateT s m ())
-> (s -> m ((), s)) -> StateT s m ()
forall a b. (a -> b) -> a -> b
$ (s -> ((), s)) -> m s -> m ((), s)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap ((,) ()) (m s -> m ((), s)) -> (s -> m s) -> s -> m ((), s)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. s -> m s
f