{-# LANGUAGE ExistentialQuantification #-}
module GHC.Tc.Errors.Hole.FitTypes (
TypedHole (..), HoleFit (..), HoleFitCandidate (..),
CandPlugin, FitPlugin, HoleFitPlugin (..), HoleFitPluginR (..),
hfIsLcl, pprHoleFitCand
) where
import GHC.Prelude
import GHC.Tc.Types
import GHC.Tc.Types.Constraint
import GHC.Tc.Utils.TcType
import GHC.Types.Name.Reader
import GHC.Hs.Doc
import GHC.Types.Id
import GHC.Utils.Outputable
import GHC.Types.Name
import Data.Function ( on )
data TypedHole = TypedHole { TypedHole -> Cts
th_relevant_cts :: Cts
, TypedHole -> [Implication]
th_implics :: [Implication]
, TypedHole -> Maybe Hole
th_hole :: Maybe Hole
}
instance Outputable TypedHole where
ppr :: TypedHole -> SDoc
ppr (TypedHole { th_relevant_cts :: TypedHole -> Cts
th_relevant_cts = Cts
rels
, th_implics :: TypedHole -> [Implication]
th_implics = [Implication]
implics
, th_hole :: TypedHole -> Maybe Hole
th_hole = Maybe Hole
hole })
= SDoc -> Int -> SDoc -> SDoc
hang (String -> SDoc
text String
"TypedHole") Int
2
(forall a. Outputable a => a -> SDoc
ppr Cts
rels SDoc -> SDoc -> SDoc
$+$ forall a. Outputable a => a -> SDoc
ppr [Implication]
implics SDoc -> SDoc -> SDoc
$+$ forall a. Outputable a => a -> SDoc
ppr Maybe Hole
hole)
data HoleFitCandidate = IdHFCand Id
| NameHFCand Name
| GreHFCand GlobalRdrElt
deriving (HoleFitCandidate -> HoleFitCandidate -> Bool
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
cid) = String -> SDoc
text String
"Id HFC: " SDoc -> SDoc -> SDoc
<> forall a. Outputable a => a -> SDoc
ppr Id
cid
pprHoleFitCand (NameHFCand Name
cname) = String -> SDoc
text String
"Name HFC: " SDoc -> SDoc -> SDoc
<> forall a. Outputable a => a -> SDoc
ppr Name
cname
pprHoleFitCand (GreHFCand GlobalRdrElt
cgre) = String -> SDoc
text String
"Gre HFC: " SDoc -> SDoc -> SDoc
<> forall a. Outputable a => a -> SDoc
ppr GlobalRdrElt
cgre
instance NamedThing HoleFitCandidate where
getName :: HoleFitCandidate -> Name
getName HoleFitCandidate
hfc = case HoleFitCandidate
hfc of
IdHFCand Id
cid -> Id -> Name
idName Id
cid
NameHFCand Name
cname -> Name
cname
GreHFCand GlobalRdrElt
cgre -> GlobalRdrElt -> Name
greMangledName GlobalRdrElt
cgre
getOccName :: HoleFitCandidate -> OccName
getOccName HoleFitCandidate
hfc = case HoleFitCandidate
hfc of
IdHFCand Id
cid -> forall name. HasOccName name => name -> OccName
occName Id
cid
NameHFCand Name
cname -> forall name. HasOccName name => name -> OccName
occName Name
cname
GreHFCand GlobalRdrElt
cgre -> forall name. HasOccName name => name -> OccName
occName (GlobalRdrElt -> Name
greMangledName GlobalRdrElt
cgre)
instance HasOccName HoleFitCandidate where
occName :: HoleFitCandidate -> OccName
occName = forall a. NamedThing a => a -> OccName
getOccName
instance Ord HoleFitCandidate where
compare :: HoleFitCandidate -> HoleFitCandidate -> Ordering
compare = forall a. Ord a => a -> a -> Ordering
compare forall b c a. (b -> b -> c) -> (a -> b) -> a -> a -> c
`on` forall a. NamedThing a => a -> Name
getName
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
}
| RawHoleFit SDoc
instance Eq HoleFit where
== :: HoleFit -> HoleFit -> Bool
(==) = forall a. Eq a => a -> a -> Bool
(==) forall b c a. (b -> b -> c) -> (a -> b) -> a -> a -> c
`on` HoleFit -> Id
hfId
instance Outputable HoleFit where
ppr :: HoleFit -> SDoc
ppr (RawHoleFit SDoc
sd) = SDoc
sd
ppr (HoleFit Id
_ HoleFitCandidate
cand TcType
ty Int
_ [TcType]
_ [TcType]
mtchs Maybe HsDocString
_) =
SDoc -> Int -> SDoc -> SDoc
hang (SDoc
name SDoc -> SDoc -> SDoc
<+> SDoc
holes) Int
2 (String -> SDoc
text String
"where" SDoc -> SDoc -> SDoc
<+> SDoc
name SDoc -> SDoc -> SDoc
<+> SDoc
dcolon SDoc -> SDoc -> SDoc
<+> (forall a. Outputable a => a -> SDoc
ppr TcType
ty))
where name :: SDoc
name = forall a. Outputable a => a -> SDoc
ppr forall a b. (a -> b) -> a -> b
$ forall a. NamedThing a => a -> Name
getName HoleFitCandidate
cand
holes :: SDoc
holes = [SDoc] -> SDoc
sep forall a b. (a -> b) -> a -> b
$ forall a b. (a -> b) -> [a] -> [b]
map (SDoc -> SDoc
parens forall b c a. (b -> c) -> (a -> b) -> a -> c
. (String -> SDoc
text String
"_" SDoc -> SDoc -> SDoc
<+> SDoc
dcolon SDoc -> SDoc -> SDoc
<+>) forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. Outputable a => a -> SDoc
ppr) [TcType]
mtchs
instance Ord HoleFit where
compare :: HoleFit -> HoleFit -> Ordering
compare (RawHoleFit SDoc
_) (RawHoleFit SDoc
_) = Ordering
EQ
compare (RawHoleFit SDoc
_) HoleFit
_ = Ordering
LT
compare HoleFit
_ (RawHoleFit SDoc
_) = Ordering
GT
compare a :: HoleFit
a@(HoleFit {}) b :: HoleFit
b@(HoleFit {}) = HoleFit -> HoleFit -> Ordering
cmp HoleFit
a HoleFit
b
where cmp :: HoleFit -> HoleFit -> Ordering
cmp = if HoleFit -> Int
hfRefLvl HoleFit
a forall a. Eq a => a -> a -> Bool
== HoleFit -> Int
hfRefLvl HoleFit
b
then forall a. Ord a => a -> a -> Ordering
compare forall b c a. (b -> b -> c) -> (a -> b) -> a -> a -> c
`on` (forall a. NamedThing a => a -> Name
getName forall b c a. (b -> c) -> (a -> b) -> a -> c
. HoleFit -> HoleFitCandidate
hfCand)
else forall a. Ord a => a -> a -> Ordering
compare forall b c a. (b -> b -> c) -> (a -> b) -> a -> a -> c
`on` HoleFit -> Int
hfRefLvl
hfIsLcl :: HoleFit -> Bool
hfIsLcl :: HoleFit -> Bool
hfIsLcl hf :: HoleFit
hf@(HoleFit {}) = case HoleFit -> HoleFitCandidate
hfCand HoleFit
hf of
IdHFCand Id
_ -> Bool
True
NameHFCand Name
_ -> Bool
False
GreHFCand GlobalRdrElt
gre -> GlobalRdrElt -> Bool
gre_lcl GlobalRdrElt
gre
hfIsLcl HoleFit
_ = Bool
False
type CandPlugin = TypedHole -> [HoleFitCandidate] -> TcM [HoleFitCandidate]
type FitPlugin = TypedHole -> [HoleFit] -> TcM [HoleFit]
data HoleFitPlugin = HoleFitPlugin
{ HoleFitPlugin -> CandPlugin
candPlugin :: CandPlugin
, HoleFitPlugin -> FitPlugin
fitPlugin :: FitPlugin }
data HoleFitPluginR = forall s. HoleFitPluginR
{ ()
hfPluginInit :: TcM (TcRef s)
, ()
hfPluginRun :: TcRef s -> HoleFitPlugin
, ()
hfPluginStop :: TcRef s -> TcM ()
}