diff --git a/library/Require.hs b/library/Require.hs
--- a/library/Require.hs
+++ b/library/Require.hs
@@ -4,6 +4,7 @@
 import Options.Generic
 import Relude
 import System.Directory
+import qualified Require.Error as Error
 import qualified Require.File as File
 import Require.Transform
 import Require.Types
@@ -33,12 +34,13 @@
   CommandArguments inputFile _ outputFile <- getRecord "Require Haskell preprocessor" :: IO CommandArguments
   requiresFile <- findRequires
   case requiresFile of
-    Nothing -> die "There is no Requires file in the system"
+    Nothing -> Error.die (File.Name inputFile) Error.MissingRequiresFile
     Just fn -> run (AutorequireEnabled fn) (File.Name inputFile) (File.Name outputFile)
 
 run :: AutorequireMode File.Name -> File.Name -> File.Name -> IO ()
 run autoMode inputFile outputFile = do
   input <- File.read inputFile
   autoInput <- traverse File.read autoMode
-  let transformed = transform autoInput input
-  File.write outputFile transformed
+  case transform autoInput input of
+    Left err -> Error.die inputFile err
+    Right ls -> File.writeLines outputFile ls
diff --git a/library/Require/Error.hs b/library/Require/Error.hs
new file mode 100644
--- /dev/null
+++ b/library/Require/Error.hs
@@ -0,0 +1,41 @@
+module Require.Error where
+
+import Control.Exception
+import Relude
+import qualified Require.File as File
+import System.Console.ANSI
+import System.IO
+
+
+data Error
+  = MissingRequiresFile
+  | MissingOptionalRequiresFile
+  | AutorequireImpossible
+  deriving (Eq, Show)
+
+
+describe :: Error -> [String]
+describe MissingRequiresFile =
+  [ "`autorequirepp` couldn't find a `Requires` file in the system." ]
+describe MissingOptionalRequiresFile =
+  [ "Discovered an `autorequire` directive but no `Requires` file was found." ]
+describe AutorequireImpossible =
+  [ "Unable to determine where to insert the autorequire contents."
+  , "Use the `autorequire` directive to specify a location yourself."
+  ]
+
+
+die :: File.Name -> Error -> IO a
+die (File.Name fn) e = do
+  let outputHeaderColored = do
+        hSetSGR stderr [SetConsoleIntensity BoldIntensity]
+        hPutStr stderr (toString fn ++ ": ")
+        hSetSGR stderr [SetColor Foreground Vivid Red]
+        hPutStr stderr "error:\n"
+
+  -- Don't mess up the terminal if there is an exception half-way through.
+  outputHeaderColored `finally` hSetSGR stderr []
+
+  let indent s = replicate 4 ' ' ++ s
+  traverse_ (hPutStrLn stderr . indent) (describe e)
+  exitFailure
diff --git a/library/Require/File.hs b/library/Require/File.hs
--- a/library/Require/File.hs
+++ b/library/Require/File.hs
@@ -9,6 +9,7 @@
 module Require.File where
 
 import Relude
+import qualified Data.Text.IO as TIO
 
 -- | Wraps the name of a file as given by the user. Usually this corresponds to
 -- the file's path.
@@ -30,7 +31,7 @@
 -- | Returns the 'LineTag' referencing the first line in a given 'FileInput'.
 --
 -- Note that the tag's line number is 1-based, which fits well with how GHC
--- understands @{-# LINE ... #-}@ pragmas.
+-- understands @{-\# LINE ... #-}@ pragmas.
 initialLineTag :: Input -> LineTag
 initialLineTag inp = LineTag (inputName inp) (LineNumber 1)
 
@@ -42,9 +43,11 @@
 read :: Name -> IO Input
 read f = Input f <$> readFileText (nameToPath f)
 
--- | @write name content@ writes @content@ to the file identified by @name@.
-write :: Name -> Text -> IO ()
-write = writeFileText . nameToPath
+-- | @write name lines@ writes all every line in @lines@ to the file identified
+-- by @name@ and appends a newline.
+writeLines :: Name -> [Text] -> IO ()
+writeLines name theLines = withFile (nameToPath name) WriteMode $ \h ->
+  traverse_ (TIO.hPutStrLn h) theLines
 
 -- | Splits the input into lines and annotates each with a 'LineTag'.
 inputLines :: Input -> [(LineTag, Text)]
diff --git a/library/Require/Transform.hs b/library/Require/Transform.hs
--- a/library/Require/Transform.hs
+++ b/library/Require/Transform.hs
@@ -1,79 +1,110 @@
 {-# LANGUAGE FlexibleContexts #-}
 module Require.Transform where
 
+import Control.Monad.Except
+import Control.Monad.Writer.Strict
+import Data.DList (DList)
 import qualified Data.Text as Text
 import Relude
+import Require.Error (Error(..))
 import qualified Require.File as File
 import qualified Require.Parser as Parser
 import Require.Types
 
 
-type LineTagPrepend = File.LineTag -> Text -> Text
+-- | The monad stack used during transformation:
+--
+-- * @'StateT' 'TransformState'@ to keep track of whether to render the next
+--   line tag, the module's name etc.
+-- * @'WriterT' ('DList' 'Text')@ to collect the output lines. Instead of
+--   haskell's built-in list type we use 'DList' because of it's /O(1)/ append
+--   operation.
+-- * @'Either' 'Error'@ to return errors.
+type TransformM =
+  StateT TransformState
+    (WriterT (DList Text)
+      (Either Error))
 
+
 data TransformState = TransformState
-  { tstLineTagPrepend :: !LineTagPrepend
+  { tstLineTagOutput  :: File.LineTag -> TransformM ()
   , tstHostModule     :: !(Maybe ModuleName)
   , tstAutorequire    :: !(AutorequireMode File.Input)
   }
 
 
-renderLineTag :: File.LineTag -> Text
-renderLineTag (File.LineTag (File.Name fn) (File.LineNumber ln)) =
-  "{-# LINE " <> show ln <> " \"" <> fn <> "\" #-}\n"
-
+-- | Outputs a single line.
+output :: Text -> TransformM ()
+output = tell . pure
 
-prependLineTag :: LineTagPrepend
-prependLineTag = (<>) . renderLineTag
+-- | Outputs the pragma representation of the given line tag.
+renderLineTag :: File.LineTag -> TransformM ()
+renderLineTag (File.LineTag (File.Name fn) (File.LineNumber ln)) =
+  output $ "{-# LINE " <> show ln <> " \"" <> fn <> "\" #-}"
 
-ignoreLineTag :: LineTagPrepend
-ignoreLineTag = const id
+-- | Ignore the given line tag, specifically don't render it.
+ignoreLineTag :: File.LineTag -> TransformM ()
+ignoreLineTag = const (pure ())
 
 
-transform :: AutorequireMode File.Input -> File.Input -> Text
+transform :: AutorequireMode File.Input -> File.Input -> Either Error [Text]
 transform autorequire input =
-  -- TODO:
-  --  * if the mapM overhead is too much maybe use a streaming library
-  --  * there is no need to concatenate the whole output in memory, a lazy text would be fine
-  --  * maybe we should check if tstAutorequired is set after processing
   File.inputLines input
-    & mapM (process (pure Nothing))
-    & flip evalState initialState
-    & mconcat
+    & traverse_ (process False)
+    & flip execStateT initialState
+    & chainedTo checkDidAutorequire
+    & execWriterT
+    & fmap toList
   where
     initialState = TransformState
-      { tstLineTagPrepend = prependLineTag
+      { tstLineTagOutput  = renderLineTag
       , tstHostModule     = Nothing
       , tstAutorequire    = autorequire
       }
 
-process
-  :: State TransformState (Maybe ModuleName)
-  -> (File.LineTag, Text)
-  -> State TransformState Text
-process getHostModule (tag, line) = do
-  let useTagPrep text = do
-        prep <- gets tstLineTagPrepend
-        modify $ \s -> s { tstLineTagPrepend = ignoreLineTag }
-        pure $ prep tag text
+    unableToAutorequire resultState
+      -- If the autorequire mode was `enabled` initially and still is
+      -- afterwards, we were unable to find where to place the Require contents.
+      | AutorequireEnabled _ <- autorequire
+      , AutorequireEnabled _ <- tstAutorequire resultState
+      = True
+      -- In any other case this either wasn't goal or it was done successfully.
+      | otherwise
+      = False
 
+    checkDidAutorequire resultState
+      | unableToAutorequire resultState = throwError AutorequireImpossible
+      | otherwise = pure ()
+
+
+process :: Bool -> (File.LineTag, Text) -> TransformM ()
+process filterImports (tag, line) = do
+  -- Uses 'tstLineTagOutput' to render the current lines tag if necessary.
+  let useTagPrep = do
+        tst <- get
+        tstLineTagOutput tst tag
+        put (tst { tstLineTagOutput = ignoreLineTag })
+
   let lineWithAutorequire isDirective autoCondition = do
         autoMode <- gets tstAutorequire
         case autoMode of
           AutorequireEnabled autoContent
             | isDirective || autoCondition -> do
-                line' <- if isDirective then pure "" else useTagPrep (line <> "\n")
-                auto  <- processAutorequireContent autoContent
-                pure $ line' <> auto
-          AutorequireOnDirective (Just autoContent)
-            | isDirective -> do
+                -- If this is an `autorequire` directive, ignore it. Otherwise
+                -- output the line tag if necessary (useTagPrep) and then the
+                -- line itself.
+                unless isDirective (useTagPrep >> output line)
                 processAutorequireContent autoContent
+
+          AutorequireOnDirective (Just autoContent)
+            | isDirective -> processAutorequireContent autoContent
+
           AutorequireOnDirective Nothing
-            | isDirective ->
-                -- TODO: Better error reporting.
-                error "Found an `autorequire` directive but no `Requires` file was found."
-          _ | isDirective -> pure ""
-            | otherwise   -> useTagPrep $ line <> "\n"
+            | isDirective -> throwError MissingOptionalRequiresFile
 
+          _ | isDirective -> pure ()
+            | otherwise   -> useTagPrep >> output line
+
   let hasWhere =
         -- TODO: This assumes that comments have whitespace before them and
         -- that `where` has whitespace before it. But
@@ -95,51 +126,47 @@
 
     Just (RequireDirective ri) ->
       -- renderImport already prepends the line tag if necessary.
-      renderImport getHostModule tag ri
+      renderImport filterImports tag ri
 
     Just AutorequireDirective ->
       lineWithAutorequire True False
 
 
-processAutorequireContent :: File.Input -> State TransformState Text
+processAutorequireContent :: File.Input -> TransformM ()
 processAutorequireContent autorequireContent = do
   modify $ \s -> s
-     { tstLineTagPrepend = prependLineTag
+     { tstLineTagOutput  = renderLineTag
      , tstAutorequire    = AutorequireDisabled
      }
 
-  processed <- File.inputLines autorequireContent
-     & mapM (process (gets tstHostModule))
-     & fmap mconcat
+  traverse_ (process True) (File.inputLines autorequireContent)
+  modify $ \s -> s { tstLineTagOutput = renderLineTag }
 
-  modify $ \s -> s { tstLineTagPrepend = prependLineTag }
-  pure processed
 
+renderImport :: Bool -> File.LineTag -> RequireInfo -> TransformM ()
+renderImport filterImports line RequireInfo {..} = do
+    tst <- get
+    if filterImports && tstHostModule tst == Just riFullModuleName
+      then
+        -- We skipped a line, therefore we need a line tag before outputting
+        -- the next one.
+        put (tst { tstLineTagOutput = renderLineTag })
 
-renderImport
-  :: MonadState TransformState m
-  => m (Maybe ModuleName)
-  -> File.LineTag
-  -> RequireInfo
-  -> m Text
-renderImport getHostModule line RequireInfo {..} = do
-    mhostModule <- getHostModule
-    lineTagPrep <- gets tstLineTagPrepend
-    let (res, prep) =
-          if mhostModule == Just riFullModuleName
-             then ("", prependLineTag)
-             else (typesImport <> renderLineTag line <> qualifiedImport, ignoreLineTag)
-    modify $ \s -> s { tstLineTagPrepend = prep }
-    pure $ lineTagPrep line res
+      else do
+        tstLineTagOutput tst line
+        output typesImport
+        renderLineTag line
+        output qualifiedImport
+        put (tst { tstLineTagOutput = ignoreLineTag })
   where
     typesImport = unwords
       [ "import"
       , unModuleName riFullModuleName
       , "(" <> riImportedTypes <> ")"
-      ] <> "\n"
+      ]
     qualifiedImport = unwords
       [ "import qualified"
       , unModuleName riFullModuleName
       , "as"
       , riModuleAlias
-      ] <> "\n"
+      ]
diff --git a/package.yaml b/package.yaml
--- a/package.yaml
+++ b/package.yaml
@@ -1,5 +1,5 @@
 name: require
-version: "0.4.8"
+version: "0.4.9"
 github: "theam/require"
 license: Apache-2.0
 author: "The Agile Monkeys"
@@ -32,10 +32,12 @@
   - relude
   - bytestring >= 0.10 && < 0.11
   - text >= 1.2.3.0 && < 2
-  - megaparsec >= 7 && < 8
+  - megaparsec >= 7 && < 9
+  - mtl >= 2.2.1
   - directory
-  - inliterate
   - optparse-generic
+  - dlist
+  - ansi-terminal
 
 library:
   source-dirs: library
@@ -48,8 +50,6 @@
       - require
     ghc-options:
       - -rtsopts
-      - -threaded
-      - -with-rtsopts=-N
   autorequirepp:
     source-dirs: executable/AutoRequire/
     main: Main.hs
@@ -57,8 +57,6 @@
       - require
     ghc-options:
       - -rtsopts
-      - -threaded
-      - -with-rtsopts=-N
 
 benchmarks:
   require-benchmarks:
diff --git a/require.cabal b/require.cabal
--- a/require.cabal
+++ b/require.cabal
@@ -4,10 +4,10 @@
 --
 -- see: https://github.com/sol/hpack
 --
--- hash: ceeb2f9c5a160393a1fd86ca01c63c4d957d256ae92501abfd87e3d415f5c686
+-- hash: 17d63ecaad4aef59bc1c65336dd500edd837396b8e80b9609aacca8fed98e770
 
 name:           require
-version:        0.4.8
+version:        0.4.9
 synopsis:       Scrap your qualified import clutter
 description:    See <https://theam.github.io/require>
 category:       Other
@@ -34,6 +34,7 @@
 library
   exposed-modules:
       Require
+      Require.Error
       Require.File
       Require.Parser
       Require.Transform
@@ -45,11 +46,13 @@
   default-extensions: NoImplicitPrelude OverloadedStrings TypeApplications RecordWildCards DeriveGeneric
   ghc-options: -Wall
   build-depends:
-      base >=4.9 && <5
+      ansi-terminal
+    , base >=4.9 && <5
     , bytestring >=0.10 && <0.11
     , directory
-    , inliterate
-    , megaparsec >=7 && <8
+    , dlist
+    , megaparsec >=7 && <9
+    , mtl >=2.2.1
     , optparse-generic
     , relude
     , text >=1.2.3.0 && <2
@@ -62,13 +65,15 @@
   hs-source-dirs:
       executable/AutoRequire/
   default-extensions: NoImplicitPrelude OverloadedStrings TypeApplications RecordWildCards DeriveGeneric
-  ghc-options: -Wall -rtsopts -threaded -with-rtsopts=-N
+  ghc-options: -Wall -rtsopts
   build-depends:
-      base >=4.9 && <5
+      ansi-terminal
+    , base >=4.9 && <5
     , bytestring >=0.10 && <0.11
     , directory
-    , inliterate
-    , megaparsec >=7 && <8
+    , dlist
+    , megaparsec >=7 && <9
+    , mtl >=2.2.1
     , optparse-generic
     , relude
     , require
@@ -82,13 +87,15 @@
   hs-source-dirs:
       executable/Require/
   default-extensions: NoImplicitPrelude OverloadedStrings TypeApplications RecordWildCards DeriveGeneric
-  ghc-options: -Wall -rtsopts -threaded -with-rtsopts=-N
+  ghc-options: -Wall -rtsopts
   build-depends:
-      base >=4.9 && <5
+      ansi-terminal
+    , base >=4.9 && <5
     , bytestring >=0.10 && <0.11
     , directory
-    , inliterate
-    , megaparsec >=7 && <8
+    , dlist
+    , megaparsec >=7 && <9
+    , mtl >=2.2.1
     , optparse-generic
     , relude
     , require
@@ -105,11 +112,13 @@
   default-extensions: NoImplicitPrelude OverloadedStrings TypeApplications RecordWildCards DeriveGeneric
   ghc-options: -Wall -rtsopts -threaded -with-rtsopts=-N
   build-depends:
-      base >=4.9 && <5
+      ansi-terminal
+    , base >=4.9 && <5
     , bytestring >=0.10 && <0.11
     , directory
-    , inliterate
-    , megaparsec >=7 && <8
+    , dlist
+    , megaparsec >=7 && <9
+    , mtl >=2.2.1
     , optparse-generic
     , relude
     , require
@@ -128,12 +137,14 @@
   default-extensions: NoImplicitPrelude OverloadedStrings TypeApplications RecordWildCards DeriveGeneric
   ghc-options: -Wall -rtsopts -threaded -with-rtsopts=-N
   build-depends:
-      base >=4.9 && <5
+      ansi-terminal
+    , base >=4.9 && <5
     , bytestring >=0.10 && <0.11
     , criterion
     , directory
-    , inliterate
-    , megaparsec >=7 && <8
+    , dlist
+    , megaparsec >=7 && <9
+    , mtl >=2.2.1
     , optparse-generic
     , relude
     , require
diff --git a/test-suite/Main.hs b/test-suite/Main.hs
--- a/test-suite/Main.hs
+++ b/test-suite/Main.hs
@@ -1,5 +1,6 @@
 import qualified Data.Text as Text
 import Relude
+import qualified Require.Error as Error
 import qualified Require.File as File
 import qualified Require.Transform as Require
 import Require.Types
@@ -13,21 +14,36 @@
 
 spec :: Spec
 spec = parallel $ do
+  let transformLines autoMode fileInput =
+        case Require.transform autoMode fileInput of
+          Left err -> do
+            -- sadly expectationFailure is not polymorphic in its return type
+            expectationFailure $ "Tranform failed: " ++ show err
+            pure $ error "expectationFailure should have thrown"
+          Right tr ->
+            pure tr
+
+      transformString autoMode =
+         fmap toString . transform autoMode
+
+      transform autoMode =
+         fmap unlines . transformLines autoMode
+
   describe "the transformation" $ do
     it "transforms the 'require' keyword into a properly qualified import" $ do
       let input = "require Data.Text"
       let expected = "import qualified Data.Text as Text"
-      let actual = Require.transform
+      actual <- transformString
             AutorequireDisabled
             (File.Input (File.Name "Foo.hs") input)
-      expected `Text.isInfixOf` actual
+      actual `shouldContain` expected
     it "imports the type based on the module" $ do
       let input = "require Data.Text"
       let expected = "import Data.Text (Text)"
-      let actual = Require.transform
+      actual <- transformString
             AutorequireDisabled
             (File.Input (File.Name "Foo.hs") input)
-      expected `Text.isInfixOf` actual
+      actual `shouldContain` expected
     it "keeps the rest of the content intact" $ do
       let input = "module Foo where\nrequire Data.Text\nfoo = 42"
       let expectedStart = "{-# LINE 1"
@@ -35,7 +51,7 @@
       let expectedTypeImport = "import Data.Text (Text)"
       let expectedQualifiedImport = "import qualified Data.Text as Text"
       let expectedContent = "foo = 42\n"
-      let actual = toString $ Require.transform
+      actual <- transformString
             AutorequireDisabled
             (File.Input (File.Name "Foo.hs") input)
       actual `shouldStartWith` expectedStart
@@ -47,7 +63,7 @@
       let input = "require Data.Text as Foo"
       let expectedTypeImport = "import Data.Text (Text)"
       let expectedQualifiedImport = "import qualified Data.Text as Foo"
-      let actual = toString $ Require.transform
+      actual <- transformString
             AutorequireDisabled
             (File.Input (File.Name "Foo.hs") input)
       actual `shouldContain` expectedTypeImport
@@ -56,7 +72,7 @@
       let input = "require Data.Text (Foo)"
       let expectedTypeImport = "import Data.Text (Foo)"
       let expectedQualifiedImport = "import qualified Data.Text as Text"
-      let actual = toString $ Require.transform
+      actual <- transformString
             AutorequireDisabled
             (File.Input (File.Name "Foo.hs") input)
       actual `shouldContain` expectedTypeImport
@@ -65,7 +81,7 @@
       let input = "require Data.Text as Quux (Foo)"
       let expectedTypeImport = "import Data.Text (Foo)"
       let expectedQualifiedImport = "import qualified Data.Text as Quux"
-      let actual = toString $ Require.transform
+      actual <- transformString
             AutorequireDisabled
             (File.Input (File.Name "Foo.hs") input)
       actual `shouldContain` expectedTypeImport
@@ -73,55 +89,63 @@
     it "skips comments" $ do
       let input = "require Data.Text -- test of comments"
       let expected = "import Data.Text (Text)"
-      let actual = Require.transform
+      actual <- transformString
             AutorequireDisabled
             (File.Input (File.Name "Foo.hs") input)
-      expected `Text.isInfixOf` actual
+      actual `shouldContain` expected
     it "allows empty parentheses" $ do
       let input = "require Data.Text ()"
       let expected1 = "import Data.Text ()"
       let expected2 = "import qualified Data.Text as Text"
-      let actual = lines $ Require.transform
+      actual <- transformLines
             AutorequireDisabled
             (File.Input (File.Name "Foo.hs") input)
       actual `shouldSatisfy` elem expected1
       actual `shouldSatisfy` elem expected2
 
   describe "require-mode" $ do
-    it "respects autorequire directives" $ do
-      let fileInput = Text.unlines [ "module Main where", "autorequire", "import B" ]
-      let requireInput = Text.unlines [ "import A" ]
-      let actual = Text.lines $ Require.transform
-            (AutorequireOnDirective $ Just $ File.Input (File.Name "Requires") requireInput)
-            (File.Input (File.Name "src/Foo/Bar.hs") fileInput)
-      actual `shouldSatisfy` elem "module Main where"
-      actual `shouldSatisfy` elem "import A"
-      actual `shouldSatisfy` elem "import B"
-      actual `shouldSatisfy` elemN 0 "autorequire"
-    it "ignores a second autorequire directive" $ do
-      let fileInput = Text.unlines [ "autorequire", "autorequire" ]
-      let requireInput = Text.unlines [ "import A" ]
-      let actual = Text.lines $ Require.transform
-            (AutorequireOnDirective $ Just $ File.Input (File.Name "Requires") requireInput)
-            (File.Input (File.Name "src/Foo/Bar.hs") fileInput)
-      actual `shouldSatisfy` elemN 1 "import A"
-      actual `shouldSatisfy` elemN 0 "autorequire"
     it "keeps requires where the module is a substring of the filename" $ do
       -- Test case for https://github.com/theam/require/issues/20
       let fileInput = Text.unlines [ "module FooTest where", "require Foo" ]
       let expected1 = "import Foo (Foo)"
       let expected2 = "import qualified Foo as Foo"
-      let actual = lines $ Require.transform
+      actual <- transformLines
             AutorequireDisabled
             (File.Input (File.Name "FooTests.hs") fileInput)
       actual `shouldSatisfy` elem expected1
       actual `shouldSatisfy` elem expected2
 
+    describe "autorequire directive" $ do
+      it "respects them" $ do
+        let fileInput = Text.unlines [ "module Main where", "autorequire", "import B" ]
+        let requireInput = Text.unlines [ "import A" ]
+        actual <- transformLines
+              (AutorequireOnDirective $ Just $ File.Input (File.Name "Requires") requireInput)
+              (File.Input (File.Name "src/Foo/Bar.hs") fileInput)
+        actual `shouldSatisfy` elem "module Main where"
+        actual `shouldSatisfy` elem "import A"
+        actual `shouldSatisfy` elem "import B"
+        actual `shouldSatisfy` elemN 0 "autorequire"
+      it "ignores them after the first one" $ do
+        let fileInput = Text.unlines [ "autorequire", "autorequire" ]
+        let requireInput = Text.unlines [ "import A" ]
+        actual <- transformLines
+              (AutorequireOnDirective $ Just $ File.Input (File.Name "Requires") requireInput)
+              (File.Input (File.Name "src/Foo/Bar.hs") fileInput)
+        actual `shouldSatisfy` elemN 1 "import A"
+        actual `shouldSatisfy` elemN 0 "autorequire"
+      it "throws an error if no requires file is provided" $ do
+        let fileInput = "autorequire"
+        let actual = Require.transform
+              (AutorequireOnDirective Nothing)
+              (File.Input (File.Name "Foo.hs") fileInput)
+        actual `shouldBe` Left Error.MissingOptionalRequiresFile
+
   describe "autorequire-mode" $ do
     describe "inclusion after module directive" $ do
       let checkInclusion n fileInput = do
             let requireInput = "import A"
-            let actual = Text.lines $ Require.transform
+            actual <- transformLines
                   (AutorequireEnabled $ File.Input (File.Name "Requires") requireInput)
                   (File.Input (File.Name "src/Foo/Bar.hs") fileInput)
             actual `shouldSatisfy` elemN n requireInput
@@ -141,18 +165,28 @@
           , "  ) where"
           ]
       it "doesn't add after data/class/instance declarations" $ do
-        checkInclusion 0 $ Text.unlines
-          [ "class Foo a where"
-          , "instance Foo x => Bar (Baz x) where"
-          , "data Vec n a where"
-          , "  Nil :: Vec 0 a"
-          , "  Cons :: a -> Vec n a -> Vec (n + 1) a"
-          ]
+        let fileInput = unlines
+              [ "class Foo a where"
+              , "instance Foo x => Bar (Baz x) where"
+              , "data Vec n a where"
+              , "  Nil :: Vec 0 a"
+              , "  Cons :: a -> Vec n a -> Vec (n + 1) a"
+              ]
+        let requireInput = unlines [ "import A" ]
+        let actual = Require.transform
+              (AutorequireEnabled $ File.Input (File.Name "Requires") requireInput)
+              (File.Input (File.Name "Foo.hs") fileInput)
+        actual `shouldBe` Left Error.AutorequireImpossible
       it "doesn't add after data/class/instance declarations split to multiple lines" $ do
-        checkInclusion 0 $ Text.unlines
-          [ "class Foo a -- some explanation here"
-          , "  where"
-          ]
+        let fileInput = unlines
+              [ "class Foo a -- some explanation here"
+              , "  where"
+              ]
+        let requireInput = unlines [ "import A" ]
+        let actual = Require.transform
+              (AutorequireEnabled $ File.Input (File.Name "Requires") requireInput)
+              (File.Input (File.Name "Foo.hs") fileInput)
+        actual `shouldBe` Left Error.AutorequireImpossible
 
     describe "triggered using the autorequire directive" $ do
       it "can be triggered before without a module directive" $ do
@@ -164,7 +198,7 @@
               , "{-# LINE 2 \"Foo.hs\" #-}"
               , "main = return ()"
               ]
-        let actual = Require.transform
+        actual <- transform
               (AutorequireEnabled $ File.Input (File.Name "Requires") requireInput)
               (File.Input (File.Name "Foo.hs") fileInput)
         actual `shouldBe` expected
@@ -177,7 +211,7 @@
               , "{-# LINE 1 \"Requires\" #-}"
               , "import A"
               ]
-        let actual = Require.transform
+        actual <- transform
               (AutorequireEnabled $ File.Input (File.Name "Requires") requireInput)
               (File.Input (File.Name "Foo.hs") fileInput)
         actual `shouldBe` expected
@@ -190,7 +224,7 @@
               , "{-# LINE 2 \"Foo.hs\" #-}"
               , "module Main where"
               ]
-        let actual = Require.transform
+        actual <- transform
               (AutorequireEnabled $ File.Input (File.Name "Requires") requireInput)
               (File.Input (File.Name "Foo.hs") fileInput)
         actual `shouldBe` expected
@@ -199,7 +233,7 @@
       let fileInput = "module Foo.Bar where"
       let requireInput = "require Foo.Bar"
       let notExpected = "import Foo.Bar"
-      let actual = Require.transform
+      actual <- transform
             (AutorequireEnabled $ File.Input (File.Name "Requires") requireInput)
             (File.Input (File.Name "src/Foo/Bar.hs") fileInput)
       toString actual `shouldNotContain` notExpected
@@ -214,7 +248,7 @@
             , "{-# LINE 2 \"Foo.hs\" #-}"
             , "import B"
             ]
-      let actual = Require.transform
+      actual <- transform
             (AutorequireEnabled $ File.Input (File.Name "Requires") requireInput)
             (File.Input (File.Name "Foo.hs") fileInput)
       actual `shouldBe` expected
