diff --git a/crates/hir/src/code_model.rs b/crates/hir/src/code_model.rs
index a4141e11198..aaa7013b66a 100644
--- a/crates/hir/src/code_model.rs
+++ b/crates/hir/src/code_model.rs
@@ -90,7 +90,7 @@ impl Crate {
     }
 
     pub fn root_module(self, db: &dyn HirDatabase) -> Module {
-        let module_id = db.crate_def_map(self.id).root;
+        let module_id = db.crate_def_map(self.id).root();
         Module::new(self, module_id)
     }
 
@@ -302,7 +302,7 @@ impl Module {
     /// in the module tree of any target in `Cargo.toml`.
     pub fn crate_root(self, db: &dyn HirDatabase) -> Module {
         let def_map = db.crate_def_map(self.id.krate);
-        self.with_module_id(def_map.root)
+        self.with_module_id(def_map.root())
     }
 
     /// Iterates over all child modules.
@@ -1000,7 +1000,7 @@ impl MacroDef {
     /// early, in `hir_expand`, where modules simply do not exist yet.
     pub fn module(self, db: &dyn HirDatabase) -> Option<Module> {
         let krate = self.id.krate;
-        let module_id = db.crate_def_map(krate).root;
+        let module_id = db.crate_def_map(krate).root();
         Some(Module::new(Crate { id: krate }, module_id))
     }
 
diff --git a/crates/hir_def/src/find_path.rs b/crates/hir_def/src/find_path.rs
index 422a6eeb4a8..d7b7b9cc0dc 100644
--- a/crates/hir_def/src/find_path.rs
+++ b/crates/hir_def/src/find_path.rs
@@ -51,7 +51,7 @@ fn check_self_super(def_map: &DefMap, item: ItemInNs, from: ModuleId) -> Option<
     if item == ItemInNs::Types(from.into()) {
         // - if the item is the module we're in, use `self`
         Some(ModPath::from_segments(PathKind::Super(0), Vec::new()))
-    } else if let Some(parent_id) = def_map.modules[from.local_id].parent {
+    } else if let Some(parent_id) = def_map[from.local_id].parent {
         // - if the item is the parent module, use `super` (this is not used recursively, since `super::super` is ugly)
         if item
             == ItemInNs::Types(ModuleDefId::ModuleId(ModuleId {
@@ -111,7 +111,7 @@ fn find_path_inner(
 
     // - if the item is already in scope, return the name under which it is
     let def_map = db.crate_def_map(from.krate);
-    let from_scope: &crate::item_scope::ItemScope = &def_map.modules[from.local_id].scope;
+    let from_scope: &crate::item_scope::ItemScope = &def_map[from.local_id].scope;
     let scope_name =
         if let Some((name, _)) = from_scope.name_of(item) { Some(name.clone()) } else { None };
     if prefixed.is_none() && scope_name.is_some() {
@@ -123,7 +123,7 @@ fn find_path_inner(
     if item
         == ItemInNs::Types(ModuleDefId::ModuleId(ModuleId {
             krate: from.krate,
-            local_id: def_map.root,
+            local_id: def_map.root(),
         }))
     {
         return Some(ModPath::from_segments(PathKind::Crate, Vec::new()));
@@ -147,7 +147,7 @@ fn find_path_inner(
     if let Some(prelude_module) = def_map.prelude {
         let prelude_def_map = db.crate_def_map(prelude_module.krate);
         let prelude_scope: &crate::item_scope::ItemScope =
-            &prelude_def_map.modules[prelude_module.local_id].scope;
+            &prelude_def_map[prelude_module.local_id].scope;
         if let Some((name, vis)) = prelude_scope.name_of(item) {
             if vis.is_visible_from(db, from) {
                 return Some(ModPath::from_segments(PathKind::Plain, vec![name.clone()]));
@@ -175,7 +175,7 @@ fn find_path_inner(
 
     // - otherwise, look for modules containing (reexporting) it and import it from one of those
 
-    let crate_root = ModuleId { local_id: def_map.root, krate: from.krate };
+    let crate_root = ModuleId { local_id: def_map.root(), krate: from.krate };
     let crate_attrs = db.attrs(crate_root.into());
     let prefer_no_std = crate_attrs.by_key("no_std").exists();
     let mut best_path = None;
@@ -287,7 +287,7 @@ fn find_local_import_locations(
 
     // Compute the initial worklist. We start with all direct child modules of `from` as well as all
     // of its (recursive) parent modules.
-    let data = &def_map.modules[from.local_id];
+    let data = &def_map[from.local_id];
     let mut worklist = data
         .children
         .values()
@@ -296,7 +296,7 @@ fn find_local_import_locations(
     let mut parent = data.parent;
     while let Some(p) = parent {
         worklist.push(ModuleId { krate: from.krate, local_id: p });
-        parent = def_map.modules[p].parent;
+        parent = def_map[p].parent;
     }
 
     let mut seen: FxHashSet<_> = FxHashSet::default();
diff --git a/crates/hir_def/src/import_map.rs b/crates/hir_def/src/import_map.rs
index fac0de90cd6..0251d016b74 100644
--- a/crates/hir_def/src/import_map.rs
+++ b/crates/hir_def/src/import_map.rs
@@ -75,7 +75,7 @@ impl ImportMap {
 
         // We look only into modules that are public(ly reexported), starting with the crate root.
         let empty = ImportPath { segments: vec![] };
-        let root = ModuleId { krate, local_id: def_map.root };
+        let root = ModuleId { krate, local_id: def_map.root() };
         let mut worklist = vec![(root, empty)];
         while let Some((module, mod_path)) = worklist.pop() {
             let ext_def_map;
diff --git a/crates/hir_def/src/lang_item.rs b/crates/hir_def/src/lang_item.rs
index 30188b740d3..9e90f745ce2 100644
--- a/crates/hir_def/src/lang_item.rs
+++ b/crates/hir_def/src/lang_item.rs
@@ -84,7 +84,7 @@ impl LangItems {
 
         let crate_def_map = db.crate_def_map(krate);
 
-        for (_, module_data) in crate_def_map.modules.iter() {
+        for (_, module_data) in crate_def_map.modules() {
             for impl_def in module_data.scope.impls() {
                 lang_items.collect_lang_item(db, impl_def, LangItemTarget::ImplDefId)
             }
diff --git a/crates/hir_def/src/nameres.rs b/crates/hir_def/src/nameres.rs
index 769a557ad78..c3d3efc6bd8 100644
--- a/crates/hir_def/src/nameres.rs
+++ b/crates/hir_def/src/nameres.rs
@@ -75,8 +75,8 @@ use crate::{
 /// Contains all top-level defs from a macro-expanded crate
 #[derive(Debug, PartialEq, Eq)]
 pub struct DefMap {
-    pub root: LocalModuleId,
-    pub modules: Arena<ModuleData>,
+    root: LocalModuleId,
+    modules: Arena<ModuleData>,
     pub(crate) krate: CrateId,
     /// The prelude module for this crate. This either comes from an import
     /// marked with the `prelude_import` attribute, or (in the normal case) from
@@ -208,6 +208,14 @@ impl DefMap {
             .map(|(id, _data)| id)
     }
 
+    pub fn modules(&self) -> impl Iterator<Item = (LocalModuleId, &ModuleData)> + '_ {
+        self.modules.iter()
+    }
+
+    pub fn root(&self) -> LocalModuleId {
+        self.root
+    }
+
     pub(crate) fn resolve_path(
         &self,
         db: &dyn DefDatabase,
diff --git a/crates/hir_def/src/test_db.rs b/crates/hir_def/src/test_db.rs
index 574c0201a79..4ff219fb702 100644
--- a/crates/hir_def/src/test_db.rs
+++ b/crates/hir_def/src/test_db.rs
@@ -75,7 +75,7 @@ impl TestDB {
     pub(crate) fn module_for_file(&self, file_id: FileId) -> crate::ModuleId {
         for &krate in self.relevant_crates(file_id).iter() {
             let crate_def_map = self.crate_def_map(krate);
-            for (local_id, data) in crate_def_map.modules.iter() {
+            for (local_id, data) in crate_def_map.modules() {
                 if data.origin.file_id() == Some(file_id) {
                     return crate::ModuleId { krate, local_id };
                 }
@@ -110,7 +110,7 @@ impl TestDB {
         let crate_graph = self.crate_graph();
         for krate in crate_graph.iter() {
             let crate_def_map = self.crate_def_map(krate);
-            for (module_id, _) in crate_def_map.modules.iter() {
+            for (module_id, _) in crate_def_map.modules() {
                 let file_id = crate_def_map[module_id].origin.file_id();
                 files.extend(file_id)
             }
@@ -135,7 +135,7 @@ impl TestDB {
             let crate_def_map = self.crate_def_map(krate);
 
             let mut sink = DiagnosticSinkBuilder::new().build(&mut cb);
-            for (module_id, module) in crate_def_map.modules.iter() {
+            for (module_id, module) in crate_def_map.modules() {
                 crate_def_map.add_diagnostics(self, module_id, &mut sink);
 
                 for decl in module.scope.declarations() {
diff --git a/crates/hir_ty/src/diagnostics.rs b/crates/hir_ty/src/diagnostics.rs
index c67a289f283..247da43f22d 100644
--- a/crates/hir_ty/src/diagnostics.rs
+++ b/crates/hir_ty/src/diagnostics.rs
@@ -409,7 +409,7 @@ mod tests {
                 let crate_def_map = self.crate_def_map(krate);
 
                 let mut fns = Vec::new();
-                for (module_id, _) in crate_def_map.modules.iter() {
+                for (module_id, _) in crate_def_map.modules() {
                     for decl in crate_def_map[module_id].scope.declarations() {
                         let mut sink = DiagnosticSinkBuilder::new().build(&mut cb);
                         validate_module_item(self, krate, decl, &mut sink);
diff --git a/crates/hir_ty/src/method_resolution.rs b/crates/hir_ty/src/method_resolution.rs
index 8a289f52a65..f06aeeb4286 100644
--- a/crates/hir_ty/src/method_resolution.rs
+++ b/crates/hir_ty/src/method_resolution.rs
@@ -112,7 +112,7 @@ impl TraitImpls {
         let mut impls = Self { map: FxHashMap::default() };
 
         let crate_def_map = db.crate_def_map(krate);
-        for (_module_id, module_data) in crate_def_map.modules.iter() {
+        for (_module_id, module_data) in crate_def_map.modules() {
             for impl_id in module_data.scope.impls() {
                 let target_trait = match db.impl_trait(impl_id) {
                     Some(tr) => tr.value.trait_,
@@ -198,7 +198,7 @@ impl InherentImpls {
         let mut map: FxHashMap<_, Vec<_>> = FxHashMap::default();
 
         let crate_def_map = db.crate_def_map(krate);
-        for (_module_id, module_data) in crate_def_map.modules.iter() {
+        for (_module_id, module_data) in crate_def_map.modules() {
             for impl_id in module_data.scope.impls() {
                 let data = db.impl_data(impl_id);
                 if data.target_trait.is_some() {
diff --git a/crates/hir_ty/src/test_db.rs b/crates/hir_ty/src/test_db.rs
index 646e16bbecf..3bbcbc242a8 100644
--- a/crates/hir_ty/src/test_db.rs
+++ b/crates/hir_ty/src/test_db.rs
@@ -81,7 +81,7 @@ impl TestDB {
     pub(crate) fn module_for_file(&self, file_id: FileId) -> ModuleId {
         for &krate in self.relevant_crates(file_id).iter() {
             let crate_def_map = self.crate_def_map(krate);
-            for (local_id, data) in crate_def_map.modules.iter() {
+            for (local_id, data) in crate_def_map.modules() {
                 if data.origin.file_id() == Some(file_id) {
                     return ModuleId { krate, local_id };
                 }
@@ -95,7 +95,7 @@ impl TestDB {
         let crate_graph = self.crate_graph();
         for krate in crate_graph.iter() {
             let crate_def_map = self.crate_def_map(krate);
-            for (module_id, _) in crate_def_map.modules.iter() {
+            for (module_id, _) in crate_def_map.modules() {
                 let file_id = crate_def_map[module_id].origin.file_id();
                 files.extend(file_id)
             }
diff --git a/crates/ide_db/src/symbol_index.rs b/crates/ide_db/src/symbol_index.rs
index 500bdfd6b23..e954bd72e2a 100644
--- a/crates/ide_db/src/symbol_index.rs
+++ b/crates/ide_db/src/symbol_index.rs
@@ -191,7 +191,7 @@ pub fn crate_symbols(db: &RootDatabase, krate: CrateId, query: Query) -> Vec<Fil
 
     let def_map = db.crate_def_map(krate);
     let mut files = Vec::new();
-    let mut modules = vec![def_map.root];
+    let mut modules = vec![def_map.root()];
     while let Some(module) = modules.pop() {
         let data = &def_map[module];
         files.extend(data.origin.file_id());