diff --git a/src/librustc_infer/infer/error_reporting/mod.rs b/src/librustc_infer/infer/error_reporting/mod.rs
index 925f92edd7da9..942d76e3202b9 100644
--- a/src/librustc_infer/infer/error_reporting/mod.rs
+++ b/src/librustc_infer/infer/error_reporting/mod.rs
@@ -1594,7 +1594,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
                 self.tcx.hir().body_owner_def_id(hir::BodyId { hir_id: cause.body_id })
             });
         self.check_and_note_conflicting_crates(diag, terr);
-        self.tcx.note_and_explain_type_err(diag, terr, span, body_owner_def_id);
+        self.tcx.note_and_explain_type_err(diag, terr, span, body_owner_def_id.to_def_id());
 
         // It reads better to have the error origin as the final
         // thing.
diff --git a/src/librustc_interface/passes.rs b/src/librustc_interface/passes.rs
index 609c80a2b7905..4c054795136b9 100644
--- a/src/librustc_interface/passes.rs
+++ b/src/librustc_interface/passes.rs
@@ -812,7 +812,7 @@ fn analysis(tcx: TyCtxt<'_>, cnum: CrateNum) -> Result<()> {
             {
                 sess.time("match_checking", || {
                     tcx.par_body_owners(|def_id| {
-                        tcx.ensure().check_match(def_id);
+                        tcx.ensure().check_match(def_id.to_def_id());
                     });
                 });
             },
@@ -834,7 +834,7 @@ fn analysis(tcx: TyCtxt<'_>, cnum: CrateNum) -> Result<()> {
     });
 
     sess.time("MIR_borrow_checking", || {
-        tcx.par_body_owners(|def_id| tcx.ensure().mir_borrowck(def_id));
+        tcx.par_body_owners(|def_id| tcx.ensure().mir_borrowck(def_id.to_def_id()));
     });
 
     sess.time("dumping_chalk_like_clauses", || {
@@ -843,7 +843,7 @@ fn analysis(tcx: TyCtxt<'_>, cnum: CrateNum) -> Result<()> {
 
     sess.time("MIR_effect_checking", || {
         for def_id in tcx.body_owners() {
-            mir::transform::check_unsafety::check_unsafety(tcx, def_id)
+            mir::transform::check_unsafety::check_unsafety(tcx, def_id.to_def_id())
         }
     });
 
diff --git a/src/librustc_lint/builtin.rs b/src/librustc_lint/builtin.rs
index 84cf2258ac223..910d53880f22d 100644
--- a/src/librustc_lint/builtin.rs
+++ b/src/librustc_lint/builtin.rs
@@ -1166,7 +1166,7 @@ declare_lint_pass!(
 );
 
 fn check_const(cx: &LateContext<'_, '_>, body_id: hir::BodyId) {
-    let def_id = cx.tcx.hir().body_owner_def_id(body_id);
+    let def_id = cx.tcx.hir().body_owner_def_id(body_id).to_def_id();
     // trigger the query once for all constants since that will already report the errors
     // FIXME: Use ensure here
     let _ = cx.tcx.const_eval_poly(def_id);
diff --git a/src/librustc_middle/hir/map/mod.rs b/src/librustc_middle/hir/map/mod.rs
index e8ce13e06e9f5..3eaacb54d5b42 100644
--- a/src/librustc_middle/hir/map/mod.rs
+++ b/src/librustc_middle/hir/map/mod.rs
@@ -150,16 +150,15 @@ impl<'hir> Map<'hir> {
     }
 
     pub fn def_path_from_hir_id(&self, id: HirId) -> Option<DefPath> {
-        self.opt_local_def_id(id).map(|def_id| self.def_path(def_id.expect_local()))
+        self.opt_local_def_id(id).map(|def_id| self.def_path(def_id))
     }
 
     pub fn def_path(&self, def_id: LocalDefId) -> DefPath {
         self.tcx.definitions.def_path(def_id)
     }
 
-    // FIXME(eddyb) this function can and should return `LocalDefId`.
     #[inline]
-    pub fn local_def_id_from_node_id(&self, node: NodeId) -> DefId {
+    pub fn local_def_id_from_node_id(&self, node: NodeId) -> LocalDefId {
         self.opt_local_def_id_from_node_id(node).unwrap_or_else(|| {
             let hir_id = self.node_id_to_hir_id(node);
             bug!(
@@ -173,24 +172,26 @@ impl<'hir> Map<'hir> {
     // FIXME(eddyb) this function can and should return `LocalDefId`.
     #[inline]
     pub fn local_def_id(&self, hir_id: HirId) -> DefId {
-        self.opt_local_def_id(hir_id).unwrap_or_else(|| {
-            bug!(
-                "local_def_id: no entry for `{:?}`, which has a map of `{:?}`",
-                hir_id,
-                self.find_entry(hir_id)
-            )
-        })
+        self.opt_local_def_id(hir_id)
+            .unwrap_or_else(|| {
+                bug!(
+                    "local_def_id: no entry for `{:?}`, which has a map of `{:?}`",
+                    hir_id,
+                    self.find_entry(hir_id)
+                )
+            })
+            .to_def_id()
     }
 
     #[inline]
-    pub fn opt_local_def_id(&self, hir_id: HirId) -> Option<DefId> {
+    pub fn opt_local_def_id(&self, hir_id: HirId) -> Option<LocalDefId> {
         let node_id = self.hir_id_to_node_id(hir_id);
         self.opt_local_def_id_from_node_id(node_id)
     }
 
     #[inline]
-    pub fn opt_local_def_id_from_node_id(&self, node: NodeId) -> Option<DefId> {
-        Some(self.tcx.definitions.opt_local_def_id(node)?.to_def_id())
+    pub fn opt_local_def_id_from_node_id(&self, node: NodeId) -> Option<LocalDefId> {
+        self.tcx.definitions.opt_local_def_id(node)
     }
 
     #[inline]
@@ -366,9 +367,8 @@ impl<'hir> Map<'hir> {
         parent
     }
 
-    // FIXME(eddyb) this function can and should return `LocalDefId`.
-    pub fn body_owner_def_id(&self, id: BodyId) -> DefId {
-        self.local_def_id(self.body_owner(id))
+    pub fn body_owner_def_id(&self, id: BodyId) -> LocalDefId {
+        self.local_def_id(self.body_owner(id)).expect_local()
     }
 
     /// Given a `HirId`, returns the `BodyId` associated with it,
@@ -720,9 +720,8 @@ impl<'hir> Map<'hir> {
         scope
     }
 
-    // FIXME(eddyb) this function can and should return `LocalDefId`.
-    pub fn get_parent_did(&self, id: HirId) -> DefId {
-        self.local_def_id(self.get_parent_item(id))
+    pub fn get_parent_did(&self, id: HirId) -> LocalDefId {
+        self.local_def_id(self.get_parent_item(id)).expect_local()
     }
 
     pub fn get_foreign_abi(&self, hir_id: HirId) -> Abi {
diff --git a/src/librustc_middle/ty/mod.rs b/src/librustc_middle/ty/mod.rs
index 18518e78e3556..b4c80f623f38a 100644
--- a/src/librustc_middle/ty/mod.rs
+++ b/src/librustc_middle/ty/mod.rs
@@ -2678,13 +2678,13 @@ pub enum ImplOverlapKind {
 
 impl<'tcx> TyCtxt<'tcx> {
     pub fn body_tables(self, body: hir::BodyId) -> &'tcx TypeckTables<'tcx> {
-        self.typeck_tables_of(self.hir().body_owner_def_id(body))
+        self.typeck_tables_of(self.hir().body_owner_def_id(body).to_def_id())
     }
 
     /// Returns an iterator of the `DefId`s for all body-owners in this
     /// crate. If you would prefer to iterate over the bodies
     /// themselves, you can do `self.hir().krate().body_ids.iter()`.
-    pub fn body_owners(self) -> impl Iterator<Item = DefId> + Captures<'tcx> + 'tcx {
+    pub fn body_owners(self) -> impl Iterator<Item = LocalDefId> + Captures<'tcx> + 'tcx {
         self.hir()
             .krate()
             .body_ids
@@ -2692,7 +2692,7 @@ impl<'tcx> TyCtxt<'tcx> {
             .map(move |&body_id| self.hir().body_owner_def_id(body_id))
     }
 
-    pub fn par_body_owners<F: Fn(DefId) + sync::Sync + sync::Send>(self, f: F) {
+    pub fn par_body_owners<F: Fn(LocalDefId) + sync::Sync + sync::Send>(self, f: F) {
         par_iter(&self.hir().krate().body_ids)
             .for_each(|&body_id| f(self.hir().body_owner_def_id(body_id)));
     }
diff --git a/src/librustc_mir/const_eval/fn_queries.rs b/src/librustc_mir/const_eval/fn_queries.rs
index 8ae4f9f4a0d6e..f1dff4fceb498 100644
--- a/src/librustc_mir/const_eval/fn_queries.rs
+++ b/src/librustc_mir/const_eval/fn_queries.rs
@@ -84,11 +84,7 @@ pub fn is_min_const_fn(tcx: TyCtxt<'_>, def_id: DefId) -> bool {
 
 pub fn is_parent_const_impl_raw(tcx: TyCtxt<'_>, hir_id: hir::HirId) -> bool {
     let parent_id = tcx.hir().get_parent_did(hir_id);
-    if !parent_id.is_top_level_module() {
-        is_const_impl_raw(tcx, parent_id.expect_local())
-    } else {
-        false
-    }
+    if !parent_id.is_top_level_module() { is_const_impl_raw(tcx, parent_id) } else { false }
 }
 
 /// Checks whether the function has a `const` modifier or, in case it is an intrinsic, whether
diff --git a/src/librustc_mir/transform/mod.rs b/src/librustc_mir/transform/mod.rs
index 18b3e88c86fee..81ea57e4c004c 100644
--- a/src/librustc_mir/transform/mod.rs
+++ b/src/librustc_mir/transform/mod.rs
@@ -1,7 +1,7 @@
 use crate::{shim, util};
 use rustc_ast::ast;
 use rustc_hir as hir;
-use rustc_hir::def_id::{CrateNum, DefId, DefIdSet, LOCAL_CRATE};
+use rustc_hir::def_id::{CrateNum, DefId, DefIdSet, LocalDefId, LOCAL_CRATE};
 use rustc_hir::intravisit::{self, NestedVisitorMap, Visitor};
 use rustc_index::vec::IndexVec;
 use rustc_middle::mir::{BodyAndCache, ConstQualifs, MirPhase, Promoted};
@@ -62,7 +62,7 @@ fn mir_keys(tcx: TyCtxt<'_>, krate: CrateNum) -> &DefIdSet {
     let mut set = DefIdSet::default();
 
     // All body-owners have MIR associated with them.
-    set.extend(tcx.body_owners());
+    set.extend(tcx.body_owners().map(LocalDefId::to_def_id));
 
     // Additionally, tuple struct/variant constructors have MIR, but
     // they don't have a BodyId, so we need to build them separately.
diff --git a/src/librustc_passes/intrinsicck.rs b/src/librustc_passes/intrinsicck.rs
index cc1af630cdd3c..ad5a649a24a9f 100644
--- a/src/librustc_passes/intrinsicck.rs
+++ b/src/librustc_passes/intrinsicck.rs
@@ -131,8 +131,8 @@ impl Visitor<'tcx> for ItemVisitor<'tcx> {
     fn visit_nested_body(&mut self, body_id: hir::BodyId) {
         let owner_def_id = self.tcx.hir().body_owner_def_id(body_id);
         let body = self.tcx.hir().body(body_id);
-        let param_env = self.tcx.param_env(owner_def_id);
-        let tables = self.tcx.typeck_tables_of(owner_def_id);
+        let param_env = self.tcx.param_env(owner_def_id.to_def_id());
+        let tables = self.tcx.typeck_tables_of(owner_def_id.to_def_id());
         ExprVisitor { tcx: self.tcx, param_env, tables }.visit_body(body);
         self.visit_body(body);
     }
diff --git a/src/librustc_passes/reachable.rs b/src/librustc_passes/reachable.rs
index c0ae6519d2e56..dcf50d7c08990 100644
--- a/src/librustc_passes/reachable.rs
+++ b/src/librustc_passes/reachable.rs
@@ -10,7 +10,7 @@ use rustc_data_structures::sync::Lrc;
 use rustc_hir as hir;
 use rustc_hir::def::{DefKind, Res};
 use rustc_hir::def_id::LOCAL_CRATE;
-use rustc_hir::def_id::{CrateNum, DefId};
+use rustc_hir::def_id::{CrateNum, DefId, LocalDefId};
 use rustc_hir::intravisit::{self, NestedVisitorMap, Visitor};
 use rustc_hir::itemlikevisit::ItemLikeVisitor;
 use rustc_hir::{HirIdSet, Node};
@@ -42,7 +42,7 @@ fn item_might_be_inlined(tcx: TyCtxt<'tcx>, item: &hir::Item<'_>, attrs: Codegen
 fn method_might_be_inlined(
     tcx: TyCtxt<'_>,
     impl_item: &hir::ImplItem<'_>,
-    impl_src: DefId,
+    impl_src: LocalDefId,
 ) -> bool {
     let codegen_fn_attrs = tcx.codegen_fn_attrs(impl_item.hir_id.owner.to_def_id());
     let generics = tcx.generics_of(tcx.hir().local_def_id(impl_item.hir_id));
@@ -54,7 +54,7 @@ fn method_might_be_inlined(
             return true;
         }
     }
-    if let Some(impl_hir_id) = tcx.hir().as_local_hir_id(impl_src) {
+    if let Some(impl_hir_id) = tcx.hir().as_local_hir_id(impl_src.to_def_id()) {
         match tcx.hir().find(impl_hir_id) {
             Some(Node::Item(item)) => item_might_be_inlined(tcx, &item, codegen_fn_attrs),
             Some(..) | None => span_bug!(impl_item.span, "impl did is not an item"),
@@ -171,7 +171,7 @@ impl<'a, 'tcx> ReachableContext<'a, 'tcx> {
                         if generics.requires_monomorphization(self.tcx) || attrs.requests_inline() {
                             true
                         } else {
-                            let impl_did = self.tcx.hir().get_parent_did(hir_id);
+                            let impl_did = self.tcx.hir().get_parent_did(hir_id).to_def_id();
                             // Check the impl. If the generics on the self
                             // type of the impl require inlining, this method
                             // does too.
diff --git a/src/librustc_privacy/lib.rs b/src/librustc_privacy/lib.rs
index 34470c2ded5f9..a6d880667adf2 100644
--- a/src/librustc_privacy/lib.rs
+++ b/src/librustc_privacy/lib.rs
@@ -248,7 +248,7 @@ fn def_id_visibility<'tcx>(
                     }
                 }
                 Node::TraitItem(..) | Node::Variant(..) => {
-                    return def_id_visibility(tcx, tcx.hir().get_parent_did(hir_id));
+                    return def_id_visibility(tcx, tcx.hir().get_parent_did(hir_id).to_def_id());
                 }
                 Node::ImplItem(impl_item) => {
                     match tcx.hir().get(tcx.hir().get_parent_item(hir_id)) {
@@ -270,7 +270,7 @@ fn def_id_visibility<'tcx>(
                             let (mut ctor_vis, mut span, mut descr) =
                                 def_id_visibility(tcx, parent_did);
 
-                            let adt_def = tcx.adt_def(tcx.hir().get_parent_did(hir_id));
+                            let adt_def = tcx.adt_def(tcx.hir().get_parent_did(hir_id).to_def_id());
                             let ctor_did = tcx.hir().local_def_id(vdata.ctor_hir_id().unwrap());
                             let variant = adt_def.variant_with_ctor_id(ctor_did);
 
@@ -309,7 +309,8 @@ fn def_id_visibility<'tcx>(
                             // If the structure is marked as non_exhaustive then lower the
                             // visibility to within the crate.
                             if ctor_vis == ty::Visibility::Public {
-                                let adt_def = tcx.adt_def(tcx.hir().get_parent_did(hir_id));
+                                let adt_def =
+                                    tcx.adt_def(tcx.hir().get_parent_did(hir_id).to_def_id());
                                 if adt_def.non_enum_variant().is_field_list_non_exhaustive() {
                                     ctor_vis =
                                         ty::Visibility::Restricted(DefId::local(CRATE_DEF_INDEX));
diff --git a/src/librustc_save_analysis/dump_visitor.rs b/src/librustc_save_analysis/dump_visitor.rs
index 05eb524dff5e3..5b93c73e07ce2 100644
--- a/src/librustc_save_analysis/dump_visitor.rs
+++ b/src/librustc_save_analysis/dump_visitor.rs
@@ -107,7 +107,7 @@ impl<'l, 'tcx> DumpVisitor<'l, 'tcx> {
     where
         F: FnOnce(&mut Self),
     {
-        let item_def_id = self.tcx.hir().local_def_id_from_node_id(item_id);
+        let item_def_id = self.tcx.hir().local_def_id_from_node_id(item_id).to_def_id();
 
         let tables = if self.tcx.has_typeck_tables(item_def_id) {
             self.tcx.typeck_tables_of(item_def_id)
@@ -423,8 +423,10 @@ impl<'l, 'tcx> DumpVisitor<'l, 'tcx> {
         vis: ast::Visibility,
         attrs: &'l [Attribute],
     ) {
-        let qualname =
-            format!("::{}", self.tcx.def_path_str(self.tcx.hir().local_def_id_from_node_id(id)));
+        let qualname = format!(
+            "::{}",
+            self.tcx.def_path_str(self.tcx.hir().local_def_id_from_node_id(id).to_def_id())
+        );
 
         if !self.span.filter_generated(ident.span) {
             let sig = sig::assoc_const_signature(id, ident.name, typ, expr, &self.save_ctxt);
@@ -470,7 +472,7 @@ impl<'l, 'tcx> DumpVisitor<'l, 'tcx> {
         let name = item.ident.to_string();
         let qualname = format!(
             "::{}",
-            self.tcx.def_path_str(self.tcx.hir().local_def_id_from_node_id(item.id))
+            self.tcx.def_path_str(self.tcx.hir().local_def_id_from_node_id(item.id).to_def_id())
         );
 
         let kind = match item.kind {
@@ -670,7 +672,7 @@ impl<'l, 'tcx> DumpVisitor<'l, 'tcx> {
             }
             v.process_generic_params(generics, "", item.id);
             for impl_item in impl_items {
-                v.process_impl_item(impl_item, map.local_def_id_from_node_id(item.id));
+                v.process_impl_item(impl_item, map.local_def_id_from_node_id(item.id).to_def_id());
             }
         });
     }
@@ -685,7 +687,7 @@ impl<'l, 'tcx> DumpVisitor<'l, 'tcx> {
         let name = item.ident.to_string();
         let qualname = format!(
             "::{}",
-            self.tcx.def_path_str(self.tcx.hir().local_def_id_from_node_id(item.id))
+            self.tcx.def_path_str(self.tcx.hir().local_def_id_from_node_id(item.id).to_def_id())
         );
         let mut val = name.clone();
         if !generics.params.is_empty() {
@@ -751,7 +753,7 @@ impl<'l, 'tcx> DumpVisitor<'l, 'tcx> {
         self.process_generic_params(generics, &qualname, item.id);
         for method in methods {
             let map = &self.tcx.hir();
-            self.process_trait_item(method, map.local_def_id_from_node_id(item.id))
+            self.process_trait_item(method, map.local_def_id_from_node_id(item.id).to_def_id())
         }
     }
 
@@ -1030,7 +1032,9 @@ impl<'l, 'tcx> DumpVisitor<'l, 'tcx> {
                 let name = trait_item.ident.name.to_string();
                 let qualname = format!(
                     "::{}",
-                    self.tcx.def_path_str(self.tcx.hir().local_def_id_from_node_id(trait_item.id))
+                    self.tcx.def_path_str(
+                        self.tcx.hir().local_def_id_from_node_id(trait_item.id).to_def_id()
+                    )
                 );
 
                 if !self.span.filter_generated(trait_item.ident.span) {
@@ -1134,7 +1138,7 @@ impl<'l, 'tcx> DumpVisitor<'l, 'tcx> {
             .tcx
             .hir()
             .opt_local_def_id_from_node_id(id)
-            .and_then(|id| self.save_ctxt.tcx.parent(id))
+            .and_then(|id| self.save_ctxt.tcx.parent(id.to_def_id()))
             .map(id_from_def_id);
 
         match use_tree.kind {
@@ -1173,7 +1177,7 @@ impl<'l, 'tcx> DumpVisitor<'l, 'tcx> {
 
                 // Make a comma-separated list of names of imported modules.
                 let def_id = self.tcx.hir().local_def_id_from_node_id(id);
-                let names = self.tcx.names_imported_by_glob_use(def_id);
+                let names = self.tcx.names_imported_by_glob_use(def_id.to_def_id());
                 let names: Vec<_> = names.iter().map(|n| n.to_string()).collect();
 
                 // Otherwise it's a span with wrong macro expansion info, which
@@ -1227,8 +1231,10 @@ impl<'l, 'tcx> Visitor<'l> for DumpVisitor<'l, 'tcx> {
         // only get called for the root module of a crate.
         assert_eq!(id, ast::CRATE_NODE_ID);
 
-        let qualname =
-            format!("::{}", self.tcx.def_path_str(self.tcx.hir().local_def_id_from_node_id(id)));
+        let qualname = format!(
+            "::{}",
+            self.tcx.def_path_str(self.tcx.hir().local_def_id_from_node_id(id).to_def_id())
+        );
 
         let sm = self.tcx.sess.source_map();
         let filename = sm.span_to_filename(span);
@@ -1273,7 +1279,7 @@ impl<'l, 'tcx> Visitor<'l> for DumpVisitor<'l, 'tcx> {
                         .tcx
                         .hir()
                         .opt_local_def_id_from_node_id(item.id)
-                        .and_then(|id| self.save_ctxt.tcx.parent(id))
+                        .and_then(|id| self.save_ctxt.tcx.parent(id.to_def_id()))
                         .map(id_from_def_id);
                     self.dumper.import(
                         &Access { public: false, reachable: false },
@@ -1311,7 +1317,9 @@ impl<'l, 'tcx> Visitor<'l> for DumpVisitor<'l, 'tcx> {
             TyAlias(_, ref ty_params, _, ref ty) => {
                 let qualname = format!(
                     "::{}",
-                    self.tcx.def_path_str(self.tcx.hir().local_def_id_from_node_id(item.id))
+                    self.tcx.def_path_str(
+                        self.tcx.hir().local_def_id_from_node_id(item.id).to_def_id()
+                    )
                 );
                 let value = match ty {
                     Some(ty) => ty_to_string(&ty),
diff --git a/src/librustc_save_analysis/lib.rs b/src/librustc_save_analysis/lib.rs
index 24b7be0c9b306..cb3032de83ddb 100644
--- a/src/librustc_save_analysis/lib.rs
+++ b/src/librustc_save_analysis/lib.rs
@@ -130,7 +130,7 @@ impl<'l, 'tcx> SaveContext<'l, 'tcx> {
     pub fn get_extern_item_data(&self, item: &ast::ForeignItem) -> Option<Data> {
         let qualname = format!(
             "::{}",
-            self.tcx.def_path_str(self.tcx.hir().local_def_id_from_node_id(item.id))
+            self.tcx.def_path_str(self.tcx.hir().local_def_id_from_node_id(item.id).to_def_id())
         );
         match item.kind {
             ast::ForeignItemKind::Fn(_, ref sig, ref generics, _) => {
@@ -183,7 +183,9 @@ impl<'l, 'tcx> SaveContext<'l, 'tcx> {
             ast::ItemKind::Fn(_, ref sig, .., ref generics, _) => {
                 let qualname = format!(
                     "::{}",
-                    self.tcx.def_path_str(self.tcx.hir().local_def_id_from_node_id(item.id))
+                    self.tcx.def_path_str(
+                        self.tcx.hir().local_def_id_from_node_id(item.id).to_def_id()
+                    )
                 );
                 filter!(self.span_utils, item.ident.span);
                 Some(Data::DefData(Def {
@@ -204,7 +206,9 @@ impl<'l, 'tcx> SaveContext<'l, 'tcx> {
             ast::ItemKind::Static(ref typ, ..) => {
                 let qualname = format!(
                     "::{}",
-                    self.tcx.def_path_str(self.tcx.hir().local_def_id_from_node_id(item.id))
+                    self.tcx.def_path_str(
+                        self.tcx.hir().local_def_id_from_node_id(item.id).to_def_id()
+                    )
                 );
 
                 filter!(self.span_utils, item.ident.span);
@@ -230,7 +234,9 @@ impl<'l, 'tcx> SaveContext<'l, 'tcx> {
             ast::ItemKind::Const(_, ref typ, _) => {
                 let qualname = format!(
                     "::{}",
-                    self.tcx.def_path_str(self.tcx.hir().local_def_id_from_node_id(item.id))
+                    self.tcx.def_path_str(
+                        self.tcx.hir().local_def_id_from_node_id(item.id).to_def_id()
+                    )
                 );
                 filter!(self.span_utils, item.ident.span);
 
@@ -255,7 +261,9 @@ impl<'l, 'tcx> SaveContext<'l, 'tcx> {
             ast::ItemKind::Mod(ref m) => {
                 let qualname = format!(
                     "::{}",
-                    self.tcx.def_path_str(self.tcx.hir().local_def_id_from_node_id(item.id))
+                    self.tcx.def_path_str(
+                        self.tcx.hir().local_def_id_from_node_id(item.id).to_def_id()
+                    )
                 );
 
                 let sm = self.tcx.sess.source_map();
@@ -282,7 +290,9 @@ impl<'l, 'tcx> SaveContext<'l, 'tcx> {
                 let name = item.ident.to_string();
                 let qualname = format!(
                     "::{}",
-                    self.tcx.def_path_str(self.tcx.hir().local_def_id_from_node_id(item.id))
+                    self.tcx.def_path_str(
+                        self.tcx.hir().local_def_id_from_node_id(item.id).to_def_id()
+                    )
                 );
                 filter!(self.span_utils, item.ident.span);
                 let variants_str =
@@ -363,11 +373,11 @@ impl<'l, 'tcx> SaveContext<'l, 'tcx> {
             let name = ident.to_string();
             let qualname = format!(
                 "::{}::{}",
-                self.tcx.def_path_str(self.tcx.hir().local_def_id_from_node_id(scope)),
+                self.tcx.def_path_str(self.tcx.hir().local_def_id_from_node_id(scope).to_def_id()),
                 ident
             );
             filter!(self.span_utils, ident.span);
-            let def_id = self.tcx.hir().local_def_id_from_node_id(field.id);
+            let def_id = self.tcx.hir().local_def_id_from_node_id(field.id).to_def_id();
             let typ = self.tcx.type_of(def_id).to_string();
 
             let id = id_from_node_id(field.id, self);
@@ -399,7 +409,7 @@ impl<'l, 'tcx> SaveContext<'l, 'tcx> {
         // which the method is declared in, followed by the method's name.
         let (qualname, parent_scope, decl_id, docs, attributes) = match self
             .tcx
-            .impl_of_method(self.tcx.hir().local_def_id_from_node_id(id))
+            .impl_of_method(self.tcx.hir().local_def_id_from_node_id(id).to_def_id())
         {
             Some(impl_id) => match self.tcx.hir().get_if_local(impl_id) {
                 Some(Node::Item(item)) => match item.kind {
@@ -448,7 +458,10 @@ impl<'l, 'tcx> SaveContext<'l, 'tcx> {
                     );
                 }
             },
-            None => match self.tcx.trait_of_item(self.tcx.hir().local_def_id_from_node_id(id)) {
+            None => match self
+                .tcx
+                .trait_of_item(self.tcx.hir().local_def_id_from_node_id(id).to_def_id())
+            {
                 Some(def_id) => {
                     let mut docs = String::new();
                     let mut attrs = vec![];
@@ -1073,7 +1086,7 @@ fn id_from_def_id(id: DefId) -> rls_data::Id {
 
 fn id_from_node_id(id: NodeId, scx: &SaveContext<'_, '_>) -> rls_data::Id {
     let def_id = scx.tcx.hir().opt_local_def_id_from_node_id(id);
-    def_id.map(id_from_def_id).unwrap_or_else(|| {
+    def_id.map(|id| id_from_def_id(id.to_def_id())).unwrap_or_else(|| {
         // Create a *fake* `DefId` out of a `NodeId` by subtracting the `NodeId`
         // out of the maximum u32 value. This will work unless you have *billions*
         // of definitions in a single crate (very unlikely to actually happen).
diff --git a/src/librustc_span/def_id.rs b/src/librustc_span/def_id.rs
index 73b46d753d787..fad9f2f613012 100644
--- a/src/librustc_span/def_id.rs
+++ b/src/librustc_span/def_id.rs
@@ -224,6 +224,11 @@ impl LocalDefId {
     pub fn to_def_id(self) -> DefId {
         DefId { krate: LOCAL_CRATE, index: self.local_def_index }
     }
+
+    #[inline]
+    pub fn is_top_level_module(self) -> bool {
+        self.local_def_index == CRATE_DEF_INDEX
+    }
 }
 
 impl fmt::Debug for LocalDefId {
diff --git a/src/librustc_trait_selection/traits/error_reporting/mod.rs b/src/librustc_trait_selection/traits/error_reporting/mod.rs
index f0a157b377076..b2c9d9956cb1a 100644
--- a/src/librustc_trait_selection/traits/error_reporting/mod.rs
+++ b/src/librustc_trait_selection/traits/error_reporting/mod.rs
@@ -358,7 +358,8 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
                                         tcx.hir().body_owner_def_id(hir::BodyId {
                                             hir_id: obligation.cause.body_id,
                                         })
-                                    }),
+                                    })
+                                    .to_def_id(),
                             );
 
                             err.span_label(enclosing_scope_span, s.as_str());
diff --git a/src/librustc_typeck/astconv.rs b/src/librustc_typeck/astconv.rs
index ed7ec1c3b10da..83e56e3c96a96 100644
--- a/src/librustc_typeck/astconv.rs
+++ b/src/librustc_typeck/astconv.rs
@@ -2371,7 +2371,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
 
             let parent_def_id = def_id
                 .and_then(|def_id| tcx.hir().as_local_hir_id(def_id))
-                .map(|hir_id| tcx.hir().get_parent_did(hir_id));
+                .map(|hir_id| tcx.hir().get_parent_did(hir_id).to_def_id());
 
             debug!("qpath_to_ty: parent_def_id={:?}", parent_def_id);
 
diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs
index eebc34d3db8ea..4754f495ca79e 100644
--- a/src/librustc_typeck/check/mod.rs
+++ b/src/librustc_typeck/check/mod.rs
@@ -751,7 +751,7 @@ fn check_mod_item_types(tcx: TyCtxt<'_>, module_def_id: DefId) {
 fn typeck_item_bodies(tcx: TyCtxt<'_>, crate_num: CrateNum) {
     debug_assert!(crate_num == LOCAL_CRATE);
     tcx.par_body_owners(|body_owner_def_id| {
-        tcx.ensure().typeck_tables_of(body_owner_def_id);
+        tcx.ensure().typeck_tables_of(body_owner_def_id.to_def_id());
     });
 }
 
diff --git a/src/librustc_typeck/check/regionck.rs b/src/librustc_typeck/check/regionck.rs
index 393f9f8bdfbaf..f7564623946d8 100644
--- a/src/librustc_typeck/check/regionck.rs
+++ b/src/librustc_typeck/check/regionck.rs
@@ -109,7 +109,7 @@ macro_rules! ignore_err {
 
 impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
     pub fn regionck_expr(&self, body: &'tcx hir::Body<'tcx>) {
-        let subject = self.tcx.hir().body_owner_def_id(body.id());
+        let subject = self.tcx.hir().body_owner_def_id(body.id()).to_def_id();
         let id = body.value.hir_id;
         let mut rcx =
             RegionCtxt::new(self, RepeatingScope(id), id, Subject(subject), self.param_env);
@@ -154,7 +154,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
     /// constraints to add.
     pub fn regionck_fn(&self, fn_id: hir::HirId, body: &'tcx hir::Body<'tcx>) {
         debug!("regionck_fn(id={})", fn_id);
-        let subject = self.tcx.hir().body_owner_def_id(body.id());
+        let subject = self.tcx.hir().body_owner_def_id(body.id()).to_def_id();
         let hir_id = body.value.hir_id;
         let mut rcx =
             RegionCtxt::new(self, RepeatingScope(hir_id), hir_id, Subject(subject), self.param_env);
@@ -290,7 +290,7 @@ impl<'a, 'tcx> RegionCtxt<'a, 'tcx> {
 
         let body_id = body.id();
         self.body_id = body_id.hir_id;
-        self.body_owner = self.tcx.hir().body_owner_def_id(body_id);
+        self.body_owner = self.tcx.hir().body_owner_def_id(body_id).to_def_id();
 
         let call_site =
             region::Scope { id: body.value.hir_id.local_id, data: region::ScopeData::CallSite };
diff --git a/src/librustc_typeck/check/upvar.rs b/src/librustc_typeck/check/upvar.rs
index c6c11ee9d9b5b..2c9e23d8095ca 100644
--- a/src/librustc_typeck/check/upvar.rs
+++ b/src/librustc_typeck/check/upvar.rs
@@ -146,7 +146,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             }
         }
 
-        let body_owner_def_id = self.tcx.hir().body_owner_def_id(body.id());
+        let body_owner_def_id = self.tcx.hir().body_owner_def_id(body.id()).to_def_id();
         assert_eq!(body_owner_def_id, closure_def_id);
         let mut delegate = InferBorrowKind {
             fcx: self,
diff --git a/src/librustc_typeck/check_unused.rs b/src/librustc_typeck/check_unused.rs
index f552b53d8bab8..cc99ae2019939 100644
--- a/src/librustc_typeck/check_unused.rs
+++ b/src/librustc_typeck/check_unused.rs
@@ -12,7 +12,7 @@ pub fn check_crate(tcx: TyCtxt<'_>) {
     let mut used_trait_imports = DefIdSet::default();
     for &body_id in tcx.hir().krate().bodies.keys() {
         let item_def_id = tcx.hir().body_owner_def_id(body_id);
-        let imports = tcx.used_trait_imports(item_def_id);
+        let imports = tcx.used_trait_imports(item_def_id.to_def_id());
         debug!("GatherVisitor: item_def_id={:?} with imports {:#?}", item_def_id, imports);
         used_trait_imports.extend(imports.iter());
     }
diff --git a/src/librustc_typeck/collect.rs b/src/librustc_typeck/collect.rs
index c5e9a288c9ce8..5414a343c68e1 100644
--- a/src/librustc_typeck/collect.rs
+++ b/src/librustc_typeck/collect.rs
@@ -1513,7 +1513,7 @@ fn fn_sig(tcx: TyCtxt<'_>, def_id: DefId) -> ty::PolyFnSig<'_> {
         }
 
         Ctor(data) | Variant(hir::Variant { data, .. }) if data.ctor_hir_id().is_some() => {
-            let ty = tcx.type_of(tcx.hir().get_parent_did(hir_id));
+            let ty = tcx.type_of(tcx.hir().get_parent_did(hir_id).to_def_id());
             let inputs =
                 data.fields().iter().map(|f| tcx.type_of(tcx.hir().local_def_id(f.hir_id)));
             ty::Binder::bind(tcx.mk_fn_sig(
diff --git a/src/librustc_typeck/collect/type_of.rs b/src/librustc_typeck/collect/type_of.rs
index d45c82700689a..985f66694b671 100644
--- a/src/librustc_typeck/collect/type_of.rs
+++ b/src/librustc_typeck/collect/type_of.rs
@@ -59,14 +59,14 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: DefId) -> Ty<'_> {
                 }
             }
             ImplItemKind::OpaqueTy(_) => {
-                if tcx.impl_trait_ref(tcx.hir().get_parent_did(hir_id)).is_none() {
+                if tcx.impl_trait_ref(tcx.hir().get_parent_did(hir_id).to_def_id()).is_none() {
                     report_assoc_ty_on_inherent_impl(tcx, item.span);
                 }
 
                 find_opaque_ty_constraints(tcx, def_id)
             }
             ImplItemKind::TyAlias(ref ty) => {
-                if tcx.impl_trait_ref(tcx.hir().get_parent_did(hir_id)).is_none() {
+                if tcx.impl_trait_ref(tcx.hir().get_parent_did(hir_id).to_def_id()).is_none() {
                     report_assoc_ty_on_inherent_impl(tcx, item.span);
                 }
 
@@ -177,7 +177,7 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: DefId) -> Ty<'_> {
 
         Node::Ctor(&ref def) | Node::Variant(Variant { data: ref def, .. }) => match *def {
             VariantData::Unit(..) | VariantData::Struct(..) => {
-                tcx.type_of(tcx.hir().get_parent_did(hir_id))
+                tcx.type_of(tcx.hir().get_parent_did(hir_id).to_def_id())
             }
             VariantData::Tuple(..) => {
                 let substs = InternalSubsts::identity_for_item(tcx, def_id);
@@ -207,9 +207,11 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: DefId) -> Ty<'_> {
                     tcx.types.usize
                 }
 
-                Node::Variant(Variant { disr_expr: Some(ref e), .. }) if e.hir_id == hir_id => {
-                    tcx.adt_def(tcx.hir().get_parent_did(hir_id)).repr.discr_type().to_ty(tcx)
-                }
+                Node::Variant(Variant { disr_expr: Some(ref e), .. }) if e.hir_id == hir_id => tcx
+                    .adt_def(tcx.hir().get_parent_did(hir_id).to_def_id())
+                    .repr
+                    .discr_type()
+                    .to_ty(tcx),
 
                 Node::Ty(&Ty { kind: TyKind::Path(_), .. })
                 | Node::Expr(&Expr { kind: ExprKind::Struct(..), .. })
diff --git a/src/librustdoc/clean/inline.rs b/src/librustdoc/clean/inline.rs
index 0906d2f384548..a82015dea5fc8 100644
--- a/src/librustdoc/clean/inline.rs
+++ b/src/librustdoc/clean/inline.rs
@@ -451,7 +451,11 @@ fn build_module(cx: &DocContext<'_>, did: DefId, visited: &mut FxHashSet<DefId>)
                         name: None,
                         attrs: clean::Attributes::default(),
                         source: clean::Span::empty(),
-                        def_id: cx.tcx.hir().local_def_id_from_node_id(ast::CRATE_NODE_ID),
+                        def_id: cx
+                            .tcx
+                            .hir()
+                            .local_def_id_from_node_id(ast::CRATE_NODE_ID)
+                            .to_def_id(),
                         visibility: clean::Public,
                         stability: None,
                         deprecation: None,
diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs
index 03413f67f88fb..66df5eb45bb70 100644
--- a/src/librustdoc/clean/mod.rs
+++ b/src/librustdoc/clean/mod.rs
@@ -419,7 +419,10 @@ impl Clean<Lifetime> for hir::GenericParam<'_> {
 impl Clean<Constant> for hir::ConstArg {
     fn clean(&self, cx: &DocContext<'_>) -> Constant {
         Constant {
-            type_: cx.tcx.type_of(cx.tcx.hir().body_owner_def_id(self.value.body)).clean(cx),
+            type_: cx
+                .tcx
+                .type_of(cx.tcx.hir().body_owner_def_id(self.value.body).to_def_id())
+                .clean(cx),
             expr: print_const_expr(cx, self.value.body),
             value: None,
             is_literal: is_literal_expr(cx, self.value.body.hir_id),
@@ -1551,7 +1554,7 @@ impl<'tcx> Clean<Type> for Ty<'tcx> {
                 BareFunction(box BareFunctionDecl {
                     unsafety: sig.unsafety(),
                     generic_params: Vec::new(),
-                    decl: (local_def_id, sig).clean(cx),
+                    decl: (local_def_id.to_def_id(), sig).clean(cx),
                     abi: sig.abi(),
                 })
             }
@@ -2261,7 +2264,7 @@ impl Clean<Vec<Item>> for doctree::Import<'_> {
             name: None,
             attrs: self.attrs.clean(cx),
             source: self.whence.clean(cx),
-            def_id: cx.tcx.hir().local_def_id_from_node_id(ast::CRATE_NODE_ID),
+            def_id: cx.tcx.hir().local_def_id_from_node_id(ast::CRATE_NODE_ID).to_def_id(),
             visibility: self.vis.clean(cx),
             stability: None,
             deprecation: None,
diff --git a/src/librustdoc/core.rs b/src/librustdoc/core.rs
index 98f4b592fea6e..762ec7e9ac3c6 100644
--- a/src/librustdoc/core.rs
+++ b/src/librustdoc/core.rs
@@ -152,12 +152,15 @@ impl<'tcx> DocContext<'tcx> {
         self.tcx
             .hir()
             .opt_local_def_id(id)
-            .and_then(|def_id| self.tcx.lookup_stability(def_id))
+            .and_then(|def_id| self.tcx.lookup_stability(def_id.to_def_id()))
             .cloned()
     }
 
     pub fn deprecation(&self, id: HirId) -> Option<attr::Deprecation> {
-        self.tcx.hir().opt_local_def_id(id).and_then(|def_id| self.tcx.lookup_deprecation(def_id))
+        self.tcx
+            .hir()
+            .opt_local_def_id(id)
+            .and_then(|def_id| self.tcx.lookup_deprecation(def_id.to_def_id()))
     }
 }