{-# LANGUAGE CPP #-}
{-# LANGUAGE BlockArguments #-}
{-# LANGUAGE ViewPatterns #-}
{-# LANGUAGE MultiWayIf #-}
{-# LANGUAGE TupleSections #-}
{-# LANGUAGE DerivingVia #-}
{-# OPTIONS_GHC -Wno-x-partial -Wno-incomplete-uni-patterns -Wno-unused-imports #-}
module Stock.Internal (module Stock.Internal) where
import GHC.Plugins hiding (TcPlugin)
import GHC.Tc.Plugin
import GHC.Tc.Types
import GHC.Tc.Types.Constraint
#if MIN_VERSION_ghc(9,12,0)
import GHC.Tc.Types.CtLoc (CtLoc)
#else
import GHC.Tc.Types.Constraint (CtLoc)
#endif
import GHC.Tc.Types.Evidence
import GHC.Tc.Utils.Monad (addErrTc)
import GHC.Tc.Errors.Types (mkTcRnUnknownMessage)
import GHC.Types.Error (mkPlainError, noHints)
import GHC.Core.Class (Class, className, classMethods, classOpItems, classTyCon)
import GHC.Core.Predicate (classifyPredType, Pred(ClassPred), mkClassPred)
#if MIN_VERSION_ghc(9,14,0)
import GHC.Core.Predicate (mkReprEqPred)
#else
import GHC.Core.Predicate (mkReprPrimEqPred)
#endif
import GHC.Builtin.Types (promotedConsDataCon, promotedNilDataCon, unitTy)
import GHC.Builtin.Types.Prim (intPrimTy)
import GHC.Builtin.PrimOps (PrimOp(TagToEnumOp))
import GHC.Builtin.PrimOps.Ids (primOpId)
import GHC.Builtin.Names ( eqClassName, ordClassName, appendName
, enumClassName, mapName, numClassName
, enumFromToName, enumFromThenToName
, eqStringName
, genClassName, repTyConName, u1TyConName, k1TyConName
, prodTyConName, sumTyConName
, monoidClassName, foldableClassName, functorClassName
, semigroupClassName, monadClassName )
import Stock.Compat ( gHC_INTERNAL_SHOW, gHC_INTERNAL_READ
, gHC_INTERNAL_LIST, gHC_INTERNAL_GENERICS
, tEXT_READPREC, tEXT_READ_LEX )
import GHC.Core.Reduction (mkReduction)
import GHC.Core.TyCo.Rep (UnivCoProvenance(PluginProv))
import GHC.Rename.Fixity (lookupFixityRn)
import GHC.Types.Fixity (Fixity(..), defaultFixity, FixityDirection(..))
import GHC.Types.SourceText (SourceText(NoSourceText))
import GHC.Core.DataCon (dataConSrcBangs, dataConImplBangs, HsSrcBang(..), HsImplBang(..), SrcStrictness(..), SrcUnpackedness(..))
import GHC.Core.TyCo.Compare (eqType)
import GHC.Core.Multiplicity (scaledThing)
import GHC.Core.SimpleOpt (defaultSimpleOpts)
import GHC.Core.Unfold.Make (mkInlineUnfoldingWithArity)
import GHC.Core.InstEnv (classInstances, is_dfun, is_tys)
import GHC.Runtime.Loader (getValueSafely)
import Stock.Derive
import Data.Maybe (catMaybes, fromJust, isJust, fromMaybe, listToMaybe)
import Data.List (zipWith4)
import Data.Traversable (for)
import qualified Data.Monoid as Mon (Alt(..))
import Stock.Trans (MaybeT(..))
import Control.Monad (zipWithM, unless, guard)
import Data.IORef (IORef, newIORef, readIORef, modifyIORef')
data GenEnv = GenEnv
{ GenEnv -> Maybe TyCon
geStock :: Maybe TyCon
, GenEnv -> Maybe TyCon
geStock1 :: Maybe TyCon
, GenEnv -> Maybe TyCon
geStock2 :: Maybe TyCon
, GenEnv -> Maybe Class
geWitness :: Maybe Class
, GenEnv -> Class
geGen :: Class
, GenEnv -> TyCon
geRepTc :: TyCon
, GenEnv -> TyCon
geU1Tc :: TyCon
, GenEnv -> TyCon
geK1Tc :: TyCon
, GenEnv -> TyCon
geProdTc :: TyCon
, GenEnv -> DataCon
geProdDc :: DataCon
, GenEnv -> TyCon
geSumTc :: TyCon
, GenEnv -> MetaEnv
geMeta :: MetaEnv
, GenEnv -> Gen1Env
geGen1 :: Gen1Env
, GenEnv -> Type
geRTy :: Type
, GenEnv -> Maybe TyCon
geOverride :: Maybe TyCon
, GenEnv -> Maybe TyCon
geAssign :: Maybe TyCon
, GenEnv -> Maybe TyCon
geAt :: Maybe TyCon
, GenEnv -> Maybe TyCon
geKeep :: Maybe TyCon
, GenEnv -> Maybe TyCon
geArrow :: Maybe TyCon
, GenEnv -> Maybe Class
geWitness1 :: Maybe Class
, GenEnv -> Maybe Class
geWitness2 :: Maybe Class
, GenEnv -> Maybe TyCon
geOverride2 :: Maybe TyCon
, GenEnv -> Maybe TyCon
geOverride1 :: Maybe TyCon
}
data MetaEnv = MetaEnv
{ MetaEnv -> TyCon
meM1 :: TyCon
, MetaEnv -> Type
meD, MetaEnv -> Type
meC, MetaEnv -> Type
meS :: Type
, MetaEnv -> TyCon
meMetaData :: TyCon
, MetaEnv -> TyCon
meMetaCons :: TyCon
, MetaEnv -> TyCon
meMetaSel :: TyCon
, MetaEnv -> Type
mePrefixI :: Type
, MetaEnv -> TyCon
meInfixI :: TyCon
, MetaEnv -> Type
meLeftAssoc, MetaEnv -> Type
meRightAssoc, MetaEnv -> Type
meNotAssoc :: Type
, MetaEnv -> Type
meNoUnpack, MetaEnv -> Type
meSrcNoUnpack, MetaEnv -> Type
meSrcUnpack :: Type
, MetaEnv -> Type
meNoStrict, MetaEnv -> Type
meSrcLazy, MetaEnv -> Type
meSrcStrict :: Type
, MetaEnv -> Type
meDecidedLazy, MetaEnv -> Type
meDecidedStrict, MetaEnv -> Type
meDecidedUnpack :: Type
, MetaEnv -> TyCon
meJustSym :: TyCon
, MetaEnv -> Type
meNothingSym :: Type
}
data Gen1Env = Gen1Env
{ Gen1Env -> TyCon
g1RepTc :: TyCon
, Gen1Env -> TyCon
g1Par1Tc :: TyCon
, Gen1Env -> TyCon
g1Rec1Tc :: TyCon
, Gen1Env -> TyCon
g1CompTc :: TyCon
}
data PluginState = PluginState
{ PluginState -> IORef [String]
psSeen :: IORef [String]
, PluginState -> GenEnv
psGen :: GenEnv
}
andE :: [CoreExpr] -> TcPluginM CoreExpr
andE :: [CoreExpr] -> TcPluginM CoreExpr
andE [] = CoreExpr -> TcPluginM CoreExpr
forall a. a -> TcPluginM a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Id -> CoreExpr
forall b. Id -> Expr b
Var (DataCon -> Id
dataConWorkId DataCon
trueDataCon))
andE [CoreExpr
a] = CoreExpr -> TcPluginM CoreExpr
forall a. a -> TcPluginM a
forall (f :: * -> *) a. Applicative f => a -> f a
pure CoreExpr
a
andE (CoreExpr
a:[CoreExpr]
as) = do
r <- [CoreExpr] -> TcPluginM CoreExpr
andE [CoreExpr]
as
scr <- freshId boolTy "c"
pure (Case a scr boolTy [ Alt (DataAlt falseDataCon) [] (Var (dataConWorkId falseDataCon))
, Alt (DataAlt trueDataCon) [] r ])
lookupTyConMaybe :: String -> String -> TcPluginM (Maybe TyCon)
lookupTyConMaybe :: String -> String -> TcPluginM (Maybe TyCon)
lookupTyConMaybe String
modName String
occ = do
res <- ModuleName -> PkgQual -> TcPluginM FindResult
findImportedModule (String -> ModuleName
mkModuleName String
modName) PkgQual
NoPkgQual
case res of
Found ModLocation
_ Module
m -> TyCon -> Maybe TyCon
forall a. a -> Maybe a
Just (TyCon -> Maybe TyCon)
-> TcPluginM TyCon -> TcPluginM (Maybe TyCon)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (Module -> OccName -> TcPluginM Name
lookupOrig Module
m (String -> OccName
mkTcOcc String
occ) TcPluginM Name -> (Name -> TcPluginM TyCon) -> TcPluginM TyCon
forall a b. TcPluginM a -> (a -> TcPluginM b) -> TcPluginM b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= Name -> TcPluginM TyCon
tcLookupTyCon)
FindResult
_ -> Maybe TyCon -> TcPluginM (Maybe TyCon)
forall a. a -> TcPluginM a
forall (f :: * -> *) a. Applicative f => a -> f a
pure Maybe TyCon
forall a. Maybe a
Nothing
lookupMetaEnv :: TcPluginM MetaEnv
lookupMetaEnv :: TcPluginM MetaEnv
lookupMetaEnv = do
let gTc :: String -> TcPluginM TyCon
gTc String
occ = Module -> OccName -> TcPluginM Name
lookupOrig Module
gHC_INTERNAL_GENERICS (String -> OccName
mkTcOcc String
occ) TcPluginM Name -> (Name -> TcPluginM TyCon) -> TcPluginM TyCon
forall a b. TcPluginM a -> (a -> TcPluginM b) -> TcPluginM b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= Name -> TcPluginM TyCon
tcLookupTyCon
gDc :: String -> TcPluginM DataCon
gDc String
occ = Module -> OccName -> TcPluginM Name
lookupOrig Module
gHC_INTERNAL_GENERICS (String -> OccName
mkDataOcc String
occ) TcPluginM Name -> (Name -> TcPluginM DataCon) -> TcPluginM DataCon
forall a b. TcPluginM a -> (a -> TcPluginM b) -> TcPluginM b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= Name -> TcPluginM DataCon
tcLookupDataCon
promTy :: String -> TcPluginM Type
promTy = (DataCon -> Type) -> TcPluginM DataCon -> TcPluginM Type
forall a b. (a -> b) -> TcPluginM a -> TcPluginM b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (TyCon -> Type
mkTyConTy (TyCon -> Type) -> (DataCon -> TyCon) -> DataCon -> Type
forall b c a. (b -> c) -> (a -> b) -> a -> c
. DataCon -> TyCon
promoteDataCon) (TcPluginM DataCon -> TcPluginM Type)
-> (String -> TcPluginM DataCon) -> String -> TcPluginM Type
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> TcPluginM DataCon
gDc
m1 <- String -> TcPluginM TyCon
gTc String
"M1"
dT <- mkTyConTy <$> gTc "D" ; cT <- mkTyConTy <$> gTc "C" ; sT <- mkTyConTy <$> gTc "S"
md <- promoteDataCon <$> gDc "MetaData"
mc <- promoteDataCon <$> gDc "MetaCons"
ms <- promoteDataCon <$> gDc "MetaSel"
pfx <- promTy "PrefixI"
inI <- promoteDataCon <$> gDc "InfixI"
la <- promTy "LeftAssociative" ; ra <- promTy "RightAssociative" ; na <- promTy "NotAssociative"
nu <- promTy "NoSourceUnpackedness" ; snu <- promTy "SourceNoUnpack" ; su <- promTy "SourceUnpack"
ns <- promTy "NoSourceStrictness" ; sl <- promTy "SourceLazy" ; ss <- promTy "SourceStrict"
dl <- promTy "DecidedLazy" ; ds <- promTy "DecidedStrict" ; du <- promTy "DecidedUnpack"
pure MetaEnv { meM1 = m1, meD = dT, meC = cT, meS = sT
, meMetaData = md, meMetaCons = mc, meMetaSel = ms
, mePrefixI = pfx, meInfixI = inI
, meLeftAssoc = la, meRightAssoc = ra, meNotAssoc = na
, meNoUnpack = nu, meSrcNoUnpack = snu, meSrcUnpack = su
, meNoStrict = ns, meSrcLazy = sl, meSrcStrict = ss
, meDecidedLazy = dl, meDecidedStrict = ds, meDecidedUnpack = du
, meJustSym = promotedJustDataCon
, meNothingSym = mkTyConApp promotedNothingDataCon [typeSymbolKind] }
lookupGen1Env :: TcPluginM Gen1Env
lookupGen1Env :: TcPluginM Gen1Env
lookupGen1Env = do
let gTc :: String -> TcPluginM TyCon
gTc String
occ = Module -> OccName -> TcPluginM Name
lookupOrig Module
gHC_INTERNAL_GENERICS (String -> OccName
mkTcOcc String
occ) TcPluginM Name -> (Name -> TcPluginM TyCon) -> TcPluginM TyCon
forall a b. TcPluginM a -> (a -> TcPluginM b) -> TcPluginM b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= Name -> TcPluginM TyCon
tcLookupTyCon
TyCon -> TyCon -> TyCon -> TyCon -> Gen1Env
Gen1Env (TyCon -> TyCon -> TyCon -> TyCon -> Gen1Env)
-> TcPluginM TyCon
-> TcPluginM (TyCon -> TyCon -> TyCon -> Gen1Env)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> String -> TcPluginM TyCon
gTc String
"Rep1" TcPluginM (TyCon -> TyCon -> TyCon -> Gen1Env)
-> TcPluginM TyCon -> TcPluginM (TyCon -> TyCon -> Gen1Env)
forall a b. TcPluginM (a -> b) -> TcPluginM a -> TcPluginM b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> String -> TcPluginM TyCon
gTc String
"Par1" TcPluginM (TyCon -> TyCon -> Gen1Env)
-> TcPluginM TyCon -> TcPluginM (TyCon -> Gen1Env)
forall a b. TcPluginM (a -> b) -> TcPluginM a -> TcPluginM b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> String -> TcPluginM TyCon
gTc String
"Rec1" TcPluginM (TyCon -> Gen1Env)
-> TcPluginM TyCon -> TcPluginM Gen1Env
forall a b. TcPluginM (a -> b) -> TcPluginM a -> TcPluginM b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> String -> TcPluginM TyCon
gTc String
":.:"
lookupClassMaybe :: String -> String -> TcPluginM (Maybe Class)
lookupClassMaybe :: String -> String -> TcPluginM (Maybe Class)
lookupClassMaybe String
modName String
occ = do
res <- ModuleName -> PkgQual -> TcPluginM FindResult
findImportedModule (String -> ModuleName
mkModuleName String
modName) PkgQual
NoPkgQual
case res of
Found ModLocation
_ Module
m -> Class -> Maybe Class
forall a. a -> Maybe a
Just (Class -> Maybe Class)
-> TcPluginM Class -> TcPluginM (Maybe Class)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (Module -> OccName -> TcPluginM Name
lookupOrig Module
m (String -> OccName
mkTcOcc String
occ) TcPluginM Name -> (Name -> TcPluginM Class) -> TcPluginM Class
forall a b. TcPluginM a -> (a -> TcPluginM b) -> TcPluginM b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= Name -> TcPluginM Class
tcLookupClass)
FindResult
_ -> Maybe Class -> TcPluginM (Maybe Class)
forall a. a -> TcPluginM a
forall (f :: * -> *) a. Applicative f => a -> f a
pure Maybe Class
forall a. Maybe a
Nothing
lookupIdMaybe :: String -> String -> TcPluginM (Maybe Id)
lookupIdMaybe :: String -> String -> TcPluginM (Maybe Id)
lookupIdMaybe String
modName String
occ = do
res <- ModuleName -> PkgQual -> TcPluginM FindResult
findImportedModule (String -> ModuleName
mkModuleName String
modName) PkgQual
NoPkgQual
case res of
Found ModLocation
_ Module
m -> Id -> Maybe Id
forall a. a -> Maybe a
Just (Id -> Maybe Id) -> TcPluginM Id -> TcPluginM (Maybe Id)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (Module -> OccName -> TcPluginM Name
lookupOrig Module
m (String -> OccName
mkVarOcc String
occ) TcPluginM Name -> (Name -> TcPluginM Id) -> TcPluginM Id
forall a b. TcPluginM a -> (a -> TcPluginM b) -> TcPluginM b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= Name -> TcPluginM Id
tcLookupId)
FindResult
_ -> Maybe Id -> TcPluginM (Maybe Id)
forall a. a -> TcPluginM a
forall (f :: * -> *) a. Applicative f => a -> f a
pure Maybe Id
forall a. Maybe a
Nothing
repData :: GenEnv -> [[Type]] -> Type
repData :: GenEnv -> [[Type]] -> Type
repData GenEnv
gen [[Type]
fts] = GenEnv -> [Type] -> Type
repStruct GenEnv
gen [Type]
fts
repData GenEnv
gen [[Type]]
ftss = (Type -> Type -> Type) -> [Type] -> Type
forall a. (a -> a -> a) -> [a] -> a
foldBal Type -> Type -> Type
sumOf (([Type] -> Type) -> [[Type]] -> [Type]
forall a b. (a -> b) -> [a] -> [b]
map (GenEnv -> [Type] -> Type
repStruct GenEnv
gen) [[Type]]
ftss) where
sumOf :: Type -> Type -> Type
sumOf :: Type -> Type -> Type
sumOf Type
f Type
g = TyCon -> [Type] -> Type
mkTyConApp (GenEnv -> TyCon
geSumTc GenEnv
gen) [Type
liftedTypeKind, Type
f, Type
g]
rec0Of :: GenEnv -> Type -> Type
rec0Of :: GenEnv -> Type -> Type
rec0Of GenEnv
gen Type
t = TyCon -> [Type] -> Type
mkTyConApp (GenEnv -> TyCon
geK1Tc GenEnv
gen) [Type
liftedTypeKind, GenEnv -> Type
geRTy GenEnv
gen, Type
t]
repMeta :: GenEnv -> (DataCon -> Type) -> Type -> [DataCon] -> Type
repMeta :: GenEnv -> (DataCon -> Type) -> Type -> [DataCon] -> Type
repMeta GenEnv
gen DataCon -> Type
fixOf Type
innerTy [DataCon]
dcons =
GenEnv
-> (DataCon -> Type)
-> (Type -> Type)
-> Type
-> [(DataCon, [Type])]
-> Type
repMetaWith GenEnv
gen DataCon -> Type
fixOf (GenEnv -> Type -> Type
rec0Of GenEnv
gen) Type
innerTy [ (DataCon
dc, Type -> DataCon -> [Type]
fieldTysAt Type
innerTy DataCon
dc) | DataCon
dc <- [DataCon]
dcons ]
repMetaFts :: GenEnv -> (DataCon -> Type) -> Type -> [(DataCon, [Type])] -> Type
repMetaFts :: GenEnv -> (DataCon -> Type) -> Type -> [(DataCon, [Type])] -> Type
repMetaFts GenEnv
gen DataCon -> Type
fixOf = GenEnv
-> (DataCon -> Type)
-> (Type -> Type)
-> Type
-> [(DataCon, [Type])]
-> Type
repMetaWith GenEnv
gen DataCon -> Type
fixOf (GenEnv -> Type -> Type
rec0Of GenEnv
gen)
repMetaWith :: GenEnv -> (DataCon -> Type) -> (Type -> Type) -> Type -> [(DataCon, [Type])] -> Type
repMetaWith :: GenEnv
-> (DataCon -> Type)
-> (Type -> Type)
-> Type
-> [(DataCon, [Type])]
-> Type
repMetaWith GenEnv
gen DataCon -> Type
fixOf Type -> Type
leaf Type
innerTy [(DataCon, [Type])]
cons =
Type -> Type -> Type
d1 (TyCon -> Type
metaData TyCon
innerTc) ((Type -> Type -> Type) -> [Type] -> Type
forall a. (a -> a -> a) -> [a] -> a
foldBal Type -> Type -> Type
sumTy (((DataCon, [Type]) -> Type) -> [(DataCon, [Type])] -> [Type]
forall a b. (a -> b) -> [a] -> [b]
map (DataCon, [Type]) -> Type
conRep [(DataCon, [Type])]
cons)) where
me :: MetaEnv
me = GenEnv -> MetaEnv
geMeta GenEnv
gen
innerTc :: TyCon
innerTc = HasDebugCallStack => Type -> TyCon
Type -> TyCon
tyConAppTyCon Type
innerTy
kTy :: Type
kTy = Type
liftedTypeKind
m1 :: Type -> Type -> Type -> Type
m1 Type
i Type
c Type
f = TyCon -> [Type] -> Type
mkTyConApp (MetaEnv -> TyCon
meM1 MetaEnv
me) [Type
kTy, Type
i, Type
c, Type
f]
d1 :: Type -> Type -> Type
d1 = Type -> Type -> Type -> Type
m1 (MetaEnv -> Type
meD MetaEnv
me) ; c1 :: Type -> Type -> Type
c1 = Type -> Type -> Type -> Type
m1 (MetaEnv -> Type
meC MetaEnv
me) ; s1 :: Type -> Type -> Type
s1 = Type -> Type -> Type -> Type
m1 (MetaEnv -> Type
meS MetaEnv
me)
sumTy :: Type -> Type -> Type
sumTy Type
a Type
b = TyCon -> [Type] -> Type
mkTyConApp (GenEnv -> TyCon
geSumTc GenEnv
gen) [Type
kTy, Type
a, Type
b]
prodTy :: Type -> Type -> Type
prodTy Type
a Type
b = TyCon -> [Type] -> Type
mkTyConApp (GenEnv -> TyCon
geProdTc GenEnv
gen) [Type
kTy, Type
a, Type
b]
u1 :: Type
u1 = TyCon -> [Type] -> Type
mkTyConApp (GenEnv -> TyCon
geU1Tc GenEnv
gen) [Type
kTy]
strLit :: String -> Type
strLit = FastString -> Type
mkStrLitTy (FastString -> Type) -> (String -> FastString) -> String -> Type
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> FastString
fsLit
boolT :: Bool -> Type
boolT Bool
b = TyCon -> Type
mkTyConTy (if Bool
b then TyCon
promotedTrueDataCon else TyCon
promotedFalseDataCon)
metaData :: TyCon -> Type
metaData TyCon
tc = TyCon -> [Type] -> Type
mkTyConApp (MetaEnv -> TyCon
meMetaData MetaEnv
me)
[ String -> Type
strLit (OccName -> String
occNameString (Name -> OccName
nameOccName (TyCon -> Name
tyConName TyCon
tc)))
, String -> Type
strLit (ModuleName -> String
moduleNameString (Module -> ModuleName
forall unit. GenModule unit -> ModuleName
moduleName Module
modu))
, String -> Type
strLit (Unit -> String
forall u. IsUnitId u => u -> String
unitString (Module -> Unit
forall unit. GenModule unit -> unit
moduleUnit Module
modu))
, Bool -> Type
boolT (TyCon -> Bool
isNewTyCon TyCon
tc) ]
where modu :: Module
modu = HasDebugCallStack => Name -> Module
Name -> Module
nameModule (TyCon -> Name
tyConName TyCon
tc)
metaCons :: DataCon -> Type
metaCons DataCon
dc = TyCon -> [Type] -> Type
mkTyConApp (MetaEnv -> TyCon
meMetaCons MetaEnv
me)
[ String -> Type
strLit (OccName -> String
occNameString (DataCon -> OccName
forall a. NamedThing a => a -> OccName
getOccName DataCon
dc))
, DataCon -> Type
fixOf DataCon
dc
, Bool -> Type
boolT (Bool -> Bool
not ([FieldLabel] -> Bool
forall a. [a] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null (DataCon -> [FieldLabel]
dataConFieldLabels DataCon
dc))) ]
metaSel :: Maybe String -> (Type, Type, Type) -> Type
metaSel Maybe String
mnm (Type
suT, Type
ssT, Type
dsT) = TyCon -> [Type] -> Type
mkTyConApp (MetaEnv -> TyCon
meMetaSel MetaEnv
me)
[ Type -> (String -> Type) -> Maybe String -> Type
forall b a. b -> (a -> b) -> Maybe a -> b
maybe (MetaEnv -> Type
meNothingSym MetaEnv
me)
(\String
nm -> TyCon -> [Type] -> Type
mkTyConApp (MetaEnv -> TyCon
meJustSym MetaEnv
me) [Type
typeSymbolKind, String -> Type
strLit String
nm]) Maybe String
mnm
, Type
suT, Type
ssT, Type
dsT ]
selStr :: DataCon -> Int -> (Type, Type, Type)
selStr DataCon
dc Int
i = case if Int
i Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< [HsImplBang] -> Int
forall a. [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [HsImplBang]
implB then [HsImplBang]
implB [HsImplBang] -> Int -> HsImplBang
forall a. HasCallStack => [a] -> Int -> a
!! Int
i else HsImplBang
HsLazy of
HsImplBang
HsLazy -> (MetaEnv -> Type
meNoUnpack MetaEnv
me, MetaEnv -> Type
meNoStrict MetaEnv
me, MetaEnv -> Type
meDecidedLazy MetaEnv
me)
HsStrict Bool
_ -> (MetaEnv -> Type
meNoUnpack MetaEnv
me, MetaEnv -> Type
meSrcStrict MetaEnv
me, MetaEnv -> Type
meDecidedStrict MetaEnv
me)
HsUnpack Maybe Coercion
_ -> (MetaEnv -> Type
meSrcUnpack MetaEnv
me, MetaEnv -> Type
meSrcStrict MetaEnv
me, MetaEnv -> Type
meDecidedUnpack MetaEnv
me)
where implB :: [HsImplBang]
implB = DataCon -> [HsImplBang]
dataConImplBangs DataCon
dc
conRep :: (DataCon, [Type]) -> Type
conRep (DataCon
dc, [Type]
fts) = Type -> Type -> Type
c1 (DataCon -> Type
metaCons DataCon
dc) Type
prod
where labels :: [FieldLabel]
labels = DataCon -> [FieldLabel]
dataConFieldLabels DataCon
dc
nameAt :: Int -> Maybe String
nameAt Int
i | [FieldLabel] -> Bool
forall a. [a] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [FieldLabel]
labels = Maybe String
forall a. Maybe a
Nothing
| Bool
otherwise = String -> Maybe String
forall a. a -> Maybe a
Just (OccName -> String
occNameString (Name -> OccName
nameOccName (FieldLabel -> Name
flSelector ([FieldLabel]
labels [FieldLabel] -> Int -> FieldLabel
forall a. HasCallStack => [a] -> Int -> a
!! Int
i))))
prod :: Type
prod = case [Type]
fts of
[] -> Type
u1
[Type]
_ -> (Type -> Type -> Type) -> [Type] -> Type
forall a. (a -> a -> a) -> [a] -> a
foldBal Type -> Type -> Type
prodTy
[ Type -> Type -> Type
s1 (Maybe String -> (Type, Type, Type) -> Type
metaSel (Int -> Maybe String
nameAt Int
i) (DataCon -> Int -> (Type, Type, Type)
selStr DataCon
dc Int
i)) (Type -> Type
leaf Type
ft)
| (Int
i, Type
ft) <- [Int] -> [Type] -> [(Int, Type)]
forall a b. [a] -> [b] -> [(a, b)]
zip [Int
0 :: Int ..] [Type]
fts ]
fixityParts :: Fixity -> (Int, FixityDirection)
#if MIN_VERSION_ghc(9,12,0)
fixityParts (Fixity p d) = (p, d)
#else
fixityParts :: Fixity -> (Int, FixityDirection)
fixityParts (Fixity SourceText
_ Int
p FixityDirection
d) = (Int
p, FixityDirection
d)
#endif
conFixityTy :: MetaEnv -> DataCon -> TcPluginM Type
conFixityTy :: MetaEnv -> DataCon -> TcPluginM Type
conFixityTy MetaEnv
me DataCon
dc
| DataCon -> Bool
dataConIsInfix DataCon
dc = do
fx <- TcM Fixity -> TcPluginM Fixity
forall a. TcM a -> TcPluginM a
unsafeTcPluginTcM (Name -> TcM Fixity
lookupFixityRn (DataCon -> Name
dataConName DataCon
dc))
let (prec, dir) = fixityParts fx
assoc = case FixityDirection
dir of FixityDirection
InfixL -> MetaEnv -> Type
meLeftAssoc MetaEnv
me; FixityDirection
InfixR -> MetaEnv -> Type
meRightAssoc MetaEnv
me; FixityDirection
InfixN -> MetaEnv -> Type
meNotAssoc MetaEnv
me
pure (mkTyConApp (meInfixI me) [assoc, mkNumLitTy (fromIntegral prec)])
| Bool
otherwise = Type -> TcPluginM Type
forall a. a -> TcPluginM a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (MetaEnv -> Type
mePrefixI MetaEnv
me)
mkFixOf :: MetaEnv -> [DataCon] -> TcPluginM (DataCon -> Type)
mkFixOf :: MetaEnv -> [DataCon] -> TcPluginM (DataCon -> Type)
mkFixOf MetaEnv
me [DataCon]
dcs = do
tys <- (DataCon -> TcPluginM Type) -> [DataCon] -> TcPluginM [Type]
forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
forall (m :: * -> *) a b. Monad m => (a -> m b) -> [a] -> m [b]
mapM (MetaEnv -> DataCon -> TcPluginM Type
conFixityTy MetaEnv
me) [DataCon]
dcs
let m = [Unique] -> [Type] -> [(Unique, Type)]
forall a b. [a] -> [b] -> [(a, b)]
zip ((DataCon -> Unique) -> [DataCon] -> [Unique]
forall a b. (a -> b) -> [a] -> [b]
map DataCon -> Unique
forall a. Uniquable a => a -> Unique
getUnique [DataCon]
dcs) [Type]
tys
pure (\DataCon
dc -> Type -> Maybe Type -> Type
forall a. a -> Maybe a -> a
fromMaybe (MetaEnv -> Type
mePrefixI MetaEnv
me) (Unique -> [(Unique, Type)] -> Maybe Type
forall a b. Eq a => a -> [(a, b)] -> Maybe b
lookup (DataCon -> Unique
forall a. Uniquable a => a -> Unique
getUnique DataCon
dc) [(Unique, Type)]
m))
repStruct :: GenEnv -> [Type] -> Type
repStruct :: GenEnv -> [Type] -> Type
repStruct GenEnv
gen [] = TyCon -> [Type] -> Type
mkTyConApp (GenEnv -> TyCon
geU1Tc GenEnv
gen) [Type
liftedTypeKind]
repStruct GenEnv
gen [Type]
fts = (Type -> Type -> Type) -> [Type] -> Type
forall a. (a -> a -> a) -> [a] -> a
foldBal Type -> Type -> Type
prodOf ((Type -> Type) -> [Type] -> [Type]
forall a b. (a -> b) -> [a] -> [b]
map Type -> Type
rec0 [Type]
fts) where
rec0 :: Type -> Type
rec0 Type
t = TyCon -> [Type] -> Type
mkTyConApp (GenEnv -> TyCon
geK1Tc GenEnv
gen) [Type
liftedTypeKind, GenEnv -> Type
geRTy GenEnv
gen, Type
t]
prodOf :: Type -> Type -> Type
prodOf Type
f Type
g = TyCon -> [Type] -> Type
mkTyConApp (GenEnv -> TyCon
geProdTc GenEnv
gen) [Type
liftedTypeKind, Type
f, Type
g]
rep1Field :: GenEnv -> TyVar -> Type -> Maybe Type
rep1Field :: GenEnv -> Id -> Type -> Maybe Type
rep1Field GenEnv
gen Id
aTv Type
ft
| Type
ft Type -> Type -> Bool
`eqType` Type
aTy = Type -> Maybe Type
forall a. a -> Maybe a
Just Type
par1
| Bool -> Bool
not (Id
aTv Id -> VarSet -> Bool
`elemVarSet` Type -> VarSet
tyCoVarsOfType Type
ft) = Type -> Maybe Type
forall a. a -> Maybe a
Just (GenEnv -> Type -> Type
rec0Of GenEnv
gen Type
ft)
| Just (Type
h, Type
larg) <- Type -> Maybe (Type, Type)
splitAppTy_maybe Type
ft
, Bool -> Bool
not (Id
aTv Id -> VarSet -> Bool
`elemVarSet` Type -> VarSet
tyCoVarsOfType Type
h) =
if Type
larg Type -> Type -> Bool
`eqType` Type
aTy then Type -> Maybe Type
forall a. a -> Maybe a
Just (Type -> Type
rec1 Type
h)
else Type -> Type -> Type
comp Type
h (Type -> Type) -> Maybe Type -> Maybe Type
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> GenEnv -> Id -> Type -> Maybe Type
rep1Field GenEnv
gen Id
aTv Type
larg
| Bool
otherwise = Maybe Type
forall a. Maybe a
Nothing
where
g1 :: Gen1Env
g1 = GenEnv -> Gen1Env
geGen1 GenEnv
gen ; kTy :: Type
kTy = Type
liftedTypeKind ; aTy :: Type
aTy = Id -> Type
mkTyVarTy Id
aTv
par1 :: Type
par1 = TyCon -> Type
mkTyConTy (Gen1Env -> TyCon
g1Par1Tc Gen1Env
g1)
rec1 :: Type -> Type
rec1 Type
h = TyCon -> [Type] -> Type
mkTyConApp (Gen1Env -> TyCon
g1Rec1Tc Gen1Env
g1) [Type
kTy, Type
h]
comp :: Type -> Type -> Type
comp Type
h Type
inr = TyCon -> [Type] -> Type
mkTyConApp (Gen1Env -> TyCon
g1CompTc Gen1Env
g1) [Type
kTy, Type
kTy, Type
h, Type
inr]
foldBal :: (a -> a -> a) -> [a] -> a
foldBal :: forall a. (a -> a -> a) -> [a] -> a
foldBal a -> a -> a
_ [a
x] = a
x
foldBal a -> a -> a
op [a]
xs = let ([a]
l, [a]
r) = Int -> [a] -> ([a], [a])
forall a. Int -> [a] -> ([a], [a])
splitAt ([a] -> Int
forall a. [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [a]
xs Int -> Int -> Int
forall a. Integral a => a -> a -> a
`div` Int
2) [a]
xs
in a -> a -> a
op ((a -> a -> a) -> [a] -> a
forall a. (a -> a -> a) -> [a] -> a
foldBal a -> a -> a
op [a]
l) ((a -> a -> a) -> [a] -> a
forall a. (a -> a -> a) -> [a] -> a
foldBal a -> a -> a
op [a]
r)
type Attempt = (Maybe (EvTerm, Ct), [Ct], [Ct])
data ConInfo = ConInfo
{ ConInfo -> DataCon
ciCon :: DataCon
, ConInfo -> [Type]
ciFields :: [Type]
, ConInfo -> [Coercion]
ciFieldCos :: [Coercion]
}
data Repr = Repr
{ Repr -> Type
rInner :: Type
, Repr -> Coercion
rCo :: Coercion
, Repr -> [ConInfo]
rCons :: [ConInfo]
}
mkRepr :: Maybe TyCon -> Type -> Maybe Repr
mkRepr :: Maybe TyCon -> Type -> Maybe Repr
mkRepr Maybe TyCon
ourStock Type
wrappedTy = do
ourTc <- Maybe TyCon
ourStock
stockTc <- tyConAppTyCon_maybe wrappedTy
guard (stockTc == ourTc)
innerTy <- case tyConAppArgs wrappedTy of { (Type
a:[Type]
_) -> Type -> Maybe Type
forall a. a -> Maybe a
Just Type
a; [Type]
_ -> Maybe Type
forall a. Maybe a
Nothing }
innerTc <- tyConAppTyCon_maybe innerTy
let dcons = TyCon -> [DataCon]
tyConDataCons TyCon
innerTc
guard (not (null dcons))
let co = Role -> CoAxiom Unbranched -> [Type] -> [Coercion] -> Coercion
mkUnbranchedAxInstCo Role
Representational
(TyCon -> CoAxiom Unbranched
newTyConCo TyCon
stockTc) (HasCallStack => Type -> [Type]
Type -> [Type]
tyConAppArgs Type
wrappedTy) []
cons = [ DataCon -> [Type] -> [Coercion] -> ConInfo
ConInfo DataCon
dc [Type]
fts ((Type -> Coercion) -> [Type] -> [Coercion]
forall a b. (a -> b) -> [a] -> [b]
map Type -> Coercion
mkRepReflCo [Type]
fts)
| DataCon
dc <- [DataCon]
dcons, let fts :: [Type]
fts = Type -> DataCon -> [Type]
fieldTysAt Type
innerTy DataCon
dc ]
pure (Repr innerTy co cons)
mkStockCo :: UnivCoProvenance -> Role -> Type -> Type -> Coercion
#if MIN_VERSION_ghc(9,12,0)
mkStockCo prov = mkUnivCo prov []
#else
mkStockCo :: UnivCoProvenance -> Role -> Type -> Type -> Coercion
mkStockCo = UnivCoProvenance -> Role -> Type -> Type -> Coercion
mkUnivCo
#endif
reshapeCo :: Type -> Type -> Type -> Coercion
reshapeCo :: Type -> Type -> Type -> Coercion
reshapeCo Type
h Type
m Type
t
| Type
h Type -> Type -> Bool
`eqType` Type
m = Type -> Coercion
mkRepReflCo (Type -> Type -> Type
mkAppTy Type
h Type
t)
| Bool
otherwise = UnivCoProvenance -> Role -> Type -> Type -> Coercion
mkStockCo (String -> UnivCoProvenance
PluginProv String
"stock") Role
Representational (Type -> Type -> Type
mkAppTy Type
h Type
t) (Type -> Type -> Type
mkAppTy Type
m Type
t)
castReshape :: CoreExpr -> Coercion -> CoreExpr
castReshape :: CoreExpr -> Coercion -> CoreExpr
castReshape CoreExpr
e Coercion
co = if Coercion -> Bool
isReflCo Coercion
co then CoreExpr
e else CoreExpr -> Coercion -> CoreExpr
forall b. Expr b -> Coercion -> Expr b
Cast CoreExpr
e Coercion
co
peelOverride1 :: GenEnv -> Type -> (Type, Maybe [Type])
peelOverride1 :: GenEnv -> Type -> (Type, Maybe [Type])
peelOverride1 GenEnv
gen = OvTcs -> Type -> (Type, Maybe [Type])
peelOverride1With (String -> GenEnv -> OvTcs
ovTcsGen String
"Override1" GenEnv
gen)
data OvTcs = OvTcs
{ OvTcs -> Maybe TyCon
ovWrap :: Maybe TyCon
, OvTcs -> Maybe TyCon
ovKeep :: Maybe TyCon
, OvTcs -> Maybe TyCon
ovArrow :: Maybe TyCon
, OvTcs -> Maybe TyCon
ovAssign :: Maybe TyCon
, OvTcs -> Maybe TyCon
ovAt :: Maybe TyCon
}
ovTcsGen :: String -> GenEnv -> OvTcs
ovTcsGen :: String -> GenEnv -> OvTcs
ovTcsGen String
wrap GenEnv
gen = Maybe TyCon
-> Maybe TyCon
-> Maybe TyCon
-> Maybe TyCon
-> Maybe TyCon
-> OvTcs
OvTcs
(if String
wrap String -> String -> Bool
forall a. Eq a => a -> a -> Bool
== String
"Override2" then GenEnv -> Maybe TyCon
geOverride2 GenEnv
gen else GenEnv -> Maybe TyCon
geOverride1 GenEnv
gen)
(GenEnv -> Maybe TyCon
geKeep GenEnv
gen) (GenEnv -> Maybe TyCon
geArrow GenEnv
gen) (GenEnv -> Maybe TyCon
geAssign GenEnv
gen) (GenEnv -> Maybe TyCon
geAt GenEnv
gen)
lookupOvTcs :: String -> TcPluginM OvTcs
lookupOvTcs :: String -> TcPluginM OvTcs
lookupOvTcs String
wrap = Maybe TyCon
-> Maybe TyCon
-> Maybe TyCon
-> Maybe TyCon
-> Maybe TyCon
-> OvTcs
OvTcs
(Maybe TyCon
-> Maybe TyCon
-> Maybe TyCon
-> Maybe TyCon
-> Maybe TyCon
-> OvTcs)
-> TcPluginM (Maybe TyCon)
-> TcPluginM
(Maybe TyCon -> Maybe TyCon -> Maybe TyCon -> Maybe TyCon -> OvTcs)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> String -> String -> TcPluginM (Maybe TyCon)
lookupTyConMaybe String
"Stock.Override" String
wrap
TcPluginM
(Maybe TyCon -> Maybe TyCon -> Maybe TyCon -> Maybe TyCon -> OvTcs)
-> TcPluginM (Maybe TyCon)
-> TcPluginM (Maybe TyCon -> Maybe TyCon -> Maybe TyCon -> OvTcs)
forall a b. TcPluginM (a -> b) -> TcPluginM a -> TcPluginM b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> String -> String -> TcPluginM (Maybe TyCon)
lookupTyConMaybe String
"Stock.Override" String
"Keep"
TcPluginM (Maybe TyCon -> Maybe TyCon -> Maybe TyCon -> OvTcs)
-> TcPluginM (Maybe TyCon)
-> TcPluginM (Maybe TyCon -> Maybe TyCon -> OvTcs)
forall a b. TcPluginM (a -> b) -> TcPluginM a -> TcPluginM b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> String -> String -> TcPluginM (Maybe TyCon)
lookupTyConMaybe String
"Stock.Override" String
"-->"
TcPluginM (Maybe TyCon -> Maybe TyCon -> OvTcs)
-> TcPluginM (Maybe TyCon) -> TcPluginM (Maybe TyCon -> OvTcs)
forall a b. TcPluginM (a -> b) -> TcPluginM a -> TcPluginM b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> String -> String -> TcPluginM (Maybe TyCon)
lookupTyConMaybe String
"Stock.Override" String
":="
TcPluginM (Maybe TyCon -> OvTcs)
-> TcPluginM (Maybe TyCon) -> TcPluginM OvTcs
forall a b. TcPluginM (a -> b) -> TcPluginM a -> TcPluginM b
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> String -> String -> TcPluginM (Maybe TyCon)
lookupTyConMaybe String
"Stock.Override" String
"At"
peelOverride1With :: OvTcs -> Type -> (Type, Maybe [Type])
peelOverride1With :: OvTcs -> Type -> (Type, Maybe [Type])
peelOverride1With OvTcs
tcs Type
f = case OvTcs -> Maybe TyCon
ovWrap OvTcs
tcs of
Just TyCon
ov1Tc | Just (TyCon
tc, [Type
_, Type
_, Type
realF, Type
cfg]) <- HasDebugCallStack => Type -> Maybe (TyCon, [Type])
Type -> Maybe (TyCon, [Type])
splitTyConApp_maybe Type
f, TyCon
tc TyCon -> TyCon -> Bool
forall a. Eq a => a -> a -> Bool
== TyCon
ov1Tc
-> (Type
realF, OvTcs -> Type -> Type -> Maybe [Type]
decodeOvCfg OvTcs
tcs Type
realF Type
cfg)
Maybe TyCon
_ -> (Type
f, Maybe [Type]
forall a. Maybe a
Nothing)
decodeOvCfg :: OvTcs -> Type -> Type -> Maybe [Type]
decodeOvCfg :: OvTcs -> Type -> Type -> Maybe [Type]
decodeOvCfg OvTcs
tcs Type
realInner Type
cfg =
case Type -> Maybe [[Type]]
decodePositional Type
cfg of
Just [[Type]]
perCon -> [[Type]] -> Maybe [Type]
forall a. [a] -> Maybe a
listToMaybe [[Type]]
perCon
Maybe [[Type]]
Nothing -> do
arrowTc <- OvTcs -> Maybe TyCon
ovArrow OvTcs
tcs ; assignTc <- ovAssign tcs
atTc <- ovAt tcs ; keepTc <- ovKeep tcs
fTc <- tyConAppTyCon_maybe realInner
let dcons = TyCon -> [DataCon]
tyConDataCons TyCon
fTc
guard (not (null dcons))
entries <- promotedListElems cfg >>= traverse (decodeEntry arrowTc assignTc atTc)
cells <- either (const Nothing) Just (resolveCellsRaw dcons realInner entries)
Just [ fromMaybe (mkTyConTy keepTc) (lookup (0, fi) cells)
| fi <- [0 .. dataConSourceArity (head dcons) - 1] ]
override1Mod :: GenEnv -> Maybe [Type] -> Int -> Maybe Type
override1Mod :: GenEnv -> Maybe [Type] -> Int -> Maybe Type
override1Mod GenEnv
gen = Maybe TyCon -> Maybe [Type] -> Int -> Maybe Type
override1ModWith (GenEnv -> Maybe TyCon
geKeep GenEnv
gen)
override1ModWith :: Maybe TyCon -> Maybe [Type] -> Int -> Maybe Type
override1ModWith :: Maybe TyCon -> Maybe [Type] -> Int -> Maybe Type
override1ModWith Maybe TyCon
mKeep Maybe [Type]
mMods Int
i = case Maybe [Type]
mMods of
Just [Type]
mods | Int
i Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< [Type] -> Int
forall a. [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [Type]
mods
, let m :: Type
m = [Type]
mods [Type] -> Int -> Type
forall a. HasCallStack => [a] -> Int -> a
!! Int
i
, Bool -> Bool
not (Bool -> (TyCon -> Bool) -> Maybe TyCon -> Bool
forall b a. b -> (a -> b) -> Maybe a -> b
maybe Bool
False (\TyCon
k -> Type -> Maybe TyCon
tyConAppTyCon_maybe Type
m Maybe TyCon -> Maybe TyCon -> Bool
forall a. Eq a => a -> a -> Bool
== TyCon -> Maybe TyCon
forall a. a -> Maybe a
Just TyCon
k) Maybe TyCon
mKeep)
-> Type -> Maybe Type
forall a. a -> Maybe a
Just Type
m
Maybe [Type]
_ -> Maybe Type
forall a. Maybe a
Nothing
coDown1 :: GenEnv -> TyCon -> Type -> Type -> Type -> Type -> Coercion
coDown1 :: GenEnv -> TyCon -> Type -> Type -> Type -> Type -> Coercion
coDown1 GenEnv
gen = Maybe TyCon -> TyCon -> Type -> Type -> Type -> Type -> Coercion
coDown1With (GenEnv -> Maybe TyCon
geOverride1 GenEnv
gen)
coDown1With :: Maybe TyCon -> TyCon -> Type -> Type -> Type -> Type -> Coercion
coDown1With :: Maybe TyCon -> TyCon -> Type -> Type -> Type -> Type -> Coercion
coDown1With Maybe TyCon
mOv1 TyCon
st1Tc Type
wrappedTy Type
f0 Type
realF Type
t = Coercion -> Coercion -> Coercion
mkTransCo
(Role -> CoAxiom Unbranched -> [Type] -> [Coercion] -> Coercion
mkUnbranchedAxInstCo Role
Representational (TyCon -> CoAxiom Unbranched
newTyConCo TyCon
st1Tc) (HasCallStack => Type -> [Type]
Type -> [Type]
tyConAppArgs Type
wrappedTy [Type] -> [Type] -> [Type]
forall a. [a] -> [a] -> [a]
++ [Type
t]) [])
(case Maybe TyCon
mOv1 of
Just TyCon
ov1Tc | Type -> Maybe TyCon
tyConAppTyCon_maybe Type
f0 Maybe TyCon -> Maybe TyCon -> Bool
forall a. Eq a => a -> a -> Bool
== TyCon -> Maybe TyCon
forall a. a -> Maybe a
Just TyCon
ov1Tc ->
Role -> CoAxiom Unbranched -> [Type] -> [Coercion] -> Coercion
mkUnbranchedAxInstCo Role
Representational (TyCon -> CoAxiom Unbranched
newTyConCo TyCon
ov1Tc) (HasCallStack => Type -> [Type]
Type -> [Type]
tyConAppArgs Type
f0 [Type] -> [Type] -> [Type]
forall a. [a] -> [a] -> [a]
++ [Type
t]) []
Maybe TyCon
_ -> Type -> Coercion
mkRepReflCo (Type -> Type -> Type
mkAppTy Type
realF Type
t))
peelOverride2With :: OvTcs -> Type -> (Type, Maybe [Type])
peelOverride2With :: OvTcs -> Type -> (Type, Maybe [Type])
peelOverride2With OvTcs
tcs Type
p = case OvTcs -> Maybe TyCon
ovWrap OvTcs
tcs of
Just TyCon
ov2Tc | Just (TyCon
tc, [Type
_, Type
rp, Type
cfg]) <- HasDebugCallStack => Type -> Maybe (TyCon, [Type])
Type -> Maybe (TyCon, [Type])
splitTyConApp_maybe Type
p, TyCon
tc TyCon -> TyCon -> Bool
forall a. Eq a => a -> a -> Bool
== TyCon
ov2Tc
-> (Type
rp, OvTcs -> Type -> Type -> Maybe [Type]
decodeOvCfg OvTcs
tcs Type
rp Type
cfg)
Maybe TyCon
_ -> (Type
p, Maybe [Type]
forall a. Maybe a
Nothing)
coDown2With :: Maybe TyCon -> TyCon -> Type -> Type -> Type -> Type -> Type -> Coercion
coDown2With :: Maybe TyCon
-> TyCon -> Type -> Type -> Type -> Type -> Type -> Coercion
coDown2With Maybe TyCon
mOv2 TyCon
st2Tc Type
wrappedTy Type
p0 Type
realP Type
t1 Type
t2 = Coercion -> Coercion -> Coercion
mkTransCo
(Role -> CoAxiom Unbranched -> [Type] -> [Coercion] -> Coercion
mkUnbranchedAxInstCo Role
Representational (TyCon -> CoAxiom Unbranched
newTyConCo TyCon
st2Tc) (HasCallStack => Type -> [Type]
Type -> [Type]
tyConAppArgs Type
wrappedTy [Type] -> [Type] -> [Type]
forall a. [a] -> [a] -> [a]
++ [Type
t1, Type
t2]) [])
(case Maybe TyCon
mOv2 of
Just TyCon
ov2Tc | Type -> Maybe TyCon
tyConAppTyCon_maybe Type
p0 Maybe TyCon -> Maybe TyCon -> Bool
forall a. Eq a => a -> a -> Bool
== TyCon -> Maybe TyCon
forall a. a -> Maybe a
Just TyCon
ov2Tc ->
Role -> CoAxiom Unbranched -> [Type] -> [Coercion] -> Coercion
mkUnbranchedAxInstCo Role
Representational (TyCon -> CoAxiom Unbranched
newTyConCo TyCon
ov2Tc) (HasCallStack => Type -> [Type]
Type -> [Type]
tyConAppArgs Type
p0 [Type] -> [Type] -> [Type]
forall a. [a] -> [a] -> [a]
++ [Type
t1, Type
t2]) []
Maybe TyCon
_ -> Type -> Coercion
mkRepReflCo (Type -> Type -> Type
mkAppTy (Type -> Type -> Type
mkAppTy Type
realP Type
t1) Type
t2))
mkStockReprEq :: Type -> Type -> Type
#if MIN_VERSION_ghc(9,14,0)
mkStockReprEq = mkReprEqPred
#else
mkStockReprEq :: Type -> Type -> Type
mkStockReprEq = Type -> Type -> Type
mkReprPrimEqPred
#endif
overrideFieldTypes :: GenEnv -> Type -> Maybe (Type, [(DataCon, [Type])])
overrideFieldTypes :: GenEnv -> Type -> Maybe (Type, [(DataCon, [Type])])
overrideFieldTypes GenEnv
gen Type
arg = do
ourStock <- GenEnv -> Maybe TyCon
geStock GenEnv
gen
overTc <- geOverride gen
keepTc <- geKeep gen ; arrowTc <- geArrow gen
assignTc <- geAssign gen ; atTc <- geAt gen
(stockTc, [innerOver]) <- splitTyConApp_maybe arg
guard (stockTc == ourStock)
(oTc, oArgs) <- splitTyConApp_maybe innerOver
guard (oTc == overTc)
(cfg : realInner : _) <- pure (reverse oArgs)
innerTc <- tyConAppTyCon_maybe realInner
let dcons = TyCon -> [DataCon]
tyConDataCons TyCon
innerTc
guard (not (null dcons))
perCon <-
case decodePositional cfg of
Just [[Type]]
perCon
| [[Type]] -> Int
forall a. [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [[Type]]
perCon Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== [DataCon] -> Int
forall a. [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [DataCon]
dcons ->
[Maybe [Type]] -> Maybe [[Type]]
forall (t :: * -> *) (m :: * -> *) a.
(Traversable t, Monad m) =>
t (m a) -> m (t a)
forall (m :: * -> *) a. Monad m => [m a] -> m [a]
sequence ((DataCon -> [Type] -> Maybe [Type])
-> [DataCon] -> [[Type]] -> [Maybe [Type]]
forall a b c. (a -> b -> c) -> [a] -> [b] -> [c]
zipWith (TyCon -> Type -> DataCon -> [Type] -> Maybe [Type]
posCon TyCon
keepTc Type
realInner) [DataCon]
dcons [[Type]]
perCon)
| Bool
otherwise -> Maybe [[Type]]
forall a. Maybe a
Nothing
Maybe [[Type]]
Nothing -> do
entries <- Type -> Maybe [Type]
promotedListElems Type
cfg Maybe [Type]
-> ([Type] -> Maybe [(Addr, Type)]) -> Maybe [(Addr, Type)]
forall a b. Maybe a -> (a -> Maybe b) -> Maybe b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= (Type -> Maybe (Addr, Type)) -> [Type] -> Maybe [(Addr, Type)]
forall (t :: * -> *) (f :: * -> *) a b.
(Traversable t, Applicative f) =>
(a -> f b) -> t a -> f (t b)
forall (f :: * -> *) a b.
Applicative f =>
(a -> f b) -> [a] -> f [b]
traverse (TyCon -> TyCon -> TyCon -> Type -> Maybe (Addr, Type)
decodeEntry TyCon
arrowTc TyCon
assignTc TyCon
atTc)
case resolveCells dcons realInner entries of
Left SDoc
_ -> Maybe [[Type]]
forall a. Maybe a
Nothing
Right [((Int, Int), Type)]
cells -> [[Type]] -> Maybe [[Type]]
forall a. a -> Maybe a
Just [ [ Type -> Maybe Type -> Type
forall a. a -> Maybe a -> a
fromMaybe Type
rft ((Int, Int) -> [((Int, Int), Type)] -> Maybe Type
forall a b. Eq a => a -> [(a, b)] -> Maybe b
lookup (Int
ci, Int
fi) [((Int, Int), Type)]
cells)
| (Int
fi, Type
rft) <- [Int] -> [Type] -> [(Int, Type)]
forall a b. [a] -> [b] -> [(a, b)]
zip [Int
0 ..] (Type -> DataCon -> [Type]
fieldTysAt Type
realInner DataCon
dc) ]
| (Int
ci, DataCon
dc) <- [Int] -> [DataCon] -> [(Int, DataCon)]
forall a b. [a] -> [b] -> [(a, b)]
zip [Int
0 :: Int ..] [DataCon]
dcons ]
pure (realInner, zip dcons perCon)
where
posCon :: TyCon -> Type -> DataCon -> [Type] -> Maybe [Type]
posCon TyCon
keepTc Type
realInner DataCon
dc [Type]
mods
| [Type] -> Int
forall a. [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [Type]
mods Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
/= [Type] -> Int
forall a. [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [Type]
rfts = Maybe [Type]
forall a. Maybe a
Nothing
| Bool
otherwise = [Maybe Type] -> Maybe [Type]
forall (t :: * -> *) (m :: * -> *) a.
(Traversable t, Monad m) =>
t (m a) -> m (t a)
forall (m :: * -> *) a. Monad m => [m a] -> m [a]
sequence ((Type -> Type -> Maybe Type) -> [Type] -> [Type] -> [Maybe Type]
forall a b c. (a -> b -> c) -> [a] -> [b] -> [c]
zipWith Type -> Type -> Maybe Type
cell [Type]
rfts [Type]
mods)
where rfts :: [Type]
rfts = Type -> DataCon -> [Type]
fieldTysAt Type
realInner DataCon
dc
cell :: Type -> Type -> Maybe Type
cell Type
rft Type
m
| Type -> Maybe TyCon
tyConAppTyCon_maybe Type
m Maybe TyCon -> Maybe TyCon -> Bool
forall a. Eq a => a -> a -> Bool
== TyCon -> Maybe TyCon
forall a. a -> Maybe a
Just TyCon
keepTc = Type -> Maybe Type
forall a. a -> Maybe a
Just Type
rft
| Bool
otherwise = (SDoc -> Maybe Type)
-> (Type -> Maybe Type) -> Either SDoc Type -> Maybe Type
forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
either (Maybe Type -> SDoc -> Maybe Type
forall a b. a -> b -> a
const Maybe Type
forall a. Maybe a
Nothing) Type -> Maybe Type
forall a. a -> Maybe a
Just (Type -> Type -> Either SDoc Type
modifierType Type
m Type
rft)
mkOverrideRepr :: GenEnv -> CtLoc -> Type -> TcPluginM (Maybe (Either SDoc (Repr, [Ct])))
mkOverrideRepr :: GenEnv
-> CtLoc -> Type -> TcPluginM (Maybe (Either SDoc (Repr, [Ct])))
mkOverrideRepr GenEnv
gen CtLoc
loc Type
wrappedTy
| Just TyCon
ourStock <- GenEnv -> Maybe TyCon
geStock GenEnv
gen
, Just TyCon
overTc <- GenEnv -> Maybe TyCon
geOverride GenEnv
gen
, Just TyCon
assignTc <- GenEnv -> Maybe TyCon
geAssign GenEnv
gen
, Just (TyCon
stockTc, [Type
innerOver]) <- HasDebugCallStack => Type -> Maybe (TyCon, [Type])
Type -> Maybe (TyCon, [Type])
splitTyConApp_maybe Type
wrappedTy
, TyCon
stockTc TyCon -> TyCon -> Bool
forall a. Eq a => a -> a -> Bool
== TyCon
ourStock
, Just (TyCon
oTc, [Type]
oArgs) <- HasDebugCallStack => Type -> Maybe (TyCon, [Type])
Type -> Maybe (TyCon, [Type])
splitTyConApp_maybe Type
innerOver
, TyCon
oTc TyCon -> TyCon -> Bool
forall a. Eq a => a -> a -> Bool
== TyCon
overTc
, (Type
cfg : Type
realInner : [Type]
_) <- [Type] -> [Type]
forall a. [a] -> [a]
reverse [Type]
oArgs
, Just TyCon
atTc <- GenEnv -> Maybe TyCon
geAt GenEnv
gen
, Just TyCon
keepTc <- GenEnv -> Maybe TyCon
geKeep GenEnv
gen
, Just TyCon
arrowTc <- GenEnv -> Maybe TyCon
geArrow GenEnv
gen
= Either SDoc (Repr, [Ct]) -> Maybe (Either SDoc (Repr, [Ct]))
forall a. a -> Maybe a
Just (Either SDoc (Repr, [Ct]) -> Maybe (Either SDoc (Repr, [Ct])))
-> TcPluginM (Either SDoc (Repr, [Ct]))
-> TcPluginM (Maybe (Either SDoc (Repr, [Ct])))
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> CtLoc
-> TyCon
-> TyCon
-> TyCon
-> TyCon
-> TyCon
-> TyCon
-> Type
-> Type
-> Type
-> TcPluginM (Either SDoc (Repr, [Ct]))
buildOverride CtLoc
loc TyCon
ourStock TyCon
overTc TyCon
assignTc TyCon
atTc TyCon
keepTc TyCon
arrowTc Type
innerOver Type
cfg Type
realInner
| Bool
otherwise = Maybe (Either SDoc (Repr, [Ct]))
-> TcPluginM (Maybe (Either SDoc (Repr, [Ct])))
forall a. a -> TcPluginM a
forall (f :: * -> *) a. Applicative f => a -> f a
pure Maybe (Either SDoc (Repr, [Ct]))
forall a. Maybe a
Nothing
buildOverride :: CtLoc -> TyCon -> TyCon -> TyCon -> TyCon -> TyCon -> TyCon
-> Type -> Type -> Type -> TcPluginM (Either SDoc (Repr, [Ct]))
buildOverride :: CtLoc
-> TyCon
-> TyCon
-> TyCon
-> TyCon
-> TyCon
-> TyCon
-> Type
-> Type
-> Type
-> TcPluginM (Either SDoc (Repr, [Ct]))
buildOverride CtLoc
loc TyCon
ourStock TyCon
overTc TyCon
assignTc TyCon
atTc TyCon
keepTc TyCon
arrowTc Type
innerOver Type
cfg Type
realInner =
case Type -> Maybe TyCon
tyConAppTyCon_maybe Type
realInner of
Maybe TyCon
Nothing -> SDoc -> TcPluginM (Either SDoc (Repr, [Ct]))
forall {a} {b}. a -> TcPluginM (Either a b)
bad (String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"Override target is not a concrete algebraic type:" SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> Type -> SDoc
forall a. Outputable a => a -> SDoc
ppr Type
realInner)
Just TyCon
innerTc -> case TyCon -> [DataCon]
tyConDataCons TyCon
innerTc of
[] -> SDoc -> TcPluginM (Either SDoc (Repr, [Ct]))
forall {a} {b}. a -> TcPluginM (Either a b)
bad (String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"Override: type has no constructors:" SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> Type -> SDoc
forall a. Outputable a => a -> SDoc
ppr Type
realInner)
[DataCon]
dcons
| (DataCon -> Bool) -> [DataCon] -> Bool
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
any DataCon -> Bool
dcUnpacked [DataCon]
dcons -> SDoc -> TcPluginM (Either SDoc (Repr, [Ct]))
forall {a} {b}. a -> TcPluginM (Either a b)
bad (String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"Override: a constructor has UNPACKed/strict-unboxed"
SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"or existential fields, unsupported")
| Just [[Type]]
perCon <- Type -> Maybe [[Type]]
decodePositional Type
cfg ->
CtLoc
-> TyCon
-> TyCon
-> TyCon
-> Type
-> Type
-> Type
-> [DataCon]
-> [[Type]]
-> TcPluginM (Either SDoc (Repr, [Ct]))
buildPositional CtLoc
loc TyCon
ourStock TyCon
overTc TyCon
keepTc Type
innerOver Type
cfg Type
realInner [DataCon]
dcons [[Type]]
perCon
| Bool
otherwise ->
case Type -> Maybe [Type]
promotedListElems Type
cfg Maybe [Type]
-> ([Type] -> Maybe [(Addr, Type)]) -> Maybe [(Addr, Type)]
forall a b. Maybe a -> (a -> Maybe b) -> Maybe b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= (Type -> Maybe (Addr, Type)) -> [Type] -> Maybe [(Addr, Type)]
forall (t :: * -> *) (f :: * -> *) a b.
(Traversable t, Applicative f) =>
(a -> f b) -> t a -> f (t b)
forall (f :: * -> *) a b.
Applicative f =>
(a -> f b) -> [a] -> f [b]
traverse (TyCon -> TyCon -> TyCon -> Type -> Maybe (Addr, Type)
decodeEntry TyCon
arrowTc TyCon
assignTc TyCon
atTc) of
Maybe [(Addr, Type)]
Nothing -> SDoc -> TcPluginM (Either SDoc (Repr, [Ct]))
forall {a} {b}. a -> TcPluginM (Either a b)
bad (String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"Override config is not a concrete list of"
SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"selector := modifier / path --> modifier entries:" SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> Type -> SDoc
forall a. Outputable a => a -> SDoc
ppr Type
cfg)
Just [(Addr, Type)]
entries -> CtLoc
-> TyCon
-> TyCon
-> Type
-> Type
-> Type
-> [DataCon]
-> [(Addr, Type)]
-> TcPluginM (Either SDoc (Repr, [Ct]))
resolveOverride CtLoc
loc TyCon
ourStock TyCon
overTc Type
innerOver Type
cfg Type
realInner [DataCon]
dcons [(Addr, Type)]
entries
where bad :: a -> TcPluginM (Either a b)
bad = Either a b -> TcPluginM (Either a b)
forall a. a -> TcPluginM a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Either a b -> TcPluginM (Either a b))
-> (a -> Either a b) -> a -> TcPluginM (Either a b)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> Either a b
forall a b. a -> Either a b
Left
decodePositional :: Type -> Maybe [[Type]]
decodePositional :: Type -> Maybe [[Type]]
decodePositional Type
cfg = case Type -> Maybe [Type]
promotedListElems Type
cfg of
Just es :: [Type]
es@(Type
_ : [Type]
_) -> (Type -> Maybe [Type]) -> [Type] -> Maybe [[Type]]
forall (t :: * -> *) (f :: * -> *) a b.
(Traversable t, Applicative f) =>
(a -> f b) -> t a -> f (t b)
forall (f :: * -> *) a b.
Applicative f =>
(a -> f b) -> [a] -> f [b]
traverse Type -> Maybe [Type]
promotedListElems [Type]
es
Maybe [Type]
_ -> Maybe [[Type]]
forall a. Maybe a
Nothing
buildPositional :: CtLoc -> TyCon -> TyCon -> TyCon -> Type -> Type -> Type
-> [DataCon] -> [[Type]] -> TcPluginM (Either SDoc (Repr, [Ct]))
buildPositional :: CtLoc
-> TyCon
-> TyCon
-> TyCon
-> Type
-> Type
-> Type
-> [DataCon]
-> [[Type]]
-> TcPluginM (Either SDoc (Repr, [Ct]))
buildPositional CtLoc
loc TyCon
ourStock TyCon
overTc TyCon
keepTc Type
innerOver Type
cfg Type
realInner [DataCon]
dcons [[Type]]
perCon
| [[Type]] -> Int
forall a. [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [[Type]]
perCon Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
/= [DataCon] -> Int
forall a. [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [DataCon]
dcons =
Either SDoc (Repr, [Ct]) -> TcPluginM (Either SDoc (Repr, [Ct]))
forall a. a -> TcPluginM a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (SDoc -> Either SDoc (Repr, [Ct])
forall a b. a -> Either a b
Left (String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"Override: positional config has" SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> Int -> SDoc
forall doc. IsLine doc => Int -> doc
int ([[Type]] -> Int
forall a. [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [[Type]]
perCon)
SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"constructor list(s) but" SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> Type -> SDoc
forall a. Outputable a => a -> SDoc
ppr Type
realInner SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"has"
SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> Int -> SDoc
forall doc. IsLine doc => Int -> doc
int ([DataCon] -> Int
forall a. [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [DataCon]
dcons)))
| Bool
otherwise = do
let co :: Coercion
co = Coercion -> Coercion -> Coercion
mkTransCo (Role -> CoAxiom Unbranched -> [Type] -> [Coercion] -> Coercion
mkUnbranchedAxInstCo Role
Representational (TyCon -> CoAxiom Unbranched
newTyConCo TyCon
ourStock) [Type
innerOver] [])
(Role -> CoAxiom Unbranched -> [Type] -> [Coercion] -> Coercion
mkUnbranchedAxInstCo Role
Representational (TyCon -> CoAxiom Unbranched
newTyConCo TyCon
overTc) [HasDebugCallStack => Type -> Type
Type -> Type
typeKind Type
cfg, Type
realInner, Type
cfg] [])
results <- ((DataCon, [Type]) -> TcPluginM (Either SDoc (ConInfo, [Ct])))
-> [(DataCon, [Type])] -> TcPluginM [Either SDoc (ConInfo, [Ct])]
forall (t :: * -> *) (f :: * -> *) a b.
(Traversable t, Applicative f) =>
(a -> f b) -> t a -> f (t b)
forall (f :: * -> *) a b.
Applicative f =>
(a -> f b) -> [a] -> f [b]
traverse ((DataCon -> [Type] -> TcPluginM (Either SDoc (ConInfo, [Ct])))
-> (DataCon, [Type]) -> TcPluginM (Either SDoc (ConInfo, [Ct]))
forall a b c. (a -> b -> c) -> (a, b) -> c
uncurry DataCon -> [Type] -> TcPluginM (Either SDoc (ConInfo, [Ct]))
conInfo) ([DataCon] -> [[Type]] -> [(DataCon, [Type])]
forall a b. [a] -> [b] -> [(a, b)]
zip [DataCon]
dcons [[Type]]
perCon)
pure $ case sequence results of
Left SDoc
err -> SDoc -> Either SDoc (Repr, [Ct])
forall a b. a -> Either a b
Left SDoc
err
Right [(ConInfo, [Ct])]
cws -> (Repr, [Ct]) -> Either SDoc (Repr, [Ct])
forall a b. b -> Either a b
Right (Type -> Coercion -> [ConInfo] -> Repr
Repr Type
realInner Coercion
co (((ConInfo, [Ct]) -> ConInfo) -> [(ConInfo, [Ct])] -> [ConInfo]
forall a b. (a -> b) -> [a] -> [b]
map (ConInfo, [Ct]) -> ConInfo
forall a b. (a, b) -> a
fst [(ConInfo, [Ct])]
cws), ((ConInfo, [Ct]) -> [Ct]) -> [(ConInfo, [Ct])] -> [Ct]
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap (ConInfo, [Ct]) -> [Ct]
forall a b. (a, b) -> b
snd [(ConInfo, [Ct])]
cws)
where
conInfo :: DataCon -> [Type] -> TcPluginM (Either SDoc (ConInfo, [Ct]))
conInfo :: DataCon -> [Type] -> TcPluginM (Either SDoc (ConInfo, [Ct]))
conInfo DataCon
dc [Type]
mods
| [Type] -> Int
forall a. [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [Type]
mods Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
/= [Type] -> Int
forall a. [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [Type]
realFts =
Either SDoc (ConInfo, [Ct])
-> TcPluginM (Either SDoc (ConInfo, [Ct]))
forall a. a -> TcPluginM a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (SDoc -> Either SDoc (ConInfo, [Ct])
forall a b. a -> Either a b
Left (String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"Override: constructor" SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> DataCon -> SDoc
forall a. Outputable a => a -> SDoc
ppr DataCon
dc SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"has" SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> Int -> SDoc
forall doc. IsLine doc => Int -> doc
int ([Type] -> Int
forall a. [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [Type]
realFts)
SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"field(s) but its positional list has" SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> Int -> SDoc
forall doc. IsLine doc => Int -> doc
int ([Type] -> Int
forall a. [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [Type]
mods)))
| Bool
otherwise = do
cells <- ((Type, Type) -> TcPluginM (Either SDoc ((Type, Coercion), [Ct])))
-> [(Type, Type)]
-> TcPluginM [Either SDoc ((Type, Coercion), [Ct])]
forall (t :: * -> *) (f :: * -> *) a b.
(Traversable t, Applicative f) =>
(a -> f b) -> t a -> f (t b)
forall (f :: * -> *) a b.
Applicative f =>
(a -> f b) -> [a] -> f [b]
traverse (Type, Type) -> TcPluginM (Either SDoc ((Type, Coercion), [Ct]))
cell ([Type] -> [Type] -> [(Type, Type)]
forall a b. [a] -> [b] -> [(a, b)]
zip [Type]
realFts [Type]
mods)
pure $ case sequence cells of
Left SDoc
err -> SDoc -> Either SDoc (ConInfo, [Ct])
forall a b. a -> Either a b
Left SDoc
err
Right [((Type, Coercion), [Ct])]
fs -> (ConInfo, [Ct]) -> Either SDoc (ConInfo, [Ct])
forall a b. b -> Either a b
Right (DataCon -> [Type] -> [Coercion] -> ConInfo
ConInfo DataCon
dc ((((Type, Coercion), [Ct]) -> Type)
-> [((Type, Coercion), [Ct])] -> [Type]
forall a b. (a -> b) -> [a] -> [b]
map ((Type, Coercion) -> Type
forall a b. (a, b) -> a
fst ((Type, Coercion) -> Type)
-> (((Type, Coercion), [Ct]) -> (Type, Coercion))
-> ((Type, Coercion), [Ct])
-> Type
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ((Type, Coercion), [Ct]) -> (Type, Coercion)
forall a b. (a, b) -> a
fst) [((Type, Coercion), [Ct])]
fs) ((((Type, Coercion), [Ct]) -> Coercion)
-> [((Type, Coercion), [Ct])] -> [Coercion]
forall a b. (a -> b) -> [a] -> [b]
map ((Type, Coercion) -> Coercion
forall a b. (a, b) -> b
snd ((Type, Coercion) -> Coercion)
-> (((Type, Coercion), [Ct]) -> (Type, Coercion))
-> ((Type, Coercion), [Ct])
-> Coercion
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ((Type, Coercion), [Ct]) -> (Type, Coercion)
forall a b. (a, b) -> a
fst) [((Type, Coercion), [Ct])]
fs)
, (((Type, Coercion), [Ct]) -> [Ct])
-> [((Type, Coercion), [Ct])] -> [Ct]
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap ((Type, Coercion), [Ct]) -> [Ct]
forall a b. (a, b) -> b
snd [((Type, Coercion), [Ct])]
fs)
where realFts :: [Type]
realFts = Type -> DataCon -> [Type]
fieldTysAt Type
realInner DataCon
dc
cell :: (Type, Type) -> TcPluginM (Either SDoc ((Type, Coercion), [Ct]))
cell :: (Type, Type) -> TcPluginM (Either SDoc ((Type, Coercion), [Ct]))
cell (Type
ft, Type
m)
| Type -> Maybe TyCon
tyConAppTyCon_maybe Type
m Maybe TyCon -> Maybe TyCon -> Bool
forall a. Eq a => a -> a -> Bool
== TyCon -> Maybe TyCon
forall a. a -> Maybe a
Just TyCon
keepTc = Either SDoc ((Type, Coercion), [Ct])
-> TcPluginM (Either SDoc ((Type, Coercion), [Ct]))
forall a. a -> TcPluginM a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (((Type, Coercion), [Ct]) -> Either SDoc ((Type, Coercion), [Ct])
forall a b. b -> Either a b
Right ((Type
ft, Type -> Coercion
mkRepReflCo Type
ft), []))
| Bool
otherwise = case Type -> Type -> Either SDoc Type
modifierType Type
m Type
ft of
Left SDoc
err -> Either SDoc ((Type, Coercion), [Ct])
-> TcPluginM (Either SDoc ((Type, Coercion), [Ct]))
forall a. a -> TcPluginM a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (SDoc -> Either SDoc ((Type, Coercion), [Ct])
forall a b. a -> Either a b
Left SDoc
err)
Right Type
modTy -> do
ev <- CtLoc -> Type -> TcPluginM CtEvidence
newWanted CtLoc
loc (Type -> Type -> Type
mkStockReprEq Type
ft Type
modTy)
pure (Right ((modTy, ctEvCoercion ev), [mkNonCanonical ev]))
data Hop = HopCon FastString | HopPos Integer | HopLabel FastString
data Addr = AddrPath [Hop] | AddrType Type
resolveOverride :: CtLoc -> TyCon -> TyCon -> Type -> Type -> Type -> [DataCon]
-> [(Addr, Type)] -> TcPluginM (Either SDoc (Repr, [Ct]))
resolveOverride :: CtLoc
-> TyCon
-> TyCon
-> Type
-> Type
-> Type
-> [DataCon]
-> [(Addr, Type)]
-> TcPluginM (Either SDoc (Repr, [Ct]))
resolveOverride CtLoc
loc TyCon
ourStock TyCon
overTc Type
innerOver Type
cfg Type
realInner [DataCon]
dcons [(Addr, Type)]
entries =
case [DataCon]
-> Type -> [(Addr, Type)] -> Either SDoc [((Int, Int), Type)]
resolveCells [DataCon]
dcons Type
realInner [(Addr, Type)]
entries of
Left SDoc
err -> Either SDoc (Repr, [Ct]) -> TcPluginM (Either SDoc (Repr, [Ct]))
forall a. a -> TcPluginM a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (SDoc -> Either SDoc (Repr, [Ct])
forall a b. a -> Either a b
Left SDoc
err)
Right [((Int, Int), Type)]
cells -> do
tagged <- [((Int, Int), Type)]
-> (((Int, Int), Type)
-> TcPluginM (((Int, Int), (Type, Coercion)), Ct))
-> TcPluginM [(((Int, Int), (Type, Coercion)), Ct)]
forall (t :: * -> *) (f :: * -> *) a b.
(Traversable t, Applicative f) =>
t a -> (a -> f b) -> f (t b)
for [((Int, Int), Type)]
cells \((Int
ci, Int
fi), Type
modTy) -> do
let realFt :: Type
realFt = Type -> DataCon -> [Type]
fieldTysAt Type
realInner ([DataCon]
dcons [DataCon] -> Int -> DataCon
forall a. HasCallStack => [a] -> Int -> a
!! Int
ci) [Type] -> Int -> Type
forall a. HasCallStack => [a] -> Int -> a
!! Int
fi
ev <- CtLoc -> Type -> TcPluginM CtEvidence
newWanted CtLoc
loc (Type -> Type -> Type
mkStockReprEq Type
realFt Type
modTy)
pure (((ci, fi), (modTy, ctEvCoercion ev)), mkNonCanonical ev)
let cellMap = ((((Int, Int), (Type, Coercion)), Ct)
-> ((Int, Int), (Type, Coercion)))
-> [(((Int, Int), (Type, Coercion)), Ct)]
-> [((Int, Int), (Type, Coercion))]
forall a b. (a -> b) -> [a] -> [b]
map (((Int, Int), (Type, Coercion)), Ct)
-> ((Int, Int), (Type, Coercion))
forall a b. (a, b) -> a
fst [(((Int, Int), (Type, Coercion)), Ct)]
tagged
wanteds = ((((Int, Int), (Type, Coercion)), Ct) -> Ct)
-> [(((Int, Int), (Type, Coercion)), Ct)] -> [Ct]
forall a b. (a -> b) -> [a] -> [b]
map (((Int, Int), (Type, Coercion)), Ct) -> Ct
forall a b. (a, b) -> b
snd [(((Int, Int), (Type, Coercion)), Ct)]
tagged
co = Coercion -> Coercion -> Coercion
mkTransCo (Role -> CoAxiom Unbranched -> [Type] -> [Coercion] -> Coercion
mkUnbranchedAxInstCo Role
Representational (TyCon -> CoAxiom Unbranched
newTyConCo TyCon
ourStock) [Type
innerOver] [])
(Role -> CoAxiom Unbranched -> [Type] -> [Coercion] -> Coercion
mkUnbranchedAxInstCo Role
Representational (TyCon -> CoAxiom Unbranched
newTyConCo TyCon
overTc) [HasDebugCallStack => Type -> Type
Type -> Type
typeKind Type
cfg, Type
realInner, Type
cfg] [])
cons = [ DataCon -> [Type] -> [Coercion] -> ConInfo
ConInfo DataCon
dc (((Type, Coercion) -> Type) -> [(Type, Coercion)] -> [Type]
forall a b. (a -> b) -> [a] -> [b]
map (Type, Coercion) -> Type
forall a b. (a, b) -> a
fst [(Type, Coercion)]
fields) (((Type, Coercion) -> Coercion) -> [(Type, Coercion)] -> [Coercion]
forall a b. (a -> b) -> [a] -> [b]
map (Type, Coercion) -> Coercion
forall a b. (a, b) -> b
snd [(Type, Coercion)]
fields)
| (Int
ci, DataCon
dc) <- [Int] -> [DataCon] -> [(Int, DataCon)]
forall a b. [a] -> [b] -> [(a, b)]
zip [Int
0 :: Int ..] [DataCon]
dcons
, let fields :: [(Type, Coercion)]
fields = [ (Type, Coercion) -> Maybe (Type, Coercion) -> (Type, Coercion)
forall a. a -> Maybe a -> a
fromMaybe (Type
ft, Type -> Coercion
mkRepReflCo Type
ft) ((Int, Int)
-> [((Int, Int), (Type, Coercion))] -> Maybe (Type, Coercion)
forall a b. Eq a => a -> [(a, b)] -> Maybe b
lookup (Int
ci, Int
fi) [((Int, Int), (Type, Coercion))]
cellMap)
| (Int
fi, Type
ft) <- [Int] -> [Type] -> [(Int, Type)]
forall a b. [a] -> [b] -> [(a, b)]
zip [Int
0 :: Int ..] (Type -> DataCon -> [Type]
fieldTysAt Type
realInner DataCon
dc) ] ]
pure (Right (Repr realInner co cons, wanteds))
resolveCellsRaw :: [DataCon] -> Type -> [(Addr, Type)] -> Either SDoc [((Int, Int), Type)]
resolveCellsRaw :: [DataCon]
-> Type -> [(Addr, Type)] -> Either SDoc [((Int, Int), Type)]
resolveCellsRaw [DataCon]
dcons Type
targetTy = [(Int, Int)] -> [(Addr, Type)] -> Either SDoc [((Int, Int), Type)]
forall {b}.
[(Int, Int)] -> [(Addr, b)] -> Either SDoc [((Int, Int), b)]
go []
where
go :: [(Int, Int)] -> [(Addr, b)] -> Either SDoc [((Int, Int), b)]
go [(Int, Int)]
_ [] = [((Int, Int), b)] -> Either SDoc [((Int, Int), b)]
forall a b. b -> Either a b
Right []
go [(Int, Int)]
claimed ((Addr
addr, b
m) : [(Addr, b)]
rest) = do
cells <- [DataCon] -> Type -> Addr -> Either SDoc [(Int, Int)]
resolveAddr [DataCon]
dcons Type
targetTy Addr
addr
case filter (`elem` claimed) cells of
clash :: [(Int, Int)]
clash@((Int, Int)
_ : [(Int, Int)]
_) -> SDoc -> Either SDoc [((Int, Int), b)]
forall a b. a -> Either a b
Left (String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"Override: cell(s)" SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> [(Int, Int)] -> SDoc
forall a. Outputable a => a -> SDoc
ppr [(Int, Int)]
clash
SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"claimed by more than one entry (make them disjoint)")
[] -> ((((Int, Int) -> ((Int, Int), b))
-> [(Int, Int)] -> [((Int, Int), b)]
forall a b. (a -> b) -> [a] -> [b]
map (\(Int, Int)
c -> ((Int, Int)
c, b
m)) [(Int, Int)]
cells) [((Int, Int), b)] -> [((Int, Int), b)] -> [((Int, Int), b)]
forall a. [a] -> [a] -> [a]
++) ([((Int, Int), b)] -> [((Int, Int), b)])
-> Either SDoc [((Int, Int), b)] -> Either SDoc [((Int, Int), b)]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> [(Int, Int)] -> [(Addr, b)] -> Either SDoc [((Int, Int), b)]
go ([(Int, Int)]
cells [(Int, Int)] -> [(Int, Int)] -> [(Int, Int)]
forall a. [a] -> [a] -> [a]
++ [(Int, Int)]
claimed) [(Addr, b)]
rest
resolveCells :: [DataCon] -> Type -> [(Addr, Type)]
-> Either SDoc [((Int, Int), Type)]
resolveCells :: [DataCon]
-> Type -> [(Addr, Type)] -> Either SDoc [((Int, Int), Type)]
resolveCells [DataCon]
dcons Type
targetTy = [(Int, Int)] -> [(Addr, Type)] -> Either SDoc [((Int, Int), Type)]
go []
where
go :: [(Int, Int)] -> [(Addr, Type)] -> Either SDoc [((Int, Int), Type)]
go [(Int, Int)]
_ [] = [((Int, Int), Type)] -> Either SDoc [((Int, Int), Type)]
forall a b. b -> Either a b
Right []
go [(Int, Int)]
claimed ((Addr
addr, Type
m) : [(Addr, Type)]
rest) = do
cells <- [DataCon] -> Type -> Addr -> Either SDoc [(Int, Int)]
resolveAddr [DataCon]
dcons Type
targetTy Addr
addr
case filter (`elem` claimed) cells of
clash :: [(Int, Int)]
clash@((Int, Int)
_ : [(Int, Int)]
_) -> SDoc -> Either SDoc [((Int, Int), Type)]
forall a b. a -> Either a b
Left (String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"Override: cell(s)" SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> [(Int, Int)] -> SDoc
forall a. Outputable a => a -> SDoc
ppr [(Int, Int)]
clash
SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"claimed by more than one entry (make them disjoint)")
[] -> do
here <- [(Int, Int)]
-> ((Int, Int) -> Either SDoc ((Int, Int), Type))
-> Either SDoc [((Int, Int), Type)]
forall (t :: * -> *) (f :: * -> *) a b.
(Traversable t, Applicative f) =>
t a -> (a -> f b) -> f (t b)
for [(Int, Int)]
cells \(Int
ci, Int
fi) ->
(,) (Int
ci, Int
fi) (Type -> ((Int, Int), Type))
-> Either SDoc Type -> Either SDoc ((Int, Int), Type)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Type -> Type -> Either SDoc Type
modifierType Type
m (Type -> DataCon -> [Type]
fieldTysAt Type
targetTy ([DataCon]
dcons [DataCon] -> Int -> DataCon
forall a. HasCallStack => [a] -> Int -> a
!! Int
ci) [Type] -> Int -> Type
forall a. HasCallStack => [a] -> Int -> a
!! Int
fi)
(here ++) <$> go (cells ++ claimed) rest
resolveAddr :: [DataCon] -> Type -> Addr -> Either SDoc [(Int, Int)]
resolveAddr :: [DataCon] -> Type -> Addr -> Either SDoc [(Int, Int)]
resolveAddr [DataCon]
dcons Type
targetTy Addr
addr = case Addr
addr of
AddrType Type
t
| Type
t Type -> Type -> Bool
`eqType` Type
targetTy -> [(Int, Int)] -> Either SDoc [(Int, Int)]
forall a b. b -> Either a b
Right ([DataCon] -> Type -> [(Int, Int)]
allCells [DataCon]
dcons Type
targetTy)
| Bool
otherwise -> case [ (Int
ci, Int
fi) | (Int
ci, DataCon
dc) <- [Int] -> [DataCon] -> [(Int, DataCon)]
forall a b. [a] -> [b] -> [(a, b)]
zip [Int
0 ..] [DataCon]
dcons
, (Int
fi, Type
ft) <- [Int] -> [Type] -> [(Int, Type)]
forall a b. [a] -> [b] -> [(a, b)]
zip [Int
0 ..] (Type -> DataCon -> [Type]
fieldTysAt Type
targetTy DataCon
dc)
, Type
ft Type -> Type -> Bool
`eqType` Type
t ] of
[] -> SDoc -> Either SDoc [(Int, Int)]
forall a b. a -> Either a b
Left (String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"Override: no field of type" SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> SDoc -> SDoc
quotes (Type -> SDoc
forall a. Outputable a => a -> SDoc
ppr Type
t))
[(Int, Int)]
cs -> [(Int, Int)] -> Either SDoc [(Int, Int)]
forall a b. b -> Either a b
Right [(Int, Int)]
cs
AddrPath [Hop]
hops -> [DataCon]
-> Type -> [(Int, Int)] -> [Hop] -> Either SDoc [(Int, Int)]
foldHops [DataCon]
dcons Type
targetTy ([DataCon] -> Type -> [(Int, Int)]
allCells [DataCon]
dcons Type
targetTy) [Hop]
hops
foldHops :: [DataCon] -> Type -> [(Int, Int)] -> [Hop] -> Either SDoc [(Int, Int)]
foldHops :: [DataCon]
-> Type -> [(Int, Int)] -> [Hop] -> Either SDoc [(Int, Int)]
foldHops [DataCon]
_ Type
_ [(Int, Int)]
scope [] = [(Int, Int)] -> Either SDoc [(Int, Int)]
forall a b. b -> Either a b
Right [(Int, Int)]
scope
foldHops [DataCon]
dcons Type
targetTy [(Int, Int)]
scope (HopCon FastString
nm : [Hop]
hs) =
case [ Int
ci | (Int
ci, DataCon
dc) <- [Int] -> [DataCon] -> [(Int, DataCon)]
forall a b. [a] -> [b] -> [(a, b)]
zip [Int
0 ..] [DataCon]
dcons, OccName -> FastString
occNameFS (DataCon -> OccName
forall a. NamedThing a => a -> OccName
getOccName DataCon
dc) FastString -> FastString -> Bool
forall a. Eq a => a -> a -> Bool
== FastString
nm ] of
[] -> SDoc -> Either SDoc [(Int, Int)]
forall a b. a -> Either a b
Left (String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"Override: unknown constructor" SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> SDoc -> SDoc
quotes (FastString -> SDoc
forall doc. IsLine doc => FastString -> doc
ftext FastString
nm))
[Int]
cis -> [DataCon]
-> Type -> [(Int, Int)] -> [Hop] -> Either SDoc [(Int, Int)]
foldHops [DataCon]
dcons Type
targetTy (((Int, Int) -> Bool) -> [(Int, Int)] -> [(Int, Int)]
forall a. (a -> Bool) -> [a] -> [a]
filter ((Int -> [Int] -> Bool
forall a. Eq a => a -> [a] -> Bool
forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem` [Int]
cis) (Int -> Bool) -> ((Int, Int) -> Int) -> (Int, Int) -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Int, Int) -> Int
forall a b. (a, b) -> a
fst) [(Int, Int)]
scope) [Hop]
hs
foldHops [DataCon]
dcons Type
targetTy [(Int, Int)]
scope (HopPos Integer
n : [Hop]
hs) =
case ((Int, Int) -> Bool) -> [(Int, Int)] -> [(Int, Int)]
forall a. (a -> Bool) -> [a] -> [a]
filter ((Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Integer -> Int
forall a. Num a => Integer -> a
fromInteger Integer
n) (Int -> Bool) -> ((Int, Int) -> Int) -> (Int, Int) -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Int, Int) -> Int
forall a b. (a, b) -> b
snd) [(Int, Int)]
scope of
[] -> SDoc -> Either SDoc [(Int, Int)]
forall a b. a -> Either a b
Left (String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"Override: no field at position" SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> Integer -> SDoc
forall doc. IsLine doc => Integer -> doc
integer Integer
n SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"in the addressed scope")
[(Int, Int)]
sc' -> [DataCon]
-> Type -> [(Int, Int)] -> [Hop] -> Either SDoc [(Int, Int)]
foldHops [DataCon]
dcons Type
targetTy [(Int, Int)]
sc' [Hop]
hs
foldHops [DataCon]
dcons Type
targetTy [(Int, Int)]
scope (HopLabel FastString
l : [Hop]
hs) =
case [ (Int
ci, Int
fi) | (Int
ci, Int
fi) <- [(Int, Int)]
scope, DataCon -> Int -> Maybe String
labelAt ([DataCon]
dcons [DataCon] -> Int -> DataCon
forall a. HasCallStack => [a] -> Int -> a
!! Int
ci) Int
fi Maybe String -> Maybe String -> Bool
forall a. Eq a => a -> a -> Bool
== String -> Maybe String
forall a. a -> Maybe a
Just (FastString -> String
unpackFS FastString
l) ] of
[] -> SDoc -> Either SDoc [(Int, Int)]
forall a b. a -> Either a b
Left (String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"Override: no field labelled" SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> SDoc -> SDoc
quotes (FastString -> SDoc
forall doc. IsLine doc => FastString -> doc
ftext FastString
l) SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"in the addressed scope")
[(Int, Int)]
sc' -> [DataCon]
-> Type -> [(Int, Int)] -> [Hop] -> Either SDoc [(Int, Int)]
foldHops [DataCon]
dcons Type
targetTy [(Int, Int)]
sc' [Hop]
hs
allCells :: [DataCon] -> Type -> [(Int, Int)]
allCells :: [DataCon] -> Type -> [(Int, Int)]
allCells [DataCon]
dcons Type
_ =
[ (Int
ci, Int
fi) | (Int
ci, DataCon
dc) <- [Int] -> [DataCon] -> [(Int, DataCon)]
forall a b. [a] -> [b] -> [(a, b)]
zip [Int
0 ..] [DataCon]
dcons, Int
fi <- [Int
0 .. DataCon -> Int
dataConSourceArity DataCon
dc Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
1] ]
labelAt :: DataCon -> Int -> Maybe String
labelAt :: DataCon -> Int -> Maybe String
labelAt DataCon
dc Int
i =
let ls :: [String]
ls = (FieldLabel -> String) -> [FieldLabel] -> [String]
forall a b. (a -> b) -> [a] -> [b]
map (OccName -> String
occNameString (OccName -> String)
-> (FieldLabel -> OccName) -> FieldLabel -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Name -> OccName
nameOccName (Name -> OccName) -> (FieldLabel -> Name) -> FieldLabel -> OccName
forall b c a. (b -> c) -> (a -> b) -> a -> c
. FieldLabel -> Name
flSelector) (DataCon -> [FieldLabel]
dataConFieldLabels DataCon
dc)
in if Int
i Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< [String] -> Int
forall a. [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [String]
ls then String -> Maybe String
forall a. a -> Maybe a
Just ([String]
ls [String] -> Int -> String
forall a. HasCallStack => [a] -> Int -> a
!! Int
i) else Maybe String
forall a. Maybe a
Nothing
modifierType :: Type -> Type -> Either SDoc Type
modifierType :: Type -> Type -> Either SDoc Type
modifierType Type
m Type
fieldTy
| Type
k Type -> Type -> Bool
`eqType` Type
liftedTypeKind = Type -> Either SDoc Type
forall a b. b -> Either a b
Right Type
m
| Type
k Type -> Type -> Bool
`eqType` HasDebugCallStack => Type -> Type -> Type
Type -> Type -> Type
mkVisFunTyMany Type
liftedTypeKind Type
liftedTypeKind = Type -> Either SDoc Type
forall a b. b -> Either a b
Right (Type -> Type -> Type
mkAppTy Type
m Type
fieldTy)
| Bool
otherwise = SDoc -> Either SDoc Type
forall a b. a -> Either a b
Left (String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"Override: modifier" SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> Type -> SDoc
forall a. Outputable a => a -> SDoc
ppr Type
m SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"has unsupported kind"
SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> Type -> SDoc
forall a. Outputable a => a -> SDoc
ppr Type
k SDoc -> SDoc -> SDoc
forall doc. IsLine doc => doc -> doc -> doc
<+> String -> SDoc
forall doc. IsLine doc => String -> doc
text String
"(expected Type or Type -> Type)")
where k :: Type
k = HasDebugCallStack => Type -> Type
Type -> Type
typeKind Type
m
promotedListElems :: Type -> Maybe [Type]
promotedListElems :: Type -> Maybe [Type]
promotedListElems Type
ty = do
(tc, args) <- HasDebugCallStack => Type -> Maybe (TyCon, [Type])
Type -> Maybe (TyCon, [Type])
splitTyConApp_maybe Type
ty
if | tc == promotedNilDataCon -> Just []
| tc == promotedConsDataCon -> case args of
[Type
_k, Type
x, Type
rest] -> (Type
x Type -> [Type] -> [Type]
forall a. a -> [a] -> [a]
:) ([Type] -> [Type]) -> Maybe [Type] -> Maybe [Type]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Type -> Maybe [Type]
promotedListElems Type
rest
[Type]
_ -> Maybe [Type]
forall a. Maybe a
Nothing
| otherwise -> Nothing
decodeEntry :: TyCon -> TyCon -> TyCon -> Type -> Maybe (Addr, Type)
decodeEntry :: TyCon -> TyCon -> TyCon -> Type -> Maybe (Addr, Type)
decodeEntry TyCon
arrowTc TyCon
assignTc TyCon
atTc Type
e
| Just ([Type]
hops, Type
m) <- TyCon -> Type -> Maybe ([Type], Type)
decodeArrow TyCon
arrowTc Type
e =
(\[Hop]
hs -> ([Hop] -> Addr
AddrPath [Hop]
hs, Type
m)) ([Hop] -> (Addr, Type)) -> Maybe [Hop] -> Maybe (Addr, Type)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (Type -> Maybe Hop) -> [Type] -> Maybe [Hop]
forall (t :: * -> *) (f :: * -> *) a b.
(Traversable t, Applicative f) =>
(a -> f b) -> t a -> f (t b)
forall (f :: * -> *) a b.
Applicative f =>
(a -> f b) -> [a] -> f [b]
traverse Type -> Maybe Hop
decodeHop [Type]
hops
| Just (TyCon
tc, [Type]
args) <- HasDebugCallStack => Type -> Maybe (TyCon, [Type])
Type -> Maybe (TyCon, [Type])
splitTyConApp_maybe Type
e, TyCon
tc TyCon -> TyCon -> Bool
forall a. Eq a => a -> a -> Bool
== TyCon
assignTc
, (Type
m : Type
sel : [Type]
_) <- [Type] -> [Type]
forall a. [a] -> [a]
reverse [Type]
args = (, Type
m) (Addr -> (Addr, Type)) -> Maybe Addr -> Maybe (Addr, Type)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> TyCon -> Type -> Maybe Addr
decodeSel TyCon
atTc Type
sel
| Bool
otherwise = Maybe (Addr, Type)
forall a. Maybe a
Nothing
decodeArrow :: TyCon -> Type -> Maybe ([Type], Type)
decodeArrow :: TyCon -> Type -> Maybe ([Type], Type)
decodeArrow TyCon
arrowTc Type
e = do
(tc, args) <- HasDebugCallStack => Type -> Maybe (TyCon, [Type])
Type -> Maybe (TyCon, [Type])
splitTyConApp_maybe Type
e
guard (tc == arrowTc)
case reverse args of
(Type
rhs : Type
lhs : [Type]
_) -> case TyCon -> Type -> Maybe ([Type], Type)
decodeArrow TyCon
arrowTc Type
rhs of
Just ([Type]
hs, Type
m) -> ([Type], Type) -> Maybe ([Type], Type)
forall a. a -> Maybe a
Just (Type
lhs Type -> [Type] -> [Type]
forall a. a -> [a] -> [a]
: [Type]
hs, Type
m)
Maybe ([Type], Type)
Nothing -> ([Type], Type) -> Maybe ([Type], Type)
forall a. a -> Maybe a
Just ([Type
lhs], Type
rhs)
[Type]
_ -> Maybe ([Type], Type)
forall a. Maybe a
Nothing
decodeHop :: Type -> Maybe Hop
decodeHop :: Type -> Maybe Hop
decodeHop Type
h
| Just FastString
fs <- Type -> Maybe FastString
isStrLitTy Type
h = Hop -> Maybe Hop
forall a. a -> Maybe a
Just (FastString -> Hop
HopLabel FastString
fs)
| Just Integer
n <- Type -> Maybe Integer
isNumLitTy Type
h = Hop -> Maybe Hop
forall a. a -> Maybe a
Just (Integer -> Hop
HopPos Integer
n)
| Just TyCon
tc <- Type -> Maybe TyCon
tyConAppTyCon_maybe Type
h = Hop -> Maybe Hop
forall a. a -> Maybe a
Just (FastString -> Hop
HopCon (OccName -> FastString
occNameFS (TyCon -> OccName
forall a. NamedThing a => a -> OccName
getOccName TyCon
tc)))
| Bool
otherwise = Maybe Hop
forall a. Maybe a
Nothing
decodeSel :: TyCon -> Type -> Maybe Addr
decodeSel :: TyCon -> Type -> Maybe Addr
decodeSel TyCon
atTc Type
sel
| Just FastString
fs <- Type -> Maybe FastString
isStrLitTy Type
sel = Addr -> Maybe Addr
forall a. a -> Maybe a
Just ([Hop] -> Addr
AddrPath [FastString -> Hop
HopLabel FastString
fs])
| Just (TyCon
tc, [Type]
args) <- HasDebugCallStack => Type -> Maybe (TyCon, [Type])
Type -> Maybe (TyCon, [Type])
splitTyConApp_maybe Type
sel, TyCon
tc TyCon -> TyCon -> Bool
forall a. Eq a => a -> a -> Bool
== TyCon
atTc
, (Type
pos : Type
con : [Type]
_) <- [Type] -> [Type]
forall a. [a] -> [a]
reverse [Type]
args, Just Integer
n <- Type -> Maybe Integer
isNumLitTy Type
pos
, Just TyCon
ctc <- Type -> Maybe TyCon
tyConAppTyCon_maybe Type
con =
Addr -> Maybe Addr
forall a. a -> Maybe a
Just ([Hop] -> Addr
AddrPath [FastString -> Hop
HopCon (OccName -> FastString
occNameFS (TyCon -> OccName
forall a. NamedThing a => a -> OccName
getOccName TyCon
ctc)), Integer -> Hop
HopPos Integer
n])
| Bool
otherwise = Addr -> Maybe Addr
forall a. a -> Maybe a
Just (Type -> Addr
AddrType Type
sel)
reprOverridden :: Repr -> Bool
reprOverridden :: Repr -> Bool
reprOverridden = (ConInfo -> Bool) -> [ConInfo] -> Bool
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
any ((Coercion -> Bool) -> [Coercion] -> Bool
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
any (Bool -> Bool
not (Bool -> Bool) -> (Coercion -> Bool) -> Coercion -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Coercion -> Bool
isReflCo) ([Coercion] -> Bool) -> (ConInfo -> [Coercion]) -> ConInfo -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ConInfo -> [Coercion]
ciFieldCos) ([ConInfo] -> Bool) -> (Repr -> [ConInfo]) -> Repr -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Repr -> [ConInfo]
rCons
reprHasFields, reprIsEnum, reprSingleCon, reprEmpty :: Repr -> Bool
reprHasFields :: Repr -> Bool
reprHasFields = (ConInfo -> Bool) -> [ConInfo] -> Bool
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
any (Bool -> Bool
not (Bool -> Bool) -> (ConInfo -> Bool) -> ConInfo -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [Type] -> Bool
forall a. [a] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null ([Type] -> Bool) -> (ConInfo -> [Type]) -> ConInfo -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ConInfo -> [Type]
ciFields) ([ConInfo] -> Bool) -> (Repr -> [ConInfo]) -> Repr -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Repr -> [ConInfo]
rCons
reprIsEnum :: Repr -> Bool
reprIsEnum Repr
r = Bool -> Bool
not (Repr -> Bool
reprEmpty Repr
r) Bool -> Bool -> Bool
&& Bool -> Bool
not (Repr -> Bool
reprHasFields Repr
r)
reprSingleCon :: Repr -> Bool
reprSingleCon = (Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
1) (Int -> Bool) -> (Repr -> Int) -> Repr -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [ConInfo] -> Int
forall a. [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length ([ConInfo] -> Int) -> (Repr -> [ConInfo]) -> Repr -> Int
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Repr -> [ConInfo]
rCons
reprEmpty :: Repr -> Bool
reprEmpty = [ConInfo] -> Bool
forall a. [a] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null ([ConInfo] -> Bool) -> (Repr -> [ConInfo]) -> Repr -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Repr -> [ConInfo]
rCons
reprUnpacked :: Repr -> Bool
reprUnpacked :: Repr -> Bool
reprUnpacked = (ConInfo -> Bool) -> [ConInfo] -> Bool
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
any (DataCon -> Bool
dcUnpacked (DataCon -> Bool) -> (ConInfo -> DataCon) -> ConInfo -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ConInfo -> DataCon
ciCon) ([ConInfo] -> Bool) -> (Repr -> [ConInfo]) -> Repr -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Repr -> [ConInfo]
rCons
dcUnpacked :: DataCon -> Bool
dcUnpacked :: DataCon -> Bool
dcUnpacked DataCon
dc =
let rep :: [Type]
rep = (Scaled Type -> Type) -> [Scaled Type] -> [Type]
forall a b. (a -> b) -> [a] -> [b]
map Scaled Type -> Type
forall a. Scaled a -> a
scaledThing (DataCon -> [Scaled Type]
dataConRepArgTys DataCon
dc)
orig :: [Type]
orig = (Scaled Type -> Type) -> [Scaled Type] -> [Type]
forall a b. (a -> b) -> [a] -> [b]
map Scaled Type -> Type
forall a. Scaled a -> a
scaledThing (DataCon -> [Scaled Type]
dataConOrigArgTys DataCon
dc)
in [Type] -> Int
forall a. [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [Type]
rep Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
/= [Type] -> Int
forall a. [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [Type]
orig Bool -> Bool -> Bool
|| Bool -> Bool
not ([Bool] -> Bool
forall (t :: * -> *). Foldable t => t Bool -> Bool
and ((Type -> Type -> Bool) -> [Type] -> [Type] -> [Bool]
forall a b c. (a -> b -> c) -> [a] -> [b] -> [c]
zipWith Type -> Type -> Bool
eqType [Type]
rep [Type]
orig))
mkClassDict :: Class -> Type -> [CoreExpr] -> CoreExpr
mkClassDict :: Class -> Type -> [CoreExpr] -> CoreExpr
mkClassDict Class
cls Type
ty [CoreExpr]
methods =
CoreExpr -> [CoreExpr] -> CoreExpr
forall b. Expr b -> [Expr b] -> Expr b
mkApps (Id -> CoreExpr
forall b. Id -> Expr b
Var (DataCon -> Id
dataConWorkId (Class -> DataCon
classDataCon Class
cls))) (Type -> CoreExpr
forall b. Type -> Expr b
Type Type
ty CoreExpr -> [CoreExpr] -> [CoreExpr]
forall a. a -> [a] -> [a]
: [CoreExpr]
methods)
fieldTysAt :: Type -> DataCon -> [Type]
fieldTysAt :: Type -> DataCon -> [Type]
fieldTysAt Type
innerTy DataCon
dc = (Scaled Type -> Type) -> [Scaled Type] -> [Type]
forall a b. (a -> b) -> [a] -> [b]
map Scaled Type -> Type
forall a. Scaled a -> a
scaledThing (DataCon -> [Type] -> [Scaled Type]
dataConInstOrigArgTys DataCon
dc (HasCallStack => Type -> [Type]
Type -> [Type]
tyConAppArgs Type
innerTy))
conAppAt :: Type -> DataCon -> [CoreExpr] -> CoreExpr
conAppAt :: Type -> DataCon -> [CoreExpr] -> CoreExpr
conAppAt Type
innerTy DataCon
dc [CoreExpr]
args = DataCon -> [CoreExpr] -> CoreExpr
mkCoreConApps DataCon
dc ((Type -> CoreExpr) -> [Type] -> [CoreExpr]
forall a b. (a -> b) -> [a] -> [b]
map Type -> CoreExpr
forall b. Type -> Expr b
Type (HasCallStack => Type -> [Type]
Type -> [Type]
tyConAppArgs Type
innerTy) [CoreExpr] -> [CoreExpr] -> [CoreExpr]
forall a. [a] -> [a] -> [a]
++ [CoreExpr]
args)
recClassDict :: Class -> Type -> (Id -> TcPluginM [CoreExpr]) -> TcPluginM CoreExpr
recClassDict :: Class -> Type -> (Id -> TcPluginM [CoreExpr]) -> TcPluginM CoreExpr
recClassDict Class
cls Type
ty Id -> TcPluginM [CoreExpr]
mk = do
dvar <- Type -> String -> TcPluginM Id
freshId (Class -> [Type] -> Type
mkClassPred Class
cls [Type
ty]) String
"dict"
fields <- mk dvar
pure (Let (Rec [(dvar, mkClassDict cls ty fields)]) (Var dvar))
recDictWith :: Class -> Type -> [CoreExpr] -> [(Int, CoreExpr)] -> TcPluginM CoreExpr
recDictWith :: Class
-> Type -> [CoreExpr] -> [(Int, CoreExpr)] -> TcPluginM CoreExpr
recDictWith Class
cls Type
ty [CoreExpr]
supers [(Int, CoreExpr)]
overrides = do
dvar <- Type -> String -> TcPluginM Id
freshId (Class -> [Type] -> Type
mkClassPred Class
cls [Type
ty]) String
"dict"
methodFields <- for (zip [0 ..] (classMethods cls)) \(Int
i, Id
_) ->
case Int -> [(Int, CoreExpr)] -> Maybe CoreExpr
forall a b. Eq a => a -> [(a, b)] -> Maybe b
lookup Int
i [(Int, CoreExpr)]
overrides of
Just CoreExpr
e -> CoreExpr -> TcPluginM CoreExpr
forall a. a -> TcPluginM a
forall (f :: * -> *) a. Applicative f => a -> f a
pure CoreExpr
e
Maybe CoreExpr
Nothing -> do dm <- Class -> Int -> TcPluginM Id
defMethId Class
cls Int
i
pure (mkApps (Var dm) [Type ty, Var dvar])
pure (Let (Rec [(dvar, mkClassDict cls ty (supers ++ methodFields))]) (Var dvar))
data FieldKind = FParam | FConst | FApp Type
classifyField :: TyVar -> Type -> Type -> Maybe FieldKind
classifyField :: Id -> Type -> Type -> Maybe FieldKind
classifyField Id
atv Type
aTy Type
ft
| Type
ft Type -> Type -> Bool
`eqType` Type
aTy = FieldKind -> Maybe FieldKind
forall a. a -> Maybe a
Just FieldKind
FParam
| Bool -> Bool
not (Id
atv Id -> VarSet -> Bool
`elemVarSet` Type -> VarSet
tyCoVarsOfType Type
ft) = FieldKind -> Maybe FieldKind
forall a. a -> Maybe a
Just FieldKind
FConst
| Just (Type
h, Type
larg) <- Type -> Maybe (Type, Type)
splitAppTy_maybe Type
ft
, Type
larg Type -> Type -> Bool
`eqType` Type
aTy
, Bool -> Bool
not (Id
atv Id -> VarSet -> Bool
`elemVarSet` Type -> VarSet
tyCoVarsOfType Type
h) = FieldKind -> Maybe FieldKind
forall a. a -> Maybe a
Just (Type -> FieldKind
FApp Type
h)
| Bool
otherwise = Maybe FieldKind
forall a. Maybe a
Nothing
data Roles r = Roles
{ forall r. Roles r -> r
onParam :: r
, forall r. Roles r -> CtEvidence -> Type -> r
onConst :: CtEvidence -> Type -> r
, forall r. Roles r -> CtEvidence -> Type -> (Type -> Coercion) -> r
onApply :: CtEvidence -> Type -> (Type -> Coercion) -> r
}
interpField :: Class
-> Class
-> TyVar -> Type -> CtLoc
-> Maybe Type
-> Roles r -> Type -> TcPluginM (Maybe (r, [Ct]))
interpField :: forall r.
Class
-> Class
-> Id
-> Type
-> CtLoc
-> Maybe Type
-> Roles r
-> Type
-> TcPluginM (Maybe (r, [Ct]))
interpField Class
constCls Class
liftCls Id
atv Type
aTy CtLoc
loc Maybe Type
mMod Roles r
roles Type
ftA =
case Id -> Type -> Type -> Maybe FieldKind
classifyField Id
atv Type
aTy Type
ftA of
Maybe FieldKind
Nothing -> Maybe (r, [Ct]) -> TcPluginM (Maybe (r, [Ct]))
forall a. a -> TcPluginM a
forall (f :: * -> *) a. Applicative f => a -> f a
pure Maybe (r, [Ct])
forall a. Maybe a
Nothing
Just FieldKind
FParam -> Maybe (r, [Ct]) -> TcPluginM (Maybe (r, [Ct]))
forall a. a -> TcPluginM a
forall (f :: * -> *) a. Applicative f => a -> f a
pure ((r, [Ct]) -> Maybe (r, [Ct])
forall a. a -> Maybe a
Just (Roles r -> r
forall r. Roles r -> r
onParam Roles r
roles, []))
Just FieldKind
FConst -> do
ev <- CtLoc -> Type -> TcPluginM CtEvidence
newWanted CtLoc
loc (Class -> [Type] -> Type
mkClassPred Class
constCls [Type
ftA])
pure (Just (onConst roles ev ftA, [mkNonCanonical ev]))
Just (FApp Type
h) -> do
let m :: Type
m = Type -> Maybe Type -> Type
forall a. a -> Maybe a -> a
fromMaybe Type
h Maybe Type
mMod
coB :: Type -> Coercion
coB Type
t = case Maybe Type
mMod of
Maybe Type
Nothing -> Type -> Coercion
mkRepReflCo (Type -> Type -> Type
mkAppTy Type
h Type
t)
Just Type
_ -> UnivCoProvenance -> Role -> Type -> Type -> Coercion
mkStockCo (String -> UnivCoProvenance
PluginProv String
"stock") Role
Representational
(Type -> Type -> Type
mkAppTy Type
h Type
t) (Type -> Type -> Type
mkAppTy Type
m Type
t)
ev <- CtLoc -> Type -> TcPluginM CtEvidence
newWanted CtLoc
loc (Class -> [Type] -> Type
mkClassPred Class
liftCls [Type
m])
pure (Just (onApply roles ev m coB, [mkNonCanonical ev]))
fieldsAt :: [Type] -> DataCon -> Type -> [Type]
fieldsAt :: [Type] -> DataCon -> Type -> [Type]
fieldsAt [Type]
fixed DataCon
dc Type
ty = (Scaled Type -> Type) -> [Scaled Type] -> [Type]
forall a b. (a -> b) -> [a] -> [b]
map Scaled Type -> Type
forall a. Scaled a -> a
scaledThing (DataCon -> [Type] -> [Scaled Type]
dataConInstOrigArgTys DataCon
dc ([Type]
fixed [Type] -> [Type] -> [Type]
forall a. [a] -> [a] -> [a]
++ [Type
ty]))
zipLift2 :: TyCon -> [Type] -> (Type -> Coercion)
-> Type -> Type -> Type
-> Id -> Id
-> (Int -> Int -> CoreExpr)
-> ([CoreExpr] -> TcPluginM CoreExpr)
-> (Int -> Type -> Id -> Id -> TcPluginM (Maybe (CoreExpr, [Ct])))
-> TcPluginM (Maybe (CoreExpr, [Ct]))
zipLift2 :: TyCon
-> [Type]
-> (Type -> Coercion)
-> Type
-> Type
-> Type
-> Id
-> Id
-> (Int -> Int -> CoreExpr)
-> ([CoreExpr] -> TcPluginM CoreExpr)
-> (Int -> Type -> Id -> Id -> TcPluginM (Maybe (CoreExpr, [Ct])))
-> TcPluginM (Maybe (CoreExpr, [Ct]))
zipLift2 TyCon
fTc [Type]
fixed Type -> Coercion
coAt Type
aTy Type
bTy Type
resTy Id
faId Id
fbId Int -> Int -> CoreExpr
mismatch [CoreExpr] -> TcPluginM CoreExpr
combine Int -> Type -> Id -> Id -> TcPluginM (Maybe (CoreExpr, [Ct]))
fieldOp = do
let dcons :: [DataCon]
dcons = TyCon -> [DataCon]
tyConDataCons TyCon
fTc
innerA :: Type
innerA = TyCon -> [Type] -> Type
mkTyConApp TyCon
fTc ([Type]
fixed [Type] -> [Type] -> [Type]
forall a. [a] -> [a] -> [a]
++ [Type
aTy])
innerB :: Type
innerB = TyCon -> [Type] -> Type
mkTyConApp TyCon
fTc ([Type]
fixed [Type] -> [Type] -> [Type]
forall a. [a] -> [a] -> [a]
++ [Type
bTy])
indexed :: [(Int, DataCon)]
indexed = [Int] -> [DataCon] -> [(Int, DataCon)]
forall a b. [a] -> [b] -> [(a, b)]
zip [Int
0 :: Int ..] [DataCon]
dcons
freshFields :: DataCon -> Type -> TcPluginM [Id]
freshFields DataCon
dc Type
ty = (Int -> Type -> TcPluginM Id) -> [Int] -> [Type] -> TcPluginM [Id]
forall (m :: * -> *) a b c.
Applicative m =>
(a -> b -> m c) -> [a] -> [b] -> m [c]
zipWithM (\Int
n Type
ft -> Type -> String -> TcPluginM Id
freshId Type
ft (String
"x" String -> String -> String
forall a. [a] -> [a] -> [a]
++ Int -> String
forall a. Show a => a -> String
show Int
n)) [Int
0 :: Int ..]
([Type] -> DataCon -> Type -> [Type]
fieldsAt [Type]
fixed DataCon
dc Type
ty)
mInner <- [(Int, DataCon)]
-> ((Int, DataCon) -> TcPluginM (Maybe (Alt Id, [Ct])))
-> TcPluginM [Maybe (Alt Id, [Ct])]
forall (t :: * -> *) (f :: * -> *) a b.
(Traversable t, Applicative f) =>
t a -> (a -> f b) -> f (t b)
for [(Int, DataCon)]
indexed \(Int
i, DataCon
dci) -> do
xs <- DataCon -> Type -> TcPluginM [Id]
freshFields DataCon
dci Type
aTy
mAlts <- for indexed \(Int
j, DataCon
dcj) -> do
ys <- DataCon -> Type -> TcPluginM [Id]
freshFields DataCon
dcj Type
bTy
if i /= j
then pure (Just (Alt (DataAlt dcj) ys (mismatch i j), []))
else do
mops <- sequence (zipWith4 fieldOp [0 :: Int ..] (fieldsAt fixed dci aTy) xs ys)
case sequence mops of
Maybe [(CoreExpr, [Ct])]
Nothing -> Maybe (Alt Id, [Ct]) -> TcPluginM (Maybe (Alt Id, [Ct]))
forall a. a -> TcPluginM a
forall (f :: * -> *) a. Applicative f => a -> f a
pure Maybe (Alt Id, [Ct])
forall a. Maybe a
Nothing
Just [(CoreExpr, [Ct])]
ows -> do
body <- [CoreExpr] -> TcPluginM CoreExpr
combine (((CoreExpr, [Ct]) -> CoreExpr) -> [(CoreExpr, [Ct])] -> [CoreExpr]
forall a b. (a -> b) -> [a] -> [b]
map (CoreExpr, [Ct]) -> CoreExpr
forall a b. (a, b) -> a
fst [(CoreExpr, [Ct])]
ows)
pure (Just (Alt (DataAlt dcj) ys body, concatMap snd ows))
case sequence mAlts of
Maybe [(Alt Id, [Ct])]
Nothing -> Maybe (Alt Id, [Ct]) -> TcPluginM (Maybe (Alt Id, [Ct]))
forall a. a -> TcPluginM a
forall (f :: * -> *) a. Applicative f => a -> f a
pure Maybe (Alt Id, [Ct])
forall a. Maybe a
Nothing
Just [(Alt Id, [Ct])]
altWss -> do
let ([Alt Id]
alts, [[Ct]]
wss) = [(Alt Id, [Ct])] -> ([Alt Id], [[Ct]])
forall a b. [(a, b)] -> ([a], [b])
unzip [(Alt Id, [Ct])]
altWss
cbB <- Type -> String -> TcPluginM Id
freshId Type
innerB String
"cbb"
pure (Just ( Alt (DataAlt dci) xs
(destructInner fTc (fixed ++ [bTy]) (Cast (Var fbId) (coAt bTy)) cbB resTy alts)
, concat wss ))
case sequence mInner of
Maybe [(Alt Id, [Ct])]
Nothing -> Maybe (CoreExpr, [Ct]) -> TcPluginM (Maybe (CoreExpr, [Ct]))
forall a. a -> TcPluginM a
forall (f :: * -> *) a. Applicative f => a -> f a
pure Maybe (CoreExpr, [Ct])
forall a. Maybe a
Nothing
Just [(Alt Id, [Ct])]
altWss -> do
let ([Alt Id]
alts, [[Ct]]
wss) = [(Alt Id, [Ct])] -> ([Alt Id], [[Ct]])
forall a b. [(a, b)] -> ([a], [b])
unzip [(Alt Id, [Ct])]
altWss
cbA <- Type -> String -> TcPluginM Id
freshId Type
innerA String
"cba"
pure (Just ( destructInner fTc (fixed ++ [aTy]) (Cast (Var faId) (coAt aTy)) cbA resTy alts
, concat wss ))
newtype Solver = Solver
{ Solver
-> PluginState -> Ct -> Class -> Type -> TcPluginM (Maybe Attempt)
runSolver :: PluginState -> Ct -> Class -> Type -> TcPluginM (Maybe Attempt) }
deriving (NonEmpty Solver -> Solver
Solver -> Solver -> Solver
(Solver -> Solver -> Solver)
-> (NonEmpty Solver -> Solver)
-> (forall b. Integral b => b -> Solver -> Solver)
-> Semigroup Solver
forall b. Integral b => b -> Solver -> Solver
forall a.
(a -> a -> a)
-> (NonEmpty a -> a)
-> (forall b. Integral b => b -> a -> a)
-> Semigroup a
$c<> :: Solver -> Solver -> Solver
<> :: Solver -> Solver -> Solver
$csconcat :: NonEmpty Solver -> Solver
sconcat :: NonEmpty Solver -> Solver
$cstimes :: forall b. Integral b => b -> Solver -> Solver
stimes :: forall b. Integral b => b -> Solver -> Solver
Semigroup, Semigroup Solver
Solver
Semigroup Solver =>
Solver
-> (Solver -> Solver -> Solver)
-> ([Solver] -> Solver)
-> Monoid Solver
[Solver] -> Solver
Solver -> Solver -> Solver
forall a.
Semigroup a =>
a -> (a -> a -> a) -> ([a] -> a) -> Monoid a
$cmempty :: Solver
mempty :: Solver
$cmappend :: Solver -> Solver -> Solver
mappend :: Solver -> Solver -> Solver
$cmconcat :: [Solver] -> Solver
mconcat :: [Solver] -> Solver
Monoid)
via (PluginState -> Ct -> Class -> Type -> Mon.Alt (MaybeT TcPluginM) Attempt)
notImplemented :: PluginState -> Ct -> SDoc -> TcPluginM Attempt
notImplemented :: PluginState -> Ct -> SDoc -> TcPluginM Attempt
notImplemented PluginState
st Ct
ct SDoc
doc = do
let key :: String
key = SDoc -> String
showSDocUnsafe SDoc
doc
seen <- IO [String] -> TcPluginM [String]
forall a. IO a -> TcPluginM a
tcPluginIO (IORef [String] -> IO [String]
forall a. IORef a -> IO a
readIORef (PluginState -> IORef [String]
psSeen PluginState
st))
unless (key `elem` seen) $ do
tcPluginIO (modifyIORef' (psSeen st) (key :))
unsafeTcPluginTcM (addErrTc (mkTcRnUnknownMessage (mkPlainError noHints doc)))
pure (Nothing, [], [ct])
freshId :: Type -> String -> TcPluginM Id
freshId :: Type -> String -> TcPluginM Id
freshId Type
ty String
s = do
u <- TcM Unique -> TcPluginM Unique
forall a. TcM a -> TcPluginM a
unsafeTcPluginTcM TcM Unique
forall (m :: * -> *). MonadUnique m => m Unique
getUniqueM
pure (mkLocalId (mkSystemName u (mkVarOcc s)) manyDataConTy ty)
toDatatype :: Type -> Repr -> Datatype
toDatatype :: Type -> Repr -> Datatype
toDatatype Type
via Repr
repr = Datatype
{ dtVia :: Type
dtVia = Type
via
, dtUnwrap :: Coercion
dtUnwrap = Repr -> Coercion
rCo Repr
repr
, dtType :: Type
dtType = Repr -> Type
rInner Repr
repr
, dtCons :: [Constructor]
dtCons = [ DataCon
-> [Type]
-> Fixity
-> Maybe [FieldLabel]
-> [Coercion]
-> Constructor
Constructor DataCon
dc (ConInfo -> [Type]
ciFields ConInfo
ci) Fixity
defaultFixity Maybe [FieldLabel]
labels (ConInfo -> [Coercion]
ciFieldCos ConInfo
ci)
| ConInfo
ci <- Repr -> [ConInfo]
rCons Repr
repr
, let dc :: DataCon
dc = ConInfo -> DataCon
ciCon ConInfo
ci
fls :: [FieldLabel]
fls = DataCon -> [FieldLabel]
dataConFieldLabels DataCon
dc
labels :: Maybe [FieldLabel]
labels = if [FieldLabel] -> Bool
forall a. [a] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [FieldLabel]
fls then Maybe [FieldLabel]
forall a. Maybe a
Nothing else [FieldLabel] -> Maybe [FieldLabel]
forall a. a -> Maybe a
Just [FieldLabel]
fls ]
}
runDeriverAttempt :: Deriver -> Ct -> Class -> Datatype -> TcPluginM Attempt
runDeriverAttempt :: Deriver -> Ct -> Class -> Datatype -> TcPluginM Attempt
runDeriverAttempt Deriver
drv Ct
ct Class
cls Datatype
dt = do
(ev, ws) <- CtLoc -> Synth EvTerm -> TcPluginM (EvTerm, [Ct])
forall a. CtLoc -> Synth a -> TcPluginM (a, [Ct])
runSynth (Ct -> CtLoc
ctLoc Ct
ct) (Deriver -> Class -> Datatype -> Synth EvTerm
runDeriver Deriver
drv Class
cls Datatype
dt)
pure (Just (ev, ct), ws, [])
tryWitness :: PluginState -> Ct -> Class -> Datatype -> TcPluginM (Maybe Attempt)
tryWitness :: PluginState -> Ct -> Class -> Datatype -> TcPluginM (Maybe Attempt)
tryWitness PluginState
st Ct
ct Class
cls Datatype
dt =
case GenEnv -> Maybe Class
geWitness (PluginState -> GenEnv
psGen PluginState
st) of
Maybe Class
Nothing -> Maybe Attempt -> TcPluginM (Maybe Attempt)
forall a. a -> TcPluginM a
forall (f :: * -> *) a. Applicative f => a -> f a
pure Maybe Attempt
forall a. Maybe a
Nothing
Just Class
witCls -> do
instEnvs <- TcPluginM InstEnvs
getInstEnvs
let clsTy = TyCon -> Type
mkTyConTy (Class -> TyCon
classTyCon Class
cls)
matches = [ ClsInst
inst | ClsInst
inst <- InstEnvs -> Class -> [ClsInst]
classInstances InstEnvs
instEnvs Class
witCls
, [Type
headTy] <- [ClsInst -> [Type]
is_tys ClsInst
inst], Type
headTy Type -> Type -> Bool
`eqType` Type
clsTy ]
case matches of
[] -> Maybe Attempt -> TcPluginM (Maybe Attempt)
forall a. a -> TcPluginM a
forall (f :: * -> *) a. Applicative f => a -> f a
pure Maybe Attempt
forall a. Maybe a
Nothing
(ClsInst
inst : [ClsInst]
_) -> do
let dfun :: Id
dfun = ClsInst -> Id
is_dfun ClsInst
inst
hsc <- TcPluginM HscEnv
getTopEnv
r <- unsafeTcPluginTcM $ liftIO $
getValueSafely hsc (idName dfun) (idType dfun)
case r of
Right (Deriver
drv, [Linkable]
_, PkgsLoaded
_) -> Attempt -> Maybe Attempt
forall a. a -> Maybe a
Just (Attempt -> Maybe Attempt)
-> TcPluginM Attempt -> TcPluginM (Maybe Attempt)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Deriver -> Ct -> Class -> Datatype -> TcPluginM Attempt
runDeriverAttempt Deriver
drv Ct
ct Class
cls Datatype
dt
Left Type
_ -> Maybe Attempt -> TcPluginM (Maybe Attempt)
forall a. a -> TcPluginM a
forall (f :: * -> *) a. Applicative f => a -> f a
pure Maybe Attempt
forall a. Maybe a
Nothing
tryWitness1 :: PluginState -> Ct -> Class -> Type -> Type -> TcPluginM (Maybe Attempt)
tryWitness1 :: PluginState
-> Ct -> Class -> Type -> Type -> TcPluginM (Maybe Attempt)
tryWitness1 PluginState
st Ct
ct Class
cls Type
wrappedTy Type
f =
case GenEnv -> Maybe Class
geWitness1 (PluginState -> GenEnv
psGen PluginState
st) of
Maybe Class
Nothing -> Maybe Attempt -> TcPluginM (Maybe Attempt)
forall a. a -> TcPluginM a
forall (f :: * -> *) a. Applicative f => a -> f a
pure Maybe Attempt
forall a. Maybe a
Nothing
Just Class
witCls -> do
instEnvs <- TcPluginM InstEnvs
getInstEnvs
let clsTy = TyCon -> Type
mkTyConTy (Class -> TyCon
classTyCon Class
cls)
matches = [ ClsInst
inst | ClsInst
inst <- InstEnvs -> Class -> [ClsInst]
classInstances InstEnvs
instEnvs Class
witCls
, [Type
headTy] <- [ClsInst -> [Type]
is_tys ClsInst
inst], Type
headTy Type -> Type -> Bool
`eqType` Type
clsTy ]
case matches of
[] -> Maybe Attempt -> TcPluginM (Maybe Attempt)
forall a. a -> TcPluginM a
forall (f :: * -> *) a. Applicative f => a -> f a
pure Maybe Attempt
forall a. Maybe a
Nothing
(ClsInst
inst : [ClsInst]
_) -> do
let dfun :: Id
dfun = ClsInst -> Id
is_dfun ClsInst
inst
hsc <- TcPluginM HscEnv
getTopEnv
r <- unsafeTcPluginTcM $ liftIO $
getValueSafely hsc (idName dfun) (idType dfun)
case r of
Right (Deriver1 Class -> CtLoc -> Type -> Type -> TcPluginM (Maybe (EvTerm, [Ct]))
synth, [Linkable]
_, PkgsLoaded
_) -> do
m <- Class -> CtLoc -> Type -> Type -> TcPluginM (Maybe (EvTerm, [Ct]))
synth Class
cls (Ct -> CtLoc
ctLoc Ct
ct) Type
wrappedTy Type
f
pure $ case m of
Just (EvTerm
ev, [Ct]
ws) -> Attempt -> Maybe Attempt
forall a. a -> Maybe a
Just ((EvTerm, Ct) -> Maybe (EvTerm, Ct)
forall a. a -> Maybe a
Just (EvTerm
ev, Ct
ct), [Ct]
ws, [])
Maybe (EvTerm, [Ct])
Nothing -> Maybe Attempt
forall a. Maybe a
Nothing
Left Type
_ -> Maybe Attempt -> TcPluginM (Maybe Attempt)
forall a. a -> TcPluginM a
forall (f :: * -> *) a. Applicative f => a -> f a
pure Maybe Attempt
forall a. Maybe a
Nothing
tryWitness2 :: PluginState -> Ct -> Class -> Type -> Type -> TcPluginM (Maybe Attempt)
tryWitness2 :: PluginState
-> Ct -> Class -> Type -> Type -> TcPluginM (Maybe Attempt)
tryWitness2 PluginState
st Ct
ct Class
cls Type
wrappedTy Type
p =
case GenEnv -> Maybe Class
geWitness2 (PluginState -> GenEnv
psGen PluginState
st) of
Maybe Class
Nothing -> Maybe Attempt -> TcPluginM (Maybe Attempt)
forall a. a -> TcPluginM a
forall (f :: * -> *) a. Applicative f => a -> f a
pure Maybe Attempt
forall a. Maybe a
Nothing
Just Class
witCls -> do
instEnvs <- TcPluginM InstEnvs
getInstEnvs
let clsTy = TyCon -> Type
mkTyConTy (Class -> TyCon
classTyCon Class
cls)
matches = [ ClsInst
inst | ClsInst
inst <- InstEnvs -> Class -> [ClsInst]
classInstances InstEnvs
instEnvs Class
witCls
, [Type
headTy] <- [ClsInst -> [Type]
is_tys ClsInst
inst], Type
headTy Type -> Type -> Bool
`eqType` Type
clsTy ]
case matches of
[] -> Maybe Attempt -> TcPluginM (Maybe Attempt)
forall a. a -> TcPluginM a
forall (f :: * -> *) a. Applicative f => a -> f a
pure Maybe Attempt
forall a. Maybe a
Nothing
(ClsInst
inst : [ClsInst]
_) -> do
let dfun :: Id
dfun = ClsInst -> Id
is_dfun ClsInst
inst
hsc <- TcPluginM HscEnv
getTopEnv
r <- unsafeTcPluginTcM $ liftIO $
getValueSafely hsc (idName dfun) (idType dfun)
case r of
Right (Deriver2 Class -> CtLoc -> Type -> Type -> TcPluginM (Maybe (EvTerm, [Ct]))
synth, [Linkable]
_, PkgsLoaded
_) -> do
m <- Class -> CtLoc -> Type -> Type -> TcPluginM (Maybe (EvTerm, [Ct]))
synth Class
cls (Ct -> CtLoc
ctLoc Ct
ct) Type
wrappedTy Type
p
pure $ case m of
Just (EvTerm
ev, [Ct]
ws) -> Attempt -> Maybe Attempt
forall a. a -> Maybe a
Just ((EvTerm, Ct) -> Maybe (EvTerm, Ct)
forall a. a -> Maybe a
Just (EvTerm
ev, Ct
ct), [Ct]
ws, [])
Maybe (EvTerm, [Ct])
Nothing -> Maybe Attempt
forall a. Maybe a
Nothing
Left Type
_ -> Maybe Attempt -> TcPluginM (Maybe Attempt)
forall a. a -> TcPluginM a
forall (f :: * -> *) a. Applicative f => a -> f a
pure Maybe Attempt
forall a. Maybe a
Nothing
conPrec :: DataCon -> TcPluginM Integer
conPrec :: DataCon -> TcPluginM Integer
conPrec DataCon
dc = do
#if MIN_VERSION_ghc(9,12,0)
Fixity p _ <- unsafeTcPluginTcM (lookupFixityRn (dataConName dc))
#else
Fixity _ p _ <- TcM Fixity -> TcPluginM Fixity
forall a. TcM a -> TcPluginM a
unsafeTcPluginTcM (Name -> TcM Fixity
lookupFixityRn (DataCon -> Name
dataConName DataCon
dc))
#endif
pure (fromIntegral p)
defMethId :: Class -> Int -> TcPluginM Id
defMethId :: Class -> Int -> TcPluginM Id
defMethId Class
cls Int
i =
case (Id, DefMethInfo) -> DefMethInfo
forall a b. (a, b) -> b
snd (Class -> [(Id, DefMethInfo)]
classOpItems Class
cls [(Id, DefMethInfo)] -> Int -> (Id, DefMethInfo)
forall a. HasCallStack => [a] -> Int -> a
!! Int
i) of
Just (Name
nm, DefMethSpec Type
_) -> Name -> TcPluginM Id
tcLookupId Name
nm
DefMethInfo
Nothing -> String -> TcPluginM Id
forall a. HasCallStack => String -> a
error String
"stock: expected a default method"
data Variance = Cov | Con
flipV :: Variance -> Variance
flipV :: Variance -> Variance
flipV Variance
Cov = Variance
Con
flipV Variance
Con = Variance
Cov
varMap :: Class -> Maybe Class -> CtLoc -> TyVar -> Type
-> Maybe CoreExpr -> Maybe CoreExpr
-> Variance -> Type -> TcPluginM (Maybe (CoreExpr, [Ct]))
varMap :: Class
-> Maybe Class
-> CtLoc
-> Id
-> Type
-> Maybe CoreExpr
-> Maybe CoreExpr
-> Variance
-> Type
-> TcPluginM (Maybe (CoreExpr, [Ct]))
varMap Class
fmapCls Maybe Class
mContraCls CtLoc
loc Id
pv Type
tgt Maybe CoreExpr
covFwd Maybe CoreExpr
conFwd =
Class
-> Maybe Class
-> CtLoc
-> [(Id, Type, Maybe CoreExpr, Maybe CoreExpr)]
-> Maybe (Type -> TcPluginM (Maybe (CoreExpr, [Ct])))
-> Variance
-> Type
-> TcPluginM (Maybe (CoreExpr, [Ct]))
varMapN Class
fmapCls Maybe Class
mContraCls CtLoc
loc [(Id
pv, Type
tgt, Maybe CoreExpr
covFwd, Maybe CoreExpr
conFwd)] Maybe (Type -> TcPluginM (Maybe (CoreExpr, [Ct])))
forall a. Maybe a
Nothing
varMapN :: Class -> Maybe Class -> CtLoc
-> [(TyVar, Type, Maybe CoreExpr, Maybe CoreExpr)]
-> Maybe (Type -> TcPluginM (Maybe (CoreExpr, [Ct])))
-> Variance -> Type -> TcPluginM (Maybe (CoreExpr, [Ct]))
varMapN :: Class
-> Maybe Class
-> CtLoc
-> [(Id, Type, Maybe CoreExpr, Maybe CoreExpr)]
-> Maybe (Type -> TcPluginM (Maybe (CoreExpr, [Ct])))
-> Variance
-> Type
-> TcPluginM (Maybe (CoreExpr, [Ct]))
varMapN Class
fmapCls Maybe Class
mContraCls CtLoc
loc [(Id, Type, Maybe CoreExpr, Maybe CoreExpr)]
params Maybe (Type -> TcPluginM (Maybe (CoreExpr, [Ct])))
mSelf = Variance -> Type -> TcPluginM (Maybe (CoreExpr, [Ct]))
go
where
fmapSel :: Id
fmapSel = String -> Class -> Id
classMethod String
"fmap" Class
fmapCls
pvs :: [Id]
pvs = [ Id
pv | (Id
pv, Type
_, Maybe CoreExpr
_, Maybe CoreExpr
_) <- [(Id, Type, Maybe CoreExpr, Maybe CoreExpr)]
params ]
tgts :: [Type]
tgts = [ Type
tgt | (Id
_, Type
tgt, Maybe CoreExpr
_, Maybe CoreExpr
_) <- [(Id, Type, Maybe CoreExpr, Maybe CoreExpr)]
params ]
sub :: Type -> Type
sub Type
t = [Id] -> [Type] -> Type -> Type
HasDebugCallStack => [Id] -> [Type] -> Type -> Type
substTyWith [Id]
pvs [Type]
tgts Type
t
inA :: Type -> Bool
inA Type
t = (Id -> Bool) -> [Id] -> Bool
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
any (Id -> VarSet -> Bool
`elemVarSet` Type -> VarSet
tyCoVarsOfType Type
t) [Id]
pvs
bareFwd :: Type -> Variance -> Maybe (Maybe CoreExpr)
bareFwd Type
t Variance
v = case [ (Maybe CoreExpr
cf, Maybe CoreExpr
conf) | (Id
p, Type
_, Maybe CoreExpr
cf, Maybe CoreExpr
conf) <- [(Id, Type, Maybe CoreExpr, Maybe CoreExpr)]
params, Type
t Type -> Type -> Bool
`eqType` Id -> Type
mkTyVarTy Id
p ] of
((Maybe CoreExpr
cf, Maybe CoreExpr
conf) : [(Maybe CoreExpr, Maybe CoreExpr)]
_) -> Maybe CoreExpr -> Maybe (Maybe CoreExpr)
forall a. a -> Maybe a
Just (case Variance
v of Variance
Cov -> Maybe CoreExpr
cf; Variance
Con -> Maybe CoreExpr
conf)
[] -> Maybe (Maybe CoreExpr)
forall a. Maybe a
Nothing
spine :: Type -> (Type, [Type])
spine Type
ty = case Type -> Maybe (Type, Type)
splitAppTy_maybe Type
ty of
Just (Type
f, Type
a) -> let (Type
h, [Type]
as) = Type -> (Type, [Type])
spine Type
f in (Type
h, [Type]
as [Type] -> [Type] -> [Type]
forall a. [a] -> [a] -> [a]
++ [Type
a])
Maybe (Type, Type)
Nothing -> (Type
ty, [])
matchSelf :: Type -> Maybe Type
matchSelf Type
ty =
let (Type
h, [Type]
args) = Type -> (Type, [Type])
spine Type
ty
n :: Int
n = [(Id, Type, Maybe CoreExpr, Maybe CoreExpr)] -> Int
forall a. [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [(Id, Type, Maybe CoreExpr, Maybe CoreExpr)]
params
in if [Type] -> Int
forall a. [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [Type]
args Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
>= Int
n
then let ([Type]
pre, [Type]
tl) = Int -> [Type] -> ([Type], [Type])
forall a. Int -> [a] -> ([a], [a])
splitAt ([Type] -> Int
forall a. [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [Type]
args Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
n) [Type]
args
qhead :: Type
qhead = Type -> [Type] -> Type
mkAppTys Type
h [Type]
pre
in if [Bool] -> Bool
forall (t :: * -> *). Foldable t => t Bool -> Bool
and ((Type -> Type -> Bool) -> [Type] -> [Type] -> [Bool]
forall a b c. (a -> b -> c) -> [a] -> [b] -> [c]
zipWith Type -> Type -> Bool
eqType [Type]
tl ((Id -> Type) -> [Id] -> [Type]
forall a b. (a -> b) -> [a] -> [b]
map Id -> Type
mkTyVarTy [Id]
pvs)) Bool -> Bool -> Bool
&& Bool -> Bool
not (Type -> Bool
inA Type
qhead)
then Type -> Maybe Type
forall a. a -> Maybe a
Just Type
qhead else Maybe Type
forall a. Maybe a
Nothing
else Maybe Type
forall a. Maybe a
Nothing
go :: Variance -> Type -> TcPluginM (Maybe (CoreExpr, [Ct]))
go Variance
v Type
t
| Bool -> Bool
not (Type -> Bool
inA Type
t) = do x <- Type -> String -> TcPluginM Id
freshId Type
t String
"x"; pure (Just (Lam x (Var x), []))
| Just Maybe CoreExpr
mfwd <- Type -> Variance -> Maybe (Maybe CoreExpr)
bareFwd Type
t Variance
v = Maybe (CoreExpr, [Ct]) -> TcPluginM (Maybe (CoreExpr, [Ct]))
forall a. a -> TcPluginM a
forall (f :: * -> *) a. Applicative f => a -> f a
pure ((CoreExpr -> (CoreExpr, [Ct]))
-> Maybe CoreExpr -> Maybe (CoreExpr, [Ct])
forall a b. (a -> b) -> Maybe a -> Maybe b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (\CoreExpr
e -> (CoreExpr
e, [])) Maybe CoreExpr
mfwd)
| Just (FunTyFlag
_, Type
_, Type
s, Type
r) <- Type -> Maybe (FunTyFlag, Type, Type, Type)
splitFunTy_maybe Type
t = do
ms <- Variance -> Type -> TcPluginM (Maybe (CoreExpr, [Ct]))
go (Variance -> Variance
flipV Variance
v) Type
s
mr <- go v r
case (ms, mr) of
(Just (CoreExpr
es, [Ct]
w1), Just (CoreExpr
er, [Ct]
w2)) -> do
let (Type
sf, Type
rf) = case Variance
v of Variance
Cov -> (Type
s, Type
r); Variance
Con -> (Type -> Type
sub Type
s, Type -> Type
sub Type
r)
xTy :: Type
xTy = case Variance
v of Variance
Cov -> Type -> Type
sub Type
s; Variance
Con -> Type
s
g <- Type -> String -> TcPluginM Id
freshId (HasDebugCallStack => Type -> Type -> Type
Type -> Type -> Type
mkVisFunTyMany Type
sf Type
rf) String
"g"
x <- freshId xTy "x"
pure (Just (mkLams [g, x] (App er (App (Var g) (App es (Var x)))), w1 ++ w2))
(Maybe (CoreExpr, [Ct]), Maybe (CoreExpr, [Ct]))
_ -> Maybe (CoreExpr, [Ct]) -> TcPluginM (Maybe (CoreExpr, [Ct]))
forall a. a -> TcPluginM a
forall (f :: * -> *) a. Applicative f => a -> f a
pure Maybe (CoreExpr, [Ct])
forall a. Maybe a
Nothing
| Variance
Cov <- Variance
v, Just (TyCon
tc, [Type]
args) <- HasDebugCallStack => Type -> Maybe (TyCon, [Type])
Type -> Maybe (TyCon, [Type])
splitTyConApp_maybe Type
t
, TyCon -> Bool
isTupleTyCon TyCon
tc, [Type] -> Int
forall a. [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [Type]
args Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
>= Int
2 = do
ms <- (Type -> TcPluginM (Maybe (CoreExpr, [Ct])))
-> [Type] -> TcPluginM [Maybe (CoreExpr, [Ct])]
forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
forall (m :: * -> *) a b. Monad m => (a -> m b) -> [a] -> m [b]
mapM (Variance -> Type -> TcPluginM (Maybe (CoreExpr, [Ct]))
go Variance
Cov) [Type]
args
case sequence ms of
Maybe [(CoreExpr, [Ct])]
Nothing -> Maybe (CoreExpr, [Ct]) -> TcPluginM (Maybe (CoreExpr, [Ct]))
forall a. a -> TcPluginM a
forall (f :: * -> *) a. Applicative f => a -> f a
pure Maybe (CoreExpr, [Ct])
forall a. Maybe a
Nothing
Just [(CoreExpr, [Ct])]
pairs -> do
let ([CoreExpr]
mappers, [[Ct]]
wss) = [(CoreExpr, [Ct])] -> ([CoreExpr], [[Ct]])
forall a b. [(a, b)] -> ([a], [b])
unzip [(CoreExpr, [Ct])]
pairs
dc :: DataCon
dc = Boxity -> Int -> DataCon
tupleDataCon Boxity
Boxed ([Type] -> Int
forall a. [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [Type]
args)
xs <- (Type -> TcPluginM Id) -> [Type] -> TcPluginM [Id]
forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
forall (m :: * -> *) a b. Monad m => (a -> m b) -> [a] -> m [b]
mapM (Type -> String -> TcPluginM Id
`freshId` String
"u") [Type]
args
tup <- freshId t "tup" ; cb <- freshId t "cb"
let body = DataCon -> [CoreExpr] -> CoreExpr
mkCoreConApps DataCon
dc ((Type -> CoreExpr) -> [Type] -> [CoreExpr]
forall a b. (a -> b) -> [a] -> [b]
map (Type -> CoreExpr
forall b. Type -> Expr b
Type (Type -> CoreExpr) -> (Type -> Type) -> Type -> CoreExpr
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Type -> Type
sub) [Type]
args [CoreExpr] -> [CoreExpr] -> [CoreExpr]
forall a. [a] -> [a] -> [a]
++ (CoreExpr -> CoreExpr -> CoreExpr)
-> [CoreExpr] -> [CoreExpr] -> [CoreExpr]
forall a b c. (a -> b -> c) -> [a] -> [b] -> [c]
zipWith CoreExpr -> CoreExpr -> CoreExpr
forall b. Expr b -> Expr b -> Expr b
App [CoreExpr]
mappers ((Id -> CoreExpr) -> [Id] -> [CoreExpr]
forall a b. (a -> b) -> [a] -> [b]
map Id -> CoreExpr
forall b. Id -> Expr b
Var [Id]
xs))
pure (Just (Lam tup (Case (Var tup) cb (sub t) [Alt (DataAlt dc) xs body]), concat wss))
| Just Type -> TcPluginM (Maybe (CoreExpr, [Ct]))
self <- Maybe (Type -> TcPluginM (Maybe (CoreExpr, [Ct])))
mSelf, Variance
Cov <- Variance
v, Just Type
q <- Type -> Maybe Type
matchSelf Type
t = Type -> TcPluginM (Maybe (CoreExpr, [Ct]))
self Type
q
| Just (Type
h, Type
larg) <- Type -> Maybe (Type, Type)
splitAppTy_maybe Type
t, Bool -> Bool
not (Type -> Bool
inA Type
h) = do
mf <- Variance -> Type -> TcPluginM (Maybe (CoreExpr, [Ct]))
go Variance
v Type
larg
case mf of
Just (CoreExpr
e, [Ct]
w) -> do
ev <- CtLoc -> Type -> TcPluginM CtEvidence
newWanted CtLoc
loc (Class -> [Type] -> Type
mkClassPred Class
fmapCls [Type
h])
let (ft, tt) = case v of Variance
Cov -> (Type
larg, Type -> Type
sub Type
larg); Variance
Con -> (Type -> Type
sub Type
larg, Type
larg)
pure (Just ( mkApps (Var fmapSel) [Type h, ctEvExpr ev, Type ft, Type tt, e]
, mkNonCanonical ev : w ))
Maybe (CoreExpr, [Ct])
Nothing -> case Maybe Class
mContraCls of
Maybe Class
Nothing -> Maybe (CoreExpr, [Ct]) -> TcPluginM (Maybe (CoreExpr, [Ct]))
forall a. a -> TcPluginM a
forall (f :: * -> *) a. Applicative f => a -> f a
pure Maybe (CoreExpr, [Ct])
forall a. Maybe a
Nothing
Just Class
contraCls -> do
mc <- Variance -> Type -> TcPluginM (Maybe (CoreExpr, [Ct]))
go (Variance -> Variance
flipV Variance
v) Type
larg
case mc of
Maybe (CoreExpr, [Ct])
Nothing -> Maybe (CoreExpr, [Ct]) -> TcPluginM (Maybe (CoreExpr, [Ct]))
forall a. a -> TcPluginM a
forall (f :: * -> *) a. Applicative f => a -> f a
pure Maybe (CoreExpr, [Ct])
forall a. Maybe a
Nothing
Just (CoreExpr
e, [Ct]
w) -> do
ev <- CtLoc -> Type -> TcPluginM CtEvidence
newWanted CtLoc
loc (Class -> [Type] -> Type
mkClassPred Class
contraCls [Type
h])
let (xT, yT) = case v of Variance
Cov -> (Type -> Type
sub Type
larg, Type
larg); Variance
Con -> (Type
larg, Type -> Type
sub Type
larg)
pure (Just ( mkApps (Var (classMethod "contramap" contraCls))
[Type h, ctEvExpr ev, Type xT, Type yT, e]
, mkNonCanonical ev : w ))
| Bool
otherwise = Maybe (CoreExpr, [Ct]) -> TcPluginM (Maybe (CoreExpr, [Ct]))
forall a. a -> TcPluginM a
forall (f :: * -> *) a. Applicative f => a -> f a
pure Maybe (CoreExpr, [Ct])
forall a. Maybe a
Nothing
destructInner :: TyCon -> [Type] -> CoreExpr -> Id -> Type -> [CoreAlt] -> CoreExpr
destructInner :: TyCon -> [Type] -> CoreExpr -> Id -> Type -> [Alt Id] -> CoreExpr
destructInner TyCon
fTc [Type]
instTys CoreExpr
scrut Id
cb Type
resTy [Alt Id]
alts
| TyCon -> Bool
isNewTyCon TyCon
fTc
, [Alt AltCon
_ [Id
x] CoreExpr
body] <- [Alt Id]
alts
= Bind Id -> CoreExpr -> CoreExpr
forall b. Bind b -> Expr b -> Expr b
Let (Id -> CoreExpr -> Bind Id
forall b. b -> Expr b -> Bind b
NonRec Id
x (CoreExpr -> Coercion -> CoreExpr
forall b. Expr b -> Coercion -> Expr b
Cast CoreExpr
scrut (Role -> CoAxiom Unbranched -> [Type] -> [Coercion] -> Coercion
mkUnbranchedAxInstCo Role
Representational
(TyCon -> CoAxiom Unbranched
newTyConCo TyCon
fTc) [Type]
instTys []))) CoreExpr
body
| Bool
otherwise = CoreExpr -> Id -> Type -> [Alt Id] -> CoreExpr
forall b. Expr b -> b -> Type -> [Alt b] -> Expr b
Case CoreExpr
scrut Id
cb Type
resTy [Alt Id]
alts
freshTyVar :: String -> TcPluginM TyVar
freshTyVar :: String -> TcPluginM Id
freshTyVar = Type -> String -> TcPluginM Id
freshTyVarK Type
liftedTypeKind
freshTyVarK :: Kind -> String -> TcPluginM TyVar
freshTyVarK :: Type -> String -> TcPluginM Id
freshTyVarK Type
k String
s = do
u <- TcM Unique -> TcPluginM Unique
forall a. TcM a -> TcPluginM a
unsafeTcPluginTcM TcM Unique
forall (m :: * -> *). MonadUnique m => m Unique
getUniqueM
pure (mkTyVar (mkSystemName u (mkTyVarOcc s)) k)
unwrapEv :: EvTerm -> CoreExpr
unwrapEv :: EvTerm -> CoreExpr
unwrapEv (EvExpr CoreExpr
e) = CoreExpr
e
unwrapEv EvTerm
_ = String -> CoreExpr
forall a. HasCallStack => String -> a
error String
"stock: expected EvExpr"
data ReadPrecEnv = ReadPrecEnv
{ ReadPrecEnv -> TyCon
rpReadPrecTc :: TyCon
, ReadPrecEnv -> CoreExpr
rpMonadDict :: CoreExpr
, ReadPrecEnv -> Id
rpBindSel, ReadPrecEnv -> Id
rpThenSel, ReadPrecEnv -> Id
rpReturnSel :: Id
, ReadPrecEnv -> Id
rpParens, ReadPrecEnv -> Id
rpChoose, ReadPrecEnv -> Id
rpExpectP, ReadPrecEnv -> Id
rpReadField :: Id
, ReadPrecEnv -> Id
rpPrec, ReadPrecEnv -> Id
rpStep, ReadPrecEnv -> Id
rpReset, ReadPrecEnv -> Id
rpPlus, ReadPrecEnv -> Id
rpPfail :: Id
, ReadPrecEnv -> DataCon
rpIdentCon, ReadPrecEnv -> DataCon
rpSymbolCon, ReadPrecEnv -> DataCon
rpPuncCon :: DataCon
}
lookupReadPrecEnv :: CtLoc -> TcPluginM (ReadPrecEnv, Ct)
lookupReadPrecEnv :: CtLoc -> TcPluginM (ReadPrecEnv, Ct)
lookupReadPrecEnv CtLoc
loc = do
monadCls <- Name -> TcPluginM Class
tcLookupClass Name
monadClassName
readPrecTc <- lookupOrig tEXT_READPREC (mkTcOcc "ReadPrec") >>= tcLookupTyCon
parensId <- lookupOrig gHC_INTERNAL_READ (mkVarOcc "parens") >>= tcLookupId
chooseId <- lookupOrig gHC_INTERNAL_READ (mkVarOcc "choose") >>= tcLookupId
expectPId <- lookupOrig gHC_INTERNAL_READ (mkVarOcc "expectP") >>= tcLookupId
readFieldId <- lookupOrig gHC_INTERNAL_READ (mkVarOcc "readField") >>= tcLookupId
precId <- lookupOrig tEXT_READPREC (mkVarOcc "prec") >>= tcLookupId
stepId <- lookupOrig tEXT_READPREC (mkVarOcc "step") >>= tcLookupId
resetId <- lookupOrig tEXT_READPREC (mkVarOcc "reset") >>= tcLookupId
plusId <- lookupOrig tEXT_READPREC (mkVarOcc "+++") >>= tcLookupId
pfailId <- lookupOrig tEXT_READPREC (mkVarOcc "pfail") >>= tcLookupId
identCon <- lookupOrig tEXT_READ_LEX (mkDataOcc "Ident") >>= tcLookupDataCon
symbolCon <- lookupOrig tEXT_READ_LEX (mkDataOcc "Symbol") >>= tcLookupDataCon
puncCon <- lookupOrig tEXT_READ_LEX (mkDataOcc "Punc") >>= tcLookupDataCon
monadEv <- newWanted loc (mkClassPred monadCls [mkTyConTy readPrecTc])
pure ( ReadPrecEnv readPrecTc (ctEvExpr monadEv)
(classMethod ">>=" monadCls) (classMethod ">>" monadCls) (classMethod "return" monadCls)
parensId chooseId expectPId readFieldId precId stepId resetId plusId pfailId
identCon symbolCon puncCon
, mkNonCanonical monadEv )
buildReadPrecBody :: ReadPrecEnv -> Type -> (DataCon -> [Id] -> CoreExpr)
-> [(DataCon, [(Type, CoreExpr)])] -> TcPluginM CoreExpr
buildReadPrecBody :: ReadPrecEnv
-> Type
-> (DataCon -> [Id] -> CoreExpr)
-> [(DataCon, [(Type, CoreExpr)])]
-> TcPluginM CoreExpr
buildReadPrecBody ReadPrecEnv
env Type
gTy DataCon -> [Id] -> CoreExpr
mkConVal [(DataCon, [(Type, CoreExpr)])]
cons = do
let ReadPrecEnv TyCon
readPrecTc CoreExpr
monadDict Id
bindSel Id
thenSel Id
returnSel
Id
parensId Id
chooseId Id
expectPId Id
readFieldId Id
precId Id
stepId Id
resetId Id
plusId Id
pfailId
DataCon
identCon DataCon
symbolCon DataCon
puncCon = ReadPrecEnv
env
readPrecTy :: Type
readPrecTy = TyCon -> Type
mkTyConTy TyCon
readPrecTc
strPairTy :: Type
strPairTy = [Type] -> Type
mkBoxedTupleTy [Type
stringTy, TyCon -> [Type] -> Type
mkTyConApp TyCon
readPrecTc [Type
gTy]]
bindP :: Type -> Type -> CoreExpr -> CoreExpr -> CoreExpr
bindP Type
a Type
b CoreExpr
m CoreExpr
k = CoreExpr -> [CoreExpr] -> CoreExpr
forall b. Expr b -> [Expr b] -> Expr b
mkApps (Id -> CoreExpr
forall b. Id -> Expr b
Var Id
bindSel) [Type -> CoreExpr
forall b. Type -> Expr b
Type Type
readPrecTy, CoreExpr
monadDict, Type -> CoreExpr
forall b. Type -> Expr b
Type Type
a, Type -> CoreExpr
forall b. Type -> Expr b
Type Type
b, CoreExpr
m, CoreExpr
k]
thenP :: Type -> Type -> CoreExpr -> CoreExpr -> CoreExpr
thenP Type
a Type
b CoreExpr
m CoreExpr
n = CoreExpr -> [CoreExpr] -> CoreExpr
forall b. Expr b -> [Expr b] -> Expr b
mkApps (Id -> CoreExpr
forall b. Id -> Expr b
Var Id
thenSel) [Type -> CoreExpr
forall b. Type -> Expr b
Type Type
readPrecTy, CoreExpr
monadDict, Type -> CoreExpr
forall b. Type -> Expr b
Type Type
a, Type -> CoreExpr
forall b. Type -> Expr b
Type Type
b, CoreExpr
m, CoreExpr
n]
returnP :: Type -> CoreExpr -> CoreExpr
returnP Type
a CoreExpr
v = CoreExpr -> [CoreExpr] -> CoreExpr
forall b. Expr b -> [Expr b] -> Expr b
mkApps (Id -> CoreExpr
forall b. Id -> Expr b
Var Id
returnSel) [Type -> CoreExpr
forall b. Type -> Expr b
Type Type
readPrecTy, CoreExpr
monadDict, Type -> CoreExpr
forall b. Type -> Expr b
Type Type
a, CoreExpr
v]
seqW :: CoreExpr -> CoreExpr -> CoreExpr
seqW CoreExpr
m CoreExpr
n = Type -> Type -> CoreExpr -> CoreExpr -> CoreExpr
thenP Type
unitTy Type
gTy CoreExpr
m CoreExpr
n
parensE :: Type -> Arg b -> Arg b
parensE Type
a Arg b
p = Arg b -> [Arg b] -> Arg b
forall b. Expr b -> [Expr b] -> Expr b
mkApps (Id -> Arg b
forall b. Id -> Expr b
Var Id
parensId) [Type -> Arg b
forall b. Type -> Expr b
Type Type
a, Arg b
p]
precE :: Type -> Integer -> CoreExpr -> CoreExpr
precE Type
a Integer
n CoreExpr
p = CoreExpr -> [CoreExpr] -> CoreExpr
forall b. Expr b -> [Expr b] -> Expr b
mkApps (Id -> CoreExpr
forall b. Id -> Expr b
Var Id
precId) [Type -> CoreExpr
forall b. Type -> Expr b
Type Type
a, Integer -> CoreExpr
mkUncheckedIntExpr Integer
n, CoreExpr
p]
stepE :: Type -> Arg b -> Arg b
stepE Type
a Arg b
p = Arg b -> [Arg b] -> Arg b
forall b. Expr b -> [Expr b] -> Expr b
mkApps (Id -> Arg b
forall b. Id -> Expr b
Var Id
stepId) [Type -> Arg b
forall b. Type -> Expr b
Type Type
a, Arg b
p]
resetE :: Type -> Arg b -> Arg b
resetE Type
a Arg b
p = Arg b -> [Arg b] -> Arg b
forall b. Expr b -> [Expr b] -> Expr b
mkApps (Id -> Arg b
forall b. Id -> Expr b
Var Id
resetId) [Type -> Arg b
forall b. Type -> Expr b
Type Type
a, Arg b
p]
plusE :: Type -> Arg b -> Arg b -> Arg b
plusE Type
a Arg b
p Arg b
q = Arg b -> [Arg b] -> Arg b
forall b. Expr b -> [Expr b] -> Expr b
mkApps (Id -> Arg b
forall b. Id -> Expr b
Var Id
plusId) [Type -> Arg b
forall b. Type -> Expr b
Type Type
a, Arg b
p, Arg b
q]
chooseE :: Type -> Arg b -> Arg b
chooseE Type
a Arg b
xs = Arg b -> [Arg b] -> Arg b
forall b. Expr b -> [Expr b] -> Expr b
mkApps (Id -> Arg b
forall b. Id -> Expr b
Var Id
chooseId) [Type -> Arg b
forall b. Type -> Expr b
Type Type
a, Arg b
xs]
readFieldE :: Type -> Arg b -> Arg b -> Arg b
readFieldE Type
a Arg b
s Arg b
p = Arg b -> [Arg b] -> Arg b
forall b. Expr b -> [Expr b] -> Expr b
mkApps (Id -> Arg b
forall b. Id -> Expr b
Var Id
readFieldId) [Type -> Arg b
forall b. Type -> Expr b
Type Type
a, Arg b
s, Arg b
p]
expectPE :: Arg b -> Arg b
expectPE Arg b
l = Arg b -> Arg b -> Arg b
forall b. Expr b -> Expr b -> Expr b
App (Id -> Arg b
forall b. Id -> Expr b
Var Id
expectPId) Arg b
l
identE :: CoreExpr -> CoreExpr
identE CoreExpr
s = DataCon -> [CoreExpr] -> CoreExpr
mkCoreConApps DataCon
identCon [CoreExpr
s]
symbolE :: CoreExpr -> CoreExpr
symbolE CoreExpr
s = DataCon -> [CoreExpr] -> CoreExpr
mkCoreConApps DataCon
symbolCon [CoreExpr
s]
puncE :: CoreExpr -> CoreExpr
puncE CoreExpr
s = DataCon -> [CoreExpr] -> CoreExpr
mkCoreConApps DataCon
puncCon [CoreExpr
s]
str :: String -> TcPluginM CoreExpr
str String
s = TcM CoreExpr -> TcPluginM CoreExpr
forall a. TcM a -> TcPluginM a
unsafeTcPluginTcM (FastString -> TcM CoreExpr
forall (m :: * -> *). MonadThings m => FastString -> m CoreExpr
mkStringExprFS (String -> FastString
fsLit String
s))
entries <- [(DataCon, [(Type, CoreExpr)])]
-> ((DataCon, [(Type, CoreExpr)])
-> TcPluginM (Either (CoreExpr, CoreExpr) CoreExpr))
-> TcPluginM [Either (CoreExpr, CoreExpr) CoreExpr]
forall (t :: * -> *) (f :: * -> *) a b.
(Traversable t, Applicative f) =>
t a -> (a -> f b) -> f (t b)
for [(DataCon, [(Type, CoreExpr)])]
cons \(DataCon
dc, [(Type, CoreExpr)]
readers) -> do
let name :: String
name = OccName -> String
occNameString (DataCon -> OccName
forall a. NamedThing a => a -> OccName
getOccName DataCon
dc)
labels :: [String]
labels = (FieldLabel -> String) -> [FieldLabel] -> [String]
forall a b. (a -> b) -> [a] -> [b]
map (OccName -> String
occNameString (OccName -> String)
-> (FieldLabel -> OccName) -> FieldLabel -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Name -> OccName
nameOccName (Name -> OccName) -> (FieldLabel -> Name) -> FieldLabel -> OccName
forall b c a. (b -> c) -> (a -> b) -> a -> c
. FieldLabel -> Name
flSelector) (DataCon -> [FieldLabel]
dataConFieldLabels DataCon
dc)
nameE <- String -> TcPluginM CoreExpr
str String
name
argIds <- zipWithM (\(Type
ft, CoreExpr
_) Int
i -> Type -> String -> TcPluginM Id
freshId Type
ft (String
"a" String -> String -> String
forall a. [a] -> [a] -> [a]
++ Int -> String
forall a. Show a => a -> String
show (Int
i :: Int))) readers [0 ..]
let ret = Type -> CoreExpr -> CoreExpr
returnP Type
gTy (DataCon -> [Id] -> CoreExpr
mkConVal DataCon
dc [Id]
argIds)
items = [Id] -> [Type] -> [CoreExpr] -> [(Id, Type, CoreExpr)]
forall a b c. [a] -> [b] -> [c] -> [(a, b, c)]
zip3 [Id]
argIds (((Type, CoreExpr) -> Type) -> [(Type, CoreExpr)] -> [Type]
forall a b. (a -> b) -> [a] -> [b]
map (Type, CoreExpr) -> Type
forall a b. (a, b) -> a
fst [(Type, CoreExpr)]
readers) (((Type, CoreExpr) -> CoreExpr) -> [(Type, CoreExpr)] -> [CoreExpr]
forall a b. (a -> b) -> [a] -> [b]
map (Type, CoreExpr) -> CoreExpr
forall a b. (a, b) -> b
snd [(Type, CoreExpr)]
readers)
if null readers
then pure (Left (nameE, ret))
else if dataConIsInfix dc
then do
prec <- conPrec dc
let [(a0, ft0, rd0), (a1, ft1, rd1)] = items
inner = Type -> Type -> CoreExpr -> CoreExpr -> CoreExpr
bindP Type
ft0 Type
gTy (Type -> CoreExpr -> CoreExpr
forall {b}. Type -> Arg b -> Arg b
stepE Type
ft0 CoreExpr
rd0) (CoreExpr -> CoreExpr) -> CoreExpr -> CoreExpr
forall a b. (a -> b) -> a -> b
$ Id -> CoreExpr -> CoreExpr
forall b. b -> Expr b -> Expr b
Lam Id
a0 (CoreExpr -> CoreExpr) -> CoreExpr -> CoreExpr
forall a b. (a -> b) -> a -> b
$
CoreExpr -> CoreExpr -> CoreExpr
seqW (CoreExpr -> CoreExpr
forall {b}. Arg b -> Arg b
expectPE (CoreExpr -> CoreExpr
symbolE CoreExpr
nameE)) (CoreExpr -> CoreExpr) -> CoreExpr -> CoreExpr
forall a b. (a -> b) -> a -> b
$
Type -> Type -> CoreExpr -> CoreExpr -> CoreExpr
bindP Type
ft1 Type
gTy (Type -> CoreExpr -> CoreExpr
forall {b}. Type -> Arg b -> Arg b
stepE Type
ft1 CoreExpr
rd1) (Id -> CoreExpr -> CoreExpr
forall b. b -> Expr b -> Expr b
Lam Id
a1 CoreExpr
ret)
pure (Right (precE gTy prec inner))
else if not (null labels)
then do
openCE <- str "{"; closeCE <- str "}"; commaCE <- str ","
lblEs <- mapM str labels
let closeRet = CoreExpr -> CoreExpr -> CoreExpr
seqW (CoreExpr -> CoreExpr
forall {b}. Arg b -> Arg b
expectPE (CoreExpr -> CoreExpr
puncE CoreExpr
closeCE)) CoreExpr
ret
go [] = CoreExpr
closeRet
go ((Int
i, CoreExpr
lblE, (Id
aId, Type
ft, CoreExpr
rd)) : [(Int, CoreExpr, (Id, Type, CoreExpr))]
rest) =
let bound :: CoreExpr
bound = Type -> Type -> CoreExpr -> CoreExpr -> CoreExpr
bindP Type
ft Type
gTy (Type -> CoreExpr -> CoreExpr -> CoreExpr
forall {b}. Type -> Arg b -> Arg b -> Arg b
readFieldE Type
ft CoreExpr
lblE (Type -> CoreExpr -> CoreExpr
forall {b}. Type -> Arg b -> Arg b
resetE Type
ft CoreExpr
rd)) (Id -> CoreExpr -> CoreExpr
forall b. b -> Expr b -> Expr b
Lam Id
aId ([(Int, CoreExpr, (Id, Type, CoreExpr))] -> CoreExpr
go [(Int, CoreExpr, (Id, Type, CoreExpr))]
rest))
in if Int
i Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== (Int
0 :: Int) then CoreExpr
bound else CoreExpr -> CoreExpr -> CoreExpr
seqW (CoreExpr -> CoreExpr
forall {b}. Arg b -> Arg b
expectPE (CoreExpr -> CoreExpr
puncE CoreExpr
commaCE)) CoreExpr
bound
inner = CoreExpr -> CoreExpr -> CoreExpr
seqW (CoreExpr -> CoreExpr
forall {b}. Arg b -> Arg b
expectPE (CoreExpr -> CoreExpr
identE CoreExpr
nameE)) (CoreExpr -> CoreExpr) -> CoreExpr -> CoreExpr
forall a b. (a -> b) -> a -> b
$
CoreExpr -> CoreExpr -> CoreExpr
seqW (CoreExpr -> CoreExpr
forall {b}. Arg b -> Arg b
expectPE (CoreExpr -> CoreExpr
puncE CoreExpr
openCE)) (CoreExpr -> CoreExpr) -> CoreExpr -> CoreExpr
forall a b. (a -> b) -> a -> b
$
[(Int, CoreExpr, (Id, Type, CoreExpr))] -> CoreExpr
go ([Int]
-> [CoreExpr]
-> [(Id, Type, CoreExpr)]
-> [(Int, CoreExpr, (Id, Type, CoreExpr))]
forall a b c. [a] -> [b] -> [c] -> [(a, b, c)]
zip3 [Int
0 ..] [CoreExpr]
lblEs [(Id, Type, CoreExpr)]
items)
pure (Right (precE gTy 11 inner))
else do
let chain = ((Id, Type, CoreExpr) -> CoreExpr -> CoreExpr)
-> CoreExpr -> [(Id, Type, CoreExpr)] -> CoreExpr
forall a b. (a -> b -> b) -> b -> [a] -> b
forall (t :: * -> *) a b.
Foldable t =>
(a -> b -> b) -> b -> t a -> b
foldr (\(Id
aId, Type
ft, CoreExpr
rd) CoreExpr
acc -> Type -> Type -> CoreExpr -> CoreExpr -> CoreExpr
bindP Type
ft Type
gTy (Type -> CoreExpr -> CoreExpr
forall {b}. Type -> Arg b -> Arg b
stepE Type
ft CoreExpr
rd) (Id -> CoreExpr -> CoreExpr
forall b. b -> Expr b -> Expr b
Lam Id
aId CoreExpr
acc)) CoreExpr
ret [(Id, Type, CoreExpr)]
items
inner = CoreExpr -> CoreExpr -> CoreExpr
seqW (CoreExpr -> CoreExpr
forall {b}. Arg b -> Arg b
expectPE (CoreExpr -> CoreExpr
identE CoreExpr
nameE)) CoreExpr
chain
pure (Right (precE gTy 10 inner))
let nullaries = [(CoreExpr, CoreExpr)
e | Left (CoreExpr, CoreExpr)
e <- [Either (CoreExpr, CoreExpr) CoreExpr]
entries]
others = [CoreExpr
p | Right CoreExpr
p <- [Either (CoreExpr, CoreExpr) CoreExpr]
entries]
chooseP = Type -> CoreExpr -> CoreExpr
forall {b}. Type -> Arg b -> Arg b
chooseE Type
gTy (Type -> [CoreExpr] -> CoreExpr
mkListExpr Type
strPairTy [ [CoreExpr] -> CoreExpr
mkCoreTup [CoreExpr
n, CoreExpr
p] | (CoreExpr
n, CoreExpr
p) <- [(CoreExpr, CoreExpr)]
nullaries ])
allP = [CoreExpr
chooseP | Bool -> Bool
not ([(CoreExpr, CoreExpr)] -> Bool
forall a. [a] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [(CoreExpr, CoreExpr)]
nullaries)] [CoreExpr] -> [CoreExpr] -> [CoreExpr]
forall a. [a] -> [a] -> [a]
++ [CoreExpr]
others
combined = case [CoreExpr]
allP of
[] -> CoreExpr -> [CoreExpr] -> CoreExpr
forall b. Expr b -> [Expr b] -> Expr b
mkApps (Id -> CoreExpr
forall b. Id -> Expr b
Var Id
pfailId) [Type -> CoreExpr
forall b. Type -> Expr b
Type Type
gTy]
[CoreExpr
p] -> CoreExpr
p
[CoreExpr]
ps -> (CoreExpr -> CoreExpr -> CoreExpr) -> [CoreExpr] -> CoreExpr
forall a. (a -> a -> a) -> [a] -> a
forall (t :: * -> *) a. Foldable t => (a -> a -> a) -> t a -> a
foldr1 (Type -> CoreExpr -> CoreExpr -> CoreExpr
forall {b}. Type -> Arg b -> Arg b -> Arg b
plusE Type
gTy) [CoreExpr]
ps
pure (parensE gTy combined)