recursion-ninja pushed to branch wip/fix-26670 at Glasgow Haskell Compiler / GHC
Commits:
-
b57f032c
by Recursion Ninja at 2025-12-17T09:20:10-05:00
15 changed files:
- compiler/GHC/Core/Opt/WorkWrap.hs
- compiler/GHC/HsToCore.hs
- compiler/GHC/HsToCore/Binds.hs
- compiler/GHC/HsToCore/Quote.hs
- compiler/GHC/Rename/Bind.hs
- compiler/GHC/Tc/Deriv/Generics.hs
- compiler/GHC/Tc/Gen/Arrow.hs
- compiler/GHC/Tc/TyCl/Instance.hs
- compiler/GHC/Tc/Utils/Instantiate.hs
- + compiler/GHC/Types/Arity.hs
- compiler/GHC/Types/Basic.hs
- compiler/GHC/Types/Id/Info.hs
- compiler/GHC/Types/InlinePragma.hs
- compiler/Language/Haskell/Syntax/Binds.hs
- compiler/ghc.cabal.in
Changes:
| ... | ... | @@ -834,7 +834,7 @@ mkWWBindPair ww_opts fn_id fn_info fn_args fn_body work_uniq div |
| 834 | 834 | _ -> inl_act wrap_prag
|
| 835 | 835 | |
| 836 | 836 | srcTxt = SourceText $ fsLit "{-# INLINE"
|
| 837 | - work_prag = InlinePragma { inl_src = XInlinePragmaGhcRn srcTxt arity
|
|
| 837 | + work_prag = InlinePragma { inl_src = InlinePragmaGhcTag srcTxt arity
|
|
| 838 | 838 | , inl_inline = fn_inline_spec
|
| 839 | 839 | , inl_act = work_act
|
| 840 | 840 | , inl_rule = FunLike }
|
| ... | ... | @@ -901,7 +901,7 @@ mkStrWrapperInlinePrag :: InlinePragma (GhcPass p) -> [CoreRule] -> Arity -> Inl |
| 901 | 901 | mkStrWrapperInlinePrag (InlinePragma { inl_inline = fn_inl
|
| 902 | 902 | , inl_act = fn_act
|
| 903 | 903 | , inl_rule = rule_info }) rules arity
|
| 904 | - = InlinePragma { inl_src = XInlinePragmaGhcRn srcTxt arity
|
|
| 904 | + = InlinePragma { inl_src = InlinePragmaGhcTag srcTxt arity
|
|
| 905 | 905 | |
| 906 | 906 | , inl_inline = fn_inl
|
| 907 | 907 | -- See Note [Worker/wrapper for INLINABLE functions]
|
| ... | ... | @@ -77,6 +77,7 @@ import GHC.Utils.Logger |
| 77 | 77 | import GHC.Types.Id
|
| 78 | 78 | import GHC.Types.Id.Info
|
| 79 | 79 | import GHC.Types.Id.Make ( mkRepPolyIdConcreteTyVars )
|
| 80 | +import GHC.Types.InlinePragma ( alwaysInlinePragma )
|
|
| 80 | 81 | import GHC.Types.ForeignStubs
|
| 81 | 82 | import GHC.Types.Avail
|
| 82 | 83 | import GHC.Types.Var.Set
|
| ... | ... | @@ -49,7 +49,6 @@ import GHC.Core.Opt.OccurAnal ( occurAnalyseExpr ) |
| 49 | 49 | import GHC.Core.InstEnv ( CanonicalEvidence(..) )
|
| 50 | 50 | import GHC.Core.Make
|
| 51 | 51 | import GHC.Core.Utils
|
| 52 | -import GHC.Core.Opt.Arity ( etaExpand )
|
|
| 53 | 52 | import GHC.Core.Unfold.Make
|
| 54 | 53 | import GHC.Core.FVs
|
| 55 | 54 | import GHC.Core.Predicate
|
| ... | ... | @@ -1097,7 +1097,7 @@ rep_wc_ty_sig mk_sig loc sig_ty nm |
| 1097 | 1097 | = rep_ty_sig mk_sig loc (hswc_body sig_ty) nm
|
| 1098 | 1098 | |
| 1099 | 1099 | rep_inline :: LocatedN Name
|
| 1100 | - -> InlinePragma -- Never defaultInlinePragma
|
|
| 1100 | + -> InlinePragma GhcRn -- Never defaultInlinePragma
|
|
| 1101 | 1101 | -> SrcSpan
|
| 1102 | 1102 | -> MetaM [(SrcSpan, Core (M TH.Dec))]
|
| 1103 | 1103 | rep_inline nm ispec loc
|
| ... | ... | @@ -1116,7 +1116,7 @@ rep_inline nm ispec loc |
| 1116 | 1116 | ; return [(loc, pragma)]
|
| 1117 | 1117 | }
|
| 1118 | 1118 | |
| 1119 | -rep_inline_phases :: InlinePragma -> MetaM (Maybe (Core TH.Inline), Core TH.Phases)
|
|
| 1119 | +rep_inline_phases :: InlinePragma GhcRn -> MetaM (Maybe (Core TH.Inline), Core TH.Phases)
|
|
| 1120 | 1120 | rep_inline_phases (InlinePragma { inl_act = act, inl_inline = inl })
|
| 1121 | 1121 | = do { phases <- repPhases act
|
| 1122 | 1122 | ; inl <- if noUserInlineSpec inl
|
| ... | ... | @@ -1126,7 +1126,7 @@ rep_inline_phases (InlinePragma { inl_act = act, inl_inline = inl }) |
| 1126 | 1126 | else Just <$> repInline inl
|
| 1127 | 1127 | ; return (inl, phases) }
|
| 1128 | 1128 | |
| 1129 | -rep_specialise :: LocatedN Name -> LHsSigType GhcRn -> InlinePragma
|
|
| 1129 | +rep_specialise :: LocatedN Name -> LHsSigType GhcRn -> InlinePragma GhcRn
|
|
| 1130 | 1130 | -> SrcSpan
|
| 1131 | 1131 | -> MetaM [(SrcSpan, Core (M TH.Dec))]
|
| 1132 | 1132 | rep_specialise nm ty ispec loc
|
| ... | ... | @@ -1138,7 +1138,7 @@ rep_specialise nm ty ispec loc |
| 1138 | 1138 | ; return [(loc, pragma)]
|
| 1139 | 1139 | }
|
| 1140 | 1140 | |
| 1141 | -rep_specialiseE :: RuleBndrs GhcRn -> LHsExpr GhcRn -> InlinePragma
|
|
| 1141 | +rep_specialiseE :: RuleBndrs GhcRn -> LHsExpr GhcRn -> InlinePragma GhcRn
|
|
| 1142 | 1142 | -> MetaM (Core (M TH.Dec))
|
| 1143 | 1143 | rep_specialiseE bndrs e ispec
|
| 1144 | 1144 | -- New form SPECIALISE pragmas
|
| ... | ... | @@ -1111,15 +1111,15 @@ renameSig ctxt sig@(SpecSig _ v tys inl) |
| 1111 | 1111 | ; return ( new_ty:tys, fvs_ty `plusFV` fvs) }
|
| 1112 | 1112 | |
| 1113 | 1113 | renameSig _ctxt (SpecSigE _ bndrs spec_e inl)
|
| 1114 | - = do { (fn_rdr <- checkSpecESigShape spec_e
|
|
| 1115 | - ; (fn_name <- lookupOccRn WL_TermVariable fn_rdr -- Checks that the head isn't forall-bound
|
|
| 1114 | + = do { fn_rdr <- checkSpecESigShape spec_e
|
|
| 1115 | + ; fn_name <- lookupOccRn WL_TermVariable fn_rdr -- Checks that the head isn't forall-bound
|
|
| 1116 | 1116 | ; bindRuleBndrs (SpecECtx fn_rdr) bndrs $ \_ bndrs' ->
|
| 1117 | 1117 | do { (spec_e', fvs) <- rnLExpr spec_e
|
| 1118 | - ; return (SpecSigE fn_name bndrs' spec_e' ( inl), fvs) } }
|
|
| 1118 | + ; return (SpecSigE fn_name bndrs' spec_e' ( inl `setInlinePragmaArity` 0), fvs) } } -- TODO: setting arity to 0 is likely wrong
|
|
| 1119 | 1119 | |
| 1120 | 1120 | renameSig ctxt sig@(InlineSig _ v s)
|
| 1121 | 1121 | = do { new_v <- lookupSigOccRn ctxt sig v
|
| 1122 | - ; return (InlineSig noAnn new_v s, emptyFVs) }
|
|
| 1122 | + ; return (InlineSig noAnn new_v ( s `setInlinePragmaArity` 0 ), emptyFVs) } -- TODO: setting arity to 0 is likely wrong
|
|
| 1123 | 1123 | |
| 1124 | 1124 | renameSig ctxt (FixSig _ fsig)
|
| 1125 | 1125 | = do { new_fsig <- rnSrcFixityDecl ctxt fsig
|
| ... | ... | @@ -42,6 +42,7 @@ import GHC.Unit.Module ( moduleName, moduleUnit |
| 42 | 42 | |
| 43 | 43 | import GHC.Iface.Env ( newGlobalBinder )
|
| 44 | 44 | |
| 45 | +import GHC.Types.InlinePragma ( alwaysInlinePragma )
|
|
| 45 | 46 | import GHC.Types.Name hiding ( varName )
|
| 46 | 47 | import GHC.Types.Name.Reader
|
| 47 | 48 | import GHC.Types.SrcLoc
|
| ... | ... | @@ -34,6 +34,7 @@ import GHC.Tc.Types.Origin |
| 34 | 34 | import GHC.Tc.Types.Evidence
|
| 35 | 35 | import GHC.Core.Multiplicity
|
| 36 | 36 | import GHC.Core.Coercion
|
| 37 | +import GHC.Types.Arity ( Arity )
|
|
| 37 | 38 | import GHC.Types.Id( mkLocalId )
|
| 38 | 39 | import GHC.Tc.Utils.Instantiate
|
| 39 | 40 | import GHC.Builtin.Types
|
| ... | ... | @@ -73,6 +73,8 @@ import GHC.Types.Var.Env |
| 73 | 73 | import GHC.Types.Var.Set
|
| 74 | 74 | import GHC.Types.Basic
|
| 75 | 75 | import GHC.Types.Id
|
| 76 | +import GHC.Types.Id.Info (arityInfo)
|
|
| 77 | +import GHC.Types.InlinePragma
|
|
| 76 | 78 | import GHC.Types.SourceFile
|
| 77 | 79 | import GHC.Types.SourceText
|
| 78 | 80 | import GHC.Types.Name
|
| ... | ... | @@ -1430,11 +1432,12 @@ addDFunPrags :: DFunId -> [Id] -> DFunId |
| 1430 | 1432 | -- is messing with.
|
| 1431 | 1433 | addDFunPrags dfun_id sc_meth_ids
|
| 1432 | 1434 | = dfun_id `setIdUnfolding` mkDFunUnfolding dfun_bndrs dict_con dict_args
|
| 1433 | - `setInlinePragma` dfunInlinePragma
|
|
| 1435 | + `setInlinePragma` (dfunInlinePragma `setInlinePragmaArity` arity) -- NOTE: Check if this arity calculation is correct
|
|
| 1434 | 1436 | -- NB: mkDFunUnfolding takes care of unary classes
|
| 1435 | 1437 | where
|
| 1436 | - dict_args = map Type inst_tys ++
|
|
| 1437 | - [mkVarApps (Var id) dfun_bndrs | id <- sc_meth_ids]
|
|
| 1438 | + arity = length var_apps
|
|
| 1439 | + dict_args = map Type inst_tys ++ var_apps
|
|
| 1440 | + var_apps = [mkVarApps (Var id) dfun_bndrs | id <- sc_meth_ids]
|
|
| 1438 | 1441 | |
| 1439 | 1442 | (dfun_tvs, dfun_theta, clas, inst_tys) = tcSplitDFunTy (idType dfun_id)
|
| 1440 | 1443 | ev_ids = mkTemplateLocalsNum 1 dfun_theta
|
| ... | ... | @@ -2266,7 +2269,8 @@ mkDefMethBind :: SrcSpan -> DFunId -> Class -> Id -> Name |
| 2266 | 2269 | mkDefMethBind loc dfun_id clas sel_id dm_name dm_spec
|
| 2267 | 2270 | = do { logger <- getLogger
|
| 2268 | 2271 | ; dm_id <- tcLookupId dm_name
|
| 2269 | - ; let inline_prag = idInlinePragma dm_id
|
|
| 2272 | + ; let inline_prag :: InlinePragma GhcRn
|
|
| 2273 | + inline_prag = demoteInlinePragmaRn $ idInlinePragma dm_id
|
|
| 2270 | 2274 | inline_prags | isAnyInlinePragma inline_prag
|
| 2271 | 2275 | = [noLocA (InlineSig noAnn fn inline_prag)]
|
| 2272 | 2276 | | otherwise
|
| ... | ... | @@ -2668,9 +2672,11 @@ tcSpecInstPrags dfun_id (InstBindings { ib_binds = binds, ib_pragmas = uprags }) |
| 2668 | 2672 | tcSpecInst :: Id -> Sig GhcRn -> TcM TcSpecPrag
|
| 2669 | 2673 | tcSpecInst dfun_id prag@(SpecInstSig _ hs_ty)
|
| 2670 | 2674 | = addErrCtxt (SpecPragmaCtxt prag) $
|
| 2671 | - do { spec_dfun_ty <- tcHsClsInstType SpecInstCtxt hs_ty
|
|
| 2672 | - ; co_fn <- tcSpecWrapper SpecInstCtxt (idType dfun_id) spec_dfun_ty
|
|
| 2673 | - ; return (SpecPrag dfun_id co_fn defaultInlinePragma) }
|
|
| 2675 | + let arity = arityInfo $ idInfo dfun_id
|
|
| 2676 | + prag = defaultInlinePragma `setInlinePragmaArity` arity
|
|
| 2677 | + in do { spec_dfun_ty <- tcHsClsInstType SpecInstCtxt hs_ty
|
|
| 2678 | + ; co_fn <- tcSpecWrapper SpecInstCtxt (idType dfun_id) spec_dfun_ty
|
|
| 2679 | + ; return (SpecPrag dfun_id co_fn prag) }
|
|
| 2674 | 2680 | |
| 2675 | 2681 | tcSpecInst _ _ = panic "tcSpecInst"
|
| 2676 | 2682 |
| ... | ... | @@ -74,7 +74,8 @@ import GHC.Tc.Zonk.Monad ( ZonkM ) |
| 74 | 74 | import GHC.Rename.Utils( mkRnSyntaxExpr )
|
| 75 | 75 | |
| 76 | 76 | import GHC.Types.Id.Make( mkDictFunId )
|
| 77 | -import GHC.Types.Basic ( TypeOrKind(..), VisArity )
|
|
| 77 | +import GHC.Types.Arity ( Arity, VisArity )
|
|
| 78 | +import GHC.Types.Basic ( TypeOrKind(..) )
|
|
| 78 | 79 | import GHC.Types.SourceText
|
| 79 | 80 | import GHC.Types.SrcLoc as SrcLoc
|
| 80 | 81 | import GHC.Types.Var.Env
|
| 1 | +{-
|
|
| 2 | +(c) The University of Glasgow 2006
|
|
| 3 | +(c) The GRASP/AQUA Project, Glasgow University, 1997-1998
|
|
| 4 | + |
|
| 5 | +\section[BasicTypes]{Miscellaneous types}
|
|
| 6 | + |
|
| 7 | +This module defines a miscellaneously collection of very simple
|
|
| 8 | +types that
|
|
| 9 | + |
|
| 10 | +\begin{itemize}
|
|
| 11 | +\item have no other obvious home
|
|
| 12 | +\item don't depend on any other complicated types
|
|
| 13 | +\item are used in more than one "part" of the compiler
|
|
| 14 | +\end{itemize}
|
|
| 15 | +-}
|
|
| 16 | + |
|
| 17 | +module GHC.Types.Arity
|
|
| 18 | + ( Arity
|
|
| 19 | + , VisArity
|
|
| 20 | + , RepArity
|
|
| 21 | + , JoinArity
|
|
| 22 | + , FullArgCount
|
|
| 23 | + ) where
|
|
| 24 | + |
|
| 25 | +import GHC.Prelude
|
|
| 26 | + |
|
| 27 | +{-
|
|
| 28 | +************************************************************************
|
|
| 29 | +* *
|
|
| 30 | +\subsection[Arity]{Arity}
|
|
| 31 | +* *
|
|
| 32 | +************************************************************************
|
|
| 33 | +-}
|
|
| 34 | + |
|
| 35 | +-- | The number of value arguments that can be applied to a value before it does
|
|
| 36 | +-- "real work". So:
|
|
| 37 | +-- fib 100 has arity 0
|
|
| 38 | +-- \x -> fib x has arity 1
|
|
| 39 | +-- See also Note [Definition of arity] in "GHC.Core.Opt.Arity"
|
|
| 40 | +type Arity = Int
|
|
| 41 | + |
|
| 42 | +-- | Syntactic (visibility) arity, i.e. the number of visible arguments.
|
|
| 43 | +-- See Note [Visibility and arity]
|
|
| 44 | +type VisArity = Int
|
|
| 45 | + |
|
| 46 | +-- | Representation Arity
|
|
| 47 | +--
|
|
| 48 | +-- The number of represented arguments that can be applied to a value before it does
|
|
| 49 | +-- "real work". So:
|
|
| 50 | +-- fib 100 has representation arity 0
|
|
| 51 | +-- \x -> fib x has representation arity 1
|
|
| 52 | +-- \(# x, y #) -> fib (x + y) has representation arity 2
|
|
| 53 | +type RepArity = Int
|
|
| 54 | + |
|
| 55 | +-- | The number of arguments that a join point takes. Unlike the arity of a
|
|
| 56 | +-- function, this is a purely syntactic property and is fixed when the join
|
|
| 57 | +-- point is created (or converted from a value). Both type and value arguments
|
|
| 58 | +-- are counted.
|
|
| 59 | +type JoinArity = Int
|
|
| 60 | + |
|
| 61 | +-- | FullArgCount is the number of type or value arguments in an application,
|
|
| 62 | +-- or the number of type or value binders in a lambda. Note: it includes
|
|
| 63 | +-- both type and value arguments!
|
|
| 64 | +type FullArgCount = Int
|
|
| 65 | + |
|
| 66 | +{- Note [Visibility and arity]
|
|
| 67 | +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
| 68 | +Arity is the number of arguments that a function expects. In a curried language
|
|
| 69 | +like Haskell, there is more than one way to count those arguments.
|
|
| 70 | + |
|
| 71 | +* `Arity` is the classic notion of arity, concerned with evalution, so it counts
|
|
| 72 | + the number of /value/ arguments that need to be supplied before evaluation can
|
|
| 73 | + take place, as described in notes
|
|
| 74 | + Note [Definition of arity] in GHC.Core.Opt.Arity
|
|
| 75 | + Note [Arity and function types] in GHC.Types.Id.Info
|
|
| 76 | + |
|
| 77 | + Examples:
|
|
| 78 | + Int has arity == 0
|
|
| 79 | + Int -> Int has arity <= 1
|
|
| 80 | + Int -> Bool -> Int has arity <= 2
|
|
| 81 | + We write (<=) rather than (==) as sometimes evaluation can occur before all
|
|
| 82 | + value arguments are supplied, depending on the actual function definition.
|
|
| 83 | + |
|
| 84 | + This evaluation-focused notion of arity ignores type arguments, so:
|
|
| 85 | + forall a. a has arity == 0
|
|
| 86 | + forall a. a -> a has arity <= 1
|
|
| 87 | + forall a b. a -> b -> a has arity <= 2
|
|
| 88 | + This is true regardless of ForAllTyFlag, so the arity is also unaffected by
|
|
| 89 | + (forall {a}. ty) or (forall a -> ty).
|
|
| 90 | + |
|
| 91 | + Class dictionaries count towards the arity, as they are passed at runtime
|
|
| 92 | + forall a. (Num a) => a has arity <= 1
|
|
| 93 | + forall a. (Num a) => a -> a has arity <= 2
|
|
| 94 | + forall a b. (Num a, Ord b) => a -> b -> a has arity <= 4
|
|
| 95 | + |
|
| 96 | +* `VisArity` is the syntactic notion of arity. It is the number of /visible/
|
|
| 97 | + arguments, i.e. arguments that occur visibly in the source code.
|
|
| 98 | + |
|
| 99 | + In a function call `f x y z`, we can confidently say that f's vis-arity >= 3,
|
|
| 100 | + simply because we see three arguments [x,y,z]. We write (>=) rather than (==)
|
|
| 101 | + as this could be a partial application.
|
|
| 102 | + |
|
| 103 | + At definition sites, we can acquire an underapproximation of vis-arity by
|
|
| 104 | + counting the patterns on the LHS, e.g. `f a b = rhs` has vis-arity >= 2.
|
|
| 105 | + The actual vis-arity can be higher if there is a lambda on the RHS,
|
|
| 106 | + e.g. `f a b = \c -> rhs`.
|
|
| 107 | + |
|
| 108 | + If we look at the types, we can observe the following
|
|
| 109 | + * function arrows (a -> b) add to the vis-arity
|
|
| 110 | + * visible foralls (forall a -> b) add to the vis-arity
|
|
| 111 | + * constraint arrows (a => b) do not affect the vis-arity
|
|
| 112 | + * invisible foralls (forall a. b) do not affect the vis-arity
|
|
| 113 | + |
|
| 114 | + This means that ForAllTyFlag matters for VisArity (in contrast to Arity),
|
|
| 115 | + while the type/value distinction is unimportant (again in contrast to Arity).
|
|
| 116 | + |
|
| 117 | + Examples:
|
|
| 118 | + Int -- vis-arity == 0 (no args)
|
|
| 119 | + Int -> Int -- vis-arity == 1 (1 funarg)
|
|
| 120 | + forall a. a -> a -- vis-arity == 1 (1 funarg)
|
|
| 121 | + forall a. Num a => a -> a -- vis-arity == 1 (1 funarg)
|
|
| 122 | + forall a -> Num a => a -- vis-arity == 1 (1 req tyarg, 0 funargs)
|
|
| 123 | + forall a -> a -> a -- vis-arity == 2 (1 req tyarg, 1 funarg)
|
|
| 124 | + Int -> forall a -> Int -- vis-arity == 2 (1 funarg, 1 req tyarg)
|
|
| 125 | + |
|
| 126 | + Wrinkle: with TypeApplications and TypeAbstractions, it is possible to visibly
|
|
| 127 | + bind and pass invisible arguments, e.g. `f @a x = ...` or `f @Int 42`. Those
|
|
| 128 | + @-prefixed arguments are ignored for the purposes of vis-arity.
|
|
| 129 | +-} |
| ... | ... | @@ -133,7 +133,7 @@ module GHC.Types.Basic ( |
| 133 | 133 | |
| 134 | 134 | ImportLevel(..), convImportLevel, convImportLevelSpec, allImportLevels,
|
| 135 | 135 | |
| 136 | --- XInlinePragmaGhc(..)
|
|
| 136 | +-- InlinePragmaGhcTag(..)
|
|
| 137 | 137 | ) where
|
| 138 | 138 | |
| 139 | 139 | import GHC.Prelude
|
| ... | ... | @@ -143,6 +143,7 @@ import GHC.Data.FastString |
| 143 | 143 | import GHC.Utils.Outputable
|
| 144 | 144 | import GHC.Utils.Panic
|
| 145 | 145 | import GHC.Utils.Binary
|
| 146 | +import GHC.Types.Arity
|
|
| 146 | 147 | import GHC.Types.SourceText
|
| 147 | 148 | import qualified GHC.LanguageExtensions as LangExt
|
| 148 | 149 | import {-# SOURCE #-} Language.Haskell.Syntax.Type (PromotionFlag(..), isPromoted)
|
| ... | ... | @@ -187,105 +188,6 @@ instance NFData LeftOrRight where |
| 187 | 188 | rnf CLeft = ()
|
| 188 | 189 | rnf CRight = ()
|
| 189 | 190 | |
| 190 | - |
|
| 191 | - |
|
| 192 | -{-
|
|
| 193 | -************************************************************************
|
|
| 194 | -* *
|
|
| 195 | -\subsection[Arity]{Arity}
|
|
| 196 | -* *
|
|
| 197 | -************************************************************************
|
|
| 198 | --}
|
|
| 199 | - |
|
| 200 | --- | Syntactic (visibility) arity, i.e. the number of visible arguments.
|
|
| 201 | --- See Note [Visibility and arity]
|
|
| 202 | -type VisArity = Int
|
|
| 203 | - |
|
| 204 | --- | Representation Arity
|
|
| 205 | ---
|
|
| 206 | --- The number of represented arguments that can be applied to a value before it does
|
|
| 207 | --- "real work". So:
|
|
| 208 | --- fib 100 has representation arity 0
|
|
| 209 | --- \x -> fib x has representation arity 1
|
|
| 210 | --- \(# x, y #) -> fib (x + y) has representation arity 2
|
|
| 211 | -type RepArity = Int
|
|
| 212 | - |
|
| 213 | --- | The number of arguments that a join point takes. Unlike the arity of a
|
|
| 214 | --- function, this is a purely syntactic property and is fixed when the join
|
|
| 215 | --- point is created (or converted from a value). Both type and value arguments
|
|
| 216 | --- are counted.
|
|
| 217 | -type JoinArity = Int
|
|
| 218 | - |
|
| 219 | --- | FullArgCount is the number of type or value arguments in an application,
|
|
| 220 | --- or the number of type or value binders in a lambda. Note: it includes
|
|
| 221 | --- both type and value arguments!
|
|
| 222 | -type FullArgCount = Int
|
|
| 223 | - |
|
| 224 | -{- Note [Visibility and arity]
|
|
| 225 | -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
| 226 | -Arity is the number of arguments that a function expects. In a curried language
|
|
| 227 | -like Haskell, there is more than one way to count those arguments.
|
|
| 228 | - |
|
| 229 | -* `Arity` is the classic notion of arity, concerned with evalution, so it counts
|
|
| 230 | - the number of /value/ arguments that need to be supplied before evaluation can
|
|
| 231 | - take place, as described in notes
|
|
| 232 | - Note [Definition of arity] in GHC.Core.Opt.Arity
|
|
| 233 | - Note [Arity and function types] in GHC.Types.Id.Info
|
|
| 234 | - |
|
| 235 | - Examples:
|
|
| 236 | - Int has arity == 0
|
|
| 237 | - Int -> Int has arity <= 1
|
|
| 238 | - Int -> Bool -> Int has arity <= 2
|
|
| 239 | - We write (<=) rather than (==) as sometimes evaluation can occur before all
|
|
| 240 | - value arguments are supplied, depending on the actual function definition.
|
|
| 241 | - |
|
| 242 | - This evaluation-focused notion of arity ignores type arguments, so:
|
|
| 243 | - forall a. a has arity == 0
|
|
| 244 | - forall a. a -> a has arity <= 1
|
|
| 245 | - forall a b. a -> b -> a has arity <= 2
|
|
| 246 | - This is true regardless of ForAllTyFlag, so the arity is also unaffected by
|
|
| 247 | - (forall {a}. ty) or (forall a -> ty).
|
|
| 248 | - |
|
| 249 | - Class dictionaries count towards the arity, as they are passed at runtime
|
|
| 250 | - forall a. (Num a) => a has arity <= 1
|
|
| 251 | - forall a. (Num a) => a -> a has arity <= 2
|
|
| 252 | - forall a b. (Num a, Ord b) => a -> b -> a has arity <= 4
|
|
| 253 | - |
|
| 254 | -* `VisArity` is the syntactic notion of arity. It is the number of /visible/
|
|
| 255 | - arguments, i.e. arguments that occur visibly in the source code.
|
|
| 256 | - |
|
| 257 | - In a function call `f x y z`, we can confidently say that f's vis-arity >= 3,
|
|
| 258 | - simply because we see three arguments [x,y,z]. We write (>=) rather than (==)
|
|
| 259 | - as this could be a partial application.
|
|
| 260 | - |
|
| 261 | - At definition sites, we can acquire an underapproximation of vis-arity by
|
|
| 262 | - counting the patterns on the LHS, e.g. `f a b = rhs` has vis-arity >= 2.
|
|
| 263 | - The actual vis-arity can be higher if there is a lambda on the RHS,
|
|
| 264 | - e.g. `f a b = \c -> rhs`.
|
|
| 265 | - |
|
| 266 | - If we look at the types, we can observe the following
|
|
| 267 | - * function arrows (a -> b) add to the vis-arity
|
|
| 268 | - * visible foralls (forall a -> b) add to the vis-arity
|
|
| 269 | - * constraint arrows (a => b) do not affect the vis-arity
|
|
| 270 | - * invisible foralls (forall a. b) do not affect the vis-arity
|
|
| 271 | - |
|
| 272 | - This means that ForAllTyFlag matters for VisArity (in contrast to Arity),
|
|
| 273 | - while the type/value distinction is unimportant (again in contrast to Arity).
|
|
| 274 | - |
|
| 275 | - Examples:
|
|
| 276 | - Int -- vis-arity == 0 (no args)
|
|
| 277 | - Int -> Int -- vis-arity == 1 (1 funarg)
|
|
| 278 | - forall a. a -> a -- vis-arity == 1 (1 funarg)
|
|
| 279 | - forall a. Num a => a -> a -- vis-arity == 1 (1 funarg)
|
|
| 280 | - forall a -> Num a => a -- vis-arity == 1 (1 req tyarg, 0 funargs)
|
|
| 281 | - forall a -> a -> a -- vis-arity == 2 (1 req tyarg, 1 funarg)
|
|
| 282 | - Int -> forall a -> Int -- vis-arity == 2 (1 funarg, 1 req tyarg)
|
|
| 283 | - |
|
| 284 | - Wrinkle: with TypeApplications and TypeAbstractions, it is possible to visibly
|
|
| 285 | - bind and pass invisible arguments, e.g. `f @a x = ...` or `f @Int 42`. Those
|
|
| 286 | - @-prefixed arguments are ignored for the purposes of vis-arity.
|
|
| 287 | --}
|
|
| 288 | - |
|
| 289 | 191 | {-
|
| 290 | 192 | ************************************************************************
|
| 291 | 193 | * *
|
| ... | ... | @@ -1439,18 +1341,18 @@ failed Succeeded = False |
| 1439 | 1341 | failed Failed = True
|
| 1440 | 1342 | |
| 1441 | 1343 | {-
|
| 1442 | -data XInlinePragmaGhc = XInlinePragmaGhcRn
|
|
| 1344 | +data InlinePragmaGhcTag = InlinePragmaGhcTag
|
|
| 1443 | 1345 | { inl_ghcrn_src :: {-# UNPACK#-} !SourceText
|
| 1444 | 1346 | , inl_ghcrn_arity :: {-# UNPACK#-} !Arity
|
| 1445 | 1347 | }
|
| 1446 | 1348 | deriving (Eq, Data)
|
| 1447 | 1349 | |
| 1448 | -instance NFData XInlinePragmaGhc where
|
|
| 1449 | - rnf (XInlinePragmaGhcRn s a) = rnf s `seq` rnf a `seq` ()
|
|
| 1350 | +instance NFData InlinePragmaGhcTag where
|
|
| 1351 | + rnf (InlinePragmaGhcTag s a) = rnf s `seq` rnf a `seq` ()
|
|
| 1450 | 1352 | |
| 1451 | 1353 | type instance XInlinePragma GhcPs = SourceText
|
| 1452 | -type instance XInlinePragma GhcRn = XInlinePragmaGhc
|
|
| 1453 | -type instance XInlinePragma GhcTc = XInlinePragmaGhc
|
|
| 1354 | +type instance XInlinePragma GhcRn = InlinePragmaGhcTag
|
|
| 1355 | +type instance XInlinePragma GhcTc = InlinePragmaGhcTag
|
|
| 1454 | 1356 | type instance XXInlinePragma (GhcPass _) = DataConCantHappen
|
| 1455 | 1357 | |
| 1456 | 1358 | defaultInlinePragma, alwaysInlinePragma, neverInlinePragma, dfunInlinePragma
|
| ... | ... | @@ -1474,7 +1376,7 @@ dfunInlinePragma = defaultInlinePragma { inl_act = AlwaysActive |
| 1474 | 1376 | |
| 1475 | 1377 | setInlinePragmaArity :: InlinePragma GhcPs -> Arity -> InlinePragma GhcTc
|
| 1476 | 1378 | setInlinePragmaArity prag@(InlinePragma { inl_src = srcTxt }) arity =
|
| 1477 | - prag { inl_src = XInlinePragmaGhcRn srcTxt arity }
|
|
| 1379 | + prag { inl_src = InlinePragmaGhcTag srcTxt arity }
|
|
| 1478 | 1380 | |
| 1479 | 1381 | {-
|
| 1480 | 1382 | inlinePragmaSource :: forall p. IsPass p => InlinePragma (GhcPass p) -> SourceText
|
| ... | ... | @@ -2072,15 +1974,15 @@ instance Binary InlineSpec where |
| 2072 | 1974 | instance Outputable (InlinePragma (GhcPass p)) where
|
| 2073 | 1975 | ppr = pprInline
|
| 2074 | 1976 | |
| 2075 | -instance Binary XInlinePragmaGhc where
|
|
| 2076 | - put_ bh (XInlinePragmaGhcRn s a) = do
|
|
| 1977 | +instance Binary InlinePragmaGhcTag where
|
|
| 1978 | + put_ bh (InlinePragmaGhcTag s a) = do
|
|
| 2077 | 1979 | put_ bh s
|
| 2078 | 1980 | put_ bh a
|
| 2079 | 1981 | |
| 2080 | 1982 | get bh = do
|
| 2081 | 1983 | s <- get bh
|
| 2082 | 1984 | a <- get bh
|
| 2083 | - return (XInlinePragmaGhcRn s a)
|
|
| 1985 | + return (InlinePragmaGhcTag s a)
|
|
| 2084 | 1986 | |
| 2085 | 1987 | instance Binary (InlinePragma GhcPs) where
|
| 2086 | 1988 | put_ bh (InlinePragma s a b c) = do
|
| ... | ... | @@ -564,11 +564,11 @@ setRuleInfo info sp = sp `seq` info { ruleInfo = sp } |
| 564 | 564 | setInlinePragInfo :: forall p. IsPass p => IdInfo -> InlinePragma (GhcPass p) -> IdInfo
|
| 565 | 565 | setInlinePragInfo info pr@(InlinePragma { inl_src = src }) = pr `seq` info { inlinePragInfo = pr { inl_src = tag } }
|
| 566 | 566 | where
|
| 567 | - tag :: XInlinePragmaGhc
|
|
| 567 | + tag :: InlinePragmaGhcTag
|
|
| 568 | 568 | tag = case ghcPass @p of
|
| 569 | - GhcPs -> XInlinePragmaGhcRn (src :: SourceText) 0
|
|
| 570 | - GhcRn -> (src :: XInlinePragmaGhc)
|
|
| 571 | - GhcTc -> (src :: XInlinePragmaGhc)
|
|
| 569 | + GhcPs -> InlinePragmaGhcTag (src :: SourceText) 0
|
|
| 570 | + GhcRn -> (src :: InlinePragmaGhcTag)
|
|
| 571 | + GhcTc -> (src :: InlinePragmaGhcTag)
|
|
| 572 | 572 | |
| 573 | 573 | setOccInfo :: IdInfo -> OccInfo -> IdInfo
|
| 574 | 574 | setOccInfo info oc = oc `seq` info { occInfo = oc }
|
| ... | ... | @@ -52,10 +52,13 @@ module GHC.Types.InlinePragma ( |
| 52 | 52 | setInlinePragmaArity,
|
| 53 | 53 | unsetInlinePragmaArity,
|
| 54 | 54 | pprInline, pprInlineDebug,
|
| 55 | + |
|
| 56 | + -- ** Pass conversions
|
|
| 57 | + demoteInlinePragmaRn,
|
|
| 55 | 58 | promoteInlinePragmaRn,
|
| 56 | 59 | |
| 57 | 60 | -- ** Extensible record type for GhcRn & GhcTc
|
| 58 | - XInlinePragmaGhc(..)
|
|
| 61 | + InlinePragmaGhcTag(..)
|
|
| 59 | 62 | ) where
|
| 60 | 63 | |
| 61 | 64 | import GHC.Prelude
|
| ... | ... | @@ -64,25 +67,26 @@ import GHC.Data.FastString |
| 64 | 67 | import GHC.Hs.Extension
|
| 65 | 68 | import GHC.Utils.Outputable
|
| 66 | 69 | import GHC.Utils.Binary
|
| 70 | +import GHC.Types.Arity (Arity)
|
|
| 67 | 71 | import GHC.Types.SourceText
|
| 68 | -import Control.DeepSeq ( NFData(..) )
|
|
| 72 | +import Control.DeepSeq (NFData(..))
|
|
| 69 | 73 | import Data.Data
|
| 70 | 74 | |
| 71 | 75 | import Language.Haskell.Syntax.Binds
|
| 72 | 76 | import Language.Haskell.Syntax.Extension
|
| 73 | 77 | |
| 74 | -data XInlinePragmaGhc = XInlinePragmaGhcRn
|
|
| 78 | +data InlinePragmaGhcTag = InlinePragmaGhcTag
|
|
| 75 | 79 | { inl_ghcrn_src :: {-# UNPACK#-} !SourceText
|
| 76 | 80 | , inl_ghcrn_arity :: {-# UNPACK#-} !Arity
|
| 77 | 81 | }
|
| 78 | 82 | deriving (Eq, Data)
|
| 79 | 83 | |
| 80 | -instance NFData XInlinePragmaGhc where
|
|
| 81 | - rnf (XInlinePragmaGhcRn s a) = rnf s `seq` rnf a `seq` ()
|
|
| 84 | +instance NFData InlinePragmaGhcTag where
|
|
| 85 | + rnf (InlinePragmaGhcTag s a) = rnf s `seq` rnf a `seq` ()
|
|
| 82 | 86 | |
| 83 | 87 | type instance XInlinePragma GhcPs = SourceText
|
| 84 | -type instance XInlinePragma GhcRn = XInlinePragmaGhc
|
|
| 85 | -type instance XInlinePragma GhcTc = XInlinePragmaGhc
|
|
| 88 | +type instance XInlinePragma GhcRn = InlinePragmaGhcTag
|
|
| 89 | +type instance XInlinePragma GhcTc = InlinePragmaGhcTag
|
|
| 86 | 90 | type instance XXInlinePragma (GhcPass _) = DataConCantHappen
|
| 87 | 91 | |
| 88 | 92 | defaultInlinePragma, alwaysInlinePragma, neverInlinePragma, dfunInlinePragma
|
| ... | ... | @@ -105,10 +109,10 @@ alwaysInlineConLikePragma = alwaysInlinePragma { inl_rule = ConLike } |
| 105 | 109 | dfunInlinePragma = defaultInlinePragma { inl_act = AlwaysActive
|
| 106 | 110 | , inl_rule = ConLike }
|
| 107 | 111 | |
| 108 | -setInlinePragmaArity :: forall p q. (IsPass p, XInlinePragma (GhcPass q) ~ XInlinePragmaGhc)
|
|
| 112 | +setInlinePragmaArity :: forall p q. (IsPass p, XInlinePragma (GhcPass q) ~ InlinePragmaGhcTag)
|
|
| 109 | 113 | => InlinePragma (GhcPass p) -> Arity -> InlinePragma (GhcPass q)
|
| 110 | 114 | setInlinePragmaArity prag arity =
|
| 111 | - prag { inl_src = XInlinePragmaGhcRn (inlinePragmaSource prag) arity }
|
|
| 115 | + prag { inl_src = InlinePragmaGhcTag (inlinePragmaSource prag) arity }
|
|
| 112 | 116 | |
| 113 | 117 | unsetInlinePragmaArity :: forall p. IsPass p => InlinePragma (GhcPass p) -> InlinePragma GhcPs
|
| 114 | 118 | unsetInlinePragmaArity prag =
|
| ... | ... | @@ -126,6 +130,9 @@ inlinePragmaSource (InlinePragma { inl_src = src }) = srcTxt |
| 126 | 130 | promoteInlinePragmaRn :: InlinePragma GhcRn -> InlinePragma GhcTc
|
| 127 | 131 | promoteInlinePragmaRn prag@(InlinePragma { inl_src = src }) = prag { inl_src = src }
|
| 128 | 132 | |
| 133 | +demoteInlinePragmaRn :: InlinePragma GhcTc -> InlinePragma GhcRn
|
|
| 134 | +demoteInlinePragmaRn prag@(InlinePragma { inl_src = src }) = prag { inl_src = src }
|
|
| 135 | + |
|
| 129 | 136 | -- | Outputs string for pragma name for any of INLINE/INLINABLE/NOINLINE. This
|
| 130 | 137 | -- differs from the Outputable instance for the InlineSpec type where the pragma
|
| 131 | 138 | -- name string as well as the accompanying SourceText (if any) is printed.
|
| ... | ... | @@ -238,54 +245,32 @@ instance Binary InlineSpec where |
| 238 | 245 | instance Outputable (InlinePragma (GhcPass p)) where
|
| 239 | 246 | ppr = pprInline
|
| 240 | 247 | |
| 241 | -instance Binary XInlinePragmaGhc where
|
|
| 242 | - put_ bh (XInlinePragmaGhcRn s a) = do
|
|
| 243 | - put_ bh s
|
|
| 244 | - put_ bh a
|
|
| 245 | - |
|
| 246 | - get bh = do
|
|
| 247 | - s <- get bh
|
|
| 248 | - a <- get bh
|
|
| 249 | - return (XInlinePragmaGhcRn s a)
|
|
| 250 | - |
|
| 251 | -instance Binary (InlinePragma GhcPs) where
|
|
| 252 | - put_ bh (InlinePragma s a b c) = do
|
|
| 253 | - put_ bh s
|
|
| 254 | - put_ bh a
|
|
| 255 | - put_ bh b
|
|
| 256 | - put_ bh c
|
|
| 257 | - |
|
| 258 | - get bh = do
|
|
| 259 | - s <- get bh
|
|
| 260 | - a <- get bh
|
|
| 261 | - b <- get bh
|
|
| 262 | - c <- get bh
|
|
| 263 | - return (InlinePragma s a b c)
|
|
| 264 | - |
|
| 265 | -instance Binary (InlinePragma GhcRn) where
|
|
| 266 | - put_ bh (InlinePragma s a b c) = do
|
|
| 248 | +instance Binary InlinePragmaGhcTag where
|
|
| 249 | + put_ bh (InlinePragmaGhcTag s a) = do
|
|
| 267 | 250 | put_ bh s
|
| 268 | 251 | put_ bh a
|
| 269 | - put_ bh b
|
|
| 270 | - put_ bh c
|
|
| 271 | 252 | |
| 272 | 253 | get bh = do
|
| 273 | 254 | s <- get bh
|
| 274 | 255 | a <- get bh
|
| 275 | - b <- get bh
|
|
| 276 | - c <- get bh
|
|
| 277 | - return (InlinePragma s a b c)
|
|
| 256 | + return (InlinePragmaGhcTag s a)
|
|
| 278 | 257 | |
| 279 | -instance Binary (InlinePragma GhcTc) where
|
|
| 258 | +instance forall p. IsPass p => Binary (InlinePragma (GhcPass p)) where
|
|
| 280 | 259 | put_ bh (InlinePragma s a b c) = do
|
| 281 | - put_ bh s
|
|
| 282 | 260 | put_ bh a
|
| 283 | 261 | put_ bh b
|
| 284 | 262 | put_ bh c
|
| 263 | + case ghcPass @p of
|
|
| 264 | + GhcPs -> put_ bh s
|
|
| 265 | + GhcRn -> put_ bh s
|
|
| 266 | + GhcTc -> put_ bh s
|
|
| 285 | 267 | |
| 286 | 268 | get bh = do
|
| 287 | - s <- get bh
|
|
| 288 | 269 | a <- get bh
|
| 289 | 270 | b <- get bh
|
| 290 | 271 | c <- get bh
|
| 272 | + s <- case ghcPass @p of
|
|
| 273 | + GhcPs -> get bh
|
|
| 274 | + GhcRn -> get bh
|
|
| 275 | + GhcTc -> get bh
|
|
| 291 | 276 | return (InlinePragma s a b c) |
| ... | ... | @@ -556,13 +556,6 @@ data HsPatSynDir id |
| 556 | 556 | | ImplicitBidirectional
|
| 557 | 557 | | ExplicitBidirectional (MatchGroup id (LHsExpr id))
|
| 558 | 558 | |
| 559 | --- | The number of value arguments that can be applied to a value before it does
|
|
| 560 | --- "real work". So:
|
|
| 561 | --- fib 100 has arity 0
|
|
| 562 | --- \x -> fib x has arity 1
|
|
| 563 | --- See also Note [Definition of arity] in "GHC.Core.Opt.Arity"
|
|
| 564 | -type Arity = Int
|
|
| 565 | - |
|
| 566 | 559 | {-
|
| 567 | 560 | ************************************************************************
|
| 568 | 561 | * *
|
| ... | ... | @@ -902,6 +902,7 @@ Library |
| 902 | 902 | GHC.Tc.Zonk.Type
|
| 903 | 903 | GHC.ThToHs
|
| 904 | 904 | GHC.Types.Annotations
|
| 905 | + GHC.Types.Arity
|
|
| 905 | 906 | GHC.Types.Avail
|
| 906 | 907 | GHC.Types.Basic
|
| 907 | 908 | GHC.Types.CompleteMatch
|