Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC
Commits:
-
5b841d82
by Teo Camarasu at 2025-08-14T17:57:56-04:00
-
33e2c7e5
by Teo Camarasu at 2025-08-14T17:57:56-04:00
10 changed files:
- libraries/ghc-internal/src/GHC/Internal/TH/Lib.hs
- libraries/ghc-internal/src/GHC/Internal/TH/Lift.hs
- libraries/ghc-internal/src/GHC/Internal/TH/Syntax.hs
- libraries/template-haskell/Language/Haskell/TH/Lib.hs
- libraries/template-haskell/Language/Haskell/TH/Quote.hs
- libraries/template-haskell/Language/Haskell/TH/Syntax.hs
- libraries/template-haskell/tests/all.T
- testsuite/tests/interface-stability/template-haskell-exports.stdout
- testsuite/tests/quasiquotation/T4491/test.T
- testsuite/tests/th/Makefile
Changes:
... | ... | @@ -555,20 +555,6 @@ pragInlD name inline rm phases |
555 | 555 | pragOpaqueD :: Quote m => Name -> m Dec
|
556 | 556 | pragOpaqueD name = pure $ PragmaD $ OpaqueP name
|
557 | 557 | |
558 | -{-# DEPRECATED pragSpecD "Please use 'pragSpecED' instead. 'pragSpecD' will be removed in GHC 9.18." #-}
|
|
559 | -pragSpecD :: Quote m => Name -> m Type -> Phases -> m Dec
|
|
560 | -pragSpecD n ty phases
|
|
561 | - = do
|
|
562 | - ty1 <- ty
|
|
563 | - pure $ PragmaD $ SpecialiseP n ty1 Nothing phases
|
|
564 | - |
|
565 | -{-# DEPRECATED pragSpecInlD "Please use 'pragSpecInlED' instead. 'pragSpecInlD' will be removed in GHC 9.18." #-}
|
|
566 | -pragSpecInlD :: Quote m => Name -> m Type -> Inline -> Phases -> m Dec
|
|
567 | -pragSpecInlD n ty inline phases
|
|
568 | - = do
|
|
569 | - ty1 <- ty
|
|
570 | - pure $ PragmaD $ SpecialiseP n ty1 (Just inline) phases
|
|
571 | - |
|
572 | 558 | pragSpecED :: Quote m
|
573 | 559 | => Maybe [m (TyVarBndr ())] -> [m RuleBndr]
|
574 | 560 | -> m Exp
|
... | ... | @@ -868,22 +854,6 @@ implicitParamT n t |
868 | 854 | t' <- t
|
869 | 855 | pure $ ImplicitParamT n t'
|
870 | 856 | |
871 | -{-# DEPRECATED classP "As of template-haskell-2.10, constraint predicates (Pred) are just types (Type), in keeping with ConstraintKinds. Please use 'conT' and 'appT'." #-}
|
|
872 | -classP :: Quote m => Name -> [m Type] -> m Pred
|
|
873 | -classP cla tys
|
|
874 | - = do
|
|
875 | - tysl <- sequenceA tys
|
|
876 | - pure (foldl AppT (ConT cla) tysl)
|
|
877 | - |
|
878 | -{-# DEPRECATED equalP "As of template-haskell-2.10, constraint predicates (Pred) are just types (Type), in keeping with ConstraintKinds. Please see 'equalityT'." #-}
|
|
879 | -equalP :: Quote m => m Type -> m Type -> m Pred
|
|
880 | -equalP tleft tright
|
|
881 | - = do
|
|
882 | - tleft1 <- tleft
|
|
883 | - tright1 <- tright
|
|
884 | - eqT <- equalityT
|
|
885 | - pure (foldl AppT eqT [tleft1, tright1])
|
|
886 | - |
|
887 | 857 | promotedT :: Quote m => Name -> m Type
|
888 | 858 | promotedT = pure . PromotedT
|
889 | 859 | |
... | ... | @@ -906,20 +876,6 @@ noSourceStrictness = pure NoSourceStrictness |
906 | 876 | sourceLazy = pure SourceLazy
|
907 | 877 | sourceStrict = pure SourceStrict
|
908 | 878 | |
909 | -{-# DEPRECATED isStrict
|
|
910 | - ["Use 'bang'. See https://gitlab.haskell.org/ghc/ghc/wikis/migration/8.0. ",
|
|
911 | - "Example usage: 'bang noSourceUnpackedness sourceStrict'"] #-}
|
|
912 | -{-# DEPRECATED notStrict
|
|
913 | - ["Use 'bang'. See https://gitlab.haskell.org/ghc/ghc/wikis/migration/8.0. ",
|
|
914 | - "Example usage: 'bang noSourceUnpackedness noSourceStrictness'"] #-}
|
|
915 | -{-# DEPRECATED unpacked
|
|
916 | - ["Use 'bang'. See https://gitlab.haskell.org/ghc/ghc/wikis/migration/8.0. ",
|
|
917 | - "Example usage: 'bang sourceUnpack sourceStrict'"] #-}
|
|
918 | -isStrict, notStrict, unpacked :: Quote m => m Strict
|
|
919 | -isStrict = bang noSourceUnpackedness sourceStrict
|
|
920 | -notStrict = bang noSourceUnpackedness noSourceStrictness
|
|
921 | -unpacked = bang sourceUnpack sourceStrict
|
|
922 | - |
|
923 | 879 | bang :: Quote m => m SourceUnpackedness -> m SourceStrictness -> m Bang
|
924 | 880 | bang u s = do u' <- u
|
925 | 881 | s' <- s
|
... | ... | @@ -931,16 +887,6 @@ bangType = liftA2 (,) |
931 | 887 | varBangType :: Quote m => Name -> m BangType -> m VarBangType
|
932 | 888 | varBangType v bt = (\(b, t) -> (v, b, t)) <$> bt
|
933 | 889 | |
934 | -{-# DEPRECATED strictType
|
|
935 | - "As of @template-haskell-2.11.0.0@, 'StrictType' has been replaced by 'BangType'. Please use 'bangType' instead." #-}
|
|
936 | -strictType :: Quote m => m Strict -> m Type -> m StrictType
|
|
937 | -strictType = bangType
|
|
938 | - |
|
939 | -{-# DEPRECATED varStrictType
|
|
940 | - "As of @template-haskell-2.11.0.0@, 'VarStrictType' has been replaced by 'VarBangType'. Please use 'varBangType' instead." #-}
|
|
941 | -varStrictType :: Quote m => Name -> m StrictType -> m VarStrictType
|
|
942 | -varStrictType = varBangType
|
|
943 | - |
|
944 | 890 | -- * Type Literals
|
945 | 891 | |
946 | 892 | -- MonadFail here complicates things (a lot) because it would mean we would
|
... | ... | @@ -24,40 +24,22 @@ |
24 | 24 | |
25 | 25 | module GHC.Internal.TH.Lift
|
26 | 26 | ( Lift(..)
|
27 | - -- * Generic Lift implementations
|
|
28 | - , dataToQa
|
|
29 | - , dataToCodeQ
|
|
30 | - , dataToExpQ
|
|
31 | - , liftDataTyped
|
|
32 | - , liftData
|
|
33 | - , dataToPatQ
|
|
34 | 27 | -- * Wired-in names
|
35 | 28 | , liftString
|
36 | - , trueName
|
|
37 | - , falseName
|
|
38 | - , nothingName
|
|
39 | - , justName
|
|
40 | - , leftName
|
|
41 | - , rightName
|
|
42 | - , nonemptyName
|
|
43 | 29 | )
|
44 | 30 | where
|
45 | 31 | |
46 | 32 | import GHC.Internal.TH.Syntax
|
47 | 33 | import qualified GHC.Internal.TH.Lib as Lib (litE) -- See wrinkle (W4) of Note [Tracking dependencies on primitives]
|
48 | -import GHC.Internal.Lexeme ( startsVarSym, startsVarId )
|
|
49 | 34 | |
50 | 35 | import GHC.Internal.Data.Either
|
51 | -import GHC.Internal.Type.Reflection
|
|
52 | 36 | import GHC.Internal.Data.Bool
|
53 | 37 | import GHC.Internal.Base hiding (NonEmpty(..), Type, Module, inline)
|
54 | -import GHC.Internal.Data.Foldable
|
|
55 | 38 | import GHC.Internal.Data.NonEmpty (NonEmpty(..))
|
56 | 39 | import GHC.Internal.Integer
|
57 | 40 | import GHC.Internal.Real
|
58 | 41 | import GHC.Internal.Word
|
59 | 42 | import GHC.Internal.Int
|
60 | -import GHC.Internal.Data.Data hiding (Fixity)
|
|
61 | 43 | import GHC.Internal.Natural
|
62 | 44 | import GHC.Internal.ForeignPtr
|
63 | 45 | |
... | ... | @@ -294,20 +276,6 @@ deriving instance (Lift a, Lift b, Lift c, Lift d, Lift e, Lift f) |
294 | 276 | deriving instance (Lift a, Lift b, Lift c, Lift d, Lift e, Lift f, Lift g)
|
295 | 277 | => Lift (# a | b | c | d | e | f | g #)
|
296 | 278 | |
297 | -trueName, falseName :: Name
|
|
298 | -trueName = 'True
|
|
299 | -falseName = 'False
|
|
300 | - |
|
301 | -nothingName, justName :: Name
|
|
302 | -nothingName = 'Nothing
|
|
303 | -justName = 'Just
|
|
304 | - |
|
305 | -leftName, rightName :: Name
|
|
306 | -leftName = 'Left
|
|
307 | -rightName = 'Right
|
|
308 | - |
|
309 | -nonemptyName :: Name
|
|
310 | -nonemptyName = '(:|)
|
|
311 | 279 | |
312 | 280 | -----------------------------------------------------
|
313 | 281 | --
|
... | ... | @@ -443,157 +411,3 @@ deriving instance Lift Info |
443 | 411 | deriving instance Lift AnnLookup
|
444 | 412 | -- | @since template-haskell-2.22.1.0
|
445 | 413 | deriving instance Lift Extension |
446 | - |
|
447 | ------------------------------------------------------
|
|
448 | ---
|
|
449 | --- Generic Lift implementations
|
|
450 | ---
|
|
451 | ------------------------------------------------------
|
|
452 | - |
|
453 | --- | 'dataToQa' is an internal utility function for constructing generic
|
|
454 | --- conversion functions from types with 'Data' instances to various
|
|
455 | --- quasi-quoting representations. See the source of 'dataToExpQ' and
|
|
456 | --- 'dataToPatQ' for two example usages: @mkCon@, @mkLit@
|
|
457 | --- and @appQ@ are overloadable to account for different syntax for
|
|
458 | --- expressions and patterns; @antiQ@ allows you to override type-specific
|
|
459 | --- cases, a common usage is just @const Nothing@, which results in
|
|
460 | --- no overloading.
|
|
461 | -dataToQa :: forall m a k q. (Quote m, Data a)
|
|
462 | - => (Name -> k)
|
|
463 | - -> (Lit -> m q)
|
|
464 | - -> (k -> [m q] -> m q)
|
|
465 | - -> (forall b . Data b => b -> Maybe (m q))
|
|
466 | - -> a
|
|
467 | - -> m q
|
|
468 | -dataToQa mkCon mkLit appCon antiQ t =
|
|
469 | - case antiQ t of
|
|
470 | - Nothing ->
|
|
471 | - case constrRep constr of
|
|
472 | - AlgConstr _ ->
|
|
473 | - appCon (mkCon funOrConName) conArgs
|
|
474 | - where
|
|
475 | - funOrConName :: Name
|
|
476 | - funOrConName =
|
|
477 | - case showConstr constr of
|
|
478 | - "(:)" -> Name (mkOccName ":")
|
|
479 | - (NameG DataName
|
|
480 | - (mkPkgName "ghc-internal")
|
|
481 | - (mkModName "GHC.Internal.Types"))
|
|
482 | - con@"[]" -> Name (mkOccName con)
|
|
483 | - (NameG DataName
|
|
484 | - (mkPkgName "ghc-internal")
|
|
485 | - (mkModName "GHC.Internal.Types"))
|
|
486 | - con@('(':_) -> Name (mkOccName con)
|
|
487 | - (NameG DataName
|
|
488 | - (mkPkgName "ghc-internal")
|
|
489 | - (mkModName "GHC.Internal.Tuple"))
|
|
490 | - |
|
491 | - -- Tricky case: see Note [Data for non-algebraic types]
|
|
492 | - fun@(x:_) | startsVarSym x || startsVarId x
|
|
493 | - -> mkNameG_v tyconPkg tyconMod fun
|
|
494 | - con -> mkNameG_d tyconPkg tyconMod con
|
|
495 | - |
|
496 | - where
|
|
497 | - tycon :: TyCon
|
|
498 | - tycon = (typeRepTyCon . typeOf) t
|
|
499 | - |
|
500 | - tyconPkg, tyconMod :: String
|
|
501 | - tyconPkg = tyConPackage tycon
|
|
502 | - tyconMod = tyConModule tycon
|
|
503 | - |
|
504 | - conArgs :: [m q]
|
|
505 | - conArgs = gmapQ (dataToQa mkCon mkLit appCon antiQ) t
|
|
506 | - IntConstr n ->
|
|
507 | - mkLit $ IntegerL n
|
|
508 | - FloatConstr n ->
|
|
509 | - mkLit $ RationalL n
|
|
510 | - CharConstr c ->
|
|
511 | - mkLit $ CharL c
|
|
512 | - where
|
|
513 | - constr :: Constr
|
|
514 | - constr = toConstr t
|
|
515 | - |
|
516 | - Just y -> y
|
|
517 | - |
|
518 | - |
|
519 | -{- Note [Data for non-algebraic types]
|
|
520 | -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
521 | -Class Data was originally intended for algebraic data types. But
|
|
522 | -it is possible to use it for abstract types too. For example, in
|
|
523 | -package `text` we find
|
|
524 | - |
|
525 | - instance Data Text where
|
|
526 | - ...
|
|
527 | - toConstr _ = packConstr
|
|
528 | - |
|
529 | - packConstr :: Constr
|
|
530 | - packConstr = mkConstr textDataType "pack" [] Prefix
|
|
531 | - |
|
532 | -Here `packConstr` isn't a real data constructor, it's an ordinary
|
|
533 | -function. Two complications
|
|
534 | - |
|
535 | -* In such a case, we must take care to build the Name using
|
|
536 | - mkNameG_v (for values), not mkNameG_d (for data constructors).
|
|
537 | - See #10796.
|
|
538 | - |
|
539 | -* The pseudo-constructor is named only by its string, here "pack".
|
|
540 | - But 'dataToQa' needs the TyCon of its defining module, and has
|
|
541 | - to assume it's defined in the same module as the TyCon itself.
|
|
542 | - But nothing enforces that; #12596 shows what goes wrong if
|
|
543 | - "pack" is defined in a different module than the data type "Text".
|
|
544 | - -}
|
|
545 | - |
|
546 | --- | A typed variant of 'dataToExpQ'.
|
|
547 | -dataToCodeQ :: (Quote m, Data a)
|
|
548 | - => (forall b . Data b => b -> Maybe (Code m b))
|
|
549 | - -> a -> Code m a
|
|
550 | -dataToCodeQ f = unsafeCodeCoerce . dataToExpQ (fmap unTypeCode . f)
|
|
551 | - |
|
552 | --- | 'dataToExpQ' converts a value to a 'Exp' representation of the
|
|
553 | --- same value, in the SYB style. It is generalized to take a function
|
|
554 | --- override type-specific cases; see 'liftData' for a more commonly
|
|
555 | --- used variant.
|
|
556 | -dataToExpQ :: (Quote m, Data a)
|
|
557 | - => (forall b . Data b => b -> Maybe (m Exp))
|
|
558 | - -> a
|
|
559 | - -> m Exp
|
|
560 | -dataToExpQ = dataToQa varOrConE litE (foldl appE)
|
|
561 | - where
|
|
562 | - -- Make sure that VarE is used if the Constr value relies on a
|
|
563 | - -- function underneath the surface (instead of a constructor).
|
|
564 | - -- See #10796.
|
|
565 | - varOrConE s =
|
|
566 | - case nameSpace s of
|
|
567 | - Just VarName -> return (VarE s)
|
|
568 | - Just (FldName {}) -> return (VarE s)
|
|
569 | - Just DataName -> return (ConE s)
|
|
570 | - _ -> error $ "Can't construct an expression from name "
|
|
571 | - ++ showName s
|
|
572 | - appE x y = do { a <- x; b <- y; return (AppE a b)}
|
|
573 | - litE c = return (LitE c)
|
|
574 | - |
|
575 | --- | A typed variant of 'liftData'.
|
|
576 | -liftDataTyped :: (Quote m, Data a) => a -> Code m a
|
|
577 | -liftDataTyped = dataToCodeQ (const Nothing)
|
|
578 | - |
|
579 | --- | 'liftData' is a variant of 'lift' in the 'Lift' type class which
|
|
580 | --- works for any type with a 'Data' instance.
|
|
581 | -liftData :: (Quote m, Data a) => a -> m Exp
|
|
582 | -liftData = dataToExpQ (const Nothing)
|
|
583 | - |
|
584 | --- | 'dataToPatQ' converts a value to a 'Pat' representation of the same
|
|
585 | --- value, in the SYB style. It takes a function to handle type-specific cases,
|
|
586 | --- alternatively, pass @const Nothing@ to get default behavior.
|
|
587 | -dataToPatQ :: (Quote m, Data a)
|
|
588 | - => (forall b . Data b => b -> Maybe (m Pat))
|
|
589 | - -> a
|
|
590 | - -> m Pat
|
|
591 | -dataToPatQ = dataToQa id litP conP
|
|
592 | - where litP l = return (LitP l)
|
|
593 | - conP n ps =
|
|
594 | - case nameSpace n of
|
|
595 | - Just DataName -> do
|
|
596 | - ps' <- sequence ps
|
|
597 | - return (ConP n [] ps')
|
|
598 | - _ -> error $ "Can't construct a pattern from name "
|
|
599 | - ++ showName n |
... | ... | @@ -22,9 +22,6 @@ module GHC.Internal.TH.Syntax |
22 | 22 | -- * Language extensions
|
23 | 23 | , module GHC.Internal.LanguageExtensions
|
24 | 24 | , ForeignSrcLang(..)
|
25 | - -- * Notes
|
|
26 | - -- ** Unresolved Infix
|
|
27 | - -- $infix
|
|
28 | 25 | ) where
|
29 | 26 | |
30 | 27 | #ifdef BOOTSTRAP_TH
|
... | ... | @@ -847,12 +844,6 @@ addTempFile suffix = Q (qAddTempFile suffix) |
847 | 844 | addTopDecls :: [Dec] -> Q ()
|
848 | 845 | addTopDecls ds = Q (qAddTopDecls ds)
|
849 | 846 | |
850 | --- |
|
|
851 | -addForeignFile :: ForeignSrcLang -> String -> Q ()
|
|
852 | -addForeignFile = addForeignSource
|
|
853 | -{-# DEPRECATED addForeignFile
|
|
854 | - "Use 'Language.Haskell.TH.Syntax.addForeignSource' instead"
|
|
855 | - #-} -- deprecated in 8.6
|
|
856 | 847 | |
857 | 848 | -- | Emit a foreign file which will be compiled and linked to the object for
|
858 | 849 | -- the current module. Currently only languages that can be compiled with
|
... | ... | @@ -1614,73 +1605,6 @@ maxPrecedence = (9::Int) |
1614 | 1605 | defaultFixity :: Fixity
|
1615 | 1606 | defaultFixity = Fixity maxPrecedence InfixL
|
1616 | 1607 | |
1617 | - |
|
1618 | -{-
|
|
1619 | -Note [Unresolved infix]
|
|
1620 | -~~~~~~~~~~~~~~~~~~~~~~~
|
|
1621 | --}
|
|
1622 | -{- $infix #infix#
|
|
1623 | - |
|
1624 | -When implementing antiquotation for quasiquoters, one often wants
|
|
1625 | -to parse strings into expressions:
|
|
1626 | - |
|
1627 | -> parse :: String -> Maybe Exp
|
|
1628 | - |
|
1629 | -But how should we parse @a + b * c@? If we don't know the fixities of
|
|
1630 | -@+@ and @*@, we don't know whether to parse it as @a + (b * c)@ or @(a
|
|
1631 | -+ b) * c@.
|
|
1632 | - |
|
1633 | -In cases like this, use 'UInfixE', 'UInfixP', 'UInfixT', or 'PromotedUInfixT',
|
|
1634 | -which stand for \"unresolved infix expression / pattern / type / promoted
|
|
1635 | -constructor\", respectively. When the compiler is given a splice containing a
|
|
1636 | -tree of @UInfixE@ applications such as
|
|
1637 | - |
|
1638 | -> UInfixE
|
|
1639 | -> (UInfixE e1 op1 e2)
|
|
1640 | -> op2
|
|
1641 | -> (UInfixE e3 op3 e4)
|
|
1642 | - |
|
1643 | -it will look up and the fixities of the relevant operators and
|
|
1644 | -reassociate the tree as necessary.
|
|
1645 | - |
|
1646 | - * trees will not be reassociated across 'ParensE', 'ParensP', or 'ParensT',
|
|
1647 | - which are of use for parsing expressions like
|
|
1648 | - |
|
1649 | - > (a + b * c) + d * e
|
|
1650 | - |
|
1651 | - * 'InfixE', 'InfixP', 'InfixT', and 'PromotedInfixT' expressions are never
|
|
1652 | - reassociated.
|
|
1653 | - |
|
1654 | - * The 'UInfixE' constructor doesn't support sections. Sections
|
|
1655 | - such as @(a *)@ have no ambiguity, so 'InfixE' suffices. For longer
|
|
1656 | - sections such as @(a + b * c -)@, use an 'InfixE' constructor for the
|
|
1657 | - outer-most section, and use 'UInfixE' constructors for all
|
|
1658 | - other operators:
|
|
1659 | - |
|
1660 | - > InfixE
|
|
1661 | - > Just (UInfixE ...a + b * c...)
|
|
1662 | - > op
|
|
1663 | - > Nothing
|
|
1664 | - |
|
1665 | - Sections such as @(a + b +)@ and @((a + b) +)@ should be rendered
|
|
1666 | - into 'Exp's differently:
|
|
1667 | - |
|
1668 | - > (+ a + b) ---> InfixE Nothing + (Just $ UInfixE a + b)
|
|
1669 | - > -- will result in a fixity error if (+) is left-infix
|
|
1670 | - > (+ (a + b)) ---> InfixE Nothing + (Just $ ParensE $ UInfixE a + b)
|
|
1671 | - > -- no fixity errors
|
|
1672 | - |
|
1673 | - * Quoted expressions such as
|
|
1674 | - |
|
1675 | - > [| a * b + c |] :: Q Exp
|
|
1676 | - > [p| a : b : c |] :: Q Pat
|
|
1677 | - > [t| T + T |] :: Q Type
|
|
1678 | - |
|
1679 | - will never contain 'UInfixE', 'UInfixP', 'UInfixT', 'PromotedUInfixT',
|
|
1680 | - 'InfixT', 'PromotedInfixT, 'ParensE', 'ParensP', or 'ParensT' constructors.
|
|
1681 | - |
|
1682 | --}
|
|
1683 | - |
|
1684 | 1608 | -----------------------------------------------------
|
1685 | 1609 | --
|
1686 | 1610 | -- The main syntax data types
|
... | ... | @@ -395,3 +395,66 @@ mdoE = Internal.mdoE Nothing |
395 | 395 | |
396 | 396 | conP :: Quote m => Name -> [m Pat] -> m Pat
|
397 | 397 | conP n xs = Internal.conP n [] xs
|
398 | + |
|
399 | + |
|
400 | +--------------------------------------------------------------------------------
|
|
401 | +-- * Constraint predicates (deprecated)
|
|
402 | + |
|
403 | +{-# DEPRECATED classP "As of template-haskell-2.10, constraint predicates (Pred) are just types (Type), in keeping with ConstraintKinds. Please use 'conT' and 'appT'." #-}
|
|
404 | +classP :: Quote m => Name -> [m Type] -> m Pred
|
|
405 | +classP cla tys
|
|
406 | + = do
|
|
407 | + tysl <- sequenceA tys
|
|
408 | + pure (foldl AppT (ConT cla) tysl)
|
|
409 | + |
|
410 | +{-# DEPRECATED equalP "As of template-haskell-2.10, constraint predicates (Pred) are just types (Type), in keeping with ConstraintKinds. Please see 'equalityT'." #-}
|
|
411 | +equalP :: Quote m => m Type -> m Type -> m Pred
|
|
412 | +equalP tleft tright
|
|
413 | + = do
|
|
414 | + tleft1 <- tleft
|
|
415 | + tright1 <- tright
|
|
416 | + eqT <- equalityT
|
|
417 | + pure (foldl AppT eqT [tleft1, tright1])
|
|
418 | + |
|
419 | +--------------------------------------------------------------------------------
|
|
420 | +-- * Strictness queries (deprecated)
|
|
421 | +{-# DEPRECATED isStrict
|
|
422 | + ["Use 'bang'. See https://gitlab.haskell.org/ghc/ghc/wikis/migration/8.0. ",
|
|
423 | + "Example usage: 'bang noSourceUnpackedness sourceStrict'"] #-}
|
|
424 | +{-# DEPRECATED notStrict
|
|
425 | + ["Use 'bang'. See https://gitlab.haskell.org/ghc/ghc/wikis/migration/8.0. ",
|
|
426 | + "Example usage: 'bang noSourceUnpackedness noSourceStrictness'"] #-}
|
|
427 | +{-# DEPRECATED unpacked
|
|
428 | + ["Use 'bang'. See https://gitlab.haskell.org/ghc/ghc/wikis/migration/8.0. ",
|
|
429 | + "Example usage: 'bang sourceUnpack sourceStrict'"] #-}
|
|
430 | +isStrict, notStrict, unpacked :: Quote m => m Strict
|
|
431 | +isStrict = bang noSourceUnpackedness sourceStrict
|
|
432 | +notStrict = bang noSourceUnpackedness noSourceStrictness
|
|
433 | +unpacked = bang sourceUnpack sourceStrict
|
|
434 | + |
|
435 | +{-# DEPRECATED strictType
|
|
436 | + "As of @template-haskell-2.11.0.0@, 'StrictType' has been replaced by 'BangType'. Please use 'bangType' instead." #-}
|
|
437 | +strictType :: Quote m => m Strict -> m Type -> m StrictType
|
|
438 | +strictType = bangType
|
|
439 | + |
|
440 | +{-# DEPRECATED varStrictType
|
|
441 | + "As of @template-haskell-2.11.0.0@, 'VarStrictType' has been replaced by 'VarBangType'. Please use 'varBangType' instead." #-}
|
|
442 | +varStrictType :: Quote m => Name -> m StrictType -> m VarStrictType
|
|
443 | +varStrictType = varBangType
|
|
444 | + |
|
445 | +--------------------------------------------------------------------------------
|
|
446 | +-- * Specialisation pragmas (deprecated)
|
|
447 | + |
|
448 | +{-# DEPRECATED pragSpecD "Please use 'pragSpecED' instead. 'pragSpecD' will be removed in GHC 9.18." #-}
|
|
449 | +pragSpecD :: Quote m => Name -> m Type -> Phases -> m Dec
|
|
450 | +pragSpecD n ty phases
|
|
451 | + = do
|
|
452 | + ty1 <- ty
|
|
453 | + pure $ PragmaD $ SpecialiseP n ty1 Nothing phases
|
|
454 | + |
|
455 | +{-# DEPRECATED pragSpecInlD "Please use 'pragSpecInlED' instead. 'pragSpecInlD' will be removed in GHC 9.18." #-}
|
|
456 | +pragSpecInlD :: Quote m => Name -> m Type -> Inline -> Phases -> m Dec
|
|
457 | +pragSpecInlD n ty inline phases
|
|
458 | + = do
|
|
459 | + ty1 <- ty
|
|
460 | + pure $ PragmaD $ SpecialiseP n ty1 (Just inline) phases |
... | ... | @@ -19,12 +19,12 @@ module Language.Haskell.TH.Quote |
19 | 19 | , namedDefaultQuasiQuoter
|
20 | 20 | , defaultQuasiQuoter
|
21 | 21 | -- * For backwards compatibility
|
22 | - ,dataToQa, dataToExpQ, dataToPatQ
|
|
22 | + , dataToQa, dataToExpQ, dataToPatQ
|
|
23 | 23 | ) where
|
24 | 24 | |
25 | 25 | import GHC.Boot.TH.Syntax
|
26 | 26 | import GHC.Boot.TH.Quote
|
27 | -import GHC.Boot.TH.Lift
|
|
27 | +import Language.Haskell.TH.Syntax (dataToQa, dataToExpQ, dataToPatQ)
|
|
28 | 28 | |
29 | 29 | |
30 | 30 | -- | 'quoteFile' takes a 'QuasiQuoter' and lifts it into one that read
|
1 | 1 | {-# LANGUAGE MagicHash #-}
|
2 | +{-# LANGUAGE RankNTypes #-}
|
|
3 | +{-# LANGUAGE ScopedTypeVariables #-}
|
|
2 | 4 | {-# LANGUAGE TemplateHaskellQuotes #-}
|
3 | -{-# LANGUAGE Safe #-}
|
|
5 | +{-# LANGUAGE Trustworthy #-}
|
|
4 | 6 | {-# LANGUAGE UnboxedTuples #-}
|
5 | 7 | |
6 | 8 | module Language.Haskell.TH.Syntax (
|
... | ... | @@ -190,19 +192,267 @@ module Language.Haskell.TH.Syntax ( |
190 | 192 | nothingName,
|
191 | 193 | rightName,
|
192 | 194 | trueName,
|
195 | + -- * Notes
|
|
196 | + -- ** Unresolved Infix
|
|
197 | + -- $infix
|
|
193 | 198 | )
|
194 | 199 | where
|
195 | 200 | |
196 | 201 | import GHC.Boot.TH.Lift
|
197 | 202 | import GHC.Boot.TH.Syntax
|
198 | 203 | import System.FilePath
|
204 | +import Data.Data hiding (Fixity(..))
|
|
205 | +import Data.List.NonEmpty (NonEmpty(..))
|
|
206 | +import GHC.Lexeme ( startsVarSym, startsVarId )
|
|
199 | 207 | |
200 | 208 | -- This module completely re-exports 'GHC.Boot.TH.Syntax',
|
201 | 209 | -- and exports additionally functions that depend on filepath.
|
202 | 210 | |
211 | +-- |
|
|
212 | +addForeignFile :: ForeignSrcLang -> String -> Q ()
|
|
213 | +addForeignFile = addForeignSource
|
|
214 | +{-# DEPRECATED addForeignFile
|
|
215 | + "Use 'Language.Haskell.TH.Syntax.addForeignSource' instead"
|
|
216 | + #-} -- deprecated in 8.6
|
|
217 | + |
|
203 | 218 | -- | The input is a filepath, which if relative is offset by the package root.
|
204 | 219 | makeRelativeToProject :: FilePath -> Q FilePath
|
205 | 220 | makeRelativeToProject fp | isRelative fp = do
|
206 | 221 | root <- getPackageRoot
|
207 | 222 | return (root </> fp)
|
208 | 223 | makeRelativeToProject fp = return fp
|
224 | + |
|
225 | +trueName, falseName :: Name
|
|
226 | +trueName = 'True
|
|
227 | +falseName = 'False
|
|
228 | + |
|
229 | +nothingName, justName :: Name
|
|
230 | +nothingName = 'Nothing
|
|
231 | +justName = 'Just
|
|
232 | + |
|
233 | +leftName, rightName :: Name
|
|
234 | +leftName = 'Left
|
|
235 | +rightName = 'Right
|
|
236 | + |
|
237 | +nonemptyName :: Name
|
|
238 | +nonemptyName = '(:|)
|
|
239 | + |
|
240 | +-----------------------------------------------------
|
|
241 | +--
|
|
242 | +-- Generic Lift implementations
|
|
243 | +--
|
|
244 | +-----------------------------------------------------
|
|
245 | + |
|
246 | +-- | 'dataToQa' is an internal utility function for constructing generic
|
|
247 | +-- conversion functions from types with 'Data' instances to various
|
|
248 | +-- quasi-quoting representations. See the source of 'dataToExpQ' and
|
|
249 | +-- 'dataToPatQ' for two example usages: @mkCon@, @mkLit@
|
|
250 | +-- and @appQ@ are overloadable to account for different syntax for
|
|
251 | +-- expressions and patterns; @antiQ@ allows you to override type-specific
|
|
252 | +-- cases, a common usage is just @const Nothing@, which results in
|
|
253 | +-- no overloading.
|
|
254 | +dataToQa :: forall m a k q. (Quote m, Data a)
|
|
255 | + => (Name -> k)
|
|
256 | + -> (Lit -> m q)
|
|
257 | + -> (k -> [m q] -> m q)
|
|
258 | + -> (forall b . Data b => b -> Maybe (m q))
|
|
259 | + -> a
|
|
260 | + -> m q
|
|
261 | +dataToQa mkCon mkLit appCon antiQ t =
|
|
262 | + case antiQ t of
|
|
263 | + Nothing ->
|
|
264 | + case constrRep constr of
|
|
265 | + AlgConstr _ ->
|
|
266 | + appCon (mkCon funOrConName) conArgs
|
|
267 | + where
|
|
268 | + funOrConName :: Name
|
|
269 | + funOrConName =
|
|
270 | + case showConstr constr of
|
|
271 | + "(:)" -> Name (mkOccName ":")
|
|
272 | + (NameG DataName
|
|
273 | + (mkPkgName "ghc-internal")
|
|
274 | + (mkModName "GHC.Internal.Types"))
|
|
275 | + con@"[]" -> Name (mkOccName con)
|
|
276 | + (NameG DataName
|
|
277 | + (mkPkgName "ghc-internal")
|
|
278 | + (mkModName "GHC.Internal.Types"))
|
|
279 | + con@('(':_) -> Name (mkOccName con)
|
|
280 | + (NameG DataName
|
|
281 | + (mkPkgName "ghc-internal")
|
|
282 | + (mkModName "GHC.Internal.Tuple"))
|
|
283 | + |
|
284 | + -- Tricky case: see Note [Data for non-algebraic types]
|
|
285 | + fun@(x:_) | startsVarSym x || startsVarId x
|
|
286 | + -> mkNameG_v tyconPkg tyconMod fun
|
|
287 | + con -> mkNameG_d tyconPkg tyconMod con
|
|
288 | + |
|
289 | + where
|
|
290 | + tycon :: TyCon
|
|
291 | + tycon = (typeRepTyCon . typeOf) t
|
|
292 | + |
|
293 | + tyconPkg, tyconMod :: String
|
|
294 | + tyconPkg = tyConPackage tycon
|
|
295 | + tyconMod = tyConModule tycon
|
|
296 | + |
|
297 | + conArgs :: [m q]
|
|
298 | + conArgs = gmapQ (dataToQa mkCon mkLit appCon antiQ) t
|
|
299 | + IntConstr n ->
|
|
300 | + mkLit $ IntegerL n
|
|
301 | + FloatConstr n ->
|
|
302 | + mkLit $ RationalL n
|
|
303 | + CharConstr c ->
|
|
304 | + mkLit $ CharL c
|
|
305 | + where
|
|
306 | + constr :: Constr
|
|
307 | + constr = toConstr t
|
|
308 | + |
|
309 | + Just y -> y
|
|
310 | + |
|
311 | + |
|
312 | +{- Note [Data for non-algebraic types]
|
|
313 | +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
314 | +Class Data was originally intended for algebraic data types. But
|
|
315 | +it is possible to use it for abstract types too. For example, in
|
|
316 | +package `text` we find
|
|
317 | + |
|
318 | + instance Data Text where
|
|
319 | + ...
|
|
320 | + toConstr _ = packConstr
|
|
321 | + |
|
322 | + packConstr :: Constr
|
|
323 | + packConstr = mkConstr textDataType "pack" [] Prefix
|
|
324 | + |
|
325 | +Here `packConstr` isn't a real data constructor, it's an ordinary
|
|
326 | +function. Two complications
|
|
327 | + |
|
328 | +* In such a case, we must take care to build the Name using
|
|
329 | + mkNameG_v (for values), not mkNameG_d (for data constructors).
|
|
330 | + See #10796.
|
|
331 | + |
|
332 | +* The pseudo-constructor is named only by its string, here "pack".
|
|
333 | + But 'dataToQa' needs the TyCon of its defining module, and has
|
|
334 | + to assume it's defined in the same module as the TyCon itself.
|
|
335 | + But nothing enforces that; #12596 shows what goes wrong if
|
|
336 | + "pack" is defined in a different module than the data type "Text".
|
|
337 | + -}
|
|
338 | + |
|
339 | +-- | A typed variant of 'dataToExpQ'.
|
|
340 | +dataToCodeQ :: (Quote m, Data a)
|
|
341 | + => (forall b . Data b => b -> Maybe (Code m b))
|
|
342 | + -> a -> Code m a
|
|
343 | +dataToCodeQ f = unsafeCodeCoerce . dataToExpQ (fmap unTypeCode . f)
|
|
344 | + |
|
345 | +-- | 'dataToExpQ' converts a value to a 'Exp' representation of the
|
|
346 | +-- same value, in the SYB style. It is generalized to take a function
|
|
347 | +-- override type-specific cases; see 'liftData' for a more commonly
|
|
348 | +-- used variant.
|
|
349 | +dataToExpQ :: (Quote m, Data a)
|
|
350 | + => (forall b . Data b => b -> Maybe (m Exp))
|
|
351 | + -> a
|
|
352 | + -> m Exp
|
|
353 | +dataToExpQ = dataToQa varOrConE litE (foldl appE)
|
|
354 | + where
|
|
355 | + -- Make sure that VarE is used if the Constr value relies on a
|
|
356 | + -- function underneath the surface (instead of a constructor).
|
|
357 | + -- See #10796.
|
|
358 | + varOrConE s =
|
|
359 | + case nameSpace s of
|
|
360 | + Just VarName -> return (VarE s)
|
|
361 | + Just (FldName {}) -> return (VarE s)
|
|
362 | + Just DataName -> return (ConE s)
|
|
363 | + _ -> error $ "Can't construct an expression from name "
|
|
364 | + ++ showName s
|
|
365 | + appE x y = do { a <- x; b <- y; return (AppE a b)}
|
|
366 | + litE c = return (LitE c)
|
|
367 | + |
|
368 | +-- | A typed variant of 'liftData'.
|
|
369 | +liftDataTyped :: (Quote m, Data a) => a -> Code m a
|
|
370 | +liftDataTyped = dataToCodeQ (const Nothing)
|
|
371 | + |
|
372 | +-- | 'liftData' is a variant of 'lift' in the 'Lift' type class which
|
|
373 | +-- works for any type with a 'Data' instance.
|
|
374 | +liftData :: (Quote m, Data a) => a -> m Exp
|
|
375 | +liftData = dataToExpQ (const Nothing)
|
|
376 | + |
|
377 | +-- | 'dataToPatQ' converts a value to a 'Pat' representation of the same
|
|
378 | +-- value, in the SYB style. It takes a function to handle type-specific cases,
|
|
379 | +-- alternatively, pass @const Nothing@ to get default behavior.
|
|
380 | +dataToPatQ :: (Quote m, Data a)
|
|
381 | + => (forall b . Data b => b -> Maybe (m Pat))
|
|
382 | + -> a
|
|
383 | + -> m Pat
|
|
384 | +dataToPatQ = dataToQa id litP conP
|
|
385 | + where litP l = return (LitP l)
|
|
386 | + conP n ps =
|
|
387 | + case nameSpace n of
|
|
388 | + Just DataName -> do
|
|
389 | + ps' <- sequence ps
|
|
390 | + return (ConP n [] ps')
|
|
391 | + _ -> error $ "Can't construct a pattern from name "
|
|
392 | + ++ showName n
|
|
393 | + |
|
394 | +{-
|
|
395 | +Note [Unresolved infix]
|
|
396 | +~~~~~~~~~~~~~~~~~~~~~~~
|
|
397 | +-}
|
|
398 | +{- $infix #infix#
|
|
399 | + |
|
400 | +When implementing antiquotation for quasiquoters, one often wants
|
|
401 | +to parse strings into expressions:
|
|
402 | + |
|
403 | +> parse :: String -> Maybe Exp
|
|
404 | + |
|
405 | +But how should we parse @a + b * c@? If we don't know the fixities of
|
|
406 | +@+@ and @*@, we don't know whether to parse it as @a + (b * c)@ or @(a
|
|
407 | ++ b) * c@.
|
|
408 | + |
|
409 | +In cases like this, use 'UInfixE', 'UInfixP', 'UInfixT', or 'PromotedUInfixT',
|
|
410 | +which stand for \"unresolved infix expression / pattern / type / promoted
|
|
411 | +constructor\", respectively. When the compiler is given a splice containing a
|
|
412 | +tree of @UInfixE@ applications such as
|
|
413 | + |
|
414 | +> UInfixE
|
|
415 | +> (UInfixE e1 op1 e2)
|
|
416 | +> op2
|
|
417 | +> (UInfixE e3 op3 e4)
|
|
418 | + |
|
419 | +it will look up and the fixities of the relevant operators and
|
|
420 | +reassociate the tree as necessary.
|
|
421 | + |
|
422 | + * trees will not be reassociated across 'ParensE', 'ParensP', or 'ParensT',
|
|
423 | + which are of use for parsing expressions like
|
|
424 | + |
|
425 | + > (a + b * c) + d * e
|
|
426 | + |
|
427 | + * 'InfixE', 'InfixP', 'InfixT', and 'PromotedInfixT' expressions are never
|
|
428 | + reassociated.
|
|
429 | + |
|
430 | + * The 'UInfixE' constructor doesn't support sections. Sections
|
|
431 | + such as @(a *)@ have no ambiguity, so 'InfixE' suffices. For longer
|
|
432 | + sections such as @(a + b * c -)@, use an 'InfixE' constructor for the
|
|
433 | + outer-most section, and use 'UInfixE' constructors for all
|
|
434 | + other operators:
|
|
435 | + |
|
436 | + > InfixE
|
|
437 | + > Just (UInfixE ...a + b * c...)
|
|
438 | + > op
|
|
439 | + > Nothing
|
|
440 | + |
|
441 | + Sections such as @(a + b +)@ and @((a + b) +)@ should be rendered
|
|
442 | + into 'Exp's differently:
|
|
443 | + |
|
444 | + > (+ a + b) ---> InfixE Nothing + (Just $ UInfixE a + b)
|
|
445 | + > -- will result in a fixity error if (+) is left-infix
|
|
446 | + > (+ (a + b)) ---> InfixE Nothing + (Just $ ParensE $ UInfixE a + b)
|
|
447 | + > -- no fixity errors
|
|
448 | + |
|
449 | + * Quoted expressions such as
|
|
450 | + |
|
451 | + > [| a * b + c |] :: Q Exp
|
|
452 | + > [p| a : b : c |] :: Q Pat
|
|
453 | + > [t| T + T |] :: Q Type
|
|
454 | + |
|
455 | + will never contain 'UInfixE', 'UInfixP', 'UInfixT', 'PromotedUInfixT',
|
|
456 | + 'InfixT', 'PromotedInfixT, 'ParensE', 'ParensP', or 'ParensT' constructors.
|
|
457 | + |
|
458 | +-} |
1 | 1 | # difficult to test TH with profiling, because we have to build twice
|
2 | -test('dataToExpQUnit', [omit_ways(prof_ways), req_th], compile, ['-v0'])
|
|
3 | -test('dataToCodeQUnit', [omit_ways(prof_ways), req_th], compile, ['-v0'])
|
|
2 | +test('dataToExpQUnit', [omit_ways(prof_ways), req_th], compile, ['-package template-haskell -v0'])
|
|
3 | +test('dataToCodeQUnit', [omit_ways(prof_ways), req_th], compile, ['-package template-haskell -v0'])
|
|
4 | 4 | test('pragCompletePpr', [omit_ways(prof_ways), req_th], compile_and_run, ['']) |
... | ... | @@ -1375,7 +1375,7 @@ module Language.Haskell.TH.Quote where |
1375 | 1375 | quoteFile :: QuasiQuoter -> QuasiQuoter
|
1376 | 1376 | |
1377 | 1377 | module Language.Haskell.TH.Syntax where
|
1378 | - -- Safety: Safe
|
|
1378 | + -- Safety: Trustworthy
|
|
1379 | 1379 | type AnnLookup :: *
|
1380 | 1380 | data AnnLookup = AnnLookupModule Module | AnnLookupName Name
|
1381 | 1381 | type AnnTarget :: *
|
... | ... | @@ -7,4 +7,4 @@ test('T4491', |
7 | 7 | # the TH way
|
8 | 8 | only_ways([config.ghc_th_way]),
|
9 | 9 | ],
|
10 | - compile_and_run, ['']) |
|
10 | + compile_and_run, ['-package template-haskell']) |
... | ... | @@ -9,8 +9,8 @@ T2386: |
9 | 9 | '$(TEST_HC)' $(TEST_HC_OPTS) $(ghcThWayFlags) -v0 -c T2386.hs
|
10 | 10 | |
11 | 11 | T7445:
|
12 | - '$(TEST_HC)' $(TEST_HC_OPTS) $(ghcThWayFlags) -v0 -c T7445a.hs
|
|
13 | - '$(TEST_HC)' $(TEST_HC_OPTS) $(ghcThWayFlags) -v0 -c T7445.hs
|
|
12 | + '$(TEST_HC)' $(TEST_HC_OPTS) $(ghcThWayFlags) -package template-haskell -v0 -c T7445a.hs
|
|
13 | + '$(TEST_HC)' $(TEST_HC_OPTS) $(ghcThWayFlags) -package template-haskell -v0 -c T7445.hs
|
|
14 | 14 | |
15 | 15 | HC_OPTS = -XTemplateHaskell -package template-haskell
|
16 | 16 |