diff --git a/ghcide/src/Development/IDE/Core/Shake.hs b/ghcide/src/Development/IDE/Core/Shake.hs index 5b6aea20e..7b0ab79d0 100644 --- a/ghcide/src/Development/IDE/Core/Shake.hs +++ b/ghcide/src/Development/IDE/Core/Shake.hs @@ -307,13 +307,17 @@ type GetStalePersistent = NormalizedFilePath -> IdeAction (Maybe (Dynamic,Positi getShakeExtras :: Action ShakeExtras getShakeExtras = do + -- Will fail the action with a pattern match failure, but be caught Just x <- getShakeExtra @ShakeExtras return x getShakeExtrasRules :: Rules ShakeExtras getShakeExtrasRules = do - Just x <- getShakeExtraRules @ShakeExtras - return x + mExtras <- getShakeExtraRules @ShakeExtras + case mExtras of + Just x -> return x + -- This will actually crash HLS + Nothing -> liftIO $ fail "missing ShakeExtras" -- | Returns the client configuration, creating a build dependency. -- You should always use this function when accessing client configuration diff --git a/hls-graph/src/Development/IDE/Graph/Internal/Types.hs b/hls-graph/src/Development/IDE/Graph/Internal/Types.hs index 8451f641a..891b358c7 100644 --- a/hls-graph/src/Development/IDE/Graph/Internal/Types.hs +++ b/hls-graph/src/Development/IDE/Graph/Internal/Types.hs @@ -54,8 +54,13 @@ unwrapDynamic x = fromMaybe (error msg) $ fromDynamic x type TheRules = Map.HashMap TypeRep Dynamic +-- | A computation that defines all the rules that form part of the computation graph. +-- +-- 'Rules' has access to 'IO' through 'MonadIO'. Use of 'IO' is at your own risk: if +-- you write 'Rules' that throw exceptions, then you need to make sure to handle them +-- yourself when you run the resulting 'Rules'. newtype Rules a = Rules (ReaderT SRules IO a) - deriving newtype (Monad, Applicative, Functor, MonadIO, MonadFail) + deriving newtype (Monad, Applicative, Functor, MonadIO) data SRules = SRules { rulesExtra :: !Dynamic, @@ -67,6 +72,12 @@ data SRules = SRules { --------------------------------------------------------------------- -- ACTIONS +-- | An action representing something that can be run as part of a 'Rule'. +-- +-- 'Action's can be pure functions but also have access to 'IO' via 'MonadIO' and 'MonadUnliftIO. +-- It should be assumed that actions throw exceptions, these can be caught with +-- 'Development.IDE.Graph.Internal.Action.actionCatch'. In particular, it is +-- permissible to use the 'MonadFail' instance, which will lead to an 'IOException'. newtype Action a = Action {fromAction :: ReaderT SAction IO a} deriving newtype (Monad, Applicative, Functor, MonadIO, MonadFail, MonadThrow, MonadCatch, MonadMask, MonadUnliftIO)