Teo Camarasu pushed to branch wip/abstract-q at Glasgow Haskell Compiler / GHC
Commits:
-
ce1298c9
by Teo Camarasu at 2026-06-08T15:01:00+01:00
9 changed files:
- + changelog.d/AbstractQ
- compiler/GHC/Data/IOEnv.hs
- compiler/GHC/Tc/Gen/Splice.hs
- compiler/GHC/Tc/Gen/Splice.hs-boot
- libraries/ghc-internal/src/GHC/Internal/TH/Lib.hs
- libraries/ghc-internal/src/GHC/Internal/TH/Monad.hs
- libraries/ghci/GHCi/TH.hs
- libraries/template-haskell/Language/Haskell/TH/Syntax.hs
- testsuite/tests/interface-stability/template-haskell-exports.stdout
Changes:
| 1 | +section: template-haskell
|
|
| 2 | +synopsis: Hide the implementation of Q
|
|
| 3 | +description: The constructor of Q is now hidden.
|
|
| 4 | + This is done to improve the stability of ``template-haskell``.
|
|
| 5 | + To minimize breakage, we have added a new ``qRunQ`` operation to ``Quasi``.
|
|
| 6 | +mrs: !15696
|
|
| 7 | +issues: #27341 |
| ... | ... | @@ -29,7 +29,7 @@ module GHC.Data.IOEnv ( |
| 29 | 29 | |
| 30 | 30 | -- I/O operations
|
| 31 | 31 | IORef, newMutVar, readMutVar, writeMutVar, updMutVar,
|
| 32 | - atomicUpdMutVar, atomicUpdMutVar'
|
|
| 32 | + atomicUpdMutVar, atomicUpdMutVar', unliftIOEnv
|
|
| 33 | 33 | ) where
|
| 34 | 34 | |
| 35 | 35 | import GHC.Prelude
|
| ... | ... | @@ -258,3 +258,11 @@ updEnv upd (IOEnv m) = IOEnv (\ env -> m (upd env)) |
| 258 | 258 | updEnvIO :: (env -> IO env') -> IOEnv env' a -> IOEnv env a
|
| 259 | 259 | {-# INLINE updEnvIO #-}
|
| 260 | 260 | updEnvIO upd (IOEnv m) = IOEnv (\ env -> m =<< upd env)
|
| 261 | + |
|
| 262 | +-- | Provide a continuation with a function that allows unlifting 'IOEnv' computations into 'IO'.
|
|
| 263 | +unliftIOEnv :: forall env b. ((forall a. IOEnv env a -> IO a) -> IO b) -> IOEnv env b
|
|
| 264 | +unliftIOEnv k = IOEnv $ \env ->
|
|
| 265 | + let
|
|
| 266 | + unlift :: forall a. IOEnv env a -> IO a
|
|
| 267 | + unlift (IOEnv m) = m env
|
|
| 268 | + in k unlift |
| ... | ... | @@ -25,7 +25,7 @@ module GHC.Tc.Gen.Splice( |
| 25 | 25 | tcTypedSplice, tcTypedBracket, tcUntypedBracket,
|
| 26 | 26 | runAnnotation, getUntypedSpliceBody,
|
| 27 | 27 | |
| 28 | - runMetaE, runMetaP, runMetaT, runMetaD, runQuasi,
|
|
| 28 | + runMetaE, runMetaP, runMetaT, runMetaD, runQinTcM,
|
|
| 29 | 29 | tcTopSpliceExpr, lookupThName_maybe,
|
| 30 | 30 | defaultRunMeta, runMeta', runRemoteModFinalizers,
|
| 31 | 31 | finishTH, runTopSplice
|
| ... | ... | @@ -138,6 +138,7 @@ import qualified GHC.LanguageExtensions as LangExt |
| 138 | 138 | -- THSyntax gives access to internal functions and data types
|
| 139 | 139 | import qualified GHC.Boot.TH.Syntax as TH
|
| 140 | 140 | import qualified GHC.Boot.TH.Monad as TH
|
| 141 | +import GHC.Boot.TH.Monad (MetaHandlers(..))
|
|
| 141 | 142 | import qualified GHC.Boot.TH.Ppr as TH
|
| 142 | 143 | |
| 143 | 144 | #if defined(HAVE_INTERNAL_INTERPRETER)
|
| ... | ... | @@ -1138,8 +1139,8 @@ convertAnnotationWrapper fhv = do |
| 1138 | 1139 | ************************************************************************
|
| 1139 | 1140 | -}
|
| 1140 | 1141 | |
| 1141 | -runQuasi :: TH.Q a -> TcM a
|
|
| 1142 | -runQuasi act = TH.runQ act
|
|
| 1142 | +runQinTcM :: TH.Q a -> TcM a
|
|
| 1143 | +runQinTcM (TH.Q act) = unliftIOEnv $ \runInIO -> liftIO $ act (metaHandlersTcM runInIO)
|
|
| 1143 | 1144 | |
| 1144 | 1145 | runRemoteModFinalizers :: ThModFinalizers -> TcM ()
|
| 1145 | 1146 | runRemoteModFinalizers (ThModFinalizers finRefs) = do
|
| ... | ... | @@ -1152,7 +1153,7 @@ runRemoteModFinalizers (ThModFinalizers finRefs) = do |
| 1152 | 1153 | #if defined(HAVE_INTERNAL_INTERPRETER)
|
| 1153 | 1154 | InternalInterp -> do
|
| 1154 | 1155 | qs <- liftIO (withForeignRefs finRefs $ mapM localRef)
|
| 1155 | - runQuasi $ sequence_ qs
|
|
| 1156 | + runQinTcM $ sequence_ qs
|
|
| 1156 | 1157 | #endif
|
| 1157 | 1158 | |
| 1158 | 1159 | ExternalInterp ext -> withExtInterp ext $ \inst -> do
|
| ... | ... | @@ -1466,70 +1467,14 @@ when showing an error message. |
| 1466 | 1467 | To call runQ in the Tc monad, we need to make TcM an instance of Quasi:
|
| 1467 | 1468 | -}
|
| 1468 | 1469 | |
| 1469 | -instance TH.Quasi TcM where
|
|
| 1470 | - qNewName s = do { u <- newUnique
|
|
| 1471 | - ; let i = toInteger (getKey u)
|
|
| 1472 | - ; return (TH.mkNameU s i) }
|
|
| 1470 | +-- 'msg' is forced to ensure exceptions don't escape,
|
|
| 1471 | +-- see Note [Exceptions in TH]
|
|
| 1472 | +report :: Bool -> [Char] -> TcM ()
|
|
| 1473 | +report True msg = seqList msg $ addErr $ TcRnTHError $ ReportCustomQuasiError True msg
|
|
| 1474 | +report False msg = seqList msg $ addDiagnostic $ TcRnTHError $ ReportCustomQuasiError False msg
|
|
| 1473 | 1475 | |
| 1474 | - -- 'msg' is forced to ensure exceptions don't escape,
|
|
| 1475 | - -- see Note [Exceptions in TH]
|
|
| 1476 | - qReport True msg = seqList msg $ addErr $ TcRnTHError $ ReportCustomQuasiError True msg
|
|
| 1477 | - qReport False msg = seqList msg $ addDiagnostic $ TcRnTHError $ ReportCustomQuasiError False msg
|
|
| 1478 | - |
|
| 1479 | - qLocation :: TcM TH.Loc
|
|
| 1480 | - qLocation = do { m <- getModule
|
|
| 1481 | - ; l <- getSrcSpanM
|
|
| 1482 | - ; r <- case l of
|
|
| 1483 | - RealSrcSpan s _ -> return s
|
|
| 1484 | - GeneratedSrcSpan{} -> pprPanic "qLocation: generatedSrcSpan"
|
|
| 1485 | - (pprGeneratedSrcSpanDetails)
|
|
| 1486 | - UnhelpfulSpan _ -> pprPanic "qLocation: Unhelpful location"
|
|
| 1487 | - (ppr l)
|
|
| 1488 | - ; return (TH.Loc { TH.loc_filename = unpackFS (srcSpanFile r)
|
|
| 1489 | - , TH.loc_module = moduleNameString (moduleName m)
|
|
| 1490 | - , TH.loc_package = unitString (moduleUnit m)
|
|
| 1491 | - , TH.loc_start = (srcSpanStartLine r, srcSpanStartCol r)
|
|
| 1492 | - , TH.loc_end = (srcSpanEndLine r, srcSpanEndCol r) }) }
|
|
| 1493 | - |
|
| 1494 | - qLookupName = lookupName
|
|
| 1495 | - qReify = reify
|
|
| 1496 | - qReifyFixity nm = lookupThName nm >>= reifyFixity
|
|
| 1497 | - qReifyType = reifyTypeOfThing
|
|
| 1498 | - qReifyInstances = reifyInstances
|
|
| 1499 | - qReifyRoles = reifyRoles
|
|
| 1500 | - qReifyAnnotations = reifyAnnotations
|
|
| 1501 | - qReifyModule = reifyModule
|
|
| 1502 | - qReifyConStrictness nm = do { nm' <- lookupThName nm
|
|
| 1503 | - ; dc <- tcLookupDataCon nm'
|
|
| 1504 | - ; let bangs = dataConImplBangs dc
|
|
| 1505 | - ; return (map reifyDecidedStrictness bangs) }
|
|
| 1506 | - |
|
| 1507 | - -- For qRecover, discard error messages if
|
|
| 1508 | - -- the recovery action is chosen. Otherwise
|
|
| 1509 | - -- we'll only fail higher up.
|
|
| 1510 | - qRecover recover main = tryTcDiscardingErrs recover main
|
|
| 1511 | - |
|
| 1512 | - qGetPackageRoot = do
|
|
| 1513 | - dflags <- getDynFlags
|
|
| 1514 | - return $ fromMaybe "." (workingDirectory dflags)
|
|
| 1515 | - |
|
| 1516 | - qAddDependentFile fp = do
|
|
| 1517 | - ref <- fmap tcg_dependent_files getGblEnv
|
|
| 1518 | - dep_files <- readTcRef ref
|
|
| 1519 | - writeTcRef ref (fp:dep_files)
|
|
| 1520 | - |
|
| 1521 | - qAddDependentDirectory dp = do
|
|
| 1522 | - ref <- fmap tcg_dependent_dirs getGblEnv
|
|
| 1523 | - dep_dirs <- readTcRef ref
|
|
| 1524 | - writeTcRef ref (dp:dep_dirs)
|
|
| 1525 | - |
|
| 1526 | - qAddTempFile suffix = do
|
|
| 1527 | - dflags <- getDynFlags
|
|
| 1528 | - logger <- getLogger
|
|
| 1529 | - tmpfs <- hsc_tmpfs <$> getTopEnv
|
|
| 1530 | - liftIO $ newTempName logger tmpfs (tmpDir dflags) TFL_GhcSession suffix
|
|
| 1531 | - |
|
| 1532 | - qAddTopDecls thds = do
|
|
| 1476 | +addTopDecls :: [TH.Dec] -> TcM ()
|
|
| 1477 | +addTopDecls thds = do
|
|
| 1533 | 1478 | exts <- fmap extensionFlags getDynFlags
|
| 1534 | 1479 | l <- getSrcSpanM
|
| 1535 | 1480 | th_origin <- getThSpliceOrigin
|
| ... | ... | @@ -1557,52 +1502,13 @@ instance TH.Quasi TcM where |
| 1557 | 1502 | bindName :: RdrName -> TcM ()
|
| 1558 | 1503 | bindName (Exact n)
|
| 1559 | 1504 | = do { th_topnames_var <- fmap tcg_th_topnames getGblEnv
|
| 1560 | - ; updTcRef th_topnames_var (\ns -> extendNameSet ns n)
|
|
| 1561 | - }
|
|
| 1505 | + ; updTcRef th_topnames_var (\ns -> extendNameSet ns n)
|
|
| 1506 | + }
|
|
| 1562 | 1507 | |
| 1563 | 1508 | bindName name = addErr $ TcRnTHError $ THNameError $ NonExactName name
|
| 1564 | 1509 | |
| 1565 | - qAddForeignFilePath lang fp = do
|
|
| 1566 | - var <- fmap tcg_th_foreign_files getGblEnv
|
|
| 1567 | - updTcRef var ((lang, fp) :)
|
|
| 1568 | - |
|
| 1569 | - qAddModFinalizer fin = do
|
|
| 1570 | - r <- liftIO $ mkRemoteRef fin
|
|
| 1571 | - fref <- liftIO $ mkForeignRef r (freeRemoteRef r)
|
|
| 1572 | - addModFinalizerRef fref
|
|
| 1573 | - |
|
| 1574 | - qAddCorePlugin plugin = do
|
|
| 1575 | - hsc_env <- getTopEnv
|
|
| 1576 | - let fc = hsc_FC hsc_env
|
|
| 1577 | - let home_unit = hsc_home_unit hsc_env
|
|
| 1578 | - let dflags = hsc_dflags hsc_env
|
|
| 1579 | - let fopts = initFinderOpts dflags
|
|
| 1580 | - r <- liftIO $ findHomeModule fc fopts home_unit (mkModuleName plugin)
|
|
| 1581 | - let err = TcRnTHError $ AddInvalidCorePlugin plugin
|
|
| 1582 | - case r of
|
|
| 1583 | - Found {} -> addErr err
|
|
| 1584 | - FoundMultiple {} -> addErr err
|
|
| 1585 | - _ -> return ()
|
|
| 1586 | - th_coreplugins_var <- tcg_th_coreplugins <$> getGblEnv
|
|
| 1587 | - updTcRef th_coreplugins_var (plugin:)
|
|
| 1588 | - |
|
| 1589 | - qGetQ :: forall a. Typeable a => TcM (Maybe a)
|
|
| 1590 | - qGetQ = do
|
|
| 1591 | - th_state_var <- fmap tcg_th_state getGblEnv
|
|
| 1592 | - th_state <- readTcRef th_state_var
|
|
| 1593 | - -- See #10596 for why we use a scoped type variable here.
|
|
| 1594 | - return (Map.lookup (typeRep (Proxy :: Proxy a)) th_state >>= fromDynamic)
|
|
| 1595 | - |
|
| 1596 | - qPutQ x = do
|
|
| 1597 | - th_state_var <- fmap tcg_th_state getGblEnv
|
|
| 1598 | - updTcRef th_state_var (\m -> Map.insert (typeOf x) (toDyn x) m)
|
|
| 1599 | - |
|
| 1600 | - qIsExtEnabled = xoptM
|
|
| 1601 | - |
|
| 1602 | - qExtsEnabled =
|
|
| 1603 | - EnumSet.toList . extensionFlags . hsc_dflags <$> getTopEnv
|
|
| 1604 | - |
|
| 1605 | - qPutDoc doc_loc s = do
|
|
| 1510 | +putDoc :: TH.DocLoc -> String -> TcM ()
|
|
| 1511 | +putDoc doc_loc s = do
|
|
| 1606 | 1512 | th_doc_var <- tcg_th_docs <$> getGblEnv
|
| 1607 | 1513 | resolved_doc_loc <- resolve_loc doc_loc
|
| 1608 | 1514 | is_local <- checkLocalName resolved_doc_loc
|
| ... | ... | @@ -1624,15 +1530,133 @@ instance TH.Quasi TcM where |
| 1624 | 1530 | checkLocalName (InstDoc n) = nameIsLocalOrFrom <$> getModule <*> pure n
|
| 1625 | 1531 | checkLocalName ModuleDoc = pure True
|
| 1626 | 1532 | |
| 1627 | - |
|
| 1628 | - qGetDoc (TH.DeclDoc n) = lookupThName n >>= lookupDeclDoc
|
|
| 1629 | - qGetDoc (TH.InstDoc t) = lookupThInstName t >>= lookupDeclDoc
|
|
| 1630 | - qGetDoc (TH.ArgDoc n i) = lookupThName n >>= lookupArgDoc i
|
|
| 1631 | - qGetDoc TH.ModuleDoc = do
|
|
| 1533 | +getDoc :: TH.DocLoc -> TcM (Maybe String)
|
|
| 1534 | +getDoc (TH.DeclDoc n) = lookupThName n >>= lookupDeclDoc
|
|
| 1535 | +getDoc (TH.InstDoc t) = lookupThInstName t >>= lookupDeclDoc
|
|
| 1536 | +getDoc (TH.ArgDoc n i) = lookupThName n >>= lookupArgDoc i
|
|
| 1537 | +getDoc TH.ModuleDoc = do
|
|
| 1632 | 1538 | df <- getDynFlags
|
| 1633 | 1539 | docs <- getGblEnv >>= extractDocs df
|
| 1634 | 1540 | return (renderHsDocString . hsDocString <$> (docs_mod_hdr =<< docs))
|
| 1635 | 1541 | |
| 1542 | +getQ :: forall a. Typeable a => TcM (Maybe a)
|
|
| 1543 | +getQ = do
|
|
| 1544 | + th_state_var <- fmap tcg_th_state getGblEnv
|
|
| 1545 | + th_state <- readTcRef th_state_var
|
|
| 1546 | + -- See #10596 for why we use a scoped type variable here.
|
|
| 1547 | + return (Map.lookup (typeRep (Proxy :: Proxy a)) th_state >>= fromDynamic)
|
|
| 1548 | + |
|
| 1549 | +location :: TcM TH.Loc
|
|
| 1550 | +location = do { m <- getModule
|
|
| 1551 | + ; l <- getSrcSpanM
|
|
| 1552 | + ; r <- case l of
|
|
| 1553 | + RealSrcSpan s _ -> return s
|
|
| 1554 | + GeneratedSrcSpan{} -> pprPanic "qLocation: generatedSrcSpan"
|
|
| 1555 | + (pprGeneratedSrcSpanDetails)
|
|
| 1556 | + UnhelpfulSpan _ -> pprPanic "qLocation: Unhelpful location"
|
|
| 1557 | + (ppr l)
|
|
| 1558 | + ; return (TH.Loc { TH.loc_filename = unpackFS (srcSpanFile r)
|
|
| 1559 | + , TH.loc_module = moduleNameString (moduleName m)
|
|
| 1560 | + , TH.loc_package = unitString (moduleUnit m)
|
|
| 1561 | + , TH.loc_start = (srcSpanStartLine r, srcSpanStartCol r)
|
|
| 1562 | + , TH.loc_end = (srcSpanEndLine r, srcSpanEndCol r) }) }
|
|
| 1563 | + |
|
| 1564 | +metaHandlersTcM :: (forall x. TcM x -> IO x) -> TH.MetaHandlers IO
|
|
| 1565 | +metaHandlersTcM runInIO = TH.MetaHandlers {
|
|
| 1566 | + mLiftIO = id
|
|
| 1567 | + -- We are careful to use the TcM instance not the one for IO, since that would lead to a different error.
|
|
| 1568 | + , mFail = \s -> runInIO $ fail @TcM s
|
|
| 1569 | + , mNewName = \s -> runInIO $ do { u <- newUnique
|
|
| 1570 | + ; let i = toInteger (getKey u)
|
|
| 1571 | + ; return (TH.mkNameU s i) }
|
|
| 1572 | + |
|
| 1573 | + , mReport = fmap runInIO . report
|
|
| 1574 | + |
|
| 1575 | + , mLocation = runInIO location
|
|
| 1576 | + |
|
| 1577 | + , mLookupName = fmap runInIO . lookupName
|
|
| 1578 | + , mReify = runInIO . reify
|
|
| 1579 | + , mReifyFixity = \nm -> runInIO $ lookupThName nm >>= reifyFixity
|
|
| 1580 | + , mReifyType = runInIO . reifyTypeOfThing
|
|
| 1581 | + , mReifyInstances = fmap runInIO . reifyInstances
|
|
| 1582 | + , mReifyRoles = runInIO . reifyRoles
|
|
| 1583 | + , mReifyAnnotations = runInIO . reifyAnnotations
|
|
| 1584 | + , mReifyModule = runInIO . reifyModule
|
|
| 1585 | + , mReifyConStrictness = \nm -> runInIO $ do
|
|
| 1586 | + { nm' <- lookupThName nm
|
|
| 1587 | + ; dc <- tcLookupDataCon nm'
|
|
| 1588 | + ; let bangs = dataConImplBangs dc
|
|
| 1589 | + ; return (map reifyDecidedStrictness bangs) }
|
|
| 1590 | + |
|
| 1591 | + -- For qRecover, discard error messages if
|
|
| 1592 | + -- the recovery action is chosen. Otherwise
|
|
| 1593 | + -- we'll only fail higher up.
|
|
| 1594 | + -- NB: extremely subtle!!! TODO: write up note
|
|
| 1595 | + -- tryTcDiscardingErrs manipulates the reader env so we need to be careful we don't sneak in the outside env
|
|
| 1596 | + , mRecover = \recover main -> runInIO $ tryTcDiscardingErrs (runQinTcM recover) (runQinTcM main)
|
|
| 1597 | + |
|
| 1598 | + , mGetPackageRoot = runInIO $ do
|
|
| 1599 | + dflags <- getDynFlags
|
|
| 1600 | + return $ fromMaybe "." (workingDirectory dflags)
|
|
| 1601 | + |
|
| 1602 | + , mAddDependentFile = \fp -> runInIO $ do
|
|
| 1603 | + ref <- fmap tcg_dependent_files getGblEnv
|
|
| 1604 | + dep_files <- readTcRef ref
|
|
| 1605 | + writeTcRef ref (fp:dep_files)
|
|
| 1606 | + |
|
| 1607 | + , mAddDependentDirectory = \dp -> runInIO $ do
|
|
| 1608 | + ref <- fmap tcg_dependent_dirs getGblEnv
|
|
| 1609 | + dep_dirs <- readTcRef ref
|
|
| 1610 | + writeTcRef ref (dp:dep_dirs)
|
|
| 1611 | + |
|
| 1612 | + , mAddTempFile = \suffix -> runInIO $ do
|
|
| 1613 | + dflags <- getDynFlags
|
|
| 1614 | + logger <- getLogger
|
|
| 1615 | + tmpfs <- hsc_tmpfs <$> getTopEnv
|
|
| 1616 | + liftIO $ newTempName logger tmpfs (tmpDir dflags) TFL_GhcSession suffix
|
|
| 1617 | + |
|
| 1618 | + , mAddTopDecls = runInIO . addTopDecls
|
|
| 1619 | + |
|
| 1620 | + , mAddForeignFilePath = \lang fp -> runInIO $ do
|
|
| 1621 | + var <- fmap tcg_th_foreign_files getGblEnv
|
|
| 1622 | + updTcRef var ((lang, fp) :)
|
|
| 1623 | + |
|
| 1624 | + , mAddModFinalizer = \fin -> runInIO $ do
|
|
| 1625 | + r <- liftIO $ mkRemoteRef fin
|
|
| 1626 | + fref <- liftIO $ mkForeignRef r (freeRemoteRef r)
|
|
| 1627 | + addModFinalizerRef fref
|
|
| 1628 | + |
|
| 1629 | + , mAddCorePlugin = \plugin -> runInIO $ do
|
|
| 1630 | + hsc_env <- getTopEnv
|
|
| 1631 | + let fc = hsc_FC hsc_env
|
|
| 1632 | + let home_unit = hsc_home_unit hsc_env
|
|
| 1633 | + let dflags = hsc_dflags hsc_env
|
|
| 1634 | + let fopts = initFinderOpts dflags
|
|
| 1635 | + r <- liftIO $ findHomeModule fc fopts home_unit (mkModuleName plugin)
|
|
| 1636 | + let err = TcRnTHError $ AddInvalidCorePlugin plugin
|
|
| 1637 | + case r of
|
|
| 1638 | + Found {} -> addErr err
|
|
| 1639 | + FoundMultiple {} -> addErr err
|
|
| 1640 | + _ -> return ()
|
|
| 1641 | + th_coreplugins_var <- tcg_th_coreplugins <$> getGblEnv
|
|
| 1642 | + updTcRef th_coreplugins_var (plugin:)
|
|
| 1643 | + |
|
| 1644 | + , mGetQ = runInIO getQ
|
|
| 1645 | + |
|
| 1646 | + , mPutQ = \x -> runInIO $ do
|
|
| 1647 | + th_state_var <- fmap tcg_th_state getGblEnv
|
|
| 1648 | + updTcRef th_state_var (\m -> Map.insert (typeOf x) (toDyn x) m)
|
|
| 1649 | + |
|
| 1650 | + , mIsExtEnabled = runInIO . xoptM
|
|
| 1651 | + |
|
| 1652 | + , mExtsEnabled = runInIO $
|
|
| 1653 | + EnumSet.toList . extensionFlags . hsc_dflags <$> getTopEnv
|
|
| 1654 | + |
|
| 1655 | + , mPutDoc = fmap runInIO . putDoc
|
|
| 1656 | + |
|
| 1657 | + , mGetDoc = runInIO . getDoc
|
|
| 1658 | + }
|
|
| 1659 | + |
|
| 1636 | 1660 | -- | Looks up documentation for a declaration in first the current module,
|
| 1637 | 1661 | -- otherwise tries to find it in another module via 'hscGetModuleInterface'.
|
| 1638 | 1662 | lookupDeclDoc :: Name -> TcM (Maybe String)
|
| ... | ... | @@ -1788,7 +1812,7 @@ runTH ty fhv = do |
| 1788 | 1812 | InternalInterp -> do
|
| 1789 | 1813 | -- Run it in the local TcM
|
| 1790 | 1814 | hv <- liftIO $ wormhole interp fhv
|
| 1791 | - r <- runQuasi (unsafeCoerce hv :: TH.Q a)
|
|
| 1815 | + r <- runQinTcM (unsafeCoerce hv :: TH.Q a)
|
|
| 1792 | 1816 | return r
|
| 1793 | 1817 | #endif
|
| 1794 | 1818 | |
| ... | ... | @@ -1797,7 +1821,7 @@ runTH ty fhv = do |
| 1797 | 1821 | -- Remote GHCi, see Note [Remote Template Haskell] in
|
| 1798 | 1822 | -- libraries/ghci/GHCi/TH.hs.
|
| 1799 | 1823 | rstate <- getTHState inst
|
| 1800 | - loc <- TH.qLocation
|
|
| 1824 | + loc <- location
|
|
| 1801 | 1825 | -- run a remote TH request
|
| 1802 | 1826 | r <- liftIO $
|
| 1803 | 1827 | withForeignRef rstate $ \state_hv ->
|
| ... | ... | @@ -1913,32 +1937,32 @@ wrapTHResult tcm = do |
| 1913 | 1937 | |
| 1914 | 1938 | handleTHMessage :: THMessage a -> TcM a
|
| 1915 | 1939 | handleTHMessage msg = case msg of
|
| 1916 | - NewName a -> wrapTHResult $ TH.qNewName a
|
|
| 1917 | - Report b str -> wrapTHResult $ TH.qReport b str
|
|
| 1918 | - LookupName b str -> wrapTHResult $ TH.qLookupName b str
|
|
| 1919 | - Reify n -> wrapTHResult $ TH.qReify n
|
|
| 1920 | - ReifyFixity n -> wrapTHResult $ TH.qReifyFixity n
|
|
| 1921 | - ReifyType n -> wrapTHResult $ TH.qReifyType n
|
|
| 1922 | - ReifyInstances n ts -> wrapTHResult $ TH.qReifyInstances n ts
|
|
| 1923 | - ReifyRoles n -> wrapTHResult $ TH.qReifyRoles n
|
|
| 1940 | + NewName a -> wrapTHResult $ runQinTcM $ TH.newName a
|
|
| 1941 | + Report b str -> wrapTHResult $ runQinTcM $ TH.report b str
|
|
| 1942 | + LookupName b str -> wrapTHResult $ runQinTcM $ TH.lookupName b str
|
|
| 1943 | + Reify n -> wrapTHResult $ runQinTcM $ TH.reify n
|
|
| 1944 | + ReifyFixity n -> wrapTHResult $ runQinTcM $ TH.reifyFixity n
|
|
| 1945 | + ReifyType n -> wrapTHResult $ runQinTcM $ TH.reifyType n
|
|
| 1946 | + ReifyInstances n ts -> wrapTHResult $ runQinTcM $ TH.reifyInstances n ts
|
|
| 1947 | + ReifyRoles n -> wrapTHResult $ runQinTcM $ TH.reifyRoles n
|
|
| 1924 | 1948 | ReifyAnnotations lookup tyrep ->
|
| 1925 | 1949 | wrapTHResult $ (map B.pack <$> getAnnotationsByTypeRep lookup tyrep)
|
| 1926 | - ReifyModule m -> wrapTHResult $ TH.qReifyModule m
|
|
| 1927 | - ReifyConStrictness nm -> wrapTHResult $ TH.qReifyConStrictness nm
|
|
| 1928 | - GetPackageRoot -> wrapTHResult $ TH.qGetPackageRoot
|
|
| 1929 | - AddDependentFile f -> wrapTHResult $ TH.qAddDependentFile f
|
|
| 1930 | - AddDependentDirectory d -> wrapTHResult $ TH.qAddDependentDirectory d
|
|
| 1931 | - AddTempFile s -> wrapTHResult $ TH.qAddTempFile s
|
|
| 1950 | + ReifyModule m -> wrapTHResult $ runQinTcM $ TH.reifyModule m
|
|
| 1951 | + ReifyConStrictness nm -> wrapTHResult $ runQinTcM $ TH.reifyConStrictness nm
|
|
| 1952 | + GetPackageRoot -> wrapTHResult $ runQinTcM $ TH.getPackageRoot
|
|
| 1953 | + AddDependentFile f -> wrapTHResult $ runQinTcM $ TH.addDependentFile f
|
|
| 1954 | + AddDependentDirectory d -> wrapTHResult $ runQinTcM $ TH.addDependentDirectory d
|
|
| 1955 | + AddTempFile s -> wrapTHResult $ runQinTcM $ TH.addTempFile s
|
|
| 1932 | 1956 | AddModFinalizer r -> do
|
| 1933 | 1957 | interp <- hscInterp <$> getTopEnv
|
| 1934 | 1958 | wrapTHResult $ liftIO (mkFinalizedHValue interp r) >>= addModFinalizerRef
|
| 1935 | - AddCorePlugin str -> wrapTHResult $ TH.qAddCorePlugin str
|
|
| 1936 | - AddTopDecls decs -> wrapTHResult $ TH.qAddTopDecls decs
|
|
| 1937 | - AddForeignFilePath lang str -> wrapTHResult $ TH.qAddForeignFilePath lang str
|
|
| 1938 | - IsExtEnabled ext -> wrapTHResult $ TH.qIsExtEnabled ext
|
|
| 1939 | - ExtsEnabled -> wrapTHResult $ TH.qExtsEnabled
|
|
| 1940 | - PutDoc l s -> wrapTHResult $ TH.qPutDoc l s
|
|
| 1941 | - GetDoc l -> wrapTHResult $ TH.qGetDoc l
|
|
| 1959 | + AddCorePlugin str -> wrapTHResult $ runQinTcM $ TH.addCorePlugin str
|
|
| 1960 | + AddTopDecls decs -> wrapTHResult $ runQinTcM $ TH.addTopDecls decs
|
|
| 1961 | + AddForeignFilePath lang str -> wrapTHResult $ runQinTcM $ TH.addForeignFilePath lang str
|
|
| 1962 | + IsExtEnabled ext -> wrapTHResult $ runQinTcM $ TH.isExtEnabled ext
|
|
| 1963 | + ExtsEnabled -> wrapTHResult $ runQinTcM $ TH.extsEnabled
|
|
| 1964 | + PutDoc l s -> wrapTHResult $ runQinTcM $ TH.putDoc l s
|
|
| 1965 | + GetDoc l -> wrapTHResult $ runQinTcM $ TH.getDoc l
|
|
| 1942 | 1966 | FailIfErrs -> wrapTHResult failIfErrsM
|
| 1943 | 1967 | _ -> panic ("handleTHMessage: unexpected message " ++ show msg)
|
| 1944 | 1968 |
| ... | ... | @@ -42,6 +42,6 @@ runMetaT :: LHsExpr GhcTc -> TcM (LHsType GhcPs) |
| 42 | 42 | runMetaD :: LHsExpr GhcTc -> TcM [LHsDecl GhcPs]
|
| 43 | 43 | |
| 44 | 44 | lookupThName_maybe :: TH.Name -> TcM (Maybe Name)
|
| 45 | -runQuasi :: TH.Q a -> TcM a
|
|
| 45 | +runQinTcM :: TH.Q a -> TcM a
|
|
| 46 | 46 | runRemoteModFinalizers :: ThModFinalizers -> TcM ()
|
| 47 | 47 | finishTH :: TcM () |
| ... | ... | @@ -1079,7 +1079,7 @@ withDecDoc :: String -> Q Dec -> Q Dec |
| 1079 | 1079 | withDecDoc doc dec = do
|
| 1080 | 1080 | dec' <- dec
|
| 1081 | 1081 | case doc_loc dec' of
|
| 1082 | - Just loc -> qAddModFinalizer $ qPutDoc loc doc
|
|
| 1082 | + Just loc -> addModFinalizer $ putDoc loc doc
|
|
| 1083 | 1083 | Nothing -> pure ()
|
| 1084 | 1084 | pure dec'
|
| 1085 | 1085 | where
|
| ... | ... | @@ -1128,7 +1128,7 @@ funD_doc :: Name -> [Q Clause] |
| 1128 | 1128 | -> [Maybe String] -- ^ Documentation to attach to arguments
|
| 1129 | 1129 | -> Q Dec
|
| 1130 | 1130 | funD_doc nm cs mfun_doc arg_docs = do
|
| 1131 | - qAddModFinalizer $ sequence_
|
|
| 1131 | + addModFinalizer $ sequence_
|
|
| 1132 | 1132 | [putDoc (ArgDoc nm i) s | (i, Just s) <- zip [0..] arg_docs]
|
| 1133 | 1133 | let dec = funD nm cs
|
| 1134 | 1134 | case mfun_doc of
|
| ... | ... | @@ -1145,7 +1145,7 @@ dataD_doc :: Q Cxt -> Name -> [Q (TyVarBndr BndrVis)] -> Maybe (Q Kind) |
| 1145 | 1145 | -- ^ Documentation to attach to the data declaration
|
| 1146 | 1146 | -> Q Dec
|
| 1147 | 1147 | dataD_doc ctxt tc tvs ksig cons_with_docs derivs mdoc = do
|
| 1148 | - qAddModFinalizer $ mapM_ docCons cons_with_docs
|
|
| 1148 | + addModFinalizer $ mapM_ docCons cons_with_docs
|
|
| 1149 | 1149 | let dec = dataD ctxt tc tvs ksig (map (\(con, _, _) -> con) cons_with_docs) derivs
|
| 1150 | 1150 | maybe dec (flip withDecDoc dec) mdoc
|
| 1151 | 1151 | |
| ... | ... | @@ -1159,7 +1159,7 @@ newtypeD_doc :: Q Cxt -> Name -> [Q (TyVarBndr BndrVis)] -> Maybe (Q Kind) |
| 1159 | 1159 | -- ^ Documentation to attach to the newtype declaration
|
| 1160 | 1160 | -> Q Dec
|
| 1161 | 1161 | newtypeD_doc ctxt tc tvs ksig con_with_docs@(con, _, _) derivs mdoc = do
|
| 1162 | - qAddModFinalizer $ docCons con_with_docs
|
|
| 1162 | + addModFinalizer $ docCons con_with_docs
|
|
| 1163 | 1163 | let dec = newtypeD ctxt tc tvs ksig con derivs
|
| 1164 | 1164 | maybe dec (flip withDecDoc dec) mdoc
|
| 1165 | 1165 | |
| ... | ... | @@ -1172,7 +1172,7 @@ typeDataD_doc :: Name -> [Q (TyVarBndr BndrVis)] -> Maybe (Q Kind) |
| 1172 | 1172 | -- ^ Documentation to attach to the data declaration
|
| 1173 | 1173 | -> Q Dec
|
| 1174 | 1174 | typeDataD_doc tc tvs ksig cons_with_docs mdoc = do
|
| 1175 | - qAddModFinalizer $ mapM_ docCons cons_with_docs
|
|
| 1175 | + addModFinalizer $ mapM_ docCons cons_with_docs
|
|
| 1176 | 1176 | let dec = typeDataD tc tvs ksig (map (\(con, _, _) -> con) cons_with_docs)
|
| 1177 | 1177 | maybe dec (flip withDecDoc dec) mdoc
|
| 1178 | 1178 | |
| ... | ... | @@ -1186,7 +1186,7 @@ dataInstD_doc :: Q Cxt -> (Maybe [Q (TyVarBndr ())]) -> Q Type -> Maybe (Q Kind) |
| 1186 | 1186 | -- ^ Documentation to attach to the instance declaration
|
| 1187 | 1187 | -> Q Dec
|
| 1188 | 1188 | dataInstD_doc ctxt mb_bndrs ty ksig cons_with_docs derivs mdoc = do
|
| 1189 | - qAddModFinalizer $ mapM_ docCons cons_with_docs
|
|
| 1189 | + addModFinalizer $ mapM_ docCons cons_with_docs
|
|
| 1190 | 1190 | let dec = dataInstD ctxt mb_bndrs ty ksig (map (\(con, _, _) -> con) cons_with_docs)
|
| 1191 | 1191 | derivs
|
| 1192 | 1192 | maybe dec (flip withDecDoc dec) mdoc
|
| ... | ... | @@ -1202,7 +1202,7 @@ newtypeInstD_doc :: Q Cxt -> (Maybe [Q (TyVarBndr ())]) -> Q Type |
| 1202 | 1202 | -- ^ Documentation to attach to the instance declaration
|
| 1203 | 1203 | -> Q Dec
|
| 1204 | 1204 | newtypeInstD_doc ctxt mb_bndrs ty ksig con_with_docs@(con, _, _) derivs mdoc = do
|
| 1205 | - qAddModFinalizer $ docCons con_with_docs
|
|
| 1205 | + addModFinalizer $ docCons con_with_docs
|
|
| 1206 | 1206 | let dec = newtypeInstD ctxt mb_bndrs ty ksig con derivs
|
| 1207 | 1207 | maybe dec (flip withDecDoc dec) mdoc
|
| 1208 | 1208 | |
| ... | ... | @@ -1212,7 +1212,7 @@ patSynD_doc :: Name -> Q PatSynArgs -> Q PatSynDir -> Q Pat |
| 1212 | 1212 | -> [Maybe String] -- ^ Documentation to attach to the pattern arguments
|
| 1213 | 1213 | -> Q Dec
|
| 1214 | 1214 | patSynD_doc name args dir pat mdoc arg_docs = do
|
| 1215 | - qAddModFinalizer $ sequence_
|
|
| 1215 | + addModFinalizer $ sequence_
|
|
| 1216 | 1216 | [putDoc (ArgDoc name i) s | (i, Just s) <- zip [0..] arg_docs]
|
| 1217 | 1217 | let dec = patSynD name args dir pat
|
| 1218 | 1218 | maybe dec (flip withDecDoc dec) mdoc
|
| ... | ... | @@ -35,7 +35,7 @@ import GHC.Types (TYPE, RuntimeRep(..)) |
| 35 | 35 | #else
|
| 36 | 36 | import GHC.Internal.Base (
|
| 37 | 37 | Applicative(..), Functor(..), Monad(..), Monoid(..), Semigroup(..), String,
|
| 38 | - flip, id, (.), (++),
|
|
| 38 | + flip, id, (.), (++), ($),
|
|
| 39 | 39 | )
|
| 40 | 40 | import GHC.Internal.Classes (not)
|
| 41 | 41 | import GHC.Internal.Data.Data hiding (Fixity(..))
|
| ... | ... | @@ -59,145 +59,137 @@ import GHC.Internal.ForeignSrcLang |
| 59 | 59 | import GHC.Internal.LanguageExtensions
|
| 60 | 60 | import GHC.Internal.TH.Syntax
|
| 61 | 61 | |
| 62 | ------------------------------------------------------
|
|
| 63 | ---
|
|
| 64 | --- The Quasi class
|
|
| 65 | ---
|
|
| 66 | ------------------------------------------------------
|
|
| 67 | - |
|
| 68 | -class (MonadIO m, MonadFail m) => Quasi m where
|
|
| 69 | - -- | Fresh names. See 'newName'.
|
|
| 70 | - qNewName :: String -> m Name
|
|
| 71 | - |
|
| 72 | - ------- Error reporting and recovery -------
|
|
| 73 | - -- | Report an error (True) or warning (False)
|
|
| 74 | - -- ...but carry on; use 'fail' to stop. See 'report'.
|
|
| 75 | - qReport :: Bool -> String -> m ()
|
|
| 76 | - |
|
| 77 | - -- | See 'recover'.
|
|
| 78 | - qRecover :: m a -- ^ the error handler
|
|
| 79 | - -> m a -- ^ action which may fail
|
|
| 80 | - -> m a -- ^ Recover from the monadic 'fail'
|
|
| 81 | - |
|
| 82 | - ------- Inspect the type-checker's environment -------
|
|
| 83 | - -- | True <=> type namespace, False <=> value namespace. See 'lookupName'.
|
|
| 84 | - qLookupName :: Bool -> String -> m (Maybe Name)
|
|
| 85 | - -- | See 'reify'.
|
|
| 86 | - qReify :: Name -> m Info
|
|
| 87 | - -- | See 'reifyFixity'.
|
|
| 88 | - qReifyFixity :: Name -> m (Maybe Fixity)
|
|
| 89 | - -- | See 'reifyType'.
|
|
| 90 | - qReifyType :: Name -> m Type
|
|
| 91 | - -- | Is (n tys) an instance? Returns list of matching instance Decs (with
|
|
| 92 | - -- empty sub-Decs) Works for classes and type functions. See 'reifyInstances'.
|
|
| 93 | - qReifyInstances :: Name -> [Type] -> m [Dec]
|
|
| 94 | - -- | See 'reifyRoles'.
|
|
| 95 | - qReifyRoles :: Name -> m [Role]
|
|
| 96 | - -- | See 'reifyAnnotations'.
|
|
| 97 | - qReifyAnnotations :: Data a => AnnLookup -> m [a]
|
|
| 98 | - -- | See 'reifyModule'.
|
|
| 99 | - qReifyModule :: Module -> m ModuleInfo
|
|
| 100 | - -- | See 'reifyConStrictness'.
|
|
| 101 | - qReifyConStrictness :: Name -> m [DecidedStrictness]
|
|
| 102 | - |
|
| 103 | - -- | See 'location'.
|
|
| 104 | - qLocation :: m Loc
|
|
| 105 | - |
|
| 106 | - -- | Input/output (dangerous). See 'runIO'.
|
|
| 107 | - qRunIO :: IO a -> m a
|
|
| 108 | - qRunIO = liftIO
|
|
| 109 | - -- | See 'getPackageRoot'.
|
|
| 110 | - qGetPackageRoot :: m FilePath
|
|
| 111 | - |
|
| 112 | - -- | See 'addDependentFile'.
|
|
| 113 | - qAddDependentFile :: FilePath -> m ()
|
|
| 114 | - |
|
| 115 | - -- | See 'addDependentDirectory'.
|
|
| 116 | - qAddDependentDirectory :: FilePath -> m ()
|
|
| 117 | - |
|
| 118 | - -- | See 'addTempFile'.
|
|
| 119 | - qAddTempFile :: String -> m FilePath
|
|
| 120 | - |
|
| 121 | - -- | See 'addTopDecls'.
|
|
| 122 | - qAddTopDecls :: [Dec] -> m ()
|
|
| 123 | - |
|
| 124 | - -- | See 'addForeignFilePath'.
|
|
| 125 | - qAddForeignFilePath :: ForeignSrcLang -> String -> m ()
|
|
| 126 | - |
|
| 127 | - -- | See 'addModFinalizer'.
|
|
| 128 | - qAddModFinalizer :: Q () -> m ()
|
|
| 129 | - |
|
| 130 | - -- | See 'addCorePlugin'.
|
|
| 131 | - qAddCorePlugin :: String -> m ()
|
|
| 132 | - |
|
| 133 | - -- | See 'getQ'.
|
|
| 134 | - qGetQ :: Typeable a => m (Maybe a)
|
|
| 135 | - |
|
| 136 | - -- | See 'putQ'.
|
|
| 137 | - qPutQ :: Typeable a => a -> m ()
|
|
| 138 | - |
|
| 139 | - -- | See 'isExtEnabled'.
|
|
| 140 | - qIsExtEnabled :: Extension -> m Bool
|
|
| 141 | - -- | See 'extsEnabled'.
|
|
| 142 | - qExtsEnabled :: m [Extension]
|
|
| 143 | - |
|
| 144 | - -- | See 'putDoc'.
|
|
| 145 | - qPutDoc :: DocLoc -> String -> m ()
|
|
| 146 | - -- | See 'getDoc'.
|
|
| 147 | - qGetDoc :: DocLoc -> m (Maybe String)
|
|
| 62 | +data MetaHandlers m = MetaHandlers {
|
|
| 63 | + mLiftIO :: forall a. IO a -> m a
|
|
| 64 | + , mFail :: forall a. String -> m a
|
|
| 65 | + -- | Fresh names. See 'newName'.
|
|
| 66 | + , mNewName :: String -> m Name
|
|
| 67 | + |
|
| 68 | + ------- Error reporting and recovery -------
|
|
| 69 | + -- | Report an error (True) or warning (False)
|
|
| 70 | + -- ...but carry on; use 'fail' to stop. See 'report'.
|
|
| 71 | + , mReport :: Bool -> String -> m ()
|
|
| 72 | + |
|
| 73 | + -- | See 'recover'.
|
|
| 74 | + , mRecover :: forall a. Q a -- ^ the error handler
|
|
| 75 | + -> Q a -- ^ action which may fail
|
|
| 76 | + -> m a -- ^ Recover from the monadic 'fail'
|
|
| 77 | + |
|
| 78 | + ------- Inspect the type-checker's environment -------
|
|
| 79 | + -- | True <=> type namespace, False <=> value namespace. See 'lookupName'.
|
|
| 80 | + , mLookupName :: Bool -> String -> m (Maybe Name)
|
|
| 81 | + -- | See 'reify'.
|
|
| 82 | + , mReify :: Name -> m Info
|
|
| 83 | + -- | See 'reifyFixity'.
|
|
| 84 | + , mReifyFixity :: Name -> m (Maybe Fixity)
|
|
| 85 | + -- | See 'reifyType'.
|
|
| 86 | + , mReifyType :: Name -> m Type
|
|
| 87 | + -- | Is (n tys) an instance? Returns list of matching instance Decs (with
|
|
| 88 | + -- empty sub-Decs) Works for classes and type functions. See 'reifyInstances'.
|
|
| 89 | + , mReifyInstances :: Name -> [Type] -> m [Dec]
|
|
| 90 | + -- | See 'reifyRoles'.
|
|
| 91 | + , mReifyRoles :: Name -> m [Role]
|
|
| 92 | + -- | See 'reifyAnnotations'.
|
|
| 93 | + , mReifyAnnotations :: forall a. Data a => AnnLookup -> m [a]
|
|
| 94 | + -- | See 'reifyModule'.
|
|
| 95 | + , mReifyModule :: Module -> m ModuleInfo
|
|
| 96 | + -- | See 'reifyConStrictness'.
|
|
| 97 | + , mReifyConStrictness :: Name -> m [DecidedStrictness]
|
|
| 98 | + |
|
| 99 | + -- | See 'location'.
|
|
| 100 | + , mLocation :: m Loc
|
|
| 101 | + |
|
| 102 | + -- | See 'getPackageRoot'.
|
|
| 103 | + , mGetPackageRoot :: m FilePath
|
|
| 104 | + |
|
| 105 | + -- | See 'addDependentFile'.
|
|
| 106 | + , mAddDependentFile :: FilePath -> m ()
|
|
| 107 | + |
|
| 108 | + -- | See 'addDependentDirectory'.
|
|
| 109 | + , mAddDependentDirectory :: FilePath -> m ()
|
|
| 110 | + |
|
| 111 | + -- | See 'addTempFile'.
|
|
| 112 | + , mAddTempFile :: String -> m FilePath
|
|
| 113 | + |
|
| 114 | + -- | See 'addTopDecls'.
|
|
| 115 | + , mAddTopDecls :: [Dec] -> m ()
|
|
| 116 | + |
|
| 117 | + -- | See 'addForeignFilePath'.
|
|
| 118 | + , mAddForeignFilePath :: ForeignSrcLang -> String -> m ()
|
|
| 119 | + |
|
| 120 | + -- | See 'addModFinalizer'.
|
|
| 121 | + , mAddModFinalizer :: Q () -> m ()
|
|
| 122 | + |
|
| 123 | + -- | See 'addCorePlugin'.
|
|
| 124 | + , mAddCorePlugin :: String -> m ()
|
|
| 125 | + |
|
| 126 | + -- | See 'getQ'.
|
|
| 127 | + , mGetQ :: forall a. Typeable a => m (Maybe a)
|
|
| 128 | + |
|
| 129 | + -- | See 'putQ'.
|
|
| 130 | + , mPutQ :: forall a. Typeable a => a -> m ()
|
|
| 131 | + |
|
| 132 | + -- | See 'isExtEnabled'.
|
|
| 133 | + , mIsExtEnabled :: Extension -> m Bool
|
|
| 134 | + -- | See 'extsEnabled'.
|
|
| 135 | + , mExtsEnabled :: m [Extension]
|
|
| 136 | + |
|
| 137 | + -- | See 'putDoc'.
|
|
| 138 | + , mPutDoc :: DocLoc -> String -> m ()
|
|
| 139 | + -- | See 'getDoc'.
|
|
| 140 | + , mGetDoc :: DocLoc -> m (Maybe String)
|
|
| 141 | + }
|
|
| 148 | 142 | |
| 149 | ------------------------------------------------------
|
|
| 150 | --- The IO instance of Quasi
|
|
| 151 | ------------------------------------------------------
|
|
| 143 | +badIO :: String -> IO a
|
|
| 144 | +badIO op = do { hPutStrLn stderr ("Can't do `" ++ op ++ "' in the IO monad")
|
|
| 145 | + ; fail "Template Haskell failure" }
|
|
| 152 | 146 | |
| 153 | --- | This instance is used only when running a Q
|
|
| 154 | --- computation in the IO monad, usually just to
|
|
| 155 | --- print the result. There is no interesting
|
|
| 156 | --- type environment, so reification isn't going to
|
|
| 157 | --- work.
|
|
| 158 | -instance Quasi IO where
|
|
| 159 | - qNewName = newNameIO
|
|
| 160 | - |
|
| 161 | - qReport True msg = hPutStrLn stderr ("Template Haskell error: " ++ msg)
|
|
| 162 | - qReport False msg = hPutStrLn stderr ("Template Haskell error: " ++ msg)
|
|
| 163 | - |
|
| 164 | - qLookupName _ _ = badIO "lookupName"
|
|
| 165 | - qReify _ = badIO "reify"
|
|
| 166 | - qReifyFixity _ = badIO "reifyFixity"
|
|
| 167 | - qReifyType _ = badIO "reifyFixity"
|
|
| 168 | - qReifyInstances _ _ = badIO "reifyInstances"
|
|
| 169 | - qReifyRoles _ = badIO "reifyRoles"
|
|
| 170 | - qReifyAnnotations _ = badIO "reifyAnnotations"
|
|
| 171 | - qReifyModule _ = badIO "reifyModule"
|
|
| 172 | - qReifyConStrictness _ = badIO "reifyConStrictness"
|
|
| 173 | - qLocation = badIO "currentLocation"
|
|
| 174 | - qRecover _ _ = badIO "recover" -- Maybe we could fix this?
|
|
| 175 | - qGetPackageRoot = badIO "getProjectRoot"
|
|
| 176 | - qAddDependentFile _ = badIO "addDependentFile"
|
|
| 177 | - qAddTempFile _ = badIO "addTempFile"
|
|
| 178 | - qAddTopDecls _ = badIO "addTopDecls"
|
|
| 179 | - qAddForeignFilePath _ _ = badIO "addForeignFilePath"
|
|
| 180 | - qAddModFinalizer _ = badIO "addModFinalizer"
|
|
| 181 | - qAddCorePlugin _ = badIO "addCorePlugin"
|
|
| 182 | - qGetQ = badIO "getQ"
|
|
| 183 | - qPutQ _ = badIO "putQ"
|
|
| 184 | - qIsExtEnabled _ = badIO "isExtEnabled"
|
|
| 185 | - qExtsEnabled = badIO "extsEnabled"
|
|
| 186 | - qPutDoc _ _ = badIO "putDoc"
|
|
| 187 | - qGetDoc _ = badIO "getDoc"
|
|
| 188 | - qAddDependentDirectory _ = badIO "AddDependentDirectory"
|
|
| 147 | +metaHandlersIO :: MetaHandlers IO
|
|
| 148 | +metaHandlersIO = MetaHandlers {
|
|
| 149 | + mLiftIO = id
|
|
| 150 | + , mFail = fail
|
|
| 151 | + , mNewName = newNameIO
|
|
| 152 | + , mReport = \b msg ->
|
|
| 153 | + if b then
|
|
| 154 | + hPutStrLn stderr ("Template Haskell error: " ++ msg)
|
|
| 155 | + else
|
|
| 156 | + hPutStrLn stderr ("Template Haskell error: " ++ msg) -- TODO: should this be different from above?
|
|
| 157 | + , mLookupName = \ _ _ -> badIO "lookupName"
|
|
| 158 | + , mReify = \_ -> badIO "reify"
|
|
| 159 | + , mReifyFixity = \_ -> badIO "reifyFixity"
|
|
| 160 | + , mReifyType = \_ -> badIO "reifyFixity"
|
|
| 161 | + , mReifyInstances = \_ _ -> badIO "reifyInstances"
|
|
| 162 | + , mReifyRoles = \_ -> badIO "reifyRoles"
|
|
| 163 | + , mReifyAnnotations = \_ -> badIO "reifyAnnotations"
|
|
| 164 | + , mReifyModule = \_ -> badIO "reifyModule"
|
|
| 165 | + , mReifyConStrictness = \_ -> badIO "reifyConStrictness"
|
|
| 166 | + , mLocation = badIO "currentLocation"
|
|
| 167 | + , mRecover = \_ _ -> badIO "recover" -- Maybe we could fix this?
|
|
| 168 | + , mGetPackageRoot = badIO "getProjectRoot"
|
|
| 169 | + , mAddDependentFile = \_ -> badIO "addDependentFile"
|
|
| 170 | + , mAddTempFile = \_ -> badIO "addTempFile"
|
|
| 171 | + , mAddTopDecls = \_ -> badIO "addTopDecls"
|
|
| 172 | + , mAddForeignFilePath = \_ _ -> badIO "addForeignFilePath"
|
|
| 173 | + , mAddModFinalizer = \_ -> badIO "addModFinalizer"
|
|
| 174 | + , mAddCorePlugin = \_ -> badIO "addCorePlugin"
|
|
| 175 | + , mGetQ = badIO "getQ"
|
|
| 176 | + , mPutQ = \_ -> badIO "putQ"
|
|
| 177 | + , mIsExtEnabled = \_ -> badIO "isExtEnabled"
|
|
| 178 | + , mExtsEnabled = badIO "extsEnabled"
|
|
| 179 | + , mPutDoc = \_ _ -> badIO "putDoc"
|
|
| 180 | + , mGetDoc = \_ -> badIO "getDoc"
|
|
| 181 | + , mAddDependentDirectory = \_ -> badIO "AddDependentDirectory"
|
|
| 182 | + }
|
|
| 189 | 183 | |
| 190 | 184 | instance Quote IO where
|
| 191 | 185 | newName = newNameIO
|
| 192 | 186 | |
| 187 | + |
|
| 188 | + |
|
| 193 | 189 | newNameIO :: String -> IO Name
|
| 194 | 190 | newNameIO s = do { n <- atomicModifyIORef' counter (\x -> (x + 1, x))
|
| 195 | 191 | ; pure (mkNameU s n) }
|
| 196 | 192 | |
| 197 | -badIO :: String -> IO a
|
|
| 198 | -badIO op = do { qReport True ("Can't do `" ++ op ++ "' in the IO monad")
|
|
| 199 | - ; fail "Template Haskell failure" }
|
|
| 200 | - |
|
| 201 | 193 | -- Global variable to generate unique symbols
|
| 202 | 194 | counter :: IORef Uniq
|
| 203 | 195 | {-# NOINLINE counter #-}
|
| ... | ... | @@ -220,36 +212,22 @@ counter = unsafePerformIO (newIORef 0) |
| 220 | 212 | -- inversion](https://en.wikipedia.org/wiki/Dependency_inversion_principle),
|
| 221 | 213 | -- providing an abstract interface for the user which is later concretely
|
| 222 | 214 | -- fufilled by an concrete 'Quasi' instance, internal to GHC.
|
| 223 | -newtype Q a = Q { unQ :: forall m. Quasi m => m a }
|
|
| 224 | - |
|
| 225 | --- | \"Runs\" the 'Q' monad. Normal users of Template Haskell
|
|
| 226 | --- should not need this function, as the splice brackets @$( ... )@
|
|
| 227 | --- are the usual way of running a 'Q' computation.
|
|
| 228 | ---
|
|
| 229 | --- This function is primarily used in GHC internals, and for debugging
|
|
| 230 | --- splices by running them in 'IO'.
|
|
| 231 | ---
|
|
| 232 | --- Note that many functions in 'Q', such as 'reify' and other compiler
|
|
| 233 | --- queries, are not supported when running 'Q' in 'IO'; these operations
|
|
| 234 | --- simply fail at runtime. Indeed, the only operations guaranteed to succeed
|
|
| 235 | --- are 'newName', 'runIO', 'reportError' and 'reportWarning'.
|
|
| 236 | -runQ :: Quasi m => Q a -> m a
|
|
| 237 | -runQ (Q m) = m
|
|
| 215 | +newtype Q a = Q { unQ :: MetaHandlers IO -> IO a }
|
|
| 238 | 216 | |
| 239 | 217 | instance Monad Q where
|
| 240 | - Q m >>= k = Q (m >>= \x -> unQ (k x))
|
|
| 218 | + Q m >>= k = Q $ \h -> (m h >>= \x -> unQ (k x) h)
|
|
| 241 | 219 | (>>) = (*>)
|
| 242 | 220 | |
| 243 | 221 | instance MonadFail Q where
|
| 244 | - fail s = report True s >> Q (fail "Q monad failure")
|
|
| 222 | + fail s = report True s >> Q (\h -> mFail h "Q monad failure")
|
|
| 245 | 223 | |
| 246 | 224 | instance Functor Q where
|
| 247 | - fmap f (Q x) = Q (fmap f x)
|
|
| 225 | + fmap f (Q x) = Q $ \h -> fmap f (x h)
|
|
| 248 | 226 | |
| 249 | 227 | instance Applicative Q where
|
| 250 | - pure x = Q (pure x)
|
|
| 251 | - Q f <*> Q x = Q (f <*> x)
|
|
| 252 | - Q m *> Q n = Q (m *> n)
|
|
| 228 | + pure x = Q $ \_ -> pure x
|
|
| 229 | + Q f <*> Q x = Q $ \h -> (f h <*> x h)
|
|
| 230 | + Q m *> Q n = Q $ \h -> (m h *> n h)
|
|
| 253 | 231 | |
| 254 | 232 | -- | @since 2.17.0.0
|
| 255 | 233 | instance Semigroup a => Semigroup (Q a) where
|
| ... | ... | @@ -319,7 +297,7 @@ class Monad m => Quote m where |
| 319 | 297 | newName :: String -> m Name
|
| 320 | 298 | |
| 321 | 299 | instance Quote Q where
|
| 322 | - newName s = Q (qNewName s)
|
|
| 300 | + newName s = Q $ \h -> mNewName h s
|
|
| 323 | 301 | |
| 324 | 302 | -----------------------------------------------------
|
| 325 | 303 | --
|
| ... | ... | @@ -517,7 +495,7 @@ joinCode = flip bindCode id |
| 517 | 495 | -- | Report an error (True) or warning (False),
|
| 518 | 496 | -- but carry on; use 'fail' to stop.
|
| 519 | 497 | report :: Bool -> String -> Q ()
|
| 520 | -report b s = Q (qReport b s)
|
|
| 498 | +report b s = Q $ \h -> mReport h b s
|
|
| 521 | 499 | {-# DEPRECATED report "Use reportError or reportWarning instead" #-} -- deprecated in 7.6
|
| 522 | 500 | |
| 523 | 501 | -- | Report an error to the user, but allow the current splice's computation to carry on. To abort the computation, use 'fail'.
|
| ... | ... | @@ -532,20 +510,20 @@ reportWarning = report False |
| 532 | 510 | recover :: Q a -- ^ handler to invoke on failure
|
| 533 | 511 | -> Q a -- ^ computation to run
|
| 534 | 512 | -> Q a
|
| 535 | -recover (Q r) (Q m) = Q (qRecover r m)
|
|
| 513 | +recover rec main = Q $ \h -> mRecover h rec main
|
|
| 536 | 514 | |
| 537 | 515 | -- We don't export lookupName; the Bool isn't a great API
|
| 538 | 516 | -- Instead we export lookupTypeName, lookupValueName
|
| 539 | 517 | lookupName :: Bool -> String -> Q (Maybe Name)
|
| 540 | -lookupName ns s = Q (qLookupName ns s)
|
|
| 518 | +lookupName ns s = Q $ \h -> mLookupName h ns s
|
|
| 541 | 519 | |
| 542 | 520 | -- | Look up the given name in the (type namespace of the) current splice's scope. See "Language.Haskell.TH.Syntax#namelookup" for more details.
|
| 543 | 521 | lookupTypeName :: String -> Q (Maybe Name)
|
| 544 | -lookupTypeName s = Q (qLookupName True s)
|
|
| 522 | +lookupTypeName s = Q $ \h -> mLookupName h True s
|
|
| 545 | 523 | |
| 546 | 524 | -- | Look up the given name in the (value namespace of the) current splice's scope. See "Language.Haskell.TH.Syntax#namelookup" for more details.
|
| 547 | 525 | lookupValueName :: String -> Q (Maybe Name)
|
| 548 | -lookupValueName s = Q (qLookupName False s)
|
|
| 526 | +lookupValueName s = Q $ \h -> mLookupName h False s
|
|
| 549 | 527 | |
| 550 | 528 | {-
|
| 551 | 529 | Note [Name lookup]
|
| ... | ... | @@ -620,7 +598,7 @@ To ensure we get information about @D@-the-value, use 'lookupValueName': |
| 620 | 598 | and to get information about @D@-the-type, use 'lookupTypeName'.
|
| 621 | 599 | -}
|
| 622 | 600 | reify :: Name -> Q Info
|
| 623 | -reify v = Q (qReify v)
|
|
| 601 | +reify v = Q $ \h -> mReify h v
|
|
| 624 | 602 | |
| 625 | 603 | {- | @reifyFixity nm@ attempts to find a fixity declaration for @nm@. For
|
| 626 | 604 | example, if the function @foo@ has the fixity declaration @infixr 7 foo@, then
|
| ... | ... | @@ -629,7 +607,7 @@ example, if the function @foo@ has the fixity declaration @infixr 7 foo@, then |
| 629 | 607 | 'Nothing', so you may assume @bar@ has 'defaultFixity'.
|
| 630 | 608 | -}
|
| 631 | 609 | reifyFixity :: Name -> Q (Maybe Fixity)
|
| 632 | -reifyFixity nm = Q (qReifyFixity nm)
|
|
| 610 | +reifyFixity nm = Q $ \h -> mReifyFixity h nm
|
|
| 633 | 611 | |
| 634 | 612 | {- | @reifyType nm@ attempts to find the type or kind of @nm@. For example,
|
| 635 | 613 | @reifyType 'not@ returns @Bool -> Bool@, and
|
| ... | ... | @@ -637,7 +615,7 @@ reifyFixity nm = Q (qReifyFixity nm) |
| 637 | 615 | This works even if there's no explicit signature and the type or kind is inferred.
|
| 638 | 616 | -}
|
| 639 | 617 | reifyType :: Name -> Q Type
|
| 640 | -reifyType nm = Q (qReifyType nm)
|
|
| 618 | +reifyType nm = Q $ \h -> mReifyType h nm
|
|
| 641 | 619 | |
| 642 | 620 | {- | Template Haskell is capable of reifying information about types and
|
| 643 | 621 | terms defined in previous declaration groups. Top-level declaration splices break up
|
| ... | ... | @@ -729,7 +707,7 @@ has some discussion around this. |
| 729 | 707 | |
| 730 | 708 | -}
|
| 731 | 709 | reifyInstances :: Name -> [Type] -> Q [InstanceDec]
|
| 732 | -reifyInstances cls tys = Q (qReifyInstances cls tys)
|
|
| 710 | +reifyInstances cls tys = Q $ \h -> mReifyInstances h cls tys
|
|
| 733 | 711 | |
| 734 | 712 | {- | @reifyRoles nm@ returns the list of roles associated with the parameters
|
| 735 | 713 | (both visible and invisible) of
|
| ... | ... | @@ -748,20 +726,20 @@ and @reifyRoles Proxy@, we will get @['NominalR', 'PhantomR']@. The 'NominalR' i |
| 748 | 726 | the role of the invisible @k@ parameter. Kind parameters are always nominal.
|
| 749 | 727 | -}
|
| 750 | 728 | reifyRoles :: Name -> Q [Role]
|
| 751 | -reifyRoles nm = Q (qReifyRoles nm)
|
|
| 729 | +reifyRoles nm = Q $ \h -> mReifyRoles h nm
|
|
| 752 | 730 | |
| 753 | 731 | -- | @reifyAnnotations target@ returns the list of annotations
|
| 754 | 732 | -- associated with @target@. Only the annotations that are
|
| 755 | 733 | -- appropriately typed is returned. So if you have @Int@ and @String@
|
| 756 | 734 | -- annotations for the same target, you have to call this function twice.
|
| 757 | 735 | reifyAnnotations :: Data a => AnnLookup -> Q [a]
|
| 758 | -reifyAnnotations an = Q (qReifyAnnotations an)
|
|
| 736 | +reifyAnnotations an = Q $ \h -> mReifyAnnotations h an
|
|
| 759 | 737 | |
| 760 | 738 | -- | @reifyModule mod@ looks up information about module @mod@. To
|
| 761 | 739 | -- look up the current module, call this function with the return
|
| 762 | 740 | -- value of 'Language.Haskell.TH.Lib.thisModule'.
|
| 763 | 741 | reifyModule :: Module -> Q ModuleInfo
|
| 764 | -reifyModule m = Q (qReifyModule m)
|
|
| 742 | +reifyModule m = Q $ \h -> mReifyModule h m
|
|
| 765 | 743 | |
| 766 | 744 | -- | @reifyConStrictness nm@ looks up the strictness information for the fields
|
| 767 | 745 | -- of the constructor with the name @nm@. Note that the strictness information
|
| ... | ... | @@ -776,7 +754,7 @@ reifyModule m = Q (qReifyModule m) |
| 776 | 754 | -- circumstances, but it would return @['DecidedStrict', DecidedStrict]@ if the
|
| 777 | 755 | -- @-XStrictData@ language extension was enabled.
|
| 778 | 756 | reifyConStrictness :: Name -> Q [DecidedStrictness]
|
| 779 | -reifyConStrictness n = Q (qReifyConStrictness n)
|
|
| 757 | +reifyConStrictness n = Q $ \h -> mReifyConStrictness h n
|
|
| 780 | 758 | |
| 781 | 759 | -- | Is the list of instances returned by 'reifyInstances' nonempty?
|
| 782 | 760 | --
|
| ... | ... | @@ -789,7 +767,7 @@ isInstance nm tys = do { decs <- reifyInstances nm tys |
| 789 | 767 | |
| 790 | 768 | -- | The location at which this computation is spliced.
|
| 791 | 769 | location :: Q Loc
|
| 792 | -location = Q qLocation
|
|
| 770 | +location = Q mLocation
|
|
| 793 | 771 | |
| 794 | 772 | -- |The 'runIO' function lets you run an I\/O computation in the 'Q' monad.
|
| 795 | 773 | -- Take care: you are guaranteed the ordering of calls to 'runIO' within
|
| ... | ... | @@ -799,7 +777,7 @@ location = Q qLocation |
| 799 | 777 | -- necessarily flushed when the compiler finishes running, so you should
|
| 800 | 778 | -- flush them yourself.
|
| 801 | 779 | runIO :: IO a -> Q a
|
| 802 | -runIO m = Q (qRunIO m)
|
|
| 780 | +runIO m = Q $ \h -> mLiftIO h m
|
|
| 803 | 781 | |
| 804 | 782 | -- | Get the package root for the current package which is being compiled.
|
| 805 | 783 | -- This can be set explicitly with the -package-root flag but is normally
|
| ... | ... | @@ -811,7 +789,7 @@ runIO m = Q (qRunIO m) |
| 811 | 789 | -- change directory when compiling files but instead set the -package-root flag
|
| 812 | 790 | -- appropriately.
|
| 813 | 791 | getPackageRoot :: Q FilePath
|
| 814 | -getPackageRoot = Q qGetPackageRoot
|
|
| 792 | +getPackageRoot = Q mGetPackageRoot
|
|
| 815 | 793 | |
| 816 | 794 | -- | Record external directories that runIO is using (dependent upon).
|
| 817 | 795 | -- The compiler can then recognize that it should re-compile the Haskell file
|
| ... | ... | @@ -830,7 +808,7 @@ getPackageRoot = Q qGetPackageRoot |
| 830 | 808 | -- * The state of the directory is read at the interface generation time,
|
| 831 | 809 | -- not at the time of the function call.
|
| 832 | 810 | addDependentDirectory :: FilePath -> Q ()
|
| 833 | -addDependentDirectory dp = Q (qAddDependentDirectory dp)
|
|
| 811 | +addDependentDirectory dp = Q $ \h -> mAddDependentDirectory h dp
|
|
| 834 | 812 | |
| 835 | 813 | -- | Record external files that runIO is using (dependent upon).
|
| 836 | 814 | -- The compiler can then recognize that it should re-compile the Haskell file
|
| ... | ... | @@ -844,17 +822,17 @@ addDependentDirectory dp = Q (qAddDependentDirectory dp) |
| 844 | 822 | --
|
| 845 | 823 | -- * The dependency is based on file content, not a modification time
|
| 846 | 824 | addDependentFile :: FilePath -> Q ()
|
| 847 | -addDependentFile fp = Q (qAddDependentFile fp)
|
|
| 825 | +addDependentFile fp = Q $ \h -> mAddDependentFile h fp
|
|
| 848 | 826 | |
| 849 | 827 | -- | Obtain a temporary file path with the given suffix. The compiler will
|
| 850 | 828 | -- delete this file after compilation.
|
| 851 | 829 | addTempFile :: String -> Q FilePath
|
| 852 | -addTempFile suffix = Q (qAddTempFile suffix)
|
|
| 830 | +addTempFile suffix = Q $ \h -> mAddTempFile h suffix
|
|
| 853 | 831 | |
| 854 | 832 | -- | Add additional top-level declarations. The added declarations will be type
|
| 855 | 833 | -- checked along with the current declaration group.
|
| 856 | 834 | addTopDecls :: [Dec] -> Q ()
|
| 857 | -addTopDecls ds = Q (qAddTopDecls ds)
|
|
| 835 | +addTopDecls ds = Q $ \h -> mAddTopDecls h ds
|
|
| 858 | 836 | |
| 859 | 837 | -- | Same as 'addForeignSource', but expects to receive a path pointing to the
|
| 860 | 838 | -- foreign file instead of a 'String' of its contents. Consider using this in
|
| ... | ... | @@ -863,7 +841,7 @@ addTopDecls ds = Q (qAddTopDecls ds) |
| 863 | 841 | -- This is a good alternative to 'addForeignSource' when you are trying to
|
| 864 | 842 | -- directly link in an object file.
|
| 865 | 843 | addForeignFilePath :: ForeignSrcLang -> FilePath -> Q ()
|
| 866 | -addForeignFilePath lang fp = Q (qAddForeignFilePath lang fp)
|
|
| 844 | +addForeignFilePath lang fp = Q $ \h -> mAddForeignFilePath h lang fp
|
|
| 867 | 845 | |
| 868 | 846 | -- | Add a finalizer that will run in the Q monad after the current module has
|
| 869 | 847 | -- been type checked. This only makes sense when run within a top-level splice.
|
| ... | ... | @@ -872,7 +850,7 @@ addForeignFilePath lang fp = Q (qAddForeignFilePath lang fp) |
| 872 | 850 | -- 'reify' is able to find the local definitions when executed inside the
|
| 873 | 851 | -- finalizer.
|
| 874 | 852 | addModFinalizer :: Q () -> Q ()
|
| 875 | -addModFinalizer act = Q (qAddModFinalizer (unQ act))
|
|
| 853 | +addModFinalizer act = Q $ \h -> mAddModFinalizer h act
|
|
| 876 | 854 | |
| 877 | 855 | -- | Adds a core plugin to the compilation pipeline.
|
| 878 | 856 | --
|
| ... | ... | @@ -882,7 +860,7 @@ addModFinalizer act = Q (qAddModFinalizer (unQ act)) |
| 882 | 860 | -- to tell the compiler that we needed to compile first a plugin module in the
|
| 883 | 861 | -- current package.
|
| 884 | 862 | addCorePlugin :: String -> Q ()
|
| 885 | -addCorePlugin plugin = Q (qAddCorePlugin plugin)
|
|
| 863 | +addCorePlugin plugin = Q $ \h -> mAddCorePlugin h plugin
|
|
| 886 | 864 | |
| 887 | 865 | -- | Get state from the 'Q' monad. The state maintained by 'Q' is isomorphic to
|
| 888 | 866 | -- a type-indexed finite map. That is,
|
| ... | ... | @@ -896,20 +874,20 @@ addCorePlugin plugin = Q (qAddCorePlugin plugin) |
| 896 | 874 | -- Note that the state is local to the Haskell module in which the Template
|
| 897 | 875 | -- Haskell expression is executed.
|
| 898 | 876 | getQ :: Typeable a => Q (Maybe a)
|
| 899 | -getQ = Q qGetQ
|
|
| 877 | +getQ = Q mGetQ
|
|
| 900 | 878 | |
| 901 | 879 | -- | Replace the state in the 'Q' monad. Note that the state is local to the
|
| 902 | 880 | -- Haskell module in which the Template Haskell expression is executed.
|
| 903 | 881 | putQ :: Typeable a => a -> Q ()
|
| 904 | -putQ x = Q (qPutQ x)
|
|
| 882 | +putQ x = Q $ \h -> mPutQ h x
|
|
| 905 | 883 | |
| 906 | 884 | -- | Determine whether the given language extension is enabled in the 'Q' monad.
|
| 907 | 885 | isExtEnabled :: Extension -> Q Bool
|
| 908 | -isExtEnabled ext = Q (qIsExtEnabled ext)
|
|
| 886 | +isExtEnabled ext = Q $ \h -> mIsExtEnabled h ext
|
|
| 909 | 887 | |
| 910 | 888 | -- | List all enabled language extensions.
|
| 911 | 889 | extsEnabled :: Q [Extension]
|
| 912 | -extsEnabled = Q qExtsEnabled
|
|
| 890 | +extsEnabled = Q mExtsEnabled
|
|
| 913 | 891 | |
| 914 | 892 | -- | Add Haddock documentation to the specified location. This will overwrite
|
| 915 | 893 | -- any documentation at the location if it already exists. This will reify the
|
| ... | ... | @@ -928,48 +906,18 @@ extsEnabled = Q qExtsEnabled |
| 928 | 906 | -- Adding documentation to anything outside of the current module will cause an
|
| 929 | 907 | -- error.
|
| 930 | 908 | putDoc :: DocLoc -> String -> Q ()
|
| 931 | -putDoc t s = Q (qPutDoc t s)
|
|
| 909 | +putDoc t s = Q $ \h -> mPutDoc h t s
|
|
| 932 | 910 | |
| 933 | 911 | -- | Retrieves the Haddock documentation at the specified location, if one
|
| 934 | 912 | -- exists.
|
| 935 | 913 | -- It can be used to read documentation on things defined outside of the current
|
| 936 | 914 | -- module, provided that those modules were compiled with the @-haddock@ flag.
|
| 937 | 915 | getDoc :: DocLoc -> Q (Maybe String)
|
| 938 | -getDoc n = Q (qGetDoc n)
|
|
| 916 | +getDoc n = Q $ \h -> mGetDoc h n
|
|
| 939 | 917 | |
| 940 | 918 | instance MonadIO Q where
|
| 941 | 919 | liftIO = runIO
|
| 942 | 920 | |
| 943 | -instance Quasi Q where
|
|
| 944 | - qNewName = newName
|
|
| 945 | - qReport = report
|
|
| 946 | - qRecover = recover
|
|
| 947 | - qReify = reify
|
|
| 948 | - qReifyFixity = reifyFixity
|
|
| 949 | - qReifyType = reifyType
|
|
| 950 | - qReifyInstances = reifyInstances
|
|
| 951 | - qReifyRoles = reifyRoles
|
|
| 952 | - qReifyAnnotations = reifyAnnotations
|
|
| 953 | - qReifyModule = reifyModule
|
|
| 954 | - qReifyConStrictness = reifyConStrictness
|
|
| 955 | - qLookupName = lookupName
|
|
| 956 | - qLocation = location
|
|
| 957 | - qGetPackageRoot = getPackageRoot
|
|
| 958 | - qAddDependentFile = addDependentFile
|
|
| 959 | - qAddDependentDirectory = addDependentDirectory
|
|
| 960 | - qAddTempFile = addTempFile
|
|
| 961 | - qAddTopDecls = addTopDecls
|
|
| 962 | - qAddForeignFilePath = addForeignFilePath
|
|
| 963 | - qAddModFinalizer = addModFinalizer
|
|
| 964 | - qAddCorePlugin = addCorePlugin
|
|
| 965 | - qGetQ = getQ
|
|
| 966 | - qPutQ = putQ
|
|
| 967 | - qIsExtEnabled = isExtEnabled
|
|
| 968 | - qExtsEnabled = extsEnabled
|
|
| 969 | - qPutDoc = putDoc
|
|
| 970 | - qGetDoc = getDoc
|
|
| 971 | - |
|
| 972 | - |
|
| 973 | 921 | ----------------------------------------------------
|
| 974 | 922 | -- The following operations are used solely in GHC.HsToCore.Quote when
|
| 975 | 923 | -- desugaring brackets. They are not necessary for the user, who can use
|
| 1 | 1 | {-# LANGUAGE ScopedTypeVariables, StandaloneDeriving, DeriveGeneric,
|
| 2 | - TupleSections, RecordWildCards, InstanceSigs, CPP #-}
|
|
| 2 | + TupleSections, RecordWildCards, InstanceSigs, CPP, RankNTypes #-}
|
|
| 3 | 3 | {-# OPTIONS_GHC -fno-warn-name-shadowing #-}
|
| 4 | 4 | |
| 5 | 5 | -- |
|
| ... | ... | @@ -164,58 +164,70 @@ ghcCmd m = GHCiQ $ \sRef -> do |
| 164 | 164 | instance MonadIO GHCiQ where
|
| 165 | 165 | liftIO m = GHCiQ $ \_ -> m
|
| 166 | 166 | |
| 167 | -instance TH.Quasi GHCiQ where
|
|
| 168 | - qNewName str = ghcCmd (NewName str)
|
|
| 169 | - qReport isError msg = ghcCmd (Report isError msg)
|
|
| 170 | - |
|
| 171 | - -- See Note [TH recover with -fexternal-interpreter] in GHC.Tc.Gen.Splice
|
|
| 172 | - qRecover (GHCiQ h) a = GHCiQ $ \sRef -> mask $ \unmask -> do
|
|
| 173 | - s <- readIORef sRef
|
|
| 174 | - remoteTHCall (qsPipe s) StartRecover
|
|
| 175 | - e <- try $ unmask $ runGHCiQ (a <* ghcCmd FailIfErrs) sRef
|
|
| 176 | - remoteTHCall (qsPipe s) (EndRecover (isLeft e))
|
|
| 177 | - case e of
|
|
| 178 | - Left GHCiQException{} -> h sRef
|
|
| 179 | - Right r -> return r
|
|
| 180 | - qLookupName isType occ = ghcCmd (LookupName isType occ)
|
|
| 181 | - qReify name = ghcCmd (Reify name)
|
|
| 182 | - qReifyFixity name = ghcCmd (ReifyFixity name)
|
|
| 183 | - qReifyType name = ghcCmd (ReifyType name)
|
|
| 184 | - qReifyInstances name tys = ghcCmd (ReifyInstances name tys)
|
|
| 185 | - qReifyRoles name = ghcCmd (ReifyRoles name)
|
|
| 186 | - |
|
| 187 | 167 | -- To reify annotations, we send GHC the AnnLookup and also the
|
| 188 | 168 | -- TypeRep of the thing we're looking for, to avoid needing to
|
| 189 | 169 | -- serialize irrelevant annotations.
|
| 190 | - qReifyAnnotations :: forall a . Data a => TH.AnnLookup -> GHCiQ [a]
|
|
| 191 | - qReifyAnnotations lookup =
|
|
| 170 | +reifyAnnotations :: forall a . Data a => TH.AnnLookup -> GHCiQ [a]
|
|
| 171 | +reifyAnnotations lookup =
|
|
| 192 | 172 | map (deserializeWithData . B.unpack) <$>
|
| 193 | 173 | ghcCmd (ReifyAnnotations lookup typerep)
|
| 194 | 174 | where typerep = typeOf (undefined :: a)
|
| 195 | 175 | |
| 196 | - qReifyModule m = ghcCmd (ReifyModule m)
|
|
| 197 | - qReifyConStrictness name = ghcCmd (ReifyConStrictness name)
|
|
| 198 | - qLocation = fromMaybe noLoc . qsLocation <$> getState
|
|
| 199 | - qGetPackageRoot = ghcCmd GetPackageRoot
|
|
| 200 | - qAddDependentFile file = ghcCmd (AddDependentFile file)
|
|
| 201 | - qAddDependentDirectory dir = ghcCmd (AddDependentDirectory dir)
|
|
| 202 | - qAddTempFile suffix = ghcCmd (AddTempFile suffix)
|
|
| 203 | - qAddTopDecls decls = ghcCmd (AddTopDecls decls)
|
|
| 204 | - qAddForeignFilePath lang fp = ghcCmd (AddForeignFilePath lang fp)
|
|
| 205 | - qAddModFinalizer fin = GHCiQ (\_ -> mkRemoteRef fin) >>=
|
|
| 176 | +runQinGHCiQ :: TH.Q a -> GHCiQ a
|
|
| 177 | +runQinGHCiQ (TH.Q m) = GHCiQ $ \sRef -> m (metaHandlersGHCiQ (runInIO sRef))
|
|
| 178 | + where
|
|
| 179 | + runInIO :: IORef QState -> GHCiQ a -> IO a
|
|
| 180 | + runInIO sRef (GHCiQ m) = m sRef
|
|
| 181 | + |
|
| 182 | +metaHandlersGHCiQ :: (forall x. GHCiQ x -> IO x) -> TH.MetaHandlers IO
|
|
| 183 | +metaHandlersGHCiQ runInIO = TH.MetaHandlers {
|
|
| 184 | + mLiftIO = id
|
|
| 185 | + , mFail = runInIO . fail
|
|
| 186 | + , mNewName = \str -> runInIO $ ghcCmd (NewName str)
|
|
| 187 | + , mReport = \isError msg -> runInIO $ ghcCmd (Report isError msg)
|
|
| 188 | + |
|
| 189 | + -- See Note [TH recover with -fexternal-interpreter] in GHC.Tc.Gen.Splice
|
|
| 190 | + , mRecover = \h a -> runInIO $ GHCiQ $ \sRef -> mask $ \unmask -> do
|
|
| 191 | + s <- readIORef sRef
|
|
| 192 | + remoteTHCall (qsPipe s) StartRecover
|
|
| 193 | + e <- try $ unmask $ runGHCiQ (runQinGHCiQ a <* ghcCmd FailIfErrs) sRef
|
|
| 194 | + remoteTHCall (qsPipe s) (EndRecover (isLeft e))
|
|
| 195 | + case e of
|
|
| 196 | + Left GHCiQException{} ->
|
|
| 197 | + runGHCiQ (runQinGHCiQ h) sRef
|
|
| 198 | + Right r -> return r
|
|
| 199 | + , mLookupName = \isType occ -> runInIO $ ghcCmd (LookupName isType occ)
|
|
| 200 | + , mReify = \name ->runInIO $ ghcCmd (Reify name)
|
|
| 201 | + , mReifyFixity = \name ->runInIO $ ghcCmd (ReifyFixity name)
|
|
| 202 | + , mReifyType = \name -> runInIO $ ghcCmd (ReifyType name)
|
|
| 203 | + , mReifyInstances = \name tys -> runInIO $ ghcCmd (ReifyInstances name tys)
|
|
| 204 | + , mReifyRoles = \name -> runInIO $ ghcCmd (ReifyRoles name)
|
|
| 205 | + |
|
| 206 | + , mReifyAnnotations = runInIO . reifyAnnotations
|
|
| 207 | + , mReifyModule = \m -> runInIO $ ghcCmd (ReifyModule m)
|
|
| 208 | + , mReifyConStrictness = \name -> runInIO $ ghcCmd (ReifyConStrictness name)
|
|
| 209 | + , mLocation = runInIO $ fromMaybe noLoc . qsLocation <$> getState
|
|
| 210 | + , mGetPackageRoot = runInIO $ ghcCmd GetPackageRoot
|
|
| 211 | + , mAddDependentFile = \file -> runInIO $ ghcCmd (AddDependentFile file)
|
|
| 212 | + , mAddDependentDirectory = \dir -> runInIO $ ghcCmd (AddDependentDirectory dir)
|
|
| 213 | + , mAddTempFile = \suffix -> runInIO $ ghcCmd (AddTempFile suffix)
|
|
| 214 | + , mAddTopDecls = \decls -> runInIO $ ghcCmd (AddTopDecls decls)
|
|
| 215 | + , mAddForeignFilePath = \lang fp -> runInIO $ ghcCmd (AddForeignFilePath lang fp)
|
|
| 216 | + , mAddModFinalizer = \fin -> runInIO $ GHCiQ (\_ -> mkRemoteRef fin) >>=
|
|
| 206 | 217 | ghcCmd . AddModFinalizer
|
| 207 | - qAddCorePlugin str = ghcCmd (AddCorePlugin str)
|
|
| 208 | - qGetQ = do
|
|
| 218 | + , mAddCorePlugin = \str -> runInIO $ ghcCmd (AddCorePlugin str)
|
|
| 219 | + , mGetQ = runInIO $ do
|
|
| 209 | 220 | s <- getState
|
| 210 | 221 | let lookup :: forall a. Typeable a => Map TypeRep Dynamic -> Maybe a
|
| 211 | 222 | lookup m = fromDynamic =<< M.lookup (typeOf (undefined::a)) m
|
| 212 | 223 | return $ lookup (qsMap s)
|
| 213 | - qPutQ k = GHCiQ $ \sRef ->
|
|
| 214 | - modifyIORef' sRef (\s -> s { qsMap = M.insert (typeOf k) (toDyn k) (qsMap s) })
|
|
| 215 | - qIsExtEnabled x = ghcCmd (IsExtEnabled x)
|
|
| 216 | - qExtsEnabled = ghcCmd ExtsEnabled
|
|
| 217 | - qPutDoc l s = ghcCmd (PutDoc l s)
|
|
| 218 | - qGetDoc l = ghcCmd (GetDoc l)
|
|
| 224 | + , mPutQ = \k -> runInIO $ GHCiQ $ \sRef ->
|
|
| 225 | + modifyIORef' sRef (\s -> s { qsMap = M.insert (typeOf k) (toDyn k) (qsMap s) })
|
|
| 226 | + , mIsExtEnabled = \x -> runInIO $ ghcCmd (IsExtEnabled x)
|
|
| 227 | + , mExtsEnabled = runInIO $ ghcCmd ExtsEnabled
|
|
| 228 | + , mPutDoc = \l s -> runInIO $ ghcCmd (PutDoc l s)
|
|
| 229 | + , mGetDoc = \l -> runInIO $ ghcCmd (GetDoc l)
|
|
| 230 | +}
|
|
| 219 | 231 | |
| 220 | 232 | -- | The implementation of the 'StartTH' message: create
|
| 221 | 233 | -- a new IORef QState, and return a RemoteRef to it.
|
| ... | ... | @@ -235,7 +247,7 @@ runModFinalizerRefs pipe rstate qrefs = do |
| 235 | 247 | qstateref <- localRef rstate
|
| 236 | 248 | qstate <- readIORef qstateref
|
| 237 | 249 | qstate' <- newIORef $ qstate { qsPipe = pipe }
|
| 238 | - _ <- runGHCiQ (TH.runQ $ sequence_ qs) qstate'
|
|
| 250 | + _ <- runGHCiQ (runQinGHCiQ $ sequence_ qs) qstate'
|
|
| 239 | 251 | return ()
|
| 240 | 252 | |
| 241 | 253 | -- | The implementation of the 'RunTH' message
|
| ... | ... | @@ -272,5 +284,5 @@ runTHQ |
| 272 | 284 | runTHQ pipe rstate mb_loc ghciq = do
|
| 273 | 285 | qstateref <- localRef rstate
|
| 274 | 286 | modifyIORef' qstateref (\qstate -> qstate { qsLocation = mb_loc, qsPipe = pipe })
|
| 275 | - r <- runGHCiQ (TH.runQ ghciq) qstateref
|
|
| 287 | + r <- runGHCiQ (runQinGHCiQ ghciq) qstateref
|
|
| 276 | 288 | return $! LB.toStrict (runPut (put r)) |
| ... | ... | @@ -5,13 +5,16 @@ |
| 5 | 5 | {-# LANGUAGE TemplateHaskellQuotes #-}
|
| 6 | 6 | {-# LANGUAGE Trustworthy #-}
|
| 7 | 7 | {-# LANGUAGE UnboxedTuples #-}
|
| 8 | +{-# OPTIONS_GHC -Wno-warnings-deprecations #-}
|
|
| 8 | 9 | |
| 9 | 10 | module Language.Haskell.TH.Syntax (
|
| 10 | 11 | Quote (..),
|
| 11 | 12 | Exp (..),
|
| 12 | 13 | Match (..),
|
| 13 | 14 | Clause (..),
|
| 14 | - Q (..),
|
|
| 15 | + Q,
|
|
| 16 | + -- backwards compatibility
|
|
| 17 | + Language.Haskell.TH.Syntax.unQ,
|
|
| 15 | 18 | Pat (..),
|
| 16 | 19 | Stmt (..),
|
| 17 | 20 | Con (..),
|
| ... | ... | @@ -207,6 +210,8 @@ import System.FilePath |
| 207 | 210 | import Data.Data hiding (Fixity(..))
|
| 208 | 211 | import Data.List.NonEmpty (NonEmpty(..))
|
| 209 | 212 | import GHC.Lexeme ( startsVarSym, startsVarId )
|
| 213 | +import Control.Monad.IO.Class (MonadIO, liftIO)
|
|
| 214 | +import System.IO (hPutStrLn, stderr)
|
|
| 210 | 215 | |
| 211 | 216 | -- This module completely re-exports 'GHC.Boot.TH.Syntax',
|
| 212 | 217 | -- and exports additionally functions that depend on @filepath@ or @System.IO@.
|
| ... | ... | @@ -499,3 +504,180 @@ reassociate the tree as necessary. |
| 499 | 504 | -- Subsumed by the more general 'SpecialiseEP' constructor.
|
| 500 | 505 | pattern SpecialiseP :: Name -> Type -> (Maybe Inline) -> Phases -> Pragma
|
| 501 | 506 | pattern SpecialiseP nm ty inl phases = SpecialiseEP Nothing [] (SigE (VarE nm) ty) inl phases
|
| 507 | + |
|
| 508 | +unQ :: Q a -> (forall m. Quasi m => m a)
|
|
| 509 | +unQ m = runQ m
|
|
| 510 | + |
|
| 511 | +-----------------------------------------------------
|
|
| 512 | +--
|
|
| 513 | +-- The Quasi class
|
|
| 514 | +--
|
|
| 515 | +-----------------------------------------------------
|
|
| 516 | + |
|
| 517 | +class (MonadIO m, MonadFail m) => Quasi m where
|
|
| 518 | + qRunQ :: Q a -> m a
|
|
| 519 | + -- | Fresh names. See 'newName'.
|
|
| 520 | + qNewName :: String -> m Name
|
|
| 521 | + |
|
| 522 | + ------- Error reporting and recovery -------
|
|
| 523 | + -- | Report an error (True) or warning (False)
|
|
| 524 | + -- ...but carry on; use 'fail' to stop. See 'report'.
|
|
| 525 | + qReport :: Bool -> String -> m ()
|
|
| 526 | + |
|
| 527 | + -- | See 'recover'.
|
|
| 528 | + qRecover :: m a -- ^ the error handler
|
|
| 529 | + -> m a -- ^ action which may fail
|
|
| 530 | + -> m a -- ^ Recover from the monadic 'fail'
|
|
| 531 | + |
|
| 532 | + ------- Inspect the type-checker's environment -------
|
|
| 533 | + -- | True <=> type namespace, False <=> value namespace. See 'lookupName'.
|
|
| 534 | + qLookupName :: Bool -> String -> m (Maybe Name)
|
|
| 535 | + -- | See 'reify'.
|
|
| 536 | + qReify :: Name -> m Info
|
|
| 537 | + -- | See 'reifyFixity'.
|
|
| 538 | + qReifyFixity :: Name -> m (Maybe Fixity)
|
|
| 539 | + -- | See 'reifyType'.
|
|
| 540 | + qReifyType :: Name -> m Type
|
|
| 541 | + -- | Is (n tys) an instance? Returns list of matching instance Decs (with
|
|
| 542 | + -- empty sub-Decs) Works for classes and type functions. See 'reifyInstances'.
|
|
| 543 | + qReifyInstances :: Name -> [Type] -> m [Dec]
|
|
| 544 | + -- | See 'reifyRoles'.
|
|
| 545 | + qReifyRoles :: Name -> m [Role]
|
|
| 546 | + -- | See 'reifyAnnotations'.
|
|
| 547 | + qReifyAnnotations :: Data a => AnnLookup -> m [a]
|
|
| 548 | + -- | See 'reifyModule'.
|
|
| 549 | + qReifyModule :: Module -> m ModuleInfo
|
|
| 550 | + -- | See 'reifyConStrictness'.
|
|
| 551 | + qReifyConStrictness :: Name -> m [DecidedStrictness]
|
|
| 552 | + |
|
| 553 | + -- | See 'location'.
|
|
| 554 | + qLocation :: m Loc
|
|
| 555 | + |
|
| 556 | + -- | Input/output (dangerous). See 'runIO'.
|
|
| 557 | + qRunIO :: IO a -> m a
|
|
| 558 | + qRunIO = liftIO
|
|
| 559 | + -- | See 'getPackageRoot'.
|
|
| 560 | + qGetPackageRoot :: m FilePath
|
|
| 561 | + |
|
| 562 | + -- | See 'addDependentFile'.
|
|
| 563 | + qAddDependentFile :: FilePath -> m ()
|
|
| 564 | + |
|
| 565 | + -- | See 'addDependentDirectory'.
|
|
| 566 | + qAddDependentDirectory :: FilePath -> m ()
|
|
| 567 | + |
|
| 568 | + -- | See 'addTempFile'.
|
|
| 569 | + qAddTempFile :: String -> m FilePath
|
|
| 570 | + |
|
| 571 | + -- | See 'addTopDecls'.
|
|
| 572 | + qAddTopDecls :: [Dec] -> m ()
|
|
| 573 | + |
|
| 574 | + -- | See 'addForeignFilePath'.
|
|
| 575 | + qAddForeignFilePath :: ForeignSrcLang -> String -> m ()
|
|
| 576 | + |
|
| 577 | + -- | See 'addModFinalizer'.
|
|
| 578 | + qAddModFinalizer :: Q () -> m ()
|
|
| 579 | + |
|
| 580 | + -- | See 'addCorePlugin'.
|
|
| 581 | + qAddCorePlugin :: String -> m ()
|
|
| 582 | + |
|
| 583 | + -- | See 'getQ'.
|
|
| 584 | + qGetQ :: Typeable a => m (Maybe a)
|
|
| 585 | + |
|
| 586 | + -- | See 'putQ'.
|
|
| 587 | + qPutQ :: Typeable a => a -> m ()
|
|
| 588 | + |
|
| 589 | + -- | See 'isExtEnabled'.
|
|
| 590 | + qIsExtEnabled :: Extension -> m Bool
|
|
| 591 | + -- | See 'extsEnabled'.
|
|
| 592 | + qExtsEnabled :: m [Extension]
|
|
| 593 | + |
|
| 594 | + -- | See 'putDoc'.
|
|
| 595 | + qPutDoc :: DocLoc -> String -> m ()
|
|
| 596 | + -- | See 'getDoc'.
|
|
| 597 | + qGetDoc :: DocLoc -> m (Maybe String)
|
|
| 598 | + |
|
| 599 | +-- | \"Runs\" the 'Q' monad. Normal users of Template Haskell
|
|
| 600 | +-- should not need this function, as the splice brackets @$( ... )@
|
|
| 601 | +-- are the usual way of running a 'Q' computation.
|
|
| 602 | +--
|
|
| 603 | +-- This function is primarily used in GHC internals, and for debugging
|
|
| 604 | +-- splices by running them in 'IO'.
|
|
| 605 | +--
|
|
| 606 | +-- Note that many functions in 'Q', such as 'reify' and other compiler
|
|
| 607 | +-- queries, are not supported when running 'Q' in 'IO'; these operations
|
|
| 608 | +-- simply fail at runtime. Indeed, the only operations guaranteed to succeed
|
|
| 609 | +-- are 'newName', 'runIO', 'reportError' and 'reportWarning'.
|
|
| 610 | +runQ :: Quasi m => Q a -> m a
|
|
| 611 | +runQ = qRunQ
|
|
| 612 | + |
|
| 613 | +-----------------------------------------------------
|
|
| 614 | +-- The IO instance of Quasi
|
|
| 615 | +-----------------------------------------------------
|
|
| 616 | + |
|
| 617 | +-- | This instance is used only when running a Q
|
|
| 618 | +-- computation in the IO monad, usually just to
|
|
| 619 | +-- print the result. There is no interesting
|
|
| 620 | +-- type environment, so reification isn't going to
|
|
| 621 | +-- work.
|
|
| 622 | +instance Quasi IO where
|
|
| 623 | + qRunQ (Q m) = m metaHandlersIO
|
|
| 624 | + qNewName = newNameIO
|
|
| 625 | + |
|
| 626 | + qReport True msg = hPutStrLn stderr ("Template Haskell error: " ++ msg)
|
|
| 627 | + qReport False msg = hPutStrLn stderr ("Template Haskell error: " ++ msg)
|
|
| 628 | + |
|
| 629 | + qLookupName _ _ = badIO "lookupName"
|
|
| 630 | + qReify _ = badIO "reify"
|
|
| 631 | + qReifyFixity _ = badIO "reifyFixity"
|
|
| 632 | + qReifyType _ = badIO "reifyFixity"
|
|
| 633 | + qReifyInstances _ _ = badIO "reifyInstances"
|
|
| 634 | + qReifyRoles _ = badIO "reifyRoles"
|
|
| 635 | + qReifyAnnotations _ = badIO "reifyAnnotations"
|
|
| 636 | + qReifyModule _ = badIO "reifyModule"
|
|
| 637 | + qReifyConStrictness _ = badIO "reifyConStrictness"
|
|
| 638 | + qLocation = badIO "currentLocation"
|
|
| 639 | + qRecover _ _ = badIO "recover" -- Maybe we could fix this?
|
|
| 640 | + qGetPackageRoot = badIO "getProjectRoot"
|
|
| 641 | + qAddDependentFile _ = badIO "addDependentFile"
|
|
| 642 | + qAddTempFile _ = badIO "addTempFile"
|
|
| 643 | + qAddTopDecls _ = badIO "addTopDecls"
|
|
| 644 | + qAddForeignFilePath _ _ = badIO "addForeignFilePath"
|
|
| 645 | + qAddModFinalizer _ = badIO "addModFinalizer"
|
|
| 646 | + qAddCorePlugin _ = badIO "addCorePlugin"
|
|
| 647 | + qGetQ = badIO "getQ"
|
|
| 648 | + qPutQ _ = badIO "putQ"
|
|
| 649 | + qIsExtEnabled _ = badIO "isExtEnabled"
|
|
| 650 | + qExtsEnabled = badIO "extsEnabled"
|
|
| 651 | + qPutDoc _ _ = badIO "putDoc"
|
|
| 652 | + qGetDoc _ = badIO "getDoc"
|
|
| 653 | + qAddDependentDirectory _ = badIO "AddDependentDirectory"
|
|
| 654 | + |
|
| 655 | +instance Quasi Q where
|
|
| 656 | + qRunQ = id
|
|
| 657 | + qNewName = newName
|
|
| 658 | + qReport = report
|
|
| 659 | + qRecover = recover
|
|
| 660 | + qReify = reify
|
|
| 661 | + qReifyFixity = reifyFixity
|
|
| 662 | + qReifyType = reifyType
|
|
| 663 | + qReifyInstances = reifyInstances
|
|
| 664 | + qReifyRoles = reifyRoles
|
|
| 665 | + qReifyAnnotations = reifyAnnotations
|
|
| 666 | + qReifyModule = reifyModule
|
|
| 667 | + qReifyConStrictness = reifyConStrictness
|
|
| 668 | + qLookupName = lookupName
|
|
| 669 | + qLocation = location
|
|
| 670 | + qGetPackageRoot = getPackageRoot
|
|
| 671 | + qAddDependentFile = addDependentFile
|
|
| 672 | + qAddDependentDirectory = addDependentDirectory
|
|
| 673 | + qAddTempFile = addTempFile
|
|
| 674 | + qAddTopDecls = addTopDecls
|
|
| 675 | + qAddForeignFilePath = addForeignFilePath
|
|
| 676 | + qAddModFinalizer = addModFinalizer
|
|
| 677 | + qAddCorePlugin = addCorePlugin
|
|
| 678 | + qGetQ = getQ
|
|
| 679 | + qPutQ = putQ
|
|
| 680 | + qIsExtEnabled = isExtEnabled
|
|
| 681 | + qExtsEnabled = extsEnabled
|
|
| 682 | + qPutDoc = putDoc
|
|
| 683 | + qGetDoc = getDoc |
| ... | ... | @@ -354,7 +354,6 @@ module Language.Haskell.TH where |
| 354 | 354 | type Pred = Type
|
| 355 | 355 | type PredQ :: *
|
| 356 | 356 | type PredQ = Q Pred
|
| 357 | - type role Q nominal
|
|
| 358 | 357 | type Q :: * -> *
|
| 359 | 358 | newtype Q a = ...
|
| 360 | 359 | type Quote :: (* -> *) -> Constraint
|
| ... | ... | @@ -655,7 +654,7 @@ module Language.Haskell.TH where |
| 655 | 654 | roleAnnotD :: forall (m :: * -> *). Quote m => Name -> [GHC.Internal.TH.Lib.Role] -> m Dec
|
| 656 | 655 | ruleVar :: forall (m :: * -> *). Quote m => Name -> m RuleBndr
|
| 657 | 656 | runIO :: forall a. GHC.Internal.Types.IO a -> Q a
|
| 658 | - runQ :: forall (m :: * -> *) a. GHC.Internal.TH.Monad.Quasi m => Q a -> m a
|
|
| 657 | + runQ :: forall (m :: * -> *) a. Language.Haskell.TH.Syntax.Quasi m => Q a -> m a
|
|
| 659 | 658 | safe :: Safety
|
| 660 | 659 | sectionL :: forall (m :: * -> *). Quote m => m Exp -> m Exp -> m Exp
|
| 661 | 660 | sectionR :: forall (m :: * -> *). Quote m => m Exp -> m Exp -> m Exp
|
| ... | ... | @@ -1703,11 +1702,11 @@ module Language.Haskell.TH.Syntax where |
| 1703 | 1702 | data Pragma = InlineP Name Inline RuleMatch Phases | OpaqueP Name | SpecialiseEP (GHC.Internal.Maybe.Maybe [TyVarBndr ()]) [RuleBndr] Exp (GHC.Internal.Maybe.Maybe Inline) Phases | SpecialiseInstP Type | RuleP GHC.Internal.Base.String (GHC.Internal.Maybe.Maybe [TyVarBndr ()]) [RuleBndr] Exp Exp Phases | AnnP AnnTarget Exp | LineP GHC.Internal.Types.Int GHC.Internal.Base.String | CompleteP [Name] (GHC.Internal.Maybe.Maybe Name) | SCCP Name (GHC.Internal.Maybe.Maybe GHC.Internal.Base.String)
|
| 1704 | 1703 | type Pred :: *
|
| 1705 | 1704 | type Pred = Type
|
| 1706 | - type role Q nominal
|
|
| 1707 | 1705 | type Q :: * -> *
|
| 1708 | - newtype Q a = Q {unQ :: forall (m :: * -> *). Quasi m => m a}
|
|
| 1706 | + newtype Q a = ...
|
|
| 1709 | 1707 | type Quasi :: (* -> *) -> Constraint
|
| 1710 | 1708 | class (GHC.Internal.Control.Monad.IO.Class.MonadIO m, GHC.Internal.Control.Monad.Fail.MonadFail m) => Quasi m where
|
| 1709 | + qRunQ :: forall a. Q a -> m a
|
|
| 1711 | 1710 | qNewName :: GHC.Internal.Base.String -> m Name
|
| 1712 | 1711 | qReport :: GHC.Internal.Types.Bool -> GHC.Internal.Base.String -> m ()
|
| 1713 | 1712 | qRecover :: forall a. m a -> m a -> m a
|
| ... | ... | @@ -1730,13 +1729,13 @@ module Language.Haskell.TH.Syntax where |
| 1730 | 1729 | qAddForeignFilePath :: ForeignSrcLang -> GHC.Internal.Base.String -> m ()
|
| 1731 | 1730 | qAddModFinalizer :: Q () -> m ()
|
| 1732 | 1731 | qAddCorePlugin :: GHC.Internal.Base.String -> m ()
|
| 1733 | - qGetQ :: forall a. ghc-internal-9.1500.0:GHC.Internal.Data.Typeable.Internal.Typeable a => m (GHC.Internal.Maybe.Maybe a)
|
|
| 1734 | - qPutQ :: forall a. ghc-internal-9.1500.0:GHC.Internal.Data.Typeable.Internal.Typeable a => a -> m ()
|
|
| 1732 | + qGetQ :: forall a. ghc-internal-10.100.0:GHC.Internal.Data.Typeable.Internal.Typeable a => m (GHC.Internal.Maybe.Maybe a)
|
|
| 1733 | + qPutQ :: forall a. ghc-internal-10.100.0:GHC.Internal.Data.Typeable.Internal.Typeable a => a -> m ()
|
|
| 1735 | 1734 | qIsExtEnabled :: Extension -> m GHC.Internal.Types.Bool
|
| 1736 | 1735 | qExtsEnabled :: m [Extension]
|
| 1737 | 1736 | qPutDoc :: DocLoc -> GHC.Internal.Base.String -> m ()
|
| 1738 | 1737 | qGetDoc :: DocLoc -> m (GHC.Internal.Maybe.Maybe GHC.Internal.Base.String)
|
| 1739 | - {-# MINIMAL qNewName, qReport, qRecover, qLookupName, qReify, qReifyFixity, qReifyType, qReifyInstances, qReifyRoles, qReifyAnnotations, qReifyModule, qReifyConStrictness, qLocation, qGetPackageRoot, qAddDependentFile, qAddDependentDirectory, qAddTempFile, qAddTopDecls, qAddForeignFilePath, qAddModFinalizer, qAddCorePlugin, qGetQ, qPutQ, qIsExtEnabled, qExtsEnabled, qPutDoc, qGetDoc #-}
|
|
| 1738 | + {-# MINIMAL qRunQ, qNewName, qReport, qRecover, qLookupName, qReify, qReifyFixity, qReifyType, qReifyInstances, qReifyRoles, qReifyAnnotations, qReifyModule, qReifyConStrictness, qLocation, qGetPackageRoot, qAddDependentFile, qAddDependentDirectory, qAddTempFile, qAddTopDecls, qAddForeignFilePath, qAddModFinalizer, qAddCorePlugin, qGetQ, qPutQ, qIsExtEnabled, qExtsEnabled, qPutDoc, qGetDoc #-}
|
|
| 1740 | 1739 | type Quote :: (* -> *) -> Constraint
|
| 1741 | 1740 | class GHC.Internal.Base.Monad m => Quote m where
|
| 1742 | 1741 | newName :: GHC.Internal.Base.String -> m Name
|
| ... | ... | @@ -1814,7 +1813,7 @@ module Language.Haskell.TH.Syntax where |
| 1814 | 1813 | falseName :: Name
|
| 1815 | 1814 | getDoc :: DocLoc -> Q (GHC.Internal.Maybe.Maybe GHC.Internal.Base.String)
|
| 1816 | 1815 | getPackageRoot :: Q GHC.Internal.IO.FilePath
|
| 1817 | - getQ :: forall a. ghc-internal-9.1500.0:GHC.Internal.Data.Typeable.Internal.Typeable a => Q (GHC.Internal.Maybe.Maybe a)
|
|
| 1816 | + getQ :: forall a. ghc-internal-10.100.0:GHC.Internal.Data.Typeable.Internal.Typeable a => Q (GHC.Internal.Maybe.Maybe a)
|
|
| 1818 | 1817 | get_cons_names :: Con -> [Name]
|
| 1819 | 1818 | hoistCode :: forall (m :: * -> *) (n :: * -> *) (r :: GHC.Internal.Types.RuntimeRep) (a :: TYPE r). GHC.Internal.Base.Monad m => (forall x. m x -> n x) -> Code m a -> Code n a
|
| 1820 | 1819 | isExtEnabled :: Extension -> Q GHC.Internal.Types.Bool
|
| ... | ... | @@ -1861,7 +1860,7 @@ module Language.Haskell.TH.Syntax where |
| 1861 | 1860 | oneName :: Name
|
| 1862 | 1861 | pkgString :: PkgName -> GHC.Internal.Base.String
|
| 1863 | 1862 | putDoc :: DocLoc -> GHC.Internal.Base.String -> Q ()
|
| 1864 | - putQ :: forall a. ghc-internal-9.1500.0:GHC.Internal.Data.Typeable.Internal.Typeable a => a -> Q ()
|
|
| 1863 | + putQ :: forall a. ghc-internal-10.100.0:GHC.Internal.Data.Typeable.Internal.Typeable a => a -> Q ()
|
|
| 1865 | 1864 | recover :: forall a. Q a -> Q a -> Q a
|
| 1866 | 1865 | reify :: Name -> Q Info
|
| 1867 | 1866 | reifyAnnotations :: forall a. GHC.Internal.Data.Data.Data a => AnnLookup -> Q [a]
|
| ... | ... | @@ -1884,6 +1883,7 @@ module Language.Haskell.TH.Syntax where |
| 1884 | 1883 | trueName :: Name
|
| 1885 | 1884 | tupleDataName :: GHC.Internal.Types.Int -> Name
|
| 1886 | 1885 | tupleTypeName :: GHC.Internal.Types.Int -> Name
|
| 1886 | + unQ :: forall a. Q a -> forall (m :: * -> *). Quasi m => m a
|
|
| 1887 | 1887 | unTypeCode :: forall (r :: GHC.Internal.Types.RuntimeRep) (a :: TYPE r) (m :: * -> *). Quote m => Code m a -> m Exp
|
| 1888 | 1888 | unTypeQ :: forall (r :: GHC.Internal.Types.RuntimeRep) (a :: TYPE r) (m :: * -> *). Quote m => m (TExp a) -> m Exp
|
| 1889 | 1889 | unboxedSumDataName :: SumAlt -> SumArity -> Name
|
| ... | ... | @@ -2289,10 +2289,10 @@ instance forall a b c d e f g. (GHC.Internal.TH.Lift.Lift a, GHC.Internal.TH.Lif |
| 2289 | 2289 | instance GHC.Internal.TH.Lift.Lift (# #) -- Defined in ‘GHC.Internal.TH.Lift’
|
| 2290 | 2290 | instance GHC.Internal.TH.Lift.Lift GHC.Internal.Prim.Char# -- Defined in ‘GHC.Internal.TH.Lift’
|
| 2291 | 2291 | instance GHC.Internal.TH.Lift.Lift GHC.Internal.Prim.Word# -- Defined in ‘GHC.Internal.TH.Lift’
|
| 2292 | -instance GHC.Internal.TH.Monad.Quasi GHC.Internal.Types.IO -- Defined in ‘GHC.Internal.TH.Monad’
|
|
| 2293 | -instance GHC.Internal.TH.Monad.Quasi GHC.Internal.TH.Monad.Q -- Defined in ‘GHC.Internal.TH.Monad’
|
|
| 2294 | 2292 | instance GHC.Internal.TH.Monad.Quote GHC.Internal.Types.IO -- Defined in ‘GHC.Internal.TH.Monad’
|
| 2295 | 2293 | instance GHC.Internal.TH.Monad.Quote GHC.Internal.TH.Monad.Q -- Defined in ‘GHC.Internal.TH.Monad’
|
| 2296 | 2294 | instance [safe] Language.Haskell.TH.Lib.DefaultBndrFlag GHC.Internal.TH.Syntax.BndrVis -- Defined in ‘Language.Haskell.TH.Lib’
|
| 2297 | 2295 | instance [safe] Language.Haskell.TH.Lib.DefaultBndrFlag GHC.Internal.TH.Syntax.Specificity -- Defined in ‘Language.Haskell.TH.Lib’
|
| 2298 | 2296 | instance [safe] Language.Haskell.TH.Lib.DefaultBndrFlag () -- Defined in ‘Language.Haskell.TH.Lib’
|
| 2297 | +instance Language.Haskell.TH.Syntax.Quasi GHC.Internal.Types.IO -- Defined in ‘Language.Haskell.TH.Syntax’
|
|
| 2298 | +instance Language.Haskell.TH.Syntax.Quasi GHC.Internal.TH.Monad.Q -- Defined in ‘Language.Haskell.TH.Syntax’ |