diff --git a/dhall-nix.cabal b/dhall-nix.cabal
--- a/dhall-nix.cabal
+++ b/dhall-nix.cabal
@@ -1,6 +1,6 @@
 Name: dhall-nix
-Version: 1.1.13
-Cabal-Version: >=1.8.0.2
+Version: 1.1.14
+Cabal-Version: >=1.10
 Build-Type: Simple
 Tested-With: GHC == 8.0.1
 License: BSD3
@@ -30,13 +30,15 @@
         base                      >= 4.8.0.0 && < 5   ,
         containers                              < 0.7 ,
         data-fix                                < 0.3 ,
-        dhall                     >= 1.31    && < 1.32,
+        dhall                     >= 1.31    && < 1.33,
         hnix                      >= 0.7     && < 0.8 ,
-        neat-interpolation                      < 0.5 ,
+        lens-family-core          >= 1.0.0   && < 2.2 ,
+        neat-interpolation                      < 0.6 ,
         text                      >= 0.8.0.0 && < 1.3
     Exposed-Modules:
         Dhall.Nix
     GHC-Options: -Wall
+    Default-Language: Haskell2010
     if os(windows) || impl(eta)
         Buildable: False
         
@@ -55,5 +57,6 @@
         optparse-generic >= 1.1.1   && < 1.4,
         text
     GHC-Options: -Wall
+    Default-Language: Haskell2010
     if os(windows)
         Buildable: False
diff --git a/exec/Main.hs b/exec/Main.hs
--- a/exec/Main.hs
+++ b/exec/Main.hs
@@ -44,7 +44,7 @@
 
     inText <- Data.Text.IO.getContents
 
-    expr <- case Dhall.Parser.exprFromText "(stdin)" inText of
+    expr <- case Dhall.Parser.exprFromText "(input)" inText of
         Left  err  -> Control.Exception.throwIO err
         Right expr -> return expr
 
diff --git a/src/Dhall/Nix.hs b/src/Dhall/Nix.hs
--- a/src/Dhall/Nix.hs
+++ b/src/Dhall/Nix.hs
@@ -1,6 +1,7 @@
 {-# LANGUAGE DeriveDataTypeable #-}
 {-# LANGUAGE OverloadedStrings  #-}
 {-# LANGUAGE OverloadedLists    #-}
+{-# LANGUAGE RecordWildCards    #-}
 {-# LANGUAGE QuasiQuotes        #-}
 {-# LANGUAGE TypeFamilies       #-}
 
@@ -93,11 +94,13 @@
 import Control.Exception (Exception)
 import Data.Foldable (toList)
 import Data.Fix (Fix(..))
+import Data.Text (Text)
 import Data.Traversable (for)
 import Data.Typeable (Typeable)
 import Data.Void (Void, absurd)
 import Dhall.Core
-    ( Chunks(..)
+    ( Binding(..)
+    , Chunks(..)
     , Const(..)
     , DhallDouble(..)
     , Expr(..)
@@ -105,6 +108,7 @@
     , PreferAnnotation(..)
     , Var(..)
     )
+import Lens.Family (toListOf)
 import Nix.Atoms (NAtom(..))
 import Nix.Expr
     ( Antiquoted(..)
@@ -123,6 +127,7 @@
 import qualified Data.Text
 import qualified Dhall.Core
 import qualified Dhall.Map
+import qualified Dhall.Optics
 import qualified NeatInterpolation
 import qualified Nix
 
@@ -215,9 +220,76 @@
     the expression to `dhallToNix`
 -}
 dhallToNix :: Expr s Void -> Either CompileError (Fix NExprF)
-dhallToNix e = loop (Dhall.Core.normalize e)
+dhallToNix e =
+    loop (rewriteShadowed (Dhall.Core.normalize e))
   where
     untranslatable = Fix (NSet NNonRecursive [])
+
+    -- This is an intermediate utility used to remove all occurrences of
+    -- shadowing (since Nix does not support references to shadowed variables)
+    --
+    -- This finds how many bound variables of the same name that we need to
+    -- descend past to reach the "deepest" reference to the current bound
+    -- variable.  In other words, the result is the "depth" of the deepest
+    -- reference.
+    --
+    -- If `Nothing` then the current bound variable doesn't need to be renamed.
+    -- If any other number, then rename the variable to include the maximum
+    -- depth.
+    maximumDepth :: Var -> Expr s Void -> Maybe Int
+    maximumDepth v@(V x n) (Lam x' a b)
+        | x == x' =
+            max (maximumDepth v a) (fmap (+ 1) (maximumDepth (V x (n + 1)) b))
+    maximumDepth v@(V x n) (Pi x' a b)
+        | x == x' =
+            max (maximumDepth v a) (fmap (+ 1) (maximumDepth (V x (n + 1)) b))
+    maximumDepth (V x n) (Let (Binding { variable = x' }) a)
+        | x == x' = fmap (+ 1) (maximumDepth (V x (n + 1)) a)
+    maximumDepth v (Var v')
+        | v == v' = Just 0
+    maximumDepth v expression =
+        foldr max Nothing
+            (map
+                (maximumDepth v)
+                (toListOf Dhall.Core.subExpressions expression)
+            )
+
+    -- Higher-level utility that builds on top of `maximumDepth` to rename a
+    -- variable if there are shadowed references to that variable
+    rename :: (Text, Expr s Void) -> Maybe (Text, Expr s Void)
+    rename (x, expression) =
+        case maximumDepth (V x 0) expression of
+            Nothing ->
+                Nothing
+            Just 0 ->
+                Nothing
+            Just n ->
+                Just
+                  ( x'
+                  , Dhall.Core.subst (V x 0) (Var (V x' 0)) (Dhall.Core.shift 1 (V x' 0) expression)
+                  )
+              where
+                x' = x <> Data.Text.pack (show n)
+
+    renameShadowed :: Expr s Void -> Maybe (Expr s Void)
+    renameShadowed (Lam x a b) = do
+        (x', b') <- rename (x, b)
+
+        return (Lam x' a b')
+    renameShadowed (Pi x a b) = do
+        (x', b') <- rename (x, b)
+
+        return (Pi x' a b')
+    renameShadowed (Let Binding{ variable = x, .. } a) = do
+        (x' , a') <- rename (x, a)
+
+        return (Let Binding{ variable = x', .. } a')
+    renameShadowed _ = do
+        Nothing
+
+    -- Even higher-level utility that renames all shadowed references
+    rewriteShadowed =
+        Dhall.Optics.rewriteOf Dhall.Core.subExpressions renameShadowed
 
     loop (Const _) = return untranslatable
     loop (Var (V a 0)) = return (Fix (NSym a))
