summaryrefslogtreecommitdiff
path: root/compiler
diff options
context:
space:
mode:
authorVladislav Zavialov <vlad.z.4096@gmail.com>2023-01-10 23:14:50 +0300
committerVladislav Zavialov <vlad.z.4096@gmail.com>2023-01-18 20:41:52 +0300
commit8b71f510126a190ed296c87b041ae33ad19807e6 (patch)
tree4f0f2b87dd95037378713143ba8b3c9f86609ebc /compiler
parent97ac8230b0a645aae27b7ee42aa55b0c84735684 (diff)
downloadhaskell-wip/int-index/tyconpat-scoping.tar.gz
WIP: 22478 Type patternswip/int-index/tyconpat-scoping
Diffstat (limited to 'compiler')
-rw-r--r--compiler/GHC/Hs/Pat.hs2
-rw-r--r--compiler/GHC/Hs/Utils.hs59
-rw-r--r--compiler/GHC/Rename/HsType.hs84
-rw-r--r--compiler/GHC/Rename/Pat.hs152
-rw-r--r--compiler/Language/Haskell/Syntax/Pat.hs7
5 files changed, 217 insertions, 87 deletions
diff --git a/compiler/GHC/Hs/Pat.hs b/compiler/GHC/Hs/Pat.hs
index 39a788aab5..ed116a6acb 100644
--- a/compiler/GHC/Hs/Pat.hs
+++ b/compiler/GHC/Hs/Pat.hs
@@ -28,7 +28,7 @@ module GHC.Hs.Pat (
HsPatExpansion(..),
XXPatGhcTc(..),
- HsConPatDetails, hsConPatArgs,
+ HsConPatDetails, hsConPatArgs, hsConPatTyArgs,
HsConPatTyArg(..),
HsRecFields(..), HsFieldBind(..), LHsFieldBind,
HsRecField, LHsRecField,
diff --git a/compiler/GHC/Hs/Utils.hs b/compiler/GHC/Hs/Utils.hs
index af222bf98a..c7380990e9 100644
--- a/compiler/GHC/Hs/Utils.hs
+++ b/compiler/GHC/Hs/Utils.hs
@@ -1136,6 +1136,8 @@ data CollectFlag p where
CollNoDictBinders :: CollectFlag p
-- | Collect evidence binders
CollWithDictBinders :: CollectFlag GhcTc
+ -- | Collect variable and type variable binders, but no evidence binders
+ CollVarTyVarBinders :: CollectFlag GhcRn
collect_lpat :: forall p. CollectPass p
=> CollectFlag p
@@ -1171,6 +1173,63 @@ collect_pat flag pat bndrs = case pat of
CollNoDictBinders -> foldr (collect_lpat flag) bndrs (hsConPatArgs ps)
CollWithDictBinders -> foldr (collect_lpat flag) bndrs (hsConPatArgs ps)
++ collectEvBinders (cpt_binds (pat_con_ext pat))
+ CollVarTyVarBinders ->
+ let { unwrapTyArg (HsConPatTyArg _ t) = hsps_body t
+ ; bndrs' = foldr (collect_lpat flag) bndrs (hsConPatArgs ps)
+ ; bndrs'' = foldr (collect_ltypat . unwrapTyArg) bndrs' (hsConPatTyArgs ps)
+ } in bndrs''
+
+collect_ltypat :: LHsType GhcRn -> [Name] -> [Name]
+collect_ltypat ltypat = collect_typat (unLoc ltypat)
+
+collect_typat :: HsType GhcRn -> [Name] -> [Name]
+collect_typat typat bndrs = case typat of
+ HsTyVar _ _ (L _ name)
+ | isTyVarName name -> name : bndrs
+ | otherwise -> bndrs
+ HsParTy _ t -> collect_ltypat t bndrs
+ HsWildCardTy _ -> bndrs
+ HsAppTy _ t1 t2 -> collect_ltypat t1 (collect_ltypat t2 bndrs)
+ HsAppKindTy _ t1 _ t2 -> collect_ltypat t1 (collect_ltypat t2 bndrs)
+ HsOpTy _ _ t1 op t2 -> unLoc op : collect_ltypat t1 (collect_ltypat t2 bndrs)
+ HsQualTy _ (L _ ts) t -> foldr collect_ltypat (collect_ltypat t bndrs) ts
+ HsFunTy _ arr t1 t2 -> collect_arr arr (collect_ltypat t1 (collect_ltypat t2 bndrs))
+ HsListTy _ t -> collect_ltypat t bndrs
+ HsTupleTy _ _ ts -> foldr collect_ltypat bndrs ts
+ HsSumTy _ ts -> foldr collect_ltypat bndrs ts
+ HsExplicitListTy _ _ ts -> foldr collect_ltypat bndrs ts
+ HsExplicitTupleTy _ ts -> foldr collect_ltypat bndrs ts
+ HsStarTy _ _ -> bndrs
+ HsKindSig _ t _ ->
+ -- Do not collect variables in the sig: they are usages, not bindings.
+ -- See ghc-proposals/pull/556
+ collect_ltypat t bndrs
+ HsForAllTy _ _ t ->
+ -- Discard the telescope since it does not affect what variables are bound.
+ -- Consider:
+ -- f (MkT @(forall a. Maybe a)) = rhs
+ -- The "a" in "Maybe a" is *not* forall-bound, it is its own binding
+ -- that scopes outside the forall.
+ collect_ltypat t bndrs
+ HsBangTy _ _ t -> collect_ltypat t bndrs
+ HsDocTy _ t _ -> collect_ltypat t bndrs
+ HsIParamTy _ _ t -> collect_ltypat t bndrs
+ HsTyLit _ _ -> bndrs
+ HsSpliceTy _ _ -> bndrs -- FIXME (int-index): reconsider after fixing the fSpliceTy example
+ HsRecTy{} ->
+ -- Not valid syntax in type patterns, but we need to return something
+ -- instead of panicking to let the type error (generated elsewhere) propagate.
+ bndrs
+ XHsType{} ->
+ -- XHsType at GhcRn is only produced by deriving, which never generates type patterns,
+ -- so this case is unreachable at the moment.
+ panic "collect_typat: XHsType"
+
+ where
+ collect_arr :: HsArrow GhcRn -> [Name] -> [Name]
+ collect_arr (HsUnrestrictedArrow _) = id
+ collect_arr (HsLinearArrow _) = id
+ collect_arr (HsExplicitMult _ t _) = collect_ltypat t
collectEvBinders :: TcEvBinds -> [Id]
collectEvBinders (EvBinds bs) = foldr add_ev_bndr [] bs
diff --git a/compiler/GHC/Rename/HsType.hs b/compiler/GHC/Rename/HsType.hs
index f9720a53e1..521fc65f04 100644
--- a/compiler/GHC/Rename/HsType.hs
+++ b/compiler/GHC/Rename/HsType.hs
@@ -14,12 +14,13 @@ module GHC.Rename.HsType (
-- Type related stuff
rnHsType, rnLHsType, rnLHsTypes, rnContext, rnMaybeContext,
rnLHsKind, rnLHsTypeArgs,
- rnHsSigType, rnHsWcType, rnHsPatSigTypeBindingVars,
+ rnHsSigType, rnHsWcType,
HsPatSigTypeScoping(..), rnHsSigWcType, rnHsPatSigType,
newTyVarNameRn,
rnConDeclFields,
lookupField,
rnLTyVar,
+ rnHsTyLit,
rnScaledLHsType,
@@ -81,8 +82,6 @@ import qualified GHC.LanguageExtensions as LangExt
import Language.Haskell.Syntax.Basic (FieldLabelString(..))
import Data.List (nubBy, partition)
-import qualified Data.List.NonEmpty as NE
-import Data.List.NonEmpty (NonEmpty(..))
import Control.Monad
{-
@@ -185,57 +184,6 @@ rnHsWcType ctxt (HsWC { hswc_body = hs_ty })
; let sig_ty' = HsWC { hswc_ext = wcs, hswc_body = hs_ty' }
; return (sig_ty', fvs) }
--- Similar to rnHsWcType, but rather than requiring free variables in the type to
--- already be in scope, we are going to require them not to be in scope,
--- and we bind them.
-rnHsPatSigTypeBindingVars :: HsDocContext
- -> HsPatSigType GhcPs
- -> (HsPatSigType GhcRn -> RnM (r, FreeVars))
- -> RnM (r, FreeVars)
-rnHsPatSigTypeBindingVars ctxt sigType thing_inside = case sigType of
- (HsPS { hsps_body = hs_ty }) -> do
- rdr_env <- getLocalRdrEnv
- let (varsInScope, varsNotInScope) =
- partition (inScope rdr_env . unLoc) (extractHsTyRdrTyVars hs_ty)
- -- TODO: Resolve and remove this comment.
- -- This next bit is in some contention. The original proposal #126
- -- (https://github.com/ghc-proposals/ghc-proposals/blob/master/proposals/0126-type-applications-in-patterns.rst)
- -- says that in-scope variables are fine here: don't bind them, just use
- -- the existing vars, like in type signatures. An amendment #291
- -- (https://github.com/ghc-proposals/ghc-proposals/pull/291) says that the
- -- use of an in-scope variable should *shadow* an in-scope tyvar, like in
- -- terms. In an effort to make forward progress, the current implementation
- -- just rejects any use of an in-scope variable, meaning GHC will accept
- -- a subset of programs common to both variants. If this comment still exists
- -- in mid-to-late 2021 or thereafter, we have done a poor job on following
- -- up on this point.
- -- Example:
- -- f :: forall a. ...
- -- f (MkT @a ...) = ...
- -- Should the inner `a` refer to the outer one? shadow it? We are, as yet, undecided,
- -- so we currently reject.
- when (not (null varsInScope)) $
- addErr $ mkTcRnUnknownMessage $ mkPlainError noHints $
- vcat
- [ text "Type variable" <> plural varsInScope
- <+> hcat (punctuate (text ",") (map (quotes . ppr) varsInScope))
- <+> isOrAre varsInScope
- <+> text "already in scope."
- , text "Type applications in patterns must bind fresh variables, without shadowing."
- ]
- (wcVars, ibVars) <- partition_nwcs varsNotInScope
- rnImplicitTvBndrs ctxt Nothing ibVars $ \ ibVars' -> do
- (wcVars', hs_ty', fvs) <- rnWcBody ctxt wcVars hs_ty
- let sig_ty = HsPS
- { hsps_body = hs_ty'
- , hsps_ext = HsPSRn
- { hsps_nwcs = wcVars'
- , hsps_imp_tvs = ibVars'
- }
- }
- (res, fvs') <- thing_inside sig_ty
- return (res, fvs `plusFV` fvs')
-
rnWcBody :: HsDocContext -> [LocatedN RdrName] -> LHsType GhcPs
-> RnM ([Name], LHsType GhcRn, FreeVars)
rnWcBody ctxt nwc_rdrs hs_ty
@@ -432,34 +380,6 @@ type signature, since the type signature implicitly carries their binding
sites. This is less precise, but more accurate.
-}
--- | Create fresh type variables for binders, disallowing multiple occurrences of the same variable. Similar to `rnImplicitTvOccs` except that duplicate occurrences will
--- result in an error, and the source locations of the variables are not adjusted, as these variable occurrences are themselves the binding sites for the type variables,
--- rather than the variables being implicitly bound by a signature.
-rnImplicitTvBndrs :: HsDocContext
- -> Maybe assoc
- -- ^ @'Just' _@ => an associated type decl
- -> FreeKiTyVars
- -- ^ Surface-syntax free vars that we will implicitly bind.
- -- Duplicate variables will cause a compile-time error regarding repeated bindings.
- -> ([Name] -> RnM (a, FreeVars))
- -> RnM (a, FreeVars)
-rnImplicitTvBndrs ctx mb_assoc implicit_vs_with_dups thing_inside
- = do { implicit_vs <- forM (NE.groupAllWith unLoc $ implicit_vs_with_dups) $ \case
- (x :| []) -> return x
- (x :| _) -> do
- let msg = mkTcRnUnknownMessage $ mkPlainError noHints $
- text "Variable" <+> text "`" <> ppr x <> text "'" <+> text "would be bound multiple times by" <+> pprHsDocContext ctx <> text "."
- addErr msg
- return x
-
- ; traceRn "rnImplicitTvBndrs" $
- vcat [ ppr implicit_vs_with_dups, ppr implicit_vs ]
-
- ; vars <- mapM (newTyVarNameRn mb_assoc) implicit_vs
-
- ; bindLocalNamesFV vars $
- thing_inside vars }
-
{- ******************************************************
* *
LHsType and HsType
diff --git a/compiler/GHC/Rename/Pat.hs b/compiler/GHC/Rename/Pat.hs
index 169c2e508c..1a7a82ccf7 100644
--- a/compiler/GHC/Rename/Pat.hs
+++ b/compiler/GHC/Rename/Pat.hs
@@ -53,7 +53,8 @@ import GHC.Rename.Utils ( newLocalBndrRn, bindLocalNames
, warnUnusedMatches, newLocalBndrRn
, checkUnusedRecordWildcard
, checkDupNames, checkDupAndShadowedNames
- , wrapGenSpan, genHsApps, genLHsVar, genHsIntegralLit, warnForallIdentifier )
+ , wrapGenSpan, genHsApps, genLHsVar, genHsIntegralLit, warnForallIdentifier
+ , bindLocalNamesFV )
import GHC.Rename.HsType
import GHC.Builtin.Names
import GHC.Types.Avail ( greNameMangledName )
@@ -75,8 +76,11 @@ import GHC.Driver.Session ( getDynFlags, xopt_DuplicateRecordFields )
import qualified GHC.LanguageExtensions as LangExt
import Control.Monad ( when, ap, guard, unless )
+import Control.Monad.Trans.Class
+import Control.Monad.Trans.Writer.CPS
import Data.Foldable
import Data.Functor.Identity ( Identity (..) )
+import qualified Data.Semigroup as S
import qualified Data.List.NonEmpty as NE
import Data.Maybe
import Data.Ratio
@@ -145,6 +149,14 @@ wrapSrcSpanCps fn (L loc a)
unCpsRn (fn a) $ \v ->
k (L loc v))
+wrapSrcSpanWriterCps :: Monoid w => (a -> WriterT w CpsRn b) -> LocatedAn ann a -> WriterT w CpsRn (LocatedAn ann b)
+wrapSrcSpanWriterCps fn (L loc a) =
+ mapWriterT
+ (\m -> CpsRn (\k -> setSrcSpanA loc $
+ unCpsRn m $ \(v, acc) ->
+ k (L loc v, acc)))
+ (fn a)
+
lookupConCps :: LocatedN RdrName -> CpsRn (LocatedN Name)
lookupConCps con_rdr
= CpsRn (\k -> do { con_name <- lookupLocatedOccRnConstr con_rdr
@@ -424,7 +436,7 @@ rnPats ctxt pats thing_inside
-- complain *twice* about duplicates e.g. f (x,x) = ...
--
-- See Note [Don't report shadowing for pattern synonyms]
- ; let bndrs = collectPatsBinders CollNoDictBinders (toList pats')
+ ; let bndrs = collectPatsBinders CollVarTyVarBinders (toList pats')
; addErrCtxt doc_pat $
if isPatSynCtxt ctxt
then checkDupNames bndrs
@@ -649,7 +661,7 @@ rnConPatAndThen mk con (PrefixCon tyargs pats)
<+> quotes (ppr tyarg))
2 (text "Perhaps you intended to use TypeAbstractions")
rnConPatTyArg (HsConPatTyArg at t) = do
- t' <- liftCpsWithCont $ rnHsPatSigTypeBindingVars HsTypeCtx t
+ t' <- rnHsTyPat t
return (HsConPatTyArg at t')
rnConPatAndThen mk con (InfixCon pat1 pat2)
@@ -711,6 +723,140 @@ rnHsRecPatsAndThen mk (L _ con)
nested_mk (Just (unLoc -> n)) (LamMk report_unused) n'
= LamMk (report_unused && (n' <= n))
+{- *********************************************************************
+* *
+ Type patterns
+* *
+********************************************************************* -}
+
+data TyPatVarsAccum =
+ TyPatVarsAccum {
+ tpv_acc_nwcs :: [Name] -> [Name], -- ^ Wildcard names
+ tpv_acc_exp_tvs :: [Name] -> [Name], -- ^ Explicitly bound variable names
+ tpv_acc_imp_tvs :: [Name] -> [Name] -- ^ Implicitly bound variable names
+ }
+
+instance Semigroup TyPatVarsAccum where
+ TyPatVarsAccum a1 b1 c1 <> TyPatVarsAccum a2 b2 c2 =
+ TyPatVarsAccum (a1 S.<> a2) (b1 S.<> b2) (c1 S.<> c2)
+
+instance Monoid TyPatVarsAccum where
+ mempty = TyPatVarsAccum id id id
+
+tpv_HsPSRn :: TyPatVarsAccum -> HsPSRn
+tpv_HsPSRn (TyPatVarsAccum nwcs_acc exp_tvs_acc imp_tvs_acc) =
+ HsPSRn (nwcs_acc []) (exp_tvs_acc (imp_tvs_acc []))
+
+tpv_exp_tv :: Name -> TyPatVarsAccum
+tpv_exp_tv tv = mempty { tpv_acc_exp_tvs = (tv:) }
+
+tpv_sig_tvs :: HsPSRn -> TyPatVarsAccum
+tpv_sig_tvs (HsPSRn nwcs imp_tvs) =
+ mempty { tpv_acc_nwcs = (nwcs++)
+ , tpv_acc_imp_tvs = (imp_tvs++) }
+
+rnHsTyPat :: HsPatSigType GhcPs -> CpsRn (HsPatSigType GhcRn)
+rnHsTyPat (HsPS _ hs_top_ty) =
+ do { (hs_top_ty', tpv_acc) <- runWriterT (go_lty hs_top_ty)
+ ; return (HsPS (tpv_HsPSRn tpv_acc) hs_top_ty') }
+ where
+ go_lty :: LHsType GhcPs -> WriterT TyPatVarsAccum CpsRn (LHsType GhcRn)
+ go_lty = wrapSrcSpanWriterCps go_ty
+
+ go_ty :: HsType GhcPs -> WriterT TyPatVarsAccum CpsRn (HsType GhcRn)
+ go_ty (HsTyVar _ prom lrdr) =
+ fmap (\lnm -> HsTyVar noAnn prom lnm)
+ (go_name prom lrdr)
+ go_ty (HsParTy _ t) =
+ do { t' <- go_lty t
+ ; return (HsParTy noAnn t') }
+ go_ty (HsWildCardTy _) = return (HsWildCardTy noExtField)
+ go_ty (HsAppTy _ ty1 ty2) =
+ do { ty1' <- go_lty ty1
+ ; ty2' <- go_lty ty2
+ ; return (HsAppTy noExtField ty1' ty2') }
+ go_ty (HsAppKindTy _ ty1 at ty2) =
+ do { ty1' <- go_lty ty1
+ ; ty2' <- go_lty ty2
+ ; return (HsAppKindTy noExtField ty1' at ty2') }
+ go_ty (HsOpTy _ prom ty1 op ty2) =
+ do { op' <- go_name prom op
+ ; ty1' <- go_lty ty1
+ ; ty2' <- go_lty ty2
+ ; return (HsOpTy noAnn prom ty1' op' ty2') }
+ -- FIXME (int-index): check operator fixity
+ go_ty (HsQualTy _ lctx t) =
+ do { lctx' <- wrapSrcSpanWriterCps (mapM go_lty) lctx
+ ; t' <- go_lty t
+ ; return (HsQualTy noExtField lctx' t') }
+ go_ty (HsFunTy u mult ty1 ty2) =
+ do { mult' <- go_arr mult
+ ; ty1' <- go_lty ty1
+ ; ty2' <- go_lty ty2
+ ; return (HsFunTy u mult' ty1' ty2') }
+ go_ty (HsListTy x t) =
+ do { t' <- go_lty t
+ ; return (HsListTy x t') }
+ go_ty (HsTupleTy x tup_con ts) =
+ do { ts' <- mapM go_lty ts
+ ; return (HsTupleTy x tup_con ts') }
+ go_ty (HsSumTy x ts) =
+ do { ts' <- mapM go_lty ts
+ ; return (HsSumTy x ts') }
+ go_ty (HsExplicitListTy _ prom ts) =
+ do { ts' <- mapM go_lty ts
+ ; return (HsExplicitListTy noExtField prom ts') }
+ go_ty (HsExplicitTupleTy _ ts) =
+ do { ts' <- mapM go_lty ts
+ ; return (HsExplicitTupleTy noExtField ts') }
+ go_ty (HsStarTy _ isUni) = return (HsStarTy noExtField isUni)
+ go_ty (HsKindSig x t k) =
+ do { k' <- go_lksig k
+ ; t' <- go_lty t
+ ; return (HsKindSig x t' k') }
+ go_ty (HsForAllTy _ _ _) = panic "rnHsTyPat: HsForAllTy"
+ go_ty (HsBangTy _ _ _) = panic "rnHsTyPat: HsBangTy"
+ go_ty (HsDocTy _ _ _) = panic "rnHsTyPat: HsDocTy"
+ go_ty (HsIParamTy x n t) =
+ do { t' <- go_lty t
+ ; return (HsIParamTy x n t') }
+ go_ty (HsTyLit src lit) = return (HsTyLit src (rnHsTyLit lit))
+ go_ty (HsSpliceTy _ _) = panic "rnHsTyPat: HsSpliceTy"
+ go_ty HsRecTy{} = panic "rnHsTyPat: HsRecTy"
+ go_ty XHsType{} =
+ -- XHsType at GhcRn is only produced by deriving, which never generates type patterns,
+ -- so this case is unreachable at the moment.
+ panic "rnHsTyPat: XHsType"
+
+ go_lksig :: LHsKind GhcPs -> WriterT TyPatVarsAccum CpsRn (LHsKind GhcRn)
+ go_lksig k =
+ do { sig' <- lift $ liftCpsWithCont $ rnHsPatSigType AlwaysBind PatCtx (HsPS noAnn k)
+ ; let !(HsPS x k') = sig'
+ ; writer (k', tpv_sig_tvs x) }
+
+ go_name :: PromotionFlag -> LIdP GhcPs -> WriterT TyPatVarsAccum CpsRn (LIdP GhcRn)
+ go_name _ lrdr
+ | isRdrTyVar (unLoc lrdr) = go_var lrdr -- Type variable binding
+ | otherwise = lift $ liftCpsFV $ -- Type constructor usage
+ do { lnm@(L _ nm) <- rnLTyVar lrdr
+ ; return (lnm, unitFV nm) }
+
+ go_var :: LIdP GhcPs -> WriterT TyPatVarsAccum CpsRn (LIdP GhcRn)
+ go_var lrdr =
+ writerT $ liftCpsWithCont $ \thing_inside ->
+ do { nm <- newTyVarNameRn Nothing lrdr
+ ; let lnm = L (getLoc lrdr) nm
+ ; bindLocalNamesFV [nm] $
+ thing_inside (lnm, tpv_exp_tv nm)
+ }
+
+ go_arr :: HsArrow GhcPs -> WriterT TyPatVarsAccum CpsRn (HsArrow GhcRn)
+ go_arr (HsUnrestrictedArrow arr) = return (HsUnrestrictedArrow arr)
+ go_arr (HsLinearArrow (HsPct1 pct1 arr)) = return (HsLinearArrow (HsPct1 pct1 arr))
+ go_arr (HsLinearArrow (HsLolly arr)) = return (HsLinearArrow (HsLolly arr))
+ go_arr (HsExplicitMult pct p arr) =
+ do { p' <- go_lty p
+ ; return (HsExplicitMult pct p' arr) }
{- *********************************************************************
* *
diff --git a/compiler/Language/Haskell/Syntax/Pat.hs b/compiler/Language/Haskell/Syntax/Pat.hs
index 66b9708bfe..fd5b052433 100644
--- a/compiler/Language/Haskell/Syntax/Pat.hs
+++ b/compiler/Language/Haskell/Syntax/Pat.hs
@@ -22,7 +22,7 @@ module Language.Haskell.Syntax.Pat (
Pat(..), LPat,
ConLikeP,
- HsConPatDetails, hsConPatArgs,
+ HsConPatDetails, hsConPatArgs, hsConPatTyArgs,
HsConPatTyArg(..),
HsRecFields(..), HsFieldBind(..), LHsFieldBind,
HsRecField, LHsRecField,
@@ -243,6 +243,11 @@ hsConPatArgs (PrefixCon _ ps) = ps
hsConPatArgs (RecCon fs) = Data.List.map (hfbRHS . unXRec @p) (rec_flds fs)
hsConPatArgs (InfixCon p1 p2) = [p1,p2]
+hsConPatTyArgs :: forall p. HsConPatDetails p -> [HsConPatTyArg (NoGhcTc p)]
+hsConPatTyArgs (PrefixCon tyargs _) = tyargs
+hsConPatTyArgs (RecCon _) = []
+hsConPatTyArgs (InfixCon _ _) = []
+
-- | Haskell Record Fields
--
-- HsRecFields is used only for patterns and expressions (not data type