Teo Camarasu pushed to branch wip/abstract-q at Glasgow Haskell Compiler / GHC

Commits:

3 changed files:

Changes:

  • compiler/GHC/Data/IOEnv.hs
    ... ... @@ -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,10 @@ 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
    +unliftIOEnv :: forall env b. ((forall a. IOEnv env a -> IO a) -> IO b) -> IOEnv env b
    
    263
    +unliftIOEnv k = IOEnv $ \env ->
    
    264
    +  let
    
    265
    +    unlift :: forall a. IOEnv env a -> IO a
    
    266
    +    unlift (IOEnv m) = m env
    
    267
    +  in k unlift

  • compiler/GHC/Tc/Gen/Splice.hs
    ... ... @@ -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)
    
    ... ... @@ -1139,7 +1140,7 @@ convertAnnotationWrapper fhv = do
    1139 1140
     -}
    
    1140 1141
     
    
    1141 1142
     runQuasi :: TH.Q a -> TcM a
    
    1142
    -runQuasi act = TH.runQ act
    
    1143
    +runQuasi (TH.Q act) = runMetaHandlersInTcM metaHandlersTcM >>= liftIO . act
    
    1143 1144
     
    
    1144 1145
     runRemoteModFinalizers :: ThModFinalizers -> TcM ()
    
    1145 1146
     runRemoteModFinalizers (ThModFinalizers finRefs) = do
    
    ... ... @@ -1466,68 +1467,11 @@ 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) }
    
    1473
    -
    
    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
    -                        UnhelpfulSpan _ -> pprPanic "qLocation: Unhelpful location"
    
    1484
    -                                                    (ppr l)
    
    1485
    -                        RealSrcSpan s _ -> return s
    
    1486
    -                 ; return (TH.Loc { TH.loc_filename = unpackFS (srcSpanFile r)
    
    1487
    -                                  , TH.loc_module   = moduleNameString (moduleName m)
    
    1488
    -                                  , TH.loc_package  = unitString (moduleUnit m)
    
    1489
    -                                  , TH.loc_start = (srcSpanStartLine r, srcSpanStartCol r)
    
    1490
    -                                  , TH.loc_end = (srcSpanEndLine   r, srcSpanEndCol   r) }) }
    
    1491
    -
    
    1492
    -  qLookupName       = lookupName
    
    1493
    -  qReify            = reify
    
    1494
    -  qReifyFixity nm   = lookupThName nm >>= reifyFixity
    
    1495
    -  qReifyType        = reifyTypeOfThing
    
    1496
    -  qReifyInstances   = reifyInstances
    
    1497
    -  qReifyRoles       = reifyRoles
    
    1498
    -  qReifyAnnotations = reifyAnnotations
    
    1499
    -  qReifyModule      = reifyModule
    
    1500
    -  qReifyConStrictness nm = do { nm' <- lookupThName nm
    
    1501
    -                              ; dc  <- tcLookupDataCon nm'
    
    1502
    -                              ; let bangs = dataConImplBangs dc
    
    1503
    -                              ; return (map reifyDecidedStrictness bangs) }
    
    1504
    -
    
    1505
    -        -- For qRecover, discard error messages if
    
    1506
    -        -- the recovery action is chosen.  Otherwise
    
    1507
    -        -- we'll only fail higher up.
    
    1508
    -  qRecover recover main = tryTcDiscardingErrs recover main
    
    1509
    -
    
    1510
    -  qGetPackageRoot = do
    
    1511
    -    dflags <- getDynFlags
    
    1512
    -    return $ fromMaybe "." (workingDirectory dflags)
    
    1513
    -
    
    1514
    -  qAddDependentFile fp = do
    
    1515
    -    ref <- fmap tcg_dependent_files getGblEnv
    
    1516
    -    dep_files <- readTcRef ref
    
    1517
    -    writeTcRef ref (fp:dep_files)
    
    1518
    -
    
    1519
    -  qAddDependentDirectory dp = do
    
    1520
    -    ref <- fmap tcg_dependent_dirs getGblEnv
    
    1521
    -    dep_dirs <- readTcRef ref
    
    1522
    -    writeTcRef ref (dp:dep_dirs)
    
    1523
    -
    
    1524
    -  qAddTempFile suffix = do
    
    1525
    -    dflags <- getDynFlags
    
    1526
    -    logger <- getLogger
    
    1527
    -    tmpfs  <- hsc_tmpfs <$> getTopEnv
    
    1528
    -    liftIO $ newTempName logger tmpfs (tmpDir dflags) TFL_GhcSession suffix
    
    1529
    -
    
    1530
    -  qAddTopDecls thds = do
    
    1470
    +report True msg  = seqList msg $ addErr        $ TcRnTHError $ ReportCustomQuasiError True  msg
    
    1471
    +report False msg = seqList msg $ addDiagnostic $ TcRnTHError $ ReportCustomQuasiError False msg
    
    1472
    +
    
    1473
    +addTopDecls :: [TH.Dec] -> TcM ()
    
    1474
    +addTopDecls thds = do
    
    1531 1475
           exts <- fmap extensionFlags getDynFlags
    
    1532 1476
           l <- getSrcSpanM
    
    1533 1477
           th_origin <- getThSpliceOrigin
    
    ... ... @@ -1555,52 +1499,12 @@ instance TH.Quasi TcM where
    1555 1499
           bindName :: RdrName -> TcM ()
    
    1556 1500
           bindName (Exact n)
    
    1557 1501
             = do { th_topnames_var <- fmap tcg_th_topnames getGblEnv
    
    1558
    -             ; updTcRef th_topnames_var (\ns -> extendNameSet ns n)
    
    1559
    -             }
    
    1502
    +            ; updTcRef th_topnames_var (\ns -> extendNameSet ns n)
    
    1503
    +            }
    
    1560 1504
     
    
    1561 1505
           bindName name = addErr $ TcRnTHError $ THNameError $ NonExactName name
    
    1562 1506
     
    
    1563
    -  qAddForeignFilePath lang fp = do
    
    1564
    -    var <- fmap tcg_th_foreign_files getGblEnv
    
    1565
    -    updTcRef var ((lang, fp) :)
    
    1566
    -
    
    1567
    -  qAddModFinalizer fin = do
    
    1568
    -      r <- liftIO $ mkRemoteRef fin
    
    1569
    -      fref <- liftIO $ mkForeignRef r (freeRemoteRef r)
    
    1570
    -      addModFinalizerRef fref
    
    1571
    -
    
    1572
    -  qAddCorePlugin plugin = do
    
    1573
    -      hsc_env <- getTopEnv
    
    1574
    -      let fc        = hsc_FC hsc_env
    
    1575
    -      let home_unit = hsc_home_unit hsc_env
    
    1576
    -      let dflags    = hsc_dflags hsc_env
    
    1577
    -      let fopts     = initFinderOpts dflags
    
    1578
    -      r <- liftIO $ findHomeModule fc fopts home_unit (mkModuleName plugin)
    
    1579
    -      let err = TcRnTHError $ AddInvalidCorePlugin plugin
    
    1580
    -      case r of
    
    1581
    -        Found {} -> addErr err
    
    1582
    -        FoundMultiple {} -> addErr err
    
    1583
    -        _ -> return ()
    
    1584
    -      th_coreplugins_var <- tcg_th_coreplugins <$> getGblEnv
    
    1585
    -      updTcRef th_coreplugins_var (plugin:)
    
    1586
    -
    
    1587
    -  qGetQ :: forall a. Typeable a => TcM (Maybe a)
    
    1588
    -  qGetQ = do
    
    1589
    -      th_state_var <- fmap tcg_th_state getGblEnv
    
    1590
    -      th_state <- readTcRef th_state_var
    
    1591
    -      -- See #10596 for why we use a scoped type variable here.
    
    1592
    -      return (Map.lookup (typeRep (Proxy :: Proxy a)) th_state >>= fromDynamic)
    
    1593
    -
    
    1594
    -  qPutQ x = do
    
    1595
    -      th_state_var <- fmap tcg_th_state getGblEnv
    
    1596
    -      updTcRef th_state_var (\m -> Map.insert (typeOf x) (toDyn x) m)
    
    1597
    -
    
    1598
    -  qIsExtEnabled = xoptM
    
    1599
    -
    
    1600
    -  qExtsEnabled =
    
    1601
    -    EnumSet.toList . extensionFlags . hsc_dflags <$> getTopEnv
    
    1602
    -
    
    1603
    -  qPutDoc doc_loc s = do
    
    1507
    +putDoc doc_loc s = do
    
    1604 1508
         th_doc_var <- tcg_th_docs <$> getGblEnv
    
    1605 1509
         resolved_doc_loc <- resolve_loc doc_loc
    
    1606 1510
         is_local <- checkLocalName resolved_doc_loc
    
    ... ... @@ -1623,14 +1527,184 @@ instance TH.Quasi TcM where
    1623 1527
           checkLocalName ModuleDoc = pure True
    
    1624 1528
     
    
    1625 1529
     
    
    1626
    -  qGetDoc (TH.DeclDoc n) = lookupThName n >>= lookupDeclDoc
    
    1627
    -  qGetDoc (TH.InstDoc t) = lookupThInstName t >>= lookupDeclDoc
    
    1628
    -  qGetDoc (TH.ArgDoc n i) = lookupThName n >>= lookupArgDoc i
    
    1629
    -  qGetDoc TH.ModuleDoc = do
    
    1530
    +getDoc (TH.DeclDoc n) = lookupThName n >>= lookupDeclDoc
    
    1531
    +getDoc (TH.InstDoc t) = lookupThInstName t >>= lookupDeclDoc
    
    1532
    +getDoc (TH.ArgDoc n i) = lookupThName n >>= lookupArgDoc i
    
    1533
    +getDoc TH.ModuleDoc = do
    
    1630 1534
         df <- getDynFlags
    
    1631 1535
         docs <- getGblEnv >>= extractDocs df
    
    1632 1536
         return (renderHsDocString . hsDocString <$> (docs_mod_hdr =<< docs))
    
    1633 1537
     
    
    1538
    +getQ :: forall a. Typeable a => TcM (Maybe a)
    
    1539
    +getQ = do
    
    1540
    +    th_state_var <- fmap tcg_th_state getGblEnv
    
    1541
    +    th_state <- readTcRef th_state_var
    
    1542
    +    -- See #10596 for why we use a scoped type variable here.
    
    1543
    +    return (Map.lookup (typeRep (Proxy :: Proxy a)) th_state >>= fromDynamic)
    
    1544
    +
    
    1545
    +location :: TcM TH.Loc
    
    1546
    +location = do { m <- getModule
    
    1547
    +              ; l <- getSrcSpanM
    
    1548
    +              ; r <- case l of
    
    1549
    +                      UnhelpfulSpan _ -> pprPanic "qLocation: Unhelpful location"
    
    1550
    +                                                  (ppr l)
    
    1551
    +                      RealSrcSpan s _ -> return s
    
    1552
    +              ; return (TH.Loc { TH.loc_filename = unpackFS (srcSpanFile r)
    
    1553
    +                                , TH.loc_module   = moduleNameString (moduleName m)
    
    1554
    +                                , TH.loc_package  = unitString (moduleUnit m)
    
    1555
    +                                , TH.loc_start = (srcSpanStartLine r, srcSpanStartCol r)
    
    1556
    +                                , TH.loc_end = (srcSpanEndLine   r, srcSpanEndCol   r) }) }
    
    1557
    +
    
    1558
    +runMetaHandlersInTcM :: TH.MetaHandlers TcM -> TcM (TH.MetaHandlers IO)
    
    1559
    +runMetaHandlersInTcM mh = unliftIOEnv $ \unliftTcM -> do
    
    1560
    +  let
    
    1561
    +    unliftTcM2 :: (a -> b -> TcM c) -> a -> b -> IO c
    
    1562
    +    unliftTcM2 m x y = unliftTcM (m x y)
    
    1563
    +  pure $ TH.MetaHandlers {
    
    1564
    +    mNewName = unliftTcM . mNewName mh
    
    1565
    +
    
    1566
    +    -- 'msg' is forced to ensure exceptions don't escape,
    
    1567
    +    -- see Note [Exceptions in TH]
    
    1568
    +    , mReport = unliftTcM2 $ mReport mh
    
    1569
    +
    
    1570
    +    , mLocation = unliftTcM $ mLocation mh
    
    1571
    +
    
    1572
    +    , mLookupName       = unliftTcM2 $ mLookupName mh
    
    1573
    +    , mReify            = unliftTcM . mReify mh
    
    1574
    +    , mReifyFixity      = unliftTcM . mReifyFixity mh
    
    1575
    +    , mReifyType        = unliftTcM . mReifyType mh
    
    1576
    +    , mReifyInstances   = unliftTcM2 $ mReifyInstances mh
    
    1577
    +    , mReifyRoles       = unliftTcM . mReifyRoles mh
    
    1578
    +    , mReifyAnnotations = unliftTcM . mReifyAnnotations mh
    
    1579
    +    , mReifyModule      = unliftTcM . mReifyModule mh
    
    1580
    +    , mReifyConStrictness = unliftTcM . mReifyConStrictness mh
    
    1581
    +
    
    1582
    +          -- For qRecover, discard error messages if
    
    1583
    +          -- the recovery action is chosen.  Otherwise
    
    1584
    +          -- we'll only fail higher up.
    
    1585
    +    , mRecover = \recover main -> unliftTcM $ mRecover mh (liftIO recover) (liftIO main)
    
    1586
    +
    
    1587
    +    , mGetPackageRoot = unliftTcM $ mGetPackageRoot mh
    
    1588
    +
    
    1589
    +    , mAddDependentFile = unliftTcM . mAddDependentFile mh
    
    1590
    +
    
    1591
    +    , mAddDependentDirectory = unliftTcM . mAddDependentDirectory mh
    
    1592
    +
    
    1593
    +    , mAddTempFile = unliftTcM . mAddTempFile mh
    
    1594
    +
    
    1595
    +    , mAddTopDecls = unliftTcM . mAddTopDecls mh
    
    1596
    +
    
    1597
    +    , mAddForeignFilePath = unliftTcM2 $ mAddForeignFilePath mh
    
    1598
    +
    
    1599
    +    , mAddModFinalizer = unliftTcM . mAddModFinalizer mh
    
    1600
    +
    
    1601
    +    , mAddCorePlugin = unliftTcM . mAddCorePlugin mh
    
    1602
    +
    
    1603
    +    , mGetQ = unliftTcM $ mGetQ mh
    
    1604
    +
    
    1605
    +    , mPutQ = unliftTcM . mPutQ mh
    
    1606
    +
    
    1607
    +    , mIsExtEnabled = unliftTcM . mIsExtEnabled mh
    
    1608
    +
    
    1609
    +    , mExtsEnabled = unliftTcM $ mExtsEnabled mh
    
    1610
    +
    
    1611
    +    , mPutDoc = unliftTcM2 $ mPutDoc mh
    
    1612
    +
    
    1613
    +    , mGetDoc = unliftTcM . mGetDoc mh
    
    1614
    +  }
    
    1615
    +
    
    1616
    +metaHandlersTcM :: TH.MetaHandlers TcM
    
    1617
    +metaHandlersTcM = TH.MetaHandlers {
    
    1618
    +    mNewName = \s -> do { u <- newUnique
    
    1619
    +                    ; let i = toInteger (getKey u)
    
    1620
    +                    ; return (TH.mkNameU s i) }
    
    1621
    +
    
    1622
    +    -- 'msg' is forced to ensure exceptions don't escape,
    
    1623
    +    -- see Note [Exceptions in TH]
    
    1624
    +    , mReport = report
    
    1625
    +
    
    1626
    +    , mLocation = location
    
    1627
    +
    
    1628
    +    , mLookupName       = lookupName
    
    1629
    +    , mReify            = reify
    
    1630
    +    , mReifyFixity      = \nm -> lookupThName nm >>= reifyFixity
    
    1631
    +    , mReifyType        = reifyTypeOfThing
    
    1632
    +    , mReifyInstances   = reifyInstances
    
    1633
    +    , mReifyRoles       = reifyRoles
    
    1634
    +    , mReifyAnnotations = reifyAnnotations
    
    1635
    +    , mReifyModule      = reifyModule
    
    1636
    +    , mReifyConStrictness = \nm -> do { nm' <- lookupThName nm
    
    1637
    +                                      ; dc  <- tcLookupDataCon nm'
    
    1638
    +                                      ; let bangs = dataConImplBangs dc
    
    1639
    +                                      ; return (map reifyDecidedStrictness bangs) }
    
    1640
    +
    
    1641
    +          -- For qRecover, discard error messages if
    
    1642
    +          -- the recovery action is chosen.  Otherwise
    
    1643
    +          -- we'll only fail higher up.
    
    1644
    +    , mRecover = \recover main -> tryTcDiscardingErrs recover main
    
    1645
    +
    
    1646
    +    , mGetPackageRoot = do
    
    1647
    +        dflags <- getDynFlags
    
    1648
    +        return $ fromMaybe "." (workingDirectory dflags)
    
    1649
    +
    
    1650
    +    , mAddDependentFile = \fp -> do
    
    1651
    +        ref <- fmap tcg_dependent_files getGblEnv
    
    1652
    +        dep_files <- readTcRef ref
    
    1653
    +        writeTcRef ref (fp:dep_files)
    
    1654
    +
    
    1655
    +    , mAddDependentDirectory = \dp -> do
    
    1656
    +        ref <- fmap tcg_dependent_dirs getGblEnv
    
    1657
    +        dep_dirs <- readTcRef ref
    
    1658
    +        writeTcRef ref (dp:dep_dirs)
    
    1659
    +
    
    1660
    +    , mAddTempFile = \suffix -> do
    
    1661
    +        dflags <- getDynFlags
    
    1662
    +        logger <- getLogger
    
    1663
    +        tmpfs  <- hsc_tmpfs <$> getTopEnv
    
    1664
    +        liftIO $ newTempName logger tmpfs (tmpDir dflags) TFL_GhcSession suffix
    
    1665
    +
    
    1666
    +    , mAddTopDecls = addTopDecls
    
    1667
    +
    
    1668
    +    , mAddForeignFilePath = \lang fp -> do
    
    1669
    +        var <- fmap tcg_th_foreign_files getGblEnv
    
    1670
    +        updTcRef var ((lang, fp) :)
    
    1671
    +
    
    1672
    +    , mAddModFinalizer = \fin -> do
    
    1673
    +        r <- liftIO $ mkRemoteRef fin
    
    1674
    +        fref <- liftIO $ mkForeignRef r (freeRemoteRef r)
    
    1675
    +        addModFinalizerRef fref
    
    1676
    +
    
    1677
    +    , mAddCorePlugin = \plugin -> do
    
    1678
    +        hsc_env <- getTopEnv
    
    1679
    +        let fc        = hsc_FC hsc_env
    
    1680
    +        let home_unit = hsc_home_unit hsc_env
    
    1681
    +        let dflags    = hsc_dflags hsc_env
    
    1682
    +        let fopts     = initFinderOpts dflags
    
    1683
    +        r <- liftIO $ findHomeModule fc fopts home_unit (mkModuleName plugin)
    
    1684
    +        let err = TcRnTHError $ AddInvalidCorePlugin plugin
    
    1685
    +        case r of
    
    1686
    +          Found {} -> addErr err
    
    1687
    +          FoundMultiple {} -> addErr err
    
    1688
    +          _ -> return ()
    
    1689
    +        th_coreplugins_var <- tcg_th_coreplugins <$> getGblEnv
    
    1690
    +        updTcRef th_coreplugins_var (plugin:)
    
    1691
    +
    
    1692
    +    , mGetQ = getQ
    
    1693
    +
    
    1694
    +    , mPutQ = \x -> do
    
    1695
    +        th_state_var <- fmap tcg_th_state getGblEnv
    
    1696
    +        updTcRef th_state_var (\m -> Map.insert (typeOf x) (toDyn x) m)
    
    1697
    +
    
    1698
    +    , mIsExtEnabled = xoptM
    
    1699
    +
    
    1700
    +    , mExtsEnabled =
    
    1701
    +        EnumSet.toList . extensionFlags . hsc_dflags <$> getTopEnv
    
    1702
    +
    
    1703
    +    , mPutDoc = putDoc
    
    1704
    +
    
    1705
    +    , mGetDoc = getDoc
    
    1706
    +  }
    
    1707
    +
    
    1634 1708
     -- | Looks up documentation for a declaration in first the current module,
    
    1635 1709
     -- otherwise tries to find it in another module via 'hscGetModuleInterface'.
    
    1636 1710
     lookupDeclDoc :: Name -> TcM (Maybe String)
    
    ... ... @@ -1795,7 +1869,7 @@ runTH ty fhv = do
    1795 1869
           -- Remote GHCi, see Note [Remote Template Haskell] in
    
    1796 1870
           -- libraries/ghci/GHCi/TH.hs.
    
    1797 1871
           rstate <- getTHState inst
    
    1798
    -      loc <- TH.qLocation
    
    1872
    +      loc <- location
    
    1799 1873
           -- run a remote TH request
    
    1800 1874
           r <- liftIO $
    
    1801 1875
             withForeignRef rstate $ \state_hv ->
    
    ... ... @@ -1911,32 +1985,33 @@ wrapTHResult tcm = do
    1911 1985
     
    
    1912 1986
     handleTHMessage :: THMessage a -> TcM a
    
    1913 1987
     handleTHMessage msg = case msg of
    
    1914
    -  NewName a -> wrapTHResult $ TH.qNewName a
    
    1915
    -  Report b str -> wrapTHResult $ TH.qReport b str
    
    1916
    -  LookupName b str -> wrapTHResult $ TH.qLookupName b str
    
    1917
    -  Reify n -> wrapTHResult $ TH.qReify n
    
    1918
    -  ReifyFixity n -> wrapTHResult $ TH.qReifyFixity n
    
    1919
    -  ReifyType n -> wrapTHResult $ TH.qReifyType n
    
    1920
    -  ReifyInstances n ts -> wrapTHResult $ TH.qReifyInstances n ts
    
    1921
    -  ReifyRoles n -> wrapTHResult $ TH.qReifyRoles n
    
    1922
    -  ReifyAnnotations lookup tyrep ->
    
    1923
    -    wrapTHResult $ (map B.pack <$> getAnnotationsByTypeRep lookup tyrep)
    
    1924
    -  ReifyModule m -> wrapTHResult $ TH.qReifyModule m
    
    1925
    -  ReifyConStrictness nm -> wrapTHResult $ TH.qReifyConStrictness nm
    
    1926
    -  GetPackageRoot -> wrapTHResult $ TH.qGetPackageRoot
    
    1927
    -  AddDependentFile f -> wrapTHResult $ TH.qAddDependentFile f
    
    1928
    -  AddDependentDirectory d -> wrapTHResult $ TH.qAddDependentDirectory d
    
    1929
    -  AddTempFile s -> wrapTHResult $ TH.qAddTempFile s
    
    1930
    -  AddModFinalizer r -> do
    
    1931
    -    interp <- hscInterp <$> getTopEnv
    
    1932
    -    wrapTHResult $ liftIO (mkFinalizedHValue interp r) >>= addModFinalizerRef
    
    1933
    -  AddCorePlugin str -> wrapTHResult $ TH.qAddCorePlugin str
    
    1934
    -  AddTopDecls decs -> wrapTHResult $ TH.qAddTopDecls decs
    
    1935
    -  AddForeignFilePath lang str -> wrapTHResult $ TH.qAddForeignFilePath lang str
    
    1936
    -  IsExtEnabled ext -> wrapTHResult $ TH.qIsExtEnabled ext
    
    1937
    -  ExtsEnabled -> wrapTHResult $ TH.qExtsEnabled
    
    1938
    -  PutDoc l s -> wrapTHResult $ TH.qPutDoc l s
    
    1939
    -  GetDoc l -> wrapTHResult $ TH.qGetDoc l
    
    1988
    +  -- TODO
    
    1989
    +  -- NewName a -> wrapTHResult $ TH.qNewName a
    
    1990
    +  -- Report b str -> wrapTHResult $ TH.qReport b str
    
    1991
    +  -- LookupName b str -> wrapTHResult $ TH.qLookupName b str
    
    1992
    +  -- Reify n -> wrapTHResult $ TH.qReify n
    
    1993
    +  -- ReifyFixity n -> wrapTHResult $ TH.qReifyFixity n
    
    1994
    +  -- ReifyType n -> wrapTHResult $ TH.qReifyType n
    
    1995
    +  -- ReifyInstances n ts -> wrapTHResult $ TH.qReifyInstances n ts
    
    1996
    +  -- ReifyRoles n -> wrapTHResult $ TH.qReifyRoles n
    
    1997
    +  -- ReifyAnnotations lookup tyrep ->
    
    1998
    +  --   wrapTHResult $ (map B.pack <$> getAnnotationsByTypeRep lookup tyrep)
    
    1999
    +  -- ReifyModule m -> wrapTHResult $ TH.qReifyModule m
    
    2000
    +  -- ReifyConStrictness nm -> wrapTHResult $ TH.qReifyConStrictness nm
    
    2001
    +  -- GetPackageRoot -> wrapTHResult $ TH.qGetPackageRoot
    
    2002
    +  -- AddDependentFile f -> wrapTHResult $ TH.qAddDependentFile f
    
    2003
    +  -- AddDependentDirectory d -> wrapTHResult $ TH.qAddDependentDirectory d
    
    2004
    +  -- AddTempFile s -> wrapTHResult $ TH.qAddTempFile s
    
    2005
    +  -- AddModFinalizer r -> do
    
    2006
    +  --   interp <- hscInterp <$> getTopEnv
    
    2007
    +  --   wrapTHResult $ liftIO (mkFinalizedHValue interp r) >>= addModFinalizerRef
    
    2008
    +  -- AddCorePlugin str -> wrapTHResult $ TH.qAddCorePlugin str
    
    2009
    +  -- AddTopDecls decs -> wrapTHResult $ TH.qAddTopDecls decs
    
    2010
    +  -- AddForeignFilePath lang str -> wrapTHResult $ TH.qAddForeignFilePath lang str
    
    2011
    +  -- IsExtEnabled ext -> wrapTHResult $ TH.qIsExtEnabled ext
    
    2012
    +  -- ExtsEnabled -> wrapTHResult $ TH.qExtsEnabled
    
    2013
    +  -- PutDoc l s -> wrapTHResult $ TH.qPutDoc l s
    
    2014
    +  -- GetDoc l -> wrapTHResult $ TH.qGetDoc l
    
    1940 2015
       FailIfErrs -> wrapTHResult failIfErrsM
    
    1941 2016
       _ -> panic ("handleTHMessage: unexpected message " ++ show msg)
    
    1942 2017
     
    

  • libraries/ghc-internal/src/GHC/Internal/TH/Monad.hs
    ... ... @@ -59,6 +59,7 @@ import GHC.Internal.TH.Syntax
    59 59
     -----------------------------------------------------
    
    60 60
     
    
    61 61
     class (MonadIO m, MonadFail m) => Quasi m where
    
    62
    +  qRunQ :: Q a -> m a
    
    62 63
       -- | Fresh names. See 'newName'.
    
    63 64
       qNewName :: String -> m Name
    
    64 65
     
    
    ... ... @@ -149,6 +150,7 @@ class (MonadIO m, MonadFail m) => Quasi m where
    149 150
     --  type environment, so reification isn't going to
    
    150 151
     --  work.
    
    151 152
     instance Quasi IO where
    
    153
    +  qRunQ (Q m) = m (MetaHandlers {}) -- TODO: create a metahandlers instance which matches the quasi instance, ie, mostly badIO
    
    152 154
       qNewName = newNameIO
    
    153 155
     
    
    154 156
       qReport True  msg = hPutStrLn stderr ("Template Haskell error: " ++ msg)
    
    ... ... @@ -183,6 +185,86 @@ instance Quasi IO where
    183 185
     instance Quote IO where
    
    184 186
       newName = newNameIO
    
    185 187
     
    
    188
    +data MetaHandlers m = MetaHandlers {
    
    189
    +    -- | Fresh names. See 'newName'.
    
    190
    +    mNewName :: String -> m Name
    
    191
    +
    
    192
    +    ------- Error reporting and recovery -------
    
    193
    +    -- | Report an error (True) or warning (False)
    
    194
    +    -- ...but carry on; use 'fail' to stop. See 'report'.
    
    195
    +    , mReport  :: Bool -> String -> m ()
    
    196
    +
    
    197
    +    -- | See 'recover'.
    
    198
    +    , mRecover :: forall a. m a -- ^ the error handler
    
    199
    +            -> m a -- ^ action which may fail
    
    200
    +            -> m a -- ^ Recover from the monadic 'fail'
    
    201
    +
    
    202
    +    ------- Inspect the type-checker's environment -------
    
    203
    +    -- | True <=> type namespace, False <=> value namespace. See 'lookupName'.
    
    204
    +    , mLookupName :: Bool -> String -> m (Maybe Name)
    
    205
    +    -- | See 'reify'.
    
    206
    +    , mReify          :: Name -> m Info
    
    207
    +    -- | See 'reifyFixity'.
    
    208
    +    , mReifyFixity    :: Name -> m (Maybe Fixity)
    
    209
    +    -- | See 'reifyType'.
    
    210
    +    , mReifyType      :: Name -> m Type
    
    211
    +    -- | Is (n tys) an instance? Returns list of matching instance Decs (with
    
    212
    +    -- empty sub-Decs) Works for classes and type functions. See 'reifyInstances'.
    
    213
    +    , mReifyInstances :: Name -> [Type] -> m [Dec]
    
    214
    +    -- | See 'reifyRoles'.
    
    215
    +    , mReifyRoles         :: Name -> m [Role]
    
    216
    +    -- | See 'reifyAnnotations'.
    
    217
    +    , mReifyAnnotations   :: forall a. Data a => AnnLookup -> m [a]
    
    218
    +    -- | See 'reifyModule'.
    
    219
    +    , mReifyModule        :: Module -> m ModuleInfo
    
    220
    +    -- | See 'reifyConStrictness'.
    
    221
    +    , mReifyConStrictness :: Name -> m [DecidedStrictness]
    
    222
    +
    
    223
    +    -- | See 'location'.
    
    224
    +    , mLocation :: m Loc
    
    225
    +
    
    226
    +    -- | See 'getPackageRoot'.
    
    227
    +    , mGetPackageRoot :: m FilePath
    
    228
    +
    
    229
    +    -- | See 'addDependentFile'.
    
    230
    +    , mAddDependentFile :: FilePath -> m ()
    
    231
    +
    
    232
    +    -- | See 'addDependentDirectory'.
    
    233
    +    , mAddDependentDirectory :: FilePath -> m ()
    
    234
    +
    
    235
    +    -- | See 'addTempFile'.
    
    236
    +    , mAddTempFile :: String -> m FilePath
    
    237
    +
    
    238
    +    -- | See 'addTopDecls'.
    
    239
    +    , mAddTopDecls :: [Dec] -> m ()
    
    240
    +
    
    241
    +    -- | See 'addForeignFilePath'.
    
    242
    +    , mAddForeignFilePath :: ForeignSrcLang -> String -> m ()
    
    243
    +
    
    244
    +    -- | See 'addModFinalizer'.
    
    245
    +    , mAddModFinalizer :: Q () -> m ()
    
    246
    +
    
    247
    +    -- | See 'addCorePlugin'.
    
    248
    +    , mAddCorePlugin :: String -> m ()
    
    249
    +
    
    250
    +    -- | See 'getQ'.
    
    251
    +    , mGetQ :: forall a. Typeable a => m (Maybe a)
    
    252
    +
    
    253
    +    -- | See 'putQ'.
    
    254
    +    , mPutQ :: forall a. Typeable a => a -> m ()
    
    255
    +
    
    256
    +    -- | See 'isExtEnabled'.
    
    257
    +    , mIsExtEnabled :: Extension -> m Bool
    
    258
    +    -- | See 'extsEnabled'.
    
    259
    +    , mExtsEnabled :: m [Extension]
    
    260
    +
    
    261
    +    -- | See 'putDoc'.
    
    262
    +    , mPutDoc :: DocLoc -> String -> m ()
    
    263
    +    -- | See 'getDoc'.
    
    264
    +    , mGetDoc :: DocLoc -> m (Maybe String)
    
    265
    +  }
    
    266
    +
    
    267
    +
    
    186 268
     newNameIO :: String -> IO Name
    
    187 269
     newNameIO s = do { n <- atomicModifyIORef' counter (\x -> (x + 1, x))
    
    188 270
                      ; pure (mkNameU s n) }
    
    ... ... @@ -213,7 +295,7 @@ counter = unsafePerformIO (newIORef 0)
    213 295
     -- inversion](https://en.wikipedia.org/wiki/Dependency_inversion_principle),
    
    214 296
     -- providing an abstract interface for the user which is later concretely
    
    215 297
     -- fufilled by an concrete 'Quasi' instance, internal to GHC.
    
    216
    -newtype Q a = Q { unQ :: forall m. Quasi m => m a }
    
    298
    +newtype Q a = Q { unQ :: MetaHandlers IO -> IO a }
    
    217 299
     
    
    218 300
     -- | \"Runs\" the 'Q' monad. Normal users of Template Haskell
    
    219 301
     -- should not need this function, as the splice brackets @$( ... )@
    
    ... ... @@ -227,22 +309,22 @@ newtype Q a = Q { unQ :: forall m. Quasi m => m a }
    227 309
     -- simply fail at runtime. Indeed, the only operations guaranteed to succeed
    
    228 310
     -- are 'newName', 'runIO', 'reportError' and 'reportWarning'.
    
    229 311
     runQ :: Quasi m => Q a -> m a
    
    230
    -runQ (Q m) = m
    
    312
    +runQ = qRunQ
    
    231 313
     
    
    232 314
     instance Monad Q where
    
    233
    -  Q m >>= k  = Q (m >>= \x -> unQ (k x))
    
    315
    +  Q m >>= k  = Q $ \h -> (m h >>= \x -> unQ (k x) h)
    
    234 316
       (>>) = (*>)
    
    235 317
     
    
    236 318
     instance MonadFail Q where
    
    237
    -  fail s     = report True s >> Q (fail "Q monad failure")
    
    319
    +  fail s     = report True s >> Q (\h -> fail "Q monad failure")
    
    238 320
     
    
    239 321
     instance Functor Q where
    
    240
    -  fmap f (Q x) = Q (fmap f x)
    
    322
    +  fmap f (Q x) = Q $ \h -> fmap f (x h)
    
    241 323
     
    
    242 324
     instance Applicative Q where
    
    243
    -  pure x = Q (pure x)
    
    244
    -  Q f <*> Q x = Q (f <*> x)
    
    245
    -  Q m *> Q n = Q (m *> n)
    
    325
    +  pure x = Q $ \h -> (pure x)
    
    326
    +  Q f <*> Q x = Q $ \h -> (f h <*> x h)
    
    327
    +  Q m *> Q n = Q $ \h ->(m h *> n h)
    
    246 328
     
    
    247 329
     -- | @since 2.17.0.0
    
    248 330
     instance Semigroup a => Semigroup (Q a) where
    
    ... ... @@ -312,7 +394,7 @@ class Monad m => Quote m where
    312 394
       newName :: String -> m Name
    
    313 395
     
    
    314 396
     instance Quote Q where
    
    315
    -  newName s = Q (qNewName s)
    
    397
    +  newName s = Q $ \h -> mNewName h s
    
    316 398
     
    
    317 399
     -----------------------------------------------------
    
    318 400
     --
    
    ... ... @@ -510,7 +592,7 @@ joinCode = flip bindCode id
    510 592
     -- | Report an error (True) or warning (False),
    
    511 593
     -- but carry on; use 'fail' to stop.
    
    512 594
     report  :: Bool -> String -> Q ()
    
    513
    -report b s = Q (qReport b s)
    
    595
    +report b s = Q $ \h -> mReport h b s
    
    514 596
     {-# DEPRECATED report "Use reportError or reportWarning instead" #-} -- deprecated in 7.6
    
    515 597
     
    
    516 598
     -- | Report an error to the user, but allow the current splice's computation to carry on. To abort the computation, use 'fail'.
    
    ... ... @@ -525,20 +607,20 @@ reportWarning = report False
    525 607
     recover :: Q a -- ^ handler to invoke on failure
    
    526 608
             -> Q a -- ^ computation to run
    
    527 609
             -> Q a
    
    528
    -recover (Q r) (Q m) = Q (qRecover r m)
    
    610
    +recover (Q r) (Q m) = Q $ \h -> mRecover h (r h) (m h)
    
    529 611
     
    
    530 612
     -- We don't export lookupName; the Bool isn't a great API
    
    531 613
     -- Instead we export lookupTypeName, lookupValueName
    
    532 614
     lookupName :: Bool -> String -> Q (Maybe Name)
    
    533
    -lookupName ns s = Q (qLookupName ns s)
    
    615
    +lookupName ns s = Q $ \h -> (mLookupName h ns s)
    
    534 616
     
    
    535 617
     -- | Look up the given name in the (type namespace of the) current splice's scope. See "Language.Haskell.TH.Syntax#namelookup" for more details.
    
    536 618
     lookupTypeName :: String -> Q (Maybe Name)
    
    537
    -lookupTypeName  s = Q (qLookupName True s)
    
    619
    +lookupTypeName  s = Q $ \h -> (mLookupName h True s)
    
    538 620
     
    
    539 621
     -- | Look up the given name in the (value namespace of the) current splice's scope. See "Language.Haskell.TH.Syntax#namelookup" for more details.
    
    540 622
     lookupValueName :: String -> Q (Maybe Name)
    
    541
    -lookupValueName s = Q (qLookupName False s)
    
    623
    +lookupValueName s = Q $ \h -> (mLookupName h False s)
    
    542 624
     
    
    543 625
     {-
    
    544 626
     Note [Name lookup]
    
    ... ... @@ -613,7 +695,7 @@ To ensure we get information about @D@-the-value, use 'lookupValueName':
    613 695
     and to get information about @D@-the-type, use 'lookupTypeName'.
    
    614 696
     -}
    
    615 697
     reify :: Name -> Q Info
    
    616
    -reify v = Q (qReify v)
    
    698
    +reify v = Q $ \h -> (mReify h v)
    
    617 699
     
    
    618 700
     {- | @reifyFixity nm@ attempts to find a fixity declaration for @nm@. For
    
    619 701
     example, if the function @foo@ has the fixity declaration @infixr 7 foo@, then
    
    ... ... @@ -622,7 +704,7 @@ example, if the function @foo@ has the fixity declaration @infixr 7 foo@, then
    622 704
     'Nothing', so you may assume @bar@ has 'defaultFixity'.
    
    623 705
     -}
    
    624 706
     reifyFixity :: Name -> Q (Maybe Fixity)
    
    625
    -reifyFixity nm = Q (qReifyFixity nm)
    
    707
    +reifyFixity nm = Q $ \h ->(mReifyFixity h nm)
    
    626 708
     
    
    627 709
     {- | @reifyType nm@ attempts to find the type or kind of @nm@. For example,
    
    628 710
     @reifyType 'not@   returns @Bool -> Bool@, and
    
    ... ... @@ -630,7 +712,7 @@ reifyFixity nm = Q (qReifyFixity nm)
    630 712
     This works even if there's no explicit signature and the type or kind is inferred.
    
    631 713
     -}
    
    632 714
     reifyType :: Name -> Q Type
    
    633
    -reifyType nm = Q (qReifyType nm)
    
    715
    +reifyType nm = Q $ \h ->(mReifyType h nm)
    
    634 716
     
    
    635 717
     {- | Template Haskell is capable of reifying information about types and
    
    636 718
     terms defined in previous declaration groups. Top-level declaration splices break up
    
    ... ... @@ -722,7 +804,7 @@ has some discussion around this.
    722 804
     
    
    723 805
     -}
    
    724 806
     reifyInstances :: Name -> [Type] -> Q [InstanceDec]
    
    725
    -reifyInstances cls tys = Q (qReifyInstances cls tys)
    
    807
    +reifyInstances cls tys = Q $ \h ->(mReifyInstances h cls tys)
    
    726 808
     
    
    727 809
     {- | @reifyRoles nm@ returns the list of roles associated with the parameters
    
    728 810
     (both visible and invisible) of
    
    ... ... @@ -741,20 +823,20 @@ and @reifyRoles Proxy@, we will get @['NominalR', 'PhantomR']@. The 'NominalR' i
    741 823
     the role of the invisible @k@ parameter. Kind parameters are always nominal.
    
    742 824
     -}
    
    743 825
     reifyRoles :: Name -> Q [Role]
    
    744
    -reifyRoles nm = Q (qReifyRoles nm)
    
    826
    +reifyRoles nm = Q $ \h -> (mReifyRoles h nm)
    
    745 827
     
    
    746 828
     -- | @reifyAnnotations target@ returns the list of annotations
    
    747 829
     -- associated with @target@.  Only the annotations that are
    
    748 830
     -- appropriately typed is returned.  So if you have @Int@ and @String@
    
    749 831
     -- annotations for the same target, you have to call this function twice.
    
    750 832
     reifyAnnotations :: Data a => AnnLookup -> Q [a]
    
    751
    -reifyAnnotations an = Q (qReifyAnnotations an)
    
    833
    +reifyAnnotations an = Q $ \h -> (mReifyAnnotations h an)
    
    752 834
     
    
    753 835
     -- | @reifyModule mod@ looks up information about module @mod@.  To
    
    754 836
     -- look up the current module, call this function with the return
    
    755 837
     -- value of 'Language.Haskell.TH.Lib.thisModule'.
    
    756 838
     reifyModule :: Module -> Q ModuleInfo
    
    757
    -reifyModule m = Q (qReifyModule m)
    
    839
    +reifyModule m = Q $ \h -> (mReifyModule h m)
    
    758 840
     
    
    759 841
     -- | @reifyConStrictness nm@ looks up the strictness information for the fields
    
    760 842
     -- of the constructor with the name @nm@. Note that the strictness information
    
    ... ... @@ -769,7 +851,7 @@ reifyModule m = Q (qReifyModule m)
    769 851
     -- circumstances, but it would return @['DecidedStrict', DecidedStrict]@ if the
    
    770 852
     -- @-XStrictData@ language extension was enabled.
    
    771 853
     reifyConStrictness :: Name -> Q [DecidedStrictness]
    
    772
    -reifyConStrictness n = Q (qReifyConStrictness n)
    
    854
    +reifyConStrictness n = Q $ \h ->(mReifyConStrictness h n)
    
    773 855
     
    
    774 856
     -- | Is the list of instances returned by 'reifyInstances' nonempty?
    
    775 857
     --
    
    ... ... @@ -782,7 +864,7 @@ isInstance nm tys = do { decs <- reifyInstances nm tys
    782 864
     
    
    783 865
     -- | The location at which this computation is spliced.
    
    784 866
     location :: Q Loc
    
    785
    -location = Q qLocation
    
    867
    +location = Q mLocation
    
    786 868
     
    
    787 869
     -- |The 'runIO' function lets you run an I\/O computation in the 'Q' monad.
    
    788 870
     -- Take care: you are guaranteed the ordering of calls to 'runIO' within
    
    ... ... @@ -792,7 +874,7 @@ location = Q qLocation
    792 874
     -- necessarily flushed when the compiler finishes running, so you should
    
    793 875
     -- flush them yourself.
    
    794 876
     runIO :: IO a -> Q a
    
    795
    -runIO m = Q (qRunIO m)
    
    877
    +runIO m = Q $ \h -> m
    
    796 878
     
    
    797 879
     -- | Get the package root for the current package which is being compiled.
    
    798 880
     -- This can be set explicitly with the -package-root flag but is normally
    
    ... ... @@ -804,7 +886,7 @@ runIO m = Q (qRunIO m)
    804 886
     -- change directory when compiling files but instead set the -package-root flag
    
    805 887
     -- appropriately.
    
    806 888
     getPackageRoot :: Q FilePath
    
    807
    -getPackageRoot = Q qGetPackageRoot
    
    889
    +getPackageRoot = Q mGetPackageRoot
    
    808 890
     
    
    809 891
     -- | Record external directories that runIO is using (dependent upon).
    
    810 892
     -- The compiler can then recognize that it should re-compile the Haskell file
    
    ... ... @@ -823,7 +905,7 @@ getPackageRoot = Q qGetPackageRoot
    823 905
     --   * The state of the directory is read at the interface generation time,
    
    824 906
     --     not at the time of the function call.
    
    825 907
     addDependentDirectory :: FilePath -> Q ()
    
    826
    -addDependentDirectory dp = Q (qAddDependentDirectory dp)
    
    908
    +addDependentDirectory dp = Q $ \h -> (mAddDependentDirectory h dp)
    
    827 909
     
    
    828 910
     -- | Record external files that runIO is using (dependent upon).
    
    829 911
     -- The compiler can then recognize that it should re-compile the Haskell file
    
    ... ... @@ -837,17 +919,17 @@ addDependentDirectory dp = Q (qAddDependentDirectory dp)
    837 919
     --
    
    838 920
     --   * The dependency is based on file content, not a modification time
    
    839 921
     addDependentFile :: FilePath -> Q ()
    
    840
    -addDependentFile fp = Q (qAddDependentFile fp)
    
    922
    +addDependentFile fp = Q $ \h -> (mAddDependentFile h fp)
    
    841 923
     
    
    842 924
     -- | Obtain a temporary file path with the given suffix. The compiler will
    
    843 925
     -- delete this file after compilation.
    
    844 926
     addTempFile :: String -> Q FilePath
    
    845
    -addTempFile suffix = Q (qAddTempFile suffix)
    
    927
    +addTempFile suffix = Q $ \h -> (mAddTempFile h suffix)
    
    846 928
     
    
    847 929
     -- | Add additional top-level declarations. The added declarations will be type
    
    848 930
     -- checked along with the current declaration group.
    
    849 931
     addTopDecls :: [Dec] -> Q ()
    
    850
    -addTopDecls ds = Q (qAddTopDecls ds)
    
    932
    +addTopDecls ds = Q $ \h ->(mAddTopDecls h ds)
    
    851 933
     
    
    852 934
     -- | Same as 'addForeignSource', but expects to receive a path pointing to the
    
    853 935
     -- foreign file instead of a 'String' of its contents. Consider using this in
    
    ... ... @@ -856,7 +938,7 @@ addTopDecls ds = Q (qAddTopDecls ds)
    856 938
     -- This is a good alternative to 'addForeignSource' when you are trying to
    
    857 939
     -- directly link in an object file.
    
    858 940
     addForeignFilePath :: ForeignSrcLang -> FilePath -> Q ()
    
    859
    -addForeignFilePath lang fp = Q (qAddForeignFilePath lang fp)
    
    941
    +addForeignFilePath lang fp = Q $ \h ->(mAddForeignFilePath h lang fp)
    
    860 942
     
    
    861 943
     -- | Add a finalizer that will run in the Q monad after the current module has
    
    862 944
     -- been type checked. This only makes sense when run within a top-level splice.
    
    ... ... @@ -865,7 +947,7 @@ addForeignFilePath lang fp = Q (qAddForeignFilePath lang fp)
    865 947
     -- 'reify' is able to find the local definitions when executed inside the
    
    866 948
     -- finalizer.
    
    867 949
     addModFinalizer :: Q () -> Q ()
    
    868
    -addModFinalizer act = Q (qAddModFinalizer (unQ act))
    
    950
    +addModFinalizer act = Q $ \h -> mAddModFinalizer h act
    
    869 951
     
    
    870 952
     -- | Adds a core plugin to the compilation pipeline.
    
    871 953
     --
    
    ... ... @@ -875,7 +957,7 @@ addModFinalizer act = Q (qAddModFinalizer (unQ act))
    875 957
     -- to tell the compiler that we needed to compile first a plugin module in the
    
    876 958
     -- current package.
    
    877 959
     addCorePlugin :: String -> Q ()
    
    878
    -addCorePlugin plugin = Q (qAddCorePlugin plugin)
    
    960
    +addCorePlugin plugin = Q $ \h -> mAddCorePlugin h plugin
    
    879 961
     
    
    880 962
     -- | Get state from the 'Q' monad. The state maintained by 'Q' is isomorphic to
    
    881 963
     -- a type-indexed finite map. That is,
    
    ... ... @@ -889,20 +971,20 @@ addCorePlugin plugin = Q (qAddCorePlugin plugin)
    889 971
     -- Note that the state is local to the Haskell module in which the Template
    
    890 972
     -- Haskell expression is executed.
    
    891 973
     getQ :: Typeable a => Q (Maybe a)
    
    892
    -getQ = Q qGetQ
    
    974
    +getQ = Q mGetQ
    
    893 975
     
    
    894 976
     -- | Replace the state in the 'Q' monad. Note that the state is local to the
    
    895 977
     -- Haskell module in which the Template Haskell expression is executed.
    
    896 978
     putQ :: Typeable a => a -> Q ()
    
    897
    -putQ x = Q (qPutQ x)
    
    979
    +putQ x = Q $ \h -> mPutQ h x
    
    898 980
     
    
    899 981
     -- | Determine whether the given language extension is enabled in the 'Q' monad.
    
    900 982
     isExtEnabled :: Extension -> Q Bool
    
    901
    -isExtEnabled ext = Q (qIsExtEnabled ext)
    
    983
    +isExtEnabled ext = Q $ \h -> mIsExtEnabled h ext
    
    902 984
     
    
    903 985
     -- | List all enabled language extensions.
    
    904 986
     extsEnabled :: Q [Extension]
    
    905
    -extsEnabled = Q qExtsEnabled
    
    987
    +extsEnabled = Q $ mExtsEnabled
    
    906 988
     
    
    907 989
     -- | Add Haddock documentation to the specified location. This will overwrite
    
    908 990
     -- any documentation at the location if it already exists. This will reify the
    
    ... ... @@ -921,19 +1003,20 @@ extsEnabled = Q qExtsEnabled
    921 1003
     -- Adding documentation to anything outside of the current module will cause an
    
    922 1004
     -- error.
    
    923 1005
     putDoc :: DocLoc -> String -> Q ()
    
    924
    -putDoc t s = Q (qPutDoc t s)
    
    1006
    +putDoc t s = Q $ \h -> mPutDoc h t s
    
    925 1007
     
    
    926 1008
     -- | Retrieves the Haddock documentation at the specified location, if one
    
    927 1009
     -- exists.
    
    928 1010
     -- It can be used to read documentation on things defined outside of the current
    
    929 1011
     -- module, provided that those modules were compiled with the @-haddock@ flag.
    
    930 1012
     getDoc :: DocLoc -> Q (Maybe String)
    
    931
    -getDoc n = Q (qGetDoc n)
    
    1013
    +getDoc n = Q $ \h ->mGetDoc h n
    
    932 1014
     
    
    933 1015
     instance MonadIO Q where
    
    934 1016
       liftIO = runIO
    
    935 1017
     
    
    936 1018
     instance Quasi Q where
    
    1019
    +  qRunQ               = id
    
    937 1020
       qNewName            = newName
    
    938 1021
       qReport             = report
    
    939 1022
       qRecover            = recover