diff --git a/avro.cabal b/avro.cabal
--- a/avro.cabal
+++ b/avro.cabal
@@ -5,7 +5,7 @@
 -- hash: 307ace222c16e9660fc8fd8f1d3b126a4254daea39bb616b93782a86b81d73b0
 
 name:           avro
-version:        0.3.4.2
+version:        0.3.4.3
 synopsis:       Avro serialization support for Haskell
 description:    Avro serialization and deserialization support for Haskell
 category:       Data
@@ -23,6 +23,7 @@
     test/data/deconflict/writer.avsc
     test/data/enums-object.json
     test/data/enums.avsc
+    test/data/internal-bindings.avsc
     test/data/karma.avsc
     test/data/logical.avsc
     test/data/maybe.avsc
@@ -136,6 +137,7 @@
       Avro.THSimpleSpec
       Avro.THUnionSpec
       Avro.ToAvroSpec
+      Avro.SchemaSpec
       DecodeContainer
       Example1
       Paths_avro
diff --git a/src/Data/Avro/Schema.hs b/src/Data/Avro/Schema.hs
--- a/src/Data/Avro/Schema.hs
+++ b/src/Data/Avro/Schema.hs
@@ -544,6 +544,7 @@
         Union {..}  -> concatMap go options
         Fixed {..}  -> mk name aliases namespace
         Array {..}  -> go item
+        Map {..}    -> go values
         _           -> []
 
 -- | Checks that two schemas match. This is like equality of schemas,
diff --git a/test/Avro/SchemaSpec.hs b/test/Avro/SchemaSpec.hs
new file mode 100644
--- /dev/null
+++ b/test/Avro/SchemaSpec.hs
@@ -0,0 +1,38 @@
+{-# LANGUAGE DeriveGeneric       #-}
+{-# LANGUAGE OverloadedStrings   #-}
+{-# LANGUAGE ScopedTypeVariables #-}
+{-# LANGUAGE TemplateHaskell     #-}
+module Avro.SchemaSpec
+where
+
+import           Data.Avro
+import           Data.Avro.Deriving (makeSchema)
+import           Data.Avro.Schema   (buildTypeEnvironment, matches)
+
+import           Test.Hspec
+
+{-# ANN module ("HLint: ignore Redundant do"        :: String) #-}
+
+spec :: Spec
+spec = describe "Avro.SchemaSpec" $ do
+  describe "buildTypeEnvironment" $
+    it "should contain definitions for all internal types" $ do
+      let schema      = $(makeSchema "test/data/internal-bindings.avsc")
+          environment = buildTypeEnvironment err schema
+          err name    = fail $ "Missing " ++ show name ++ " in environment."
+          expected    =
+            [ "InternalBindings"
+            , "InField"
+            , "NestedInField"
+            , "AliasNestedInField"
+            , "NestedEnum"
+            , "NestedFixed"
+            , "InArray"
+            , "NestedInArray"
+            , "InMap"
+            , "NestedInMap"
+            , "InUnionA"
+            , "InUnionB"
+            ]
+      definitions <- traverse environment expected
+      length definitions `shouldBe` length expected
diff --git a/test/data/internal-bindings.avsc b/test/data/internal-bindings.avsc
new file mode 100644
--- /dev/null
+++ b/test/data/internal-bindings.avsc
@@ -0,0 +1,105 @@
+{
+  "name" : "InternalBindings",
+  "type" : "record",
+  "doc" : "A test record that includes subdefinitions nested in different ways.",
+  "fields" : [
+    {
+      "name" : "inField",
+      "doc" : "A record definition nested in a field of a record.",
+      "type" : {
+        "name" : "InField",
+        "type" : "record",
+        "fields" : [
+          {
+            "name" : "nestedInField",
+            "doc" : "A record definition nested in two other records.",
+            "type" : {
+              "name" : "NestedInField",
+              "type" : "record",
+              "aliases" : ["AliasNestedInField"],
+              "fields" : []
+            }
+          },
+          {
+            "name" : "nestedEnum",
+            "doc" : "An enum definition nested in a nested record.",
+            "type" : {
+              "type" : "enum",
+              "name" : "NestedEnum",
+              "symbols" : ["Foo", "Bar"]
+            }
+          },
+          {
+            "name" : "nestedFixed",
+            "doc" : "A fixed definition nested in a nested record.",
+            "type" : {
+              "type" : "fixed",
+              "size" : 42,
+              "name" : "NestedFixed"
+            }
+          }
+        ]
+      }
+    },
+    {
+      "name" : "inArray",
+      "doc" : "A record definition nested in an array type.",
+      "type" : {
+        "type" : "array",
+        "items" : {
+          "name" : "InArray",
+          "type" : "record",
+          "fields" : [
+            {
+              "name" : "nestedInArray",
+              "doc" : "A record definition nested inside a record defined in an array.",
+              "type" : {
+                "name" : "NestedInArray",
+                "type" : "record",
+                "fields" : []
+              }
+            }
+          ]
+        }
+      }
+    },
+    {
+      "name" : "inMap",
+      "doc" : "A record definition nested in a map type.",
+      "type" : {
+        "type" : "map",
+        "values" : {
+          "name" : "InMap",
+          "type" : "record",
+          "fields" : [
+            {
+              "name" : "nestedInMap",
+              "doc" : "A record definition nested inside a record defined in a map.",
+              "type" : {
+                "name" : "NestedInMap",
+                "type" : "record",
+                "fields" : []
+              }
+            }
+          ]
+        }
+      }
+    },
+    {
+      "name" : "inUnion",
+      "doc" : "Record definitions nested in a union.",
+      "type" : [
+        {
+          "name" : "InUnionA",
+          "type" : "record",
+          "fields" : []
+        },
+        {
+          "name" : "InUnionB",
+          "type" : "record",
+          "fields" : []
+        }
+      ]
+    }
+  ]
+}
