diff --git a/CHANGELOG.md b/CHANGELOG.md
new file mode 100644
--- /dev/null
+++ b/CHANGELOG.md
@@ -0,0 +1,19 @@
+# Changelog
+
+## [0.9.0](https://github.com/haskell-nix/hnix/compare/0.8.0...0.9.0) (2020-06-15)
+
+* Changelog started. Previous release was `0.8.0`. In new release:
+
+* Major breaking:
+  * Removed instances due to migration to `haskeline >= 0.8 && < 0.9`:
+    * `instance MonadException m => MonadException(StateT(HashMap FilePath NExprLoc) m)`
+    * `instance MonadException m => MonadException(Fix1T StandardTF m)`
+
+* Minor:
+  * Added support for `GHC 8.4.4, 8.8.3`
+
+---
+
+`HNix` uses [PVP Versioning][1].
+
+[1]: https://pvp.haskell.org
diff --git a/hnix.cabal b/hnix.cabal
--- a/hnix.cabal
+++ b/hnix.cabal
@@ -1,5 +1,5 @@
 name:           hnix
-version:        0.8.0
+version:        0.9.0
 synopsis:       Haskell implementation of the Nix language
 description:    Haskell implementation of the Nix language.
 category:       System, Data, Nix
@@ -758,6 +758,7 @@
     data/let.nix
     LICENSE
     README.md
+    CHANGELOG.md
     tests/eval-compare/builtins.split-01.nix
     tests/eval-compare/builtins.split-02.nix
     tests/eval-compare/builtins.split-03.nix
@@ -780,6 +781,21 @@
     tests/eval-compare/ind-string-15.nix
     tests/eval-compare/ind-string-16.nix
     tests/eval-compare/ind-string-17.nix
+    tests/files/attrs.nix
+    tests/files/callLibs.nix
+    tests/files/eighty.nix
+    tests/files/file.nix
+    tests/files/file2.nix
+    tests/files/findFile.nix
+    tests/files/force.nix
+    tests/files/goodbye.nix
+    tests/files/hello.nix
+    tests/files/hello2.nix
+    tests/files/if-then.nix
+    tests/files/lint.nix
+    tests/files/loop.nix
+    tests/files/test.nix
+    tests/files/with.nix
 
 source-repository head
   type: git
@@ -872,8 +888,8 @@
     , http-client-tls >= 0.3.5 && < 0.4
     , http-types >= 0.12.2 && < 0.13
     , interpolate >= 0.2.0 && < 0.3
-    , lens-family >=1.2.2
-    , lens-family-core >=1.2.2
+    , lens-family >=1.2.2 && < 2.2
+    , lens-family-core >=1.2.2 && < 2.2
     , lens-family-th >= 0.5.0 && < 0.6
     , logict >= 0.6.0 && < 0.7 || >= 0.7.0.2 && < 0.8
     , megaparsec >=7.0 && <8.1
@@ -893,7 +909,7 @@
     , some >= 1.0.1 && < 1.1
     , split >= 0.2.3 && < 0.3
     , syb >= 0.7 && < 0.8
-    , template-haskell
+    , template-haskell >= 2.13 && < 2.17
     , text >= 1.2.3 && < 1.3
     , these >= 1.0.1 && < 1.2
     , time >= 1.8.0 && < 1.9 || >= 1.9.3 && < 1.10
@@ -910,11 +926,6 @@
         Nix.Options.Parser
     build-depends:
         base16-bytestring >= 0.1.1 && < 0.2
-      , cryptohash-md5 >= 0.11.100 && < 0.12
-      , cryptohash-sha1 >= 0.11.100 && < 0.12
-      , cryptohash-sha256 >= 0.11.101 && < 0.12
-      , cryptohash-sha512 >= 0.11.100 && < 0.12
-      , haskeline >= 0.7.4.2 && < 0.8
       , pretty-show >= 1.9.5 && < 1.11
       , serialise >= 0.2.1 && < 0.3
   -- if !flag(profiling)
@@ -937,17 +948,12 @@
     , bytestring
     , comonad
     , containers
-    , cryptohash-md5
-    , cryptohash-sha1
-    , cryptohash-sha256
-    , cryptohash-sha512
     , data-fix
     , deepseq
     , exceptions
     , filepath
     , free
-    , hashing
-    , haskeline
+    , haskeline >= 0.8.0.0 && < 0.9
     , hnix
     , mtl
     , optparse-applicative
@@ -963,6 +969,10 @@
     , unordered-containers
   if flag(optimize)
     ghc-options: -fexpose-all-unfoldings -fspecialise-aggressively -O2
+  if impl(ghc < 8.10)
+    -- GHC < 8.10 comes with haskeline < 0.8, which we don't support.
+    -- To simplify CI, we just disable the component.
+    buildable: False
   if impl(ghcjs)
     buildable: False
   default-language: Haskell2010
@@ -989,17 +999,12 @@
     , base16-bytestring
     , bytestring
     , containers
-    , cryptohash-md5
-    , cryptohash-sha1
-    , cryptohash-sha256
-    , cryptohash-sha512
     , data-fix
     , deepseq >=1.4.3 && <1.5
     , directory
     , exceptions
     , filepath
     , generic-random
-    , hashing
     , hedgehog
     , hnix
     , interpolate
@@ -1043,15 +1048,10 @@
     , bytestring
     , containers
     , criterion
-    , cryptohash-md5
-    , cryptohash-sha1
-    , cryptohash-sha256
-    , cryptohash-sha512
     , data-fix
     , deepseq >=1.4.3 && <1.5
     , exceptions
     , filepath
-    , hashing
     , hnix
     , mtl
     , optparse-applicative
diff --git a/main/Repl.hs b/main/Repl.hs
--- a/main/Repl.hs
+++ b/main/Repl.hs
@@ -38,7 +38,6 @@
                                                 , foldl'
                                                 )
 import qualified Data.Map                      as Map
-import           Data.Monoid
 import           Data.Text                      ( unpack
                                                 , pack
                                                 )
@@ -52,19 +51,14 @@
 import           Control.Monad.Reader
 import           Control.Monad.State.Strict
 
-import           System.Console.Haskeline.MonadException
-import           System.Console.Repline        hiding ( options )
+import           System.Console.Repline        hiding ( options, prefix )
 import           System.Environment
 import           System.Exit
 
 
-main :: (MonadNix e t f m, MonadIO m, MonadException m) => m ()
+main :: (MonadNix e t f m, MonadIO m, MonadMask m) => m ()
 main = flip evalStateT initState
-#if MIN_VERSION_repline(0, 2, 0)
     $ evalRepl (return prefix) cmd options (Just ':') completer welcomeText
-#else
-    $ evalRepl prefix cmd options completer welcomeText
-#endif
  where
   prefix = "hnix> "
   welcomeText =
@@ -86,7 +80,7 @@
 initState = IState M.empty
 
 type Repl e t f m = HaskelineT (StateT (IState t f m) m)
-hoistErr :: MonadIO m => Result a -> Repl e t f m a
+hoistErr :: (MonadIO m, MonadThrow m) => Result a -> Repl e t f m a
 hoistErr (Success val) = return val
 hoistErr (Failure err) = do
   liftIO $ print err
@@ -98,7 +92,7 @@
 
 exec
   :: forall e t f m
-   . (MonadNix e t f m, MonadIO m, MonadException m)
+   . (MonadNix e t f m, MonadIO m)
   => Bool
   -> Text.Text
   -> Repl e t f m (NValue t f m)
@@ -129,7 +123,7 @@
 
 
 cmd
-  :: (MonadNix e t f m, MonadIO m, MonadException m)
+  :: (MonadNix e t f m, MonadIO m)
   => String
   -> Repl e t f m ()
 cmd source = do
@@ -153,7 +147,7 @@
 
 -- :load command
 load
-  :: (MonadNix e t f m, MonadIO m, MonadException m)
+  :: (MonadNix e t f m, MonadIO m)
   => [String]
   -> Repl e t f m ()
 load args = do
@@ -162,7 +156,7 @@
 
 -- :type command
 typeof
-  :: (MonadNix e t f m, MonadException m, MonadIO m)
+  :: (MonadNix e t f m, MonadIO m)
   => [String]
   -> Repl e t f m ()
 typeof args = do
@@ -199,7 +193,7 @@
                                       )
 
 options
-  :: (MonadNix e t f m, MonadIO m, MonadException m)
+  :: (MonadNix e t f m, MonadIO m)
   => [(String, [String] -> Repl e t f m ())]
 options =
   [ ( "load"
@@ -213,7 +207,7 @@
 
 help
   :: forall e t f m
-   . (MonadNix e t f m, MonadIO m, MonadException m)
+   . (MonadNix e t f m, MonadIO m)
   => [String]
   -> Repl e t f m ()
 help _ = liftIO $ do
diff --git a/src/Nix/Builtins.hs b/src/Nix/Builtins.hs
--- a/src/Nix/Builtins.hs
+++ b/src/Nix/Builtins.hs
@@ -30,23 +30,11 @@
 import           Control.Monad.Catch
 import           Control.Monad.ListM            ( sortByM )
 import           Control.Monad.Reader           ( asks )
-
--- Using package imports here because there is a bug in cabal2nix that demands
--- us to put the hashing package in the unconditional dependency list.
--- See https://github.com/NixOS/cabal2nix/issues/348 for more info
-#if MIN_VERSION_hashing(0, 1, 0)
-import "hashing" Crypto.Hash
-import qualified "hashing" Crypto.Hash.MD5     as MD5
-import qualified "hashing" Crypto.Hash.SHA1    as SHA1
-import qualified "hashing" Crypto.Hash.SHA256  as SHA256
-import qualified "hashing" Crypto.Hash.SHA512  as SHA512
-#else
-import qualified "cryptohash-md5" Crypto.Hash.MD5 as MD5
-import qualified "cryptohash-sha1" Crypto.Hash.SHA1 as SHA1
-import qualified "cryptohash-sha256" Crypto.Hash.SHA256 as SHA256
-import qualified "cryptohash-sha512" Crypto.Hash.SHA512 as SHA512
-#endif
-
+import           Crypto.Hash
+import qualified Crypto.Hash.MD5               as MD5
+import qualified Crypto.Hash.SHA1              as SHA1
+import qualified Crypto.Hash.SHA256            as SHA256
+import qualified Crypto.Hash.SHA512            as SHA512
 import qualified Data.Aeson                    as A
 import           Data.Align                     ( alignWith )
 import           Data.Array
@@ -71,9 +59,7 @@
 import qualified Data.Text.Lazy.Builder        as Builder
 import           Data.These                     ( fromThese )
 import qualified Data.Time.Clock.POSIX         as Time
-import           Data.Traversable               ( for
-                                                , mapM
-                                                )
+import           Data.Traversable               ( for )
 import qualified Data.Vector                   as V
 import           Nix.Atoms
 import           Nix.Convert
@@ -1208,32 +1194,16 @@
   case algo of
     "md5" ->
       f $ \s ->
-#if MIN_VERSION_hashing(0, 1, 0)
                 Text.pack $ show (hash (encodeUtf8 s) :: MD5.MD5)
-#else
-          decodeUtf8 $ Base16.encode $ MD5.hash $ encodeUtf8 s
-#endif
     "sha1" ->
       f $ \s ->
-#if MIN_VERSION_hashing(0, 1, 0)
                 Text.pack $ show (hash (encodeUtf8 s) :: SHA1.SHA1)
-#else
-          decodeUtf8 $ Base16.encode $ SHA1.hash $ encodeUtf8 s
-#endif
     "sha256" ->
       f $ \s ->
-#if MIN_VERSION_hashing(0, 1, 0)
                 Text.pack $ show (hash (encodeUtf8 s) :: SHA256.SHA256)
-#else
-          decodeUtf8 $ Base16.encode $ SHA256.hash $ encodeUtf8 s
-#endif
     "sha512" ->
       f $ \s ->
-#if MIN_VERSION_hashing(0, 1, 0)
                 Text.pack $ show (hash (encodeUtf8 s) :: SHA512.SHA512)
-#else
-          decodeUtf8 $ Base16.encode $ SHA512.hash $ encodeUtf8 s
-#endif
     _ ->
       throwError
         $  ErrorCall
diff --git a/src/Nix/Exec.hs b/src/Nix/Exec.hs
--- a/src/Nix/Exec.hs
+++ b/src/Nix/Exec.hs
@@ -33,7 +33,6 @@
 import           Control.Monad.Catch     hiding ( catchJust )
 import           Control.Monad.Fix
 import           Control.Monad.Reader
-import           Control.Monad.Trans.Reader     ( ReaderT(..) )
 import           Data.Fix
 import qualified Data.HashMap.Lazy             as M
 import           Data.List
diff --git a/src/Nix/Expr/Strings.hs b/src/Nix/Expr/Strings.hs
--- a/src/Nix/Expr/Strings.hs
+++ b/src/Nix/Expr/Strings.hs
@@ -8,7 +8,6 @@
                                                 , dropWhileEnd
                                                 , inits
                                                 )
-import           Data.Monoid                    ( (<>) )
 import           Data.Text                      ( Text )
 import qualified Data.Text                     as T
 import           Data.Tuple                     ( swap )
diff --git a/src/Nix/Fresh.hs b/src/Nix/Fresh.hs
--- a/src/Nix/Fresh.hs
+++ b/src/Nix/Fresh.hs
@@ -21,9 +21,6 @@
 import           Control.Monad.Ref
 import           Control.Monad.ST
 import           Data.Typeable
-#ifdef MIN_VERSION_haskeline
-import System.Console.Haskeline.MonadException hiding(catch)
-#endif
 
 import           Nix.Var
 import           Nix.Thunk
@@ -42,9 +39,7 @@
     , MonadIO
     , MonadCatch
     , MonadThrow
-#ifdef MIN_VERSION_haskeline
-    , MonadException
-#endif
+    , MonadMask
     )
 
 instance MonadTrans (FreshIdT i) where
diff --git a/src/Nix/Parser.hs b/src/Nix/Parser.hs
--- a/src/Nix/Parser.hs
+++ b/src/Nix/Parser.hs
@@ -58,7 +58,6 @@
                                                 , isSpace
                                                 )
 import           Data.Data                      ( Data(..) )
-import           Data.Foldable                  ( concat )
 import           Data.Functor
 import           Data.Functor.Identity
 import           Data.HashSet                   ( HashSet )
@@ -66,7 +65,6 @@
 import           Data.List.NonEmpty             ( NonEmpty(..) )
 import qualified Data.List.NonEmpty            as NE
 import qualified Data.Map                      as Map
-import           Data.Text                      ( Text )
 import           Data.Text               hiding ( map
                                                 , foldr1
                                                 , concat
diff --git a/src/Nix/Reduce.hs b/src/Nix/Reduce.hs
--- a/src/Nix/Reduce.hs
+++ b/src/Nix/Reduce.hs
@@ -40,9 +40,6 @@
 import           Control.Monad.IO.Class
 import           Control.Monad.Reader
 import           Control.Monad.State.Strict
-import           Control.Monad.Trans.Reader     ( ReaderT(..) )
-import           Control.Monad.Trans.State.Strict
-                                                ( StateT(..) )
 import           Data.Fix
 -- import           Data.Foldable
 import           Data.HashMap.Lazy              ( HashMap )
diff --git a/src/Nix/Standard.hs b/src/Nix/Standard.hs
--- a/src/Nix/Standard.hs
+++ b/src/Nix/Standard.hs
@@ -47,9 +47,6 @@
 import           Nix.Value
 import           Nix.Value.Monad
 import           Nix.Var
-#ifdef MIN_VERSION_haskeline
-import           System.Console.Haskeline.MonadException hiding(catch)
-#endif
 
 -- All of the following type classes defer to the underlying 'm'.
 
@@ -69,21 +66,6 @@
 deriving instance MonadExec (t (Fix1T t m) m) => MonadExec (Fix1T t m)
 deriving instance MonadIntrospect (t (Fix1T t m) m) => MonadIntrospect (Fix1T t m)
 
-#ifdef MIN_VERSION_haskeline
--- For whatever reason, using the default StateT instance provided by
--- haskeline does not work.
-instance MonadException m
-  => MonadException(StateT(HashMap FilePath NExprLoc) m) where
-  controlIO f = StateT $ \s -> controlIO $ \(RunIO run) -> let
-    run' = RunIO(fmap(StateT . const) . run . flip runStateT s)
-    in fmap(flip runStateT s) $ f run'
-
-instance MonadException m => MonadException(Fix1T StandardTF m) where
-  controlIO f = mkStandardT $ controlIO $ \(RunIO run) ->
-    let run' = RunIO(fmap mkStandardT . run . runStandardT)
-    in runStandardT <$> f run'
-#endif
-
 type MonadFix1T t m = (MonadTrans (Fix1T t), Monad (t (Fix1T t m) m))
 
 instance (MonadFix1T t m, MonadRef m) => MonadRef (Fix1T t m) where
@@ -219,6 +201,7 @@
     , MonadIO
     , MonadCatch
     , MonadThrow
+    , MonadMask
     , MonadReader (Context r (StdValue r))
     , MonadState (HashMap FilePath NExprLoc)
     )
diff --git a/src/Nix/Type/Infer.hs b/src/Nix/Type/Infer.hs
--- a/src/Nix/Type/Infer.hs
+++ b/src/Nix/Type/Infer.hs
@@ -40,7 +40,6 @@
 import           Data.Foldable
 import qualified Data.HashMap.Lazy             as M
 import           Data.List                      ( delete
-                                                , find
                                                 , nub
                                                 , intersect
                                                 , (\\)
diff --git a/src/Nix/Utils.hs b/src/Nix/Utils.hs
--- a/src/Nix/Utils.hs
+++ b/src/Nix/Utils.hs
@@ -25,9 +25,7 @@
 import           Data.HashMap.Lazy              ( HashMap )
 import qualified Data.HashMap.Lazy             as M
 import           Data.List                      ( sortOn )
-import           Data.Monoid                    ( Endo
-                                                , (<>)
-                                                )
+import           Data.Monoid                    ( Endo )
 import           Data.Text                      ( Text )
 import qualified Data.Text                     as Text
 import qualified Data.Vector                   as V
diff --git a/src/Nix/Utils/Fix1.hs b/src/Nix/Utils/Fix1.hs
--- a/src/Nix/Utils/Fix1.hs
+++ b/src/Nix/Utils/Fix1.hs
@@ -48,6 +48,7 @@
 deriving instance MonadIO (t (Fix1T t m) m) => MonadIO (Fix1T t m)
 deriving instance MonadCatch (t (Fix1T t m) m) => MonadCatch (Fix1T t m)
 deriving instance MonadThrow (t (Fix1T t m) m) => MonadThrow (Fix1T t m)
+deriving instance MonadMask (t (Fix1T t m) m) => MonadMask (Fix1T t m)
 
 deriving instance MonadReader e (t (Fix1T t m) m) => MonadReader e (Fix1T t m)
 deriving instance MonadState s (t (Fix1T t m) m) => MonadState s (Fix1T t m)
diff --git a/src/Nix/Value.hs b/src/Nix/Value.hs
--- a/src/Nix/Value.hs
+++ b/src/Nix/Value.hs
@@ -30,20 +30,23 @@
 
 module Nix.Value where
 
-import           Control.Comonad
-import           Control.Exception
-import           Control.Monad
-import           Control.Monad.Free
-import           Control.Monad.Trans.Class
+import           Control.Comonad                ( Comonad, extract )
+import           Control.Exception              ( Exception )
+import           Control.Monad                  ( (<=<) )
+import           Control.Monad.Free             ( Free(..)
+                                                , hoistFree, iter, iterM )
+import           Control.Monad.Trans.Class      ( MonadTrans, lift )
 import qualified Data.Aeson                    as A
-import           Data.Functor.Classes
+import           Data.Functor.Classes           ( Show1
+                                                , liftShowsPrec
+                                                , showsUnaryWith )
 import           Data.HashMap.Lazy              ( HashMap )
 import           Data.Text                      ( Text )
 import           Data.Typeable                  ( Typeable )
-import           GHC.Generics
-import           Lens.Family2
-import           Lens.Family2.Stock
-import           Lens.Family2.TH
+import           GHC.Generics                   ( Generic )
+import           Lens.Family2.Stock             ( _1 )
+import           Lens.Family2.TH                ( makeTraversals
+                                                , makeLenses )
 import           Nix.Atoms
 import           Nix.Expr.Types
 import           Nix.Expr.Types.Annotated
diff --git a/tests/files/attrs.nix b/tests/files/attrs.nix
new file mode 100644
--- /dev/null
+++ b/tests/files/attrs.nix
@@ -0,0 +1,12 @@
+rec {
+
+  y = 2;
+  z = { w = 4; };
+  v = rec {
+    u = 6;
+    t = [ u z.w s.q ];
+  };
+  s = { r = import ./goodbye.nix; q = 10; };
+  p = import ./hello.nix;
+
+}
diff --git a/tests/files/callLibs.nix b/tests/files/callLibs.nix
new file mode 100644
--- /dev/null
+++ b/tests/files/callLibs.nix
@@ -0,0 +1,3 @@
+let callLibs = file: import file { lib = self; };
+    trivial = callLibs ./trivial.nix;
+in trivial
diff --git a/tests/files/eighty.nix b/tests/files/eighty.nix
new file mode 100644
--- /dev/null
+++ b/tests/files/eighty.nix
@@ -0,0 +1,1 @@
+80
diff --git a/tests/files/file.nix b/tests/files/file.nix
new file mode 100644
--- /dev/null
+++ b/tests/files/file.nix
@@ -0,0 +1,1 @@
+({ x ? 1, y ? x * 3 }: import ./file2.nix { a = y; }) {}
diff --git a/tests/files/file2.nix b/tests/files/file2.nix
new file mode 100644
--- /dev/null
+++ b/tests/files/file2.nix
@@ -0,0 +1,1 @@
+{ a }: a + 100
diff --git a/tests/files/findFile.nix b/tests/files/findFile.nix
new file mode 100644
--- /dev/null
+++ b/tests/files/findFile.nix
diff --git a/tests/files/force.nix b/tests/files/force.nix
new file mode 100644
--- /dev/null
+++ b/tests/files/force.nix
@@ -0,0 +1,1 @@
+let f = { a = 1; b = import ./hello.nix; }; in f.a
diff --git a/tests/files/goodbye.nix b/tests/files/goodbye.nix
new file mode 100644
--- /dev/null
+++ b/tests/files/goodbye.nix
@@ -0,0 +1,1 @@
+"Goodbye, world!"
diff --git a/tests/files/hello.nix b/tests/files/hello.nix
new file mode 100644
--- /dev/null
+++ b/tests/files/hello.nix
@@ -0,0 +1,1 @@
+"Hello, world!"
diff --git a/tests/files/hello2.nix b/tests/files/hello2.nix
new file mode 100644
--- /dev/null
+++ b/tests/files/hello2.nix
@@ -0,0 +1,15 @@
+let x = { z = x: import ./eighty.nix + 20 + x; w = 123; };
+            allPackages = self:
+              super:
+                let
+                  res = import ./eighty.nix {
+                    inherit lib nixpkgsFun noSysDirs
+                            config;
+                  } null self;
+                in res;
+    y = "Hello";
+    z = "Goodbye";
+    f = x: if x == 0 then x * 2 else x + 2;
+    w = x.z 5 + f 3 - 15;
+in assert w == 1;
+   if x.z 2 == 100 then y else 3
diff --git a/tests/files/if-then.nix b/tests/files/if-then.nix
new file mode 100644
--- /dev/null
+++ b/tests/files/if-then.nix
@@ -0,0 +1,6 @@
+# [ ({ a = 1; b = 2; } // { c = 1; d = 2; })
+#   ([1 2 3] ++ [4.0 5.0 6.0])
+#   (x: y: x + y)
+# ]
+
+({ x, y ? x + 1 }: x + x)
diff --git a/tests/files/lint.nix b/tests/files/lint.nix
new file mode 100644
--- /dev/null
+++ b/tests/files/lint.nix
@@ -0,0 +1,1 @@
+{ x, y }: let z = x + y; in [ z (y + 2) ]
diff --git a/tests/files/loop.nix b/tests/files/loop.nix
new file mode 100644
--- /dev/null
+++ b/tests/files/loop.nix
@@ -0,0 +1,144 @@
+(with builtins;
+{ localSystem ? builtins.intersectAttrs {
+     system = null;
+     platform = null;
+   } args
+   , system ? null
+   , platform ? null
+   , crossSystem ? null
+   , config ? {}
+   , overlays ? []
+   , ... }@args:
+  ({ localSystem
+   , crossSystem ? null
+   , config ? null
+   , overlays ? null
+   , stdenvStages ? { lib, localSystem, crossSystem, config, overlays }@args:
+     let
+       inherit (
+         rec {
+           stageFun = step:
+             last:
+               { shell ? "/bin/bash"
+               , overrides ? (self: super: {})
+               , allowedRequisites ? null }:
+                 let
+                   name = "bootstrap-stage${toString step}";
+                   thisStdenv = (let
+                     fix' = f: let x = f x // { __unfix__ = null; }; in x;
+                     makeExtensible = rattrs: fix' rattrs // { extend = null; };
+                     lib = makeExtensible (self:
+                         let callLibs = file: import file { lib = self; };
+                         in with self; {
+                           customisation =
+                             callLibs <nixpkgs/lib/customisation.nix>;
+                           trivial =
+                             callLibs <nixpkgs/lib/trivial.nix>;
+                           inherit (customisation) makeOverridable;
+                           inherit (trivial) functionArgs setFunctionArgs;
+                         });
+                   in lib.makeOverridable ({ name ? null
+                                           , preHook ? null
+                                           , initialPath
+                                           , shell
+                                           , allowedRequisites ? null
+                                           , overrides ? (self: super: {})
+                                           , config
+                                           , buildPlatform
+                                           , hostPlatform
+                                           , targetPlatform }:
+                     let
+                       defaultBuildInputs = [];
+                       stdenv = derivation
+                         ({ allowedRequisites =
+                              allowedRequisites ++
+                              defaultBuildInputs;
+                          } // {
+                         inherit name;
+                         inherit (buildPlatform) system;
+                         builder = shell;
+                       }) // {
+                         inherit overrides;
+                       };
+                     in stdenv)) {
+                     name = "${name}-stdenv-darwin";
+                     inherit config shell;
+                     allowedRequisites = if allowedRequisites == null
+                       then null else allowedRequisites ++ [];
+                     buildPlatform = localSystem;
+                     hostPlatform = localSystem;
+                     targetPlatform = localSystem;
+                     initialPath = [];
+                     overrides = self: super: (overrides self super) // { fetchurl = null; };
+                   };
+                 in {
+                   inherit config overlays;
+                   stdenv = thisStdenv;
+                 };
+           stage0 = stageFun 0 null {
+             overrides = self: super: super;
+           };
+           stage1 = prevStage:
+             with prevStage;
+             stageFun 1 prevStage {
+               allowedRequisites = [
+                 (pkgs.darwin.Libsystem) # THUNK FORCE STARTS HERE
+               ];
+               overrides = sefl: super: {};
+             };
+           stagesDarwin = [ ({  }: stage0) stage1 ];
+         }) stagesDarwin;
+     in stagesDarwin }@args:
+    let
+      lib = let
+        fix' = f: let x = f x // { __unfix__ = null; }; in x;
+        makeExtensible = rattrs: fix' rattrs // { extend = null; };
+        in makeExtensible (self:
+            let callLibs = file: import file { lib = self; };
+            in with self;
+            {
+              fixedPoints = callLibs <nixpkgs/lib/fixed-points.nix>;
+              lists = callLibs <nixpkgs/lib/lists.nix>;
+              inherit (fixedPoints) fix extends;
+              inherit (lists) foldl' imap1;
+            });
+
+      allPackages = newArgs:
+        ({ lib
+         , nixpkgsFun
+         , stdenv
+         , allowCustomOverrides
+         , noSysDirs ? null
+         , config
+         , overlays }:
+          let
+            allPackages = pkgs: super: {
+              pkgs = pkgs;
+              darwin = pkgs.darwin; # THUNK FORCE LOOPS: self-reference
+            };
+          in lib.fix (lib.foldl' (x: y: lib.extends y x) (self:
+              {}) ([
+              (self: super: { inherit stdenv; })
+              allPackages
+              (self: super: super.stdenv.overrides null super)
+            ]))) ({ inherit lib nixpkgsFun; } // newArgs);
+
+       withAllowCustomOverrides = lib.lists.imap1 (index: stageFun: prevStage:
+           { allowCustomOverrides = index == 1; } // stageFun prevStage)
+         (lib.lists.reverseList
+          (stdenvStages {
+             inherit lib localSystem crossSystem config overlays;
+           }));
+
+       go = n:
+         if n == builtins.length withAllowCustomOverrides
+         then {}
+         else let
+           succ = go (n + 1);
+           in allPackages (builtins.elemAt withAllowCustomOverrides n succ);
+     in go 0)
+
+  (args // {
+     inherit config overlays crossSystem;
+     localSystem = { system = builtins.currentSystem; };
+   })) {}
diff --git a/tests/files/test.nix b/tests/files/test.nix
new file mode 100644
--- /dev/null
+++ b/tests/files/test.nix
@@ -0,0 +1,12 @@
+let x = rec {
+
+  y = 2;
+  z = { w = 4; };
+  v = rec {
+    u = 6;
+    t = [ u z.w s.q ];
+  };
+  s = { r = import ./goodbye.nix; q = 10; };
+  p = import ./hello.nix;
+
+}; o = 100; in [ x.v.t x.z.w x.p x.p ]
diff --git a/tests/files/with.nix b/tests/files/with.nix
new file mode 100644
--- /dev/null
+++ b/tests/files/with.nix
@@ -0,0 +1,1 @@
+with { x = 1; }; with { x = 2; }; y
