Simon Peyton Jones pushed to branch wip/T27557 at Glasgow Haskell Compiler / GHC
Commits:
-
4f2a21f7
by Andreas Klebinger at 2026-08-02T22:46:46-04:00
-
21e4b89d
by Andreas Klebinger at 2026-08-02T22:46:46-04:00
-
d415f38a
by Alan Zimmerman at 2026-08-02T22:47:27-04:00
-
a7622111
by Simon Peyton Jones at 2026-08-03T13:50:08+01:00
26 changed files:
- + changelog.d/T27557
- compiler/GHC/Core/Opt/Arity.hs
- compiler/GHC/Hs/Decls.hs
- compiler/GHC/Hs/Expr.hs
- compiler/GHC/HsToCore/Binds.hs
- compiler/GHC/HsToCore/Match.hs
- compiler/GHC/HsToCore/Ticks.hs
- compiler/GHC/Parser.y
- compiler/GHC/Parser/PostProcess.hs
- compiler/GHC/Stg/Lint.hs
- compiler/GHC/Tc/Gen/Bind.hs
- compiler/GHC/Tc/Gen/Sig.hs
- compiler/GHC/Types/Arity.hs
- compiler/GHC/Types/ForeignCall.hs
- compiler/GHC/Types/InlinePragma.hs
- compiler/GHC/Types/Var.hs
- libraries/base/tests/perf/ElemFusionUnknownList_O1.stderr
- + testsuite/tests/simplCore/should_compile/T27589.hs
- + testsuite/tests/simplCore/should_compile/T27589.stderr
- + testsuite/tests/simplCore/should_compile/T27590.hs
- + testsuite/tests/simplCore/should_compile/T27590.stderr
- testsuite/tests/simplCore/should_compile/all.T
- + testsuite/tests/typecheck/should_compile/T27557.hs
- testsuite/tests/typecheck/should_compile/all.T
- utils/check-exact/ExactPrint.hs
- utils/haddock/haddock-api/src/Haddock/Types.hs
Changes:
| 1 | +section: compiler
|
|
| 2 | +issues: #27577 #27589 #27590
|
|
| 3 | +mrs: !16433
|
|
| 4 | +synopsis:
|
|
| 5 | + Fix three bugs around INLINE pragmas
|
|
| 6 | +description:
|
|
| 7 | + One bug (#25777) gave a Lint error. The other two were lurking but un-reported;
|
|
| 8 | + they showed up when fixing the first |
| ... | ... | @@ -2370,11 +2370,15 @@ mkEtaForAllMCo (Bndr tcv vis) ty mco |
| 2370 | 2370 | | otherwise -> mk_fco (mkRepReflCo ty)
|
| 2371 | 2371 | MCo co -> mk_fco co
|
| 2372 | 2372 | where
|
| 2373 | - mk_fco co = MCo (mkForAllCo tcv vis coreTyLamForAllTyFlag MRefl co)
|
|
| 2373 | + mk_fco co = MCo (mkForAllCo tcv coreTyLamForAllTyFlag vis MRefl co)
|
|
| 2374 | 2374 | -- coreTyLamForAllTyFlag: See Note [The EtaInfo mechanism], particularly
|
| 2375 | 2375 | -- the (EtaInfo Invariant). (sym co) wraps a lambda that always has
|
| 2376 | 2376 | -- a ForAllTyFlag of coreTyLamForAllTyFlag; see Note [Required foralls in Core]
|
| 2377 | 2377 | -- in GHC.Core.TyCo.Rep
|
| 2378 | + --
|
|
| 2379 | + -- Orientation: remember, the output of mkEtaForAllCo goes into an `EI bs mco`,
|
|
| 2380 | + -- and is SymCo'd in `etaInfoAbs`. Hence the orientation of the visibility
|
|
| 2381 | + -- flags. A bit of a brain-strain (#27557).
|
|
| 2378 | 2382 | |
| 2379 | 2383 | {-
|
| 2380 | 2384 | ************************************************************************
|
| ... | ... | @@ -1583,7 +1583,7 @@ type instance Anno (FunDep (GhcPass p)) = SrcSpanAnnA |
| 1583 | 1583 | type instance Anno (FamilyResultSig (GhcPass p)) = EpAnnCO
|
| 1584 | 1584 | type instance Anno (FamilyDecl (GhcPass p)) = SrcSpanAnnA
|
| 1585 | 1585 | type instance Anno (InjectivityAnn (GhcPass p)) = EpAnnCO
|
| 1586 | -type instance Anno (CType (GhcPass p)) = SrcSpanAnnP
|
|
| 1586 | +type instance Anno (CType (GhcPass p)) = SrcSpanAnnA
|
|
| 1587 | 1587 | type instance Anno (HsDerivingClause (GhcPass p)) = EpAnnCO
|
| 1588 | 1588 | type instance Anno (DerivClauseTys (GhcPass _)) = SrcSpanAnnA
|
| 1589 | 1589 | type instance Anno (StandaloneKindSig (GhcPass p)) = SrcSpanAnnA
|
| ... | ... | @@ -1687,10 +1687,11 @@ isSingletonMatchGroup matches |
| 1687 | 1687 | | otherwise
|
| 1688 | 1688 | = False
|
| 1689 | 1689 | |
| 1690 | -matchGroupArity :: MatchGroup (GhcPass id) body -> Arity
|
|
| 1690 | +matchGroupVisArity :: MatchGroup (GhcPass id) body -> VisArity
|
|
| 1691 | 1691 | -- This is called before type checking, when mg_arg_tys is not set
|
| 1692 | -matchGroupArity MG { mg_alts = L _ [] } = 1 -- See Note [Empty mg_alts]
|
|
| 1693 | -matchGroupArity MG { mg_alts = L _ (alt1 : _) } = count isVisArgLPat (hsLMatchPats alt1)
|
|
| 1692 | +-- Returns the "visible arity" of the MatchGroup i.e. including required type arguments.
|
|
| 1693 | +matchGroupVisArity MG { mg_alts = L _ [] } = 1 -- See Note [Empty mg_alts]
|
|
| 1694 | +matchGroupVisArity MG { mg_alts = L _ (alt1 : _) } = count isVisArgLPat (hsLMatchPats alt1)
|
|
| 1694 | 1695 | |
| 1695 | 1696 | hsLMatchPats :: LMatch (GhcPass id) body -> [LPat (GhcPass id)]
|
| 1696 | 1697 | hsLMatchPats (L _ (Match { m_pats = L _ pats })) = pats
|
| ... | ... | @@ -69,7 +69,7 @@ import GHC.Types.InlinePragma |
| 69 | 69 | import GHC.Types.Name
|
| 70 | 70 | import GHC.Types.Var.Set
|
| 71 | 71 | import GHC.Types.Var.Env
|
| 72 | -import GHC.Types.Var( EvVar, mkLocalVar )
|
|
| 72 | +import GHC.Types.Var( EvVar, mkLocalVar, isRuntimePiTyBinder )
|
|
| 73 | 73 | import GHC.Types.SrcLoc
|
| 74 | 74 | import GHC.Types.Basic
|
| 75 | 75 | import GHC.Types.Unique.Set( nonDetEltsUniqSet )
|
| ... | ... | @@ -196,7 +196,7 @@ dsHsBind dflags (VarBind { var_id = var |
| 196 | 196 | = do { core_expr <- dsLExpr expr
|
| 197 | 197 | -- Dictionary bindings are always VarBinds,
|
| 198 | 198 | -- so we only need do this here
|
| 199 | - ; let core_bind@(id,_) = makeCorePair dflags var False 0 core_expr
|
|
| 199 | + ; let core_bind@(id,_) = makeCorePair dflags var False core_expr
|
|
| 200 | 200 | force_var = if xopt LangExt.Strict dflags
|
| 201 | 201 | then [id]
|
| 202 | 202 | else []
|
| ... | ... | @@ -211,11 +211,11 @@ dsHsBind dflags b@(FunBind { fun_id = L loc fun |
| 211 | 211 | |
| 212 | 212 | ; let body' = mkOptTickBox tick body
|
| 213 | 213 | rhs = core_wrap (mkLams args body')
|
| 214 | - core_binds@(id,_) = makeCorePair dflags fun False 0 rhs
|
|
| 214 | + core_binds@(id,_) = makeCorePair dflags fun False rhs
|
|
| 215 | 215 | force_var
|
| 216 | 216 | -- Bindings are strict when -XStrict is enabled
|
| 217 | 217 | | xopt LangExt.Strict dflags
|
| 218 | - , matchGroupArity matches == 0 -- no need to force lambdas
|
|
| 218 | + , matchGroupVisArity matches == 0 -- no need to force lambdas
|
|
| 219 | 219 | = [id]
|
| 220 | 220 | | isBangedHsBind b
|
| 221 | 221 | = [id]
|
| ... | ... | @@ -303,7 +303,7 @@ dsAbsBinds dflags tyvars dicts exports |
| 303 | 303 | ; let global_id' = addIdSpecialisations global_id rules
|
| 304 | 304 | main_bind = makeCorePair dflags global_id'
|
| 305 | 305 | (isDefaultMethod prags)
|
| 306 | - (dictArity dicts) rhs
|
|
| 306 | + rhs
|
|
| 307 | 307 | |
| 308 | 308 | ; return (force_vars', fromOL spec_binds ++ [main_bind]) } }
|
| 309 | 309 | |
| ... | ... | @@ -386,7 +386,7 @@ dsAbsBinds dflags tyvars dicts exports |
| 386 | 386 | mk_aux_bind (lcl_id, rhs) = let lcl_w_inline = lookupVarEnv inline_env lcl_id
|
| 387 | 387 | `orElse` lcl_id
|
| 388 | 388 | in
|
| 389 | - makeCorePair dflags lcl_w_inline False 0 rhs
|
|
| 389 | + makeCorePair dflags lcl_w_inline False rhs
|
|
| 390 | 390 | |
| 391 | 391 | inline_env :: IdEnv Id -- Maps a monomorphic local Id to one with
|
| 392 | 392 | -- the inline pragma from the source
|
| ... | ... | @@ -437,9 +437,9 @@ dsAbsBinds dflags tyvars dicts exports |
| 437 | 437 | -- the unfolding in the interface file is made in `GHC.Iface.Tidy.addExternal`
|
| 438 | 438 | -- using this information.
|
| 439 | 439 | ------------------------
|
| 440 | -makeCorePair :: DynFlags -> Id -> Bool -> Arity -> CoreExpr
|
|
| 440 | +makeCorePair :: DynFlags -> Id -> Bool -> CoreExpr
|
|
| 441 | 441 | -> (Id, CoreExpr)
|
| 442 | -makeCorePair dflags gbl_id is_default_method dict_arity rhs
|
|
| 442 | +makeCorePair dflags gbl_id is_default_method rhs
|
|
| 443 | 443 | | is_default_method -- Default methods are *always* inlined
|
| 444 | 444 | -- See Note [INLINE and default methods] in GHC.Tc.TyCl.Instance
|
| 445 | 445 | = (gbl_id `setIdUnfolding` mkCompulsoryUnfolding' simpl_opts rhs, rhs)
|
| ... | ... | @@ -456,22 +456,43 @@ makeCorePair dflags gbl_id is_default_method dict_arity rhs |
| 456 | 456 | inline_prag = idInlinePragma gbl_id
|
| 457 | 457 | inlinable_unf = mkInlinableUnfolding simpl_opts StableUserSrc rhs
|
| 458 | 458 | inline_pair
|
| 459 | - | AppliedToAtLeast arity <- inlinePragmaSaturation inline_prag
|
|
| 459 | + | AppliedToAtLeast vis_arity <- inlinePragmaSaturation inline_prag
|
|
| 460 | 460 | -- Add an Unfolding for an INLINE (but not for NOINLINE)
|
| 461 | 461 | -- And eta-expand the RHS; see Note [Eta-expanding INLINE things]
|
| 462 | - , let real_arity = dict_arity + arity
|
|
| 463 | - -- NB: The arity passed to mkInlineUnfoldingWithArity
|
|
| 464 | - -- must take account of the dictionaries
|
|
| 465 | - = ( gbl_id `setIdUnfolding` mkInlineUnfoldingWithArity simpl_opts StableUserSrc real_arity rhs
|
|
| 466 | - , etaExpand real_arity rhs)
|
|
| 462 | + , let runtime_arity = findSatArity vis_arity (idType gbl_id)
|
|
| 463 | + -- NB: runtime_arity: the arity passed to mkInlineUnfoldingWithArity
|
|
| 464 | + -- must take account of dictionaries and required type args
|
|
| 465 | + = ( gbl_id `setIdUnfolding` mkInlineUnfoldingWithArity simpl_opts StableUserSrc
|
|
| 466 | + runtime_arity rhs
|
|
| 467 | + , etaExpand runtime_arity rhs)
|
|
| 467 | 468 | |
| 468 | 469 | | otherwise
|
| 469 | 470 | = pprTrace "makeCorePair: arity missing" (ppr gbl_id) $
|
| 470 | 471 | (gbl_id `setIdUnfolding` mkInlineUnfoldingNoArity simpl_opts StableUserSrc rhs, rhs)
|
| 471 | 472 | |
| 472 | -dictArity :: [Var] -> Arity
|
|
| 473 | --- Don't count coercion variables in arity
|
|
| 474 | -dictArity dicts = count isId dicts
|
|
| 473 | +findSatArity :: VisArity -> Type -> Arity
|
|
| 474 | +-- Given the VisArity, find the value Arity of the function.
|
|
| 475 | +-- This is the number of runtime-value arguments the function must be applied
|
|
| 476 | +-- to before the INLINE pragma fires and inlines the function
|
|
| 477 | +-- We must:
|
|
| 478 | +-- add one for each invisible dictionary arg; and
|
|
| 479 | +-- subtract one for each required type argment
|
|
| 480 | +findSatArity vis_arity ty
|
|
| 481 | + = go vis_arity pi_bndrs
|
|
| 482 | + where
|
|
| 483 | + (pi_bndrs, _) = splitPiTys ty
|
|
| 484 | + |
|
| 485 | + go vis_arity (bndr : bndrs)
|
|
| 486 | + | isInvisiblePiTyBinder bndr = add_bndr bndr (go vis_arity bndrs)
|
|
| 487 | + | vis_arity == 0 = 0
|
|
| 488 | + | otherwise = add_bndr bndr (go (vis_arity-1) bndrs)
|
|
| 489 | + go vis_arity []
|
|
| 490 | + | vis_arity == 0 = 0
|
|
| 491 | + | otherwise = pprPanic "findSatArity" (ppr vis_arity $$ ppr ty)
|
|
| 492 | + |
|
| 493 | + add_bndr :: PiTyBinder -> Arity -> Arity
|
|
| 494 | + add_bndr bndr ar | isRuntimePiTyBinder bndr = ar+1
|
|
| 495 | + | otherwise = ar
|
|
| 475 | 496 | |
| 476 | 497 | {-
|
| 477 | 498 | Note [Desugaring AbsBinds]
|
| ... | ... | @@ -737,21 +737,21 @@ Call @match@ with all of this information! |
| 737 | 737 | -- There are three possible cases for matchWrapper's scrutinees argument:
|
| 738 | 738 | --
|
| 739 | 739 | -- 1. Nothing Used for FunBind, HsLam, HsLamcase, where there is no explicit scrutinee
|
| 740 | --- The MatchGroup may have matchGroupArity of 0 or more. Examples:
|
|
| 741 | --- f p1 q1 = ... -- matchGroupArity 2
|
|
| 740 | +-- The MatchGroup may have matchGroupVisArity of 0 or more. Examples:
|
|
| 741 | +-- f p1 q1 = ... -- matchGroupVisArity 2
|
|
| 742 | 742 | -- f p2 q2 = ...
|
| 743 | 743 | --
|
| 744 | 744 | -- \cases | g1 -> ... -- matchGroupArity 0
|
| 745 | 745 | -- | g2 -> ...
|
| 746 | 746 | --
|
| 747 | 747 | -- 2. Just [e] Used for HsCase, RecordUpd; exactly one scrutinee
|
| 748 | --- The MatchGroup has matchGroupArity of exactly 1. Example:
|
|
| 749 | --- case e of p1 -> e1 -- matchGroupArity 1
|
|
| 748 | +-- The MatchGroup has matchGroupVisArity of exactly 1. Example:
|
|
| 749 | +-- case e of p1 -> e1 -- matchGroupVisArity 1
|
|
| 750 | 750 | -- p2 -> e2
|
| 751 | 751 | --
|
| 752 | 752 | -- 3. Just es Used for HsCmdLamCase; zero or more scrutinees
|
| 753 | 753 | -- The MatchGroup has matchGroupArity of (length es). Example:
|
| 754 | --- \cases p1 q1 -> returnA -< ... -- matchGroupArity 2
|
|
| 754 | +-- \cases p1 q1 -> returnA -< ... -- matchGroupVisArity 2
|
|
| 755 | 755 | -- p2 q2 -> ...
|
| 756 | 756 | |
| 757 | 757 | matchWrapper
|
| ... | ... | @@ -288,7 +288,7 @@ addTickLHsBind (L pos (funBind@(FunBind { fun_id = L _ id, fun_matches = matches |
| 288 | 288 | -- We don't want to generate code for blacklisted positions
|
| 289 | 289 | -- We don't want redundant ticks on simple pattern bindings
|
| 290 | 290 | -- We don't want to tick non-exported bindings in TickExportedFunctions
|
| 291 | - let simple = matchGroupArity matches == 0
|
|
| 291 | + let simple = matchGroupVisArity matches == 0
|
|
| 292 | 292 | -- A binding is a "simple pattern binding" if it is a
|
| 293 | 293 | -- funbind with zero patterns
|
| 294 | 294 | toplev = null decl_path
|
| ... | ... | @@ -1707,15 +1707,17 @@ datafam_inst_hdr :: { Located (Maybe (LHsContext GhcPs), HsOuterFamEqnTyVarBndrs |
| 1707 | 1707 | | type { sL1 $1 (Nothing, mkHsOuterImplicit, $1) }
|
| 1708 | 1708 | |
| 1709 | 1709 | |
| 1710 | -capi_ctype :: { Maybe (LocatedP (CType GhcPs)) }
|
|
| 1710 | +capi_ctype :: { Maybe (LocatedA (CType GhcPs)) }
|
|
| 1711 | 1711 | capi_ctype : '{-# CTYPE' STRING STRING '#-}'
|
| 1712 | - {% fmap Just $ amsr (sLL $1 $> (mkCType (getCTYPEs $1) (getSTRINGs $3) (Just (Header (getSTRINGs $2) (getSTRING $2)))
|
|
| 1713 | - (getSTRING $3)))
|
|
| 1714 | - (AnnPragma (glR $1) (epTok $4) noAnn (glR $2) (glR $3) noAnn noAnn) }
|
|
| 1712 | + {% fmap Just $ amsA' (sLL $1 $> (mkCType (getCTYPEs $1) (getSTRINGs $3)
|
|
| 1713 | + (AnnPragma (glR $1) (epTok $4) noAnn (glR $2) (glR $3) noAnn noAnn)
|
|
| 1714 | + (Just (Header (getSTRINGs $2) (getSTRING $2)))
|
|
| 1715 | + (getSTRING $3)))}
|
|
| 1715 | 1716 | |
| 1716 | 1717 | | '{-# CTYPE' STRING '#-}'
|
| 1717 | - {% fmap Just $ amsr (sLL $1 $> (mkCType (getCTYPEs $1) (getSTRINGs $2) Nothing (getSTRING $2)))
|
|
| 1718 | - (AnnPragma (glR $1) (epTok $3) noAnn noAnn (glR $2) noAnn noAnn) }
|
|
| 1718 | + {% fmap Just $ amsA' (sLL $1 $> (mkCType (getCTYPEs $1) (getSTRINGs $2)
|
|
| 1719 | + (AnnPragma (glR $1) (epTok $3) noAnn noAnn (glR $2) noAnn noAnn)
|
|
| 1720 | + Nothing (getSTRING $2)))}
|
|
| 1719 | 1721 | |
| 1720 | 1722 | | { Nothing }
|
| 1721 | 1723 |
| ... | ... | @@ -229,7 +229,7 @@ mkClassDecl loc' (L _ (mcxt, tycl_hdr)) fds where_cls layout annsIn |
| 229 | 229 | mkTyData :: SrcSpan
|
| 230 | 230 | -> Bool
|
| 231 | 231 | -> NewOrData
|
| 232 | - -> Maybe (LocatedP (CType GhcPs))
|
|
| 232 | + -> Maybe (LocatedA (CType GhcPs))
|
|
| 233 | 233 | -> Located (Maybe (LHsContext GhcPs), LHsType GhcPs)
|
| 234 | 234 | -> Maybe (LHsKind GhcPs)
|
| 235 | 235 | -> [LConDecl GhcPs]
|
| ... | ... | @@ -251,7 +251,7 @@ mkTyData loc' is_type_data new_or_data cType (L _ (mcxt, tycl_hdr)) |
| 251 | 251 | tcdDataDefn = defn,
|
| 252 | 252 | tcdModifiers = [] })) }
|
| 253 | 253 | |
| 254 | -mkDataDefn :: Maybe (LocatedP (CType GhcPs))
|
|
| 254 | +mkDataDefn :: Maybe (LocatedA (CType GhcPs))
|
|
| 255 | 255 | -> Maybe (LHsContext GhcPs)
|
| 256 | 256 | -> Maybe (LHsKind GhcPs)
|
| 257 | 257 | -> DataDefnCons (LConDecl GhcPs)
|
| ... | ... | @@ -326,7 +326,7 @@ mkTyFamInstEqn loc bndrs lhs rhs annEq |
| 326 | 326 | |
| 327 | 327 | mkDataFamInst :: SrcSpan
|
| 328 | 328 | -> NewOrData
|
| 329 | - -> Maybe (LocatedP (CType GhcPs))
|
|
| 329 | + -> Maybe (LocatedA (CType GhcPs))
|
|
| 330 | 330 | -> (Maybe ( LHsContext GhcPs), HsOuterFamEqnTyVarBndrs GhcPs
|
| 331 | 331 | , LHsType GhcPs)
|
| 332 | 332 | -> Maybe (LHsKind GhcPs)
|
| ... | ... | @@ -92,6 +92,7 @@ be ill-typed in Core. But it must still be well-kinded! |
| 92 | 92 | -}
|
| 93 | 93 | |
| 94 | 94 | {-# LANGUAGE TypeFamilies #-}
|
| 95 | +{-# LANGUAGE PatternSynonyms #-}
|
|
| 95 | 96 | |
| 96 | 97 | module GHC.Stg.Lint ( lintStgTopBindings ) where
|
| 97 | 98 | |
| ... | ... | @@ -123,6 +124,7 @@ import GHC.Unit.Module ( Module ) |
| 123 | 124 | import GHC.Data.Bag ( Bag, emptyBag, isEmptyBag, snocBag, bagToList )
|
| 124 | 125 | |
| 125 | 126 | import Control.Monad
|
| 127 | +import GHC.Exts ( oneShot )
|
|
| 126 | 128 | import GHC.Core.Multiplicity (scaledThing)
|
| 127 | 129 | import GHC.Settings (Platform)
|
| 128 | 130 | import GHC.Core.TyCon (primRepCompatible, primRepsCompatible)
|
| ... | ... | @@ -432,17 +434,40 @@ The Lint monad |
| 432 | 434 | ************************************************************************
|
| 433 | 435 | -}
|
| 434 | 436 | |
| 435 | -newtype LintM a = LintM
|
|
| 436 | - { unLintM :: Module
|
|
| 437 | - -> LintFlags
|
|
| 438 | - -> DiagOpts -- Diagnostic options
|
|
| 439 | - -> StgPprOpts -- Pretty-printing options
|
|
| 437 | +data LintReaderEnv = LintReaderEnv
|
|
| 438 | + { le_mod :: !Module
|
|
| 439 | + , le_flags :: !LintFlags
|
|
| 440 | + , le_diag_opts :: !DiagOpts -- Diagnostic options
|
|
| 441 | + , le_ppr_opts :: !StgPprOpts -- Pretty-printing options
|
|
| 442 | + }
|
|
| 443 | + |
|
| 444 | +newtype LintM a = LintM'
|
|
| 445 | + { unLintM :: LintReaderEnv
|
|
| 440 | 446 | -> [LintLocInfo] -- Locations
|
| 441 | 447 | -> IdSet -- Local vars in scope
|
| 442 | 448 | -> Bag SDoc -- Error messages so far
|
| 443 | 449 | -> (a, Bag SDoc) -- Result and error messages (if any)
|
| 444 | 450 | }
|
| 445 | - deriving (Functor)
|
|
| 451 | +instance Functor LintM where
|
|
| 452 | + fmap f (LintM m) =
|
|
| 453 | + LintM $ \env loc scope errs ->
|
|
| 454 | + case m env loc scope errs of
|
|
| 455 | + (a, errs') -> (f a, errs')
|
|
| 456 | + |
|
| 457 | +-- See Note [The one-shot state monad trick] in GHC.Utils.Monad
|
|
| 458 | +{-# COMPLETE LintM #-}
|
|
| 459 | +pattern LintM :: (LintReaderEnv
|
|
| 460 | + -> [LintLocInfo]
|
|
| 461 | + -> IdSet
|
|
| 462 | + -> Bag SDoc
|
|
| 463 | + -> (a, Bag SDoc))
|
|
| 464 | + -> LintM a
|
|
| 465 | +pattern LintM m <- LintM' m
|
|
| 466 | + where
|
|
| 467 | + LintM m = LintM' $ oneShot (\env -> oneShot
|
|
| 468 | + (\loc -> oneShot
|
|
| 469 | + (\scope -> oneShot
|
|
| 470 | + (\errs -> m env loc scope errs))))
|
|
| 446 | 471 | |
| 447 | 472 | data LintFlags = LintFlags { lf_unarised :: !Bool
|
| 448 | 473 | , lf_platform :: !Platform
|
| ... | ... | @@ -473,14 +498,16 @@ pp_binders bs |
| 473 | 498 | |
| 474 | 499 | initL :: Platform -> DiagOpts -> Module -> Bool -> StgPprOpts -> IdSet -> LintM a -> Maybe SDoc
|
| 475 | 500 | initL platform diag_opts this_mod unarised opts locals (LintM m) = do
|
| 476 | - let (_, errs) = m this_mod (LintFlags unarised platform) diag_opts opts [] locals emptyBag
|
|
| 501 | + let !flags = LintFlags unarised platform
|
|
| 502 | + !env = LintReaderEnv this_mod flags diag_opts opts
|
|
| 503 | + (_, errs) = m env [] locals emptyBag
|
|
| 477 | 504 | if isEmptyBag errs then
|
| 478 | 505 | Nothing
|
| 479 | 506 | else
|
| 480 | 507 | Just (vcat (punctuate blankLine (bagToList errs)))
|
| 481 | 508 | |
| 482 | 509 | instance Applicative LintM where
|
| 483 | - pure a = LintM $ \_mod _lf _df _opts _loc _scope errs -> (a, errs)
|
|
| 510 | + pure a = LintM $ \_env _loc _scope errs -> (a, errs)
|
|
| 484 | 511 | (<*>) = ap
|
| 485 | 512 | (*>) = thenL_
|
| 486 | 513 | |
| ... | ... | @@ -489,14 +516,14 @@ instance Monad LintM where |
| 489 | 516 | (>>) = (*>)
|
| 490 | 517 | |
| 491 | 518 | thenL :: LintM a -> (a -> LintM b) -> LintM b
|
| 492 | -thenL m k = LintM $ \mod lf diag_opts opts loc scope errs
|
|
| 493 | - -> case unLintM m mod lf diag_opts opts loc scope errs of
|
|
| 494 | - (r, errs') -> unLintM (k r) mod lf diag_opts opts loc scope errs'
|
|
| 519 | +thenL m k = LintM $ \env loc scope errs
|
|
| 520 | + -> case unLintM m env loc scope errs of
|
|
| 521 | + (r, errs') -> unLintM (k r) env loc scope errs'
|
|
| 495 | 522 | |
| 496 | 523 | thenL_ :: LintM a -> LintM b -> LintM b
|
| 497 | -thenL_ m k = LintM $ \mod lf diag_opts opts loc scope errs
|
|
| 498 | - -> case unLintM m mod lf diag_opts opts loc scope errs of
|
|
| 499 | - (_, errs') -> unLintM k mod lf diag_opts opts loc scope errs'
|
|
| 524 | +thenL_ m k = LintM $ \env loc scope errs
|
|
| 525 | + -> case unLintM m env loc scope errs of
|
|
| 526 | + (_, errs') -> unLintM k env loc scope errs'
|
|
| 500 | 527 | |
| 501 | 528 | checkL :: Bool -> SDoc -> LintM ()
|
| 502 | 529 | checkL True _ = return ()
|
| ... | ... | @@ -525,7 +552,8 @@ checkPostUnariseId id |
| 525 | 552 | id_ty = idType id
|
| 526 | 553 | |
| 527 | 554 | addErrL :: SDoc -> LintM ()
|
| 528 | -addErrL msg = LintM $ \_mod _lf df _opts loc _scope errs -> ((), addErr df errs msg loc)
|
|
| 555 | +addErrL msg = LintM $ \LintReaderEnv{le_diag_opts = df} loc _scope errs
|
|
| 556 | + -> ((), addErr df errs msg loc)
|
|
| 529 | 557 | |
| 530 | 558 | addErr :: DiagOpts -> Bag SDoc -> SDoc -> [LintLocInfo] -> Bag SDoc
|
| 531 | 559 | addErr diag_opts errs_so_far msg locs
|
| ... | ... | @@ -537,23 +565,23 @@ addErr diag_opts errs_so_far msg locs |
| 537 | 565 | mk_msg [] = msg
|
| 538 | 566 | |
| 539 | 567 | addLoc :: LintLocInfo -> LintM a -> LintM a
|
| 540 | -addLoc extra_loc m = LintM $ \mod lf diag_opts opts loc scope errs
|
|
| 541 | - -> unLintM m mod lf diag_opts opts (extra_loc:loc) scope errs
|
|
| 568 | +addLoc extra_loc m = LintM $ \env loc scope errs
|
|
| 569 | + -> unLintM m env (extra_loc:loc) scope errs
|
|
| 542 | 570 | |
| 543 | 571 | addInScopeVars :: [Id] -> LintM a -> LintM a
|
| 544 | -addInScopeVars ids m = LintM $ \mod lf diag_opts opts loc scope errs
|
|
| 572 | +addInScopeVars ids m = LintM $ \env loc scope errs
|
|
| 545 | 573 | -> let
|
| 546 | 574 | new_set = mkVarSet ids
|
| 547 | - in unLintM m mod lf diag_opts opts loc (scope `unionVarSet` new_set) errs
|
|
| 575 | + in unLintM m env loc (scope `unionVarSet` new_set) errs
|
|
| 548 | 576 | |
| 549 | 577 | getLintFlags :: LintM LintFlags
|
| 550 | -getLintFlags = LintM $ \_mod lf _df _opts _loc _scope errs -> (lf, errs)
|
|
| 578 | +getLintFlags = LintM $ \LintReaderEnv{le_flags = lf} _loc _scope errs -> (lf, errs)
|
|
| 551 | 579 | |
| 552 | 580 | getStgPprOpts :: LintM StgPprOpts
|
| 553 | -getStgPprOpts = LintM $ \_mod _lf _df opts _loc _scope errs -> (opts, errs)
|
|
| 581 | +getStgPprOpts = LintM $ \LintReaderEnv{le_ppr_opts = opts} _loc _scope errs -> (opts, errs)
|
|
| 554 | 582 | |
| 555 | 583 | checkInScope :: Id -> LintM ()
|
| 556 | -checkInScope id = LintM $ \mod _lf diag_opts _opts loc scope errs
|
|
| 584 | +checkInScope id = LintM $ \LintReaderEnv{le_mod = mod, le_diag_opts = diag_opts} loc scope errs
|
|
| 557 | 585 | -> if nameIsLocalOrFrom mod (idName id) && not (id `elemVarSet` scope) then
|
| 558 | 586 | ((), addErr diag_opts errs (hsep [ppr id, dcolon, ppr (idType id),
|
| 559 | 587 | text "is out of scope"]) loc)
|
| ... | ... | @@ -808,7 +808,7 @@ checkMonomorphismRestriction mbis lbinds |
| 808 | 808 | restricted (VarBind { var_ext = x }) = dataConCantHappen x
|
| 809 | 809 | restricted b@(PatSynBind {}) = pprPanic "isRestrictedGroup/unrestricted" (ppr b)
|
| 810 | 810 | |
| 811 | - restricted_match mg = matchGroupArity mg == 0
|
|
| 811 | + restricted_match mg = matchGroupVisArity mg == 0
|
|
| 812 | 812 | -- No args => like a pattern binding
|
| 813 | 813 | -- Some args => a function binding
|
| 814 | 814 |
| ... | ... | @@ -599,26 +599,26 @@ mkPragEnv sigs binds |
| 599 | 599 | Nothing -> sig -- See Note [Pattern synonym inline arity]
|
| 600 | 600 | |
| 601 | 601 | -- ar_env maps a local to the arity of its definition
|
| 602 | - ar_env :: NameEnv Arity
|
|
| 603 | - ar_env = foldr lhsBindArity emptyNameEnv binds
|
|
| 602 | + ar_env :: NameEnv VisArity
|
|
| 603 | + ar_env = foldr lhsBindVisArity emptyNameEnv binds
|
|
| 604 | 604 | |
| 605 | -addInlinePragArity :: Arity -> LSig GhcRn -> LSig GhcRn
|
|
| 605 | +addInlinePragArity :: VisArity -> LSig GhcRn -> LSig GhcRn
|
|
| 606 | 606 | addInlinePragArity ar (L l (InlineSig x nm inl)) = L l (InlineSig x nm (add_inl_arity ar inl))
|
| 607 | 607 | addInlinePragArity ar (L l (SpecSig x nm ty inl)) = L l (SpecSig x nm ty (add_inl_arity ar inl))
|
| 608 | 608 | addInlinePragArity ar (L l (SpecSigE n x e inl)) = L l (SpecSigE n x e (add_inl_arity ar inl))
|
| 609 | 609 | addInlinePragArity _ sig = sig
|
| 610 | 610 | |
| 611 | -add_inl_arity :: Arity -> InlinePragma GhcRn -> InlinePragma GhcRn
|
|
| 611 | +add_inl_arity :: VisArity -> InlinePragma GhcRn -> InlinePragma GhcRn
|
|
| 612 | 612 | add_inl_arity ar prag@(InlinePragma { inl_inline = inl_spec })
|
| 613 | 613 | | Inline {} <- inl_spec -- Add arity only for real INLINE pragmas, not INLINABLE
|
| 614 | 614 | = prag `setInlinePragmaSaturation` AppliedToAtLeast ar
|
| 615 | 615 | | otherwise
|
| 616 | 616 | = prag
|
| 617 | 617 | |
| 618 | -lhsBindArity :: LHsBind GhcRn -> NameEnv Arity -> NameEnv Arity
|
|
| 619 | -lhsBindArity (L _ (FunBind { fun_id = id, fun_matches = ms })) env
|
|
| 620 | - = extendNameEnv env (unLoc id) (matchGroupArity ms)
|
|
| 621 | -lhsBindArity _ env = env -- PatBind/VarBind
|
|
| 618 | +lhsBindVisArity :: LHsBind GhcRn -> NameEnv Arity -> NameEnv Arity
|
|
| 619 | +lhsBindVisArity (L _ (FunBind { fun_id = id, fun_matches = ms })) env
|
|
| 620 | + = extendNameEnv env (unLoc id) (matchGroupVisArity ms)
|
|
| 621 | +lhsBindVisArity _ env = env -- PatBind/VarBind
|
|
| 622 | 622 | |
| 623 | 623 | |
| 624 | 624 | -----------------
|
| ... | ... | @@ -84,7 +84,14 @@ like Haskell, there is more than one way to count those arguments. |
| 84 | 84 | forall a b. (Num a, Ord b) => a -> b -> a has arity <= 4
|
| 85 | 85 | |
| 86 | 86 | * `VisArity` is the syntactic notion of arity. It is the number of /visible/
|
| 87 | - arguments, i.e. arguments that occur visibly in the source code.
|
|
| 87 | + arguments, i.e. arguments that occur visibly in the source code. For example:
|
|
| 88 | + f1 :: forall a. a -> a
|
|
| 89 | + f1 x = x
|
|
| 90 | + f2 :: forall a -> a -> a
|
|
| 91 | + f2 t x = x
|
|
| 92 | + Both have Arity 1 because there is one /value/ argument.
|
|
| 93 | + But f1 has VisArity 1 while f2 has VisArity 2, becuase f2 has a required
|
|
| 94 | + type argument.
|
|
| 88 | 95 | |
| 89 | 96 | In a function call `f x y z`, we can confidently say that f's vis-arity >= 3,
|
| 90 | 97 | simply because we see three arguments [x,y,z]. We write (>=) rather than (==)
|
| ... | ... | @@ -109,6 +109,7 @@ import Data.Data (Data) |
| 109 | 109 | import Data.Functor ((<&>))
|
| 110 | 110 | |
| 111 | 111 | import Control.DeepSeq (NFData(..))
|
| 112 | +import GHC.Parser.Annotation (AnnPragma, noAnn)
|
|
| 112 | 113 | |
| 113 | 114 | {-
|
| 114 | 115 | ************************************************************************
|
| ... | ... | @@ -213,11 +214,11 @@ instance Outputable CCallSpec where |
| 213 | 214 | |
| 214 | 215 | defaultCType :: String -> CType (GhcPass p)
|
| 215 | 216 | defaultCType =
|
| 216 | - CType (CTypeGhc NoSourceText NoSourceText) Nothing . packHText
|
|
| 217 | + CType (CTypeGhc NoSourceText NoSourceText noAnn) Nothing . packHText
|
|
| 217 | 218 | |
| 218 | -mkCType :: SourceText -> SourceText -> Maybe (Header (GhcPass p)) -> HText -> CType (GhcPass p)
|
|
| 219 | -mkCType x y m =
|
|
| 220 | - CType (CTypeGhc x y) m
|
|
| 219 | +mkCType :: SourceText -> SourceText -> AnnPragma -> Maybe (Header (GhcPass p)) -> HText -> CType (GhcPass p)
|
|
| 220 | +mkCType x y ann m =
|
|
| 221 | + CType (CTypeGhc x y ann) m
|
|
| 221 | 222 | |
| 222 | 223 | typeCheckCType :: CType GhcRn -> CType GhcTc
|
| 223 | 224 | typeCheckCType (CType x y z) = CType x (typeCheckHeader <$> y) z
|
| ... | ... | @@ -302,6 +303,7 @@ data StaticTargetGhc = StaticTargetGhc |
| 302 | 303 | data CTypeGhc = CTypeGhc
|
| 303 | 304 | { cTypeSourceText :: SourceText
|
| 304 | 305 | , cTypeOtherText :: SourceText
|
| 306 | + , cTypeAnn :: AnnPragma
|
|
| 305 | 307 | }
|
| 306 | 308 | deriving (Data, Eq)
|
| 307 | 309 | |
| ... | ... | @@ -349,6 +351,7 @@ instance Binary CTypeGhc where |
| 349 | 351 | return $ CTypeGhc
|
| 350 | 352 | { cTypeSourceText = str1
|
| 351 | 353 | , cTypeOtherText = str2
|
| 354 | + , cTypeAnn = noAnn
|
|
| 352 | 355 | }
|
| 353 | 356 | |
| 354 | 357 | instance NFData StaticTargetGhc where
|
| ... | ... | @@ -104,7 +104,7 @@ import GHC.Prelude |
| 104 | 104 | |
| 105 | 105 | import GHC.Data.FastString
|
| 106 | 106 | import GHC.Hs.Extension
|
| 107 | -import GHC.Types.Arity (Arity)
|
|
| 107 | +import GHC.Types.Arity (VisArity)
|
|
| 108 | 108 | import GHC.Types.SourceText (SourceText(..))
|
| 109 | 109 | import GHC.Utils.Binary
|
| 110 | 110 | import GHC.Utils.Outputable
|
| ... | ... | @@ -125,12 +125,13 @@ infixl 1 `setInlinePragmaActivation`, |
| 125 | 125 | -- | The arity /at which to/ inline a function.
|
| 126 | 126 | -- This may differ from the function's syntactic arity.
|
| 127 | 127 | data InlineSaturation
|
| 128 | - = AppliedToAtLeast !Arity
|
|
| 128 | + = AppliedToAtLeast !VisArity
|
|
| 129 | 129 | -- ^ Inline only when applied to @n@ explicit
|
| 130 | - -- (non-type, non-dictionary) arguments.
|
|
| 130 | + -- (required type or value) arguments.
|
|
| 131 | 131 | --
|
| 132 | 132 | -- That is, 'AppliedToAtLeast' describes the number of
|
| 133 | 133 | -- *source-code* arguments the thing must be applied to.
|
| 134 | + |
|
| 134 | 135 | | AnySaturation
|
| 135 | 136 | -- ^ There does not exist an explicit number of arguments
|
| 136 | 137 | -- that the inlining process should be applied to.
|
| ... | ... | @@ -82,7 +82,7 @@ module GHC.Types.Var ( |
| 82 | 82 | -- * PiTyBinder
|
| 83 | 83 | PiTyBinder(..), PiTyVarBinder,
|
| 84 | 84 | isInvisiblePiTyBinder, isInvisibleAnonPiTyBinder,
|
| 85 | - isVisiblePiTyBinder,
|
|
| 85 | + isVisiblePiTyBinder, isRuntimePiTyBinder,
|
|
| 86 | 86 | isTyBinder, isNamedPiTyBinder, isAnonPiTyBinder,
|
| 87 | 87 | namedPiTyBinder_maybe, anonPiTyBinderType_maybe, piTyBinderType,
|
| 88 | 88 | |
| ... | ... | @@ -757,7 +757,12 @@ instance NamedThing tv => NamedThing (VarBndr tv flag) where |
| 757 | 757 | -- not. See Note [PiTyBinders]
|
| 758 | 758 | data PiTyBinder
|
| 759 | 759 | = Named ForAllTyBinder -- A type-lambda binder, with a ForAllTyFlag
|
| 760 | - | Anon (Scaled Type) FunTyFlag -- A term-lambda binder. Type here can be CoercionTy.
|
|
| 760 | + -- Erased (not passed at runtime) if the binder is
|
|
| 761 | + -- a type variable; not erased if coercion variable
|
|
| 762 | + |
|
| 763 | + | Anon (Scaled Type) FunTyFlag -- A term-lambda binder, passing a runtime value
|
|
| 764 | + -- The argument can be a constraint (incl dictionary)
|
|
| 765 | + -- or an ordinary value
|
|
| 761 | 766 | -- The arrow is described by the FunTyFlag
|
| 762 | 767 | deriving Data
|
| 763 | 768 | |
| ... | ... | @@ -792,6 +797,12 @@ namedPiTyBinder_maybe :: PiTyBinder -> Maybe TyCoVar |
| 792 | 797 | namedPiTyBinder_maybe (Named tv) = Just $ binderVar tv
|
| 793 | 798 | namedPiTyBinder_maybe _ = Nothing
|
| 794 | 799 | |
| 800 | +isRuntimePiTyBinder :: PiTyBinder -> Bool
|
|
| 801 | +isRuntimePiTyBinder (Anon {}) = True -- Always passed at runtime
|
|
| 802 | +isRuntimePiTyBinder (Named (Bndr tcv _)) = isCoVar tcv
|
|
| 803 | + -- isCoVar: see Note [Why ForAllTy can quantify over a coercion variable]
|
|
| 804 | + -- and Note [Unused coercion variable in ForAllTy], in GHC.Core.TyCo.Rep
|
|
| 805 | + |
|
| 795 | 806 | -- | Does this binder bind a variable that is /not/ erased? Returns
|
| 796 | 807 | -- 'True' for anonymous binders.
|
| 797 | 808 | isAnonPiTyBinder :: PiTyBinder -> Bool
|
| ... | ... | @@ -817,7 +828,7 @@ piTyBinderType (Named (Bndr tv _)) = varType tv |
| 817 | 828 | piTyBinderType (Anon ty _) = scaledThing ty
|
| 818 | 829 | |
| 819 | 830 | {- Note [PiTyBinders]
|
| 820 | -~~~~~~~~~~~~~~~~~~~
|
|
| 831 | +~~~~~~~~~~~~~~~~~~~~~
|
|
| 821 | 832 | But a type like
|
| 822 | 833 | forall a. Maybe a -> forall b. (a,b) -> b
|
| 823 | 834 | |
| ... | ... | @@ -830,14 +841,18 @@ argument to a Pi-type. GHC Core currently supports two different |
| 830 | 841 | Pi-types:
|
| 831 | 842 | |
| 832 | 843 | * Anon ty1 fun_flag: a non-dependent function type,
|
| 833 | - written with ->, e.g. ty1 -> ty2
|
|
| 834 | - represented as FunTy ty1 ty2. These are
|
|
| 835 | - lifted to Coercions with the corresponding FunCo.
|
|
| 844 | + written with ->, e.g. ty1 -> ty2
|
|
| 845 | + represented as FunTy ty1 ty2.
|
|
| 846 | + |
|
| 847 | + See wrinkle (PIT1)
|
|
| 848 | + |
|
| 849 | + These are lifted to Coercions with the corresponding FunCo.
|
|
| 850 | + |
|
| 851 | + * Named (Var tcv forall_flag): a dependent polytype,
|
|
| 852 | + written with forall, e.g. forall (a:*). ty
|
|
| 853 | + represented as ForAllTy (Bndr a v) ty
|
|
| 836 | 854 | |
| 837 | - * Named (Var tv forall_flag)
|
|
| 838 | - A dependent compile-time-only polytype,
|
|
| 839 | - written with forall, e.g. forall (a:*). ty
|
|
| 840 | - represented as ForAllTy (Bndr a v) ty
|
|
| 855 | + See wrinkle (PIT2)
|
|
| 841 | 856 | |
| 842 | 857 | Both forms of Pi-types classify terms/types that take an argument. In other
|
| 843 | 858 | words, if `x` is either a function or a polytype, `x arg` makes sense
|
| ... | ... | @@ -845,12 +860,16 @@ words, if `x` is either a function or a polytype, `x arg` makes sense |
| 845 | 860 | |
| 846 | 861 | Wrinkles
|
| 847 | 862 | |
| 848 | -* The Anon constructor of PiTyBinder contains a FunTyFlag. Since
|
|
| 863 | +(PIT1) The Anon constructor of PiTyBinder contains a FunTyFlag. Since
|
|
| 849 | 864 | the PiTyBinder really only describes the /argument/ it should perhaps
|
| 850 | 865 | only have a TypeOrConstraint rather than a full FunTyFlag. But it's
|
| 851 | 866 | very convenient to have the full FunTyFlag, say in mkPiTys, so that's
|
| 852 | 867 | what we do.
|
| 853 | 868 | |
| 869 | +(PIT2) The `tcv` in `Named (Var tcv forall_flag) is usually a type variable
|
|
| 870 | + but can exceptionally be a coercion variable: see
|
|
| 871 | + Note [Why ForAllTy can quantify over a coercion variable].
|
|
| 872 | + If it's a type variable it will be erased; if coercion variable it will not.
|
|
| 854 | 873 | |
| 855 | 874 | Note [VarBndrs, ForAllTyBinders, TyConBinders, and visibility]
|
| 856 | 875 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
| ... | ... | @@ -43,17 +43,17 @@ fusionElemFilter |
| 43 | 43 | jump go1 eta
|
| 44 | 44 | |
| 45 | 45 | fusionNotElemConcatMap
|
| 46 | - = \ x x1 ->
|
|
| 46 | + = \ x eta ->
|
|
| 47 | 47 | joinrec {
|
| 48 | 48 | go1 ds
|
| 49 | 49 | = case ds of {
|
| 50 | 50 | [] -> True;
|
| 51 | 51 | : y ys ->
|
| 52 | - case y of { I# x2 ->
|
|
| 53 | - case x of { I# x3 ->
|
|
| 54 | - case ==# x3 (+# x2 1#) of {
|
|
| 52 | + case y of { I# x1 ->
|
|
| 53 | + case x of { I# x2 ->
|
|
| 54 | + case ==# x2 (+# x1 1#) of {
|
|
| 55 | 55 | __DEFAULT ->
|
| 56 | - case ==# x3 (+# x2 2#) of {
|
|
| 56 | + case ==# x2 (+# x1 2#) of {
|
|
| 57 | 57 | __DEFAULT -> jump go1 ys;
|
| 58 | 58 | 1# -> False
|
| 59 | 59 | };
|
| ... | ... | @@ -62,20 +62,20 @@ fusionNotElemConcatMap |
| 62 | 62 | }
|
| 63 | 63 | }
|
| 64 | 64 | }; } in
|
| 65 | - jump go1 x1
|
|
| 65 | + jump go1 eta
|
|
| 66 | 66 | |
| 67 | 67 | fusionElemConcatMap
|
| 68 | - = \ x x1 ->
|
|
| 68 | + = \ x eta ->
|
|
| 69 | 69 | joinrec {
|
| 70 | 70 | go1 ds
|
| 71 | 71 | = case ds of {
|
| 72 | 72 | [] -> False;
|
| 73 | 73 | : y ys ->
|
| 74 | - case y of { I# x2 ->
|
|
| 75 | - case x of { I# x3 ->
|
|
| 76 | - case ==# x3 (+# x2 1#) of {
|
|
| 74 | + case y of { I# x1 ->
|
|
| 75 | + case x of { I# x2 ->
|
|
| 76 | + case ==# x2 (+# x1 1#) of {
|
|
| 77 | 77 | __DEFAULT ->
|
| 78 | - case ==# x3 (+# x2 2#) of {
|
|
| 78 | + case ==# x2 (+# x1 2#) of {
|
|
| 79 | 79 | __DEFAULT -> jump go1 ys;
|
| 80 | 80 | 1# -> True
|
| 81 | 81 | };
|
| ... | ... | @@ -84,7 +84,7 @@ fusionElemConcatMap |
| 84 | 84 | }
|
| 85 | 85 | }
|
| 86 | 86 | }; } in
|
| 87 | - jump go1 x1
|
|
| 87 | + jump go1 eta
|
|
| 88 | 88 | |
| 89 | 89 | fusionNotElemMap
|
| 90 | 90 | = \ x eta ->
|
| 1 | +module T28589 where
|
|
| 2 | + |
|
| 3 | +wombat :: Num a => a -> a
|
|
| 4 | +{-# INLINE wombat #-}
|
|
| 5 | +wombat x = x+x*x
|
|
| 6 | + |
|
| 7 | +g :: Num a => [a] -> [a]
|
|
| 8 | +g ys = map wombat ys
|
|
| 9 | + -- wombat should not inline here |
| 1 | +wombat [InlPrag=INLINE (sat-args=1)] :: forall a. Num a => a -> a
|
|
| 2 | +wombat
|
|
| 3 | + map @a @a (wombat @a $dNum) ys |
| 1 | +{-# LANGUAGE RequiredTypeArguments #-}
|
|
| 2 | + |
|
| 3 | +module Foo where
|
|
| 4 | + |
|
| 5 | +wombat :: forall a -> a -> Maybe a
|
|
| 6 | +{-# INLINE wombat #-}
|
|
| 7 | +wombat t x = Just x
|
|
| 8 | + |
|
| 9 | +g y = wombat Int (y+y)
|
|
| 10 | + -- wombat /should/ inline here |
| 1 | +wombat [InlPrag=INLINE (sat-args=2)] :: forall a -> a -> Maybe a
|
|
| 2 | +wombat |
| ... | ... | @@ -609,3 +609,5 @@ test('T4081', normal, compile, ['-O -ddump-simpl -dsuppress-uniques -dsuppress-a |
| 609 | 609 | test('T27261', [extra_files(['T27261_aux.hs'])], multimod_compile, ['T27261', '-v0 -O'])
|
| 610 | 610 | test('T27296', [], makefile_test, ['T27296'])
|
| 611 | 611 | test('T27296b', [], makefile_test, ['T27296b'])
|
| 612 | +test('T27589', [grep_errmsg(r'wombat')], compile, ['-O -ddump-simpl -dno-typeable-binds -dsuppress-uniques'])
|
|
| 613 | +test('T27590', [grep_errmsg(r'wombat')], compile, ['-O -ddump-simpl -dno-typeable-binds -dsuppress-uniques']) |
| 1 | +{-# LANGUAGE RequiredTypeArguments #-}
|
|
| 2 | + |
|
| 3 | +module RequiredTypeArgumentsMkSymCo where
|
|
| 4 | + |
|
| 5 | +import Data.Kind (Type)
|
|
| 6 | + |
|
| 7 | +f :: forall a . forall (b :: Type) -> a -> a
|
|
| 8 | +f t = id
|
|
| 9 | +{-# INLINE f #-} |
| ... | ... | @@ -968,4 +968,4 @@ test('T24464', normal, compile, ['']) |
| 968 | 968 | test('ExpansionQLIm', normal, compile, [''])
|
| 969 | 969 | test('T23135', normal, compile, [''])
|
| 970 | 970 | test('LazyFieldAnnotations', normal, compile, [''])
|
| 971 | - |
|
| 971 | +test('T27557', normal, compile, ['']) |
| ... | ... | @@ -4401,13 +4401,14 @@ instance ExactPrint t => ExactPrint (HsModifierOf t GhcPs) where |
| 4401 | 4401 | |
| 4402 | 4402 | -- ---------------------------------------------------------------------
|
| 4403 | 4403 | |
| 4404 | -instance Typeable p => ExactPrint (LocatedP (CType (GhcPass p))) where
|
|
| 4405 | - getAnnotationEntry = entryFromLocatedA
|
|
| 4406 | - setAnnotationAnchor = setAnchorAn
|
|
| 4404 | +instance Typeable p => ExactPrint (CType (GhcPass p)) where
|
|
| 4405 | + getAnnotationEntry _ = NoEntryVal
|
|
| 4406 | + setAnnotationAnchor a _ _ _ = a
|
|
| 4407 | 4407 | |
| 4408 | - exact (L (EpAnn l (AnnPragma o c s l1 l2 t m) cs) (CType ext mh ct)) = do
|
|
| 4408 | + exact (CType ext mh ct) = do
|
|
| 4409 | 4409 | let stp = cTypeSourceText ext
|
| 4410 | 4410 | stct = cTypeOtherText ext
|
| 4411 | + AnnPragma o c s l1 l2 t m = cTypeAnn ext
|
|
| 4411 | 4412 | o' <- markAnnOpen'' o stp "{-# CTYPE"
|
| 4412 | 4413 | l1' <- case mh of
|
| 4413 | 4414 | Nothing -> return l1
|
| ... | ... | @@ -4415,7 +4416,7 @@ instance Typeable p => ExactPrint (LocatedP (CType (GhcPass p))) where |
| 4415 | 4416 | printStringAtAA l1 (toSourceTextWithSuffix srcH "" "")
|
| 4416 | 4417 | l2' <- printStringAtAA l2 (toSourceTextWithSuffix stct (unpackHText ct) "")
|
| 4417 | 4418 | c' <- markEpToken c
|
| 4418 | - return (L (EpAnn l (AnnPragma o' c' s l1' l2' t m) cs) (CType ext mh ct))
|
|
| 4419 | + return (CType (ext { cTypeAnn = AnnPragma o' c' s l1' l2' t m }) mh ct)
|
|
| 4419 | 4420 | |
| 4420 | 4421 | -- ---------------------------------------------------------------------
|
| 4421 | 4422 |
| ... | ... | @@ -837,7 +837,7 @@ type instance Anno (HsOuterTyVarBndrs Specificity DocNameI) = SrcSpanAnnA |
| 837 | 837 | type instance Anno (HsSigType DocNameI) = SrcSpanAnnA
|
| 838 | 838 | type instance Anno (BooleanFormula DocNameI) = SrcSpanAnnBF
|
| 839 | 839 | type instance Anno (OverlapMode DocNameI) = SrcSpanAnnA
|
| 840 | -type instance Anno (CType DocNameI) = EpAnn AnnPragma
|
|
| 840 | +type instance Anno (CType DocNameI) = SrcSpanAnnA
|
|
| 841 | 841 | type instance Anno (Header DocNameI) = EpAnn AnnPragma
|
| 842 | 842 | type instance Anno (HsModifierOf (LocatedA (HsType DocNameI)) DocNameI) = SrcSpanAnnA
|
| 843 | 843 | type instance Anno (HsContextDetails DocNameI a) = SrcSpanAnnA
|