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

Commits:

3 changed files:

Changes:

  • compiler/GHC/Tc/Gen/Splice.hs
    ... ... @@ -1140,7 +1140,7 @@ convertAnnotationWrapper fhv = do
    1140 1140
     -}
    
    1141 1141
     
    
    1142 1142
     runQuasi :: TH.Q a -> TcM a
    
    1143
    -runQuasi (TH.Q act) = unliftIOEnv $ \runInIO -> liftIO $ act runInIO metaHandlersTcM
    
    1143
    +runQuasi (TH.Q act) = unliftIOEnv $ \runInIO -> liftIO $ act (metaHandlersTcM runInIO)
    
    1144 1144
     
    
    1145 1145
     runRemoteModFinalizers :: ThModFinalizers -> TcM ()
    
    1146 1146
     runRemoteModFinalizers (ThModFinalizers finRefs) = do
    
    ... ... @@ -1557,71 +1557,71 @@ location = do { m <- getModule
    1557 1557
                                     , TH.loc_start = (srcSpanStartLine r, srcSpanStartCol r)
    
    1558 1558
                                     , TH.loc_end = (srcSpanEndLine   r, srcSpanEndCol   r) }) }
    
    1559 1559
     
    
    1560
    -metaHandlersTcM :: TH.MetaHandlers TcM
    
    1561
    -metaHandlersTcM = TH.MetaHandlers {
    
    1562
    -    mFail = fail
    
    1563
    -    , mNewName = \s -> do { u <- newUnique
    
    1560
    +metaHandlersTcM :: (forall x. TcM x -> IO x) -> TH.MetaHandlers IO
    
    1561
    +metaHandlersTcM runInIO = TH.MetaHandlers {
    
    1562
    +    mFail = \s -> runInIO $ fail s
    
    1563
    +    , mNewName = \s -> runInIO $ do { u <- newUnique
    
    1564 1564
                           ; let i = toInteger (getKey u)
    
    1565 1565
                           ; return (TH.mkNameU s i) }
    
    1566 1566
     
    
    1567 1567
         -- 'msg' is forced to ensure exceptions don't escape,
    
    1568 1568
         -- see Note [Exceptions in TH]
    
    1569
    -    , mReport = report
    
    1570
    -
    
    1571
    -    , mLocation = location
    
    1572
    -
    
    1573
    -    , mLookupName       = lookupName
    
    1574
    -    , mReify            = reify
    
    1575
    -    , mReifyFixity      = \nm -> lookupThName nm >>= reifyFixity
    
    1576
    -    , mReifyType        = reifyTypeOfThing
    
    1577
    -    , mReifyInstances   = reifyInstances
    
    1578
    -    , mReifyRoles       = reifyRoles
    
    1579
    -    , mReifyAnnotations = reifyAnnotations
    
    1580
    -    , mReifyModule      = reifyModule
    
    1581
    -    , mReifyConStrictness = \nm -> do { nm' <- lookupThName nm
    
    1569
    +    , mReport = fmap runInIO . report
    
    1570
    +
    
    1571
    +    , mLocation = runInIO location
    
    1572
    +
    
    1573
    +    , mLookupName       = fmap runInIO . lookupName
    
    1574
    +    , mReify            = runInIO . reify
    
    1575
    +    , mReifyFixity      = \nm -> runInIO $ lookupThName nm >>= reifyFixity
    
    1576
    +    , mReifyType        = runInIO . reifyTypeOfThing
    
    1577
    +    , mReifyInstances   = fmap runInIO . reifyInstances
    
    1578
    +    , mReifyRoles       = runInIO . reifyRoles
    
    1579
    +    , mReifyAnnotations = runInIO . reifyAnnotations
    
    1580
    +    , mReifyModule      = runInIO . reifyModule
    
    1581
    +    , mReifyConStrictness = \nm -> runInIO $ do { nm' <- lookupThName nm
    
    1582 1582
                                           ; dc  <- tcLookupDataCon nm'
    
    1583 1583
                                           ; let bangs = dataConImplBangs dc
    
    1584 1584
                                           ; return (map reifyDecidedStrictness bangs) }
    
    1585 1585
     
    
    1586
    -          -- For qRecover, discard error messages if
    
    1587
    -          -- the recovery action is chosen.  Otherwise
    
    1588
    -          -- we'll only fail higher up.
    
    1589
    -          -- NB: extremely subtle!!! TODO: write up note
    
    1590
    -          -- tryTcDiscardingErrs manipulates the reader env so we need to be careful we don't sneak in the outside env
    
    1591
    -    , mRecover = \recover main -> tryTcDiscardingErrs (runQuasi recover) (runQuasi main)
    
    1586
    +    --       -- For qRecover, discard error messages if
    
    1587
    +    --       -- the recovery action is chosen.  Otherwise
    
    1588
    +    --       -- we'll only fail higher up.
    
    1589
    +    --       -- NB: extremely subtle!!! TODO: write up note
    
    1590
    +    --       -- tryTcDiscardingErrs manipulates the reader env so we need to be careful we don't sneak in the outside env
    
    1591
    +    , mRecover = \recover main -> runInIO $ tryTcDiscardingErrs (runQuasi recover) (runQuasi main)
    
    1592 1592
     
    
    1593
    -    , mGetPackageRoot = do
    
    1593
    +    , mGetPackageRoot = runInIO $ do
    
    1594 1594
             dflags <- getDynFlags
    
    1595 1595
             return $ fromMaybe "." (workingDirectory dflags)
    
    1596 1596
     
    
    1597
    -    , mAddDependentFile = \fp -> do
    
    1597
    +    , mAddDependentFile = \fp -> runInIO $ do
    
    1598 1598
             ref <- fmap tcg_dependent_files getGblEnv
    
    1599 1599
             dep_files <- readTcRef ref
    
    1600 1600
             writeTcRef ref (fp:dep_files)
    
    1601 1601
     
    
    1602
    -    , mAddDependentDirectory = \dp -> do
    
    1602
    +    , mAddDependentDirectory = \dp -> runInIO $ do
    
    1603 1603
             ref <- fmap tcg_dependent_dirs getGblEnv
    
    1604 1604
             dep_dirs <- readTcRef ref
    
    1605 1605
             writeTcRef ref (dp:dep_dirs)
    
    1606 1606
     
    
    1607
    -    , mAddTempFile = \suffix -> do
    
    1607
    +    , mAddTempFile = \suffix -> runInIO $ do
    
    1608 1608
             dflags <- getDynFlags
    
    1609 1609
             logger <- getLogger
    
    1610 1610
             tmpfs  <- hsc_tmpfs <$> getTopEnv
    
    1611 1611
             liftIO $ newTempName logger tmpfs (tmpDir dflags) TFL_GhcSession suffix
    
    1612 1612
     
    
    1613
    -    , mAddTopDecls = addTopDecls
    
    1613
    +    , mAddTopDecls = runInIO . addTopDecls
    
    1614 1614
     
    
    1615
    -    , mAddForeignFilePath = \lang fp -> do
    
    1615
    +    , mAddForeignFilePath = \lang fp -> runInIO $ do
    
    1616 1616
             var <- fmap tcg_th_foreign_files getGblEnv
    
    1617 1617
             updTcRef var ((lang, fp) :)
    
    1618 1618
     
    
    1619
    -    , mAddModFinalizer = \fin -> do
    
    1619
    +    , mAddModFinalizer = \fin -> runInIO $ do
    
    1620 1620
             r <- liftIO $ mkRemoteRef fin
    
    1621 1621
             fref <- liftIO $ mkForeignRef r (freeRemoteRef r)
    
    1622 1622
             addModFinalizerRef fref
    
    1623 1623
     
    
    1624
    -    , mAddCorePlugin = \plugin -> do
    
    1624
    +    , mAddCorePlugin = \plugin -> runInIO $ do
    
    1625 1625
             hsc_env <- getTopEnv
    
    1626 1626
             let fc        = hsc_FC hsc_env
    
    1627 1627
             let home_unit = hsc_home_unit hsc_env
    
    ... ... @@ -1636,20 +1636,20 @@ metaHandlersTcM = TH.MetaHandlers {
    1636 1636
             th_coreplugins_var <- tcg_th_coreplugins <$> getGblEnv
    
    1637 1637
             updTcRef th_coreplugins_var (plugin:)
    
    1638 1638
     
    
    1639
    -    , mGetQ = getQ
    
    1639
    +    , mGetQ = runInIO getQ
    
    1640 1640
     
    
    1641
    -    , mPutQ = \x -> do
    
    1641
    +    , mPutQ = \x -> runInIO $ do
    
    1642 1642
             th_state_var <- fmap tcg_th_state getGblEnv
    
    1643 1643
             updTcRef th_state_var (\m -> Map.insert (typeOf x) (toDyn x) m)
    
    1644 1644
     
    
    1645
    -    , mIsExtEnabled = xoptM
    
    1645
    +    , mIsExtEnabled = runInIO . xoptM
    
    1646 1646
     
    
    1647
    -    , mExtsEnabled =
    
    1647
    +    , mExtsEnabled = runInIO $
    
    1648 1648
             EnumSet.toList . extensionFlags . hsc_dflags <$> getTopEnv
    
    1649 1649
     
    
    1650
    -    , mPutDoc = putDoc
    
    1650
    +    , mPutDoc = fmap runInIO . putDoc
    
    1651 1651
     
    
    1652
    -    , mGetDoc = getDoc
    
    1652
    +    , mGetDoc = runInIO . getDoc
    
    1653 1653
       }
    
    1654 1654
     
    
    1655 1655
     -- | Looks up documentation for a declaration in first the current module,
    

  • libraries/ghc-internal/src/GHC/Internal/TH/Monad.hs
    ... ... @@ -150,7 +150,7 @@ class (MonadIO m, MonadFail m) => Quasi m where
    150 150
     --  type environment, so reification isn't going to
    
    151 151
     --  work.
    
    152 152
     instance Quasi IO where
    
    153
    -  qRunQ (Q m) = m id metaHandlersIO
    
    153
    +  qRunQ (Q m) = m metaHandlersIO
    
    154 154
       qNewName = newNameIO
    
    155 155
     
    
    156 156
       qReport True  msg = hPutStrLn stderr ("Template Haskell error: " ++ msg)
    
    ... ... @@ -332,7 +332,7 @@ counter = unsafePerformIO (newIORef 0)
    332 332
     -- inversion](https://en.wikipedia.org/wiki/Dependency_inversion_principle),
    
    333 333
     -- providing an abstract interface for the user which is later concretely
    
    334 334
     -- fufilled by an concrete 'Quasi' instance, internal to GHC.
    
    335
    -newtype Q a = Q { unQ :: forall m. (forall x. m x -> IO x) -> MetaHandlers m -> IO a }
    
    335
    +newtype Q a = Q { unQ :: MetaHandlers IO -> IO a }
    
    336 336
     
    
    337 337
     -- | \"Runs\" the 'Q' monad. Normal users of Template Haskell
    
    338 338
     -- should not need this function, as the splice brackets @$( ... )@
    
    ... ... @@ -349,19 +349,19 @@ runQ :: Quasi m => Q a -> m a
    349 349
     runQ = qRunQ
    
    350 350
     
    
    351 351
     instance Monad Q where
    
    352
    -  Q m >>= k  = Q $ \r h -> (m r h >>= \x -> unQ (k x) r h)
    
    352
    +  Q m >>= k  = Q $ \h -> (m h >>= \x -> unQ (k x) h)
    
    353 353
       (>>) = (*>)
    
    354 354
     
    
    355 355
     instance MonadFail Q where
    
    356
    -  fail s     = report True s >> Q (\r h -> r $ mFail h "Q monad failure")
    
    356
    +  fail s     = report True s >> Q (\h ->  mFail h "Q monad failure")
    
    357 357
     
    
    358 358
     instance Functor Q where
    
    359
    -  fmap f (Q x) = Q $ \r h -> fmap f (x r h)
    
    359
    +  fmap f (Q x) = Q $ \h -> fmap f (x h)
    
    360 360
     
    
    361 361
     instance Applicative Q where
    
    362
    -  pure x = Q $ \_ _ -> pure x
    
    363
    -  Q f <*> Q x = Q $ \r h -> (f r h <*> x r h)
    
    364
    -  Q m *> Q n = Q $ \r h -> (m r h *> n r h)
    
    362
    +  pure x = Q $ \_ -> pure x
    
    363
    +  Q f <*> Q x = Q $ \h -> (f h <*> x h)
    
    364
    +  Q m *> Q n = Q $ \h -> (m h *> n h)
    
    365 365
     
    
    366 366
     -- | @since 2.17.0.0
    
    367 367
     instance Semigroup a => Semigroup (Q a) where
    
    ... ... @@ -431,13 +431,13 @@ class Monad m => Quote m where
    431 431
       newName :: String -> m Name
    
    432 432
     
    
    433 433
     runHandler :: (forall m. MetaHandlers m -> m a) -> Q a
    
    434
    -runHandler op = Q $ \r h -> r (op h)
    
    434
    +runHandler op = Q $ \h -> (op h)
    
    435 435
     
    
    436 436
     runHandler1 :: (forall m. MetaHandlers m -> a -> m b) -> a -> Q b
    
    437
    -runHandler1 op = \x -> Q $ \r h -> r (op h x)
    
    437
    +runHandler1 op = \x -> Q $ \h -> (op h x)
    
    438 438
     
    
    439 439
     runHandler2 :: (forall m. MetaHandlers m -> a -> b -> m c) -> a -> b -> Q c
    
    440
    -runHandler2 op = \x y -> Q $ \r h -> r (op h x y)
    
    440
    +runHandler2 op = \x y -> Q $ \h -> (op h x y)
    
    441 441
     
    
    442 442
     instance Quote Q where
    
    443 443
       newName = runHandler1 mNewName
    
    ... ... @@ -653,7 +653,7 @@ reportWarning = report False
    653 653
     recover :: Q a -- ^ handler to invoke on failure
    
    654 654
             -> Q a -- ^ computation to run
    
    655 655
             -> Q a
    
    656
    -recover rec main = Q $ \r h -> r $ mRecover h rec main
    
    656
    +recover rec main = Q $ \h -> mRecover h rec main
    
    657 657
     
    
    658 658
     -- We don't export lookupName; the Bool isn't a great API
    
    659 659
     -- Instead we export lookupTypeName, lookupValueName
    
    ... ... @@ -920,7 +920,7 @@ location = runHandler mLocation
    920 920
     -- necessarily flushed when the compiler finishes running, so you should
    
    921 921
     -- flush them yourself.
    
    922 922
     runIO :: IO a -> Q a
    
    923
    -runIO m = Q $ \_ _ -> m
    
    923
    +runIO m = Q $ \_ -> m
    
    924 924
     
    
    925 925
     -- | Get the package root for the current package which is being compiled.
    
    926 926
     -- This can be set explicitly with the -package-root flag but is normally
    

  • libraries/ghci/GHCi/TH.hs
    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
     -- |
    
    ... ... @@ -174,18 +174,19 @@ reifyAnnotations lookup =
    174 174
         where typerep = typeOf (undefined :: a)
    
    175 175
     
    
    176 176
     runQinGHCiQ :: TH.Q a -> GHCiQ a
    
    177
    -runQinGHCiQ (TH.Q m) = GHCiQ $ \sRef -> m (runInIO sRef) metaHandlersGHCiQ
    
    177
    +runQinGHCiQ (TH.Q m) = GHCiQ $ \sRef -> m (metaHandlersGHCiQ (runInIO sRef))
    
    178 178
       where
    
    179 179
         runInIO :: IORef QState -> GHCiQ a -> IO a
    
    180 180
         runInIO sRef (GHCiQ m) = m sRef
    
    181 181
     
    
    182
    -metaHandlersGHCiQ = TH.MetaHandlers {
    
    183
    -    mFail = fail
    
    184
    -  , mNewName = \str -> ghcCmd (NewName str)
    
    185
    -  , mReport = \isError msg -> ghcCmd (Report isError msg)
    
    182
    +metaHandlersGHCiQ :: (forall x. GHCiQ x -> IO x) -> TH.MetaHandlers IO
    
    183
    +metaHandlersGHCiQ runInIO = TH.MetaHandlers {
    
    184
    +    mFail = runInIO . fail
    
    185
    +  , mNewName = \str -> runInIO $ ghcCmd (NewName str)
    
    186
    +  , mReport = \isError msg -> runInIO $ ghcCmd (Report isError msg)
    
    186 187
     
    
    187 188
       -- See Note [TH recover with -fexternal-interpreter] in GHC.Tc.Gen.Splice
    
    188
    -  , mRecover = \h a -> GHCiQ $ \sRef -> mask $ \unmask -> do
    
    189
    +  , mRecover = \h a -> runInIO $ GHCiQ $ \sRef -> mask $ \unmask -> do
    
    189 190
           s <- readIORef sRef
    
    190 191
           remoteTHCall (qsPipe s) StartRecover
    
    191 192
           e <- try $ unmask $ runGHCiQ (runQinGHCiQ a <* ghcCmd FailIfErrs) sRef
    
    ... ... @@ -195,37 +196,37 @@ metaHandlersGHCiQ = TH.MetaHandlers {
    195 196
               -- in case of error, restore the state to the start of the `recover` block.
    
    196 197
               newIORef s >>= runGHCiQ (runQinGHCiQ h)
    
    197 198
             Right r -> return r
    
    198
    -  , mLookupName = \isType occ -> ghcCmd (LookupName isType occ)
    
    199
    -  , mReify = \name -> ghcCmd (Reify name)
    
    200
    -  , mReifyFixity = \name -> ghcCmd (ReifyFixity name)
    
    201
    -  , mReifyType = \name -> ghcCmd (ReifyType name)
    
    202
    -  , mReifyInstances = \name tys -> ghcCmd (ReifyInstances name tys)
    
    203
    -  , mReifyRoles = \name -> ghcCmd (ReifyRoles name)
    
    204
    -
    
    205
    -  , mReifyAnnotations = reifyAnnotations
    
    206
    -  , mReifyModule = \m -> ghcCmd (ReifyModule m)
    
    207
    -  , mReifyConStrictness = \name -> ghcCmd (ReifyConStrictness name)
    
    208
    -  , mLocation = fromMaybe noLoc . qsLocation <$> getState
    
    209
    -  , mGetPackageRoot = ghcCmd GetPackageRoot
    
    210
    -  , mAddDependentFile = \file -> ghcCmd (AddDependentFile file)
    
    211
    -  , mAddDependentDirectory = \dir -> ghcCmd (AddDependentDirectory dir)
    
    212
    -  , mAddTempFile = \suffix -> ghcCmd (AddTempFile suffix)
    
    213
    -  , mAddTopDecls = \decls -> ghcCmd (AddTopDecls decls)
    
    214
    -  , mAddForeignFilePath = \lang fp -> ghcCmd (AddForeignFilePath lang fp)
    
    215
    -  , mAddModFinalizer = \fin -> GHCiQ (\s -> mkRemoteRef fin) >>=
    
    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 (\s -> mkRemoteRef fin) >>=
    
    216 217
                              ghcCmd . AddModFinalizer
    
    217
    -  , mAddCorePlugin = \str -> ghcCmd (AddCorePlugin str)
    
    218
    -  , mGetQ = do
    
    218
    +  , mAddCorePlugin = \str -> runInIO $ ghcCmd (AddCorePlugin str)
    
    219
    +  , mGetQ = runInIO $ do
    
    219 220
         s <- getState
    
    220 221
         let lookup :: forall a. Typeable a => Map TypeRep Dynamic -> Maybe a
    
    221 222
             lookup m = fromDynamic =<< M.lookup (typeOf (undefined::a)) m
    
    222 223
         return $ lookup (qsMap s)
    
    223
    -  , mPutQ = \k -> GHCiQ $ \sRef ->
    
    224
    +  , mPutQ = \k -> runInIO $ GHCiQ $ \sRef ->
    
    224 225
           modifyIORef' sRef (\s -> s { qsMap = M.insert (typeOf k) (toDyn k) (qsMap s) })
    
    225
    -  , mIsExtEnabled = \x -> ghcCmd (IsExtEnabled x)
    
    226
    -  , mExtsEnabled = ghcCmd ExtsEnabled
    
    227
    -  , mPutDoc = \l s -> ghcCmd (PutDoc l s)
    
    228
    -  , mGetDoc = \l -> ghcCmd (GetDoc l)
    
    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)
    
    229 230
     }
    
    230 231
     
    
    231 232
     -- | The implementation of the 'StartTH' message: create