{-# OPTIONS_GHC -Wno-incomplete-uni-patterns #-}
module GHC.Tc.TyCl.Build (
buildDataCon,
buildPatSyn,
TcMethInfo, MethInfo, buildClass,
mkNewTyConRhs,
newImplicitBinder, newTyConRepName
) where
import GHC.Prelude
import GHC.Iface.Env
import GHC.Core.FamInstEnv( FamInstEnvs, mkNewTypeCoAxiom )
import GHC.Builtin.Types( isCTupleTyConName, unboxedUnitTy )
import GHC.Core.DataCon
import GHC.Core.PatSyn
import GHC.Types.Var
import GHC.Types.Var.Set
import GHC.Types.Basic
import GHC.Types.Name
import GHC.Types.Name.Env
import GHC.Types.Id.Make
import GHC.Core.Class
import GHC.Core.TyCon
import GHC.Core.Type
import GHC.Types.SourceText
import GHC.Tc.Utils.TcType
import GHC.Core.Multiplicity
import GHC.Types.SrcLoc( SrcSpan, noSrcSpan )
import GHC.Tc.Utils.Monad
import GHC.Types.Unique.Supply
import GHC.Utils.Misc
import GHC.Utils.Outputable
import GHC.Utils.Panic
mkNewTyConRhs :: Name -> TyCon -> DataCon -> TcRnIf m n AlgTyConRhs
mkNewTyConRhs :: forall m n. Name -> TyCon -> DataCon -> TcRnIf m n AlgTyConRhs
mkNewTyConRhs Name
tycon_name TyCon
tycon DataCon
con
= do { Name
co_tycon_name <- Name -> (OccName -> OccName) -> TcRnIf m n Name
forall m n. Name -> (OccName -> OccName) -> TcRnIf m n Name
newImplicitBinder Name
tycon_name OccName -> OccName
mkNewTyCoOcc
; let nt_ax :: CoAxiom Unbranched
nt_ax = Name -> TyCon -> [TyVar] -> [Role] -> Type -> CoAxiom Unbranched
mkNewTypeCoAxiom Name
co_tycon_name TyCon
tycon [TyVar]
etad_tvs [Role]
etad_roles Type
etad_rhs
; SDoc -> TcRnIf m n ()
forall m n. SDoc -> TcRnIf m n ()
traceIf (String -> SDoc
text String
"mkNewTyConRhs" SDoc -> SDoc -> SDoc
<+> CoAxiom Unbranched -> SDoc
forall a. Outputable a => a -> SDoc
ppr CoAxiom Unbranched
nt_ax)
; AlgTyConRhs -> TcRnIf m n AlgTyConRhs
forall a. a -> IOEnv (Env m n) a
forall (m :: * -> *) a. Monad m => a -> m a
return (NewTyCon { data_con :: DataCon
data_con = DataCon
con,
nt_rhs :: Type
nt_rhs = Type
rhs_ty,
nt_etad_rhs :: ([TyVar], Type)
nt_etad_rhs = ([TyVar]
etad_tvs, Type
etad_rhs),
nt_co :: CoAxiom Unbranched
nt_co = CoAxiom Unbranched
nt_ax,
nt_fixed_rep :: Bool
nt_fixed_rep = (() :: Constraint) => Type -> Bool
Type -> Bool
isFixedRuntimeRepKind Type
res_kind } ) }
where
tvs :: [TyVar]
tvs = TyCon -> [TyVar]
tyConTyVars TyCon
tycon
roles :: [Role]
roles = TyCon -> [Role]
tyConRoles TyCon
tycon
res_kind :: Type
res_kind = TyCon -> Type
tyConResKind TyCon
tycon
con_arg_ty :: Type
con_arg_ty = case DataCon -> [Scaled Type]
dataConRepArgTys DataCon
con of
[Scaled Type
arg_ty] -> Scaled Type -> Type
forall a. Scaled a -> a
scaledThing Scaled Type
arg_ty
[Scaled Type]
tys -> String -> SDoc -> Type
forall a. HasCallStack => String -> SDoc -> a
pprPanic String
"mkNewTyConRhs" (DataCon -> SDoc
forall a. Outputable a => a -> SDoc
ppr DataCon
con SDoc -> SDoc -> SDoc
<+> [Scaled Type] -> SDoc
forall a. Outputable a => a -> SDoc
ppr [Scaled Type]
tys)
rhs_ty :: Type
rhs_ty = [TyVar] -> ThetaType -> Type -> Type
(() :: Constraint) => [TyVar] -> ThetaType -> Type -> Type
substTyWith (DataCon -> [TyVar]
dataConUnivTyVars DataCon
con)
([TyVar] -> ThetaType
mkTyVarTys [TyVar]
tvs) Type
con_arg_ty
etad_tvs :: [TyVar]
etad_roles :: [Role]
etad_rhs :: Type
([TyVar]
etad_tvs, [Role]
etad_roles, Type
etad_rhs) = [TyVar] -> [Role] -> Type -> ([TyVar], [Role], Type)
eta_reduce ([TyVar] -> [TyVar]
forall a. [a] -> [a]
reverse [TyVar]
tvs) ([Role] -> [Role]
forall a. [a] -> [a]
reverse [Role]
roles) Type
rhs_ty
eta_reduce :: [TyVar]
-> [Role]
-> Type
-> ([TyVar], [Role], Type)
eta_reduce :: [TyVar] -> [Role] -> Type -> ([TyVar], [Role], Type)
eta_reduce (TyVar
a:[TyVar]
as) (Role
_:[Role]
rs) Type
ty
| Just (Type
fun, Type
arg) <- Type -> Maybe (Type, Type)
splitAppTy_maybe Type
ty
, Just TyVar
tv <- Type -> Maybe TyVar
getTyVar_maybe Type
arg
, TyVar
tv TyVar -> TyVar -> Bool
forall a. Eq a => a -> a -> Bool
== TyVar
a
, Bool -> Bool
not (TyVar
a TyVar -> VarSet -> Bool
`elemVarSet` Type -> VarSet
tyCoVarsOfType Type
fun)
, (() :: Constraint) => Type -> Type
Type -> Type
typeKind Type
fun Type -> Type -> Bool
`eqType` (() :: Constraint) => Type -> Type
Type -> Type
typeKind (TyCon -> ThetaType -> Type
mkTyConApp TyCon
tycon ([TyVar] -> ThetaType
mkTyVarTys ([TyVar] -> ThetaType) -> [TyVar] -> ThetaType
forall a b. (a -> b) -> a -> b
$ [TyVar] -> [TyVar]
forall a. [a] -> [a]
reverse [TyVar]
as))
= [TyVar] -> [Role] -> Type -> ([TyVar], [Role], Type)
eta_reduce [TyVar]
as [Role]
rs Type
fun
eta_reduce [TyVar]
as [Role]
rs Type
ty = ([TyVar] -> [TyVar]
forall a. [a] -> [a]
reverse [TyVar]
as, [Role] -> [Role]
forall a. [a] -> [a]
reverse [Role]
rs, Type
ty)
buildDataCon :: FamInstEnvs
-> DataConBangOpts
-> Name
-> Bool
-> TyConRepName
-> [HsSrcBang]
-> [FieldLabel]
-> [TyVar]
-> [TyCoVar]
-> [InvisTVBinder]
-> [EqSpec]
-> KnotTied ThetaType
-> [KnotTied (Scaled Type)]
-> KnotTied Type
-> KnotTied TyCon
-> NameEnv ConTag
-> TcRnIf m n DataCon
buildDataCon :: forall m n.
FamInstEnvs
-> DataConBangOpts
-> Name
-> Bool
-> Name
-> [HsSrcBang]
-> [FieldLabel]
-> [TyVar]
-> [TyVar]
-> [InvisTVBinder]
-> [EqSpec]
-> ThetaType
-> [Scaled Type]
-> Type
-> TyCon
-> NameEnv ConTag
-> TcRnIf m n DataCon
buildDataCon FamInstEnvs
fam_envs DataConBangOpts
dc_bang_opts Name
src_name Bool
declared_infix Name
prom_info [HsSrcBang]
src_bangs
[FieldLabel]
field_lbls [TyVar]
univ_tvs [TyVar]
ex_tvs [InvisTVBinder]
user_tvbs [EqSpec]
eq_spec ThetaType
ctxt [Scaled Type]
arg_tys Type
res_ty
TyCon
rep_tycon NameEnv ConTag
tag_map
= do { Name
wrap_name <- Name -> (OccName -> OccName) -> TcRnIf m n Name
forall m n. Name -> (OccName -> OccName) -> TcRnIf m n Name
newImplicitBinder Name
src_name OccName -> OccName
mkDataConWrapperOcc
; Name
work_name <- Name -> (OccName -> OccName) -> TcRnIf m n Name
forall m n. Name -> (OccName -> OccName) -> TcRnIf m n Name
newImplicitBinder Name
src_name OccName -> OccName
mkDataConWorkerOcc
; SDoc -> TcRnIf m n ()
forall m n. SDoc -> TcRnIf m n ()
traceIf (String -> SDoc
text String
"buildDataCon 1" SDoc -> SDoc -> SDoc
<+> Name -> SDoc
forall a. Outputable a => a -> SDoc
ppr Name
src_name)
; UniqSupply
us <- TcRnIf m n UniqSupply
forall gbl lcl. TcRnIf gbl lcl UniqSupply
newUniqueSupply
; let stupid_ctxt :: ThetaType
stupid_ctxt = TyCon -> ThetaType -> [TyVar] -> ThetaType
mkDataConStupidTheta TyCon
rep_tycon ((Scaled Type -> Type) -> [Scaled Type] -> ThetaType
forall a b. (a -> b) -> [a] -> [b]
map Scaled Type -> Type
forall a. Scaled a -> a
scaledThing [Scaled Type]
arg_tys) [TyVar]
univ_tvs
tag :: ConTag
tag = NameEnv ConTag -> Name -> ConTag
forall a. NameEnv a -> Name -> a
lookupNameEnv_NF NameEnv ConTag
tag_map Name
src_name
data_con :: DataCon
data_con = Name
-> Bool
-> Name
-> [HsSrcBang]
-> [FieldLabel]
-> [TyVar]
-> [TyVar]
-> [InvisTVBinder]
-> [EqSpec]
-> ThetaType
-> [Scaled Type]
-> Type
-> RuntimeRepInfo
-> TyCon
-> ConTag
-> ThetaType
-> TyVar
-> DataConRep
-> DataCon
mkDataCon Name
src_name Bool
declared_infix Name
prom_info
[HsSrcBang]
src_bangs [FieldLabel]
field_lbls
[TyVar]
univ_tvs [TyVar]
ex_tvs [InvisTVBinder]
user_tvbs [EqSpec]
eq_spec ThetaType
ctxt
[Scaled Type]
arg_tys Type
res_ty RuntimeRepInfo
NoRRI TyCon
rep_tycon ConTag
tag
ThetaType
stupid_ctxt TyVar
dc_wrk DataConRep
dc_rep
dc_wrk :: TyVar
dc_wrk = Name -> DataCon -> TyVar
mkDataConWorkId Name
work_name DataCon
data_con
dc_rep :: DataConRep
dc_rep = UniqSupply -> UniqSM DataConRep -> DataConRep
forall a. UniqSupply -> UniqSM a -> a
initUs_ UniqSupply
us (DataConBangOpts
-> FamInstEnvs -> Name -> DataCon -> UniqSM DataConRep
mkDataConRep DataConBangOpts
dc_bang_opts FamInstEnvs
fam_envs Name
wrap_name DataCon
data_con)
; SDoc -> TcRnIf m n ()
forall m n. SDoc -> TcRnIf m n ()
traceIf (String -> SDoc
text String
"buildDataCon 2" SDoc -> SDoc -> SDoc
<+> Name -> SDoc
forall a. Outputable a => a -> SDoc
ppr Name
src_name)
; DataCon -> TcRnIf m n DataCon
forall a. a -> IOEnv (Env m n) a
forall (m :: * -> *) a. Monad m => a -> m a
return DataCon
data_con }
mkDataConStupidTheta :: TyCon -> [Type] -> [TyVar] -> [PredType]
mkDataConStupidTheta :: TyCon -> ThetaType -> [TyVar] -> ThetaType
mkDataConStupidTheta TyCon
tycon ThetaType
arg_tys [TyVar]
univ_tvs
| ThetaType -> Bool
forall a. [a] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null ThetaType
stupid_theta = []
| Bool
otherwise = (Type -> Bool) -> ThetaType -> ThetaType
forall a. (a -> Bool) -> [a] -> [a]
filter Type -> Bool
in_arg_tys ThetaType
stupid_theta
where
tc_subst :: TCvSubst
tc_subst = [TyVar] -> ThetaType -> TCvSubst
(() :: Constraint) => [TyVar] -> ThetaType -> TCvSubst
zipTvSubst (TyCon -> [TyVar]
tyConTyVars TyCon
tycon)
([TyVar] -> ThetaType
mkTyVarTys [TyVar]
univ_tvs)
stupid_theta :: ThetaType
stupid_theta = (() :: Constraint) => TCvSubst -> ThetaType -> ThetaType
TCvSubst -> ThetaType -> ThetaType
substTheta TCvSubst
tc_subst (TyCon -> ThetaType
tyConStupidTheta TyCon
tycon)
arg_tyvars :: VarSet
arg_tyvars = ThetaType -> VarSet
tyCoVarsOfTypes ThetaType
arg_tys
in_arg_tys :: Type -> Bool
in_arg_tys Type
pred = Type -> VarSet
tyCoVarsOfType Type
pred VarSet -> VarSet -> Bool
`intersectsVarSet` VarSet
arg_tyvars
buildPatSyn :: Name -> Bool
-> PatSynMatcher -> PatSynBuilder
-> ([InvisTVBinder], ThetaType)
-> ([InvisTVBinder], ThetaType)
-> [FRRType]
-> Type
-> [FieldLabel]
-> PatSyn
buildPatSyn :: Name
-> Bool
-> PatSynMatcher
-> PatSynBuilder
-> ([InvisTVBinder], ThetaType)
-> ([InvisTVBinder], ThetaType)
-> ThetaType
-> Type
-> [FieldLabel]
-> PatSyn
buildPatSyn Name
src_name Bool
declared_infix matcher :: PatSynMatcher
matcher@(Name
_, Type
matcher_ty,Bool
_) PatSynBuilder
builder
([InvisTVBinder]
univ_tvs, ThetaType
req_theta) ([InvisTVBinder]
ex_tvs, ThetaType
prov_theta) ThetaType
arg_tys
Type
pat_ty [FieldLabel]
field_labels
=
Bool -> SDoc -> PatSyn -> PatSyn
forall a. HasCallStack => Bool -> SDoc -> a -> a
assertPpr ([Bool] -> Bool
forall (t :: * -> *). Foldable t => t Bool -> Bool
and [ [InvisTVBinder]
univ_tvs [InvisTVBinder] -> [TyVar] -> Bool
forall a b. [a] -> [b] -> Bool
`equalLength` [TyVar]
univ_tvs1
, [InvisTVBinder]
ex_tvs [InvisTVBinder] -> [TyVar] -> Bool
forall a b. [a] -> [b] -> Bool
`equalLength` [TyVar]
ex_tvs1
, Type
pat_ty Type -> Type -> Bool
`eqType` (() :: Constraint) => TCvSubst -> Type -> Type
TCvSubst -> Type -> Type
substTy TCvSubst
subst (Scaled Type -> Type
forall a. Scaled a -> a
scaledThing Scaled Type
pat_ty1)
, ThetaType
prov_theta ThetaType -> ThetaType -> Bool
`eqTypes` (() :: Constraint) => TCvSubst -> ThetaType -> ThetaType
TCvSubst -> ThetaType -> ThetaType
substTys TCvSubst
subst ThetaType
prov_theta1
, ThetaType
req_theta ThetaType -> ThetaType -> Bool
`eqTypes` (() :: Constraint) => TCvSubst -> ThetaType -> ThetaType
TCvSubst -> ThetaType -> ThetaType
substTys TCvSubst
subst ThetaType
req_theta1
, ThetaType -> ThetaType -> Bool
compareArgTys ThetaType
arg_tys ((() :: Constraint) => TCvSubst -> ThetaType -> ThetaType
TCvSubst -> ThetaType -> ThetaType
substTys TCvSubst
subst ((Scaled Type -> Type) -> [Scaled Type] -> ThetaType
forall a b. (a -> b) -> [a] -> [b]
map Scaled Type -> Type
forall a. Scaled a -> a
scaledThing [Scaled Type]
arg_tys1))
])
([SDoc] -> SDoc
vcat [ [InvisTVBinder] -> SDoc
forall a. Outputable a => a -> SDoc
ppr [InvisTVBinder]
univ_tvs SDoc -> SDoc -> SDoc
<+> SDoc
twiddle SDoc -> SDoc -> SDoc
<+> [TyVar] -> SDoc
forall a. Outputable a => a -> SDoc
ppr [TyVar]
univ_tvs1
, [InvisTVBinder] -> SDoc
forall a. Outputable a => a -> SDoc
ppr [InvisTVBinder]
ex_tvs SDoc -> SDoc -> SDoc
<+> SDoc
twiddle SDoc -> SDoc -> SDoc
<+> [TyVar] -> SDoc
forall a. Outputable a => a -> SDoc
ppr [TyVar]
ex_tvs1
, Type -> SDoc
forall a. Outputable a => a -> SDoc
ppr Type
pat_ty SDoc -> SDoc -> SDoc
<+> SDoc
twiddle SDoc -> SDoc -> SDoc
<+> Scaled Type -> SDoc
forall a. Outputable a => a -> SDoc
ppr Scaled Type
pat_ty1
, ThetaType -> SDoc
forall a. Outputable a => a -> SDoc
ppr ThetaType
prov_theta SDoc -> SDoc -> SDoc
<+> SDoc
twiddle SDoc -> SDoc -> SDoc
<+> ThetaType -> SDoc
forall a. Outputable a => a -> SDoc
ppr ThetaType
prov_theta1
, ThetaType -> SDoc
forall a. Outputable a => a -> SDoc
ppr ThetaType
req_theta SDoc -> SDoc -> SDoc
<+> SDoc
twiddle SDoc -> SDoc -> SDoc
<+> ThetaType -> SDoc
forall a. Outputable a => a -> SDoc
ppr ThetaType
req_theta1
, ThetaType -> SDoc
forall a. Outputable a => a -> SDoc
ppr ThetaType
arg_tys SDoc -> SDoc -> SDoc
<+> SDoc
twiddle SDoc -> SDoc -> SDoc
<+> [Scaled Type] -> SDoc
forall a. Outputable a => a -> SDoc
ppr [Scaled Type]
arg_tys1]) (PatSyn -> PatSyn) -> PatSyn -> PatSyn
forall a b. (a -> b) -> a -> b
$
Name
-> Bool
-> ([InvisTVBinder], ThetaType)
-> ([InvisTVBinder], ThetaType)
-> ThetaType
-> Type
-> PatSynMatcher
-> PatSynBuilder
-> [FieldLabel]
-> PatSyn
mkPatSyn Name
src_name Bool
declared_infix
([InvisTVBinder]
univ_tvs, ThetaType
req_theta) ([InvisTVBinder]
ex_tvs, ThetaType
prov_theta)
ThetaType
arg_tys Type
pat_ty
PatSynMatcher
matcher PatSynBuilder
builder [FieldLabel]
field_labels
where
((TyVar
_:TyVar
_:[TyVar]
univ_tvs1), ThetaType
req_theta1, Type
tau) = Type -> ([TyVar], ThetaType, Type)
tcSplitSigmaTy (Type -> ([TyVar], ThetaType, Type))
-> Type -> ([TyVar], ThetaType, Type)
forall a b. (a -> b) -> a -> b
$ Type
matcher_ty
([Scaled Type
pat_ty1, Scaled Type
cont_sigma, Scaled Type
_], Type
_) = Type -> ([Scaled Type], Type)
tcSplitFunTys Type
tau
([TyVar]
ex_tvs1, ThetaType
prov_theta1, Type
cont_tau) = Type -> ([TyVar], ThetaType, Type)
tcSplitSigmaTy (Scaled Type -> Type
forall a. Scaled a -> a
scaledThing Scaled Type
cont_sigma)
([Scaled Type]
arg_tys1, Type
_) = (Type -> ([Scaled Type], Type)
tcSplitFunTys Type
cont_tau)
twiddle :: SDoc
twiddle = Char -> SDoc
char Char
'~'
subst :: TCvSubst
subst = [TyVar] -> ThetaType -> TCvSubst
(() :: Constraint) => [TyVar] -> ThetaType -> TCvSubst
zipTvSubst ([TyVar]
univ_tvs1 [TyVar] -> [TyVar] -> [TyVar]
forall a. [a] -> [a] -> [a]
++ [TyVar]
ex_tvs1)
([TyVar] -> ThetaType
mkTyVarTys ([InvisTVBinder] -> [TyVar]
forall tv argf. [VarBndr tv argf] -> [tv]
binderVars ([InvisTVBinder]
univ_tvs [InvisTVBinder] -> [InvisTVBinder] -> [InvisTVBinder]
forall a. [a] -> [a] -> [a]
++ [InvisTVBinder]
ex_tvs)))
compareArgTys :: [Type] -> [Type] -> Bool
compareArgTys :: ThetaType -> ThetaType -> Bool
compareArgTys [] [Type
x] = Type
x Type -> Type -> Bool
`eqType` Type
unboxedUnitTy
compareArgTys ThetaType
arg_tys ThetaType
matcher_arg_tys = ThetaType
arg_tys ThetaType -> ThetaType -> Bool
`eqTypes` ThetaType
matcher_arg_tys
type TcMethInfo = MethInfo
type MethInfo
= ( Name
, Type
, Maybe (DefMethSpec (SrcSpan, Type)))
buildClass :: Name
-> [TyConBinder]
-> [Role]
-> [FunDep TyVar]
-> Maybe (KnotTied ThetaType, [ClassATItem], [KnotTied MethInfo], ClassMinimalDef)
-> TcRnIf m n Class
buildClass :: forall m n.
Name
-> [TyConBinder]
-> [Role]
-> [FunDep TyVar]
-> Maybe
(ThetaType, [ClassATItem], [KnotTied MethInfo], ClassMinimalDef)
-> TcRnIf m n Class
buildClass Name
tycon_name [TyConBinder]
binders [Role]
roles [FunDep TyVar]
fds Maybe
(ThetaType, [ClassATItem], [KnotTied MethInfo], ClassMinimalDef)
Nothing
= (Class -> IOEnv (Env m n) Class) -> IOEnv (Env m n) Class
forall a env. (a -> IOEnv env a) -> IOEnv env a
fixM ((Class -> IOEnv (Env m n) Class) -> IOEnv (Env m n) Class)
-> (Class -> IOEnv (Env m n) Class) -> IOEnv (Env m n) Class
forall a b. (a -> b) -> a -> b
$ \ Class
rec_clas ->
do { SDoc -> TcRnIf m n ()
forall m n. SDoc -> TcRnIf m n ()
traceIf (String -> SDoc
text String
"buildClass")
; Name
tc_rep_name <- Name -> TcRnIf m n Name
forall gbl lcl. Name -> TcRnIf gbl lcl Name
newTyConRepName Name
tycon_name
; let univ_tvs :: [TyVar]
univ_tvs = [TyConBinder] -> [TyVar]
forall tv argf. [VarBndr tv argf] -> [tv]
binderVars [TyConBinder]
binders
tycon :: TyCon
tycon = Name
-> [TyConBinder] -> [Role] -> AlgTyConRhs -> Class -> Name -> TyCon
mkClassTyCon Name
tycon_name [TyConBinder]
binders [Role]
roles
AlgTyConRhs
AbstractTyCon
Class
rec_clas Name
tc_rep_name
result :: Class
result = Name -> [TyVar] -> [FunDep TyVar] -> TyCon -> Class
mkAbstractClass Name
tycon_name [TyVar]
univ_tvs [FunDep TyVar]
fds TyCon
tycon
; SDoc -> TcRnIf m n ()
forall m n. SDoc -> TcRnIf m n ()
traceIf (String -> SDoc
text String
"buildClass" SDoc -> SDoc -> SDoc
<+> TyCon -> SDoc
forall a. Outputable a => a -> SDoc
ppr TyCon
tycon)
; Class -> IOEnv (Env m n) Class
forall a. a -> IOEnv (Env m n) a
forall (m :: * -> *) a. Monad m => a -> m a
return Class
result }
buildClass Name
tycon_name [TyConBinder]
binders [Role]
roles [FunDep TyVar]
fds
(Just (ThetaType
sc_theta, [ClassATItem]
at_items, [KnotTied MethInfo]
sig_stuff, ClassMinimalDef
mindef))
= (Class -> IOEnv (Env m n) Class) -> IOEnv (Env m n) Class
forall a env. (a -> IOEnv env a) -> IOEnv env a
fixM ((Class -> IOEnv (Env m n) Class) -> IOEnv (Env m n) Class)
-> (Class -> IOEnv (Env m n) Class) -> IOEnv (Env m n) Class
forall a b. (a -> b) -> a -> b
$ \ Class
rec_clas ->
do { SDoc -> TcRnIf m n ()
forall m n. SDoc -> TcRnIf m n ()
traceIf (String -> SDoc
text String
"buildClass")
; Name
datacon_name <- Name -> (OccName -> OccName) -> TcRnIf m n Name
forall m n. Name -> (OccName -> OccName) -> TcRnIf m n Name
newImplicitBinder Name
tycon_name OccName -> OccName
mkClassDataConOcc
; Name
tc_rep_name <- Name -> TcRnIf m n Name
forall gbl lcl. Name -> TcRnIf gbl lcl Name
newTyConRepName Name
tycon_name
; [ClassOpItem]
op_items <- (KnotTied MethInfo -> IOEnv (Env m n) ClassOpItem)
-> [KnotTied MethInfo] -> IOEnv (Env m n) [ClassOpItem]
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 (Class -> KnotTied MethInfo -> IOEnv (Env m n) ClassOpItem
forall n m. Class -> KnotTied MethInfo -> TcRnIf n m ClassOpItem
mk_op_item Class
rec_clas) [KnotTied MethInfo]
sig_stuff
; [Name]
sc_sel_names <- (ConTag -> TcRnIf m n Name) -> [ConTag] -> IOEnv (Env m n) [Name]
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 (Name -> (OccName -> OccName) -> TcRnIf m n Name
forall m n. Name -> (OccName -> OccName) -> TcRnIf m n Name
newImplicitBinder Name
tycon_name ((OccName -> OccName) -> TcRnIf m n Name)
-> (ConTag -> OccName -> OccName) -> ConTag -> TcRnIf m n Name
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ConTag -> OccName -> OccName
mkSuperDictSelOcc)
(ThetaType -> [ConTag] -> [ConTag]
forall b a. [b] -> [a] -> [a]
takeList ThetaType
sc_theta [ConTag
fIRST_TAG..])
; let sc_sel_ids :: [TyVar]
sc_sel_ids = [ Name -> Class -> TyVar
mkDictSelId Name
sc_name Class
rec_clas
| Name
sc_name <- [Name]
sc_sel_names]
; let use_newtype :: Bool
use_newtype = ThetaType -> Bool
forall a. [a] -> Bool
isSingleton ThetaType
arg_tys
args :: [Name]
args = [Name]
sc_sel_names [Name] -> [Name] -> [Name]
forall a. [a] -> [a] -> [a]
++ [Name]
op_names
op_tys :: ThetaType
op_tys = [Type
ty | (Name
_,Type
ty,Maybe (DefMethSpec (SrcSpan, Type))
_) <- [KnotTied MethInfo]
sig_stuff]
op_names :: [Name]
op_names = [Name
op | (Name
op,Type
_,Maybe (DefMethSpec (SrcSpan, Type))
_) <- [KnotTied MethInfo]
sig_stuff]
arg_tys :: ThetaType
arg_tys = ThetaType
sc_theta ThetaType -> ThetaType -> ThetaType
forall a. [a] -> [a] -> [a]
++ ThetaType
op_tys
rec_tycon :: TyCon
rec_tycon = Class -> TyCon
classTyCon Class
rec_clas
univ_bndrs :: [InvisTVBinder]
univ_bndrs = [TyConBinder] -> [InvisTVBinder]
tyConInvisTVBinders [TyConBinder]
binders
univ_tvs :: [TyVar]
univ_tvs = [InvisTVBinder] -> [TyVar]
forall tv argf. [VarBndr tv argf] -> [tv]
binderVars [InvisTVBinder]
univ_bndrs
bang_opts :: DataConBangOpts
bang_opts = [HsImplBang] -> DataConBangOpts
FixedBangOpts ((Name -> HsImplBang) -> [Name] -> [HsImplBang]
forall a b. (a -> b) -> [a] -> [b]
map (HsImplBang -> Name -> HsImplBang
forall a b. a -> b -> a
const HsImplBang
HsLazy) [Name]
args)
; Name
rep_nm <- Name -> TcRnIf m n Name
forall gbl lcl. Name -> TcRnIf gbl lcl Name
newTyConRepName Name
datacon_name
; DataCon
dict_con <- FamInstEnvs
-> DataConBangOpts
-> Name
-> Bool
-> Name
-> [HsSrcBang]
-> [FieldLabel]
-> [TyVar]
-> [TyVar]
-> [InvisTVBinder]
-> [EqSpec]
-> ThetaType
-> [Scaled Type]
-> Type
-> TyCon
-> NameEnv ConTag
-> TcRnIf m n DataCon
forall m n.
FamInstEnvs
-> DataConBangOpts
-> Name
-> Bool
-> Name
-> [HsSrcBang]
-> [FieldLabel]
-> [TyVar]
-> [TyVar]
-> [InvisTVBinder]
-> [EqSpec]
-> ThetaType
-> [Scaled Type]
-> Type
-> TyCon
-> NameEnv ConTag
-> TcRnIf m n DataCon
buildDataCon (String -> FamInstEnvs
forall a. String -> a
panic String
"buildClass: FamInstEnvs")
DataConBangOpts
bang_opts
Name
datacon_name
Bool
False
Name
rep_nm
((Name -> HsSrcBang) -> [Name] -> [HsSrcBang]
forall a b. (a -> b) -> [a] -> [b]
map (HsSrcBang -> Name -> HsSrcBang
forall a b. a -> b -> a
const HsSrcBang
no_bang) [Name]
args)
[]
[TyVar]
univ_tvs
[]
[InvisTVBinder]
univ_bndrs
[]
[]
((Type -> Scaled Type) -> ThetaType -> [Scaled Type]
forall a b. (a -> b) -> [a] -> [b]
map Type -> Scaled Type
forall a. a -> Scaled a
unrestricted ThetaType
arg_tys)
(TyCon -> ThetaType -> Type
mkTyConApp TyCon
rec_tycon ([TyVar] -> ThetaType
mkTyVarTys [TyVar]
univ_tvs))
TyCon
rec_tycon
(TyCon -> NameEnv ConTag
mkTyConTagMap TyCon
rec_tycon)
; AlgTyConRhs
rhs <- case () of
()
_ | Bool
use_newtype
-> Name -> TyCon -> DataCon -> IOEnv (Env m n) AlgTyConRhs
forall m n. Name -> TyCon -> DataCon -> TcRnIf m n AlgTyConRhs
mkNewTyConRhs Name
tycon_name TyCon
rec_tycon DataCon
dict_con
| Name -> Bool
isCTupleTyConName Name
tycon_name
-> AlgTyConRhs -> IOEnv (Env m n) AlgTyConRhs
forall a. a -> IOEnv (Env m n) a
forall (m :: * -> *) a. Monad m => a -> m a
return (TupleTyCon { data_con :: DataCon
data_con = DataCon
dict_con
, tup_sort :: TupleSort
tup_sort = TupleSort
ConstraintTuple })
| Bool
otherwise
-> AlgTyConRhs -> IOEnv (Env m n) AlgTyConRhs
forall a. a -> IOEnv (Env m n) a
forall (m :: * -> *) a. Monad m => a -> m a
return ([DataCon] -> AlgTyConRhs
mkDataTyConRhs [DataCon
dict_con])
; let { tycon :: TyCon
tycon = Name
-> [TyConBinder] -> [Role] -> AlgTyConRhs -> Class -> Name -> TyCon
mkClassTyCon Name
tycon_name [TyConBinder]
binders [Role]
roles
AlgTyConRhs
rhs Class
rec_clas Name
tc_rep_name
; result :: Class
result = Name
-> [TyVar]
-> [FunDep TyVar]
-> ThetaType
-> [TyVar]
-> [ClassATItem]
-> [ClassOpItem]
-> ClassMinimalDef
-> TyCon
-> Class
mkClass Name
tycon_name [TyVar]
univ_tvs [FunDep TyVar]
fds
ThetaType
sc_theta [TyVar]
sc_sel_ids [ClassATItem]
at_items
[ClassOpItem]
op_items ClassMinimalDef
mindef TyCon
tycon
}
; SDoc -> TcRnIf m n ()
forall m n. SDoc -> TcRnIf m n ()
traceIf (String -> SDoc
text String
"buildClass" SDoc -> SDoc -> SDoc
<+> TyCon -> SDoc
forall a. Outputable a => a -> SDoc
ppr TyCon
tycon)
; Class -> IOEnv (Env m n) Class
forall a. a -> IOEnv (Env m n) a
forall (m :: * -> *) a. Monad m => a -> m a
return Class
result }
where
no_bang :: HsSrcBang
no_bang = SourceText -> SrcUnpackedness -> SrcStrictness -> HsSrcBang
HsSrcBang SourceText
NoSourceText SrcUnpackedness
NoSrcUnpack SrcStrictness
NoSrcStrict
mk_op_item :: Class -> TcMethInfo -> TcRnIf n m ClassOpItem
mk_op_item :: forall n m. Class -> KnotTied MethInfo -> TcRnIf n m ClassOpItem
mk_op_item Class
rec_clas (Name
op_name, Type
_, Maybe (DefMethSpec (SrcSpan, Type))
dm_spec)
= do { Maybe (Name, DefMethSpec Type)
dm_info <- Name
-> Maybe (DefMethSpec (SrcSpan, Type))
-> TcRnIf n m (Maybe (Name, DefMethSpec Type))
forall n m.
Name
-> Maybe (DefMethSpec (SrcSpan, Type))
-> TcRnIf n m (Maybe (Name, DefMethSpec Type))
mk_dm_info Name
op_name Maybe (DefMethSpec (SrcSpan, Type))
dm_spec
; ClassOpItem -> TcRnIf n m ClassOpItem
forall a. a -> IOEnv (Env n m) a
forall (m :: * -> *) a. Monad m => a -> m a
return (Name -> Class -> TyVar
mkDictSelId Name
op_name Class
rec_clas, Maybe (Name, DefMethSpec Type)
dm_info) }
mk_dm_info :: Name -> Maybe (DefMethSpec (SrcSpan, Type))
-> TcRnIf n m (Maybe (Name, DefMethSpec Type))
mk_dm_info :: forall n m.
Name
-> Maybe (DefMethSpec (SrcSpan, Type))
-> TcRnIf n m (Maybe (Name, DefMethSpec Type))
mk_dm_info Name
_ Maybe (DefMethSpec (SrcSpan, Type))
Nothing
= Maybe (Name, DefMethSpec Type)
-> IOEnv (Env n m) (Maybe (Name, DefMethSpec Type))
forall a. a -> IOEnv (Env n m) a
forall (m :: * -> *) a. Monad m => a -> m a
return Maybe (Name, DefMethSpec Type)
forall a. Maybe a
Nothing
mk_dm_info Name
op_name (Just DefMethSpec (SrcSpan, Type)
VanillaDM)
= do { Name
dm_name <- Name -> (OccName -> OccName) -> TcRnIf n m Name
forall m n. Name -> (OccName -> OccName) -> TcRnIf m n Name
newImplicitBinder Name
op_name OccName -> OccName
mkDefaultMethodOcc
; Maybe (Name, DefMethSpec Type)
-> IOEnv (Env n m) (Maybe (Name, DefMethSpec Type))
forall a. a -> IOEnv (Env n m) a
forall (m :: * -> *) a. Monad m => a -> m a
return ((Name, DefMethSpec Type) -> Maybe (Name, DefMethSpec Type)
forall a. a -> Maybe a
Just (Name
dm_name, DefMethSpec Type
forall ty. DefMethSpec ty
VanillaDM)) }
mk_dm_info Name
op_name (Just (GenericDM (SrcSpan
loc, Type
dm_ty)))
= do { Name
dm_name <- Name -> (OccName -> OccName) -> SrcSpan -> TcRnIf n m Name
forall m n.
Name -> (OccName -> OccName) -> SrcSpan -> TcRnIf m n Name
newImplicitBinderLoc Name
op_name OccName -> OccName
mkDefaultMethodOcc SrcSpan
loc
; Maybe (Name, DefMethSpec Type)
-> IOEnv (Env n m) (Maybe (Name, DefMethSpec Type))
forall a. a -> IOEnv (Env n m) a
forall (m :: * -> *) a. Monad m => a -> m a
return ((Name, DefMethSpec Type) -> Maybe (Name, DefMethSpec Type)
forall a. a -> Maybe a
Just (Name
dm_name, Type -> DefMethSpec Type
forall ty. ty -> DefMethSpec ty
GenericDM Type
dm_ty)) }
newImplicitBinder :: Name
-> (OccName -> OccName)
-> TcRnIf m n Name
newImplicitBinder :: forall m n. Name -> (OccName -> OccName) -> TcRnIf m n Name
newImplicitBinder Name
base_name OccName -> OccName
mk_sys_occ
= Name -> (OccName -> OccName) -> SrcSpan -> TcRnIf m n Name
forall m n.
Name -> (OccName -> OccName) -> SrcSpan -> TcRnIf m n Name
newImplicitBinderLoc Name
base_name OccName -> OccName
mk_sys_occ (Name -> SrcSpan
nameSrcSpan Name
base_name)
newImplicitBinderLoc :: Name
-> (OccName -> OccName)
-> SrcSpan
-> TcRnIf m n Name
newImplicitBinderLoc :: forall m n.
Name -> (OccName -> OccName) -> SrcSpan -> TcRnIf m n Name
newImplicitBinderLoc Name
base_name OccName -> OccName
mk_sys_occ SrcSpan
loc
| Just Module
mod <- Name -> Maybe Module
nameModule_maybe Name
base_name
= Module -> OccName -> SrcSpan -> TcRnIf m n Name
forall a b. Module -> OccName -> SrcSpan -> TcRnIf a b Name
newGlobalBinder Module
mod OccName
occ SrcSpan
loc
| Bool
otherwise
= do { Unique
uniq <- TcRnIf m n Unique
forall gbl lcl. TcRnIf gbl lcl Unique
newUnique
; Name -> TcRnIf m n Name
forall a. a -> IOEnv (Env m n) a
forall (m :: * -> *) a. Monad m => a -> m a
return (Unique -> OccName -> SrcSpan -> Name
mkInternalName Unique
uniq OccName
occ SrcSpan
loc) }
where
occ :: OccName
occ = OccName -> OccName
mk_sys_occ (Name -> OccName
nameOccName Name
base_name)
newTyConRepName :: Name -> TcRnIf gbl lcl TyConRepName
newTyConRepName :: forall gbl lcl. Name -> TcRnIf gbl lcl Name
newTyConRepName Name
tc_name
| Just Module
mod <- Name -> Maybe Module
nameModule_maybe Name
tc_name
, (Module
mod, OccName
occ) <- Module -> OccName -> (Module, OccName)
tyConRepModOcc Module
mod (Name -> OccName
nameOccName Name
tc_name)
= Module -> OccName -> SrcSpan -> TcRnIf gbl lcl Name
forall a b. Module -> OccName -> SrcSpan -> TcRnIf a b Name
newGlobalBinder Module
mod OccName
occ SrcSpan
noSrcSpan
| Bool
otherwise
= Name -> (OccName -> OccName) -> TcRnIf gbl lcl Name
forall m n. Name -> (OccName -> OccName) -> TcRnIf m n Name
newImplicitBinder Name
tc_name OccName -> OccName
mkTyConRepOcc