    module GHC.Tc.Types.TcRef (TcRef, newTcRef, readTcRef, writeTcRef, updTcRef, updTcRefM) where

    import GHC.Prelude

    import Control.Monad.IO.Class
    import Data.IORef

    -- | Type alias for 'IORef'; the convention is we'll use this for mutable
    -- bits of data in the typechecker which are updated during typechecking and
    -- returned at the end.
    type TcRef a = IORef a

    -- The following functions are all marked INLINE so that we
    -- don't end up passing a Monad or MonadIO dictionary.

    newTcRef :: MonadIO m => a -> m (TcRef a)
    newTcRef :: forall (m :: * -> *) a. MonadIO m => a -> m (TcRef a)
    newTcRef = \ a
    a -> IO (TcRef a) -> m (TcRef a)
    forall a. IO a -> m a
    forall (m :: * -> *) a. MonadIO m => IO a -> m a
    liftIO (IO (TcRef a) -> m (TcRef a)) -> IO (TcRef a) -> m (TcRef a)
    forall a b. (a -> b) -> a -> b
    $ a -> IO (TcRef a)
    forall a. a -> IO (IORef a)
    newIORef a
    a
    {-# INLINE newTcRef #-}

    readTcRef :: MonadIO m => TcRef a -> m a
    readTcRef :: forall (m :: * -> *) a. MonadIO m => TcRef a -> m a
    readTcRef = \ TcRef a
    ref -> IO a -> m a
    forall a. IO a -> m a
    forall (m :: * -> *) a. MonadIO m => IO a -> m a
    liftIO (IO a -> m a) -> IO a -> m a
    forall a b. (a -> b) -> a -> b
    $ TcRef a -> IO a
    forall a. IORef a -> IO a
    readIORef TcRef a
    ref
    {-# INLINE readTcRef #-}

    writeTcRef :: MonadIO m => TcRef a -> a -> m ()
    writeTcRef :: forall (m :: * -> *) a. MonadIO m => TcRef a -> a -> m ()
    writeTcRef = \ TcRef a
    ref a
    a -> IO () -> m ()
    forall a. IO a -> m a
    forall (m :: * -> *) a. MonadIO m => IO a -> m a
    liftIO (IO () -> m ()) -> IO () -> m ()
    forall a b. (a -> b) -> a -> b
    $ TcRef a -> a -> IO ()
    forall a. IORef a -> a -> IO ()
    writeIORef TcRef a
    ref a
    a
    {-# INLINE writeTcRef #-}

    updTcRef :: MonadIO m => TcRef a -> (a -> a) -> m ()
    updTcRef :: forall (m :: * -> *) a. MonadIO m => TcRef a -> (a -> a) -> m ()
    updTcRef = \ TcRef a
    ref a -> a
    fn -> IO () -> m ()
    forall a. IO a -> m a
    forall (m :: * -> *) a. MonadIO m => IO a -> m a
    liftIO (IO () -> m ()) -> IO () -> m ()
    forall a b. (a -> b) -> a -> b
    $ TcRef a -> (a -> a) -> IO ()
    forall a. IORef a -> (a -> a) -> IO ()
    modifyIORef' TcRef a
    ref a -> a
    fn
    {-# INLINE updTcRef #-}

    updTcRefM :: MonadIO m => TcRef a -> (a -> m a) -> m ()
    updTcRefM :: forall (m :: * -> *) a. MonadIO m => TcRef a -> (a -> m a) -> m ()
    updTcRefM TcRef a
    ref a -> m a
    upd
      = do { contents      <- TcRef a -> m a
    forall (m :: * -> *) a. MonadIO m => TcRef a -> m a
    readTcRef TcRef a
    ref
           ; !new_contents <- upd contents
           ; writeTcRef ref new_contents }
    {-# INLINE updTcRefM #-}