module TcHoleErrors ( findValidHoleFits, tcFilterHoleFits, HoleFit (..)
, HoleFitCandidate (..), tcCheckHoleFit, tcSubsumes
, withoutUnification ) where
import GhcPrelude
import TcRnTypes
import TcRnMonad
import TcMType
import TcEvidence
import TcType
import Type
import DataCon
import Name
import RdrName ( pprNameProvenance , GlobalRdrElt (..), globalRdrEnvElts )
import PrelNames ( gHC_ERR )
import Id
import VarSet
import VarEnv
import Bag
import ConLike ( ConLike(..) )
import Util
import TcEnv (tcLookup)
import Outputable
import DynFlags
import Maybes
import FV ( fvVarList, fvVarSet, unionFV, mkFVs, FV )
import Control.Arrow ( (&&&) )
import Control.Monad ( filterM, replicateM )
import Data.List ( partition, sort, sortOn, nubBy )
import Data.Graph ( graphFromEdges, topSort )
import Data.Function ( on )
import TcSimplify ( simpl_top, runTcSDeriveds )
import TcUnify ( tcSubType_NC )
import ExtractDocs ( extractDocs )
import qualified Data.Map as Map
import HsDoc ( HsDocString, unpackHDS, DeclDocMap(..) )
import HscTypes ( ModIface(..) )
import LoadIface ( loadInterfaceForNameMaybe )
import PrelInfo (knownKeyNames)
data HoleFitDispConfig = HFDC { HoleFitDispConfig -> Bool
showWrap :: Bool
, HoleFitDispConfig -> Bool
showWrapVars :: Bool
, HoleFitDispConfig -> Bool
showType :: Bool
, HoleFitDispConfig -> Bool
showProv :: Bool
, HoleFitDispConfig -> Bool
showMatches :: Bool }
debugHoleFitDispConfig :: HoleFitDispConfig
debugHoleFitDispConfig :: HoleFitDispConfig
debugHoleFitDispConfig = Bool -> Bool -> Bool -> Bool -> Bool -> HoleFitDispConfig
HFDC Bool
True Bool
True Bool
True Bool
False Bool
False
getHoleFitDispConfig :: TcM HoleFitDispConfig
getHoleFitDispConfig :: TcM HoleFitDispConfig
getHoleFitDispConfig
= do { Bool
sWrap <- GeneralFlag -> TcRnIf TcGblEnv TcLclEnv Bool
forall gbl lcl. GeneralFlag -> TcRnIf gbl lcl Bool
goptM GeneralFlag
Opt_ShowTypeAppOfHoleFits
; Bool
sWrapVars <- GeneralFlag -> TcRnIf TcGblEnv TcLclEnv Bool
forall gbl lcl. GeneralFlag -> TcRnIf gbl lcl Bool
goptM GeneralFlag
Opt_ShowTypeAppVarsOfHoleFits
; Bool
sType <- GeneralFlag -> TcRnIf TcGblEnv TcLclEnv Bool
forall gbl lcl. GeneralFlag -> TcRnIf gbl lcl Bool
goptM GeneralFlag
Opt_ShowTypeOfHoleFits
; Bool
sProv <- GeneralFlag -> TcRnIf TcGblEnv TcLclEnv Bool
forall gbl lcl. GeneralFlag -> TcRnIf gbl lcl Bool
goptM GeneralFlag
Opt_ShowProvOfHoleFits
; Bool
sMatc <- GeneralFlag -> TcRnIf TcGblEnv TcLclEnv Bool
forall gbl lcl. GeneralFlag -> TcRnIf gbl lcl Bool
goptM GeneralFlag
Opt_ShowMatchesOfHoleFits
; HoleFitDispConfig -> TcM HoleFitDispConfig
forall (m :: * -> *) a. Monad m => a -> m a
return HFDC :: Bool -> Bool -> Bool -> Bool -> Bool -> HoleFitDispConfig
HFDC{ showWrap :: Bool
showWrap = Bool
sWrap, showWrapVars :: Bool
showWrapVars = Bool
sWrapVars
, showProv :: Bool
showProv = Bool
sProv, showType :: Bool
showType = Bool
sType
, showMatches :: Bool
showMatches = Bool
sMatc } }
data SortingAlg = NoSorting
| BySize
| BySubsumption
deriving (SortingAlg -> SortingAlg -> Bool
(SortingAlg -> SortingAlg -> Bool)
-> (SortingAlg -> SortingAlg -> Bool) -> Eq SortingAlg
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: SortingAlg -> SortingAlg -> Bool
$c/= :: SortingAlg -> SortingAlg -> Bool
== :: SortingAlg -> SortingAlg -> Bool
$c== :: SortingAlg -> SortingAlg -> Bool
Eq, Eq SortingAlg
Eq SortingAlg =>
(SortingAlg -> SortingAlg -> Ordering)
-> (SortingAlg -> SortingAlg -> Bool)
-> (SortingAlg -> SortingAlg -> Bool)
-> (SortingAlg -> SortingAlg -> Bool)
-> (SortingAlg -> SortingAlg -> Bool)
-> (SortingAlg -> SortingAlg -> SortingAlg)
-> (SortingAlg -> SortingAlg -> SortingAlg)
-> Ord SortingAlg
SortingAlg -> SortingAlg -> Bool
SortingAlg -> SortingAlg -> Ordering
SortingAlg -> SortingAlg -> SortingAlg
forall a.
Eq a =>
(a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
min :: SortingAlg -> SortingAlg -> SortingAlg
$cmin :: SortingAlg -> SortingAlg -> SortingAlg
max :: SortingAlg -> SortingAlg -> SortingAlg
$cmax :: SortingAlg -> SortingAlg -> SortingAlg
>= :: SortingAlg -> SortingAlg -> Bool
$c>= :: SortingAlg -> SortingAlg -> Bool
> :: SortingAlg -> SortingAlg -> Bool
$c> :: SortingAlg -> SortingAlg -> Bool
<= :: SortingAlg -> SortingAlg -> Bool
$c<= :: SortingAlg -> SortingAlg -> Bool
< :: SortingAlg -> SortingAlg -> Bool
$c< :: SortingAlg -> SortingAlg -> Bool
compare :: SortingAlg -> SortingAlg -> Ordering
$ccompare :: SortingAlg -> SortingAlg -> Ordering
$cp1Ord :: Eq SortingAlg
Ord)
getSortingAlg :: TcM SortingAlg
getSortingAlg :: TcM SortingAlg
getSortingAlg =
do { Bool
shouldSort <- GeneralFlag -> TcRnIf TcGblEnv TcLclEnv Bool
forall gbl lcl. GeneralFlag -> TcRnIf gbl lcl Bool
goptM GeneralFlag
Opt_SortValidHoleFits
; Bool
subsumSort <- GeneralFlag -> TcRnIf TcGblEnv TcLclEnv Bool
forall gbl lcl. GeneralFlag -> TcRnIf gbl lcl Bool
goptM GeneralFlag
Opt_SortBySubsumHoleFits
; Bool
sizeSort <- GeneralFlag -> TcRnIf TcGblEnv TcLclEnv Bool
forall gbl lcl. GeneralFlag -> TcRnIf gbl lcl Bool
goptM GeneralFlag
Opt_SortBySizeHoleFits
; SortingAlg -> TcM SortingAlg
forall (m :: * -> *) a. Monad m => a -> m a
return (SortingAlg -> TcM SortingAlg) -> SortingAlg -> TcM SortingAlg
forall a b. (a -> b) -> a -> b
$ if Bool -> Bool
not Bool
shouldSort
then SortingAlg
NoSorting
else if Bool
subsumSort
then SortingAlg
BySubsumption
else if Bool
sizeSort
then SortingAlg
BySize
else SortingAlg
NoSorting }
data HoleFitCandidate = IdHFCand Id
| NameHFCand Name
| GreHFCand GlobalRdrElt
deriving (HoleFitCandidate -> HoleFitCandidate -> Bool
(HoleFitCandidate -> HoleFitCandidate -> Bool)
-> (HoleFitCandidate -> HoleFitCandidate -> Bool)
-> Eq HoleFitCandidate
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: HoleFitCandidate -> HoleFitCandidate -> Bool
$c/= :: HoleFitCandidate -> HoleFitCandidate -> Bool
== :: HoleFitCandidate -> HoleFitCandidate -> Bool
$c== :: HoleFitCandidate -> HoleFitCandidate -> Bool
Eq)
instance Outputable HoleFitCandidate where
ppr :: HoleFitCandidate -> SDoc
ppr = HoleFitCandidate -> SDoc
pprHoleFitCand
pprHoleFitCand :: HoleFitCandidate -> SDoc
pprHoleFitCand :: HoleFitCandidate -> SDoc
pprHoleFitCand (IdHFCand id :: Id
id) = String -> SDoc
text "Id HFC: " SDoc -> SDoc -> SDoc
<> Id -> SDoc
forall a. Outputable a => a -> SDoc
ppr Id
id
pprHoleFitCand (NameHFCand name :: Name
name) = String -> SDoc
text "Name HFC: " SDoc -> SDoc -> SDoc
<> Name -> SDoc
forall a. Outputable a => a -> SDoc
ppr Name
name
pprHoleFitCand (GreHFCand gre :: GlobalRdrElt
gre) = String -> SDoc
text "Gre HFC: " SDoc -> SDoc -> SDoc
<> GlobalRdrElt -> SDoc
forall a. Outputable a => a -> SDoc
ppr GlobalRdrElt
gre
instance HasOccName HoleFitCandidate where
occName :: HoleFitCandidate -> OccName
occName hfc :: HoleFitCandidate
hfc = case HoleFitCandidate
hfc of
IdHFCand id :: Id
id -> Id -> OccName
forall name. HasOccName name => name -> OccName
occName Id
id
NameHFCand name :: Name
name -> Name -> OccName
forall name. HasOccName name => name -> OccName
occName Name
name
GreHFCand gre :: GlobalRdrElt
gre -> Name -> OccName
forall name. HasOccName name => name -> OccName
occName (GlobalRdrElt -> Name
gre_name GlobalRdrElt
gre)
data HoleFit =
HoleFit { HoleFit -> Id
hfId :: Id
, HoleFit -> HoleFitCandidate
hfCand :: HoleFitCandidate
, HoleFit -> TcType
hfType :: TcType
, HoleFit -> Int
hfRefLvl :: Int
, HoleFit -> [TcType]
hfWrap :: [TcType]
, HoleFit -> [TcType]
hfMatches :: [TcType]
, HoleFit -> Maybe HsDocString
hfDoc :: Maybe HsDocString }
hfName :: HoleFit -> Name
hfName :: HoleFit -> Name
hfName hf :: HoleFit
hf = case HoleFit -> HoleFitCandidate
hfCand HoleFit
hf of
IdHFCand id :: Id
id -> Id -> Name
idName Id
id
NameHFCand name :: Name
name -> Name
name
GreHFCand gre :: GlobalRdrElt
gre -> GlobalRdrElt -> Name
gre_name GlobalRdrElt
gre
hfIsLcl :: HoleFit -> Bool
hfIsLcl :: HoleFit -> Bool
hfIsLcl hf :: HoleFit
hf = case HoleFit -> HoleFitCandidate
hfCand HoleFit
hf of
IdHFCand _ -> Bool
True
NameHFCand _ -> Bool
False
GreHFCand gre :: GlobalRdrElt
gre -> GlobalRdrElt -> Bool
gre_lcl GlobalRdrElt
gre
instance Eq HoleFit where
== :: HoleFit -> HoleFit -> Bool
(==) = Id -> Id -> Bool
forall a. Eq a => a -> a -> Bool
(==) (Id -> Id -> Bool) -> (HoleFit -> Id) -> HoleFit -> HoleFit -> Bool
forall b c a. (b -> b -> c) -> (a -> b) -> a -> a -> c
`on` HoleFit -> Id
hfId
instance Ord HoleFit where
compare :: HoleFit -> HoleFit -> Ordering
compare a :: HoleFit
a b :: HoleFit
b = HoleFit -> HoleFit -> Ordering
cmp HoleFit
a HoleFit
b
where cmp :: HoleFit -> HoleFit -> Ordering
cmp = if HoleFit -> Int
hfRefLvl HoleFit
a Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== HoleFit -> Int
hfRefLvl HoleFit
b
then Name -> Name -> Ordering
forall a. Ord a => a -> a -> Ordering
compare (Name -> Name -> Ordering)
-> (HoleFit -> Name) -> HoleFit -> HoleFit -> Ordering
forall b c a. (b -> b -> c) -> (a -> b) -> a -> a -> c
`on` HoleFit -> Name
hfName
else Int -> Int -> Ordering
forall a. Ord a => a -> a -> Ordering
compare (Int -> Int -> Ordering)
-> (HoleFit -> Int) -> HoleFit -> HoleFit -> Ordering
forall b c a. (b -> b -> c) -> (a -> b) -> a -> a -> c
`on` HoleFit -> Int
hfRefLvl
instance Outputable HoleFit where
ppr :: HoleFit -> SDoc
ppr = HoleFitDispConfig -> HoleFit -> SDoc
pprHoleFit HoleFitDispConfig
debugHoleFitDispConfig
addDocs :: [HoleFit] -> TcM [HoleFit]
addDocs :: [HoleFit] -> TcM [HoleFit]
addDocs fits :: [HoleFit]
fits =
do { Bool
showDocs <- GeneralFlag -> TcRnIf TcGblEnv TcLclEnv Bool
forall gbl lcl. GeneralFlag -> TcRnIf gbl lcl Bool
goptM GeneralFlag
Opt_ShowDocsOfHoleFits
; if Bool
showDocs
then do { (_, DeclDocMap lclDocs :: Map Name HsDocString
lclDocs, _) <- TcGblEnv -> (Maybe HsDocString, DeclDocMap, ArgDocMap)
extractDocs (TcGblEnv -> (Maybe HsDocString, DeclDocMap, ArgDocMap))
-> IOEnv (Env TcGblEnv TcLclEnv) TcGblEnv
-> IOEnv
(Env TcGblEnv TcLclEnv) (Maybe HsDocString, DeclDocMap, ArgDocMap)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> IOEnv (Env TcGblEnv TcLclEnv) TcGblEnv
forall gbl lcl. TcRnIf gbl lcl gbl
getGblEnv
; (HoleFit -> IOEnv (Env TcGblEnv TcLclEnv) HoleFit)
-> [HoleFit] -> TcM [HoleFit]
forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
mapM (Map Name HsDocString
-> HoleFit -> IOEnv (Env TcGblEnv TcLclEnv) HoleFit
upd Map Name HsDocString
lclDocs) [HoleFit]
fits }
else [HoleFit] -> TcM [HoleFit]
forall (m :: * -> *) a. Monad m => a -> m a
return [HoleFit]
fits }
where
msg :: SDoc
msg = String -> SDoc
text "TcHoleErrors addDocs"
lookupInIface :: Name -> ModIface -> Maybe HsDocString
lookupInIface name :: Name
name (ModIface { mi_decl_docs :: ModIface -> DeclDocMap
mi_decl_docs = DeclDocMap dmap :: Map Name HsDocString
dmap })
= Name -> Map Name HsDocString -> Maybe HsDocString
forall k a. Ord k => k -> Map k a -> Maybe a
Map.lookup Name
name Map Name HsDocString
dmap
upd :: Map Name HsDocString
-> HoleFit -> IOEnv (Env TcGblEnv TcLclEnv) HoleFit
upd lclDocs :: Map Name HsDocString
lclDocs fit :: HoleFit
fit =
let name :: Name
name = HoleFit -> Name
hfName HoleFit
fit in
do { Maybe HsDocString
doc <- if HoleFit -> Bool
hfIsLcl HoleFit
fit
then Maybe HsDocString
-> IOEnv (Env TcGblEnv TcLclEnv) (Maybe HsDocString)
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Name -> Map Name HsDocString -> Maybe HsDocString
forall k a. Ord k => k -> Map k a -> Maybe a
Map.lookup Name
name Map Name HsDocString
lclDocs)
else do { Maybe ModIface
mbIface <- SDoc -> Name -> TcRn (Maybe ModIface)
loadInterfaceForNameMaybe SDoc
msg Name
name
; Maybe HsDocString
-> IOEnv (Env TcGblEnv TcLclEnv) (Maybe HsDocString)
forall (m :: * -> *) a. Monad m => a -> m a
return (Maybe HsDocString
-> IOEnv (Env TcGblEnv TcLclEnv) (Maybe HsDocString))
-> Maybe HsDocString
-> IOEnv (Env TcGblEnv TcLclEnv) (Maybe HsDocString)
forall a b. (a -> b) -> a -> b
$ Maybe ModIface
mbIface Maybe ModIface
-> (ModIface -> Maybe HsDocString) -> Maybe HsDocString
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= Name -> ModIface -> Maybe HsDocString
lookupInIface Name
name }
; HoleFit -> IOEnv (Env TcGblEnv TcLclEnv) HoleFit
forall (m :: * -> *) a. Monad m => a -> m a
return (HoleFit -> IOEnv (Env TcGblEnv TcLclEnv) HoleFit)
-> HoleFit -> IOEnv (Env TcGblEnv TcLclEnv) HoleFit
forall a b. (a -> b) -> a -> b
$ HoleFit
fit {hfDoc :: Maybe HsDocString
hfDoc = Maybe HsDocString
doc} }
pprHoleFit :: HoleFitDispConfig -> HoleFit -> SDoc
pprHoleFit :: HoleFitDispConfig -> HoleFit -> SDoc
pprHoleFit (HFDC sWrp :: Bool
sWrp sWrpVars :: Bool
sWrpVars sTy :: Bool
sTy sProv :: Bool
sProv sMs :: Bool
sMs) hf :: HoleFit
hf = SDoc -> Int -> SDoc -> SDoc
hang SDoc
display 2 SDoc
provenance
where name :: Name
name = HoleFit -> Name
hfName HoleFit
hf
ty :: TcType
ty = HoleFit -> TcType
hfType HoleFit
hf
matches :: [TcType]
matches = HoleFit -> [TcType]
hfMatches HoleFit
hf
wrap :: [TcType]
wrap = HoleFit -> [TcType]
hfWrap HoleFit
hf
tyApp :: SDoc
tyApp = [SDoc] -> SDoc
sep ([SDoc] -> SDoc) -> [SDoc] -> SDoc
forall a b. (a -> b) -> a -> b
$ (TcType -> SDoc) -> [TcType] -> [SDoc]
forall a b. (a -> b) -> [a] -> [b]
map ((String -> SDoc
text "@" SDoc -> SDoc -> SDoc
<>) (SDoc -> SDoc) -> (TcType -> SDoc) -> TcType -> SDoc
forall b c a. (b -> c) -> (a -> b) -> a -> c
. TcType -> SDoc
pprParendType) [TcType]
wrap
tyAppVars :: SDoc
tyAppVars = [SDoc] -> SDoc
sep ([SDoc] -> SDoc) -> [SDoc] -> SDoc
forall a b. (a -> b) -> a -> b
$ SDoc -> [SDoc] -> [SDoc]
punctuate SDoc
comma ([SDoc] -> [SDoc]) -> [SDoc] -> [SDoc]
forall a b. (a -> b) -> a -> b
$
((Id, TcType) -> SDoc) -> [(Id, TcType)] -> [SDoc]
forall a b. (a -> b) -> [a] -> [b]
map (\(v :: Id
v,t :: TcType
t) -> Id -> SDoc
forall a. Outputable a => a -> SDoc
ppr Id
v SDoc -> SDoc -> SDoc
<+> String -> SDoc
text "~" SDoc -> SDoc -> SDoc
<+> TcType -> SDoc
pprParendType TcType
t) ([(Id, TcType)] -> [SDoc]) -> [(Id, TcType)] -> [SDoc]
forall a b. (a -> b) -> a -> b
$
[Id] -> [TcType] -> [(Id, TcType)]
forall a b. [a] -> [b] -> [(a, b)]
zip [Id]
vars [TcType]
wrap
where
vars :: [Id]
vars = TcType -> [Id]
unwrapTypeVars TcType
ty
unwrapTypeVars :: Type -> [TyVar]
unwrapTypeVars :: TcType -> [Id]
unwrapTypeVars t :: TcType
t = [Id]
vars [Id] -> [Id] -> [Id]
forall a. [a] -> [a] -> [a]
++ case TcType -> Maybe (TcType, TcType)
splitFunTy_maybe TcType
unforalled of
Just (_, unfunned :: TcType
unfunned) -> TcType -> [Id]
unwrapTypeVars TcType
unfunned
_ -> []
where (vars :: [Id]
vars, unforalled :: TcType
unforalled) = TcType -> ([Id], TcType)
splitForAllTys TcType
t
holeVs :: SDoc
holeVs = [SDoc] -> SDoc
sep ([SDoc] -> SDoc) -> [SDoc] -> SDoc
forall a b. (a -> b) -> a -> b
$ (TcType -> SDoc) -> [TcType] -> [SDoc]
forall a b. (a -> b) -> [a] -> [b]
map (SDoc -> SDoc
parens (SDoc -> SDoc) -> (TcType -> SDoc) -> TcType -> SDoc
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (String -> SDoc
text "_" SDoc -> SDoc -> SDoc
<+> SDoc
dcolon SDoc -> SDoc -> SDoc
<+>) (SDoc -> SDoc) -> (TcType -> SDoc) -> TcType -> SDoc
forall b c a. (b -> c) -> (a -> b) -> a -> c
. TcType -> SDoc
forall a. Outputable a => a -> SDoc
ppr) [TcType]
matches
holeDisp :: SDoc
holeDisp = if Bool
sMs then SDoc
holeVs
else [SDoc] -> SDoc
sep ([SDoc] -> SDoc) -> [SDoc] -> SDoc
forall a b. (a -> b) -> a -> b
$ Int -> SDoc -> [SDoc]
forall a. Int -> a -> [a]
replicate ([TcType] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [TcType]
matches) (SDoc -> [SDoc]) -> SDoc -> [SDoc]
forall a b. (a -> b) -> a -> b
$ String -> SDoc
text "_"
occDisp :: SDoc
occDisp = Name -> SDoc
forall a. OutputableBndr a => a -> SDoc
pprPrefixOcc Name
name
tyDisp :: SDoc
tyDisp = Bool -> SDoc -> SDoc
ppWhen Bool
sTy (SDoc -> SDoc) -> SDoc -> SDoc
forall a b. (a -> b) -> a -> b
$ SDoc
dcolon SDoc -> SDoc -> SDoc
<+> TcType -> SDoc
forall a. Outputable a => a -> SDoc
ppr TcType
ty
has :: [a] -> Bool
has = Bool -> Bool
not (Bool -> Bool) -> ([a] -> Bool) -> [a] -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [a] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null
wrapDisp :: SDoc
wrapDisp = Bool -> SDoc -> SDoc
ppWhen ([TcType] -> Bool
forall a. [a] -> Bool
has [TcType]
wrap Bool -> Bool -> Bool
&& (Bool
sWrp Bool -> Bool -> Bool
|| Bool
sWrpVars))
(SDoc -> SDoc) -> SDoc -> SDoc
forall a b. (a -> b) -> a -> b
$ String -> SDoc
text "with" SDoc -> SDoc -> SDoc
<+> if Bool
sWrp Bool -> Bool -> Bool
|| Bool -> Bool
not Bool
sTy
then SDoc
occDisp SDoc -> SDoc -> SDoc
<+> SDoc
tyApp
else SDoc
tyAppVars
docs :: SDoc
docs = case HoleFit -> Maybe HsDocString
hfDoc HoleFit
hf of
Just d :: HsDocString
d -> String -> SDoc
text "{-^" SDoc -> SDoc -> SDoc
<>
([SDoc] -> SDoc
vcat ([SDoc] -> SDoc) -> (HsDocString -> [SDoc]) -> HsDocString -> SDoc
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (String -> SDoc) -> [String] -> [SDoc]
forall a b. (a -> b) -> [a] -> [b]
map String -> SDoc
text ([String] -> [SDoc])
-> (HsDocString -> [String]) -> HsDocString -> [SDoc]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> [String]
lines (String -> [String])
-> (HsDocString -> String) -> HsDocString -> [String]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. HsDocString -> String
unpackHDS) HsDocString
d
SDoc -> SDoc -> SDoc
<> String -> SDoc
text "-}"
_ -> SDoc
empty
funcInfo :: SDoc
funcInfo = Bool -> SDoc -> SDoc
ppWhen ([TcType] -> Bool
forall a. [a] -> Bool
has [TcType]
matches Bool -> Bool -> Bool
&& Bool
sTy) (SDoc -> SDoc) -> SDoc -> SDoc
forall a b. (a -> b) -> a -> b
$
String -> SDoc
text "where" SDoc -> SDoc -> SDoc
<+> SDoc
occDisp SDoc -> SDoc -> SDoc
<+> SDoc
tyDisp
subDisp :: SDoc
subDisp = SDoc
occDisp SDoc -> SDoc -> SDoc
<+> if [TcType] -> Bool
forall a. [a] -> Bool
has [TcType]
matches then SDoc
holeDisp else SDoc
tyDisp
display :: SDoc
display = SDoc
subDisp SDoc -> SDoc -> SDoc
$$ Int -> SDoc -> SDoc
nest 2 (SDoc
funcInfo SDoc -> SDoc -> SDoc
$+$ SDoc
docs SDoc -> SDoc -> SDoc
$+$ SDoc
wrapDisp)
provenance :: SDoc
provenance = Bool -> SDoc -> SDoc
ppWhen Bool
sProv (SDoc -> SDoc) -> SDoc -> SDoc
forall a b. (a -> b) -> a -> b
$ SDoc -> SDoc
parens (SDoc -> SDoc) -> SDoc -> SDoc
forall a b. (a -> b) -> a -> b
$
case HoleFit -> HoleFitCandidate
hfCand HoleFit
hf of
GreHFCand gre :: GlobalRdrElt
gre -> GlobalRdrElt -> SDoc
pprNameProvenance GlobalRdrElt
gre
_ -> String -> SDoc
text "bound at" SDoc -> SDoc -> SDoc
<+> SrcLoc -> SDoc
forall a. Outputable a => a -> SDoc
ppr (Name -> SrcLoc
forall a. NamedThing a => a -> SrcLoc
getSrcLoc Name
name)
getLocalBindings :: TidyEnv -> Ct -> TcM [Id]
getLocalBindings :: TidyEnv -> Ct -> TcM [Id]
getLocalBindings tidy_orig :: TidyEnv
tidy_orig ct :: Ct
ct
= do { (env1 :: TidyEnv
env1, _) <- TidyEnv -> CtOrigin -> TcM (TidyEnv, CtOrigin)
zonkTidyOrigin TidyEnv
tidy_orig (CtLoc -> CtOrigin
ctLocOrigin CtLoc
loc)
; TidyEnv -> [Id] -> [TcBinder] -> TcM [Id]
go TidyEnv
env1 [] ([TcBinder] -> [TcBinder]
forall a. HasOccName a => [a] -> [a]
removeBindingShadowing ([TcBinder] -> [TcBinder]) -> [TcBinder] -> [TcBinder]
forall a b. (a -> b) -> a -> b
$ TcLclEnv -> [TcBinder]
tcl_bndrs TcLclEnv
lcl_env) }
where
loc :: CtLoc
loc = CtEvidence -> CtLoc
ctEvLoc (Ct -> CtEvidence
ctEvidence Ct
ct)
lcl_env :: TcLclEnv
lcl_env = CtLoc -> TcLclEnv
ctLocEnv CtLoc
loc
go :: TidyEnv -> [Id] -> [TcBinder] -> TcM [Id]
go :: TidyEnv -> [Id] -> [TcBinder] -> TcM [Id]
go _ sofar :: [Id]
sofar [] = [Id] -> TcM [Id]
forall (m :: * -> *) a. Monad m => a -> m a
return ([Id] -> [Id]
forall a. [a] -> [a]
reverse [Id]
sofar)
go env :: TidyEnv
env sofar :: [Id]
sofar (tc_bndr :: TcBinder
tc_bndr : tc_bndrs :: [TcBinder]
tc_bndrs) =
case TcBinder
tc_bndr of
TcIdBndr id :: Id
id _ -> Id -> TcM [Id]
keep_it Id
id
_ -> TcM [Id]
discard_it
where
discard_it :: TcM [Id]
discard_it = TidyEnv -> [Id] -> [TcBinder] -> TcM [Id]
go TidyEnv
env [Id]
sofar [TcBinder]
tc_bndrs
keep_it :: Id -> TcM [Id]
keep_it id :: Id
id = TidyEnv -> [Id] -> [TcBinder] -> TcM [Id]
go TidyEnv
env (Id
idId -> [Id] -> [Id]
forall a. a -> [a] -> [a]
:[Id]
sofar) [TcBinder]
tc_bndrs
findValidHoleFits :: TidyEnv
-> [Implication]
-> [Ct]
-> Ct
-> TcM (TidyEnv, SDoc)
findValidHoleFits :: TidyEnv -> [Implication] -> [Ct] -> Ct -> TcM (TidyEnv, SDoc)
findValidHoleFits tidy_env :: TidyEnv
tidy_env implics :: [Implication]
implics simples :: [Ct]
simples ct :: Ct
ct | Ct -> Bool
isExprHoleCt Ct
ct =
do { GlobalRdrEnv
rdr_env <- TcRn GlobalRdrEnv
getGlobalRdrEnv
; [Id]
lclBinds <- TidyEnv -> Ct -> TcM [Id]
getLocalBindings TidyEnv
tidy_env Ct
ct
; Maybe Int
maxVSubs <- DynFlags -> Maybe Int
maxValidHoleFits (DynFlags -> Maybe Int)
-> IOEnv (Env TcGblEnv TcLclEnv) DynFlags
-> IOEnv (Env TcGblEnv TcLclEnv) (Maybe Int)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> IOEnv (Env TcGblEnv TcLclEnv) DynFlags
forall (m :: * -> *). HasDynFlags m => m DynFlags
getDynFlags
; HoleFitDispConfig
hfdc <- TcM HoleFitDispConfig
getHoleFitDispConfig
; SortingAlg
sortingAlg <- TcM SortingAlg
getSortingAlg
; let findVLimit :: Maybe Int
findVLimit = if SortingAlg
sortingAlg SortingAlg -> SortingAlg -> Bool
forall a. Ord a => a -> a -> Bool
> SortingAlg
NoSorting then Maybe Int
forall a. Maybe a
Nothing else Maybe Int
maxVSubs
; Maybe Int
refLevel <- DynFlags -> Maybe Int
refLevelHoleFits (DynFlags -> Maybe Int)
-> IOEnv (Env TcGblEnv TcLclEnv) DynFlags
-> IOEnv (Env TcGblEnv TcLclEnv) (Maybe Int)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> IOEnv (Env TcGblEnv TcLclEnv) DynFlags
forall (m :: * -> *). HasDynFlags m => m DynFlags
getDynFlags
; String -> SDoc -> TcRn ()
traceTc "findingValidHoleFitsFor { " (SDoc -> TcRn ()) -> SDoc -> TcRn ()
forall a b. (a -> b) -> a -> b
$ Ct -> SDoc
forall a. Outputable a => a -> SDoc
ppr Ct
ct
; String -> SDoc -> TcRn ()
traceTc "hole_lvl is:" (SDoc -> TcRn ()) -> SDoc -> TcRn ()
forall a b. (a -> b) -> a -> b
$ TcLevel -> SDoc
forall a. Outputable a => a -> SDoc
ppr TcLevel
hole_lvl
; String -> SDoc -> TcRn ()
traceTc "implics are: " (SDoc -> TcRn ()) -> SDoc -> TcRn ()
forall a b. (a -> b) -> a -> b
$ [Implication] -> SDoc
forall a. Outputable a => a -> SDoc
ppr [Implication]
implics
; String -> SDoc -> TcRn ()
traceTc "simples are: " (SDoc -> TcRn ()) -> SDoc -> TcRn ()
forall a b. (a -> b) -> a -> b
$ [Ct] -> SDoc
forall a. Outputable a => a -> SDoc
ppr [Ct]
simples
; String -> SDoc -> TcRn ()
traceTc "locals are: " (SDoc -> TcRn ()) -> SDoc -> TcRn ()
forall a b. (a -> b) -> a -> b
$ [Id] -> SDoc
forall a. Outputable a => a -> SDoc
ppr [Id]
lclBinds
; let (lcl :: [GlobalRdrElt]
lcl, gbl :: [GlobalRdrElt]
gbl) = (GlobalRdrElt -> Bool)
-> [GlobalRdrElt] -> ([GlobalRdrElt], [GlobalRdrElt])
forall a. (a -> Bool) -> [a] -> ([a], [a])
partition GlobalRdrElt -> Bool
gre_lcl (GlobalRdrEnv -> [GlobalRdrElt]
globalRdrEnvElts GlobalRdrEnv
rdr_env)
locals :: [HoleFitCandidate]
locals = [HoleFitCandidate] -> [HoleFitCandidate]
forall a. HasOccName a => [a] -> [a]
removeBindingShadowing ([HoleFitCandidate] -> [HoleFitCandidate])
-> [HoleFitCandidate] -> [HoleFitCandidate]
forall a b. (a -> b) -> a -> b
$
(Id -> HoleFitCandidate) -> [Id] -> [HoleFitCandidate]
forall a b. (a -> b) -> [a] -> [b]
map Id -> HoleFitCandidate
IdHFCand [Id]
lclBinds [HoleFitCandidate] -> [HoleFitCandidate] -> [HoleFitCandidate]
forall a. [a] -> [a] -> [a]
++ (GlobalRdrElt -> HoleFitCandidate)
-> [GlobalRdrElt] -> [HoleFitCandidate]
forall a b. (a -> b) -> [a] -> [b]
map GlobalRdrElt -> HoleFitCandidate
GreHFCand [GlobalRdrElt]
lcl
globals :: [HoleFitCandidate]
globals = (GlobalRdrElt -> HoleFitCandidate)
-> [GlobalRdrElt] -> [HoleFitCandidate]
forall a b. (a -> b) -> [a] -> [b]
map GlobalRdrElt -> HoleFitCandidate
GreHFCand [GlobalRdrElt]
gbl
syntax :: [HoleFitCandidate]
syntax = (Name -> HoleFitCandidate) -> [Name] -> [HoleFitCandidate]
forall a b. (a -> b) -> [a] -> [b]
map Name -> HoleFitCandidate
NameHFCand [Name]
builtIns
to_check :: [HoleFitCandidate]
to_check = [HoleFitCandidate]
locals [HoleFitCandidate] -> [HoleFitCandidate] -> [HoleFitCandidate]
forall a. [a] -> [a] -> [a]
++ [HoleFitCandidate]
syntax [HoleFitCandidate] -> [HoleFitCandidate] -> [HoleFitCandidate]
forall a. [a] -> [a] -> [a]
++ [HoleFitCandidate]
globals
; (searchDiscards :: Bool
searchDiscards, subs :: [HoleFit]
subs) <-
Maybe Int
-> [Implication]
-> [Ct]
-> (TcType, [Id])
-> [HoleFitCandidate]
-> TcM (Bool, [HoleFit])
tcFilterHoleFits Maybe Int
findVLimit [Implication]
implics [Ct]
relevantCts (TcType
hole_ty, []) [HoleFitCandidate]
to_check
; (tidy_env :: TidyEnv
tidy_env, tidy_subs :: [HoleFit]
tidy_subs) <- TidyEnv -> [HoleFit] -> TcM (TidyEnv, [HoleFit])
zonkSubs TidyEnv
tidy_env [HoleFit]
subs
; [HoleFit]
tidy_sorted_subs <- SortingAlg -> [HoleFit] -> TcM [HoleFit]
sortFits SortingAlg
sortingAlg [HoleFit]
tidy_subs
; let (pVDisc :: Bool
pVDisc, limited_subs :: [HoleFit]
limited_subs) = Maybe Int -> [HoleFit] -> (Bool, [HoleFit])
possiblyDiscard Maybe Int
maxVSubs [HoleFit]
tidy_sorted_subs
vDiscards :: Bool
vDiscards = Bool
pVDisc Bool -> Bool -> Bool
|| Bool
searchDiscards
; [HoleFit]
subs_with_docs <- [HoleFit] -> TcM [HoleFit]
addDocs [HoleFit]
limited_subs
; let vMsg :: SDoc
vMsg = Bool -> SDoc -> SDoc
ppUnless ([HoleFit] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [HoleFit]
subs_with_docs) (SDoc -> SDoc) -> SDoc -> SDoc
forall a b. (a -> b) -> a -> b
$
SDoc -> Int -> SDoc -> SDoc
hang (String -> SDoc
text "Valid hole fits include") 2 (SDoc -> SDoc) -> SDoc -> SDoc
forall a b. (a -> b) -> a -> b
$
[SDoc] -> SDoc
vcat ((HoleFit -> SDoc) -> [HoleFit] -> [SDoc]
forall a b. (a -> b) -> [a] -> [b]
map (HoleFitDispConfig -> HoleFit -> SDoc
pprHoleFit HoleFitDispConfig
hfdc) [HoleFit]
subs_with_docs)
SDoc -> SDoc -> SDoc
$$ Bool -> SDoc -> SDoc
ppWhen Bool
vDiscards SDoc
subsDiscardMsg
; (tidy_env :: TidyEnv
tidy_env, refMsg :: SDoc
refMsg) <- if Maybe Int
refLevel Maybe Int -> Maybe Int -> Bool
forall a. Ord a => a -> a -> Bool
>= Int -> Maybe Int
forall a. a -> Maybe a
Just 0 then
do { Maybe Int
maxRSubs <- DynFlags -> Maybe Int
maxRefHoleFits (DynFlags -> Maybe Int)
-> IOEnv (Env TcGblEnv TcLclEnv) DynFlags
-> IOEnv (Env TcGblEnv TcLclEnv) (Maybe Int)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> IOEnv (Env TcGblEnv TcLclEnv) DynFlags
forall (m :: * -> *). HasDynFlags m => m DynFlags
getDynFlags
; let refLvls :: [Int]
refLvls = [1..(Maybe Int -> Int
forall a. HasCallStack => Maybe a -> a
fromJust Maybe Int
refLevel)]
; [(TcType, [Id])]
ref_tys <- (Int -> IOEnv (Env TcGblEnv TcLclEnv) (TcType, [Id]))
-> [Int] -> IOEnv (Env TcGblEnv TcLclEnv) [(TcType, [Id])]
forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
mapM Int -> IOEnv (Env TcGblEnv TcLclEnv) (TcType, [Id])
mkRefTy [Int]
refLvls
; String -> SDoc -> TcRn ()
traceTc "ref_tys are" (SDoc -> TcRn ()) -> SDoc -> TcRn ()
forall a b. (a -> b) -> a -> b
$ [(TcType, [Id])] -> SDoc
forall a. Outputable a => a -> SDoc
ppr [(TcType, [Id])]
ref_tys
; let findRLimit :: Maybe Int
findRLimit = if SortingAlg
sortingAlg SortingAlg -> SortingAlg -> Bool
forall a. Ord a => a -> a -> Bool
> SortingAlg
NoSorting then Maybe Int
forall a. Maybe a
Nothing
else Maybe Int
maxRSubs
; [(Bool, [HoleFit])]
refDs <- ((TcType, [Id]) -> TcM (Bool, [HoleFit]))
-> [(TcType, [Id])]
-> IOEnv (Env TcGblEnv TcLclEnv) [(Bool, [HoleFit])]
forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
mapM (((TcType, [Id]) -> [HoleFitCandidate] -> TcM (Bool, [HoleFit]))
-> [HoleFitCandidate] -> (TcType, [Id]) -> TcM (Bool, [HoleFit])
forall a b c. (a -> b -> c) -> b -> a -> c
flip (Maybe Int
-> [Implication]
-> [Ct]
-> (TcType, [Id])
-> [HoleFitCandidate]
-> TcM (Bool, [HoleFit])
tcFilterHoleFits Maybe Int
findRLimit [Implication]
implics
[Ct]
relevantCts) [HoleFitCandidate]
to_check) [(TcType, [Id])]
ref_tys
; (tidy_env :: TidyEnv
tidy_env, tidy_rsubs :: [HoleFit]
tidy_rsubs) <- TidyEnv -> [HoleFit] -> TcM (TidyEnv, [HoleFit])
zonkSubs TidyEnv
tidy_env ([HoleFit] -> TcM (TidyEnv, [HoleFit]))
-> [HoleFit] -> TcM (TidyEnv, [HoleFit])
forall a b. (a -> b) -> a -> b
$ ((Bool, [HoleFit]) -> [HoleFit])
-> [(Bool, [HoleFit])] -> [HoleFit]
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap (Bool, [HoleFit]) -> [HoleFit]
forall a b. (a, b) -> b
snd [(Bool, [HoleFit])]
refDs
; [HoleFit]
tidy_sorted_rsubs <- SortingAlg -> [HoleFit] -> TcM [HoleFit]
sortFits SortingAlg
sortingAlg [HoleFit]
tidy_rsubs
; (tidy_env :: TidyEnv
tidy_env, tidy_hole_ty :: TcType
tidy_hole_ty) <- TidyEnv -> TcType -> TcM (TidyEnv, TcType)
zonkTidyTcType TidyEnv
tidy_env TcType
hole_ty
; let hasExactApp :: HoleFit -> Bool
hasExactApp = (TcType -> Bool) -> [TcType] -> Bool
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
any (HasDebugCallStack => TcType -> TcType -> Bool
TcType -> TcType -> Bool
tcEqType TcType
tidy_hole_ty) ([TcType] -> Bool) -> (HoleFit -> [TcType]) -> HoleFit -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. HoleFit -> [TcType]
hfWrap
(exact :: [HoleFit]
exact, not_exact :: [HoleFit]
not_exact) = (HoleFit -> Bool) -> [HoleFit] -> ([HoleFit], [HoleFit])
forall a. (a -> Bool) -> [a] -> ([a], [a])
partition HoleFit -> Bool
hasExactApp [HoleFit]
tidy_sorted_rsubs
(pRDisc :: Bool
pRDisc, exact_last_rfits :: [HoleFit]
exact_last_rfits) =
Maybe Int -> [HoleFit] -> (Bool, [HoleFit])
possiblyDiscard Maybe Int
maxRSubs ([HoleFit] -> (Bool, [HoleFit])) -> [HoleFit] -> (Bool, [HoleFit])
forall a b. (a -> b) -> a -> b
$ [HoleFit]
not_exact [HoleFit] -> [HoleFit] -> [HoleFit]
forall a. [a] -> [a] -> [a]
++ [HoleFit]
exact
rDiscards :: Bool
rDiscards = Bool
pRDisc Bool -> Bool -> Bool
|| ((Bool, [HoleFit]) -> Bool) -> [(Bool, [HoleFit])] -> Bool
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
any (Bool, [HoleFit]) -> Bool
forall a b. (a, b) -> a
fst [(Bool, [HoleFit])]
refDs
; [HoleFit]
rsubs_with_docs <- [HoleFit] -> TcM [HoleFit]
addDocs [HoleFit]
exact_last_rfits
; (TidyEnv, SDoc) -> TcM (TidyEnv, SDoc)
forall (m :: * -> *) a. Monad m => a -> m a
return (TidyEnv
tidy_env,
Bool -> SDoc -> SDoc
ppUnless ([HoleFit] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [HoleFit]
rsubs_with_docs) (SDoc -> SDoc) -> SDoc -> SDoc
forall a b. (a -> b) -> a -> b
$
SDoc -> Int -> SDoc -> SDoc
hang (String -> SDoc
text "Valid refinement hole fits include") 2 (SDoc -> SDoc) -> SDoc -> SDoc
forall a b. (a -> b) -> a -> b
$
[SDoc] -> SDoc
vcat ((HoleFit -> SDoc) -> [HoleFit] -> [SDoc]
forall a b. (a -> b) -> [a] -> [b]
map (HoleFitDispConfig -> HoleFit -> SDoc
pprHoleFit HoleFitDispConfig
hfdc) [HoleFit]
rsubs_with_docs)
SDoc -> SDoc -> SDoc
$$ Bool -> SDoc -> SDoc
ppWhen Bool
rDiscards SDoc
refSubsDiscardMsg) }
else (TidyEnv, SDoc) -> TcM (TidyEnv, SDoc)
forall (m :: * -> *) a. Monad m => a -> m a
return (TidyEnv
tidy_env, SDoc
empty)
; String -> SDoc -> TcRn ()
traceTc "findingValidHoleFitsFor }" SDoc
empty
; (TidyEnv, SDoc) -> TcM (TidyEnv, SDoc)
forall (m :: * -> *) a. Monad m => a -> m a
return (TidyEnv
tidy_env, SDoc
vMsg SDoc -> SDoc -> SDoc
$$ SDoc
refMsg) }
where
hole_ty :: TcPredType
hole_ty :: TcType
hole_ty = Ct -> TcType
ctPred Ct
ct
hole_fvs :: FV
hole_fvs :: FV
hole_fvs = TcType -> FV
tyCoFVsOfType TcType
hole_ty
hole_lvl :: TcLevel
hole_lvl = CtLoc -> TcLevel
ctLocLevel (CtLoc -> TcLevel) -> CtLoc -> TcLevel
forall a b. (a -> b) -> a -> b
$ CtEvidence -> CtLoc
ctEvLoc (CtEvidence -> CtLoc) -> CtEvidence -> CtLoc
forall a b. (a -> b) -> a -> b
$ Ct -> CtEvidence
ctEvidence Ct
ct
builtIns :: [Name]
builtIns :: [Name]
builtIns = (Name -> Bool) -> [Name] -> [Name]
forall a. (a -> Bool) -> [a] -> [a]
filter Name -> Bool
isBuiltInSyntax [Name]
knownKeyNames
mkRefTy :: Int -> TcM (TcType, [TcTyVar])
mkRefTy :: Int -> IOEnv (Env TcGblEnv TcLclEnv) (TcType, [Id])
mkRefTy refLvl :: Int
refLvl = ([Id] -> TcType
wrapWithVars ([Id] -> TcType) -> ([Id] -> [Id]) -> [Id] -> (TcType, [Id])
forall (a :: * -> * -> *) b c c'.
Arrow a =>
a b c -> a b c' -> a b (c, c')
&&& [Id] -> [Id]
forall a. a -> a
id) ([Id] -> (TcType, [Id]))
-> TcM [Id] -> IOEnv (Env TcGblEnv TcLclEnv) (TcType, [Id])
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> TcM [Id]
newTyVars
where newTyVars :: TcM [Id]
newTyVars = Int -> IOEnv (Env TcGblEnv TcLclEnv) Id -> TcM [Id]
forall (m :: * -> *) a. Applicative m => Int -> m a -> m [a]
replicateM Int
refLvl (IOEnv (Env TcGblEnv TcLclEnv) Id -> TcM [Id])
-> IOEnv (Env TcGblEnv TcLclEnv) Id -> TcM [Id]
forall a b. (a -> b) -> a -> b
$ Id -> Id
setLvl (Id -> Id)
-> IOEnv (Env TcGblEnv TcLclEnv) Id
-> IOEnv (Env TcGblEnv TcLclEnv) Id
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$>
(TcM TcType
newOpenTypeKind TcM TcType
-> (TcType -> IOEnv (Env TcGblEnv TcLclEnv) Id)
-> IOEnv (Env TcGblEnv TcLclEnv) Id
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= TcType -> IOEnv (Env TcGblEnv TcLclEnv) Id
newFlexiTyVar)
setLvl :: Id -> Id
setLvl = (Id -> TcLevel -> Id) -> TcLevel -> Id -> Id
forall a b c. (a -> b -> c) -> b -> a -> c
flip Id -> TcLevel -> Id
setMetaTyVarTcLevel TcLevel
hole_lvl
wrapWithVars :: [Id] -> TcType
wrapWithVars vars :: [Id]
vars = [TcType] -> TcType -> TcType
mkFunTys ((Id -> TcType) -> [Id] -> [TcType]
forall a b. (a -> b) -> [a] -> [b]
map Id -> TcType
mkTyVarTy [Id]
vars) TcType
hole_ty
sortFits :: SortingAlg
-> [HoleFit]
-> TcM [HoleFit]
sortFits :: SortingAlg -> [HoleFit] -> TcM [HoleFit]
sortFits NoSorting subs :: [HoleFit]
subs = [HoleFit] -> TcM [HoleFit]
forall (m :: * -> *) a. Monad m => a -> m a
return [HoleFit]
subs
sortFits BySize subs :: [HoleFit]
subs
= [HoleFit] -> [HoleFit] -> [HoleFit]
forall a. [a] -> [a] -> [a]
(++) ([HoleFit] -> [HoleFit] -> [HoleFit])
-> TcM [HoleFit]
-> IOEnv (Env TcGblEnv TcLclEnv) ([HoleFit] -> [HoleFit])
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> [HoleFit] -> TcM [HoleFit]
sortBySize ([HoleFit] -> [HoleFit]
forall a. Ord a => [a] -> [a]
sort [HoleFit]
lclFits)
IOEnv (Env TcGblEnv TcLclEnv) ([HoleFit] -> [HoleFit])
-> TcM [HoleFit] -> TcM [HoleFit]
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> [HoleFit] -> TcM [HoleFit]
sortBySize ([HoleFit] -> [HoleFit]
forall a. Ord a => [a] -> [a]
sort [HoleFit]
gblFits)
where (lclFits :: [HoleFit]
lclFits, gblFits :: [HoleFit]
gblFits) = (HoleFit -> Bool) -> [HoleFit] -> ([HoleFit], [HoleFit])
forall a. (a -> Bool) -> [a] -> ([a], [a])
span HoleFit -> Bool
hfIsLcl [HoleFit]
subs
sortFits BySubsumption subs :: [HoleFit]
subs
= [HoleFit] -> [HoleFit] -> [HoleFit]
forall a. [a] -> [a] -> [a]
(++) ([HoleFit] -> [HoleFit] -> [HoleFit])
-> TcM [HoleFit]
-> IOEnv (Env TcGblEnv TcLclEnv) ([HoleFit] -> [HoleFit])
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> [HoleFit] -> TcM [HoleFit]
sortByGraph ([HoleFit] -> [HoleFit]
forall a. Ord a => [a] -> [a]
sort [HoleFit]
lclFits)
IOEnv (Env TcGblEnv TcLclEnv) ([HoleFit] -> [HoleFit])
-> TcM [HoleFit] -> TcM [HoleFit]
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> [HoleFit] -> TcM [HoleFit]
sortByGraph ([HoleFit] -> [HoleFit]
forall a. Ord a => [a] -> [a]
sort [HoleFit]
gblFits)
where (lclFits :: [HoleFit]
lclFits, gblFits :: [HoleFit]
gblFits) = (HoleFit -> Bool) -> [HoleFit] -> ([HoleFit], [HoleFit])
forall a. (a -> Bool) -> [a] -> ([a], [a])
span HoleFit -> Bool
hfIsLcl [HoleFit]
subs
relevantCts :: [Ct]
relevantCts :: [Ct]
relevantCts = if VarSet -> Bool
isEmptyVarSet (FV -> VarSet
fvVarSet FV
hole_fvs) then []
else (Ct -> Bool) -> [Ct] -> [Ct]
forall a. (a -> Bool) -> [a] -> [a]
filter Ct -> Bool
isRelevant [Ct]
simples
where ctFreeVarSet :: Ct -> VarSet
ctFreeVarSet :: Ct -> VarSet
ctFreeVarSet = FV -> VarSet
fvVarSet (FV -> VarSet) -> (Ct -> FV) -> Ct -> VarSet
forall b c a. (b -> c) -> (a -> b) -> a -> c
. TcType -> FV
tyCoFVsOfType (TcType -> FV) -> (Ct -> TcType) -> Ct -> FV
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Ct -> TcType
ctPred
hole_fv_set :: VarSet
hole_fv_set = FV -> VarSet
fvVarSet FV
hole_fvs
anyFVMentioned :: Ct -> Bool
anyFVMentioned :: Ct -> Bool
anyFVMentioned ct :: Ct
ct = Bool -> Bool
not (Bool -> Bool) -> Bool -> Bool
forall a b. (a -> b) -> a -> b
$ VarSet -> Bool
isEmptyVarSet (VarSet -> Bool) -> VarSet -> Bool
forall a b. (a -> b) -> a -> b
$
Ct -> VarSet
ctFreeVarSet Ct
ct VarSet -> VarSet -> VarSet
`intersectVarSet` VarSet
hole_fv_set
isRelevant :: Ct -> Bool
isRelevant ct :: Ct
ct = Bool -> Bool
not (VarSet -> Bool
isEmptyVarSet (Ct -> VarSet
ctFreeVarSet Ct
ct))
Bool -> Bool -> Bool
&& Ct -> Bool
anyFVMentioned Ct
ct
Bool -> Bool -> Bool
&& Bool -> Bool
not (Ct -> Bool
isHoleCt Ct
ct)
zonkSubs :: TidyEnv -> [HoleFit] -> TcM (TidyEnv, [HoleFit])
zonkSubs :: TidyEnv -> [HoleFit] -> TcM (TidyEnv, [HoleFit])
zonkSubs = [HoleFit] -> TidyEnv -> [HoleFit] -> TcM (TidyEnv, [HoleFit])
zonkSubs' []
where zonkSubs' :: [HoleFit] -> TidyEnv -> [HoleFit] -> TcM (TidyEnv, [HoleFit])
zonkSubs' zs :: [HoleFit]
zs env :: TidyEnv
env [] = (TidyEnv, [HoleFit]) -> TcM (TidyEnv, [HoleFit])
forall (m :: * -> *) a. Monad m => a -> m a
return (TidyEnv
env, [HoleFit] -> [HoleFit]
forall a. [a] -> [a]
reverse [HoleFit]
zs)
zonkSubs' zs :: [HoleFit]
zs env :: TidyEnv
env (hf :: HoleFit
hf:hfs :: [HoleFit]
hfs) = do { (env' :: TidyEnv
env', z :: HoleFit
z) <- TidyEnv
-> HoleFit -> IOEnv (Env TcGblEnv TcLclEnv) (TidyEnv, HoleFit)
zonkSub TidyEnv
env HoleFit
hf
; [HoleFit] -> TidyEnv -> [HoleFit] -> TcM (TidyEnv, [HoleFit])
zonkSubs' (HoleFit
zHoleFit -> [HoleFit] -> [HoleFit]
forall a. a -> [a] -> [a]
:[HoleFit]
zs) TidyEnv
env' [HoleFit]
hfs }
zonkSub :: TidyEnv
-> HoleFit -> IOEnv (Env TcGblEnv TcLclEnv) (TidyEnv, HoleFit)
zonkSub env :: TidyEnv
env hf :: HoleFit
hf@HoleFit{hfType :: HoleFit -> TcType
hfType = TcType
ty, hfMatches :: HoleFit -> [TcType]
hfMatches = [TcType]
m, hfWrap :: HoleFit -> [TcType]
hfWrap = [TcType]
wrp}
= do { (env :: TidyEnv
env, ty' :: TcType
ty') <- TidyEnv -> TcType -> TcM (TidyEnv, TcType)
zonkTidyTcType TidyEnv
env TcType
ty
; (env :: TidyEnv
env, m' :: [TcType]
m') <- TidyEnv -> [TcType] -> TcM (TidyEnv, [TcType])
zonkTidyTcTypes TidyEnv
env [TcType]
m
; (env :: TidyEnv
env, wrp' :: [TcType]
wrp') <- TidyEnv -> [TcType] -> TcM (TidyEnv, [TcType])
zonkTidyTcTypes TidyEnv
env [TcType]
wrp
; let zFit :: HoleFit
zFit = HoleFit
hf {hfType :: TcType
hfType = TcType
ty', hfMatches :: [TcType]
hfMatches = [TcType]
m', hfWrap :: [TcType]
hfWrap = [TcType]
wrp'}
; (TidyEnv, HoleFit)
-> IOEnv (Env TcGblEnv TcLclEnv) (TidyEnv, HoleFit)
forall (m :: * -> *) a. Monad m => a -> m a
return (TidyEnv
env, HoleFit
zFit ) }
possiblyDiscard :: Maybe Int -> [HoleFit] -> (Bool, [HoleFit])
possiblyDiscard :: Maybe Int -> [HoleFit] -> (Bool, [HoleFit])
possiblyDiscard (Just max :: Int
max) fits :: [HoleFit]
fits = ([HoleFit]
fits [HoleFit] -> Int -> Bool
forall a. [a] -> Int -> Bool
`lengthExceeds` Int
max, Int -> [HoleFit] -> [HoleFit]
forall a. Int -> [a] -> [a]
take Int
max [HoleFit]
fits)
possiblyDiscard Nothing fits :: [HoleFit]
fits = (Bool
False, [HoleFit]
fits)
sortBySize :: [HoleFit] -> TcM [HoleFit]
sortBySize :: [HoleFit] -> TcM [HoleFit]
sortBySize = [HoleFit] -> TcM [HoleFit]
forall (m :: * -> *) a. Monad m => a -> m a
return ([HoleFit] -> TcM [HoleFit])
-> ([HoleFit] -> [HoleFit]) -> [HoleFit] -> TcM [HoleFit]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (HoleFit -> TypeSize) -> [HoleFit] -> [HoleFit]
forall b a. Ord b => (a -> b) -> [a] -> [a]
sortOn HoleFit -> TypeSize
sizeOfFit
where sizeOfFit :: HoleFit -> TypeSize
sizeOfFit :: HoleFit -> TypeSize
sizeOfFit = [TcType] -> TypeSize
sizeTypes ([TcType] -> TypeSize)
-> (HoleFit -> [TcType]) -> HoleFit -> TypeSize
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (TcType -> TcType -> Bool) -> [TcType] -> [TcType]
forall a. (a -> a -> Bool) -> [a] -> [a]
nubBy HasDebugCallStack => TcType -> TcType -> Bool
TcType -> TcType -> Bool
tcEqType ([TcType] -> [TcType])
-> (HoleFit -> [TcType]) -> HoleFit -> [TcType]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. HoleFit -> [TcType]
hfWrap
sortByGraph :: [HoleFit] -> TcM [HoleFit]
sortByGraph :: [HoleFit] -> TcM [HoleFit]
sortByGraph fits :: [HoleFit]
fits = [(HoleFit, [HoleFit])] -> [HoleFit] -> TcM [HoleFit]
go [] [HoleFit]
fits
where tcSubsumesWCloning :: TcType -> TcType -> TcM Bool
tcSubsumesWCloning :: TcType -> TcType -> TcRnIf TcGblEnv TcLclEnv Bool
tcSubsumesWCloning ht :: TcType
ht ty :: TcType
ty = FV
-> TcRnIf TcGblEnv TcLclEnv Bool -> TcRnIf TcGblEnv TcLclEnv Bool
forall a. FV -> TcM a -> TcM a
withoutUnification FV
fvs (TcType -> TcType -> TcRnIf TcGblEnv TcLclEnv Bool
tcSubsumes TcType
ht TcType
ty)
where fvs :: FV
fvs = [TcType] -> FV
tyCoFVsOfTypes [TcType
ht,TcType
ty]
go :: [(HoleFit, [HoleFit])] -> [HoleFit] -> TcM [HoleFit]
go :: [(HoleFit, [HoleFit])] -> [HoleFit] -> TcM [HoleFit]
go sofar :: [(HoleFit, [HoleFit])]
sofar [] = do { String -> SDoc -> TcRn ()
traceTc "subsumptionGraph was" (SDoc -> TcRn ()) -> SDoc -> TcRn ()
forall a b. (a -> b) -> a -> b
$ [(HoleFit, [HoleFit])] -> SDoc
forall a. Outputable a => a -> SDoc
ppr [(HoleFit, [HoleFit])]
sofar
; [HoleFit] -> TcM [HoleFit]
forall (m :: * -> *) a. Monad m => a -> m a
return ([HoleFit] -> TcM [HoleFit]) -> [HoleFit] -> TcM [HoleFit]
forall a b. (a -> b) -> a -> b
$ ([HoleFit] -> [HoleFit] -> [HoleFit])
-> ([HoleFit], [HoleFit]) -> [HoleFit]
forall a b c. (a -> b -> c) -> (a, b) -> c
uncurry [HoleFit] -> [HoleFit] -> [HoleFit]
forall a. [a] -> [a] -> [a]
(++)
(([HoleFit], [HoleFit]) -> [HoleFit])
-> ([HoleFit], [HoleFit]) -> [HoleFit]
forall a b. (a -> b) -> a -> b
$ (HoleFit -> Bool) -> [HoleFit] -> ([HoleFit], [HoleFit])
forall a. (a -> Bool) -> [a] -> ([a], [a])
partition HoleFit -> Bool
hfIsLcl [HoleFit]
topSorted }
where toV :: (HoleFit, [HoleFit]) -> (HoleFit, Id, [Id])
toV (hf :: HoleFit
hf, adjs :: [HoleFit]
adjs) = (HoleFit
hf, HoleFit -> Id
hfId HoleFit
hf, (HoleFit -> Id) -> [HoleFit] -> [Id]
forall a b. (a -> b) -> [a] -> [b]
map HoleFit -> Id
hfId [HoleFit]
adjs)
(graph :: Graph
graph, fromV :: Int -> (HoleFit, Id, [Id])
fromV, _) = [(HoleFit, Id, [Id])]
-> (Graph, Int -> (HoleFit, Id, [Id]), Id -> Maybe Int)
forall key node.
Ord key =>
[(node, key, [key])]
-> (Graph, Int -> (node, key, [key]), key -> Maybe Int)
graphFromEdges ([(HoleFit, Id, [Id])]
-> (Graph, Int -> (HoleFit, Id, [Id]), Id -> Maybe Int))
-> [(HoleFit, Id, [Id])]
-> (Graph, Int -> (HoleFit, Id, [Id]), Id -> Maybe Int)
forall a b. (a -> b) -> a -> b
$ ((HoleFit, [HoleFit]) -> (HoleFit, Id, [Id]))
-> [(HoleFit, [HoleFit])] -> [(HoleFit, Id, [Id])]
forall a b. (a -> b) -> [a] -> [b]
map (HoleFit, [HoleFit]) -> (HoleFit, Id, [Id])
toV [(HoleFit, [HoleFit])]
sofar
topSorted :: [HoleFit]
topSorted = (Int -> HoleFit) -> [Int] -> [HoleFit]
forall a b. (a -> b) -> [a] -> [b]
map ((\(h :: HoleFit
h,_,_) -> HoleFit
h) ((HoleFit, Id, [Id]) -> HoleFit)
-> (Int -> (HoleFit, Id, [Id])) -> Int -> HoleFit
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int -> (HoleFit, Id, [Id])
fromV) ([Int] -> [HoleFit]) -> [Int] -> [HoleFit]
forall a b. (a -> b) -> a -> b
$ Graph -> [Int]
topSort Graph
graph
go sofar :: [(HoleFit, [HoleFit])]
sofar (hf :: HoleFit
hf:hfs :: [HoleFit]
hfs) =
do { [HoleFit]
adjs <-
(HoleFit -> TcRnIf TcGblEnv TcLclEnv Bool)
-> [HoleFit] -> TcM [HoleFit]
forall (m :: * -> *) a.
Applicative m =>
(a -> m Bool) -> [a] -> m [a]
filterM (TcType -> TcType -> TcRnIf TcGblEnv TcLclEnv Bool
tcSubsumesWCloning (HoleFit -> TcType
hfType HoleFit
hf) (TcType -> TcRnIf TcGblEnv TcLclEnv Bool)
-> (HoleFit -> TcType) -> HoleFit -> TcRnIf TcGblEnv TcLclEnv Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. HoleFit -> TcType
hfType) [HoleFit]
fits
; [(HoleFit, [HoleFit])] -> [HoleFit] -> TcM [HoleFit]
go ((HoleFit
hf, [HoleFit]
adjs)(HoleFit, [HoleFit])
-> [(HoleFit, [HoleFit])] -> [(HoleFit, [HoleFit])]
forall a. a -> [a] -> [a]
:[(HoleFit, [HoleFit])]
sofar) [HoleFit]
hfs }
findValidHoleFits env :: TidyEnv
env _ _ _ = (TidyEnv, SDoc) -> TcM (TidyEnv, SDoc)
forall (m :: * -> *) a. Monad m => a -> m a
return (TidyEnv
env, SDoc
empty)
tcFilterHoleFits :: Maybe Int
-> [Implication]
-> [Ct]
-> (TcType, [TcTyVar])
-> [HoleFitCandidate]
-> TcM (Bool, [HoleFit])
tcFilterHoleFits :: Maybe Int
-> [Implication]
-> [Ct]
-> (TcType, [Id])
-> [HoleFitCandidate]
-> TcM (Bool, [HoleFit])
tcFilterHoleFits (Just 0) _ _ _ _ = (Bool, [HoleFit]) -> TcM (Bool, [HoleFit])
forall (m :: * -> *) a. Monad m => a -> m a
return (Bool
False, [])
tcFilterHoleFits limit :: Maybe Int
limit implics :: [Implication]
implics relevantCts :: [Ct]
relevantCts ht :: (TcType, [Id])
ht@(hole_ty :: TcType
hole_ty, _) candidates :: [HoleFitCandidate]
candidates =
do { String -> SDoc -> TcRn ()
traceTc "checkingFitsFor {" (SDoc -> TcRn ()) -> SDoc -> TcRn ()
forall a b. (a -> b) -> a -> b
$ TcType -> SDoc
forall a. Outputable a => a -> SDoc
ppr TcType
hole_ty
; (discards :: Bool
discards, subs :: [HoleFit]
subs) <- [HoleFit]
-> VarSet
-> Maybe Int
-> (TcType, [Id])
-> [HoleFitCandidate]
-> TcM (Bool, [HoleFit])
go [] VarSet
emptyVarSet Maybe Int
limit (TcType, [Id])
ht [HoleFitCandidate]
candidates
; String -> SDoc -> TcRn ()
traceTc "checkingFitsFor }" SDoc
empty
; (Bool, [HoleFit]) -> TcM (Bool, [HoleFit])
forall (m :: * -> *) a. Monad m => a -> m a
return (Bool
discards, [HoleFit]
subs) }
where
hole_fvs :: FV
hole_fvs :: FV
hole_fvs = TcType -> FV
tyCoFVsOfType TcType
hole_ty
go :: [HoleFit]
-> VarSet
-> Maybe Int
-> (TcType, [TcTyVar])
-> [HoleFitCandidate]
-> TcM (Bool, [HoleFit])
go :: [HoleFit]
-> VarSet
-> Maybe Int
-> (TcType, [Id])
-> [HoleFitCandidate]
-> TcM (Bool, [HoleFit])
go subs :: [HoleFit]
subs _ _ _ [] = (Bool, [HoleFit]) -> TcM (Bool, [HoleFit])
forall (m :: * -> *) a. Monad m => a -> m a
return (Bool
False, [HoleFit] -> [HoleFit]
forall a. [a] -> [a]
reverse [HoleFit]
subs)
go subs :: [HoleFit]
subs _ (Just 0) _ _ = (Bool, [HoleFit]) -> TcM (Bool, [HoleFit])
forall (m :: * -> *) a. Monad m => a -> m a
return (Bool
True, [HoleFit] -> [HoleFit]
forall a. [a] -> [a]
reverse [HoleFit]
subs)
go subs :: [HoleFit]
subs seen :: VarSet
seen maxleft :: Maybe Int
maxleft ty :: (TcType, [Id])
ty (el :: HoleFitCandidate
el:elts :: [HoleFitCandidate]
elts) =
TcM (Bool, [HoleFit])
-> TcM (Bool, [HoleFit]) -> TcM (Bool, [HoleFit])
forall r. TcM r -> TcM r -> TcM r
tryTcDiscardingErrs TcM (Bool, [HoleFit])
discard_it (TcM (Bool, [HoleFit]) -> TcM (Bool, [HoleFit]))
-> TcM (Bool, [HoleFit]) -> TcM (Bool, [HoleFit])
forall a b. (a -> b) -> a -> b
$
do { String -> SDoc -> TcRn ()
traceTc "lookingUp" (SDoc -> TcRn ()) -> SDoc -> TcRn ()
forall a b. (a -> b) -> a -> b
$ HoleFitCandidate -> SDoc
forall a. Outputable a => a -> SDoc
ppr HoleFitCandidate
el
; Maybe Id
maybeThing <- HoleFitCandidate -> TcM (Maybe Id)
lookup HoleFitCandidate
el
; case Maybe Id
maybeThing of
Just id :: Id
id | Id -> Bool
not_trivial Id
id ->
do { Maybe ([TcType], [TcType])
fits <- (TcType, [Id]) -> TcType -> TcM (Maybe ([TcType], [TcType]))
fitsHole (TcType, [Id])
ty (Id -> TcType
idType Id
id)
; case Maybe ([TcType], [TcType])
fits of
Just (wrp :: [TcType]
wrp, matches :: [TcType]
matches) -> Id -> [TcType] -> [TcType] -> TcM (Bool, [HoleFit])
keep_it Id
id [TcType]
wrp [TcType]
matches
_ -> TcM (Bool, [HoleFit])
discard_it }
_ -> TcM (Bool, [HoleFit])
discard_it }
where
not_trivial :: Id -> Bool
not_trivial id :: Id
id = Name -> Maybe Module
nameModule_maybe (Id -> Name
idName Id
id) Maybe Module -> Maybe Module -> Bool
forall a. Eq a => a -> a -> Bool
/= Module -> Maybe Module
forall a. a -> Maybe a
Just Module
gHC_ERR
lookup :: HoleFitCandidate -> TcM (Maybe Id)
lookup :: HoleFitCandidate -> TcM (Maybe Id)
lookup (IdHFCand id :: Id
id) = Maybe Id -> TcM (Maybe Id)
forall (m :: * -> *) a. Monad m => a -> m a
return (Id -> Maybe Id
forall a. a -> Maybe a
Just Id
id)
lookup hfc :: HoleFitCandidate
hfc = do { TcTyThing
thing <- Name -> TcM TcTyThing
tcLookup Name
name
; Maybe Id -> TcM (Maybe Id)
forall (m :: * -> *) a. Monad m => a -> m a
return (Maybe Id -> TcM (Maybe Id)) -> Maybe Id -> TcM (Maybe Id)
forall a b. (a -> b) -> a -> b
$ case TcTyThing
thing of
ATcId {tct_id :: TcTyThing -> Id
tct_id = Id
id} -> Id -> Maybe Id
forall a. a -> Maybe a
Just Id
id
AGlobal (AnId id :: Id
id) -> Id -> Maybe Id
forall a. a -> Maybe a
Just Id
id
AGlobal (AConLike (RealDataCon con :: DataCon
con)) ->
Id -> Maybe Id
forall a. a -> Maybe a
Just (DataCon -> Id
dataConWrapId DataCon
con)
_ -> Maybe Id
forall a. Maybe a
Nothing }
where name :: Name
name = case HoleFitCandidate
hfc of
IdHFCand id :: Id
id -> Id -> Name
idName Id
id
GreHFCand gre :: GlobalRdrElt
gre -> GlobalRdrElt -> Name
gre_name GlobalRdrElt
gre
NameHFCand name :: Name
name -> Name
name
discard_it :: TcM (Bool, [HoleFit])
discard_it = [HoleFit]
-> VarSet
-> Maybe Int
-> (TcType, [Id])
-> [HoleFitCandidate]
-> TcM (Bool, [HoleFit])
go [HoleFit]
subs VarSet
seen Maybe Int
maxleft (TcType, [Id])
ty [HoleFitCandidate]
elts
keep_it :: Id -> [TcType] -> [TcType] -> TcM (Bool, [HoleFit])
keep_it eid :: Id
eid wrp :: [TcType]
wrp ms :: [TcType]
ms = [HoleFit]
-> VarSet
-> Maybe Int
-> (TcType, [Id])
-> [HoleFitCandidate]
-> TcM (Bool, [HoleFit])
go (HoleFit
fitHoleFit -> [HoleFit] -> [HoleFit]
forall a. a -> [a] -> [a]
:[HoleFit]
subs) (VarSet -> Id -> VarSet
extendVarSet VarSet
seen Id
eid)
((\n :: Int
n -> Int
n Int -> Int -> Int
forall a. Num a => a -> a -> a
- 1) (Int -> Int) -> Maybe Int -> Maybe Int
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Maybe Int
maxleft) (TcType, [Id])
ty [HoleFitCandidate]
elts
where
fit :: HoleFit
fit = HoleFit :: Id
-> HoleFitCandidate
-> TcType
-> Int
-> [TcType]
-> [TcType]
-> Maybe HsDocString
-> HoleFit
HoleFit { hfId :: Id
hfId = Id
eid, hfCand :: HoleFitCandidate
hfCand = HoleFitCandidate
el, hfType :: TcType
hfType = (Id -> TcType
idType Id
eid)
, hfRefLvl :: Int
hfRefLvl = [Id] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length ((TcType, [Id]) -> [Id]
forall a b. (a, b) -> b
snd (TcType, [Id])
ty)
, hfWrap :: [TcType]
hfWrap = [TcType]
wrp, hfMatches :: [TcType]
hfMatches = [TcType]
ms
, hfDoc :: Maybe HsDocString
hfDoc = Maybe HsDocString
forall a. Maybe a
Nothing }
unfoldWrapper :: HsWrapper -> [Type]
unfoldWrapper :: HsWrapper -> [TcType]
unfoldWrapper = [TcType] -> [TcType]
forall a. [a] -> [a]
reverse ([TcType] -> [TcType])
-> (HsWrapper -> [TcType]) -> HsWrapper -> [TcType]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. HsWrapper -> [TcType]
unfWrp'
where unfWrp' :: HsWrapper -> [TcType]
unfWrp' (WpTyApp ty :: TcType
ty) = [TcType
ty]
unfWrp' (WpCompose w1 :: HsWrapper
w1 w2 :: HsWrapper
w2) = HsWrapper -> [TcType]
unfWrp' HsWrapper
w1 [TcType] -> [TcType] -> [TcType]
forall a. [a] -> [a] -> [a]
++ HsWrapper -> [TcType]
unfWrp' HsWrapper
w2
unfWrp' _ = []
fitsHole :: (TcType, [TcTyVar])
-> TcType
-> TcM (Maybe ([TcType], [TcType]))
fitsHole :: (TcType, [Id]) -> TcType -> TcM (Maybe ([TcType], [TcType]))
fitsHole (h_ty :: TcType
h_ty, ref_vars :: [Id]
ref_vars) ty :: TcType
ty =
FV
-> TcM (Maybe ([TcType], [TcType]))
-> TcM (Maybe ([TcType], [TcType]))
forall a. FV -> TcM a -> TcM a
withoutUnification FV
fvs (TcM (Maybe ([TcType], [TcType]))
-> TcM (Maybe ([TcType], [TcType])))
-> TcM (Maybe ([TcType], [TcType]))
-> TcM (Maybe ([TcType], [TcType]))
forall a b. (a -> b) -> a -> b
$
do { String -> SDoc -> TcRn ()
traceTc "checkingFitOf {" (SDoc -> TcRn ()) -> SDoc -> TcRn ()
forall a b. (a -> b) -> a -> b
$ TcType -> SDoc
forall a. Outputable a => a -> SDoc
ppr TcType
ty
; (fits :: Bool
fits, wrp :: HsWrapper
wrp) <- Cts -> [Implication] -> TcType -> TcType -> TcM (Bool, HsWrapper)
tcCheckHoleFit ([Ct] -> Cts
forall a. [a] -> Bag a
listToBag [Ct]
relevantCts) [Implication]
implics TcType
h_ty TcType
ty
; String -> SDoc -> TcRn ()
traceTc "Did it fit?" (SDoc -> TcRn ()) -> SDoc -> TcRn ()
forall a b. (a -> b) -> a -> b
$ Bool -> SDoc
forall a. Outputable a => a -> SDoc
ppr Bool
fits
; String -> SDoc -> TcRn ()
traceTc "wrap is: " (SDoc -> TcRn ()) -> SDoc -> TcRn ()
forall a b. (a -> b) -> a -> b
$ HsWrapper -> SDoc
forall a. Outputable a => a -> SDoc
ppr HsWrapper
wrp
; String -> SDoc -> TcRn ()
traceTc "checkingFitOf }" SDoc
empty
; [TcType]
z_wrp_tys <- [TcType] -> TcM [TcType]
zonkTcTypes (HsWrapper -> [TcType]
unfoldWrapper HsWrapper
wrp)
; if Bool
fits
then if [Id] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [Id]
ref_vars
then Maybe ([TcType], [TcType]) -> TcM (Maybe ([TcType], [TcType]))
forall (m :: * -> *) a. Monad m => a -> m a
return (([TcType], [TcType]) -> Maybe ([TcType], [TcType])
forall a. a -> Maybe a
Just ([TcType]
z_wrp_tys, []))
else do { let
fvSet :: VarSet
fvSet = FV -> VarSet
fvVarSet FV
fvs
notAbstract :: TcType -> Bool
notAbstract :: TcType -> Bool
notAbstract t :: TcType
t = case TcType -> Maybe Id
getTyVar_maybe TcType
t of
Just tv :: Id
tv -> Id
tv Id -> VarSet -> Bool
`elemVarSet` VarSet
fvSet
_ -> Bool
True
allConcrete :: Bool
allConcrete = (TcType -> Bool) -> [TcType] -> Bool
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
all TcType -> Bool
notAbstract [TcType]
z_wrp_tys
; [TcType]
z_vars <- [Id] -> TcM [TcType]
zonkTcTyVars [Id]
ref_vars
; let z_mtvs :: [Id]
z_mtvs = (TcType -> Maybe Id) -> [TcType] -> [Id]
forall a b. (a -> Maybe b) -> [a] -> [b]
mapMaybe TcType -> Maybe Id
tcGetTyVar_maybe [TcType]
z_vars
; Bool
allFilled <- Bool -> Bool
not (Bool -> Bool)
-> TcRnIf TcGblEnv TcLclEnv Bool -> TcRnIf TcGblEnv TcLclEnv Bool
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (Id -> TcRnIf TcGblEnv TcLclEnv Bool)
-> [Id] -> TcRnIf TcGblEnv TcLclEnv Bool
forall (m :: * -> *) a. Monad m => (a -> m Bool) -> [a] -> m Bool
anyM Id -> TcRnIf TcGblEnv TcLclEnv Bool
isFlexiTyVar [Id]
z_mtvs
; Bool
allowAbstract <- GeneralFlag -> TcRnIf TcGblEnv TcLclEnv Bool
forall gbl lcl. GeneralFlag -> TcRnIf gbl lcl Bool
goptM GeneralFlag
Opt_AbstractRefHoleFits
; if Bool
allowAbstract Bool -> Bool -> Bool
|| (Bool
allFilled Bool -> Bool -> Bool
&& Bool
allConcrete )
then Maybe ([TcType], [TcType]) -> TcM (Maybe ([TcType], [TcType]))
forall (m :: * -> *) a. Monad m => a -> m a
return (Maybe ([TcType], [TcType]) -> TcM (Maybe ([TcType], [TcType])))
-> Maybe ([TcType], [TcType]) -> TcM (Maybe ([TcType], [TcType]))
forall a b. (a -> b) -> a -> b
$ ([TcType], [TcType]) -> Maybe ([TcType], [TcType])
forall a. a -> Maybe a
Just ([TcType]
z_wrp_tys, [TcType]
z_vars)
else Maybe ([TcType], [TcType]) -> TcM (Maybe ([TcType], [TcType]))
forall (m :: * -> *) a. Monad m => a -> m a
return Maybe ([TcType], [TcType])
forall a. Maybe a
Nothing }
else Maybe ([TcType], [TcType]) -> TcM (Maybe ([TcType], [TcType]))
forall (m :: * -> *) a. Monad m => a -> m a
return Maybe ([TcType], [TcType])
forall a. Maybe a
Nothing }
where fvs :: FV
fvs = [Id] -> FV
mkFVs [Id]
ref_vars FV -> FV -> FV
`unionFV` FV
hole_fvs FV -> FV -> FV
`unionFV` TcType -> FV
tyCoFVsOfType TcType
ty
subsDiscardMsg :: SDoc
subsDiscardMsg :: SDoc
subsDiscardMsg =
String -> SDoc
text "(Some hole fits suppressed;" SDoc -> SDoc -> SDoc
<+>
String -> SDoc
text "use -fmax-valid-hole-fits=N" SDoc -> SDoc -> SDoc
<+>
String -> SDoc
text "or -fno-max-valid-hole-fits)"
refSubsDiscardMsg :: SDoc
refSubsDiscardMsg :: SDoc
refSubsDiscardMsg =
String -> SDoc
text "(Some refinement hole fits suppressed;" SDoc -> SDoc -> SDoc
<+>
String -> SDoc
text "use -fmax-refinement-hole-fits=N" SDoc -> SDoc -> SDoc
<+>
String -> SDoc
text "or -fno-max-refinement-hole-fits)"
isFlexiTyVar :: TcTyVar -> TcM Bool
isFlexiTyVar :: Id -> TcRnIf TcGblEnv TcLclEnv Bool
isFlexiTyVar tv :: Id
tv | Id -> Bool
isMetaTyVar Id
tv = MetaDetails -> Bool
isFlexi (MetaDetails -> Bool)
-> IOEnv (Env TcGblEnv TcLclEnv) MetaDetails
-> TcRnIf TcGblEnv TcLclEnv Bool
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Id -> IOEnv (Env TcGblEnv TcLclEnv) MetaDetails
readMetaTyVar Id
tv
isFlexiTyVar _ = Bool -> TcRnIf TcGblEnv TcLclEnv Bool
forall (m :: * -> *) a. Monad m => a -> m a
return Bool
False
withoutUnification :: FV -> TcM a -> TcM a
withoutUnification :: FV -> TcM a -> TcM a
withoutUnification free_vars :: FV
free_vars action :: TcM a
action =
do { [Id]
flexis <- (Id -> TcRnIf TcGblEnv TcLclEnv Bool) -> [Id] -> TcM [Id]
forall (m :: * -> *) a.
Applicative m =>
(a -> m Bool) -> [a] -> m [a]
filterM Id -> TcRnIf TcGblEnv TcLclEnv Bool
isFlexiTyVar [Id]
fuvs
; a
result <- TcM a
action
; (Id -> TcRn ()) -> [Id] -> TcRn ()
forall (t :: * -> *) (m :: * -> *) a b.
(Foldable t, Monad m) =>
(a -> m b) -> t a -> m ()
mapM_ Id -> TcRn ()
forall gbl lcl. Id -> TcRnIf gbl lcl ()
restore [Id]
flexis
; a -> TcM a
forall (m :: * -> *) a. Monad m => a -> m a
return a
result }
where restore :: Id -> TcRnIf gbl lcl ()
restore = (TcRef MetaDetails -> MetaDetails -> TcRnIf gbl lcl ())
-> MetaDetails -> TcRef MetaDetails -> TcRnIf gbl lcl ()
forall a b c. (a -> b -> c) -> b -> a -> c
flip TcRef MetaDetails -> MetaDetails -> TcRnIf gbl lcl ()
forall a gbl lcl. TcRef a -> a -> TcRnIf gbl lcl ()
writeTcRef MetaDetails
Flexi (TcRef MetaDetails -> TcRnIf gbl lcl ())
-> (Id -> TcRef MetaDetails) -> Id -> TcRnIf gbl lcl ()
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Id -> TcRef MetaDetails
metaTyVarRef
fuvs :: [Id]
fuvs = FV -> [Id]
fvVarList FV
free_vars
tcSubsumes :: TcSigmaType -> TcSigmaType -> TcM Bool
tcSubsumes :: TcType -> TcType -> TcRnIf TcGblEnv TcLclEnv Bool
tcSubsumes ty_a :: TcType
ty_a ty_b :: TcType
ty_b = (Bool, HsWrapper) -> Bool
forall a b. (a, b) -> a
fst ((Bool, HsWrapper) -> Bool)
-> TcM (Bool, HsWrapper) -> TcRnIf TcGblEnv TcLclEnv Bool
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Cts -> [Implication] -> TcType -> TcType -> TcM (Bool, HsWrapper)
tcCheckHoleFit Cts
forall a. Bag a
emptyBag [] TcType
ty_a TcType
ty_b
tcCheckHoleFit :: Cts
-> [Implication]
-> TcSigmaType
-> TcSigmaType
-> TcM (Bool, HsWrapper)
tcCheckHoleFit :: Cts -> [Implication] -> TcType -> TcType -> TcM (Bool, HsWrapper)
tcCheckHoleFit _ _ hole_ty :: TcType
hole_ty ty :: TcType
ty | TcType
hole_ty TcType -> TcType -> Bool
`eqType` TcType
ty
= (Bool, HsWrapper) -> TcM (Bool, HsWrapper)
forall (m :: * -> *) a. Monad m => a -> m a
return (Bool
True, HsWrapper
idHsWrapper)
tcCheckHoleFit relevantCts :: Cts
relevantCts implics :: [Implication]
implics hole_ty :: TcType
hole_ty ty :: TcType
ty = TcM (Bool, HsWrapper) -> TcM (Bool, HsWrapper)
forall a. TcRn a -> TcRn a
discardErrs (TcM (Bool, HsWrapper) -> TcM (Bool, HsWrapper))
-> TcM (Bool, HsWrapper) -> TcM (Bool, HsWrapper)
forall a b. (a -> b) -> a -> b
$
do {
TcLevel
innermost_lvl <- case [Implication]
implics of
[] -> TcM TcLevel
getTcLevel
(imp :: Implication
imp:_) -> TcLevel -> TcM TcLevel
forall (m :: * -> *) a. Monad m => a -> m a
return (Implication -> TcLevel
ic_tclvl Implication
imp)
; (wrp :: HsWrapper
wrp, wanted :: WantedConstraints
wanted) <- TcLevel
-> TcM (HsWrapper, WantedConstraints)
-> TcM (HsWrapper, WantedConstraints)
forall a. TcLevel -> TcM a -> TcM a
setTcLevel TcLevel
innermost_lvl (TcM (HsWrapper, WantedConstraints)
-> TcM (HsWrapper, WantedConstraints))
-> TcM (HsWrapper, WantedConstraints)
-> TcM (HsWrapper, WantedConstraints)
forall a b. (a -> b) -> a -> b
$ TcM HsWrapper -> TcM (HsWrapper, WantedConstraints)
forall a. TcM a -> TcM (a, WantedConstraints)
captureConstraints (TcM HsWrapper -> TcM (HsWrapper, WantedConstraints))
-> TcM HsWrapper -> TcM (HsWrapper, WantedConstraints)
forall a b. (a -> b) -> a -> b
$
UserTypeCtxt -> TcType -> TcType -> TcM HsWrapper
tcSubType_NC UserTypeCtxt
ExprSigCtxt TcType
ty TcType
hole_ty
; String -> SDoc -> TcRn ()
traceTc "Checking hole fit {" SDoc
empty
; String -> SDoc -> TcRn ()
traceTc "wanteds are: " (SDoc -> TcRn ()) -> SDoc -> TcRn ()
forall a b. (a -> b) -> a -> b
$ WantedConstraints -> SDoc
forall a. Outputable a => a -> SDoc
ppr WantedConstraints
wanted
; if WantedConstraints -> Bool
isEmptyWC WantedConstraints
wanted Bool -> Bool -> Bool
&& Cts -> Bool
forall a. Bag a -> Bool
isEmptyBag Cts
relevantCts
then String -> SDoc -> TcRn ()
traceTc "}" SDoc
empty TcRn () -> TcM (Bool, HsWrapper) -> TcM (Bool, HsWrapper)
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> (Bool, HsWrapper) -> TcM (Bool, HsWrapper)
forall (m :: * -> *) a. Monad m => a -> m a
return (Bool
True, HsWrapper
wrp)
else do { EvBindsVar
fresh_binds <- TcM EvBindsVar
newTcEvBinds
; Cts
cloned_relevants <- (Ct -> IOEnv (Env TcGblEnv TcLclEnv) Ct)
-> Cts -> IOEnv (Env TcGblEnv TcLclEnv) Cts
forall (m :: * -> *) a b.
Monad m =>
(a -> m b) -> Bag a -> m (Bag b)
mapBagM Ct -> IOEnv (Env TcGblEnv TcLclEnv) Ct
cloneWanted Cts
relevantCts
; let outermost_first :: [Implication]
outermost_first = [Implication] -> [Implication]
forall a. [a] -> [a]
reverse [Implication]
implics
setWC :: Implication -> WantedConstraints -> WantedConstraints
setWC = EvBindsVar -> Implication -> WantedConstraints -> WantedConstraints
setWCAndBinds EvBindsVar
fresh_binds
w_rel_cts :: WantedConstraints
w_rel_cts = WantedConstraints -> Cts -> WantedConstraints
addSimples WantedConstraints
wanted Cts
cloned_relevants
w_givens :: WantedConstraints
w_givens = (Implication -> WantedConstraints -> WantedConstraints)
-> WantedConstraints -> [Implication] -> WantedConstraints
forall (t :: * -> *) a b.
Foldable t =>
(a -> b -> b) -> b -> t a -> b
foldr Implication -> WantedConstraints -> WantedConstraints
setWC WantedConstraints
w_rel_cts [Implication]
outermost_first
; String -> SDoc -> TcRn ()
traceTc "w_givens are: " (SDoc -> TcRn ()) -> SDoc -> TcRn ()
forall a b. (a -> b) -> a -> b
$ WantedConstraints -> SDoc
forall a. Outputable a => a -> SDoc
ppr WantedConstraints
w_givens
; WantedConstraints
rem <- TcS WantedConstraints -> TcM WantedConstraints
forall a. TcS a -> TcM a
runTcSDeriveds (TcS WantedConstraints -> TcM WantedConstraints)
-> TcS WantedConstraints -> TcM WantedConstraints
forall a b. (a -> b) -> a -> b
$ WantedConstraints -> TcS WantedConstraints
simpl_top WantedConstraints
w_givens
; String -> SDoc -> TcRn ()
traceTc "rems was:" (SDoc -> TcRn ()) -> SDoc -> TcRn ()
forall a b. (a -> b) -> a -> b
$ WantedConstraints -> SDoc
forall a. Outputable a => a -> SDoc
ppr WantedConstraints
rem
; String -> SDoc -> TcRn ()
traceTc "}" SDoc
empty
; (Bool, HsWrapper) -> TcM (Bool, HsWrapper)
forall (m :: * -> *) a. Monad m => a -> m a
return (WantedConstraints -> Bool
isSolvedWC WantedConstraints
rem, HsWrapper
wrp) } }
where
setWCAndBinds :: EvBindsVar
-> Implication
-> WantedConstraints
-> WantedConstraints
setWCAndBinds :: EvBindsVar -> Implication -> WantedConstraints -> WantedConstraints
setWCAndBinds binds :: EvBindsVar
binds imp :: Implication
imp wc :: WantedConstraints
wc
= WC :: Cts -> Bag Implication -> WantedConstraints
WC { wc_simple :: Cts
wc_simple = Cts
forall a. Bag a
emptyBag
, wc_impl :: Bag Implication
wc_impl = Implication -> Bag Implication
forall a. a -> Bag a
unitBag (Implication -> Bag Implication) -> Implication -> Bag Implication
forall a b. (a -> b) -> a -> b
$ Implication
imp { ic_wanted :: WantedConstraints
ic_wanted = WantedConstraints
wc , ic_binds :: EvBindsVar
ic_binds = EvBindsVar
binds } }