{-# LANGUAGE BlockArguments #-}
{-# LANGUAGE CPP #-}
{-# LANGUAGE ConstraintKinds #-}
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE GADTs #-}
{-# LANGUAGE LambdaCase #-}
{-# LANGUAGE PolyKinds #-}
{-# LANGUAGE RecordWildCards #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE TupleSections #-}
{-# LANGUAGE ViewPatterns #-}
module Polytropos.Plugin
(
plugin
) where
import Prelude
import Data.Either
( partitionEithers
)
import Data.List
( intercalate
, sortOn
#if !MIN_VERSION_base(4,20,0)
, foldl'
#endif
)
import Data.Bits
( xor
)
import Data.Char
( ord
)
import Data.Word
( Word64
)
import Control.Monad
( forM
, zipWithM
)
import GHC.Core.DataCon
( promoteDataCon
)
import GHC.Core.Make
( mkCoreApps
, mkCoreConApps
, mkCoreLams
, mkCharExpr
, mkStringExpr
, mkIfThenElse
, mkListExpr
)
import GHC.Plugins
( Plugin (..)
, defaultPlugin
, tcPlugin
, CoreExpr
, Expr(..)
, Type
, mkTcOcc
, nameOccName
, mkTyConTy
, mkTyConApp
, splitTyConApp_maybe
, isStrLitTy
, mkStrLitTy
, intDataCon
, wordDataCon
, FastString
, unpackFS
, Literal(..)
, LitNumType(..)
, wordTyCon
, Var(..)
, varType
, intTy
, stringTy
, mkVarOcc
, Module
, mkModuleName
, coreView
, splitFunTy
, splitFunTys
, splitForAllTyCoVars
, piResultTys
, typeKind
, mkTyVarTy
, mkAppTy
, getOccName
, occNameString
, fsLit
, nullFS
, nilFS
, TyCon
, showSDocUnsafe
, ppr
, isEmptyVarSet
, tyCoVarsOfType
)
import GHC.Core.Class
( classMethods
, classTyCon
)
import GHC.Core.Multiplicity
( scaledThing
, scaledMult
)
import GHC.Core.TyCo.Compare
( eqType
)
import GHC.Builtin.Types
( trueDataCon
, falseDataCon
, maybeTyCon
, nothingDataCon
, justDataCon
, unitTyCon
, unitDataCon
, constraintKind
, typeSymbolKind
, liftedTypeKind
, mkPromotedPairTy
, mkPromotedListTy
, mkTupleTy
)
import Language.Haskell.Syntax.Basic
( Boxity(..)
)
import GHC.Builtin.Names
( gHC_CLASSES
, eqClassName
, showClassName
, errorMessageTypeErrorFamName
, typeErrorTextDataConName
, typeErrorVAppendDataConName
)
import Polytropos.Plugin.Compat
( modBase
, modShow
, modRecords
)
import GHC.TcPlugin.API
( TcPlugin (..)
, TcPluginSolveResult(..)
, TcPluginM
, classifyPredType
, Pred(..)
, ctPred
, ctEvidence
, isWanted
, className
, EvTerm (..)
, Ct
, CtLoc
, TcPluginStage(..)
, mkTcPlugin
, listToUFM
, UniqFM
, lookupOrig
, tcLookupId
, tcLookupTyCon
, tcLookupDataCon
, findImportedModule
, resolveImport
, FindResult(..)
, Class
, classDataCon
, tcLookupClass
, evDataConApp
, newName
, mkLocalId
, newWanted
, ctEvExpr
, mkNonCanonical
, ctLoc
, Role(..)
, TcPluginRewriteResult(..)
, mkTyFamAppReduction
)
import GHC.TcPlugin.API.Internal
( unsafeLiftTcM
, TcPluginRewriter
)
import Polytropos.Plugin.Source
( sourcePlugin
)
plugin :: Plugin
plugin :: Plugin
plugin = Plugin
defaultPlugin
{ tcPlugin = const $ Just $ mkTcPlugin polytroposPlugin
, parsedResultAction = \[String]
opts ModSummary
_modSummary -> [String] -> ParsedResult -> Hsc ParsedResult
sourcePlugin [String]
opts
}
polytroposPlugin :: TcPlugin
polytroposPlugin :: TcPlugin
polytroposPlugin = TcPlugin
{ tcPluginInit :: TcPluginM 'Init PluginState
tcPluginInit = TcPluginM 'Init PluginState
polytroposInit
, tcPluginSolve :: PluginState -> TcPluginSolver
tcPluginSolve = PluginState -> TcPluginSolver
polytroposSolve
, tcPluginRewrite :: PluginState -> UniqFM TyCon TcPluginRewriter
tcPluginRewrite = PluginState -> UniqFM TyCon TcPluginRewriter
polytroposRewrite
, tcPluginPostTc :: PluginState -> TcPluginM 'PostTc ()
tcPluginPostTc = TcPluginM 'PostTc () -> PluginState -> TcPluginM 'PostTc ()
forall a b. a -> b -> a
const (() -> TcPluginM 'PostTc ()
forall a. a -> TcPluginM 'PostTc a
forall (m :: * -> *) a. Monad m => a -> m a
return ())
, tcPluginShutdown :: PluginState -> IO ()
tcPluginShutdown = IO () -> PluginState -> IO ()
forall a b. a -> b -> a
const (() -> IO ()
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return ())
}
data PluginState = PluginState
{ PluginState -> Var
psRepTag :: !Var
, PluginState -> Var
psRepArity :: !Var
, PluginState -> Var
psFieldAt :: !Var
, PluginState -> Var
psUnRowRep :: !Var
, PluginState -> Var
psNoInlineCo :: !Var
, PluginState -> Var
psAnd :: !Var
, PluginState -> Var
psComp :: !Var
, PluginState -> Var
psEqClass :: !Var
, PluginState -> Var
psShowsPrecMeth :: !Var
, PluginState -> Var
psShowString :: !Var
, PluginState -> Var
psShowChar :: !Var
, PluginState -> Var
psFEqInt :: !Var
, PluginState -> Var
psFEqBool :: !Var
, PluginState -> Var
psFEqWord :: !Var
, PluginState -> Var
psFShowInt :: !Var
, PluginState -> Var
psFShowBool :: !Var
, PluginState -> Class
psEqCls :: !Class
, PluginState -> Class
psShowCls :: !Class
, PluginState -> Class
psRowFlavourCls :: !Class
, PluginState -> Class
psHasFieldCls :: !Class
, PluginState -> TyCon
psDictAnyTyCon :: !TyCon
, PluginState -> Var
psMkDictAny :: !Var
, PluginState -> Var
psEvidenceAllFields :: !Var
, PluginState -> TyCon
psFieldTypesTyCon :: !TyCon
, PluginState -> TyCon
psSimpleFieldTypesTyCon :: !TyCon
, PluginState -> TyCon
psFieldNamesTyCon :: !TyCon
, PluginState -> TyCon
psTypeErrorTyCon :: !TyCon
, PluginState -> TyCon
psPromotedText :: !TyCon
, PluginState -> TyCon
psPromotedVcat :: !TyCon
}
polytroposInit :: TcPluginM 'Init PluginState
polytroposInit :: TcPluginM 'Init PluginState
polytroposInit = do
coreMod <- TcPluginM 'Init Module
findPolytroposCoreModule
psRepTag <- lookupIdInModule coreMod "repTag"
psRepArity <- lookupIdInModule coreMod "repArity"
psFieldAt <- lookupIdInModule coreMod "fieldAt"
psUnRowRep <- lookupIdInModule coreMod "unRowRep"
psNoInlineCo <- lookupIdInModule coreMod "noInlineUnsafeCo"
psEqClass <- lookupIdInModule gHC_CLASSES "=="
psAnd <- lookupIdInModule gHC_CLASSES "&&"
psFEqInt <- lookupIdInModule gHC_CLASSES "$fEqInt"
psFEqBool <- lookupIdInModule gHC_CLASSES "$fEqBool"
psFEqWord <- lookupIdInModule gHC_CLASSES "$fEqWord"
psShowsPrecMeth <- lookupIdInModule modShow "showsPrec"
psShowString <- lookupIdInModule modShow "showString"
psShowChar <- lookupIdInModule modShow "showChar"
psFShowInt <- lookupIdInModule modShow "$fShowInt"
psFShowBool <- lookupIdInModule modShow "$fShowBool"
psEqCls <- tcLookupClass eqClassName
psShowCls <- tcLookupClass showClassName
psComp <- lookupIdInModule modBase "."
rowFlavourName <- lookupOrig coreMod (mkTcOcc "RowFlavour")
psRowFlavourCls <- tcLookupClass rowFlavourName
hasFieldOcc <- lookupOrig modRecords (mkTcOcc "HasField")
psHasFieldCls <- tcLookupClass hasFieldOcc
dictAnyOcc <- lookupOrig coreMod (mkTcOcc "DictAny")
psDictAnyTyCon <- tcLookupTyCon dictAnyOcc
psMkDictAny <- lookupIdInModule coreMod "mkDictAny"
psEvidenceAllFields <- lookupIdInModule coreMod "evidenceAllFields"
fieldTypesOcc <- lookupOrig coreMod (mkTcOcc "FieldTypes")
psFieldTypesTyCon <- tcLookupTyCon fieldTypesOcc
simpleFieldTypesOcc <- lookupOrig coreMod (mkTcOcc "SimpleFieldTypes")
psSimpleFieldTypesTyCon <- tcLookupTyCon simpleFieldTypesOcc
fieldNamesOcc <- lookupOrig coreMod (mkTcOcc "FieldNames")
psFieldNamesTyCon <- tcLookupTyCon fieldNamesOcc
psTypeErrorTyCon <- tcLookupTyCon errorMessageTypeErrorFamName
textDataCon <- tcLookupDataCon typeErrorTextDataConName
vcatDataCon <- tcLookupDataCon typeErrorVAppendDataConName
let psPromotedText = DataCon -> TyCon
promoteDataCon DataCon
textDataCon
psPromotedVcat = DataCon -> TyCon
promoteDataCon DataCon
vcatDataCon
pure PluginState{..}
findModule :: String -> Maybe String -> TcPluginM 'Init Module
findModule :: String -> Maybe String -> TcPluginM 'Init Module
findModule String
modName Maybe String
mPkg = do
let modName' :: ModuleName
modName' = String -> ModuleName
mkModuleName String
modName
pkgQual <- ModuleName -> Maybe FastString -> TcPluginM 'Init PkgQual
forall (m :: * -> *).
MonadTcPlugin m =>
ModuleName -> Maybe FastString -> m PkgQual
resolveImport ModuleName
modName' (String -> FastString
fsLit (String -> FastString) -> Maybe String -> Maybe FastString
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Maybe String
mPkg)
result <- findImportedModule modName' pkgQual
case result of
Found ModLocation
_ Module
mod' -> Module -> TcPluginM 'Init Module
forall a. a -> TcPluginM 'Init a
forall (f :: * -> *) a. Applicative f => a -> f a
pure Module
mod'
FindResult
_ -> String -> TcPluginM 'Init Module
forall a. HasCallStack => String -> a
error (String -> TcPluginM 'Init Module)
-> String -> TcPluginM 'Init Module
forall a b. (a -> b) -> a -> b
$ String
"polytropos: could not find module " String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
modName
findPolytroposCoreModule :: TcPluginM 'Init Module
findPolytroposCoreModule :: TcPluginM 'Init Module
findPolytroposCoreModule = String -> Maybe String -> TcPluginM 'Init Module
findModule String
"Polytropos.Core" (String -> Maybe String
forall a. a -> Maybe a
Just String
"polytropos-core")
lookupIdInModule :: Module -> String -> TcPluginM 'Init Var
lookupIdInModule :: Module -> String -> TcPluginM 'Init Var
lookupIdInModule Module
modName String
occStr = do
let occ :: OccName
occ = String -> OccName
mkVarOcc String
occStr
name <- Module -> OccName -> TcPluginM 'Init Name
forall (m :: * -> *).
MonadTcPlugin m =>
Module -> OccName -> m Name
lookupOrig Module
modName OccName
occ
tcLookupId name
polytroposRewrite :: PluginState -> UniqFM TyCon TcPluginRewriter
polytroposRewrite :: PluginState -> UniqFM TyCon TcPluginRewriter
polytroposRewrite PluginState
state = [(TyCon, TcPluginRewriter)] -> UniqFM TyCon TcPluginRewriter
forall key elt. Uniquable key => [(key, elt)] -> UniqFM key elt
listToUFM
[ (PluginState -> TyCon
psFieldTypesTyCon PluginState
state, TyCon -> TcPluginRewriter
rewriteFieldTypes (PluginState -> TyCon
psFieldTypesTyCon PluginState
state))
, (PluginState -> TyCon
psSimpleFieldTypesTyCon PluginState
state, TyCon -> TcPluginRewriter
rewriteSimpleFieldTypes (PluginState -> TyCon
psSimpleFieldTypesTyCon PluginState
state))
, (PluginState -> TyCon
psFieldNamesTyCon PluginState
state, TyCon -> TcPluginRewriter
rewriteFieldNames (PluginState -> TyCon
psFieldNamesTyCon PluginState
state))
]
walkRowFields_maybe :: Type -> Maybe [(FastString, Type)]
walkRowFields_maybe :: Type -> Maybe [(FastString, Type)]
walkRowFields_maybe Type
rowTy = do
elems <- Type -> Maybe [Type]
myExtractPromotedList (Type -> Type
unwrapSynonyms Type
rowTy)
mapM extractField elems
where
extractField :: Type -> Maybe (FastString, Type)
extractField Type
elemTy =
case HasDebugCallStack => Type -> Maybe (TyCon, [Type])
Type -> Maybe (TyCon, [Type])
splitTyConApp_maybe (Type -> Type
unwrapSynonyms Type
elemTy) of
Just (TyCon
_, [Type]
args)
| [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
, let nameTy :: Type
nameTy = [Type]
args [Type] -> Int -> Type
forall a. HasCallStack => [a] -> Int -> a
!! ([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
2)
, let fieldTy :: Type
fieldTy = [Type]
args [Type] -> Int -> Type
forall a. HasCallStack => [a] -> Int -> a
!! ([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
1)
, Just FastString
n <- Type -> Maybe FastString
isStrLitTy (Type -> Type
unwrapSynonyms Type
nameTy)
-> (FastString, Type) -> Maybe (FastString, Type)
forall a. a -> Maybe a
Just (FastString
n, Type
fieldTy)
Maybe (TyCon, [Type])
_ -> Maybe (FastString, Type)
forall a. Maybe a
Nothing
rewriteFieldNames :: TyCon -> [Ct] -> [Type] -> TcPluginM 'Rewrite TcPluginRewriteResult
rewriteFieldNames :: TyCon -> TcPluginRewriter
rewriteFieldNames TyCon
tyCon [Ct]
_givens [Type]
args
| Bool -> Bool
not ([Type] -> Bool
forall a. [a] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [Type]
args)
, let rowTy :: Type
rowTy = [Type] -> Type
forall a. HasCallStack => [a] -> a
last [Type]
args
, Just [(FastString, Type)]
fields <- Type -> Maybe [(FastString, Type)]
walkRowFields_maybe Type
rowTy
= do
let names :: [Type]
names = ((FastString, Type) -> Type) -> [(FastString, Type)] -> [Type]
forall a b. (a -> b) -> [a] -> [b]
map (FastString -> Type
mkStrLitTy (FastString -> Type)
-> ((FastString, Type) -> FastString) -> (FastString, Type) -> Type
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (FastString, Type) -> FastString
forall a b. (a, b) -> a
fst) [(FastString, Type)]
fields
reducedTy :: Type
reducedTy = Type -> [Type] -> Type
mkPromotedListTy Type
typeSymbolKind [Type]
names
TcPluginRewriteResult -> TcPluginM 'Rewrite TcPluginRewriteResult
forall a. a -> TcPluginM 'Rewrite a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (TcPluginRewriteResult -> TcPluginM 'Rewrite TcPluginRewriteResult)
-> TcPluginRewriteResult
-> TcPluginM 'Rewrite TcPluginRewriteResult
forall a b. (a -> b) -> a -> b
$ TcPluginRewriteTo
{ tcRewriterNewWanteds :: [Ct]
tcRewriterNewWanteds = []
, tcPluginReduction :: Reduction
tcPluginReduction =
String
-> Role -> [Coercion] -> TyCon -> [Type] -> Type -> Reduction
mkTyFamAppReduction String
"polytropos" Role
Nominal [] TyCon
tyCon [Type]
args Type
reducedTy
}
| Bool
otherwise = TcPluginRewriteResult -> TcPluginM 'Rewrite TcPluginRewriteResult
forall a. a -> TcPluginM 'Rewrite a
forall (f :: * -> *) a. Applicative f => a -> f a
pure TcPluginRewriteResult
TcPluginNoRewrite
rewriteSimpleFieldTypes :: TyCon -> [Ct] -> [Type] -> TcPluginM 'Rewrite TcPluginRewriteResult
rewriteSimpleFieldTypes :: TyCon -> TcPluginRewriter
rewriteSimpleFieldTypes TyCon
tyCon [Ct]
_givens [Type]
args
| Bool -> Bool
not ([Type] -> Bool
forall a. [a] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [Type]
args)
, let rowTy :: Type
rowTy = [Type] -> Type
forall a. HasCallStack => [a] -> a
last [Type]
args
, Just [(FastString, Type)]
fields <- Type -> Maybe [(FastString, Type)]
walkRowFields_maybe Type
rowTy
= do
let pairKind :: Type
pairKind = Boxity -> [Type] -> Type
mkTupleTy Boxity
Boxed [Type
typeSymbolKind, Type
liftedTypeKind]
pairs :: [Type]
pairs = [ Type -> Type -> Type -> Type -> Type
mkPromotedPairTy Type
typeSymbolKind Type
liftedTypeKind (FastString -> Type
mkStrLitTy FastString
name) Type
ty
| (FastString
name, Type
ty) <- [(FastString, Type)]
fields
]
reducedTy :: Type
reducedTy = Type -> [Type] -> Type
mkPromotedListTy Type
pairKind [Type]
pairs
TcPluginRewriteResult -> TcPluginM 'Rewrite TcPluginRewriteResult
forall a. a -> TcPluginM 'Rewrite a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (TcPluginRewriteResult -> TcPluginM 'Rewrite TcPluginRewriteResult)
-> TcPluginRewriteResult
-> TcPluginM 'Rewrite TcPluginRewriteResult
forall a b. (a -> b) -> a -> b
$ TcPluginRewriteTo
{ tcRewriterNewWanteds :: [Ct]
tcRewriterNewWanteds = []
, tcPluginReduction :: Reduction
tcPluginReduction =
String
-> Role -> [Coercion] -> TyCon -> [Type] -> Type -> Reduction
mkTyFamAppReduction String
"polytropos" Role
Nominal [] TyCon
tyCon [Type]
args Type
reducedTy
}
| Bool
otherwise = TcPluginRewriteResult -> TcPluginM 'Rewrite TcPluginRewriteResult
forall a. a -> TcPluginM 'Rewrite a
forall (f :: * -> *) a. Applicative f => a -> f a
pure TcPluginRewriteResult
TcPluginNoRewrite
rewriteFieldTypes :: TyCon -> [Ct] -> [Type] -> TcPluginM 'Rewrite TcPluginRewriteResult
rewriteFieldTypes :: TyCon -> TcPluginRewriter
rewriteFieldTypes TyCon
tyCon [Ct]
_givens [Type]
args
| [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
, let rowTy :: Type
rowTy = [Type] -> Type
forall a. HasCallStack => [a] -> a
last [Type]
args
, let fTy :: Type
fTy = [Type]
args [Type] -> Int -> Type
forall a. HasCallStack => [a] -> Int -> a
!! ([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
2)
, Just [(FastString, Type)]
fields <- Type -> Maybe [(FastString, Type)]
walkRowFields_maybe Type
rowTy
= do
let pairKind :: Type
pairKind = Boxity -> [Type] -> Type
mkTupleTy Boxity
Boxed [Type
typeSymbolKind, Type
liftedTypeKind]
pairs :: [Type]
pairs = [ Type -> Type -> Type -> Type -> Type
mkPromotedPairTy Type
typeSymbolKind Type
liftedTypeKind (FastString -> Type
mkStrLitTy FastString
name) (Type -> Type -> Type
mkAppTy Type
fTy Type
ty)
| (FastString
name, Type
ty) <- [(FastString, Type)]
fields
]
reducedTy :: Type
reducedTy = Type -> [Type] -> Type
mkPromotedListTy Type
pairKind [Type]
pairs
TcPluginRewriteResult -> TcPluginM 'Rewrite TcPluginRewriteResult
forall a. a -> TcPluginM 'Rewrite a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (TcPluginRewriteResult -> TcPluginM 'Rewrite TcPluginRewriteResult)
-> TcPluginRewriteResult
-> TcPluginM 'Rewrite TcPluginRewriteResult
forall a b. (a -> b) -> a -> b
$ TcPluginRewriteTo
{ tcRewriterNewWanteds :: [Ct]
tcRewriterNewWanteds = []
, tcPluginReduction :: Reduction
tcPluginReduction =
String
-> Role -> [Coercion] -> TyCon -> [Type] -> Type -> Reduction
mkTyFamAppReduction String
"polytropos" Role
Nominal [] TyCon
tyCon [Type]
args Type
reducedTy
}
| Bool
otherwise = TcPluginRewriteResult -> TcPluginM 'Rewrite TcPluginRewriteResult
forall a. a -> TcPluginM 'Rewrite a
forall (f :: * -> *) a. Applicative f => a -> f a
pure TcPluginRewriteResult
TcPluginNoRewrite
levenshtein :: String -> String -> Int
levenshtein :: String -> String -> Int
levenshtein String
s1 String
s2 =
let n :: Int
n = String -> Int
forall a. [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length String
s1
initRow :: [Int]
initRow = [Int
0 .. Int
n]
stepRow :: [Int] -> Char -> [Int]
stepRow [Int]
row Char
c2 = case [Int]
row of
[] -> []
Int
d : [Int]
ds -> (Int -> (Char, Int, Int) -> Int)
-> Int -> [(Char, Int, Int)] -> [Int]
forall b a. (b -> a -> b) -> b -> [a] -> [b]
scanl (\Int
left (Char
c1, Int
diag, Int
above) ->
let cost :: Int
cost = if Char
c1 Char -> Char -> Bool
forall a. Eq a => a -> a -> Bool
== Char
c2 then Int
0 else Int
1
in Int -> Int -> Int
forall a. Ord a => a -> a -> a
min (Int
diag Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
cost) (Int -> Int -> Int
forall a. Ord a => a -> a -> a
min (Int
left Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1) (Int
above Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1)))
(Int
d Int -> Int -> Int
forall a. Num a => a -> a -> a
+ Int
1)
(String -> [Int] -> [Int] -> [(Char, Int, Int)]
forall a b c. [a] -> [b] -> [c] -> [(a, b, c)]
zip3 String
s1 [Int]
row [Int]
ds)
in case ([Int] -> Char -> [Int]) -> [Int] -> String -> [Int]
forall b a. (b -> a -> b) -> b -> [a] -> b
forall (t :: * -> *) b a.
Foldable t =>
(b -> a -> b) -> b -> t a -> b
foldl' [Int] -> Char -> [Int]
stepRow [Int]
initRow String
s2 of
[] -> Int
0
[Int]
res -> [Int] -> Int
forall a. HasCallStack => [a] -> a
last [Int]
res
suggestSimilar :: String -> [String] -> [String]
suggestSimilar :: String -> [String] -> [String]
suggestSimilar String
target [String]
candidates =
let scored :: [(String, Int)]
scored = [ (String
c, Int
d) | String
c <- [String]
candidates, let d :: Int
d = String -> String -> Int
levenshtein String
target String
c, Int
d Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
<= Int
2 ]
in ((String, Int) -> String) -> [(String, Int)] -> [String]
forall a b. (a -> b) -> [a] -> [b]
map (String, Int) -> String
forall a b. (a, b) -> a
fst (((String, Int) -> Int) -> [(String, Int)] -> [(String, Int)]
forall b a. Ord b => (a -> b) -> [a] -> [a]
sortOn (String, Int) -> Int
forall a b. (a, b) -> b
snd [(String, Int)]
scored)
formatRecordRow :: [(Int, FastString, Type)] -> String
formatRecordRow :: [(Int, FastString, Type)] -> String
formatRecordRow [(Int, FastString, Type)]
fields =
String
"{ " String -> String -> String
forall a. [a] -> [a] -> [a]
++ String -> [String] -> String
forall a. [a] -> [[a]] -> [a]
intercalate String
", " [ FastString -> String
unpackFS FastString
n String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
" :: " String -> String -> String
forall a. [a] -> [a] -> [a]
++ SDoc -> String
showSDocUnsafe (Type -> SDoc
forall a. Outputable a => a -> SDoc
ppr Type
ty) | (Int
_, FastString
n, Type
ty) <- [(Int, FastString, Type)]
fields ] String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
" }"
formatVariantRow :: [(Int, FastString, Type)] -> String
formatVariantRow :: [(Int, FastString, Type)] -> String
formatVariantRow [(Int, FastString, Type)]
ctors =
String
"< " String -> String -> String
forall a. [a] -> [a] -> [a]
++ String -> [String] -> String
forall a. [a] -> [[a]] -> [a]
intercalate String
" | " (((Int, FastString, Type) -> String)
-> [(Int, FastString, Type)] -> [String]
forall a b. (a -> b) -> [a] -> [b]
map (Int, FastString, Type) -> String
forall {a}. (a, FastString, Type) -> String
formatCtor [(Int, FastString, Type)]
ctors) String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
" >"
where
formatCtor :: (a, FastString, Type) -> String
formatCtor (a
_, FastString
n, Type
conRowTy) =
case Type -> [(Int, FastString, Type)]
walkRowWithTypes Type
conRowTy of
[] -> FastString -> String
unpackFS FastString
n
[(Int
_, FastString
fn, Type
ty)] | FastString -> Bool
nullFS FastString
fn -> FastString -> String
unpackFS FastString
n String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
" :: " String -> String -> String
forall a. [a] -> [a] -> [a]
++ SDoc -> String
showSDocUnsafe (Type -> SDoc
forall a. Outputable a => a -> SDoc
ppr Type
ty)
[(Int, FastString, Type)]
fs -> FastString -> String
unpackFS FastString
n String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
" " String -> String -> String
forall a. [a] -> [a] -> [a]
++ [(Int, FastString, Type)] -> String
formatRecordRow [(Int, FastString, Type)]
fs
formatSuggestion :: String -> [String] -> String
formatSuggestion :: String -> [String] -> String
formatSuggestion String
target [String]
candidates =
case String -> [String] -> [String]
suggestSimilar String
target [String]
candidates of
[] -> case [String]
candidates of
[] -> String
"(no fields in record)"
[String]
_ -> String
"Available fields: " String -> String -> String
forall a. [a] -> [a] -> [a]
++ String -> [String] -> String
forall a. [a] -> [[a]] -> [a]
intercalate String
", " ((String -> String) -> [String] -> [String]
forall a b. (a -> b) -> [a] -> [b]
map (\String
c -> String
"'" String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
c String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
"'") [String]
candidates)
[String]
suggs -> String
"Did you mean: " String -> String -> String
forall a. [a] -> [a] -> [a]
++ String -> [String] -> String
forall a. [a] -> [[a]] -> [a]
intercalate String
" or " ((String -> String) -> [String] -> [String]
forall a b. (a -> b) -> [a] -> [b]
map (\String
s -> String
"'" String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
s String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
"'") [String]
suggs) String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
"?"
formatCtorSuggestion :: String -> [String] -> String
formatCtorSuggestion :: String -> [String] -> String
formatCtorSuggestion String
target [String]
candidates =
case String -> [String] -> [String]
suggestSimilar String
target [String]
candidates of
[] -> case [String]
candidates of
[] -> String
"(no constructors in variant)"
[String]
_ -> String
"Available constructors: " String -> String -> String
forall a. [a] -> [a] -> [a]
++ String -> [String] -> String
forall a. [a] -> [[a]] -> [a]
intercalate String
", " ((String -> String) -> [String] -> [String]
forall a b. (a -> b) -> [a] -> [b]
map (\String
c -> String
"'" String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
c String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
"'") [String]
candidates)
[String]
suggs -> String
"Did you mean: " String -> String -> String
forall a. [a] -> [a] -> [a]
++ String -> [String] -> String
forall a. [a] -> [[a]] -> [a]
intercalate String
" or " ((String -> String) -> [String] -> [String]
forall a b. (a -> b) -> [a] -> [b]
map (\String
s -> String
"'" String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
s String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
"'") [String]
suggs) String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
"?"
isClosedType :: Type -> Bool
isClosedType :: Type -> Bool
isClosedType Type
ty = VarSet -> Bool
isEmptyVarSet (Type -> VarSet
tyCoVarsOfType (Type -> Type
unwrapSynonyms Type
ty))
mkTextMsg :: PluginState -> String -> Type
mkTextMsg :: PluginState -> String -> Type
mkTextMsg PluginState
state String
s = TyCon -> [Type] -> Type
mkTyConApp (PluginState -> TyCon
psPromotedText PluginState
state) [FastString -> Type
mkStrLitTy (String -> FastString
fsLit String
s)]
mkVcatMsgs :: PluginState -> [Type] -> Type
mkVcatMsgs :: PluginState -> [Type] -> Type
mkVcatMsgs PluginState
_ [] = String -> Type
forall a. HasCallStack => String -> a
error String
"mkVcatMsgs: empty list"
mkVcatMsgs PluginState
_ [Type
m] = Type
m
mkVcatMsgs PluginState
state (Type
m : [Type]
ms) = TyCon -> [Type] -> Type
mkTyConApp (PluginState -> TyCon
psPromotedVcat PluginState
state) [Type
m, PluginState -> [Type] -> Type
mkVcatMsgs PluginState
state [Type]
ms]
mkTypeErrorCt :: PluginState -> CtLoc -> [String] -> TcPluginM 'Solve Ct
mkTypeErrorCt :: PluginState -> CtLoc -> [String] -> TcPluginM 'Solve Ct
mkTypeErrorCt PluginState
state CtLoc
loc [String]
msgLines = do
let msgTys :: [Type]
msgTys = (String -> Type) -> [String] -> [Type]
forall a b. (a -> b) -> [a] -> [b]
map (PluginState -> String -> Type
mkTextMsg PluginState
state) [String]
msgLines
fullMsg :: Type
fullMsg = PluginState -> [Type] -> Type
mkVcatMsgs PluginState
state [Type]
msgTys
predTy :: Type
predTy = TyCon -> [Type] -> Type
mkTyConApp (PluginState -> TyCon
psTypeErrorTyCon PluginState
state) [Type
constraintKind, Type
fullMsg]
ev <- CtLoc -> Type -> TcPluginM 'Solve CtEvidence
forall (m :: * -> *).
MonadTcPluginWork m =>
CtLoc -> Type -> m CtEvidence
newWanted CtLoc
loc Type
predTy
pure (mkNonCanonical ev)
mkDummyHasFieldDict :: PluginState -> Class -> [Type] -> TcPluginM 'Solve EvTerm
mkDummyHasFieldDict :: PluginState -> Class -> [Type] -> TcPluginM 'Solve EvTerm
mkDummyHasFieldDict PluginState
state Class
cls [Type]
tys = do
let getFieldId :: Var
getFieldId = case Class -> [Var]
classMethods Class
cls of
(Var
m : [Var]
_) -> Var
m
[] -> String -> Var
forall a. HasCallStack => String -> a
error String
"Polytropos.Plugin: HasField has no methods"
methodFullTy :: Type
methodFullTy = HasDebugCallStack => Type -> [Type] -> Type
Type -> [Type] -> Type
piResultTys (Var -> Type
varType Var
getFieldId) [Type]
tys
(Type
_, Type
_, Type
methodInDictTy) = Type -> (Type, Type, Type)
splitFunTy Type
methodFullTy
([Var]
tyVars, Type
tauTy) = Type -> ([Var], Type)
splitForAllTyCoVars Type
methodInDictTy
([Scaled Type]
argTys, Type
_) = Type -> ([Scaled Type], Type)
splitFunTys Type
tauTy
scaledRTy :: Scaled Type
scaledRTy = [Scaled Type]
argTys [Scaled Type] -> Int -> Scaled Type
forall a. HasCallStack => [a] -> Int -> a
!! Int
0
fieldTy :: Type
fieldTy = [Type] -> Type
forall a. HasCallStack => [a] -> a
last [Type]
tys
rName <- TcM Name -> TcPluginM 'Solve Name
forall a. TcM a -> TcPluginM 'Solve a
forall (m :: * -> *) a. MonadTcPlugin m => TcM a -> m a
unsafeLiftTcM (TcM Name -> TcPluginM 'Solve Name)
-> TcM Name -> TcPluginM 'Solve Name
forall a b. (a -> b) -> a -> b
$ OccName -> TcM Name
newName (String -> OccName
mkVarOcc String
"rec")
let rVar = HasDebugCallStack => Name -> Type -> Type -> Var
Name -> Type -> Type -> Var
mkLocalId Name
rName (Scaled Type -> Type
forall a. Scaled a -> Type
scaledMult Scaled Type
scaledRTy) (Scaled Type -> Type
forall a. Scaled a -> a
scaledThing Scaled Type
scaledRTy)
dummyVal = CoreExpr -> [CoreExpr] -> CoreExpr
mkCoreApps (Var -> CoreExpr
forall b. Var -> Expr b
Var (PluginState -> Var
psNoInlineCo PluginState
state))
[ Type -> CoreExpr
forall b. Type -> Expr b
Type (TyCon -> Type
mkTyConTy TyCon
unitTyCon)
, Type -> CoreExpr
forall b. Type -> Expr b
Type Type
fieldTy
, DataCon -> [CoreExpr] -> CoreExpr
mkCoreConApps DataCon
unitDataCon []
]
getFieldExpr = [Var] -> CoreExpr -> CoreExpr
mkCoreLams ([Var]
tyVars [Var] -> [Var] -> [Var]
forall a. [a] -> [a] -> [a]
++ [Var
rVar]) CoreExpr
dummyVal
pure $ EvExpr (evDataConApp (classDataCon cls) tys [getFieldExpr])
polytroposSolve
:: PluginState
-> [Ct]
-> [Ct]
-> TcPluginM 'Solve TcPluginSolveResult
polytroposSolve :: PluginState -> TcPluginSolver
polytroposSolve PluginState
state [Ct]
givens [Ct]
wanteds = do
let allCts :: [Ct]
allCts = [Ct]
givens [Ct] -> [Ct] -> [Ct]
forall a. [a] -> [a] -> [a]
++ [Ct]
wanteds
results <- (Ct -> TcPluginM 'Solve (Either ((EvTerm, Ct), [Ct]) ()))
-> [Ct] -> TcPluginM 'Solve [Either ((EvTerm, Ct), [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 (PluginState
-> Ct -> TcPluginM 'Solve (Either ((EvTerm, Ct), [Ct]) ())
solveOne PluginState
state) [Ct]
allCts
let (solvedPairs, _) = partitionEithers results
solvedCts = (((EvTerm, Ct), [Ct]) -> (EvTerm, Ct))
-> [((EvTerm, Ct), [Ct])] -> [(EvTerm, Ct)]
forall a b. (a -> b) -> [a] -> [b]
map ((EvTerm, Ct), [Ct]) -> (EvTerm, Ct)
forall a b. (a, b) -> a
fst [((EvTerm, Ct), [Ct])]
solvedPairs
newCts = (((EvTerm, Ct), [Ct]) -> [Ct]) -> [((EvTerm, Ct), [Ct])] -> [Ct]
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap ((EvTerm, Ct), [Ct]) -> [Ct]
forall a b. (a, b) -> b
snd [((EvTerm, Ct), [Ct])]
solvedPairs
pure $ TcPluginSolveResult
{ tcPluginInsolubleCts = []
, tcPluginSolvedCts = solvedCts
, tcPluginNewCts = newCts
}
solveOne :: PluginState -> Ct -> TcPluginM 'Solve (Either ((EvTerm, Ct), [Ct]) ())
solveOne :: PluginState
-> Ct -> TcPluginM 'Solve (Either ((EvTerm, Ct), [Ct]) ())
solveOne PluginState
state Ct
ct
| Bool -> Bool
not (CtEvidence -> Bool
isWanted (Ct -> CtEvidence
ctEvidence Ct
ct))
= Either ((EvTerm, Ct), [Ct]) ()
-> TcPluginM 'Solve (Either ((EvTerm, Ct), [Ct]) ())
forall a. a -> TcPluginM 'Solve a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Either ((EvTerm, Ct), [Ct]) ()
-> TcPluginM 'Solve (Either ((EvTerm, Ct), [Ct]) ()))
-> Either ((EvTerm, Ct), [Ct]) ()
-> TcPluginM 'Solve (Either ((EvTerm, Ct), [Ct]) ())
forall a b. (a -> b) -> a -> b
$ () -> Either ((EvTerm, Ct), [Ct]) ()
forall a b. b -> Either a b
Right ()
| Bool
otherwise
= do
let predTy :: Type
predTy = Ct -> Type
ctPred Ct
ct
case HasDebugCallStack => Type -> Pred
Type -> Pred
classifyPredType Type
predTy of
ClassPred Class
cls [Type]
tys -> do
case Class -> Name
className Class
cls of
Name
name
| Name -> OccName
nameOccName Name
name OccName -> OccName -> Bool
forall a. Eq a => a -> a -> Bool
== String -> OccName
mkTcOcc String
"FieldIndex"
-> PluginState
-> Ct
-> Class
-> [Type]
-> TcPluginM 'Solve (Either ((EvTerm, Ct), [Ct]) ())
solveFieldIndex PluginState
state Ct
ct Class
cls [Type]
tys
| Name -> OccName
nameOccName Name
name OccName -> OccName -> Bool
forall a. Eq a => a -> a -> Bool
== String -> OccName
mkTcOcc String
"ConstructorIndex"
-> PluginState
-> Ct
-> Class
-> [Type]
-> TcPluginM 'Solve (Either ((EvTerm, Ct), [Ct]) ())
solveConstructorIndex PluginState
state Ct
ct Class
cls [Type]
tys
| Name -> OccName
nameOccName Name
name OccName -> OccName -> Bool
forall a. Eq a => a -> a -> Bool
== String -> OccName
mkTcOcc String
"RowEq"
-> PluginState
-> Ct
-> Class
-> [Type]
-> TcPluginM 'Solve (Either ((EvTerm, Ct), [Ct]) ())
solveRowEq PluginState
state Ct
ct Class
cls [Type]
tys
| Name -> OccName
nameOccName Name
name OccName -> OccName -> Bool
forall a. Eq a => a -> a -> Bool
== String -> OccName
mkTcOcc String
"RowShow"
-> PluginState
-> Ct
-> Class
-> [Type]
-> TcPluginM 'Solve (Either ((EvTerm, Ct), [Ct]) ())
solveRowShow PluginState
state Ct
ct Class
cls [Type]
tys
| Name -> OccName
nameOccName Name
name OccName -> OccName -> Bool
forall a. Eq a => a -> a -> Bool
== String -> OccName
mkTcOcc String
"RowEqSum"
-> PluginState
-> Ct
-> Class
-> [Type]
-> TcPluginM 'Solve (Either ((EvTerm, Ct), [Ct]) ())
solveRowEqSum PluginState
state Ct
ct Class
cls [Type]
tys
| Name -> OccName
nameOccName Name
name OccName -> OccName -> Bool
forall a. Eq a => a -> a -> Bool
== String -> OccName
mkTcOcc String
"RowShowSum"
-> PluginState
-> Ct
-> Class
-> [Type]
-> TcPluginM 'Solve (Either ((EvTerm, Ct), [Ct]) ())
solveRowShowSum PluginState
state Ct
ct Class
cls [Type]
tys
| Name -> OccName
nameOccName Name
name OccName -> OccName -> Bool
forall a. Eq a => a -> a -> Bool
== String -> OccName
mkTcOcc String
"HasField"
-> PluginState
-> Ct
-> Class
-> [Type]
-> TcPluginM 'Solve (Either ((EvTerm, Ct), [Ct]) ())
solveHasField PluginState
state Ct
ct Class
cls [Type]
tys
| Name -> OccName
nameOccName Name
name OccName -> OccName -> Bool
forall a. Eq a => a -> a -> Bool
== String -> OccName
mkTcOcc String
"AllFields"
-> PluginState
-> Ct
-> Class
-> [Type]
-> TcPluginM 'Solve (Either ((EvTerm, Ct), [Ct]) ())
solveAllFields PluginState
state Ct
ct Class
cls [Type]
tys
| Name -> OccName
nameOccName Name
name OccName -> OccName -> Bool
forall a. Eq a => a -> a -> Bool
== String -> OccName
mkTcOcc String
"SubRow"
-> PluginState
-> Ct
-> Class
-> [Type]
-> TcPluginM 'Solve (Either ((EvTerm, Ct), [Ct]) ())
solveSubRow PluginState
state Ct
ct Class
cls [Type]
tys
| Name -> OccName
nameOccName Name
name OccName -> OccName -> Bool
forall a. Eq a => a -> a -> Bool
== String -> OccName
mkTcOcc String
"SubSum"
-> PluginState
-> Ct
-> Class
-> [Type]
-> TcPluginM 'Solve (Either ((EvTerm, Ct), [Ct]) ())
solveSubSum PluginState
state Ct
ct Class
cls [Type]
tys
| Name -> OccName
nameOccName Name
name OccName -> OccName -> Bool
forall a. Eq a => a -> a -> Bool
== String -> OccName
mkTcOcc String
"KnownHash"
-> Either (EvTerm, Ct) () -> Either ((EvTerm, Ct), [Ct]) ()
forall {a} {a}. Either a () -> Either (a, [a]) ()
noNew (Either (EvTerm, Ct) () -> Either ((EvTerm, Ct), [Ct]) ())
-> TcPluginM 'Solve (Either (EvTerm, Ct) ())
-> TcPluginM 'Solve (Either ((EvTerm, Ct), [Ct]) ())
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Ct -> Class -> [Type] -> TcPluginM 'Solve (Either (EvTerm, Ct) ())
solveKnownHash Ct
ct Class
cls [Type]
tys
| Bool
otherwise
-> Either ((EvTerm, Ct), [Ct]) ()
-> TcPluginM 'Solve (Either ((EvTerm, Ct), [Ct]) ())
forall a. a -> TcPluginM 'Solve a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Either ((EvTerm, Ct), [Ct]) ()
-> TcPluginM 'Solve (Either ((EvTerm, Ct), [Ct]) ()))
-> Either ((EvTerm, Ct), [Ct]) ()
-> TcPluginM 'Solve (Either ((EvTerm, Ct), [Ct]) ())
forall a b. (a -> b) -> a -> b
$ () -> Either ((EvTerm, Ct), [Ct]) ()
forall a b. b -> Either a b
Right ()
Pred
_ -> Either ((EvTerm, Ct), [Ct]) ()
-> TcPluginM 'Solve (Either ((EvTerm, Ct), [Ct]) ())
forall a. a -> TcPluginM 'Solve a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Either ((EvTerm, Ct), [Ct]) ()
-> TcPluginM 'Solve (Either ((EvTerm, Ct), [Ct]) ()))
-> Either ((EvTerm, Ct), [Ct]) ()
-> TcPluginM 'Solve (Either ((EvTerm, Ct), [Ct]) ())
forall a b. (a -> b) -> a -> b
$ () -> Either ((EvTerm, Ct), [Ct]) ()
forall a b. b -> Either a b
Right ()
where
noNew :: Either a () -> Either (a, [a]) ()
noNew (Left a
res) = (a, [a]) -> Either (a, [a]) ()
forall a b. a -> Either a b
Left (a
res, [])
noNew (Right ()) = () -> Either (a, [a]) ()
forall a b. b -> Either a b
Right ()
solveFieldIndex
:: PluginState
-> Ct
-> Class
-> [Type]
-> TcPluginM 'Solve (Either ((EvTerm, Ct), [Ct]) ())
solveFieldIndex :: PluginState
-> Ct
-> Class
-> [Type]
-> TcPluginM 'Solve (Either ((EvTerm, Ct), [Ct]) ())
solveFieldIndex PluginState
state Ct
ct Class
cls [Type]
tys
| [Type] -> Int
forall a. [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [Type]
tys Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
>= Int
3 = do
let nTy :: Type
nTy = [Type]
tys [Type] -> Int -> Type
forall a. HasCallStack => [a] -> Int -> a
!! ([Type] -> Int
forall a. [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [Type]
tys Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
3)
rowTy :: Type
rowTy = [Type]
tys [Type] -> Int -> Type
forall a. HasCallStack => [a] -> Int -> a
!! ([Type] -> Int
forall a. [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [Type]
tys Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
2)
expectedATy :: Type
expectedATy = [Type] -> Type
forall a. HasCallStack => [a] -> a
last [Type]
tys
unwrapN :: Type
unwrapN = Type -> Type
unwrapSynonyms Type
nTy
loc :: CtLoc
loc = Ct -> CtLoc
ctLoc Ct
ct
case Type -> Maybe FastString
isStrLitTy Type
unwrapN of
Just FastString
fieldName -> do
case FastString -> Type -> Maybe (Int, Type)
findFieldType FastString
fieldName Type
rowTy of
Just (Int
i, Type
actualTy)
| Type
actualTy HasCallStack => Type -> Type -> Bool
Type -> Type -> Bool
`eqType` Type
expectedATy Bool -> Bool -> Bool
|| Bool -> Bool
not (Type -> Bool
isClosedType Type
expectedATy) -> do
let iExpr :: CoreExpr
iExpr = Int -> CoreExpr
mkIntExpr Int
i
dictExpr :: CoreExpr
dictExpr = DataCon -> [Type] -> [CoreExpr] -> CoreExpr
evDataConApp (Class -> DataCon
classDataCon Class
cls) [Type]
tys [CoreExpr
iExpr]
Either ((EvTerm, Ct), [Ct]) ()
-> TcPluginM 'Solve (Either ((EvTerm, Ct), [Ct]) ())
forall a. a -> TcPluginM 'Solve a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Either ((EvTerm, Ct), [Ct]) ()
-> TcPluginM 'Solve (Either ((EvTerm, Ct), [Ct]) ()))
-> Either ((EvTerm, Ct), [Ct]) ()
-> TcPluginM 'Solve (Either ((EvTerm, Ct), [Ct]) ())
forall a b. (a -> b) -> a -> b
$ ((EvTerm, Ct), [Ct]) -> Either ((EvTerm, Ct), [Ct]) ()
forall a b. a -> Either a b
Left ((CoreExpr -> EvTerm
EvExpr CoreExpr
dictExpr, Ct
ct), [])
| Bool
otherwise -> do
let dummyExpr :: CoreExpr
dummyExpr = Int -> CoreExpr
mkIntExpr Int
0
dummyDict :: CoreExpr
dummyDict = DataCon -> [Type] -> [CoreExpr] -> CoreExpr
evDataConApp (Class -> DataCon
classDataCon Class
cls) [Type]
tys [CoreExpr
dummyExpr]
diagLines :: [String]
diagLines =
[ String
"Polytropos Record Error:"
, String
" Field '" String -> String -> String
forall a. [a] -> [a] -> [a]
++ FastString -> String
unpackFS FastString
fieldName String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
"' in record has type:"
, String
" " String -> String -> String
forall a. [a] -> [a] -> [a]
++ SDoc -> String
showSDocUnsafe (Type -> SDoc
forall a. Outputable a => a -> SDoc
ppr Type
actualTy)
, String
" but expected:"
, String
" " String -> String -> String
forall a. [a] -> [a] -> [a]
++ SDoc -> String
showSDocUnsafe (Type -> SDoc
forall a. Outputable a => a -> SDoc
ppr Type
expectedATy)
]
errCt <- PluginState -> CtLoc -> [String] -> TcPluginM 'Solve Ct
mkTypeErrorCt PluginState
state CtLoc
loc [String]
diagLines
pure $ Left ((EvExpr dummyDict, ct), [errCt])
Maybe (Int, Type)
Nothing -> do
case Type -> Maybe [(Int, FastString, Type)]
walkRowWithTypes_maybe Type
rowTy of
Just [(Int, FastString, Type)]
fields -> do
let dummyExpr :: CoreExpr
dummyExpr = Int -> CoreExpr
mkIntExpr Int
0
dummyDict :: CoreExpr
dummyDict = DataCon -> [Type] -> [CoreExpr] -> CoreExpr
evDataConApp (Class -> DataCon
classDataCon Class
cls) [Type]
tys [CoreExpr
dummyExpr]
fNames :: [String]
fNames = [ FastString -> String
unpackFS FastString
n | (Int
_, FastString
n, Type
_) <- [(Int, FastString, Type)]
fields, Bool -> Bool
not (FastString -> Bool
nullFS FastString
n) ]
diagLines :: [String]
diagLines =
[ String
"Polytropos Record Error:"
, String
" Field '" String -> String -> String
forall a. [a] -> [a] -> [a]
++ FastString -> String
unpackFS FastString
fieldName String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
"' does not exist in record:"
, String
" " String -> String -> String
forall a. [a] -> [a] -> [a]
++ [(Int, FastString, Type)] -> String
formatRecordRow [(Int, FastString, Type)]
fields
, String
" " String -> String -> String
forall a. [a] -> [a] -> [a]
++ String -> [String] -> String
formatSuggestion (FastString -> String
unpackFS FastString
fieldName) [String]
fNames
]
errCt <- PluginState -> CtLoc -> [String] -> TcPluginM 'Solve Ct
mkTypeErrorCt PluginState
state CtLoc
loc [String]
diagLines
pure $ Left ((EvExpr dummyDict, ct), [errCt])
Maybe [(Int, FastString, Type)]
Nothing -> Either ((EvTerm, Ct), [Ct]) ()
-> TcPluginM 'Solve (Either ((EvTerm, Ct), [Ct]) ())
forall a. a -> TcPluginM 'Solve a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Either ((EvTerm, Ct), [Ct]) ()
-> TcPluginM 'Solve (Either ((EvTerm, Ct), [Ct]) ()))
-> Either ((EvTerm, Ct), [Ct]) ()
-> TcPluginM 'Solve (Either ((EvTerm, Ct), [Ct]) ())
forall a b. (a -> b) -> a -> b
$ () -> Either ((EvTerm, Ct), [Ct]) ()
forall a b. b -> Either a b
Right ()
Maybe FastString
Nothing -> do
case Type -> Type -> Maybe Int
findFieldIndexByType Type
unwrapN Type
rowTy of
Just Int
i -> do
let iExpr :: CoreExpr
iExpr = Int -> CoreExpr
mkIntExpr Int
i
dictExpr :: CoreExpr
dictExpr = DataCon -> [Type] -> [CoreExpr] -> CoreExpr
evDataConApp (Class -> DataCon
classDataCon Class
cls) [Type]
tys [CoreExpr
iExpr]
Either ((EvTerm, Ct), [Ct]) ()
-> TcPluginM 'Solve (Either ((EvTerm, Ct), [Ct]) ())
forall a. a -> TcPluginM 'Solve a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Either ((EvTerm, Ct), [Ct]) ()
-> TcPluginM 'Solve (Either ((EvTerm, Ct), [Ct]) ()))
-> Either ((EvTerm, Ct), [Ct]) ()
-> TcPluginM 'Solve (Either ((EvTerm, Ct), [Ct]) ())
forall a b. (a -> b) -> a -> b
$ ((EvTerm, Ct), [Ct]) -> Either ((EvTerm, Ct), [Ct]) ()
forall a b. a -> Either a b
Left ((CoreExpr -> EvTerm
EvExpr CoreExpr
dictExpr, Ct
ct), [])
Maybe Int
Nothing -> do
case Type -> Maybe [(Int, FastString, Type)]
walkRowWithTypes_maybe Type
rowTy of
Just [(Int, FastString, Type)]
fields -> do
let dummyExpr :: CoreExpr
dummyExpr = Int -> CoreExpr
mkIntExpr Int
0
dummyDict :: CoreExpr
dummyDict = DataCon -> [Type] -> [CoreExpr] -> CoreExpr
evDataConApp (Class -> DataCon
classDataCon Class
cls) [Type]
tys [CoreExpr
dummyExpr]
diagLines :: [String]
diagLines =
[ String
"Polytropos Record Error:"
, String
" Type '" String -> String -> String
forall a. [a] -> [a] -> [a]
++ SDoc -> String
showSDocUnsafe (Type -> SDoc
forall a. Outputable a => a -> SDoc
ppr Type
unwrapN) String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
"' is not a field in record:"
, String
" " String -> String -> String
forall a. [a] -> [a] -> [a]
++ [(Int, FastString, Type)] -> String
formatRecordRow [(Int, FastString, Type)]
fields
]
errCt <- PluginState -> CtLoc -> [String] -> TcPluginM 'Solve Ct
mkTypeErrorCt PluginState
state CtLoc
loc [String]
diagLines
pure $ Left ((EvExpr dummyDict, ct), [errCt])
Maybe [(Int, FastString, Type)]
Nothing -> Either ((EvTerm, Ct), [Ct]) ()
-> TcPluginM 'Solve (Either ((EvTerm, Ct), [Ct]) ())
forall a. a -> TcPluginM 'Solve a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Either ((EvTerm, Ct), [Ct]) ()
-> TcPluginM 'Solve (Either ((EvTerm, Ct), [Ct]) ()))
-> Either ((EvTerm, Ct), [Ct]) ()
-> TcPluginM 'Solve (Either ((EvTerm, Ct), [Ct]) ())
forall a b. (a -> b) -> a -> b
$ () -> Either ((EvTerm, Ct), [Ct]) ()
forall a b. b -> Either a b
Right ()
| Bool
otherwise = Either ((EvTerm, Ct), [Ct]) ()
-> TcPluginM 'Solve (Either ((EvTerm, Ct), [Ct]) ())
forall a. a -> TcPluginM 'Solve a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Either ((EvTerm, Ct), [Ct]) ()
-> TcPluginM 'Solve (Either ((EvTerm, Ct), [Ct]) ()))
-> Either ((EvTerm, Ct), [Ct]) ()
-> TcPluginM 'Solve (Either ((EvTerm, Ct), [Ct]) ())
forall a b. (a -> b) -> a -> b
$ () -> Either ((EvTerm, Ct), [Ct]) ()
forall a b. b -> Either a b
Right ()
solveConstructorIndex
:: PluginState
-> Ct
-> Class
-> [Type]
-> TcPluginM 'Solve (Either ((EvTerm, Ct), [Ct]) ())
solveConstructorIndex :: PluginState
-> Ct
-> Class
-> [Type]
-> TcPluginM 'Solve (Either ((EvTerm, Ct), [Ct]) ())
solveConstructorIndex PluginState
state Ct
ct Class
cls [Type]
tys
| [Type] -> Int
forall a. [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [Type]
tys Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
>= Int
2 = do
let nTy :: Type
nTy = [Type]
tys [Type] -> Int -> Type
forall a. HasCallStack => [a] -> Int -> a
!! ([Type] -> Int
forall a. [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [Type]
tys Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
2)
rowTy :: Type
rowTy = [Type]
tys [Type] -> Int -> Type
forall a. HasCallStack => [a] -> Int -> a
!! ([Type] -> Int
forall a. [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [Type]
tys Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
1)
unwrapN :: Type
unwrapN = Type -> Type
unwrapSynonyms Type
nTy
loc :: CtLoc
loc = Ct -> CtLoc
ctLoc Ct
ct
case Type -> Maybe FastString
isStrLitTy Type
unwrapN of
Just FastString
conName -> do
case FastString -> Type -> Maybe Word
findConstructorIndex FastString
conName Type
rowTy of
Just Word
w -> do
let wExpr :: CoreExpr
wExpr = Word -> CoreExpr
mkWordExpr Word
w
dictExpr :: CoreExpr
dictExpr = DataCon -> [Type] -> [CoreExpr] -> CoreExpr
evDataConApp (Class -> DataCon
classDataCon Class
cls) [Type]
tys [CoreExpr
wExpr]
Either ((EvTerm, Ct), [Ct]) ()
-> TcPluginM 'Solve (Either ((EvTerm, Ct), [Ct]) ())
forall a. a -> TcPluginM 'Solve a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Either ((EvTerm, Ct), [Ct]) ()
-> TcPluginM 'Solve (Either ((EvTerm, Ct), [Ct]) ()))
-> Either ((EvTerm, Ct), [Ct]) ()
-> TcPluginM 'Solve (Either ((EvTerm, Ct), [Ct]) ())
forall a b. (a -> b) -> a -> b
$ ((EvTerm, Ct), [Ct]) -> Either ((EvTerm, Ct), [Ct]) ()
forall a b. a -> Either a b
Left ((CoreExpr -> EvTerm
EvExpr CoreExpr
dictExpr, Ct
ct), [])
Maybe Word
Nothing -> do
case Type -> Maybe [(Int, FastString, Type)]
walkSumRowWithTypes_maybe Type
rowTy of
Just [(Int, FastString, Type)]
ctors -> do
let dummyExpr :: CoreExpr
dummyExpr = Word -> CoreExpr
mkWordExpr Word
0
dummyDict :: CoreExpr
dummyDict = DataCon -> [Type] -> [CoreExpr] -> CoreExpr
evDataConApp (Class -> DataCon
classDataCon Class
cls) [Type]
tys [CoreExpr
dummyExpr]
cNames :: [String]
cNames = [ FastString -> String
unpackFS FastString
n | (Int
_, FastString
n, Type
_) <- [(Int, FastString, Type)]
ctors, Bool -> Bool
not (FastString -> Bool
nullFS FastString
n) ]
diagLines :: [String]
diagLines =
[ String
"Polytropos Variant Error:"
, String
" Constructor '" String -> String -> String
forall a. [a] -> [a] -> [a]
++ FastString -> String
unpackFS FastString
conName String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
"' is not a member of variant:"
, String
" " String -> String -> String
forall a. [a] -> [a] -> [a]
++ [(Int, FastString, Type)] -> String
formatVariantRow [(Int, FastString, Type)]
ctors
, String
" " String -> String -> String
forall a. [a] -> [a] -> [a]
++ String -> [String] -> String
formatCtorSuggestion (FastString -> String
unpackFS FastString
conName) [String]
cNames
]
errCt <- PluginState -> CtLoc -> [String] -> TcPluginM 'Solve Ct
mkTypeErrorCt PluginState
state CtLoc
loc [String]
diagLines
pure $ Left ((EvExpr dummyDict, ct), [errCt])
Maybe [(Int, FastString, Type)]
Nothing -> Either ((EvTerm, Ct), [Ct]) ()
-> TcPluginM 'Solve (Either ((EvTerm, Ct), [Ct]) ())
forall a. a -> TcPluginM 'Solve a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Either ((EvTerm, Ct), [Ct]) ()
-> TcPluginM 'Solve (Either ((EvTerm, Ct), [Ct]) ()))
-> Either ((EvTerm, Ct), [Ct]) ()
-> TcPluginM 'Solve (Either ((EvTerm, Ct), [Ct]) ())
forall a b. (a -> b) -> a -> b
$ () -> Either ((EvTerm, Ct), [Ct]) ()
forall a b. b -> Either a b
Right ()
Maybe FastString
Nothing -> do
case Type -> Type -> Maybe Word
findConstructorIndexByType Type
unwrapN Type
rowTy of
Just Word
w -> do
let wExpr :: CoreExpr
wExpr = Word -> CoreExpr
mkWordExpr Word
w
dictExpr :: CoreExpr
dictExpr = DataCon -> [Type] -> [CoreExpr] -> CoreExpr
evDataConApp (Class -> DataCon
classDataCon Class
cls) [Type]
tys [CoreExpr
wExpr]
Either ((EvTerm, Ct), [Ct]) ()
-> TcPluginM 'Solve (Either ((EvTerm, Ct), [Ct]) ())
forall a. a -> TcPluginM 'Solve a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Either ((EvTerm, Ct), [Ct]) ()
-> TcPluginM 'Solve (Either ((EvTerm, Ct), [Ct]) ()))
-> Either ((EvTerm, Ct), [Ct]) ()
-> TcPluginM 'Solve (Either ((EvTerm, Ct), [Ct]) ())
forall a b. (a -> b) -> a -> b
$ ((EvTerm, Ct), [Ct]) -> Either ((EvTerm, Ct), [Ct]) ()
forall a b. a -> Either a b
Left ((CoreExpr -> EvTerm
EvExpr CoreExpr
dictExpr, Ct
ct), [])
Maybe Word
Nothing -> do
case Type -> Maybe [(Int, FastString, Type)]
walkSumRowWithTypes_maybe Type
rowTy of
Just [(Int, FastString, Type)]
ctors -> do
let dummyExpr :: CoreExpr
dummyExpr = Word -> CoreExpr
mkWordExpr Word
0
dummyDict :: CoreExpr
dummyDict = DataCon -> [Type] -> [CoreExpr] -> CoreExpr
evDataConApp (Class -> DataCon
classDataCon Class
cls) [Type]
tys [CoreExpr
dummyExpr]
diagLines :: [String]
diagLines =
[ String
"Polytropos Variant Error:"
, String
" Type '" String -> String -> String
forall a. [a] -> [a] -> [a]
++ SDoc -> String
showSDocUnsafe (Type -> SDoc
forall a. Outputable a => a -> SDoc
ppr Type
unwrapN) String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
"' is not a payload type in variant:"
, String
" " String -> String -> String
forall a. [a] -> [a] -> [a]
++ [(Int, FastString, Type)] -> String
formatVariantRow [(Int, FastString, Type)]
ctors
]
errCt <- PluginState -> CtLoc -> [String] -> TcPluginM 'Solve Ct
mkTypeErrorCt PluginState
state CtLoc
loc [String]
diagLines
pure $ Left ((EvExpr dummyDict, ct), [errCt])
Maybe [(Int, FastString, Type)]
Nothing -> Either ((EvTerm, Ct), [Ct]) ()
-> TcPluginM 'Solve (Either ((EvTerm, Ct), [Ct]) ())
forall a. a -> TcPluginM 'Solve a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Either ((EvTerm, Ct), [Ct]) ()
-> TcPluginM 'Solve (Either ((EvTerm, Ct), [Ct]) ()))
-> Either ((EvTerm, Ct), [Ct]) ()
-> TcPluginM 'Solve (Either ((EvTerm, Ct), [Ct]) ())
forall a b. (a -> b) -> a -> b
$ () -> Either ((EvTerm, Ct), [Ct]) ()
forall a b. b -> Either a b
Right ()
| Bool
otherwise = Either ((EvTerm, Ct), [Ct]) ()
-> TcPluginM 'Solve (Either ((EvTerm, Ct), [Ct]) ())
forall a. a -> TcPluginM 'Solve a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Either ((EvTerm, Ct), [Ct]) ()
-> TcPluginM 'Solve (Either ((EvTerm, Ct), [Ct]) ()))
-> Either ((EvTerm, Ct), [Ct]) ()
-> TcPluginM 'Solve (Either ((EvTerm, Ct), [Ct]) ())
forall a b. (a -> b) -> a -> b
$ () -> Either ((EvTerm, Ct), [Ct]) ()
forall a b. b -> Either a b
Right ()
solveRowEq
:: PluginState
-> Ct
-> Class
-> [Type]
-> TcPluginM 'Solve (Either ((EvTerm, Ct), [Ct]) ())
solveRowEq :: PluginState
-> Ct
-> Class
-> [Type]
-> TcPluginM 'Solve (Either ((EvTerm, Ct), [Ct]) ())
solveRowEq PluginState
state Ct
ct Class
cls [Type]
tys = do
let rowTy :: Type
rowTy = [Type] -> Type
forall a. HasCallStack => [a] -> a
last [Type]
tys
rTy :: Type
rTy = [Type]
tys [Type] -> Int -> Type
forall a. HasCallStack => [a] -> Int -> a
!! ([Type] -> Int
forall a. [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [Type]
tys Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
2)
fields :: [(Int, FastString, Type)]
fields = Type -> [(Int, FastString, Type)]
walkRowWithTypes Type
rowTy
loc :: CtLoc
loc = Ct -> CtLoc
ctLoc Ct
ct
scEvidence :: CoreExpr
scEvidence = DataCon -> [Type] -> [CoreExpr] -> CoreExpr
evDataConApp (Class -> DataCon
classDataCon (PluginState -> Class
psRowFlavourCls PluginState
state)) [Type
rTy] []
repEqId :: Var
repEqId = case Class -> [Var]
classMethods Class
cls of
(Var
m : [Var]
_) -> Var
m
[] -> String -> Var
forall a. HasCallStack => String -> a
error String
"Polytropos.Plugin: RowEq class has no methods"
methodFullTy :: Type
methodFullTy = HasDebugCallStack => Type -> [Type] -> Type
Type -> [Type] -> Type
piResultTys (Var -> Type
varType Var
repEqId) [Type]
tys
(Type
_, Type
_, Type
methodInDictTy) = Type -> (Type, Type, Type)
splitFunTy Type
methodFullTy
([Var]
tyVars, Type
tauTy) = Type -> ([Var], Type)
splitForAllTyCoVars Type
methodInDictTy
([Scaled Type]
argTys, Type
_) = Type -> ([Scaled Type], Type)
splitFunTys Type
tauTy
scaledR1Ty :: Scaled Type
scaledR1Ty = [Scaled Type]
argTys [Scaled Type] -> Int -> Scaled Type
forall a. HasCallStack => [a] -> Int -> a
!! Int
0
scaledR2Ty :: Scaled Type
scaledR2Ty = [Scaled Type]
argTys [Scaled Type] -> Int -> Scaled Type
forall a. HasCallStack => [a] -> Int -> a
!! Int
1
r1Name <- TcM Name -> TcPluginM 'Solve Name
forall a. TcM a -> TcPluginM 'Solve a
forall (m :: * -> *) a. MonadTcPlugin m => TcM a -> m a
unsafeLiftTcM (TcM Name -> TcPluginM 'Solve Name)
-> TcM Name -> TcPluginM 'Solve Name
forall a b. (a -> b) -> a -> b
$ OccName -> TcM Name
newName (String -> OccName
mkVarOcc String
"r1")
r2Name <- unsafeLiftTcM $ newName (mkVarOcc "r2")
let r1Var = HasDebugCallStack => Name -> Type -> Type -> Var
Name -> Type -> Type -> Var
mkLocalId Name
r1Name (Scaled Type -> Type
forall a. Scaled a -> Type
scaledMult Scaled Type
scaledR1Ty) (Scaled Type -> Type
forall a. Scaled a -> a
scaledThing Scaled Type
scaledR1Ty)
r2Var = HasDebugCallStack => Name -> Type -> Type -> Var
Name -> Type -> Type -> Var
mkLocalId Name
r2Name (Scaled Type -> Type
forall a. Scaled a -> Type
scaledMult Scaled Type
scaledR2Ty) (Scaled Type -> Type
forall a. Scaled a -> a
scaledThing Scaled Type
scaledR2Ty)
kATy = Var -> Type
mkTyVarTy ([Var]
tyVars [Var] -> Int -> Var
forall a. HasCallStack => [a] -> Int -> a
!! Int
0)
fTy = Var -> Type
mkTyVarTy ([Var]
tyVars [Var] -> Int -> Var
forall a. HasCallStack => [a] -> Int -> a
!! Int
1)
aTy = Var -> Type
mkTyVarTy ([Var]
tyVars [Var] -> Int -> Var
forall a. HasCallStack => [a] -> Int -> a
!! Int
2)
kRowTy = HasDebugCallStack => Type -> Type
Type -> Type
typeKind Type
rowTy
unRowRepTypeArgs = [Type -> CoreExpr
forall b. Type -> Expr b
Type Type
kRowTy, Type -> CoreExpr
forall b. Type -> Expr b
Type Type
kATy, Type -> CoreExpr
forall b. Type -> Expr b
Type Type
fTy, Type -> CoreExpr
forall b. Type -> Expr b
Type Type
rTy, Type -> CoreExpr
forall b. Type -> Expr b
Type Type
rowTy, Type -> CoreExpr
forall b. Type -> Expr b
Type Type
aTy]
rep1 = CoreExpr -> [CoreExpr] -> CoreExpr
mkCoreApps (Var -> CoreExpr
forall b. Var -> Expr b
Var (PluginState -> Var
psUnRowRep PluginState
state)) ([CoreExpr]
unRowRepTypeArgs [CoreExpr] -> [CoreExpr] -> [CoreExpr]
forall a. [a] -> [a] -> [a]
++ [Var -> CoreExpr
forall b. Var -> Expr b
Var Var
r1Var])
rep2 = CoreExpr -> [CoreExpr] -> CoreExpr
mkCoreApps (Var -> CoreExpr
forall b. Var -> Expr b
Var (PluginState -> Var
psUnRowRep PluginState
state)) ([CoreExpr]
unRowRepTypeArgs [CoreExpr] -> [CoreExpr] -> [CoreExpr]
forall a. [a] -> [a] -> [a]
++ [Var -> CoreExpr
forall b. Var -> Expr b
Var Var
r2Var])
repTypeArgs = [Type -> CoreExpr
forall b. Type -> Expr b
Type Type
kATy, Type -> CoreExpr
forall b. Type -> Expr b
Type Type
fTy, Type -> CoreExpr
forall b. Type -> Expr b
Type Type
aTy]
tag1 = CoreExpr -> [CoreExpr] -> CoreExpr
mkCoreApps (Var -> CoreExpr
forall b. Var -> Expr b
Var (PluginState -> Var
psRepTag PluginState
state)) ([CoreExpr]
repTypeArgs [CoreExpr] -> [CoreExpr] -> [CoreExpr]
forall a. [a] -> [a] -> [a]
++ [CoreExpr
rep1])
tag2 = CoreExpr -> [CoreExpr] -> CoreExpr
mkCoreApps (Var -> CoreExpr
forall b. Var -> Expr b
Var (PluginState -> Var
psRepTag PluginState
state)) ([CoreExpr]
repTypeArgs [CoreExpr] -> [CoreExpr] -> [CoreExpr]
forall a. [a] -> [a] -> [a]
++ [CoreExpr
rep2])
eqTag = CoreExpr -> [CoreExpr] -> CoreExpr
mkCoreApps (Var -> CoreExpr
forall b. Var -> Expr b
Var (PluginState -> Var
psEqClass PluginState
state)) [Type -> CoreExpr
forall b. Type -> Expr b
Type (TyCon -> Type
mkTyConTy TyCon
wordTyCon), Var -> CoreExpr
forall b. Var -> Expr b
Var (PluginState -> Var
psFEqWord PluginState
state), CoreExpr
tag1, CoreExpr
tag2]
arity1 = CoreExpr -> [CoreExpr] -> CoreExpr
mkCoreApps (Var -> CoreExpr
forall b. Var -> Expr b
Var (PluginState -> Var
psRepArity PluginState
state)) ([CoreExpr]
repTypeArgs [CoreExpr] -> [CoreExpr] -> [CoreExpr]
forall a. [a] -> [a] -> [a]
++ [CoreExpr
rep1])
arity2 = CoreExpr -> [CoreExpr] -> CoreExpr
mkCoreApps (Var -> CoreExpr
forall b. Var -> Expr b
Var (PluginState -> Var
psRepArity PluginState
state)) ([CoreExpr]
repTypeArgs [CoreExpr] -> [CoreExpr] -> [CoreExpr]
forall a. [a] -> [a] -> [a]
++ [CoreExpr
rep2])
eqArity = CoreExpr -> [CoreExpr] -> CoreExpr
mkCoreApps (Var -> CoreExpr
forall b. Var -> Expr b
Var (PluginState -> Var
psEqClass PluginState
state)) [Type -> CoreExpr
forall b. Type -> Expr b
Type Type
intTy, Var -> CoreExpr
forall b. Var -> Expr b
Var (PluginState -> Var
psFEqInt PluginState
state), CoreExpr
arity1, CoreExpr
arity2]
wanteds <- forM fields $ \(Int
i, FastString
_nameFS, Type
fieldTy) -> do
ev <- CtLoc -> Type -> TcPluginM 'Solve CtEvidence
forall (m :: * -> *).
MonadTcPluginWork m =>
CtLoc -> Type -> m CtEvidence
newWanted CtLoc
loc (Type -> Type -> Type
mkAppTy (TyCon -> Type
mkTyConTy (Class -> TyCon
classTyCon (PluginState -> Class
psEqCls PluginState
state))) Type
fieldTy)
pure (i, fieldTy, ev)
let compareField (Int
i, Type
fieldTy, CtEvidence
ev) =
let fieldAtTypeArgs :: [CoreExpr]
fieldAtTypeArgs = [Type -> CoreExpr
forall b. Type -> Expr b
Type Type
kATy, Type -> CoreExpr
forall b. Type -> Expr b
Type Type
fTy, Type -> CoreExpr
forall b. Type -> Expr b
Type Type
aTy, Type -> CoreExpr
forall b. Type -> Expr b
Type Type
fieldTy]
idxExpr :: CoreExpr
idxExpr = Int -> CoreExpr
mkIntExpr Int
i
raw1 :: CoreExpr
raw1 = CoreExpr -> [CoreExpr] -> CoreExpr
mkCoreApps (Var -> CoreExpr
forall b. Var -> Expr b
Var (PluginState -> Var
psFieldAt PluginState
state)) ([CoreExpr]
fieldAtTypeArgs [CoreExpr] -> [CoreExpr] -> [CoreExpr]
forall a. [a] -> [a] -> [a]
++ [CoreExpr
idxExpr, CoreExpr
rep1])
raw2 :: CoreExpr
raw2 = CoreExpr -> [CoreExpr] -> CoreExpr
mkCoreApps (Var -> CoreExpr
forall b. Var -> Expr b
Var (PluginState -> Var
psFieldAt PluginState
state)) ([CoreExpr]
fieldAtTypeArgs [CoreExpr] -> [CoreExpr] -> [CoreExpr]
forall a. [a] -> [a] -> [a]
++ [CoreExpr
idxExpr, CoreExpr
rep2])
fFieldTy :: Type
fFieldTy = Type -> Type -> Type
mkAppTy Type
fTy Type
fieldTy
val1 :: CoreExpr
val1 = CoreExpr -> [CoreExpr] -> CoreExpr
mkCoreApps (Var -> CoreExpr
forall b. Var -> Expr b
Var (PluginState -> Var
psNoInlineCo PluginState
state)) [Type -> CoreExpr
forall b. Type -> Expr b
Type Type
fFieldTy, Type -> CoreExpr
forall b. Type -> Expr b
Type Type
fieldTy, CoreExpr
raw1]
val2 :: CoreExpr
val2 = CoreExpr -> [CoreExpr] -> CoreExpr
mkCoreApps (Var -> CoreExpr
forall b. Var -> Expr b
Var (PluginState -> Var
psNoInlineCo PluginState
state)) [Type -> CoreExpr
forall b. Type -> Expr b
Type Type
fFieldTy, Type -> CoreExpr
forall b. Type -> Expr b
Type Type
fieldTy, CoreExpr
raw2]
eqDict :: CoreExpr
eqDict = HasDebugCallStack => CtEvidence -> CoreExpr
CtEvidence -> CoreExpr
ctEvExpr CtEvidence
ev
in CoreExpr -> [CoreExpr] -> CoreExpr
mkCoreApps (Var -> CoreExpr
forall b. Var -> Expr b
Var (PluginState -> Var
psEqClass PluginState
state)) [Type -> CoreExpr
forall b. Type -> Expr b
Type Type
fieldTy, CoreExpr
eqDict, CoreExpr
val1, CoreExpr
val2]
fieldComps = ((Int, Type, CtEvidence) -> CoreExpr)
-> [(Int, Type, CtEvidence)] -> [CoreExpr]
forall a b. (a -> b) -> [a] -> [b]
map (Int, Type, CtEvidence) -> CoreExpr
compareField [(Int, Type, CtEvidence)]
wanteds
andFn CoreExpr
e1 CoreExpr
e2 = CoreExpr -> [CoreExpr] -> CoreExpr
mkCoreApps (Var -> CoreExpr
forall b. Var -> Expr b
Var (PluginState -> Var
psAnd PluginState
state)) [CoreExpr
e1, CoreExpr
e2]
bodyExpr = (CoreExpr -> CoreExpr -> CoreExpr)
-> CoreExpr -> [CoreExpr] -> CoreExpr
forall b a. (b -> a -> b) -> b -> [a] -> b
forall (t :: * -> *) b a.
Foldable t =>
(b -> a -> b) -> b -> t a -> b
foldl CoreExpr -> CoreExpr -> CoreExpr
andFn (CoreExpr -> CoreExpr -> CoreExpr
andFn CoreExpr
eqTag CoreExpr
eqArity) [CoreExpr]
fieldComps
repEqExpr = [Var] -> CoreExpr -> CoreExpr
mkCoreLams ([Var]
tyVars [Var] -> [Var] -> [Var]
forall a. [a] -> [a] -> [a]
++ [Var
r1Var, Var
r2Var]) CoreExpr
bodyExpr
dictExpr = DataCon -> [Type] -> [CoreExpr] -> CoreExpr
evDataConApp (Class -> DataCon
classDataCon Class
cls) [Type]
tys [CoreExpr
scEvidence, CoreExpr
repEqExpr]
newWanteds = [CtEvidence -> Ct
mkNonCanonical CtEvidence
ev | (Int
_, Type
_, CtEvidence
ev) <- [(Int, Type, CtEvidence)]
wanteds]
pure $ Left ((EvExpr dictExpr, ct), newWanteds)
solveRowShow
:: PluginState
-> Ct
-> Class
-> [Type]
-> TcPluginM 'Solve (Either ((EvTerm, Ct), [Ct]) ())
solveRowShow :: PluginState
-> Ct
-> Class
-> [Type]
-> TcPluginM 'Solve (Either ((EvTerm, Ct), [Ct]) ())
solveRowShow PluginState
state Ct
ct Class
cls [Type]
tys = do
let rowTy :: Type
rowTy = [Type] -> Type
forall a. HasCallStack => [a] -> a
last [Type]
tys
rTy :: Type
rTy = [Type]
tys [Type] -> Int -> Type
forall a. HasCallStack => [a] -> Int -> a
!! ([Type] -> Int
forall a. [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [Type]
tys Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
2)
fields :: [(Int, FastString, Type)]
fields = Type -> [(Int, FastString, Type)]
walkRowWithTypes Type
rowTy
loc :: CtLoc
loc = Ct -> CtLoc
ctLoc Ct
ct
scEvidence :: CoreExpr
scEvidence = DataCon -> [Type] -> [CoreExpr] -> CoreExpr
evDataConApp (Class -> DataCon
classDataCon (PluginState -> Class
psRowFlavourCls PluginState
state)) [Type
rTy] []
repShowsPrecId :: Var
repShowsPrecId = case Class -> [Var]
classMethods Class
cls of
(Var
m : [Var]
_) -> Var
m
[] -> String -> Var
forall a. HasCallStack => String -> a
error String
"Polytropos.Plugin: RowShow class has no methods"
methodFullTy :: Type
methodFullTy = HasDebugCallStack => Type -> [Type] -> Type
Type -> [Type] -> Type
piResultTys (Var -> Type
varType Var
repShowsPrecId) [Type]
tys
(Type
_, Type
_, Type
methodInDictTy) = Type -> (Type, Type, Type)
splitFunTy Type
methodFullTy
([Var]
tyVars, Type
tauTy) = Type -> ([Var], Type)
splitForAllTyCoVars Type
methodInDictTy
([Scaled Type]
argTys, Type
_) = Type -> ([Scaled Type], Type)
splitFunTys Type
tauTy
scaledPrecTy :: Scaled Type
scaledPrecTy = [Scaled Type]
argTys [Scaled Type] -> Int -> Scaled Type
forall a. HasCallStack => [a] -> Int -> a
!! Int
0
scaledRTy :: Scaled Type
scaledRTy = [Scaled Type]
argTys [Scaled Type] -> Int -> Scaled Type
forall a. HasCallStack => [a] -> Int -> a
!! Int
1
precName <- TcM Name -> TcPluginM 'Solve Name
forall a. TcM a -> TcPluginM 'Solve a
forall (m :: * -> *) a. MonadTcPlugin m => TcM a -> m a
unsafeLiftTcM (TcM Name -> TcPluginM 'Solve Name)
-> TcM Name -> TcPluginM 'Solve Name
forall a b. (a -> b) -> a -> b
$ OccName -> TcM Name
newName (String -> OccName
mkVarOcc String
"p")
rName <- unsafeLiftTcM $ newName (mkVarOcc "r")
let precVar = HasDebugCallStack => Name -> Type -> Type -> Var
Name -> Type -> Type -> Var
mkLocalId Name
precName (Scaled Type -> Type
forall a. Scaled a -> Type
scaledMult Scaled Type
scaledPrecTy) (Scaled Type -> Type
forall a. Scaled a -> a
scaledThing Scaled Type
scaledPrecTy)
rVar = HasDebugCallStack => Name -> Type -> Type -> Var
Name -> Type -> Type -> Var
mkLocalId Name
rName (Scaled Type -> Type
forall a. Scaled a -> Type
scaledMult Scaled Type
scaledRTy) (Scaled Type -> Type
forall a. Scaled a -> a
scaledThing Scaled Type
scaledRTy)
kATy = Var -> Type
mkTyVarTy ([Var]
tyVars [Var] -> Int -> Var
forall a. HasCallStack => [a] -> Int -> a
!! Int
0)
fTy = Var -> Type
mkTyVarTy ([Var]
tyVars [Var] -> Int -> Var
forall a. HasCallStack => [a] -> Int -> a
!! Int
1)
aTy = Var -> Type
mkTyVarTy ([Var]
tyVars [Var] -> Int -> Var
forall a. HasCallStack => [a] -> Int -> a
!! Int
2)
kRowTy = HasDebugCallStack => Type -> Type
Type -> Type
typeKind Type
rowTy
unRowRepTypeArgs = [Type -> CoreExpr
forall b. Type -> Expr b
Type Type
kRowTy, Type -> CoreExpr
forall b. Type -> Expr b
Type Type
kATy, Type -> CoreExpr
forall b. Type -> Expr b
Type Type
fTy, Type -> CoreExpr
forall b. Type -> Expr b
Type Type
rTy, Type -> CoreExpr
forall b. Type -> Expr b
Type Type
rowTy, Type -> CoreExpr
forall b. Type -> Expr b
Type Type
aTy]
rep = CoreExpr -> [CoreExpr] -> CoreExpr
mkCoreApps (Var -> CoreExpr
forall b. Var -> Expr b
Var (PluginState -> Var
psUnRowRep PluginState
state)) ([CoreExpr]
unRowRepTypeArgs [CoreExpr] -> [CoreExpr] -> [CoreExpr]
forall a. [a] -> [a] -> [a]
++ [Var -> CoreExpr
forall b. Var -> Expr b
Var Var
rVar])
rowName = case HasDebugCallStack => Type -> Maybe (TyCon, [Type])
Type -> Maybe (TyCon, [Type])
splitTyConApp_maybe Type
rowTy of
Just (TyCon
tc, [Type]
_)
| let name :: String
name = OccName -> String
occNameString (TyCon -> OccName
forall a. NamedThing a => a -> OccName
getOccName TyCon
tc)
, String
name String -> String -> Bool
forall a. Eq a => a -> a -> Bool
/= String
":" Bool -> Bool -> Bool
&& String
name String -> String -> Bool
forall a. Eq a => a -> a -> Bool
/= String
"[]" Bool -> Bool -> Bool
&& String
name String -> String -> Bool
forall a. Eq a => a -> a -> Bool
/= String
"''[]"
-> String
name
Maybe (TyCon, [Type])
_ -> String
"R" String -> String -> String
forall a. [a] -> [a] -> [a]
++ Int -> String
forall a. Show a => a -> String
show ([(Int, FastString, Type)] -> Int
forall a. [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [(Int, FastString, Type)]
fields)
prefixExpr <- unsafeLiftTcM $ mkStringExpr (rowName ++ " ")
let prefixShowS = CoreExpr -> [CoreExpr] -> CoreExpr
mkCoreApps (Var -> CoreExpr
forall b. Var -> Expr b
Var (PluginState -> Var
psShowString PluginState
state)) [CoreExpr
prefixExpr]
spaceShowS = CoreExpr -> [CoreExpr] -> CoreExpr
mkCoreApps (Var -> CoreExpr
forall b. Var -> Expr b
Var (PluginState -> Var
psShowChar PluginState
state)) [Char -> CoreExpr
mkCharExpr Char
' ']
wanteds <- forM fields $ \(Int
i, FastString
_nameFS, Type
fieldTy) -> do
ev <- CtLoc -> Type -> TcPluginM 'Solve CtEvidence
forall (m :: * -> *).
MonadTcPluginWork m =>
CtLoc -> Type -> m CtEvidence
newWanted CtLoc
loc (Type -> Type -> Type
mkAppTy (TyCon -> Type
mkTyConTy (Class -> TyCon
classTyCon (PluginState -> Class
psShowCls PluginState
state))) Type
fieldTy)
pure (i, fieldTy, ev)
let showField (Int
i, Type
fieldTy, CtEvidence
ev) =
let fieldAtTypeArgs :: [CoreExpr]
fieldAtTypeArgs = [Type -> CoreExpr
forall b. Type -> Expr b
Type Type
kATy, Type -> CoreExpr
forall b. Type -> Expr b
Type Type
fTy, Type -> CoreExpr
forall b. Type -> Expr b
Type Type
aTy, Type -> CoreExpr
forall b. Type -> Expr b
Type Type
fieldTy]
idxExpr :: CoreExpr
idxExpr = Int -> CoreExpr
mkIntExpr Int
i
raw :: CoreExpr
raw = CoreExpr -> [CoreExpr] -> CoreExpr
mkCoreApps (Var -> CoreExpr
forall b. Var -> Expr b
Var (PluginState -> Var
psFieldAt PluginState
state)) ([CoreExpr]
fieldAtTypeArgs [CoreExpr] -> [CoreExpr] -> [CoreExpr]
forall a. [a] -> [a] -> [a]
++ [CoreExpr
idxExpr, CoreExpr
rep])
fFieldTy :: Type
fFieldTy = Type -> Type -> Type
mkAppTy Type
fTy Type
fieldTy
val :: CoreExpr
val = CoreExpr -> [CoreExpr] -> CoreExpr
mkCoreApps (Var -> CoreExpr
forall b. Var -> Expr b
Var (PluginState -> Var
psNoInlineCo PluginState
state)) [Type -> CoreExpr
forall b. Type -> Expr b
Type Type
fFieldTy, Type -> CoreExpr
forall b. Type -> Expr b
Type Type
fieldTy, CoreExpr
raw]
showDict :: CoreExpr
showDict = HasDebugCallStack => CtEvidence -> CoreExpr
CtEvidence -> CoreExpr
ctEvExpr CtEvidence
ev
zeroPrec :: CoreExpr
zeroPrec = Int -> CoreExpr
mkIntExpr Int
0
in CoreExpr -> [CoreExpr] -> CoreExpr
mkCoreApps (Var -> CoreExpr
forall b. Var -> Expr b
Var (PluginState -> Var
psShowsPrecMeth PluginState
state)) [Type -> CoreExpr
forall b. Type -> Expr b
Type Type
fieldTy, CoreExpr
showDict, CoreExpr
zeroPrec, CoreExpr
val]
fieldShows = ((Int, Type, CtEvidence) -> CoreExpr)
-> [(Int, Type, CtEvidence)] -> [CoreExpr]
forall a b. (a -> b) -> [a] -> [b]
map (Int, Type, CtEvidence) -> CoreExpr
showField [(Int, Type, CtEvidence)]
wanteds
showParts = case [CoreExpr]
fieldShows of
[] -> [CoreExpr
prefixShowS]
(CoreExpr
f0 : [CoreExpr]
fs) -> CoreExpr
prefixShowS CoreExpr -> [CoreExpr] -> [CoreExpr]
forall a. a -> [a] -> [a]
: CoreExpr
f0 CoreExpr -> [CoreExpr] -> [CoreExpr]
forall a. a -> [a] -> [a]
: (CoreExpr -> [CoreExpr]) -> [CoreExpr] -> [CoreExpr]
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap (\CoreExpr
f -> [CoreExpr
spaceShowS, CoreExpr
f]) [CoreExpr]
fs
compFn CoreExpr
f CoreExpr
g = CoreExpr -> [CoreExpr] -> CoreExpr
mkCoreApps (Var -> CoreExpr
forall b. Var -> Expr b
Var (PluginState -> Var
psComp PluginState
state)) [Type -> CoreExpr
forall b. Type -> Expr b
Type Type
stringTy, Type -> CoreExpr
forall b. Type -> Expr b
Type Type
stringTy, Type -> CoreExpr
forall b. Type -> Expr b
Type Type
stringTy, CoreExpr
f, CoreExpr
g]
bodyExpr = (CoreExpr -> CoreExpr -> CoreExpr) -> [CoreExpr] -> CoreExpr
forall a. (a -> a -> a) -> [a] -> a
forall (t :: * -> *) a. Foldable t => (a -> a -> a) -> t a -> a
foldr1 CoreExpr -> CoreExpr -> CoreExpr
compFn [CoreExpr]
showParts
repShowsPrecExpr = [Var] -> CoreExpr -> CoreExpr
mkCoreLams ([Var]
tyVars [Var] -> [Var] -> [Var]
forall a. [a] -> [a] -> [a]
++ [Var
precVar, Var
rVar]) CoreExpr
bodyExpr
dictExpr = DataCon -> [Type] -> [CoreExpr] -> CoreExpr
evDataConApp (Class -> DataCon
classDataCon Class
cls) [Type]
tys [CoreExpr
scEvidence, CoreExpr
repShowsPrecExpr]
newWanteds = [CtEvidence -> Ct
mkNonCanonical CtEvidence
ev | (Int
_, Type
_, CtEvidence
ev) <- [(Int, Type, CtEvidence)]
wanteds]
pure $ Left ((EvExpr dictExpr, ct), newWanteds)
solveRowEqSum
:: PluginState
-> Ct
-> Class
-> [Type]
-> TcPluginM 'Solve (Either ((EvTerm, Ct), [Ct]) ())
solveRowEqSum :: PluginState
-> Ct
-> Class
-> [Type]
-> TcPluginM 'Solve (Either ((EvTerm, Ct), [Ct]) ())
solveRowEqSum PluginState
state Ct
ct Class
cls [Type]
tys = do
let rowTy :: Type
rowTy = [Type] -> Type
forall a. HasCallStack => [a] -> a
last [Type]
tys
rTy :: Type
rTy = [Type]
tys [Type] -> Int -> Type
forall a. HasCallStack => [a] -> Int -> a
!! ([Type] -> Int
forall a. [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [Type]
tys Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
2)
constructors :: [(Int, FastString, Type)]
constructors = Type -> [(Int, FastString, Type)]
walkSumRowWithTypes Type
rowTy
loc :: CtLoc
loc = Ct -> CtLoc
ctLoc Ct
ct
scEvidence :: CoreExpr
scEvidence = DataCon -> [Type] -> [CoreExpr] -> CoreExpr
evDataConApp (Class -> DataCon
classDataCon (PluginState -> Class
psRowFlavourCls PluginState
state)) [Type
rTy] []
repEqSumId :: Var
repEqSumId = case Class -> [Var]
classMethods Class
cls of
(Var
m : [Var]
_) -> Var
m
[] -> String -> Var
forall a. HasCallStack => String -> a
error String
"Polytropos.Plugin: RowEqSum class has no methods"
methodFullTy :: Type
methodFullTy = HasDebugCallStack => Type -> [Type] -> Type
Type -> [Type] -> Type
piResultTys (Var -> Type
varType Var
repEqSumId) [Type]
tys
(Type
_, Type
_, Type
methodInDictTy) = Type -> (Type, Type, Type)
splitFunTy Type
methodFullTy
([Var]
tyVars, Type
tauTy) = Type -> ([Var], Type)
splitForAllTyCoVars Type
methodInDictTy
([Scaled Type]
argTys, Type
_) = Type -> ([Scaled Type], Type)
splitFunTys Type
tauTy
scaledR1Ty :: Scaled Type
scaledR1Ty = [Scaled Type]
argTys [Scaled Type] -> Int -> Scaled Type
forall a. HasCallStack => [a] -> Int -> a
!! Int
0
scaledR2Ty :: Scaled Type
scaledR2Ty = [Scaled Type]
argTys [Scaled Type] -> Int -> Scaled Type
forall a. HasCallStack => [a] -> Int -> a
!! Int
1
r1Name <- TcM Name -> TcPluginM 'Solve Name
forall a. TcM a -> TcPluginM 'Solve a
forall (m :: * -> *) a. MonadTcPlugin m => TcM a -> m a
unsafeLiftTcM (TcM Name -> TcPluginM 'Solve Name)
-> TcM Name -> TcPluginM 'Solve Name
forall a b. (a -> b) -> a -> b
$ OccName -> TcM Name
newName (String -> OccName
mkVarOcc String
"r1")
r2Name <- unsafeLiftTcM $ newName (mkVarOcc "r2")
let r1Var = HasDebugCallStack => Name -> Type -> Type -> Var
Name -> Type -> Type -> Var
mkLocalId Name
r1Name (Scaled Type -> Type
forall a. Scaled a -> Type
scaledMult Scaled Type
scaledR1Ty) (Scaled Type -> Type
forall a. Scaled a -> a
scaledThing Scaled Type
scaledR1Ty)
r2Var = HasDebugCallStack => Name -> Type -> Type -> Var
Name -> Type -> Type -> Var
mkLocalId Name
r2Name (Scaled Type -> Type
forall a. Scaled a -> Type
scaledMult Scaled Type
scaledR2Ty) (Scaled Type -> Type
forall a. Scaled a -> a
scaledThing Scaled Type
scaledR2Ty)
kATy = Var -> Type
mkTyVarTy ([Var]
tyVars [Var] -> Int -> Var
forall a. HasCallStack => [a] -> Int -> a
!! Int
0)
fTy = Var -> Type
mkTyVarTy ([Var]
tyVars [Var] -> Int -> Var
forall a. HasCallStack => [a] -> Int -> a
!! Int
1)
aTy = Var -> Type
mkTyVarTy ([Var]
tyVars [Var] -> Int -> Var
forall a. HasCallStack => [a] -> Int -> a
!! Int
2)
kRowTy = HasDebugCallStack => Type -> Type
Type -> Type
typeKind Type
rowTy
unRowRepTypeArgs = [Type -> CoreExpr
forall b. Type -> Expr b
Type Type
kRowTy, Type -> CoreExpr
forall b. Type -> Expr b
Type Type
kATy, Type -> CoreExpr
forall b. Type -> Expr b
Type Type
fTy, Type -> CoreExpr
forall b. Type -> Expr b
Type Type
rTy, Type -> CoreExpr
forall b. Type -> Expr b
Type Type
rowTy, Type -> CoreExpr
forall b. Type -> Expr b
Type Type
aTy]
rep1 = CoreExpr -> [CoreExpr] -> CoreExpr
mkCoreApps (Var -> CoreExpr
forall b. Var -> Expr b
Var (PluginState -> Var
psUnRowRep PluginState
state)) ([CoreExpr]
unRowRepTypeArgs [CoreExpr] -> [CoreExpr] -> [CoreExpr]
forall a. [a] -> [a] -> [a]
++ [Var -> CoreExpr
forall b. Var -> Expr b
Var Var
r1Var])
rep2 = CoreExpr -> [CoreExpr] -> CoreExpr
mkCoreApps (Var -> CoreExpr
forall b. Var -> Expr b
Var (PluginState -> Var
psUnRowRep PluginState
state)) ([CoreExpr]
unRowRepTypeArgs [CoreExpr] -> [CoreExpr] -> [CoreExpr]
forall a. [a] -> [a] -> [a]
++ [Var -> CoreExpr
forall b. Var -> Expr b
Var Var
r2Var])
repTypeArgs = [Type -> CoreExpr
forall b. Type -> Expr b
Type Type
kATy, Type -> CoreExpr
forall b. Type -> Expr b
Type Type
fTy, Type -> CoreExpr
forall b. Type -> Expr b
Type Type
aTy]
tag1 = CoreExpr -> [CoreExpr] -> CoreExpr
mkCoreApps (Var -> CoreExpr
forall b. Var -> Expr b
Var (PluginState -> Var
psRepTag PluginState
state)) ([CoreExpr]
repTypeArgs [CoreExpr] -> [CoreExpr] -> [CoreExpr]
forall a. [a] -> [a] -> [a]
++ [CoreExpr
rep1])
tag2 = CoreExpr -> [CoreExpr] -> CoreExpr
mkCoreApps (Var -> CoreExpr
forall b. Var -> Expr b
Var (PluginState -> Var
psRepTag PluginState
state)) ([CoreExpr]
repTypeArgs [CoreExpr] -> [CoreExpr] -> [CoreExpr]
forall a. [a] -> [a] -> [a]
++ [CoreExpr
rep2])
eqTag = CoreExpr -> [CoreExpr] -> CoreExpr
mkCoreApps (Var -> CoreExpr
forall b. Var -> Expr b
Var (PluginState -> Var
psEqClass PluginState
state)) [Type -> CoreExpr
forall b. Type -> Expr b
Type (TyCon -> Type
mkTyConTy TyCon
wordTyCon), Var -> CoreExpr
forall b. Var -> Expr b
Var (PluginState -> Var
psFEqWord PluginState
state), CoreExpr
tag1, CoreExpr
tag2]
falseExpr = DataCon -> [CoreExpr] -> CoreExpr
mkCoreConApps DataCon
falseDataCon []
trueExpr = DataCon -> [CoreExpr] -> CoreExpr
mkCoreConApps DataCon
trueDataCon []
andFn CoreExpr
e1 CoreExpr
e2 = CoreExpr -> [CoreExpr] -> CoreExpr
mkCoreApps (Var -> CoreExpr
forall b. Var -> Expr b
Var (PluginState -> Var
psAnd PluginState
state)) [CoreExpr
e1, CoreExpr
e2]
ctorWanteds <- forM constructors $ \(Int
i, FastString
conName, Type
conRowTy) -> do
let fields :: [(Int, FastString, Type)]
fields = Type -> [(Int, FastString, Type)]
walkRowWithTypes Type
conRowTy
fWanteds <- [(Int, FastString, Type)]
-> ((Int, FastString, Type)
-> TcPluginM 'Solve (Int, Type, CtEvidence))
-> TcPluginM 'Solve [(Int, Type, CtEvidence)]
forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
t a -> (a -> m b) -> m (t b)
forM [(Int, FastString, Type)]
fields (((Int, FastString, Type)
-> TcPluginM 'Solve (Int, Type, CtEvidence))
-> TcPluginM 'Solve [(Int, Type, CtEvidence)])
-> ((Int, FastString, Type)
-> TcPluginM 'Solve (Int, Type, CtEvidence))
-> TcPluginM 'Solve [(Int, Type, CtEvidence)]
forall a b. (a -> b) -> a -> b
$ \(Int
fi, FastString
_nameFS, Type
fieldTy) -> do
ev <- CtLoc -> Type -> TcPluginM 'Solve CtEvidence
forall (m :: * -> *).
MonadTcPluginWork m =>
CtLoc -> Type -> m CtEvidence
newWanted CtLoc
loc (Type -> Type -> Type
mkAppTy (TyCon -> Type
mkTyConTy (Class -> TyCon
classTyCon (PluginState -> Class
psEqCls PluginState
state))) Type
fieldTy)
pure (fi, fieldTy, ev)
pure (i, conName, fWanteds)
let compareConFields [(Int, Type, CtEvidence)]
fWanteds =
let fieldComps :: [CoreExpr]
fieldComps = [ Int -> Type -> CtEvidence -> CoreExpr
compareField Int
fi Type
fieldTy CtEvidence
ev | (Int
fi, Type
fieldTy, CtEvidence
ev) <- [(Int, Type, CtEvidence)]
fWanteds ]
in (CoreExpr -> CoreExpr -> CoreExpr)
-> CoreExpr -> [CoreExpr] -> CoreExpr
forall b a. (b -> a -> b) -> b -> [a] -> b
forall (t :: * -> *) b a.
Foldable t =>
(b -> a -> b) -> b -> t a -> b
foldl CoreExpr -> CoreExpr -> CoreExpr
andFn CoreExpr
trueExpr [CoreExpr]
fieldComps
compareField Int
fi Type
fieldTy CtEvidence
ev =
let fieldAtTypeArgs :: [CoreExpr]
fieldAtTypeArgs = [Type -> CoreExpr
forall b. Type -> Expr b
Type Type
kATy, Type -> CoreExpr
forall b. Type -> Expr b
Type Type
fTy, Type -> CoreExpr
forall b. Type -> Expr b
Type Type
aTy, Type -> CoreExpr
forall b. Type -> Expr b
Type Type
fieldTy]
idxExpr :: CoreExpr
idxExpr = Int -> CoreExpr
mkIntExpr Int
fi
raw1 :: CoreExpr
raw1 = CoreExpr -> [CoreExpr] -> CoreExpr
mkCoreApps (Var -> CoreExpr
forall b. Var -> Expr b
Var (PluginState -> Var
psFieldAt PluginState
state)) ([CoreExpr]
fieldAtTypeArgs [CoreExpr] -> [CoreExpr] -> [CoreExpr]
forall a. [a] -> [a] -> [a]
++ [CoreExpr
idxExpr, CoreExpr
rep1])
raw2 :: CoreExpr
raw2 = CoreExpr -> [CoreExpr] -> CoreExpr
mkCoreApps (Var -> CoreExpr
forall b. Var -> Expr b
Var (PluginState -> Var
psFieldAt PluginState
state)) ([CoreExpr]
fieldAtTypeArgs [CoreExpr] -> [CoreExpr] -> [CoreExpr]
forall a. [a] -> [a] -> [a]
++ [CoreExpr
idxExpr, CoreExpr
rep2])
fFieldTy :: Type
fFieldTy = Type -> Type -> Type
mkAppTy Type
fTy Type
fieldTy
val1 :: CoreExpr
val1 = CoreExpr -> [CoreExpr] -> CoreExpr
mkCoreApps (Var -> CoreExpr
forall b. Var -> Expr b
Var (PluginState -> Var
psNoInlineCo PluginState
state)) [Type -> CoreExpr
forall b. Type -> Expr b
Type Type
fFieldTy, Type -> CoreExpr
forall b. Type -> Expr b
Type Type
fieldTy, CoreExpr
raw1]
val2 :: CoreExpr
val2 = CoreExpr -> [CoreExpr] -> CoreExpr
mkCoreApps (Var -> CoreExpr
forall b. Var -> Expr b
Var (PluginState -> Var
psNoInlineCo PluginState
state)) [Type -> CoreExpr
forall b. Type -> Expr b
Type Type
fFieldTy, Type -> CoreExpr
forall b. Type -> Expr b
Type Type
fieldTy, CoreExpr
raw2]
eqDict :: CoreExpr
eqDict = HasDebugCallStack => CtEvidence -> CoreExpr
CtEvidence -> CoreExpr
ctEvExpr CtEvidence
ev
in CoreExpr -> [CoreExpr] -> CoreExpr
mkCoreApps (Var -> CoreExpr
forall b. Var -> Expr b
Var (PluginState -> Var
psEqClass PluginState
state)) [Type -> CoreExpr
forall b. Type -> Expr b
Type Type
fieldTy, CoreExpr
eqDict, CoreExpr
val1, CoreExpr
val2]
buildTree CoreExpr
_ [] = CoreExpr
falseExpr
buildTree CoreExpr
tagExpr ((Int
i, FastString
_conName, [(Int, Type, CtEvidence)]
fWanteds) : [(Int, FastString, [(Int, Type, CtEvidence)])]
rest) =
let iLit :: CoreExpr
iLit = Word -> CoreExpr
mkWordExpr (Int -> Word
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
i)
cond :: CoreExpr
cond = CoreExpr -> [CoreExpr] -> CoreExpr
mkCoreApps (Var -> CoreExpr
forall b. Var -> Expr b
Var (PluginState -> Var
psEqClass PluginState
state)) [Type -> CoreExpr
forall b. Type -> Expr b
Type (TyCon -> Type
mkTyConTy TyCon
wordTyCon), Var -> CoreExpr
forall b. Var -> Expr b
Var (PluginState -> Var
psFEqWord PluginState
state), CoreExpr
tagExpr, CoreExpr
iLit]
in CoreExpr -> CoreExpr -> CoreExpr -> CoreExpr
mkIfThenElse CoreExpr
cond ([(Int, Type, CtEvidence)] -> CoreExpr
compareConFields [(Int, Type, CtEvidence)]
fWanteds) (CoreExpr
-> [(Int, FastString, [(Int, Type, CtEvidence)])] -> CoreExpr
buildTree CoreExpr
tagExpr [(Int, FastString, [(Int, Type, CtEvidence)])]
rest)
bodyExpr = CoreExpr -> CoreExpr -> CoreExpr -> CoreExpr
mkIfThenElse CoreExpr
eqTag (CoreExpr
-> [(Int, FastString, [(Int, Type, CtEvidence)])] -> CoreExpr
buildTree CoreExpr
tag1 [(Int, FastString, [(Int, Type, CtEvidence)])]
ctorWanteds) CoreExpr
falseExpr
repEqSumExpr = [Var] -> CoreExpr -> CoreExpr
mkCoreLams ([Var]
tyVars [Var] -> [Var] -> [Var]
forall a. [a] -> [a] -> [a]
++ [Var
r1Var, Var
r2Var]) CoreExpr
bodyExpr
dictExpr = DataCon -> [Type] -> [CoreExpr] -> CoreExpr
evDataConApp (Class -> DataCon
classDataCon Class
cls) [Type]
tys [CoreExpr
scEvidence, CoreExpr
repEqSumExpr]
allNewWanteds = [ CtEvidence -> Ct
mkNonCanonical CtEvidence
ev | (Int
_, FastString
_, [(Int, Type, CtEvidence)]
fWanteds) <- [(Int, FastString, [(Int, Type, CtEvidence)])]
ctorWanteds, (Int
_, Type
_, CtEvidence
ev) <- [(Int, Type, CtEvidence)]
fWanteds ]
pure $ Left ((EvExpr dictExpr, ct), allNewWanteds)
solveRowShowSum
:: PluginState
-> Ct
-> Class
-> [Type]
-> TcPluginM 'Solve (Either ((EvTerm, Ct), [Ct]) ())
solveRowShowSum :: PluginState
-> Ct
-> Class
-> [Type]
-> TcPluginM 'Solve (Either ((EvTerm, Ct), [Ct]) ())
solveRowShowSum PluginState
state Ct
ct Class
cls [Type]
tys = do
let rowTy :: Type
rowTy = [Type] -> Type
forall a. HasCallStack => [a] -> a
last [Type]
tys
rTy :: Type
rTy = [Type]
tys [Type] -> Int -> Type
forall a. HasCallStack => [a] -> Int -> a
!! ([Type] -> Int
forall a. [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [Type]
tys Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
2)
constructors :: [(Int, FastString, Type)]
constructors = Type -> [(Int, FastString, Type)]
walkSumRowWithTypes Type
rowTy
loc :: CtLoc
loc = Ct -> CtLoc
ctLoc Ct
ct
scEvidence :: CoreExpr
scEvidence = DataCon -> [Type] -> [CoreExpr] -> CoreExpr
evDataConApp (Class -> DataCon
classDataCon (PluginState -> Class
psRowFlavourCls PluginState
state)) [Type
rTy] []
repShowsPrecSumId :: Var
repShowsPrecSumId = case Class -> [Var]
classMethods Class
cls of
(Var
m : [Var]
_) -> Var
m
[] -> String -> Var
forall a. HasCallStack => String -> a
error String
"Polytropos.Plugin: RowShowSum class has no methods"
methodFullTy :: Type
methodFullTy = HasDebugCallStack => Type -> [Type] -> Type
Type -> [Type] -> Type
piResultTys (Var -> Type
varType Var
repShowsPrecSumId) [Type]
tys
(Type
_, Type
_, Type
methodInDictTy) = Type -> (Type, Type, Type)
splitFunTy Type
methodFullTy
([Var]
tyVars, Type
tauTy) = Type -> ([Var], Type)
splitForAllTyCoVars Type
methodInDictTy
([Scaled Type]
argTys, Type
_) = Type -> ([Scaled Type], Type)
splitFunTys Type
tauTy
scaledPrecTy :: Scaled Type
scaledPrecTy = [Scaled Type]
argTys [Scaled Type] -> Int -> Scaled Type
forall a. HasCallStack => [a] -> Int -> a
!! Int
0
scaledRTy :: Scaled Type
scaledRTy = [Scaled Type]
argTys [Scaled Type] -> Int -> Scaled Type
forall a. HasCallStack => [a] -> Int -> a
!! Int
1
precName <- TcM Name -> TcPluginM 'Solve Name
forall a. TcM a -> TcPluginM 'Solve a
forall (m :: * -> *) a. MonadTcPlugin m => TcM a -> m a
unsafeLiftTcM (TcM Name -> TcPluginM 'Solve Name)
-> TcM Name -> TcPluginM 'Solve Name
forall a b. (a -> b) -> a -> b
$ OccName -> TcM Name
newName (String -> OccName
mkVarOcc String
"p")
rName <- unsafeLiftTcM $ newName (mkVarOcc "r")
let precVar = HasDebugCallStack => Name -> Type -> Type -> Var
Name -> Type -> Type -> Var
mkLocalId Name
precName (Scaled Type -> Type
forall a. Scaled a -> Type
scaledMult Scaled Type
scaledPrecTy) (Scaled Type -> Type
forall a. Scaled a -> a
scaledThing Scaled Type
scaledPrecTy)
rVar = HasDebugCallStack => Name -> Type -> Type -> Var
Name -> Type -> Type -> Var
mkLocalId Name
rName (Scaled Type -> Type
forall a. Scaled a -> Type
scaledMult Scaled Type
scaledRTy) (Scaled Type -> Type
forall a. Scaled a -> a
scaledThing Scaled Type
scaledRTy)
kATy = Var -> Type
mkTyVarTy ([Var]
tyVars [Var] -> Int -> Var
forall a. HasCallStack => [a] -> Int -> a
!! Int
0)
fTy = Var -> Type
mkTyVarTy ([Var]
tyVars [Var] -> Int -> Var
forall a. HasCallStack => [a] -> Int -> a
!! Int
1)
aTy = Var -> Type
mkTyVarTy ([Var]
tyVars [Var] -> Int -> Var
forall a. HasCallStack => [a] -> Int -> a
!! Int
2)
kRowTy = HasDebugCallStack => Type -> Type
Type -> Type
typeKind Type
rowTy
unRowRepTypeArgs = [Type -> CoreExpr
forall b. Type -> Expr b
Type Type
kRowTy, Type -> CoreExpr
forall b. Type -> Expr b
Type Type
kATy, Type -> CoreExpr
forall b. Type -> Expr b
Type Type
fTy, Type -> CoreExpr
forall b. Type -> Expr b
Type Type
rTy, Type -> CoreExpr
forall b. Type -> Expr b
Type Type
rowTy, Type -> CoreExpr
forall b. Type -> Expr b
Type Type
aTy]
rep = CoreExpr -> [CoreExpr] -> CoreExpr
mkCoreApps (Var -> CoreExpr
forall b. Var -> Expr b
Var (PluginState -> Var
psUnRowRep PluginState
state)) ([CoreExpr]
unRowRepTypeArgs [CoreExpr] -> [CoreExpr] -> [CoreExpr]
forall a. [a] -> [a] -> [a]
++ [Var -> CoreExpr
forall b. Var -> Expr b
Var Var
rVar])
repTypeArgs = [Type -> CoreExpr
forall b. Type -> Expr b
Type Type
kATy, Type -> CoreExpr
forall b. Type -> Expr b
Type Type
fTy, Type -> CoreExpr
forall b. Type -> Expr b
Type Type
aTy]
tag = CoreExpr -> [CoreExpr] -> CoreExpr
mkCoreApps (Var -> CoreExpr
forall b. Var -> Expr b
Var (PluginState -> Var
psRepTag PluginState
state)) ([CoreExpr]
repTypeArgs [CoreExpr] -> [CoreExpr] -> [CoreExpr]
forall a. [a] -> [a] -> [a]
++ [CoreExpr
rep])
spaceShowS = CoreExpr -> [CoreExpr] -> CoreExpr
mkCoreApps (Var -> CoreExpr
forall b. Var -> Expr b
Var (PluginState -> Var
psShowChar PluginState
state)) [Char -> CoreExpr
mkCharExpr Char
' ']
compFn CoreExpr
f CoreExpr
g = CoreExpr -> [CoreExpr] -> CoreExpr
mkCoreApps (Var -> CoreExpr
forall b. Var -> Expr b
Var (PluginState -> Var
psComp PluginState
state)) [Type -> CoreExpr
forall b. Type -> Expr b
Type Type
stringTy, Type -> CoreExpr
forall b. Type -> Expr b
Type Type
stringTy, Type -> CoreExpr
forall b. Type -> Expr b
Type Type
stringTy, CoreExpr
f, CoreExpr
g]
ctorWanteds <- forM constructors $ \(Int
i, FastString
conNameFS, Type
conRowTy) -> do
let fields :: [(Int, FastString, Type)]
fields = Type -> [(Int, FastString, Type)]
walkRowWithTypes Type
conRowTy
fWanteds <- [(Int, FastString, Type)]
-> ((Int, FastString, Type)
-> TcPluginM 'Solve (Int, Type, CtEvidence))
-> TcPluginM 'Solve [(Int, Type, CtEvidence)]
forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
t a -> (a -> m b) -> m (t b)
forM [(Int, FastString, Type)]
fields (((Int, FastString, Type)
-> TcPluginM 'Solve (Int, Type, CtEvidence))
-> TcPluginM 'Solve [(Int, Type, CtEvidence)])
-> ((Int, FastString, Type)
-> TcPluginM 'Solve (Int, Type, CtEvidence))
-> TcPluginM 'Solve [(Int, Type, CtEvidence)]
forall a b. (a -> b) -> a -> b
$ \(Int
fi, FastString
_nameFS, Type
fieldTy) -> do
ev <- CtLoc -> Type -> TcPluginM 'Solve CtEvidence
forall (m :: * -> *).
MonadTcPluginWork m =>
CtLoc -> Type -> m CtEvidence
newWanted CtLoc
loc (Type -> Type -> Type
mkAppTy (TyCon -> Type
mkTyConTy (Class -> TyCon
classTyCon (PluginState -> Class
psShowCls PluginState
state))) Type
fieldTy)
pure (fi, fieldTy, ev)
pure (i, conNameFS, fWanteds)
let showField Int
fi Type
fieldTy CtEvidence
ev =
let fieldAtTypeArgs :: [CoreExpr]
fieldAtTypeArgs = [Type -> CoreExpr
forall b. Type -> Expr b
Type Type
kATy, Type -> CoreExpr
forall b. Type -> Expr b
Type Type
fTy, Type -> CoreExpr
forall b. Type -> Expr b
Type Type
aTy, Type -> CoreExpr
forall b. Type -> Expr b
Type Type
fieldTy]
idxExpr :: CoreExpr
idxExpr = Int -> CoreExpr
mkIntExpr Int
fi
raw :: CoreExpr
raw = CoreExpr -> [CoreExpr] -> CoreExpr
mkCoreApps (Var -> CoreExpr
forall b. Var -> Expr b
Var (PluginState -> Var
psFieldAt PluginState
state)) ([CoreExpr]
fieldAtTypeArgs [CoreExpr] -> [CoreExpr] -> [CoreExpr]
forall a. [a] -> [a] -> [a]
++ [CoreExpr
idxExpr, CoreExpr
rep])
fFieldTy :: Type
fFieldTy = Type -> Type -> Type
mkAppTy Type
fTy Type
fieldTy
val :: CoreExpr
val = CoreExpr -> [CoreExpr] -> CoreExpr
mkCoreApps (Var -> CoreExpr
forall b. Var -> Expr b
Var (PluginState -> Var
psNoInlineCo PluginState
state)) [Type -> CoreExpr
forall b. Type -> Expr b
Type Type
fFieldTy, Type -> CoreExpr
forall b. Type -> Expr b
Type Type
fieldTy, CoreExpr
raw]
showDict :: CoreExpr
showDict = HasDebugCallStack => CtEvidence -> CoreExpr
CtEvidence -> CoreExpr
ctEvExpr CtEvidence
ev
zeroPrec :: CoreExpr
zeroPrec = Int -> CoreExpr
mkIntExpr Int
0
in CoreExpr -> [CoreExpr] -> CoreExpr
mkCoreApps (Var -> CoreExpr
forall b. Var -> Expr b
Var (PluginState -> Var
psShowsPrecMeth PluginState
state)) [Type -> CoreExpr
forall b. Type -> Expr b
Type Type
fieldTy, CoreExpr
showDict, CoreExpr
zeroPrec, CoreExpr
val]
showConFields FastString
conNameFS [(Int, Type, CtEvidence)]
fWanteds = do
let conName :: String
conName = FastString -> String
unpackFS FastString
conNameFS
prefixExpr <- TcM CoreExpr -> TcPluginM 'Solve CoreExpr
forall a. TcM a -> TcPluginM 'Solve a
forall (m :: * -> *) a. MonadTcPlugin m => TcM a -> m a
unsafeLiftTcM (TcM CoreExpr -> TcPluginM 'Solve CoreExpr)
-> TcM CoreExpr -> TcPluginM 'Solve CoreExpr
forall a b. (a -> b) -> a -> b
$ String -> TcM CoreExpr
forall (m :: * -> *). MonadThings m => String -> m CoreExpr
mkStringExpr (String
conName String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
" ")
let prefixShowS = CoreExpr -> [CoreExpr] -> CoreExpr
mkCoreApps (Var -> CoreExpr
forall b. Var -> Expr b
Var (PluginState -> Var
psShowString PluginState
state)) [CoreExpr
prefixExpr]
fieldShows = [ Int -> Type -> CtEvidence -> CoreExpr
showField Int
fi Type
fieldTy CtEvidence
ev | (Int
fi, Type
fieldTy, CtEvidence
ev) <- [(Int, Type, CtEvidence)]
fWanteds ]
showParts = case [CoreExpr]
fieldShows of
[] -> [CoreExpr
prefixShowS]
(CoreExpr
f0 : [CoreExpr]
fs) -> CoreExpr
prefixShowS CoreExpr -> [CoreExpr] -> [CoreExpr]
forall a. a -> [a] -> [a]
: CoreExpr
f0 CoreExpr -> [CoreExpr] -> [CoreExpr]
forall a. a -> [a] -> [a]
: (CoreExpr -> [CoreExpr]) -> [CoreExpr] -> [CoreExpr]
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap (\CoreExpr
f -> [CoreExpr
spaceShowS, CoreExpr
f]) [CoreExpr]
fs
pure $ foldr1 compFn showParts
let buildTree CoreExpr
_tagExpr [] = do
errorPrefix <- TcM CoreExpr -> TcPluginM 'Solve CoreExpr
forall a. TcM a -> TcPluginM 'Solve a
forall (m :: * -> *) a. MonadTcPlugin m => TcM a -> m a
unsafeLiftTcM (TcM CoreExpr -> TcPluginM 'Solve CoreExpr)
-> TcM CoreExpr -> TcPluginM 'Solve CoreExpr
forall a b. (a -> b) -> a -> b
$ String -> TcM CoreExpr
forall (m :: * -> *). MonadThings m => String -> m CoreExpr
mkStringExpr String
"??? "
pure $ mkCoreApps (Var (psShowString state)) [errorPrefix]
buildTree CoreExpr
tagExpr ((Int
i, FastString
conNameFS, [(Int, Type, CtEvidence)]
fWanteds) : [(Int, FastString, [(Int, Type, CtEvidence)])]
rest) = do
let iLit :: CoreExpr
iLit = Word -> CoreExpr
mkWordExpr (Int -> Word
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
i)
cond :: CoreExpr
cond = CoreExpr -> [CoreExpr] -> CoreExpr
mkCoreApps (Var -> CoreExpr
forall b. Var -> Expr b
Var (PluginState -> Var
psEqClass PluginState
state)) [Type -> CoreExpr
forall b. Type -> Expr b
Type (TyCon -> Type
mkTyConTy TyCon
wordTyCon), Var -> CoreExpr
forall b. Var -> Expr b
Var (PluginState -> Var
psFEqWord PluginState
state), CoreExpr
tagExpr, CoreExpr
iLit]
trueBranch <- FastString
-> [(Int, Type, CtEvidence)] -> TcPluginM 'Solve CoreExpr
showConFields FastString
conNameFS [(Int, Type, CtEvidence)]
fWanteds
falseBranch <- buildTree tagExpr rest
pure $ mkIfThenElse cond trueBranch falseBranch
bodyExpr <- buildTree tag ctorWanteds
let repShowsPrecSumExpr = [Var] -> CoreExpr -> CoreExpr
mkCoreLams ([Var]
tyVars [Var] -> [Var] -> [Var]
forall a. [a] -> [a] -> [a]
++ [Var
precVar, Var
rVar]) CoreExpr
bodyExpr
dictExpr = DataCon -> [Type] -> [CoreExpr] -> CoreExpr
evDataConApp (Class -> DataCon
classDataCon Class
cls) [Type]
tys [CoreExpr
scEvidence, CoreExpr
repShowsPrecSumExpr]
allNewWanteds = [ CtEvidence -> Ct
mkNonCanonical CtEvidence
ev | (Int
_, FastString
_, [(Int, Type, CtEvidence)]
fWanteds) <- [(Int, FastString, [(Int, Type, CtEvidence)])]
ctorWanteds, (Int
_, Type
_, CtEvidence
ev) <- [(Int, Type, CtEvidence)]
fWanteds ]
pure $ Left ((EvExpr dictExpr, ct), allNewWanteds)
solveHasField
:: PluginState
-> Ct
-> Class
-> [Type]
-> TcPluginM 'Solve (Either ((EvTerm, Ct), [Ct]) ())
solveHasField :: PluginState
-> Ct
-> Class
-> [Type]
-> TcPluginM 'Solve (Either ((EvTerm, Ct), [Ct]) ())
solveHasField PluginState
state Ct
ct Class
cls [Type]
tys = do
let len :: Int
len = [Type] -> Int
forall a. [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [Type]
tys
if Int
len Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
>= Int
3 then do
let fieldTy :: Type
fieldTy = [Type] -> Type
forall a. HasCallStack => [a] -> a
last [Type]
tys
recTy :: Type
recTy = [Type]
tys [Type] -> Int -> Type
forall a. HasCallStack => [a] -> Int -> a
!! (Int
len Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
2)
nTy :: Type
nTy = [Type]
tys [Type] -> Int -> Type
forall a. HasCallStack => [a] -> Int -> a
!! (Int
len Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
3)
loc :: CtLoc
loc = Ct -> CtLoc
ctLoc Ct
ct
case Type -> Maybe FastString
isStrLitTy (Type -> Type
unwrapSynonyms Type
nTy) of
Just FastString
fieldName -> do
case HasDebugCallStack => Type -> Maybe (TyCon, [Type])
Type -> Maybe (TyCon, [Type])
splitTyConApp_maybe (Type -> Type
unwrapSynonyms Type
recTy) of
Just (TyCon
tc, [Type]
args)
| OccName -> String
occNameString (TyCon -> OccName
forall a. NamedThing a => a -> OccName
getOccName TyCon
tc) String -> String -> Bool
forall a. Eq a => a -> a -> Bool
== String
"RowRep"
, [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
4 -> do
let aTy :: Type
aTy = [Type] -> Type
forall a. HasCallStack => [a] -> a
last [Type]
args
rowTy :: Type
rowTy = [Type]
args [Type] -> Int -> Type
forall a. HasCallStack => [a] -> Int -> a
!! ([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
2)
rTy :: Type
rTy = [Type]
args [Type] -> Int -> Type
forall a. HasCallStack => [a] -> Int -> a
!! ([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
3)
fTy :: Type
fTy = [Type]
args [Type] -> Int -> Type
forall a. HasCallStack => [a] -> Int -> a
!! ([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
4)
kATy :: Type
kATy = HasDebugCallStack => Type -> Type
Type -> Type
typeKind Type
aTy
kRowTy :: Type
kRowTy = HasDebugCallStack => Type -> Type
Type -> Type
typeKind Type
rowTy
case HasDebugCallStack => Type -> Maybe (TyCon, [Type])
Type -> Maybe (TyCon, [Type])
splitTyConApp_maybe (Type -> Type
unwrapSynonyms Type
rTy) of
Just (TyCon
tcR, []) | OccName -> String
occNameString (TyCon -> OccName
forall a. NamedThing a => a -> OccName
getOccName TyCon
tcR) String -> [String] -> Bool
forall a. Eq a => a -> [a] -> Bool
forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem` [String
"ProductRowT", String
"ProductRowHKDT"] -> do
case FastString -> Type -> Maybe (Int, Type)
findFieldType FastString
fieldName Type
rowTy of
Just (Int
i, Type
actualFieldTy) -> do
let getFieldId :: Var
getFieldId = case Class -> [Var]
classMethods Class
cls of
(Var
m : [Var]
_) -> Var
m
[] -> String -> Var
forall a. HasCallStack => String -> a
error String
"Polytropos.Plugin: HasField has no methods"
methodFullTy :: Type
methodFullTy = HasDebugCallStack => Type -> [Type] -> Type
Type -> [Type] -> Type
piResultTys (Var -> Type
varType Var
getFieldId) [Type]
tys
(Type
_, Type
_, Type
methodInDictTy) = Type -> (Type, Type, Type)
splitFunTy Type
methodFullTy
([Var]
tyVars, Type
tauTy) = Type -> ([Var], Type)
splitForAllTyCoVars Type
methodInDictTy
([Scaled Type]
argTys, Type
_) = Type -> ([Scaled Type], Type)
splitFunTys Type
tauTy
scaledRTy :: Scaled Type
scaledRTy = [Scaled Type]
argTys [Scaled Type] -> Int -> Scaled Type
forall a. HasCallStack => [a] -> Int -> a
!! Int
0
rName <- TcM Name -> TcPluginM 'Solve Name
forall a. TcM a -> TcPluginM 'Solve a
forall (m :: * -> *) a. MonadTcPlugin m => TcM a -> m a
unsafeLiftTcM (TcM Name -> TcPluginM 'Solve Name)
-> TcM Name -> TcPluginM 'Solve Name
forall a b. (a -> b) -> a -> b
$ OccName -> TcM Name
newName (String -> OccName
mkVarOcc String
"rec")
let rVar = HasDebugCallStack => Name -> Type -> Type -> Var
Name -> Type -> Type -> Var
mkLocalId Name
rName (Scaled Type -> Type
forall a. Scaled a -> Type
scaledMult Scaled Type
scaledRTy) (Scaled Type -> Type
forall a. Scaled a -> a
scaledThing Scaled Type
scaledRTy)
unRowRepTypeArgs = [Type -> CoreExpr
forall b. Type -> Expr b
Type Type
kRowTy, Type -> CoreExpr
forall b. Type -> Expr b
Type Type
kATy, Type -> CoreExpr
forall b. Type -> Expr b
Type Type
fTy, Type -> CoreExpr
forall b. Type -> Expr b
Type Type
rTy, Type -> CoreExpr
forall b. Type -> Expr b
Type Type
rowTy, Type -> CoreExpr
forall b. Type -> Expr b
Type Type
aTy]
rep = CoreExpr -> [CoreExpr] -> CoreExpr
mkCoreApps (Var -> CoreExpr
forall b. Var -> Expr b
Var (PluginState -> Var
psUnRowRep PluginState
state)) ([CoreExpr]
unRowRepTypeArgs [CoreExpr] -> [CoreExpr] -> [CoreExpr]
forall a. [a] -> [a] -> [a]
++ [Var -> CoreExpr
forall b. Var -> Expr b
Var Var
rVar])
fieldAtTypeArgs = [Type -> CoreExpr
forall b. Type -> Expr b
Type Type
kATy, Type -> CoreExpr
forall b. Type -> Expr b
Type Type
fTy, Type -> CoreExpr
forall b. Type -> Expr b
Type Type
aTy, Type -> CoreExpr
forall b. Type -> Expr b
Type Type
actualFieldTy]
idxExpr = Int -> CoreExpr
mkIntExpr Int
i
raw = CoreExpr -> [CoreExpr] -> CoreExpr
mkCoreApps (Var -> CoreExpr
forall b. Var -> Expr b
Var (PluginState -> Var
psFieldAt PluginState
state)) ([CoreExpr]
fieldAtTypeArgs [CoreExpr] -> [CoreExpr] -> [CoreExpr]
forall a. [a] -> [a] -> [a]
++ [CoreExpr
idxExpr, CoreExpr
rep])
fFieldTy = Type -> Type -> Type
mkAppTy Type
fTy Type
actualFieldTy
validTy = Type
fieldTy HasCallStack => Type -> Type -> Bool
Type -> Type -> Bool
`eqType` Type
actualFieldTy
Bool -> Bool -> Bool
|| Type
fieldTy HasCallStack => Type -> Type -> Bool
Type -> Type -> Bool
`eqType` Type
fFieldTy
val = CoreExpr -> [CoreExpr] -> CoreExpr
mkCoreApps (Var -> CoreExpr
forall b. Var -> Expr b
Var (PluginState -> Var
psNoInlineCo PluginState
state)) [Type -> CoreExpr
forall b. Type -> Expr b
Type Type
fFieldTy, Type -> CoreExpr
forall b. Type -> Expr b
Type Type
fieldTy, CoreExpr
raw]
getFieldExpr = [Var] -> CoreExpr -> CoreExpr
mkCoreLams ([Var]
tyVars [Var] -> [Var] -> [Var]
forall a. [a] -> [a] -> [a]
++ [Var
rVar]) CoreExpr
val
dictExpr = DataCon -> [Type] -> [CoreExpr] -> CoreExpr
evDataConApp (Class -> DataCon
classDataCon Class
cls) [Type]
tys [CoreExpr
getFieldExpr]
if isClosedType fieldTy && not validTy
then do
let diagLines =
[ String
"Polytropos Record Error:"
, String
" Field '" String -> String -> String
forall a. [a] -> [a] -> [a]
++ FastString -> String
unpackFS FastString
fieldName String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
"' in record has type:"
, String
" " String -> String -> String
forall a. [a] -> [a] -> [a]
++ SDoc -> String
showSDocUnsafe (Type -> SDoc
forall a. Outputable a => a -> SDoc
ppr Type
actualFieldTy)
, String
" but context expected:"
, String
" " String -> String -> String
forall a. [a] -> [a] -> [a]
++ SDoc -> String
showSDocUnsafe (Type -> SDoc
forall a. Outputable a => a -> SDoc
ppr Type
fieldTy)
]
errCt <- mkTypeErrorCt state loc diagLines
pure $ Left ((EvExpr dictExpr, ct), [errCt])
else
pure $ Left ((EvExpr dictExpr, ct), [])
Maybe (Int, Type)
Nothing -> do
case Type -> Maybe [(Int, FastString, Type)]
walkRowWithTypes_maybe Type
rowTy of
Just [(Int, FastString, Type)]
fields -> do
dummyDict <- PluginState -> Class -> [Type] -> TcPluginM 'Solve EvTerm
mkDummyHasFieldDict PluginState
state Class
cls [Type]
tys
let fNames = [ FastString -> String
unpackFS FastString
n | (Int
_, FastString
n, Type
_) <- [(Int, FastString, Type)]
fields, Bool -> Bool
not (FastString -> Bool
nullFS FastString
n) ]
diagLines =
[ String
"Polytropos Record Error:"
, String
" Field '" String -> String -> String
forall a. [a] -> [a] -> [a]
++ FastString -> String
unpackFS FastString
fieldName String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
"' does not exist in record:"
, String
" " String -> String -> String
forall a. [a] -> [a] -> [a]
++ [(Int, FastString, Type)] -> String
formatRecordRow [(Int, FastString, Type)]
fields
, String
" " String -> String -> String
forall a. [a] -> [a] -> [a]
++ String -> [String] -> String
formatSuggestion (FastString -> String
unpackFS FastString
fieldName) [String]
fNames
]
errCt <- mkTypeErrorCt state loc diagLines
pure $ Left ((dummyDict, ct), [errCt])
Maybe [(Int, FastString, Type)]
Nothing -> Either ((EvTerm, Ct), [Ct]) ()
-> TcPluginM 'Solve (Either ((EvTerm, Ct), [Ct]) ())
forall a. a -> TcPluginM 'Solve a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Either ((EvTerm, Ct), [Ct]) ()
-> TcPluginM 'Solve (Either ((EvTerm, Ct), [Ct]) ()))
-> Either ((EvTerm, Ct), [Ct]) ()
-> TcPluginM 'Solve (Either ((EvTerm, Ct), [Ct]) ())
forall a b. (a -> b) -> a -> b
$ () -> Either ((EvTerm, Ct), [Ct]) ()
forall a b. b -> Either a b
Right ()
Maybe (TyCon, [Type])
_ -> Either ((EvTerm, Ct), [Ct]) ()
-> TcPluginM 'Solve (Either ((EvTerm, Ct), [Ct]) ())
forall a. a -> TcPluginM 'Solve a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Either ((EvTerm, Ct), [Ct]) ()
-> TcPluginM 'Solve (Either ((EvTerm, Ct), [Ct]) ()))
-> Either ((EvTerm, Ct), [Ct]) ()
-> TcPluginM 'Solve (Either ((EvTerm, Ct), [Ct]) ())
forall a b. (a -> b) -> a -> b
$ () -> Either ((EvTerm, Ct), [Ct]) ()
forall a b. b -> Either a b
Right ()
Maybe (TyCon, [Type])
_ -> Either ((EvTerm, Ct), [Ct]) ()
-> TcPluginM 'Solve (Either ((EvTerm, Ct), [Ct]) ())
forall a. a -> TcPluginM 'Solve a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Either ((EvTerm, Ct), [Ct]) ()
-> TcPluginM 'Solve (Either ((EvTerm, Ct), [Ct]) ()))
-> Either ((EvTerm, Ct), [Ct]) ()
-> TcPluginM 'Solve (Either ((EvTerm, Ct), [Ct]) ())
forall a b. (a -> b) -> a -> b
$ () -> Either ((EvTerm, Ct), [Ct]) ()
forall a b. b -> Either a b
Right ()
Maybe FastString
Nothing -> Either ((EvTerm, Ct), [Ct]) ()
-> TcPluginM 'Solve (Either ((EvTerm, Ct), [Ct]) ())
forall a. a -> TcPluginM 'Solve a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Either ((EvTerm, Ct), [Ct]) ()
-> TcPluginM 'Solve (Either ((EvTerm, Ct), [Ct]) ()))
-> Either ((EvTerm, Ct), [Ct]) ()
-> TcPluginM 'Solve (Either ((EvTerm, Ct), [Ct]) ())
forall a b. (a -> b) -> a -> b
$ () -> Either ((EvTerm, Ct), [Ct]) ()
forall a b. b -> Either a b
Right ()
else Either ((EvTerm, Ct), [Ct]) ()
-> TcPluginM 'Solve (Either ((EvTerm, Ct), [Ct]) ())
forall a. a -> TcPluginM 'Solve a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Either ((EvTerm, Ct), [Ct]) ()
-> TcPluginM 'Solve (Either ((EvTerm, Ct), [Ct]) ()))
-> Either ((EvTerm, Ct), [Ct]) ()
-> TcPluginM 'Solve (Either ((EvTerm, Ct), [Ct]) ())
forall a b. (a -> b) -> a -> b
$ () -> Either ((EvTerm, Ct), [Ct]) ()
forall a b. b -> Either a b
Right ()
solveAllFields
:: PluginState
-> Ct
-> Class
-> [Type]
-> TcPluginM 'Solve (Either ((EvTerm, Ct), [Ct]) ())
solveAllFields :: PluginState
-> Ct
-> Class
-> [Type]
-> TcPluginM 'Solve (Either ((EvTerm, Ct), [Ct]) ())
solveAllFields PluginState
state Ct
ct Class
cls [Type]
tys
| [Type] -> Int
forall a. [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [Type]
tys Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
>= Int
3
, let rowTy :: Type
rowTy = [Type]
tys [Type] -> Int -> Type
forall a. HasCallStack => [a] -> Int -> a
!! ([Type] -> Int
forall a. [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [Type]
tys Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
2)
, Just [Type]
_ <- Type -> Maybe [Type]
myExtractPromotedList (Type -> Type
unwrapSynonyms Type
rowTy)
= do
let cTy :: Type
cTy = [Type] -> Type
forall a. HasCallStack => [a] -> a
last [Type]
tys
rTy :: Type
rTy = [Type]
tys [Type] -> Int -> Type
forall a. HasCallStack => [a] -> Int -> a
!! ([Type] -> Int
forall a. [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [Type]
tys Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
3)
fields :: [(Int, FastString, Type)]
fields = Type -> [(Int, FastString, Type)]
walkRowWithTypes Type
rowTy
loc :: CtLoc
loc = Ct -> CtLoc
ctLoc Ct
ct
dictAnyTy :: Type
dictAnyTy = Type -> Type -> Type
mkAppTy (TyCon -> Type
mkTyConTy (PluginState -> TyCon
psDictAnyTyCon PluginState
state)) Type
cTy
wanteds <- [(Int, FastString, Type)]
-> ((Int, FastString, Type) -> TcPluginM 'Solve (Type, CtEvidence))
-> TcPluginM 'Solve [(Type, CtEvidence)]
forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
t a -> (a -> m b) -> m (t b)
forM [(Int, FastString, Type)]
fields (((Int, FastString, Type) -> TcPluginM 'Solve (Type, CtEvidence))
-> TcPluginM 'Solve [(Type, CtEvidence)])
-> ((Int, FastString, Type) -> TcPluginM 'Solve (Type, CtEvidence))
-> TcPluginM 'Solve [(Type, CtEvidence)]
forall a b. (a -> b) -> a -> b
$ \(Int
_i, FastString
_nameFS, Type
fieldTy) -> do
ev <- CtLoc -> Type -> TcPluginM 'Solve CtEvidence
forall (m :: * -> *).
MonadTcPluginWork m =>
CtLoc -> Type -> m CtEvidence
newWanted CtLoc
loc (Type -> Type -> Type
mkAppTy Type
cTy Type
fieldTy)
pure (fieldTy, ev)
let dictAnys = [ CoreExpr -> [CoreExpr] -> CoreExpr
mkCoreApps (Var -> CoreExpr
forall b. Var -> Expr b
Var (PluginState -> Var
psMkDictAny PluginState
state))
[Type -> CoreExpr
forall b. Type -> Expr b
Type Type
cTy, Type -> CoreExpr
forall b. Type -> Expr b
Type Type
fieldTy, HasDebugCallStack => CtEvidence -> CoreExpr
CtEvidence -> CoreExpr
ctEvExpr CtEvidence
ev]
| (Type
fieldTy, CtEvidence
ev) <- [(Type, CtEvidence)]
wanteds
]
let listExpr = Type -> [CoreExpr] -> CoreExpr
mkListExpr Type
dictAnyTy [CoreExpr]
dictAnys
arrExpr = CoreExpr -> [CoreExpr] -> CoreExpr
mkCoreApps (Var -> CoreExpr
forall b. Var -> Expr b
Var (PluginState -> Var
psEvidenceAllFields PluginState
state)) [Type -> CoreExpr
forall b. Type -> Expr b
Type Type
cTy, CoreExpr
listExpr]
let scEvidence = DataCon -> [Type] -> [CoreExpr] -> CoreExpr
evDataConApp (Class -> DataCon
classDataCon (PluginState -> Class
psRowFlavourCls PluginState
state)) [Type
rTy] []
let dictExpr = DataCon -> [Type] -> [CoreExpr] -> CoreExpr
evDataConApp (Class -> DataCon
classDataCon Class
cls) [Type]
tys [CoreExpr
scEvidence, CoreExpr
arrExpr]
newWanteds = [CtEvidence -> Ct
mkNonCanonical CtEvidence
ev | (Type
_fieldTy, CtEvidence
ev) <- [(Type, CtEvidence)]
wanteds]
pure $ Left ((EvExpr dictExpr, ct), newWanteds)
| Bool
otherwise = Either ((EvTerm, Ct), [Ct]) ()
-> TcPluginM 'Solve (Either ((EvTerm, Ct), [Ct]) ())
forall a. a -> TcPluginM 'Solve a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Either ((EvTerm, Ct), [Ct]) ()
-> TcPluginM 'Solve (Either ((EvTerm, Ct), [Ct]) ()))
-> Either ((EvTerm, Ct), [Ct]) ()
-> TcPluginM 'Solve (Either ((EvTerm, Ct), [Ct]) ())
forall a b. (a -> b) -> a -> b
$ () -> Either ((EvTerm, Ct), [Ct]) ()
forall a b. b -> Either a b
Right ()
solveSubRow
:: PluginState
-> Ct
-> Class
-> [Type]
-> TcPluginM 'Solve (Either ((EvTerm, Ct), [Ct]) ())
solveSubRow :: PluginState
-> Ct
-> Class
-> [Type]
-> TcPluginM 'Solve (Either ((EvTerm, Ct), [Ct]) ())
solveSubRow PluginState
state Ct
ct Class
cls [Type]
tys
| [Type] -> Int
forall a. [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [Type]
tys Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
>= Int
2
, let subTy :: Type
subTy = [Type]
tys [Type] -> Int -> Type
forall a. HasCallStack => [a] -> Int -> a
!! ([Type] -> Int
forall a. [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [Type]
tys Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
2)
, let superTy :: Type
superTy = [Type] -> Type
forall a. HasCallStack => [a] -> a
last [Type]
tys
, let loc :: CtLoc
loc = Ct -> CtLoc
ctLoc Ct
ct
, Just [(Int, FastString, Type)]
subFields <- Type -> Maybe [(Int, FastString, Type)]
walkRowWithTypes_maybe Type
subTy
, Just [(Int, FastString, Type)]
superFields <- Type -> Maybe [(Int, FastString, Type)]
walkRowWithTypes_maybe Type
superTy
= case [(Int, FastString, Type)]
-> [(Int, FastString, Type)] -> Maybe [Int]
matchFields [(Int, FastString, Type)]
subFields [(Int, FastString, Type)]
superFields of
Just [Int]
indices -> do
let indicesExpr :: CoreExpr
indicesExpr = Type -> [CoreExpr] -> CoreExpr
mkListExpr Type
intTy ((Int -> CoreExpr) -> [Int] -> [CoreExpr]
forall a b. (a -> b) -> [a] -> [b]
map Int -> CoreExpr
mkIntExpr [Int]
indices)
dictExpr :: CoreExpr
dictExpr = DataCon -> [Type] -> [CoreExpr] -> CoreExpr
evDataConApp (Class -> DataCon
classDataCon Class
cls) [Type]
tys [CoreExpr
indicesExpr]
Either ((EvTerm, Ct), [Ct]) ()
-> TcPluginM 'Solve (Either ((EvTerm, Ct), [Ct]) ())
forall a. a -> TcPluginM 'Solve a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Either ((EvTerm, Ct), [Ct]) ()
-> TcPluginM 'Solve (Either ((EvTerm, Ct), [Ct]) ()))
-> Either ((EvTerm, Ct), [Ct]) ()
-> TcPluginM 'Solve (Either ((EvTerm, Ct), [Ct]) ())
forall a b. (a -> b) -> a -> b
$ ((EvTerm, Ct), [Ct]) -> Either ((EvTerm, Ct), [Ct]) ()
forall a b. a -> Either a b
Left ((CoreExpr -> EvTerm
EvExpr CoreExpr
dictExpr, Ct
ct), [])
Maybe [Int]
Nothing -> do
let dummyDict :: CoreExpr
dummyDict = DataCon -> [Type] -> [CoreExpr] -> CoreExpr
evDataConApp (Class -> DataCon
classDataCon Class
cls) [Type]
tys [Type -> [CoreExpr] -> CoreExpr
mkListExpr Type
intTy []]
mismatchDiag :: [String]
mismatchDiag = [(Int, FastString, Type)] -> [(Int, FastString, Type)] -> [String]
findSubRowMismatch [(Int, FastString, Type)]
subFields [(Int, FastString, Type)]
superFields
errCt <- PluginState -> CtLoc -> [String] -> TcPluginM 'Solve Ct
mkTypeErrorCt PluginState
state CtLoc
loc [String]
mismatchDiag
pure $ Left ((EvExpr dummyDict, ct), [errCt])
| Bool
otherwise = Either ((EvTerm, Ct), [Ct]) ()
-> TcPluginM 'Solve (Either ((EvTerm, Ct), [Ct]) ())
forall a. a -> TcPluginM 'Solve a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Either ((EvTerm, Ct), [Ct]) ()
-> TcPluginM 'Solve (Either ((EvTerm, Ct), [Ct]) ()))
-> Either ((EvTerm, Ct), [Ct]) ()
-> TcPluginM 'Solve (Either ((EvTerm, Ct), [Ct]) ())
forall a b. (a -> b) -> a -> b
$ () -> Either ((EvTerm, Ct), [Ct]) ()
forall a b. b -> Either a b
Right ()
where
matchFields :: [(Int, FastString, Type)] -> [(Int, FastString, Type)] -> Maybe [Int]
matchFields :: [(Int, FastString, Type)]
-> [(Int, FastString, Type)] -> Maybe [Int]
matchFields [] [(Int, FastString, Type)]
_ = [Int] -> Maybe [Int]
forall a. a -> Maybe a
Just []
matchFields ((Int
_, FastString
name, Type
fieldTy) : [(Int, FastString, Type)]
rest) [(Int, FastString, Type)]
sFields =
case [ Int
j | (Int
j, FastString
sName, Type
sFieldTy) <- [(Int, FastString, Type)]
sFields
, (if FastString -> Bool
nullFS FastString
name Bool -> Bool -> Bool
|| FastString -> Bool
nullFS FastString
sName then Bool
True else FastString
sName FastString -> FastString -> Bool
forall a. Eq a => a -> a -> Bool
== FastString
name)
, Type
fieldTy HasCallStack => Type -> Type -> Bool
Type -> Type -> Bool
`eqType` Type
sFieldTy ] of
(Int
j : [Int]
_) -> (Int
j Int -> [Int] -> [Int]
forall a. a -> [a] -> [a]
:) ([Int] -> [Int]) -> Maybe [Int] -> Maybe [Int]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> [(Int, FastString, Type)]
-> [(Int, FastString, Type)] -> Maybe [Int]
matchFields [(Int, FastString, Type)]
rest [(Int, FastString, Type)]
sFields
[] -> Maybe [Int]
forall a. Maybe a
Nothing
findSubRowMismatch :: [(Int, FastString, Type)] -> [(Int, FastString, Type)] -> [String]
findSubRowMismatch :: [(Int, FastString, Type)] -> [(Int, FastString, Type)] -> [String]
findSubRowMismatch [] [(Int, FastString, Type)]
_ =
[ String
"Polytropos SubRow Error:"
, String
" Sub-record row does not match super-record row."
]
findSubRowMismatch ((Int
_, FastString
name, Type
fieldTy) : [(Int, FastString, Type)]
rest) [(Int, FastString, Type)]
sFields =
case [ Type
sFieldTy | (Int
_, FastString
sName, Type
sFieldTy) <- [(Int, FastString, Type)]
sFields
, if FastString -> Bool
nullFS FastString
name Bool -> Bool -> Bool
|| FastString -> Bool
nullFS FastString
sName then Bool
True else FastString
sName FastString -> FastString -> Bool
forall a. Eq a => a -> a -> Bool
== FastString
name ] of
[] ->
let sNames :: [String]
sNames = [ FastString -> String
unpackFS FastString
n | (Int
_, FastString
n, Type
_) <- [(Int, FastString, Type)]
sFields, Bool -> Bool
not (FastString -> Bool
nullFS FastString
n) ]
in [ String
"Polytropos SubRow Error:"
, String
" Cannot project record: field '" String -> String -> String
forall a. [a] -> [a] -> [a]
++ FastString -> String
unpackFS FastString
name String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
"' from sub-record is missing in super-record:"
, String
" " String -> String -> String
forall a. [a] -> [a] -> [a]
++ [(Int, FastString, Type)] -> String
formatRecordRow [(Int, FastString, Type)]
sFields
, String
" " String -> String -> String
forall a. [a] -> [a] -> [a]
++ String -> [String] -> String
formatSuggestion (FastString -> String
unpackFS FastString
name) [String]
sNames
]
(Type
sFieldTy : [Type]
_)
| Bool -> Bool
not (Type
fieldTy HasCallStack => Type -> Type -> Bool
Type -> Type -> Bool
`eqType` Type
sFieldTy) ->
[ String
"Polytropos SubRow Error:"
, String
" Cannot project record: field '" String -> String -> String
forall a. [a] -> [a] -> [a]
++ FastString -> String
unpackFS FastString
name String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
"' has type:"
, String
" " String -> String -> String
forall a. [a] -> [a] -> [a]
++ SDoc -> String
showSDocUnsafe (Type -> SDoc
forall a. Outputable a => a -> SDoc
ppr Type
fieldTy)
, String
" in sub-record, but has type:"
, String
" " String -> String -> String
forall a. [a] -> [a] -> [a]
++ SDoc -> String
showSDocUnsafe (Type -> SDoc
forall a. Outputable a => a -> SDoc
ppr Type
sFieldTy)
, String
" in super-record."
]
| Bool
otherwise -> [(Int, FastString, Type)] -> [(Int, FastString, Type)] -> [String]
findSubRowMismatch [(Int, FastString, Type)]
rest [(Int, FastString, Type)]
sFields
solveSubSum
:: PluginState
-> Ct
-> Class
-> [Type]
-> TcPluginM 'Solve (Either ((EvTerm, Ct), [Ct]) ())
solveSubSum :: PluginState
-> Ct
-> Class
-> [Type]
-> TcPluginM 'Solve (Either ((EvTerm, Ct), [Ct]) ())
solveSubSum PluginState
state Ct
ct Class
cls [Type]
tys
| [Type] -> Int
forall a. [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [Type]
tys Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
>= Int
2
, let subTy :: Type
subTy = [Type]
tys [Type] -> Int -> Type
forall a. HasCallStack => [a] -> Int -> a
!! ([Type] -> Int
forall a. [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [Type]
tys Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
2)
, let superTy :: Type
superTy = [Type] -> Type
forall a. HasCallStack => [a] -> a
last [Type]
tys
, let loc :: CtLoc
loc = Ct -> CtLoc
ctLoc Ct
ct
, Just [(Int, FastString, Type)]
subCons <- Type -> Maybe [(Int, FastString, Type)]
walkSumRowWithTypes_maybe Type
subTy
, Just [(Int, FastString, Type)]
superCons <- Type -> Maybe [(Int, FastString, Type)]
walkSumRowWithTypes_maybe Type
superTy
= case [(Int, FastString, Type)]
-> [(Int, FastString, Type)] -> Maybe [Word]
matchCons [(Int, FastString, Type)]
subCons [(Int, FastString, Type)]
superCons of
Just [Word]
injectIndices -> do
let wordTy :: Type
wordTy = TyCon -> Type
mkTyConTy TyCon
wordTyCon
injectExpr :: CoreExpr
injectExpr = Type -> [CoreExpr] -> CoreExpr
mkListExpr Type
wordTy ((Word -> CoreExpr) -> [Word] -> [CoreExpr]
forall a b. (a -> b) -> [a] -> [b]
map Word -> CoreExpr
mkWordExpr [Word]
injectIndices)
narrowIndices :: [Maybe Word]
narrowIndices =
[ case [ Int -> Word
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
i :: Word
| (Int
i, FastString
sName, Type
sConRowTy) <- [(Int, FastString, Type)]
subCons
, (if FastString -> Bool
nullFS FastString
sName Bool -> Bool -> Bool
|| FastString -> Bool
nullFS FastString
superName then Bool
True else FastString
sName FastString -> FastString -> Bool
forall a. Eq a => a -> a -> Bool
== FastString
superName)
, Type -> Type -> Bool
sameRow Type
sConRowTy Type
superConRowTy
] of
(Word
subIdx : [Word]
_) -> Word -> Maybe Word
forall a. a -> Maybe a
Just Word
subIdx
[] -> Maybe Word
forall a. Maybe a
Nothing
| (Int
_j, FastString
superName, Type
superConRowTy) <- [(Int, FastString, Type)]
superCons
]
maybeWordTy :: Type
maybeWordTy = Type -> Type -> Type
mkAppTy (TyCon -> Type
mkTyConTy TyCon
maybeTyCon) Type
wordTy
narrowDataExpr :: Maybe Word -> CoreExpr
narrowDataExpr Maybe Word
Nothing = DataCon -> [CoreExpr] -> CoreExpr
mkCoreConApps DataCon
nothingDataCon [Type -> CoreExpr
forall b. Type -> Expr b
Type Type
wordTy]
narrowDataExpr (Just Word
w) = DataCon -> [CoreExpr] -> CoreExpr
mkCoreConApps DataCon
justDataCon [Type -> CoreExpr
forall b. Type -> Expr b
Type Type
wordTy, Word -> CoreExpr
mkWordExpr Word
w]
narrowExpr :: CoreExpr
narrowExpr = Type -> [CoreExpr] -> CoreExpr
mkListExpr Type
maybeWordTy ((Maybe Word -> CoreExpr) -> [Maybe Word] -> [CoreExpr]
forall a b. (a -> b) -> [a] -> [b]
map Maybe Word -> CoreExpr
narrowDataExpr [Maybe Word]
narrowIndices)
dictExpr :: CoreExpr
dictExpr = DataCon -> [Type] -> [CoreExpr] -> CoreExpr
evDataConApp (Class -> DataCon
classDataCon Class
cls) [Type]
tys [CoreExpr
injectExpr, CoreExpr
narrowExpr]
Either ((EvTerm, Ct), [Ct]) ()
-> TcPluginM 'Solve (Either ((EvTerm, Ct), [Ct]) ())
forall a. a -> TcPluginM 'Solve a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Either ((EvTerm, Ct), [Ct]) ()
-> TcPluginM 'Solve (Either ((EvTerm, Ct), [Ct]) ()))
-> Either ((EvTerm, Ct), [Ct]) ()
-> TcPluginM 'Solve (Either ((EvTerm, Ct), [Ct]) ())
forall a b. (a -> b) -> a -> b
$ ((EvTerm, Ct), [Ct]) -> Either ((EvTerm, Ct), [Ct]) ()
forall a b. a -> Either a b
Left ((CoreExpr -> EvTerm
EvExpr CoreExpr
dictExpr, Ct
ct), [])
Maybe [Word]
Nothing -> do
let wordTy :: Type
wordTy = TyCon -> Type
mkTyConTy TyCon
wordTyCon
maybeWordTy :: Type
maybeWordTy = Type -> Type -> Type
mkAppTy (TyCon -> Type
mkTyConTy TyCon
maybeTyCon) Type
wordTy
dummyDict :: CoreExpr
dummyDict = DataCon -> [Type] -> [CoreExpr] -> CoreExpr
evDataConApp (Class -> DataCon
classDataCon Class
cls) [Type]
tys [Type -> [CoreExpr] -> CoreExpr
mkListExpr Type
wordTy [], Type -> [CoreExpr] -> CoreExpr
mkListExpr Type
maybeWordTy []]
mismatchDiag :: [String]
mismatchDiag = [(Int, FastString, Type)] -> [(Int, FastString, Type)] -> [String]
findSubSumMismatch [(Int, FastString, Type)]
subCons [(Int, FastString, Type)]
superCons
errCt <- PluginState -> CtLoc -> [String] -> TcPluginM 'Solve Ct
mkTypeErrorCt PluginState
state CtLoc
loc [String]
mismatchDiag
pure $ Left ((EvExpr dummyDict, ct), [errCt])
| Bool
otherwise = Either ((EvTerm, Ct), [Ct]) ()
-> TcPluginM 'Solve (Either ((EvTerm, Ct), [Ct]) ())
forall a. a -> TcPluginM 'Solve a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Either ((EvTerm, Ct), [Ct]) ()
-> TcPluginM 'Solve (Either ((EvTerm, Ct), [Ct]) ()))
-> Either ((EvTerm, Ct), [Ct]) ()
-> TcPluginM 'Solve (Either ((EvTerm, Ct), [Ct]) ())
forall a b. (a -> b) -> a -> b
$ () -> Either ((EvTerm, Ct), [Ct]) ()
forall a b. b -> Either a b
Right ()
where
matchCons :: [(Int, FastString, Type)] -> [(Int, FastString, Type)] -> Maybe [Word]
matchCons :: [(Int, FastString, Type)]
-> [(Int, FastString, Type)] -> Maybe [Word]
matchCons [] [(Int, FastString, Type)]
_ = [Word] -> Maybe [Word]
forall a. a -> Maybe a
Just []
matchCons ((Int
_, FastString
conName, Type
conRowTy) : [(Int, FastString, Type)]
rest) [(Int, FastString, Type)]
sCons =
case [ Int
j | (Int
j, FastString
sName, Type
sRowTy) <- [(Int, FastString, Type)]
sCons
, (if FastString -> Bool
nullFS FastString
conName Bool -> Bool -> Bool
|| FastString -> Bool
nullFS FastString
sName then Bool
True else FastString
sName FastString -> FastString -> Bool
forall a. Eq a => a -> a -> Bool
== FastString
conName)
, Type -> Type -> Bool
sameRow Type
conRowTy Type
sRowTy ] of
(Int
j : [Int]
_) -> (Int -> Word
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
j Word -> [Word] -> [Word]
forall a. a -> [a] -> [a]
:) ([Word] -> [Word]) -> Maybe [Word] -> Maybe [Word]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> [(Int, FastString, Type)]
-> [(Int, FastString, Type)] -> Maybe [Word]
matchCons [(Int, FastString, Type)]
rest [(Int, FastString, Type)]
sCons
[] -> Maybe [Word]
forall a. Maybe a
Nothing
sameRow :: Type -> Type -> Bool
sameRow Type
r1 Type
r2
| Type
r1 HasCallStack => Type -> Type -> Bool
Type -> Type -> Bool
`eqType` Type
r2 = Bool
True
| Just [(Int, FastString, Type)]
fs1 <- Type -> Maybe [(Int, FastString, Type)]
walkRowWithTypes_maybe Type
r1
, Just [(Int, FastString, Type)]
fs2 <- Type -> Maybe [(Int, FastString, Type)]
walkRowWithTypes_maybe Type
r2
= [(Int, FastString, Type)] -> Int
forall a. [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [(Int, FastString, Type)]
fs1 Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== [(Int, FastString, Type)] -> Int
forall a. [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [(Int, FastString, Type)]
fs2 Bool -> Bool -> Bool
&&
[Bool] -> Bool
forall (t :: * -> *). Foldable t => t Bool -> Bool
and [ (if FastString -> Bool
nullFS FastString
n1 Bool -> Bool -> Bool
|| FastString -> Bool
nullFS FastString
n2 then Bool
True else FastString
n1 FastString -> FastString -> Bool
forall a. Eq a => a -> a -> Bool
== FastString
n2) Bool -> Bool -> Bool
&& Type
t1 HasCallStack => Type -> Type -> Bool
Type -> Type -> Bool
`eqType` Type
t2 | ((Int
_, FastString
n1, Type
t1), (Int
_, FastString
n2, Type
t2)) <- [(Int, FastString, Type)]
-> [(Int, FastString, Type)]
-> [((Int, FastString, Type), (Int, FastString, Type))]
forall a b. [a] -> [b] -> [(a, b)]
zip [(Int, FastString, Type)]
fs1 [(Int, FastString, Type)]
fs2 ]
| Bool
otherwise = Bool
False
findSubSumMismatch :: [(Int, FastString, Type)] -> [(Int, FastString, Type)] -> [String]
findSubSumMismatch :: [(Int, FastString, Type)] -> [(Int, FastString, Type)] -> [String]
findSubSumMismatch [] [(Int, FastString, Type)]
_ =
[ String
"Polytropos SubSum Error:"
, String
" Sub-variant row does not match super-variant row."
]
findSubSumMismatch ((Int
_, FastString
conName, Type
conRowTy) : [(Int, FastString, Type)]
rest) [(Int, FastString, Type)]
sCons =
case [ Type
sRowTy | (Int
_, FastString
sName, Type
sRowTy) <- [(Int, FastString, Type)]
sCons
, if FastString -> Bool
nullFS FastString
conName Bool -> Bool -> Bool
|| FastString -> Bool
nullFS FastString
sName then Bool
True else FastString
sName FastString -> FastString -> Bool
forall a. Eq a => a -> a -> Bool
== FastString
conName ] of
[] ->
let sNames :: [String]
sNames = [ FastString -> String
unpackFS FastString
n | (Int
_, FastString
n, Type
_) <- [(Int, FastString, Type)]
sCons, Bool -> Bool
not (FastString -> Bool
nullFS FastString
n) ]
in [ String
"Polytropos SubSum Error:"
, String
" Cannot widen variant: constructor '" String -> String -> String
forall a. [a] -> [a] -> [a]
++ FastString -> String
unpackFS FastString
conName String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
"' from sub-variant is missing in super-variant:"
, String
" " String -> String -> String
forall a. [a] -> [a] -> [a]
++ [(Int, FastString, Type)] -> String
formatVariantRow [(Int, FastString, Type)]
sCons
, String
" " String -> String -> String
forall a. [a] -> [a] -> [a]
++ String -> [String] -> String
formatCtorSuggestion (FastString -> String
unpackFS FastString
conName) [String]
sNames
]
(Type
sRowTy : [Type]
_)
| Bool -> Bool
not (Type -> Type -> Bool
sameRow Type
conRowTy Type
sRowTy) ->
let subFs :: [(Int, FastString, Type)]
subFs = Type -> [(Int, FastString, Type)]
walkRowWithTypes Type
conRowTy
superFs :: [(Int, FastString, Type)]
superFs = Type -> [(Int, FastString, Type)]
walkRowWithTypes Type
sRowTy
in [ String
"Polytropos SubSum Error:"
, String
" Cannot widen variant: constructor '" String -> String -> String
forall a. [a] -> [a] -> [a]
++ FastString -> String
unpackFS FastString
conName String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
"' has different payload rows:"
, String
" sub-variant payload: " String -> String -> String
forall a. [a] -> [a] -> [a]
++ [(Int, FastString, Type)] -> String
formatRecordRow [(Int, FastString, Type)]
subFs
, String
" super-variant payload: " String -> String -> String
forall a. [a] -> [a] -> [a]
++ [(Int, FastString, Type)] -> String
formatRecordRow [(Int, FastString, Type)]
superFs
]
| Bool
otherwise -> [(Int, FastString, Type)] -> [(Int, FastString, Type)] -> [String]
findSubSumMismatch [(Int, FastString, Type)]
rest [(Int, FastString, Type)]
sCons
fnv1a64FS :: FastString -> Word
fnv1a64FS :: FastString -> Word
fnv1a64FS FastString
fs = Word64 -> Word
forall a b. (Integral a, Num b) => a -> b
fromIntegral ((Word64 -> Char -> Word64) -> Word64 -> String -> Word64
forall b a. (b -> a -> b) -> b -> [a] -> b
forall (t :: * -> *) b a.
Foldable t =>
(b -> a -> b) -> b -> t a -> b
foldl' Word64 -> Char -> Word64
forall {a}. (Bits a, Num a) => a -> Char -> a
step (Word64
14695981039346656037 :: Word64) (FastString -> String
unpackFS FastString
fs))
where
step :: a -> Char -> a
step !a
h !Char
c = (a
h a -> a -> a
forall a. Bits a => a -> a -> a
`xor` Int -> a
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Char -> Int
ord Char
c)) a -> a -> a
forall a. Num a => a -> a -> a
* a
1099511628211
solveKnownHash
:: Ct
-> Class
-> [Type]
-> TcPluginM 'Solve (Either (EvTerm, Ct) ())
solveKnownHash :: Ct -> Class -> [Type] -> TcPluginM 'Solve (Either (EvTerm, Ct) ())
solveKnownHash Ct
ct Class
cls [Type]
tys = do
let mSTy :: Maybe Type
mSTy = case [Type]
tys of
[Type
s] -> Type -> Maybe Type
forall a. a -> Maybe a
Just Type
s
[Type
_, Type
s] -> Type -> Maybe Type
forall a. a -> Maybe a
Just Type
s
[Type]
_ -> Maybe Type
forall a. Maybe a
Nothing
case Maybe Type
mSTy of
Just Type
sTy -> case Type -> Maybe FastString
isStrLitTy (Type -> Type
unwrapSynonyms Type
sTy) of
Just FastString
fs -> do
let h :: Word
h = FastString -> Word
fnv1a64FS FastString
fs
wExpr :: CoreExpr
wExpr = Word -> CoreExpr
mkWordExpr Word
h
dictExpr :: CoreExpr
dictExpr = DataCon -> [Type] -> [CoreExpr] -> CoreExpr
evDataConApp (Class -> DataCon
classDataCon Class
cls) [Type]
tys [CoreExpr
wExpr]
Either (EvTerm, Ct) () -> TcPluginM 'Solve (Either (EvTerm, Ct) ())
forall a. a -> TcPluginM 'Solve a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Either (EvTerm, Ct) ()
-> TcPluginM 'Solve (Either (EvTerm, Ct) ()))
-> Either (EvTerm, Ct) ()
-> TcPluginM 'Solve (Either (EvTerm, Ct) ())
forall a b. (a -> b) -> a -> b
$ (EvTerm, Ct) -> Either (EvTerm, Ct) ()
forall a b. a -> Either a b
Left (CoreExpr -> EvTerm
EvExpr CoreExpr
dictExpr, Ct
ct)
Maybe FastString
Nothing -> Either (EvTerm, Ct) () -> TcPluginM 'Solve (Either (EvTerm, Ct) ())
forall a. a -> TcPluginM 'Solve a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Either (EvTerm, Ct) ()
-> TcPluginM 'Solve (Either (EvTerm, Ct) ()))
-> Either (EvTerm, Ct) ()
-> TcPluginM 'Solve (Either (EvTerm, Ct) ())
forall a b. (a -> b) -> a -> b
$ () -> Either (EvTerm, Ct) ()
forall a b. b -> Either a b
Right ()
Maybe Type
Nothing -> Either (EvTerm, Ct) () -> TcPluginM 'Solve (Either (EvTerm, Ct) ())
forall a. a -> TcPluginM 'Solve a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Either (EvTerm, Ct) ()
-> TcPluginM 'Solve (Either (EvTerm, Ct) ()))
-> Either (EvTerm, Ct) ()
-> TcPluginM 'Solve (Either (EvTerm, Ct) ())
forall a b. (a -> b) -> a -> b
$ () -> Either (EvTerm, Ct) ()
forall a b. b -> Either a b
Right ()
walkRowWithTypes_maybe :: Type -> Maybe [(Int, FastString, Type)]
walkRowWithTypes_maybe :: Type -> Maybe [(Int, FastString, Type)]
walkRowWithTypes_maybe Type
rowTy = do
xs <- Type -> Maybe [Type]
myExtractPromotedList (Type -> Type
unwrapSynonyms Type
rowTy)
zipWithM extractField [0..] xs
where
extractField :: a -> Type -> Maybe (a, FastString, Type)
extractField a
i Type
elemTy =
case HasDebugCallStack => Type -> Maybe (TyCon, [Type])
Type -> Maybe (TyCon, [Type])
splitTyConApp_maybe (Type -> Type
unwrapSynonyms Type
elemTy) of
Just (TyCon
_, [Type]
args)
| [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
, let nameTy :: Type
nameTy = [Type]
args [Type] -> Int -> Type
forall a. HasCallStack => [a] -> Int -> a
!! ([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
2)
, let fieldTy :: Type
fieldTy = [Type]
args [Type] -> Int -> Type
forall a. HasCallStack => [a] -> Int -> a
!! ([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
1)
, Just FastString
n <- Type -> Maybe FastString
isStrLitTy (Type -> Type
unwrapSynonyms Type
nameTy)
-> (a, FastString, Type) -> Maybe (a, FastString, Type)
forall a. a -> Maybe a
Just (a
i, FastString
n, Type
fieldTy)
Maybe (TyCon, [Type])
_ -> (a, FastString, Type) -> Maybe (a, FastString, Type)
forall a. a -> Maybe a
Just (a
i, FastString
nilFS, Type
elemTy)
walkSumRowWithTypes_maybe :: Type -> Maybe [(Int, FastString, Type)]
walkSumRowWithTypes_maybe :: Type -> Maybe [(Int, FastString, Type)]
walkSumRowWithTypes_maybe Type
rowTy = do
xs <- Type -> Maybe [Type]
myExtractPromotedList (Type -> Type
unwrapSynonyms Type
rowTy)
zipWithM extractCon [0..] xs
where
extractCon :: a -> Type -> Maybe (a, FastString, Type)
extractCon a
i Type
elemTy =
case HasDebugCallStack => Type -> Maybe (TyCon, [Type])
Type -> Maybe (TyCon, [Type])
splitTyConApp_maybe (Type -> Type
unwrapSynonyms Type
elemTy) of
Just (TyCon
_, [Type]
args)
| [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
, let nameTy :: Type
nameTy = [Type]
args [Type] -> Int -> Type
forall a. HasCallStack => [a] -> Int -> a
!! ([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
2)
, let conRowTy :: Type
conRowTy = [Type]
args [Type] -> Int -> Type
forall a. HasCallStack => [a] -> Int -> a
!! ([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
1)
, Just FastString
n <- Type -> Maybe FastString
isStrLitTy (Type -> Type
unwrapSynonyms Type
nameTy)
-> (a, FastString, Type) -> Maybe (a, FastString, Type)
forall a. a -> Maybe a
Just (a
i, FastString
n, Type
conRowTy)
Maybe (TyCon, [Type])
_ -> (a, FastString, Type) -> Maybe (a, FastString, Type)
forall a. a -> Maybe a
Just (a
i, FastString
nilFS, Type
elemTy)
unwrapSynonyms :: Type -> Type
unwrapSynonyms :: Type -> Type
unwrapSynonyms Type
ty = case Type -> Maybe Type
coreView Type
ty of
Just Type
ty' -> Type -> Type
unwrapSynonyms Type
ty'
Maybe Type
Nothing -> Type
ty
myExtractPromotedList :: Type -> Maybe [Type]
Type
ty = case HasDebugCallStack => Type -> Maybe (TyCon, [Type])
Type -> Maybe (TyCon, [Type])
splitTyConApp_maybe (Type -> Type
unwrapSynonyms Type
ty) of
Just (TyCon
tc, [Type
_, Type
x, Type
xs]) | OccName -> String
occNameString (TyCon -> OccName
forall a. NamedThing a => a -> OccName
getOccName TyCon
tc) String -> String -> Bool
forall a. Eq a => a -> a -> Bool
== String
":" -> do
rest <- Type -> Maybe [Type]
myExtractPromotedList Type
xs
return (x : rest)
Just (TyCon
tc, [Type
_]) | OccName -> String
occNameString (TyCon -> OccName
forall a. NamedThing a => a -> OccName
getOccName TyCon
tc) String -> String -> Bool
forall a. Eq a => a -> a -> Bool
== String
"[]" -> [Type] -> Maybe [Type]
forall a. a -> Maybe a
Just []
Maybe (TyCon, [Type])
_ -> Maybe [Type]
forall a. Maybe a
Nothing
walkRowWithTypes :: Type -> [(Int, FastString, Type)]
walkRowWithTypes :: Type -> [(Int, FastString, Type)]
walkRowWithTypes Type
rowTy =
case Type -> Maybe [Type]
myExtractPromotedList (Type -> Type
unwrapSynonyms Type
rowTy) of { Just [Type]
xs -> (Int -> Type -> (Int, FastString, Type))
-> [Int] -> [Type] -> [(Int, FastString, Type)]
forall a b c. (a -> b -> c) -> [a] -> [b] -> [c]
zipWith Int -> Type -> (Int, FastString, Type)
forall {a}. a -> Type -> (a, FastString, Type)
extractField [Int
0..] [Type]
xs; Maybe [Type]
Nothing -> [] }
where
extractField :: a -> Type -> (a, FastString, Type)
extractField a
i Type
elemTy =
case HasDebugCallStack => Type -> Maybe (TyCon, [Type])
Type -> Maybe (TyCon, [Type])
splitTyConApp_maybe (Type -> Type
unwrapSynonyms Type
elemTy) of
Just (TyCon
_, [Type]
args)
| [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
, let nameTy :: Type
nameTy = [Type]
args [Type] -> Int -> Type
forall a. HasCallStack => [a] -> Int -> a
!! ([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
2)
, let fieldTy :: Type
fieldTy = [Type]
args [Type] -> Int -> Type
forall a. HasCallStack => [a] -> Int -> a
!! ([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
1)
, Just FastString
n <- Type -> Maybe FastString
isStrLitTy (Type -> Type
unwrapSynonyms Type
nameTy)
-> (a
i, FastString
n, Type
fieldTy)
Maybe (TyCon, [Type])
_ -> (a
i, FastString
nilFS, Type
elemTy)
walkSumRowWithTypes :: Type -> [(Int, FastString, Type)]
walkSumRowWithTypes :: Type -> [(Int, FastString, Type)]
walkSumRowWithTypes Type
rowTy =
case Type -> Maybe [Type]
myExtractPromotedList (Type -> Type
unwrapSynonyms Type
rowTy) of { Just [Type]
xs -> (Int -> Type -> (Int, FastString, Type))
-> [Int] -> [Type] -> [(Int, FastString, Type)]
forall a b c. (a -> b -> c) -> [a] -> [b] -> [c]
zipWith Int -> Type -> (Int, FastString, Type)
forall {a}. a -> Type -> (a, FastString, Type)
extractCon [Int
0..] [Type]
xs; Maybe [Type]
Nothing -> [] }
where
extractCon :: a -> Type -> (a, FastString, Type)
extractCon a
i Type
elemTy =
case HasDebugCallStack => Type -> Maybe (TyCon, [Type])
Type -> Maybe (TyCon, [Type])
splitTyConApp_maybe (Type -> Type
unwrapSynonyms Type
elemTy) of
Just (TyCon
_, [Type]
args)
| [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
, let nameTy :: Type
nameTy = [Type]
args [Type] -> Int -> Type
forall a. HasCallStack => [a] -> Int -> a
!! ([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
2)
, let conRowTy :: Type
conRowTy = [Type]
args [Type] -> Int -> Type
forall a. HasCallStack => [a] -> Int -> a
!! ([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
1)
, Just FastString
n <- Type -> Maybe FastString
isStrLitTy (Type -> Type
unwrapSynonyms Type
nameTy)
-> (a
i, FastString
n, Type
conRowTy)
Maybe (TyCon, [Type])
_ -> (a
i, FastString
nilFS, Type
elemTy)
findConstructorIndex :: FastString -> Type -> Maybe Word
findConstructorIndex :: FastString -> Type -> Maybe Word
findConstructorIndex FastString
conName Type
rowTy =
case [Int -> Word
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
i | (Int
i, FastString
n, Type
_) <- Type -> [(Int, FastString, Type)]
walkSumRowWithTypes Type
rowTy, FastString
n FastString -> FastString -> Bool
forall a. Eq a => a -> a -> Bool
== FastString
conName] of
(Word
w : [Word]
_) -> Word -> Maybe Word
forall a. a -> Maybe a
Just Word
w
[] -> Maybe Word
forall a. Maybe a
Nothing
findFieldIndexByType :: Type -> Type -> Maybe Int
findFieldIndexByType :: Type -> Type -> Maybe Int
findFieldIndexByType Type
targetTy Type
rowTy =
case [Int
i | (Int
i, FastString
_, Type
ty) <- Type -> [(Int, FastString, Type)]
walkRowWithTypes Type
rowTy, Type
targetTy HasCallStack => Type -> Type -> Bool
Type -> Type -> Bool
`eqType` Type
ty] of
(Int
i : [Int]
_) -> Int -> Maybe Int
forall a. a -> Maybe a
Just Int
i
[] -> Maybe Int
forall a. Maybe a
Nothing
findConstructorIndexByType :: Type -> Type -> Maybe Word
findConstructorIndexByType :: Type -> Type -> Maybe Word
findConstructorIndexByType Type
targetTy Type
rowTy =
case [Int -> Word
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
i | (Int
i, FastString
_, Type
ty) <- Type -> [(Int, FastString, Type)]
walkSumRowWithTypes Type
rowTy, Type
targetTy HasCallStack => Type -> Type -> Bool
Type -> Type -> Bool
`eqType` Type
ty] of
(Word
w : [Word]
_) -> Word -> Maybe Word
forall a. a -> Maybe a
Just Word
w
[] -> Maybe Word
forall a. Maybe a
Nothing
findFieldType :: FastString -> Type -> Maybe (Int, Type)
findFieldType :: FastString -> Type -> Maybe (Int, Type)
findFieldType FastString
fieldName Type
rowTy =
case [(Int
i, Type
ty) | (Int
i, FastString
n, Type
ty) <- Type -> [(Int, FastString, Type)]
walkRowWithTypes Type
rowTy, FastString
n FastString -> FastString -> Bool
forall a. Eq a => a -> a -> Bool
== FastString
fieldName] of
((Int, Type)
res : [(Int, Type)]
_) -> (Int, Type) -> Maybe (Int, Type)
forall a. a -> Maybe a
Just (Int, Type)
res
[] -> Maybe (Int, Type)
forall a. Maybe a
Nothing
mkIntExpr :: Int -> CoreExpr
mkIntExpr :: Int -> CoreExpr
mkIntExpr Int
i = DataCon -> [CoreExpr] -> CoreExpr
mkCoreConApps DataCon
intDataCon [Literal -> CoreExpr
forall b. Literal -> Expr b
Lit (LitNumType -> Integer -> Literal
LitNumber LitNumType
LitNumInt (Int -> Integer
forall a. Integral a => a -> Integer
toInteger Int
i))]
mkWordExpr :: Word -> CoreExpr
mkWordExpr :: Word -> CoreExpr
mkWordExpr Word
w = DataCon -> [CoreExpr] -> CoreExpr
mkCoreConApps DataCon
wordDataCon [Literal -> CoreExpr
forall b. Literal -> Expr b
Lit (LitNumType -> Integer -> Literal
LitNumber LitNumType
LitNumWord (Word -> Integer
forall a. Integral a => a -> Integer
toInteger Word
w))]