{-# LANGUAGE CPP #-}
module GHC.Core.PatSyn (
PatSyn, mkPatSyn,
patSynName, patSynArity, patSynIsInfix,
patSynArgs,
patSynMatcher, patSynBuilder,
patSynUnivTyVarBinders, patSynExTyVars, patSynExTyVarBinders,
patSynSig, patSynSigBndr,
patSynInstArgTys, patSynInstResTy, patSynFieldLabels,
patSynFieldType,
updatePatSynIds, pprPatSynType
) where
#include "HsVersions.h"
import GHC.Prelude
import GHC.Core.Type
import GHC.Core.TyCo.Ppr
import GHC.Types.Name
import GHC.Utils.Outputable
import GHC.Types.Unique
import GHC.Utils.Misc
import GHC.Types.Basic
import GHC.Types.Var
import GHC.Types.FieldLabel
import qualified Data.Data as Data
import Data.Function
import Data.List (find)
data PatSyn
= MkPatSyn {
PatSyn -> Name
psName :: Name,
PatSyn -> Unique
psUnique :: Unique,
PatSyn -> [Type]
psArgs :: [Type],
PatSyn -> Arity
psArity :: Arity,
PatSyn -> Bool
psInfix :: Bool,
PatSyn -> [FieldLabel]
psFieldLabels :: [FieldLabel],
PatSyn -> [InvisTVBinder]
psUnivTyVars :: [InvisTVBinder],
PatSyn -> [Type]
psReqTheta :: ThetaType,
PatSyn -> [InvisTVBinder]
psExTyVars :: [InvisTVBinder],
PatSyn -> [Type]
psProvTheta :: ThetaType,
PatSyn -> Type
psResultTy :: Type,
PatSyn -> (TyVar, Bool)
psMatcher :: (Id, Bool),
PatSyn -> Maybe (TyVar, Bool)
psBuilder :: Maybe (Id, Bool)
}
instance Eq PatSyn where
== :: PatSyn -> PatSyn -> Bool
(==) = Unique -> Unique -> Bool
forall a. Eq a => a -> a -> Bool
(==) (Unique -> Unique -> Bool)
-> (PatSyn -> Unique) -> PatSyn -> PatSyn -> Bool
forall b c a. (b -> b -> c) -> (a -> b) -> a -> a -> c
`on` PatSyn -> Unique
forall a. Uniquable a => a -> Unique
getUnique
/= :: PatSyn -> PatSyn -> Bool
(/=) = Unique -> Unique -> Bool
forall a. Eq a => a -> a -> Bool
(/=) (Unique -> Unique -> Bool)
-> (PatSyn -> Unique) -> PatSyn -> PatSyn -> Bool
forall b c a. (b -> b -> c) -> (a -> b) -> a -> a -> c
`on` PatSyn -> Unique
forall a. Uniquable a => a -> Unique
getUnique
instance Uniquable PatSyn where
getUnique :: PatSyn -> Unique
getUnique = PatSyn -> Unique
psUnique
instance NamedThing PatSyn where
getName :: PatSyn -> Name
getName = PatSyn -> Name
patSynName
instance Outputable PatSyn where
ppr :: PatSyn -> SDoc
ppr = Name -> SDoc
forall a. Outputable a => a -> SDoc
ppr (Name -> SDoc) -> (PatSyn -> Name) -> PatSyn -> SDoc
forall b c a. (b -> c) -> (a -> b) -> a -> c
. PatSyn -> Name
forall a. NamedThing a => a -> Name
getName
instance OutputableBndr PatSyn where
pprInfixOcc :: PatSyn -> SDoc
pprInfixOcc = Name -> SDoc
forall a. (Outputable a, NamedThing a) => a -> SDoc
pprInfixName (Name -> SDoc) -> (PatSyn -> Name) -> PatSyn -> SDoc
forall b c a. (b -> c) -> (a -> b) -> a -> c
. PatSyn -> Name
forall a. NamedThing a => a -> Name
getName
pprPrefixOcc :: PatSyn -> SDoc
pprPrefixOcc = Name -> SDoc
forall a. NamedThing a => a -> SDoc
pprPrefixName (Name -> SDoc) -> (PatSyn -> Name) -> PatSyn -> SDoc
forall b c a. (b -> c) -> (a -> b) -> a -> c
. PatSyn -> Name
forall a. NamedThing a => a -> Name
getName
instance Data.Data PatSyn where
toConstr :: PatSyn -> Constr
toConstr PatSyn
_ = String -> Constr
abstractConstr String
"PatSyn"
gunfold :: forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c PatSyn
gunfold forall b r. Data b => c (b -> r) -> c r
_ forall r. r -> c r
_ = String -> Constr -> c PatSyn
forall a. HasCallStack => String -> a
error String
"gunfold"
dataTypeOf :: PatSyn -> DataType
dataTypeOf PatSyn
_ = String -> DataType
mkNoRepType String
"PatSyn"
mkPatSyn :: Name
-> Bool
-> ([InvisTVBinder], ThetaType)
-> ([InvisTVBinder], ThetaType)
-> [Type]
-> Type
-> (Id, Bool)
-> Maybe (Id, Bool)
-> [FieldLabel]
-> PatSyn
mkPatSyn :: Name
-> Bool
-> ([InvisTVBinder], [Type])
-> ([InvisTVBinder], [Type])
-> [Type]
-> Type
-> (TyVar, Bool)
-> Maybe (TyVar, Bool)
-> [FieldLabel]
-> PatSyn
mkPatSyn Name
name Bool
declared_infix
([InvisTVBinder]
univ_tvs, [Type]
req_theta)
([InvisTVBinder]
ex_tvs, [Type]
prov_theta)
[Type]
orig_args
Type
orig_res_ty
(TyVar, Bool)
matcher Maybe (TyVar, Bool)
builder [FieldLabel]
field_labels
= MkPatSyn :: Name
-> Unique
-> [Type]
-> Arity
-> Bool
-> [FieldLabel]
-> [InvisTVBinder]
-> [Type]
-> [InvisTVBinder]
-> [Type]
-> Type
-> (TyVar, Bool)
-> Maybe (TyVar, Bool)
-> PatSyn
MkPatSyn {psName :: Name
psName = Name
name, psUnique :: Unique
psUnique = Name -> Unique
forall a. Uniquable a => a -> Unique
getUnique Name
name,
psUnivTyVars :: [InvisTVBinder]
psUnivTyVars = [InvisTVBinder]
univ_tvs,
psExTyVars :: [InvisTVBinder]
psExTyVars = [InvisTVBinder]
ex_tvs,
psProvTheta :: [Type]
psProvTheta = [Type]
prov_theta, psReqTheta :: [Type]
psReqTheta = [Type]
req_theta,
psInfix :: Bool
psInfix = Bool
declared_infix,
psArgs :: [Type]
psArgs = [Type]
orig_args,
psArity :: Arity
psArity = [Type] -> Arity
forall (t :: * -> *) a. Foldable t => t a -> Arity
length [Type]
orig_args,
psResultTy :: Type
psResultTy = Type
orig_res_ty,
psMatcher :: (TyVar, Bool)
psMatcher = (TyVar, Bool)
matcher,
psBuilder :: Maybe (TyVar, Bool)
psBuilder = Maybe (TyVar, Bool)
builder,
psFieldLabels :: [FieldLabel]
psFieldLabels = [FieldLabel]
field_labels
}
patSynName :: PatSyn -> Name
patSynName :: PatSyn -> Name
patSynName = PatSyn -> Name
psName
patSynIsInfix :: PatSyn -> Bool
patSynIsInfix :: PatSyn -> Bool
patSynIsInfix = PatSyn -> Bool
psInfix
patSynArity :: PatSyn -> Arity
patSynArity :: PatSyn -> Arity
patSynArity = PatSyn -> Arity
psArity
patSynArgs :: PatSyn -> [Type]
patSynArgs :: PatSyn -> [Type]
patSynArgs = PatSyn -> [Type]
psArgs
patSynFieldLabels :: PatSyn -> [FieldLabel]
patSynFieldLabels :: PatSyn -> [FieldLabel]
patSynFieldLabels = PatSyn -> [FieldLabel]
psFieldLabels
patSynFieldType :: PatSyn -> FieldLabelString -> Type
patSynFieldType :: PatSyn -> FieldLabelString -> Type
patSynFieldType PatSyn
ps FieldLabelString
label
= case ((FieldLabel, Type) -> Bool)
-> [(FieldLabel, Type)] -> Maybe (FieldLabel, Type)
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Maybe a
find ((FieldLabelString -> FieldLabelString -> Bool
forall a. Eq a => a -> a -> Bool
== FieldLabelString
label) (FieldLabelString -> Bool)
-> ((FieldLabel, Type) -> FieldLabelString)
-> (FieldLabel, Type)
-> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. FieldLabel -> FieldLabelString
forall a. FieldLbl a -> FieldLabelString
flLabel (FieldLabel -> FieldLabelString)
-> ((FieldLabel, Type) -> FieldLabel)
-> (FieldLabel, Type)
-> FieldLabelString
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (FieldLabel, Type) -> FieldLabel
forall a b. (a, b) -> a
fst) (PatSyn -> [FieldLabel]
psFieldLabels PatSyn
ps [FieldLabel] -> [Type] -> [(FieldLabel, Type)]
forall a b. [a] -> [b] -> [(a, b)]
`zip` PatSyn -> [Type]
psArgs PatSyn
ps) of
Just (FieldLabel
_, Type
ty) -> Type
ty
Maybe (FieldLabel, Type)
Nothing -> String -> SDoc -> Type
forall a. HasCallStack => String -> SDoc -> a
pprPanic String
"dataConFieldType" (PatSyn -> SDoc
forall a. Outputable a => a -> SDoc
ppr PatSyn
ps SDoc -> SDoc -> SDoc
<+> FieldLabelString -> SDoc
forall a. Outputable a => a -> SDoc
ppr FieldLabelString
label)
patSynUnivTyVarBinders :: PatSyn -> [InvisTVBinder]
patSynUnivTyVarBinders :: PatSyn -> [InvisTVBinder]
patSynUnivTyVarBinders = PatSyn -> [InvisTVBinder]
psUnivTyVars
patSynExTyVars :: PatSyn -> [TyVar]
patSynExTyVars :: PatSyn -> [TyVar]
patSynExTyVars PatSyn
ps = [InvisTVBinder] -> [TyVar]
forall tv argf. [VarBndr tv argf] -> [tv]
binderVars (PatSyn -> [InvisTVBinder]
psExTyVars PatSyn
ps)
patSynExTyVarBinders :: PatSyn -> [InvisTVBinder]
patSynExTyVarBinders :: PatSyn -> [InvisTVBinder]
patSynExTyVarBinders = PatSyn -> [InvisTVBinder]
psExTyVars
patSynSigBndr :: PatSyn -> ([InvisTVBinder], ThetaType, [InvisTVBinder], ThetaType, [Scaled Type], Type)
patSynSigBndr :: PatSyn
-> ([InvisTVBinder], [Type], [InvisTVBinder], [Type],
[Scaled Type], Type)
patSynSigBndr (MkPatSyn { psUnivTyVars :: PatSyn -> [InvisTVBinder]
psUnivTyVars = [InvisTVBinder]
univ_tvs, psExTyVars :: PatSyn -> [InvisTVBinder]
psExTyVars = [InvisTVBinder]
ex_tvs
, psProvTheta :: PatSyn -> [Type]
psProvTheta = [Type]
prov, psReqTheta :: PatSyn -> [Type]
psReqTheta = [Type]
req
, psArgs :: PatSyn -> [Type]
psArgs = [Type]
arg_tys, psResultTy :: PatSyn -> Type
psResultTy = Type
res_ty })
= ([InvisTVBinder]
univ_tvs, [Type]
req, [InvisTVBinder]
ex_tvs, [Type]
prov, (Type -> Scaled Type) -> [Type] -> [Scaled Type]
forall a b. (a -> b) -> [a] -> [b]
map Type -> Scaled Type
forall a. a -> Scaled a
unrestricted [Type]
arg_tys, Type
res_ty)
patSynSig :: PatSyn -> ([TyVar], ThetaType, [TyVar], ThetaType, [Scaled Type], Type)
patSynSig :: PatSyn -> ([TyVar], [Type], [TyVar], [Type], [Scaled Type], Type)
patSynSig PatSyn
ps = let ([InvisTVBinder]
u_tvs, [Type]
req, [InvisTVBinder]
e_tvs, [Type]
prov, [Scaled Type]
arg_tys, Type
res_ty) = PatSyn
-> ([InvisTVBinder], [Type], [InvisTVBinder], [Type],
[Scaled Type], Type)
patSynSigBndr PatSyn
ps
in ([InvisTVBinder] -> [TyVar]
forall tv argf. [VarBndr tv argf] -> [tv]
binderVars [InvisTVBinder]
u_tvs, [Type]
req, [InvisTVBinder] -> [TyVar]
forall tv argf. [VarBndr tv argf] -> [tv]
binderVars [InvisTVBinder]
e_tvs, [Type]
prov, [Scaled Type]
arg_tys, Type
res_ty)
patSynMatcher :: PatSyn -> (Id,Bool)
patSynMatcher :: PatSyn -> (TyVar, Bool)
patSynMatcher = PatSyn -> (TyVar, Bool)
psMatcher
patSynBuilder :: PatSyn -> Maybe (Id, Bool)
patSynBuilder :: PatSyn -> Maybe (TyVar, Bool)
patSynBuilder = PatSyn -> Maybe (TyVar, Bool)
psBuilder
updatePatSynIds :: (Id -> Id) -> PatSyn -> PatSyn
updatePatSynIds :: (TyVar -> TyVar) -> PatSyn -> PatSyn
updatePatSynIds TyVar -> TyVar
tidy_fn ps :: PatSyn
ps@(MkPatSyn { psMatcher :: PatSyn -> (TyVar, Bool)
psMatcher = (TyVar, Bool)
matcher, psBuilder :: PatSyn -> Maybe (TyVar, Bool)
psBuilder = Maybe (TyVar, Bool)
builder })
= PatSyn
ps { psMatcher :: (TyVar, Bool)
psMatcher = (TyVar, Bool) -> (TyVar, Bool)
forall {b}. (TyVar, b) -> (TyVar, b)
tidy_pr (TyVar, Bool)
matcher, psBuilder :: Maybe (TyVar, Bool)
psBuilder = ((TyVar, Bool) -> (TyVar, Bool))
-> Maybe (TyVar, Bool) -> Maybe (TyVar, Bool)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (TyVar, Bool) -> (TyVar, Bool)
forall {b}. (TyVar, b) -> (TyVar, b)
tidy_pr Maybe (TyVar, Bool)
builder }
where
tidy_pr :: (TyVar, b) -> (TyVar, b)
tidy_pr (TyVar
id, b
dummy) = (TyVar -> TyVar
tidy_fn TyVar
id, b
dummy)
patSynInstArgTys :: PatSyn -> [Type] -> [Type]
patSynInstArgTys :: PatSyn -> [Type] -> [Type]
patSynInstArgTys (MkPatSyn { psName :: PatSyn -> Name
psName = Name
name, psUnivTyVars :: PatSyn -> [InvisTVBinder]
psUnivTyVars = [InvisTVBinder]
univ_tvs
, psExTyVars :: PatSyn -> [InvisTVBinder]
psExTyVars = [InvisTVBinder]
ex_tvs, psArgs :: PatSyn -> [Type]
psArgs = [Type]
arg_tys })
[Type]
inst_tys
= ASSERT2( tyvars `equalLength` inst_tys
, text "patSynInstArgTys" <+> ppr name $$ ppr tyvars $$ ppr inst_tys )
(Type -> Type) -> [Type] -> [Type]
forall a b. (a -> b) -> [a] -> [b]
map (HasCallStack => [TyVar] -> [Type] -> Type -> Type
[TyVar] -> [Type] -> Type -> Type
substTyWith [TyVar]
tyvars [Type]
inst_tys) [Type]
arg_tys
where
tyvars :: [TyVar]
tyvars = [InvisTVBinder] -> [TyVar]
forall tv argf. [VarBndr tv argf] -> [tv]
binderVars ([InvisTVBinder]
univ_tvs [InvisTVBinder] -> [InvisTVBinder] -> [InvisTVBinder]
forall a. [a] -> [a] -> [a]
++ [InvisTVBinder]
ex_tvs)
patSynInstResTy :: PatSyn -> [Type] -> Type
patSynInstResTy :: PatSyn -> [Type] -> Type
patSynInstResTy (MkPatSyn { psName :: PatSyn -> Name
psName = Name
name, psUnivTyVars :: PatSyn -> [InvisTVBinder]
psUnivTyVars = [InvisTVBinder]
univ_tvs
, psResultTy :: PatSyn -> Type
psResultTy = Type
res_ty })
[Type]
inst_tys
= ASSERT2( univ_tvs `equalLength` inst_tys
, text "patSynInstResTy" <+> ppr name $$ ppr univ_tvs $$ ppr inst_tys )
HasCallStack => [TyVar] -> [Type] -> Type -> Type
[TyVar] -> [Type] -> Type -> Type
substTyWith ([InvisTVBinder] -> [TyVar]
forall tv argf. [VarBndr tv argf] -> [tv]
binderVars [InvisTVBinder]
univ_tvs) [Type]
inst_tys Type
res_ty
pprPatSynType :: PatSyn -> SDoc
pprPatSynType :: PatSyn -> SDoc
pprPatSynType (MkPatSyn { psUnivTyVars :: PatSyn -> [InvisTVBinder]
psUnivTyVars = [InvisTVBinder]
univ_tvs, psReqTheta :: PatSyn -> [Type]
psReqTheta = [Type]
req_theta
, psExTyVars :: PatSyn -> [InvisTVBinder]
psExTyVars = [InvisTVBinder]
ex_tvs, psProvTheta :: PatSyn -> [Type]
psProvTheta = [Type]
prov_theta
, psArgs :: PatSyn -> [Type]
psArgs = [Type]
orig_args, psResultTy :: PatSyn -> Type
psResultTy = Type
orig_res_ty })
= [SDoc] -> SDoc
sep [ [TyCoVarBinder] -> SDoc
pprForAll ([TyCoVarBinder] -> SDoc) -> [TyCoVarBinder] -> SDoc
forall a b. (a -> b) -> a -> b
$ [InvisTVBinder] -> [TyCoVarBinder]
forall a. [VarBndr a Specificity] -> [VarBndr a ArgFlag]
tyVarSpecToBinders [InvisTVBinder]
univ_tvs
, [Type] -> SDoc
pprThetaArrowTy [Type]
req_theta
, Bool -> SDoc -> SDoc
ppWhen Bool
insert_empty_ctxt (SDoc -> SDoc) -> SDoc -> SDoc
forall a b. (a -> b) -> a -> b
$ SDoc -> SDoc
parens SDoc
empty SDoc -> SDoc -> SDoc
<+> SDoc
darrow
, Type -> SDoc
pprType Type
sigma_ty ]
where
sigma_ty :: Type
sigma_ty = [InvisTVBinder] -> Type -> Type
mkInvisForAllTys [InvisTVBinder]
ex_tvs (Type -> Type) -> Type -> Type
forall a b. (a -> b) -> a -> b
$
[Type] -> Type -> Type
mkInvisFunTysMany [Type]
prov_theta (Type -> Type) -> Type -> Type
forall a b. (a -> b) -> a -> b
$
[Type] -> Type -> Type
mkVisFunTysMany [Type]
orig_args Type
orig_res_ty
insert_empty_ctxt :: Bool
insert_empty_ctxt = [Type] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [Type]
req_theta Bool -> Bool -> Bool
&& Bool -> Bool
not ([Type] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [Type]
prov_theta Bool -> Bool -> Bool
&& [InvisTVBinder] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [InvisTVBinder]
ex_tvs)