From 5b5964f569ca07ba54710cb440aacaa1cf1e5c1a Mon Sep 17 00:00:00 2001 From: Vadim Petrochenkov Date: Mon, 25 Apr 2022 22:08:45 +0300 Subject: [PATCH] rustc: Panic by default in `DefIdTree::parent` Only crate root def-ids don't have a parent, and in majority of cases the argument of `DefIdTree::parent` cannot be a crate root. So we now panic by default in `parent` and introduce a new non-panicing function `opt_parent` for cases where the argument can be a crate root. Same applies to `local_parent`/`opt_local_parent`. --- .../rustc_borrowck/src/diagnostics/mod.rs | 2 +- .../rustc_codegen_llvm/src/debuginfo/utils.rs | 2 +- .../src/const_eval/fn_queries.rs | 2 +- .../rustc_const_eval/src/util/call_kind.rs | 6 +- .../infer/error_reporting/need_type_info.rs | 8 +- .../error_reporting/nice_region_error/util.rs | 2 +- compiler/rustc_lint/src/types.rs | 6 +- compiler/rustc_middle/src/hir/map/mod.rs | 2 +- compiler/rustc_middle/src/middle/stability.rs | 2 +- compiler/rustc_middle/src/ty/context.rs | 2 +- compiler/rustc_middle/src/ty/diagnostics.rs | 2 +- compiler/rustc_middle/src/ty/mod.rs | 36 +++++-- compiler/rustc_middle/src/ty/print/mod.rs | 4 +- compiler/rustc_middle/src/ty/print/pretty.rs | 4 +- compiler/rustc_middle/src/ty/sty.rs | 2 +- compiler/rustc_middle/src/ty/util.rs | 8 +- .../rustc_mir_build/src/thir/pattern/mod.rs | 4 +- .../src/partitioning/default.rs | 2 +- compiler/rustc_passes/src/dead.rs | 6 +- compiler/rustc_passes/src/entry.rs | 2 +- compiler/rustc_passes/src/liveness.rs | 6 +- compiler/rustc_passes/src/reachable.rs | 3 +- compiler/rustc_privacy/src/lib.rs | 10 +- .../rustc_resolve/src/build_reduced_graph.rs | 2 +- compiler/rustc_resolve/src/diagnostics.rs | 4 +- compiler/rustc_resolve/src/imports.rs | 9 +- compiler/rustc_resolve/src/late.rs | 8 +- compiler/rustc_resolve/src/late/lifetimes.rs | 96 +++++++++---------- compiler/rustc_resolve/src/lib.rs | 3 +- .../rustc_save_analysis/src/dump_visitor.rs | 15 ++- compiler/rustc_save_analysis/src/lib.rs | 2 +- .../src/traits/error_reporting/suggestions.rs | 2 +- compiler/rustc_typeck/src/astconv/mod.rs | 6 +- .../rustc_typeck/src/check/fn_ctxt/_impl.rs | 2 +- .../rustc_typeck/src/check/method/suggest.rs | 2 +- compiler/rustc_typeck/src/collect.rs | 2 +- compiler/rustc_typeck/src/collect/type_of.rs | 2 +- src/librustdoc/clean/mod.rs | 10 +- src/librustdoc/clean/utils.rs | 2 +- src/librustdoc/html/format.rs | 2 +- .../passes/calculate_doc_coverage.rs | 2 +- .../passes/collect_intra_doc_links.rs | 18 ++-- .../passes/collect_intra_doc_links/early.rs | 4 +- src/librustdoc/passes/collect_trait_impls.rs | 4 +- .../src/matches/redundant_pattern_match.rs | 2 +- .../src/methods/bind_instead_of_map.rs | 8 +- .../clippy_lints/src/methods/chars_cmp.rs | 2 +- .../src/methods/option_map_or_none.rs | 2 +- .../clippy/clippy_lints/src/missing_doc.rs | 2 +- src/tools/clippy/clippy_utils/src/lib.rs | 2 +- 50 files changed, 162 insertions(+), 176 deletions(-) diff --git a/compiler/rustc_borrowck/src/diagnostics/mod.rs b/compiler/rustc_borrowck/src/diagnostics/mod.rs index b81360fd6aa..368c0be794b 100644 --- a/compiler/rustc_borrowck/src/diagnostics/mod.rs +++ b/compiler/rustc_borrowck/src/diagnostics/mod.rs @@ -90,7 +90,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { { if let ty::FnDef(id, _) = *literal.ty().kind() { debug!("add_moved_or_invoked_closure_note: id={:?}", id); - if self.infcx.tcx.parent(id) == self.infcx.tcx.lang_items().fn_once_trait() { + if Some(self.infcx.tcx.parent(id)) == self.infcx.tcx.lang_items().fn_once_trait() { let closure = match args.first() { Some(Operand::Copy(ref place)) | Some(Operand::Move(ref place)) if target == place.local_or_deref_local() => diff --git a/compiler/rustc_codegen_llvm/src/debuginfo/utils.rs b/compiler/rustc_codegen_llvm/src/debuginfo/utils.rs index fe9851cfa56..8f243673907 100644 --- a/compiler/rustc_codegen_llvm/src/debuginfo/utils.rs +++ b/compiler/rustc_codegen_llvm/src/debuginfo/utils.rs @@ -46,7 +46,7 @@ pub fn DIB<'a, 'll>(cx: &'a CodegenCx<'ll, '_>) -> &'a DIBuilder<'ll> { } pub fn get_namespace_for_item<'ll>(cx: &CodegenCx<'ll, '_>, def_id: DefId) -> &'ll DIScope { - item_namespace(cx, cx.tcx.parent(def_id).expect("get_namespace_for_item: missing parent?")) + item_namespace(cx, cx.tcx.parent(def_id)) } #[derive(Debug, PartialEq, Eq)] diff --git a/compiler/rustc_const_eval/src/const_eval/fn_queries.rs b/compiler/rustc_const_eval/src/const_eval/fn_queries.rs index 19a543ae777..1f291db55be 100644 --- a/compiler/rustc_const_eval/src/const_eval/fn_queries.rs +++ b/compiler/rustc_const_eval/src/const_eval/fn_queries.rs @@ -17,7 +17,7 @@ pub fn is_unstable_const_fn(tcx: TyCtxt<'_>, def_id: DefId) -> Option { } pub fn is_parent_const_impl_raw(tcx: TyCtxt<'_>, def_id: LocalDefId) -> bool { - let parent_id = tcx.local_parent(def_id).unwrap(); + let parent_id = tcx.local_parent(def_id); tcx.def_kind(parent_id) == DefKind::Impl && tcx.impl_constness(parent_id) == hir::Constness::Const } diff --git a/compiler/rustc_const_eval/src/util/call_kind.rs b/compiler/rustc_const_eval/src/util/call_kind.rs index 60b45856f51..a7a480dd1d7 100644 --- a/compiler/rustc_const_eval/src/util/call_kind.rs +++ b/compiler/rustc_const_eval/src/util/call_kind.rs @@ -128,9 +128,9 @@ pub fn call_kind<'tcx>( } else { None }; - let parent_self_ty = tcx - .parent(method_did) - .filter(|did| tcx.def_kind(*did) == rustc_hir::def::DefKind::Impl) + let parent_did = tcx.parent(method_did); + let parent_self_ty = (tcx.def_kind(parent_did) == rustc_hir::def::DefKind::Impl) + .then_some(parent_did) .and_then(|did| match tcx.type_of(did).kind() { ty::Adt(def, ..) => Some(def.did()), _ => None, diff --git a/compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs b/compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs index 465358de932..b1eb9f0da87 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs @@ -341,7 +341,7 @@ impl InferenceDiagnosticsData { impl InferenceDiagnosticsParentData { fn for_def_id(tcx: TyCtxt<'_>, def_id: DefId) -> Option { - let parent_def_id = tcx.parent(def_id)?; + let parent_def_id = tcx.parent(def_id); let parent_name = tcx.def_key(parent_def_id).disambiguated_data.data.get_opt_name()?.to_string(); @@ -854,10 +854,8 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { if let Some((DefKind::AssocFn, def_id)) = self.in_progress_typeck_results?.borrow().type_dependent_def(hir_id) { - return self - .tcx - .parent(def_id) - .filter(|&parent_def_id| self.tcx.is_trait(parent_def_id)); + let parent_def_id = self.tcx.parent(def_id); + return self.tcx.is_trait(parent_def_id).then_some(parent_def_id); } None diff --git a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/util.rs b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/util.rs index 7d3ed2ed38a..da03d944ceb 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/util.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/util.rs @@ -42,7 +42,7 @@ pub fn find_param_with_region<'tcx>( let (id, bound_region) = match *anon_region { ty::ReFree(ref free_region) => (free_region.scope, free_region.bound_region), ty::ReEarlyBound(ebr) => { - (tcx.parent(ebr.def_id).unwrap(), ty::BoundRegionKind::BrNamed(ebr.def_id, ebr.name)) + (tcx.parent(ebr.def_id), ty::BoundRegionKind::BrNamed(ebr.def_id, ebr.name)) } _ => return None, // not a free region }; diff --git a/compiler/rustc_lint/src/types.rs b/compiler/rustc_lint/src/types.rs index 437104d1aaf..dfce30171ff 100644 --- a/compiler/rustc_lint/src/types.rs +++ b/compiler/rustc_lint/src/types.rs @@ -1471,7 +1471,7 @@ impl InvalidAtomicOrdering { && let Some(adt) = cx.tcx.type_of(impl_did).ty_adt_def() // skip extension traits, only lint functions from the standard library && cx.tcx.trait_id_of_impl(impl_did).is_none() - && let Some(parent) = cx.tcx.parent(adt.did()) + && let parent = cx.tcx.parent(adt.did()) && cx.tcx.is_diagnostic_item(sym::atomic_mod, parent) && ATOMIC_TYPES.contains(&cx.tcx.item_name(adt.did())) { @@ -1486,9 +1486,9 @@ impl InvalidAtomicOrdering { orderings.iter().any(|ordering| { tcx.item_name(did) == *ordering && { let parent = tcx.parent(did); - parent == atomic_ordering + Some(parent) == atomic_ordering // needed in case this is a ctor, not a variant - || parent.map_or(false, |parent| tcx.parent(parent) == atomic_ordering) + || tcx.opt_parent(parent) == atomic_ordering } }) } diff --git a/compiler/rustc_middle/src/hir/map/mod.rs b/compiler/rustc_middle/src/hir/map/mod.rs index e0ed4022839..85e53559c29 100644 --- a/compiler/rustc_middle/src/hir/map/mod.rs +++ b/compiler/rustc_middle/src/hir/map/mod.rs @@ -546,7 +546,7 @@ impl<'hir> Map<'hir> { let def_kind = self.tcx.def_kind(def_id); match def_kind { DefKind::Trait | DefKind::TraitAlias => def_id, - DefKind::TyParam | DefKind::ConstParam => self.tcx.local_parent(def_id).unwrap(), + DefKind::TyParam | DefKind::ConstParam => self.tcx.local_parent(def_id), _ => bug!("ty_param_owner: {:?} is a {:?} not a type parameter", def_id, def_kind), } } diff --git a/compiler/rustc_middle/src/middle/stability.rs b/compiler/rustc_middle/src/middle/stability.rs index 758658c3d8c..32041143240 100644 --- a/compiler/rustc_middle/src/middle/stability.rs +++ b/compiler/rustc_middle/src/middle/stability.rs @@ -289,7 +289,7 @@ fn suggestion_for_allocator_api( feature: Symbol, ) -> Option<(Span, String, String, Applicability)> { if feature == sym::allocator_api { - if let Some(trait_) = tcx.parent(def_id) { + if let Some(trait_) = tcx.opt_parent(def_id) { if tcx.is_diagnostic_item(sym::Vec, trait_) { let sm = tcx.sess.parse_sess.source_map(); let inner_types = sm.span_extend_to_prev_char(span, '<', true); diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs index 30fe3ffa7e3..f9ef264f68e 100644 --- a/compiler/rustc_middle/src/ty/context.rs +++ b/compiler/rustc_middle/src/ty/context.rs @@ -1491,7 +1491,7 @@ impl<'tcx> TyCtxt<'tcx> { (free_region.scope.expect_local(), free_region.bound_region) } ty::ReEarlyBound(ref ebr) => ( - self.parent(ebr.def_id).unwrap().expect_local(), + self.local_parent(ebr.def_id.expect_local()), ty::BoundRegionKind::BrNamed(ebr.def_id, ebr.name), ), _ => return None, // not a free region diff --git a/compiler/rustc_middle/src/ty/diagnostics.rs b/compiler/rustc_middle/src/ty/diagnostics.rs index f53dc0000ca..a6717746979 100644 --- a/compiler/rustc_middle/src/ty/diagnostics.rs +++ b/compiler/rustc_middle/src/ty/diagnostics.rs @@ -108,7 +108,7 @@ impl<'tcx> Ty<'tcx> { | Placeholder(_) | Error(_) => false, Opaque(did, substs) => { - let parent = tcx.parent(*did).expect("opaque types always have a parent"); + let parent = tcx.parent(*did); if let hir::def::DefKind::TyAlias | hir::def::DefKind::AssocTy = tcx.def_kind(parent) && let Opaque(parent_did, _) = tcx.type_of(parent).kind() && parent_did == did diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs index ec416722c21..af9216a990a 100644 --- a/compiler/rustc_middle/src/ty/mod.rs +++ b/compiler/rustc_middle/src/ty/mod.rs @@ -290,11 +290,28 @@ pub struct ClosureSizeProfileData<'tcx> { } pub trait DefIdTree: Copy { - fn parent(self, id: DefId) -> Option; + fn opt_parent(self, id: DefId) -> Option; #[inline] - fn local_parent(self, id: LocalDefId) -> Option { - Some(self.parent(id.to_def_id())?.expect_local()) + #[track_caller] + fn parent(self, id: DefId) -> DefId { + match self.opt_parent(id) { + Some(id) => id, + // not `unwrap_or_else` to avoid breaking caller tracking + None => bug!("{id:?} doesn't have a parent"), + } + } + + #[inline] + #[track_caller] + fn opt_local_parent(self, id: LocalDefId) -> Option { + self.opt_parent(id.to_def_id()).map(DefId::expect_local) + } + + #[inline] + #[track_caller] + fn local_parent(self, id: LocalDefId) -> LocalDefId { + self.parent(id.to_def_id()).expect_local() } fn is_descendant_of(self, mut descendant: DefId, ancestor: DefId) -> bool { @@ -303,7 +320,7 @@ pub trait DefIdTree: Copy { } while descendant != ancestor { - match self.parent(descendant) { + match self.opt_parent(descendant) { Some(parent) => descendant = parent, None => return false, } @@ -313,7 +330,8 @@ pub trait DefIdTree: Copy { } impl<'tcx> DefIdTree for TyCtxt<'tcx> { - fn parent(self, id: DefId) -> Option { + #[inline] + fn opt_parent(self, id: DefId) -> Option { self.def_key(id).parent.map(|index| DefId { index, ..id }) } } @@ -2123,17 +2141,17 @@ impl<'tcx> TyCtxt<'tcx> { pub fn expect_variant_res(self, res: Res) -> &'tcx VariantDef { match res { Res::Def(DefKind::Variant, did) => { - let enum_did = self.parent(did).unwrap(); + let enum_did = self.parent(did); self.adt_def(enum_did).variant_with_id(did) } Res::Def(DefKind::Struct | DefKind::Union, did) => self.adt_def(did).non_enum_variant(), Res::Def(DefKind::Ctor(CtorOf::Variant, ..), variant_ctor_did) => { - let variant_did = self.parent(variant_ctor_did).unwrap(); - let enum_did = self.parent(variant_did).unwrap(); + let variant_did = self.parent(variant_ctor_did); + let enum_did = self.parent(variant_did); self.adt_def(enum_did).variant_with_ctor_id(variant_ctor_did) } Res::Def(DefKind::Ctor(CtorOf::Struct, ..), ctor_did) => { - let struct_did = self.parent(ctor_did).expect("struct ctor has no parent"); + let struct_did = self.parent(ctor_did); self.adt_def(struct_did).non_enum_variant() } _ => bug!("expect_variant_res used with unexpected res {:?}", res), diff --git a/compiler/rustc_middle/src/ty/print/mod.rs b/compiler/rustc_middle/src/ty/print/mod.rs index c74b3e9d0fc..3fe68f723ec 100644 --- a/compiler/rustc_middle/src/ty/print/mod.rs +++ b/compiler/rustc_middle/src/ty/print/mod.rs @@ -235,11 +235,11 @@ pub trait Printer<'tcx>: Sized { // as the trait. let in_self_mod = match characteristic_def_id_of_type(self_ty) { None => false, - Some(ty_def_id) => self.tcx().parent(ty_def_id) == Some(parent_def_id), + Some(ty_def_id) => self.tcx().parent(ty_def_id) == parent_def_id, }; let in_trait_mod = match impl_trait_ref { None => false, - Some(trait_ref) => self.tcx().parent(trait_ref.def_id) == Some(parent_def_id), + Some(trait_ref) => self.tcx().parent(trait_ref.def_id) == parent_def_id, }; if !in_self_mod && !in_trait_mod { diff --git a/compiler/rustc_middle/src/ty/print/pretty.rs b/compiler/rustc_middle/src/ty/print/pretty.rs index 38362a4cbb9..991666908f9 100644 --- a/compiler/rustc_middle/src/ty/print/pretty.rs +++ b/compiler/rustc_middle/src/ty/print/pretty.rs @@ -408,7 +408,7 @@ pub trait PrettyPrinter<'tcx>: return Ok((self, false)); }; - let actual_parent = self.tcx().parent(def_id); + let actual_parent = self.tcx().opt_parent(def_id); debug!( "try_print_visible_def_path: visible_parent={:?} actual_parent={:?}", visible_parent, actual_parent, @@ -643,7 +643,7 @@ pub trait PrettyPrinter<'tcx>: return Ok(self); } - let parent = self.tcx().parent(def_id).expect("opaque types always have a parent"); + let parent = self.tcx().parent(def_id); match self.tcx().def_kind(parent) { DefKind::TyAlias | DefKind::AssocTy => { if let ty::Opaque(d, _) = *self.tcx().type_of(parent).kind() { diff --git a/compiler/rustc_middle/src/ty/sty.rs b/compiler/rustc_middle/src/ty/sty.rs index 1509de0e930..0d55fe3a392 100644 --- a/compiler/rustc_middle/src/ty/sty.rs +++ b/compiler/rustc_middle/src/ty/sty.rs @@ -1798,7 +1798,7 @@ impl<'tcx> Region<'tcx> { /// function might return the `DefId` of a closure. pub fn free_region_binding_scope(self, tcx: TyCtxt<'_>) -> DefId { match *self { - ty::ReEarlyBound(br) => tcx.parent(br.def_id).unwrap(), + ty::ReEarlyBound(br) => tcx.parent(br.def_id), ty::ReFree(fr) => fr.scope, _ => bug!("free_region_binding_scope invoked on inappropriate region: {:?}", self), } diff --git a/compiler/rustc_middle/src/ty/util.rs b/compiler/rustc_middle/src/ty/util.rs index 918fe49e8e3..c190eec7e5a 100644 --- a/compiler/rustc_middle/src/ty/util.rs +++ b/compiler/rustc_middle/src/ty/util.rs @@ -142,10 +142,10 @@ impl<'tcx> TyCtxt<'tcx> { pub fn res_generics_def_id(self, res: Res) -> Option { match res { Res::Def(DefKind::Ctor(CtorOf::Variant, _), def_id) => { - Some(self.parent(def_id).and_then(|def_id| self.parent(def_id)).unwrap()) + Some(self.parent(self.parent(def_id))) } Res::Def(DefKind::Variant | DefKind::Ctor(CtorOf::Struct, _), def_id) => { - Some(self.parent(def_id).unwrap()) + Some(self.parent(def_id)) } // Other `DefKind`s don't have generics and would ICE when calling // `generics_of`. @@ -500,9 +500,7 @@ impl<'tcx> TyCtxt<'tcx> { pub fn typeck_root_def_id(self, def_id: DefId) -> DefId { let mut def_id = def_id; while self.is_typeck_child(def_id) { - def_id = self.parent(def_id).unwrap_or_else(|| { - bug!("closure {:?} has no parent", def_id); - }); + def_id = self.parent(def_id); } def_id } diff --git a/compiler/rustc_mir_build/src/thir/pattern/mod.rs b/compiler/rustc_mir_build/src/thir/pattern/mod.rs index dbcd701c1ad..5b0aa4309a8 100644 --- a/compiler/rustc_mir_build/src/thir/pattern/mod.rs +++ b/compiler/rustc_mir_build/src/thir/pattern/mod.rs @@ -377,7 +377,7 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> { ) -> PatKind<'tcx> { let res = match res { Res::Def(DefKind::Ctor(CtorOf::Variant, ..), variant_ctor_id) => { - let variant_id = self.tcx.parent(variant_ctor_id).unwrap(); + let variant_id = self.tcx.parent(variant_ctor_id); Res::Def(DefKind::Variant, variant_id) } res => res, @@ -385,7 +385,7 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> { let mut kind = match res { Res::Def(DefKind::Variant, variant_id) => { - let enum_id = self.tcx.parent(variant_id).unwrap(); + let enum_id = self.tcx.parent(variant_id); let adt_def = self.tcx.adt_def(enum_id); if adt_def.is_enum() { let substs = match ty.kind() { diff --git a/compiler/rustc_monomorphize/src/partitioning/default.rs b/compiler/rustc_monomorphize/src/partitioning/default.rs index bf99cd6e424..320765e7af3 100644 --- a/compiler/rustc_monomorphize/src/partitioning/default.rs +++ b/compiler/rustc_monomorphize/src/partitioning/default.rs @@ -352,7 +352,7 @@ fn compute_codegen_unit_name( cgu_def_id = None; } - current_def_id = tcx.parent(current_def_id).unwrap(); + current_def_id = tcx.parent(current_def_id); } let cgu_def_id = cgu_def_id.unwrap(); diff --git a/compiler/rustc_passes/src/dead.rs b/compiler/rustc_passes/src/dead.rs index 3cd18390285..991d0d45546 100644 --- a/compiler/rustc_passes/src/dead.rs +++ b/compiler/rustc_passes/src/dead.rs @@ -88,15 +88,15 @@ impl<'tcx> MarkSymbolVisitor<'tcx> { _ if self.in_pat => {} Res::PrimTy(..) | Res::SelfCtor(..) | Res::Local(..) => {} Res::Def(DefKind::Ctor(CtorOf::Variant, ..), ctor_def_id) => { - let variant_id = self.tcx.parent(ctor_def_id).unwrap(); - let enum_id = self.tcx.parent(variant_id).unwrap(); + let variant_id = self.tcx.parent(ctor_def_id); + let enum_id = self.tcx.parent(variant_id); self.check_def_id(enum_id); if !self.ignore_variant_stack.contains(&ctor_def_id) { self.check_def_id(variant_id); } } Res::Def(DefKind::Variant, variant_id) => { - let enum_id = self.tcx.parent(variant_id).unwrap(); + let enum_id = self.tcx.parent(variant_id); self.check_def_id(enum_id); if !self.ignore_variant_stack.contains(&variant_id) { self.check_def_id(variant_id); diff --git a/compiler/rustc_passes/src/entry.rs b/compiler/rustc_passes/src/entry.rs index db083d0453b..f84b848e08d 100644 --- a/compiler/rustc_passes/src/entry.rs +++ b/compiler/rustc_passes/src/entry.rs @@ -27,7 +27,7 @@ struct EntryContext<'tcx> { impl<'tcx> ItemLikeVisitor<'tcx> for EntryContext<'tcx> { fn visit_item(&mut self, item: &'tcx Item<'tcx>) { - let at_root = self.tcx.local_parent(item.def_id) == Some(CRATE_DEF_ID); + let at_root = self.tcx.opt_local_parent(item.def_id) == Some(CRATE_DEF_ID); find_item(item, self, at_root); } diff --git a/compiler/rustc_passes/src/liveness.rs b/compiler/rustc_passes/src/liveness.rs index 99ea73fe2fe..9eba7fb0811 100644 --- a/compiler/rustc_passes/src/liveness.rs +++ b/compiler/rustc_passes/src/liveness.rs @@ -332,9 +332,9 @@ impl<'tcx> Visitor<'tcx> for IrMaps<'tcx> { let def_id = local_def_id.to_def_id(); // Don't run unused pass for #[derive()] - if let Some(parent) = self.tcx.parent(def_id) - && let DefKind::Impl = self.tcx.def_kind(parent.expect_local()) - && self.tcx.has_attr(parent, sym::automatically_derived) + let parent = self.tcx.local_parent(local_def_id); + if let DefKind::Impl = self.tcx.def_kind(parent) + && self.tcx.has_attr(parent.to_def_id(), sym::automatically_derived) { return; } diff --git a/compiler/rustc_passes/src/reachable.rs b/compiler/rustc_passes/src/reachable.rs index b65e3342613..b603352a9be 100644 --- a/compiler/rustc_passes/src/reachable.rs +++ b/compiler/rustc_passes/src/reachable.rs @@ -280,8 +280,7 @@ impl<'tcx> ReachableContext<'tcx> { self.visit_nested_body(body); } hir::ImplItemKind::Fn(_, body) => { - let impl_def_id = - self.tcx.parent(search_item.to_def_id()).unwrap().expect_local(); + let impl_def_id = self.tcx.local_parent(search_item); if method_might_be_inlined(self.tcx, impl_item, impl_def_id) { self.visit_nested_body(body) } diff --git a/compiler/rustc_privacy/src/lib.rs b/compiler/rustc_privacy/src/lib.rs index 619e0d0341f..ee459d9c129 100644 --- a/compiler/rustc_privacy/src/lib.rs +++ b/compiler/rustc_privacy/src/lib.rs @@ -24,7 +24,8 @@ use rustc_middle::thir::abstract_const::Node as ACNode; use rustc_middle::ty::fold::TypeVisitor; use rustc_middle::ty::query::Providers; use rustc_middle::ty::subst::InternalSubsts; -use rustc_middle::ty::{self, Const, GenericParamDefKind, TraitRef, Ty, TyCtxt, TypeFoldable}; +use rustc_middle::ty::{self, Const, DefIdTree, GenericParamDefKind}; +use rustc_middle::ty::{TraitRef, Ty, TyCtxt, TypeFoldable}; use rustc_session::lint; use rustc_span::hygiene::Transparency; use rustc_span::symbol::{kw, Ident}; @@ -456,9 +457,7 @@ impl<'tcx> EmbargoVisitor<'tcx> { return; } - let item_def_id = local_def_id.to_def_id(); - let macro_module_def_id = - ty::DefIdTree::parent(self.tcx, item_def_id).unwrap().expect_local(); + let macro_module_def_id = self.tcx.local_parent(local_def_id); if self.tcx.hir().opt_def_kind(macro_module_def_id) != Some(DefKind::Mod) { // The macro's parent doesn't correspond to a `mod`, return early (#63164, #65252). return; @@ -477,8 +476,7 @@ impl<'tcx> EmbargoVisitor<'tcx> { if changed_reachability || module_def_id == CRATE_DEF_ID { break; } - module_def_id = - ty::DefIdTree::parent(self.tcx, module_def_id.to_def_id()).unwrap().expect_local(); + module_def_id = self.tcx.local_parent(module_def_id); } } diff --git a/compiler/rustc_resolve/src/build_reduced_graph.rs b/compiler/rustc_resolve/src/build_reduced_graph.rs index 7485dd51863..b4394fcddfc 100644 --- a/compiler/rustc_resolve/src/build_reduced_graph.rs +++ b/compiler/rustc_resolve/src/build_reduced_graph.rs @@ -1388,7 +1388,7 @@ impl<'a, 'b> Visitor<'b> for BuildReducedGraphVisitor<'a, 'b> { && self .r .trait_impl_items - .contains(&ty::DefIdTree::parent(&*self.r, def_id).unwrap().expect_local())) + .contains(&ty::DefIdTree::local_parent(&*self.r, local_def_id))) { // Trait impl item visibility is inherited from its trait when not specified // explicitly. In that case we cannot determine it here in early resolve, diff --git a/compiler/rustc_resolve/src/diagnostics.rs b/compiler/rustc_resolve/src/diagnostics.rs index 7d40ecb18b7..aef9fb57a6a 100644 --- a/compiler/rustc_resolve/src/diagnostics.rs +++ b/compiler/rustc_resolve/src/diagnostics.rs @@ -1321,7 +1321,7 @@ impl<'a> Resolver<'a> { segms.push(ast::PathSegment::from_ident(ident)); let path = Path { span: name_binding.span, segments: segms, tokens: None }; let did = match res { - Res::Def(DefKind::Ctor(..), did) => this.parent(did), + Res::Def(DefKind::Ctor(..), did) => this.opt_parent(did), _ => res.opt_def_id(), }; @@ -1707,7 +1707,7 @@ impl<'a> Resolver<'a> { _, ) = binding.kind { - let def_id = self.parent(ctor_def_id).expect("no parent for a constructor"); + let def_id = self.parent(ctor_def_id); let fields = self.field_names.get(&def_id)?; return fields.iter().map(|name| name.span).reduce(Span::to); // None for `struct Foo()` } diff --git a/compiler/rustc_resolve/src/imports.rs b/compiler/rustc_resolve/src/imports.rs index ef06ec356bd..3d0e2b9921d 100644 --- a/compiler/rustc_resolve/src/imports.rs +++ b/compiler/rustc_resolve/src/imports.rs @@ -13,7 +13,6 @@ use rustc_data_structures::fx::FxHashSet; use rustc_data_structures::intern::Interned; use rustc_errors::{pluralize, struct_span_err, Applicability, MultiSpan}; use rustc_hir::def::{self, PartialRes}; -use rustc_hir::def_id::DefId; use rustc_middle::metadata::ModChild; use rustc_middle::span_bug; use rustc_middle::ty; @@ -345,12 +344,6 @@ pub struct ImportResolver<'a, 'b> { pub r: &'a mut Resolver<'b>, } -impl<'a, 'b> ty::DefIdTree for &'a ImportResolver<'a, 'b> { - fn parent(self, id: DefId) -> Option { - self.r.parent(id) - } -} - impl<'a, 'b> ImportResolver<'a, 'b> { // Import resolution // @@ -696,7 +689,7 @@ impl<'a, 'b> ImportResolver<'a, 'b> { } if !is_prelude && max_vis.get() != ty::Visibility::Invisible && // Allow empty globs. - !max_vis.get().is_at_least(import.vis.get(), &*self) + !max_vis.get().is_at_least(import.vis.get(), &*self.r) { let msg = "glob import doesn't reexport anything because no candidate is public enough"; self.r.lint_buffer.buffer_lint(UNUSED_IMPORTS, import.id, import.span, msg); diff --git a/compiler/rustc_resolve/src/late.rs b/compiler/rustc_resolve/src/late.rs index ca89f610322..b89b9c376af 100644 --- a/compiler/rustc_resolve/src/late.rs +++ b/compiler/rustc_resolve/src/late.rs @@ -1313,12 +1313,8 @@ impl<'a: 'ast, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> { // Figure out if this is a type/trait segment, // which may need lifetime elision performed. let type_def_id = match partial_res.base_res() { - Res::Def(DefKind::AssocTy, def_id) if i + 2 == proj_start => { - self.r.parent(def_id).unwrap() - } - Res::Def(DefKind::Variant, def_id) if i + 1 == proj_start => { - self.r.parent(def_id).unwrap() - } + Res::Def(DefKind::AssocTy, def_id) if i + 2 == proj_start => self.r.parent(def_id), + Res::Def(DefKind::Variant, def_id) if i + 1 == proj_start => self.r.parent(def_id), Res::Def(DefKind::Struct, def_id) | Res::Def(DefKind::Union, def_id) | Res::Def(DefKind::Enum, def_id) diff --git a/compiler/rustc_resolve/src/late/lifetimes.rs b/compiler/rustc_resolve/src/late/lifetimes.rs index 787536d2a38..50428811fff 100644 --- a/compiler/rustc_resolve/src/late/lifetimes.rs +++ b/compiler/rustc_resolve/src/late/lifetimes.rs @@ -534,21 +534,17 @@ fn is_late_bound_map<'tcx>( ) -> Option<(LocalDefId, &'tcx FxHashSet)> { match tcx.def_kind(def_id) { DefKind::AnonConst | DefKind::InlineConst => { - let mut def_id = tcx - .parent(def_id.to_def_id()) - .unwrap_or_else(|| bug!("anon const or closure without a parent")); + let mut def_id = tcx.local_parent(def_id); // We search for the next outer anon const or fn here // while skipping closures. // // Note that for `AnonConst` we still just recurse until we // find a function body, but who cares :shrug: - while tcx.is_closure(def_id) { - def_id = tcx - .parent(def_id) - .unwrap_or_else(|| bug!("anon const or closure without a parent")); + while tcx.is_closure(def_id.to_def_id()) { + def_id = tcx.local_parent(def_id); } - tcx.is_late_bound_map(def_id.expect_local()) + tcx.is_late_bound_map(def_id) } _ => resolve_lifetimes_for(tcx, def_id).late_bound.get(&def_id).map(|lt| (def_id, lt)), } @@ -1864,7 +1860,7 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> { let remove_decl = self .tcx .parent(def_id) - .and_then(|parent_def_id| parent_def_id.as_local()) + .as_local() .and_then(|parent_def_id| self.tcx.hir().get_generics(parent_def_id)) .and_then(|generics| self.lifetime_deletion_span(name, generics)); @@ -2003,37 +1999,36 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> { continue; } - if let Some(parent_def_id) = self.tcx.parent(def_id) { - if let Some(def_id) = parent_def_id.as_local() { - // lifetimes in `derive` expansions don't count (Issue #53738) - if self - .tcx - .get_attrs(def_id.to_def_id()) - .iter() - .any(|attr| attr.has_name(sym::automatically_derived)) - { - continue; - } + let parent_def_id = self.tcx.parent(def_id); + if let Some(def_id) = parent_def_id.as_local() { + // lifetimes in `derive` expansions don't count (Issue #53738) + if self + .tcx + .get_attrs(def_id.to_def_id()) + .iter() + .any(|attr| attr.has_name(sym::automatically_derived)) + { + continue; + } - // opaque types generated when desugaring an async function can have a single - // use lifetime even if it is explicitly denied (Issue #77175) - if let hir::Node::Item(hir::Item { - kind: hir::ItemKind::OpaqueTy(ref opaque), - .. - }) = self.tcx.hir().get_by_def_id(def_id) - { - if !matches!(opaque.origin, hir::OpaqueTyOrigin::AsyncFn(..)) { + // opaque types generated when desugaring an async function can have a single + // use lifetime even if it is explicitly denied (Issue #77175) + if let hir::Node::Item(hir::Item { + kind: hir::ItemKind::OpaqueTy(ref opaque), + .. + }) = self.tcx.hir().get_by_def_id(def_id) + { + if !matches!(opaque.origin, hir::OpaqueTyOrigin::AsyncFn(..)) { + continue 'lifetimes; + } + // We want to do this only if the lifetime identifier is already defined + // in the async function that generated this. Otherwise it could be + // an opaque type defined by the developer and we still want this + // lint to fail compilation + for p in opaque.generics.params { + if defined_by.contains_key(&p.name) { continue 'lifetimes; } - // We want to do this only if the lifetime identifier is already defined - // in the async function that generated this. Otherwise it could be - // an opaque type defined by the developer and we still want this - // lint to fail compilation - for p in opaque.generics.params { - if defined_by.contains_key(&p.name) { - continue 'lifetimes; - } - } } } } @@ -2087,20 +2082,19 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> { |lint| { let mut err = lint .build(&format!("lifetime parameter `{}` never used", name)); - if let Some(parent_def_id) = self.tcx.parent(def_id) { - if let Some(generics) = - self.tcx.hir().get_generics(parent_def_id.expect_local()) - { - let unused_lt_span = - self.lifetime_deletion_span(name, generics); - if let Some(span) = unused_lt_span { - err.span_suggestion( - span, - "elide the unused lifetime", - String::new(), - Applicability::MachineApplicable, - ); - } + let parent_def_id = self.tcx.parent(def_id); + if let Some(generics) = + self.tcx.hir().get_generics(parent_def_id.expect_local()) + { + let unused_lt_span = + self.lifetime_deletion_span(name, generics); + if let Some(span) = unused_lt_span { + err.span_suggestion( + span, + "elide the unused lifetime", + String::new(), + Applicability::MachineApplicable, + ); } } err.emit(); diff --git a/compiler/rustc_resolve/src/lib.rs b/compiler/rustc_resolve/src/lib.rs index 2e625fc1b4f..e173a7f72c4 100644 --- a/compiler/rustc_resolve/src/lib.rs +++ b/compiler/rustc_resolve/src/lib.rs @@ -1109,7 +1109,8 @@ impl<'a> AsMut> for Resolver<'a> { } impl<'a, 'b> DefIdTree for &'a Resolver<'b> { - fn parent(self, id: DefId) -> Option { + #[inline] + fn opt_parent(self, id: DefId) -> Option { match id.as_local() { Some(id) => self.definitions.def_key(id).parent, None => self.cstore().def_key(id).parent, diff --git a/compiler/rustc_save_analysis/src/dump_visitor.rs b/compiler/rustc_save_analysis/src/dump_visitor.rs index b4230a144f8..e1c9ecc055f 100644 --- a/compiler/rustc_save_analysis/src/dump_visitor.rs +++ b/compiler/rustc_save_analysis/src/dump_visitor.rs @@ -1138,8 +1138,7 @@ impl<'tcx> Visitor<'tcx> for DumpVisitor<'tcx> { let access = access_from!(self.save_ctxt, item.def_id); let ref_id = self.lookup_def_id(item.hir_id()).map(id_from_def_id); let span = self.span_from_span(sub_span); - let parent = - self.save_ctxt.tcx.parent(item.def_id.to_def_id()).map(id_from_def_id); + let parent = self.save_ctxt.tcx.local_parent(item.def_id); self.dumper.import( &access, Import { @@ -1149,7 +1148,7 @@ impl<'tcx> Visitor<'tcx> for DumpVisitor<'tcx> { alias_span: None, name: item.ident.to_string(), value: String::new(), - parent, + parent: Some(id_from_def_id(parent.to_def_id())), }, ); self.write_sub_paths_truncated(&path); @@ -1166,8 +1165,7 @@ impl<'tcx> Visitor<'tcx> for DumpVisitor<'tcx> { if !self.span.filter_generated(item.span) { let access = access_from!(self.save_ctxt, item.def_id); let span = self.span_from_span(sub_span); - let parent = - self.save_ctxt.tcx.parent(item.def_id.to_def_id()).map(id_from_def_id); + let parent = self.save_ctxt.tcx.local_parent(item.def_id); self.dumper.import( &access, Import { @@ -1177,7 +1175,7 @@ impl<'tcx> Visitor<'tcx> for DumpVisitor<'tcx> { alias_span: None, name: "*".to_owned(), value: names.join(", "), - parent, + parent: Some(id_from_def_id(parent.to_def_id())), }, ); self.write_sub_paths(&path); @@ -1188,8 +1186,7 @@ impl<'tcx> Visitor<'tcx> for DumpVisitor<'tcx> { let name_span = item.ident.span; if !self.span.filter_generated(name_span) { let span = self.span_from_span(name_span); - let parent = - self.save_ctxt.tcx.parent(item.def_id.to_def_id()).map(id_from_def_id); + let parent = self.save_ctxt.tcx.local_parent(item.def_id); self.dumper.import( &Access { public: false, reachable: false }, Import { @@ -1199,7 +1196,7 @@ impl<'tcx> Visitor<'tcx> for DumpVisitor<'tcx> { alias_span: None, name: item.ident.to_string(), value: String::new(), - parent, + parent: Some(id_from_def_id(parent.to_def_id())), }, ); } diff --git a/compiler/rustc_save_analysis/src/lib.rs b/compiler/rustc_save_analysis/src/lib.rs index 582186cbd1f..5d94884e0f6 100644 --- a/compiler/rustc_save_analysis/src/lib.rs +++ b/compiler/rustc_save_analysis/src/lib.rs @@ -690,7 +690,7 @@ impl<'tcx> SaveContext<'tcx> { // This is a reference to a tuple struct or an enum variant where the def_id points // to an invisible constructor function. That is not a very useful // def, so adjust to point to the tuple struct or enum variant itself. - let parent_def_id = self.tcx.parent(def_id).unwrap(); + let parent_def_id = self.tcx.parent(def_id); Some(Ref { kind: RefKind::Type, span, ref_id: id_from_def_id(parent_def_id) }) } Res::Def(HirDefKind::Static(_) | HirDefKind::Const | HirDefKind::AssocConst, _) => { diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs index 446b14a17ae..a3d3c7c0cf3 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs @@ -1906,7 +1906,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> { GeneratorKind::Async(AsyncGeneratorKind::Fn) => self .tcx .parent(generator_did) - .and_then(|parent_did| parent_did.as_local()) + .as_local() .map(|parent_did| hir.local_def_id_to_hir_id(parent_did)) .and_then(|parent_hir_id| hir.opt_name(parent_hir_id)) .map(|name| { diff --git a/compiler/rustc_typeck/src/astconv/mod.rs b/compiler/rustc_typeck/src/astconv/mod.rs index b8422ce3208..fd1b7bfa0b1 100644 --- a/compiler/rustc_typeck/src/astconv/mod.rs +++ b/compiler/rustc_typeck/src/astconv/mod.rs @@ -1952,7 +1952,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { ) -> Ty<'tcx> { let tcx = self.tcx(); - let trait_def_id = tcx.parent(item_def_id).unwrap(); + let trait_def_id = tcx.parent(item_def_id); debug!("qpath_to_ty: trait_def_id={:?}", trait_def_id); @@ -2159,11 +2159,11 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { // `DefKind::Ctor` -> `DefKind::Variant` if let DefKind::Ctor(..) = kind { - def_id = tcx.parent(def_id).unwrap() + def_id = tcx.parent(def_id); } // `DefKind::Variant` -> `DefKind::Enum` - let enum_def_id = tcx.parent(def_id).unwrap(); + let enum_def_id = tcx.parent(def_id); (enum_def_id, last - 1) } else { // FIXME: lint here recommending `Enum::<...>::Variant` form diff --git a/compiler/rustc_typeck/src/check/fn_ctxt/_impl.rs b/compiler/rustc_typeck/src/check/fn_ctxt/_impl.rs index 8feb7170983..93b0edb84c0 100644 --- a/compiler/rustc_typeck/src/check/fn_ctxt/_impl.rs +++ b/compiler/rustc_typeck/src/check/fn_ctxt/_impl.rs @@ -838,7 +838,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let def_kind = self.tcx.def_kind(def_id); let item_ty = if let DefKind::Variant = def_kind { - self.tcx.type_of(self.tcx.parent(def_id).expect("variant w/out parent")) + self.tcx.type_of(self.tcx.parent(def_id)) } else { self.tcx.type_of(def_id) }; diff --git a/compiler/rustc_typeck/src/check/method/suggest.rs b/compiler/rustc_typeck/src/check/method/suggest.rs index 640dccf66b0..634ba2baf96 100644 --- a/compiler/rustc_typeck/src/check/method/suggest.rs +++ b/compiler/rustc_typeck/src/check/method/suggest.rs @@ -1542,7 +1542,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let (candidates, globs): (Vec<_>, Vec<_>) = candidates.into_iter().partition(|trait_did| { if let Some(parent_did) = parent_map.get(trait_did) { // If the item is re-exported as `_`, we should suggest a glob-import instead. - if Some(*parent_did) != self.tcx.parent(*trait_did) + if *parent_did != self.tcx.parent(*trait_did) && self .tcx .module_children(*parent_did) diff --git a/compiler/rustc_typeck/src/collect.rs b/compiler/rustc_typeck/src/collect.rs index f85735ec57b..c1c63c46066 100644 --- a/compiler/rustc_typeck/src/collect.rs +++ b/compiler/rustc_typeck/src/collect.rs @@ -3162,7 +3162,7 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, id: DefId) -> CodegenFnAttrs { // #73631: closures inherit `#[target_feature]` annotations if tcx.features().target_feature_11 && tcx.is_closure(id) { - let owner_id = tcx.parent(id).expect("closure should have a parent"); + let owner_id = tcx.parent(id); codegen_fn_attrs .target_features .extend(tcx.codegen_fn_attrs(owner_id).target_features.iter().copied()) diff --git a/compiler/rustc_typeck/src/collect/type_of.rs b/compiler/rustc_typeck/src/collect/type_of.rs index 495b8d3b4ee..75ad584f419 100644 --- a/compiler/rustc_typeck/src/collect/type_of.rs +++ b/compiler/rustc_typeck/src/collect/type_of.rs @@ -683,7 +683,7 @@ fn find_opaque_ty_constraints(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Ty<'_> { Some(hidden) => hidden.ty, None => { let span = tcx.def_span(def_id); - let name = tcx.item_name(tcx.parent(def_id.to_def_id()).unwrap()); + let name = tcx.item_name(tcx.local_parent(def_id).to_def_id()); let label = format!( "`{}` must be used in combination with a concrete type within the same module", name diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index d458deddae3..eea4eef9065 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -421,7 +421,7 @@ impl Clean for ty::GenericParamDef { // `self_def_id` set, we override it here. // See https://github.com/rust-lang/rust/issues/85454 if let QPath { ref mut self_def_id, .. } = default { - *self_def_id = cx.tcx.parent(self.def_id); + *self_def_id = Some(cx.tcx.parent(self.def_id)); } Some(default) @@ -1068,7 +1068,7 @@ impl Clean for hir::ImplItem<'_> { let mut what_rustc_thinks = Item::from_def_id_and_parts(local_did, Some(self.ident.name), inner, cx); - let impl_ref = cx.tcx.parent(local_did).and_then(|did| cx.tcx.impl_trait_ref(did)); + let impl_ref = cx.tcx.impl_trait_ref(cx.tcx.local_parent(self.def_id)); // Trait impl items always inherit the impl's visibility -- // we don't want to show `pub`. @@ -1260,7 +1260,7 @@ impl Clean for ty::AssocItem { let mut what_rustc_thinks = Item::from_def_id_and_parts(self.def_id, Some(self.name), kind, cx); - let impl_ref = tcx.parent(self.def_id).and_then(|did| tcx.impl_trait_ref(did)); + let impl_ref = tcx.impl_trait_ref(tcx.parent(self.def_id)); // Trait impl items always inherit the impl's visibility -- // we don't want to show `pub`. @@ -1742,9 +1742,7 @@ fn clean_field(def_id: DefId, name: Symbol, ty: Type, cx: &mut DocContext<'_>) - } fn is_field_vis_inherited(tcx: TyCtxt<'_>, def_id: DefId) -> bool { - let parent = tcx - .parent(def_id) - .expect("is_field_vis_inherited can only be called on struct or variant fields"); + let parent = tcx.parent(def_id); match tcx.def_kind(parent) { DefKind::Struct | DefKind::Union => false, DefKind::Variant => true, diff --git a/src/librustdoc/clean/utils.rs b/src/librustdoc/clean/utils.rs index abfc5b80a3e..3a2f24d719c 100644 --- a/src/librustdoc/clean/utils.rs +++ b/src/librustdoc/clean/utils.rs @@ -455,7 +455,7 @@ crate fn find_nearest_parent_module(tcx: TyCtxt<'_>, def_id: DefId) -> Option { // documented on their parent's page - tcx.parent(did).unwrap() + tcx.parent(did) } _ => did, }; diff --git a/src/librustdoc/passes/calculate_doc_coverage.rs b/src/librustdoc/passes/calculate_doc_coverage.rs index 33d83aa339d..0d40ef4c600 100644 --- a/src/librustdoc/passes/calculate_doc_coverage.rs +++ b/src/librustdoc/passes/calculate_doc_coverage.rs @@ -239,7 +239,7 @@ impl<'a, 'b> DocVisitor for CoverageCalculator<'a, 'b> { let should_be_ignored = i .item_id .as_def_id() - .and_then(|def_id| self.ctx.tcx.parent(def_id)) + .and_then(|def_id| self.ctx.tcx.opt_parent(def_id)) .and_then(|def_id| self.ctx.tcx.hir().get_if_local(def_id)) .map(|node| { matches!( diff --git a/src/librustdoc/passes/collect_intra_doc_links.rs b/src/librustdoc/passes/collect_intra_doc_links.rs index 42e87f3f961..7a68a6e523b 100644 --- a/src/librustdoc/passes/collect_intra_doc_links.rs +++ b/src/librustdoc/passes/collect_intra_doc_links.rs @@ -333,7 +333,7 @@ impl ItemFragment { FragmentKind::StructField => write!(s, "structfield.{}", name), FragmentKind::Variant => write!(s, "variant.{}", name), FragmentKind::VariantField => { - let variant = tcx.item_name(tcx.parent(def_id).unwrap()); + let variant = tcx.item_name(tcx.parent(def_id)); write!(s, "variant.{}.field.{}", variant, name) } } @@ -508,10 +508,10 @@ impl<'a, 'tcx> LinkCollector<'a, 'tcx> { | DefKind::AssocTy | DefKind::Variant | DefKind::Field) => { - let parent_def_id = tcx.parent(def_id).expect("nested item has no parent"); + let parent_def_id = tcx.parent(def_id); if def_kind == DefKind::Field && tcx.def_kind(parent_def_id) == DefKind::Variant { - tcx.parent(parent_def_id).expect("variant has no parent") + tcx.parent(parent_def_id) } else { parent_def_id } @@ -2333,14 +2333,10 @@ fn handle_variant( cx: &DocContext<'_>, res: Res, ) -> Result<(Res, Option), ErrorKind<'static>> { - cx.tcx - .parent(res.def_id(cx.tcx)) - .map(|parent| { - let parent_def = Res::Def(DefKind::Enum, parent); - let variant = cx.tcx.expect_variant_res(res.as_hir_res().unwrap()); - (parent_def, Some(ItemFragment(FragmentKind::Variant, variant.def_id))) - }) - .ok_or_else(|| ResolutionFailure::NoParentItem.into()) + let parent = cx.tcx.parent(res.def_id(cx.tcx)); + let parent_def = Res::Def(DefKind::Enum, parent); + let variant = cx.tcx.expect_variant_res(res.as_hir_res().unwrap()); + Ok((parent_def, Some(ItemFragment(FragmentKind::Variant, variant.def_id)))) } /// Resolve a primitive type or value. diff --git a/src/librustdoc/passes/collect_intra_doc_links/early.rs b/src/librustdoc/passes/collect_intra_doc_links/early.rs index 68e10e3a18c..cd096c88003 100644 --- a/src/librustdoc/passes/collect_intra_doc_links/early.rs +++ b/src/librustdoc/passes/collect_intra_doc_links/early.rs @@ -188,7 +188,7 @@ impl EarlyDocLinkResolver<'_, '_> { return; } // FIXME: actually resolve links, not just add traits in scope. - if let Some(parent_id) = self.resolver.parent(scope_id) { + if let Some(parent_id) = self.resolver.opt_parent(scope_id) { self.add_traits_in_scope(parent_id); } } @@ -253,7 +253,7 @@ impl EarlyDocLinkResolver<'_, '_> { { if let Some(def_id) = child.res.opt_def_id() && !def_id.is_local() { let scope_id = match child.res { - Res::Def(DefKind::Variant, ..) => self.resolver.parent(def_id).unwrap(), + Res::Def(DefKind::Variant, ..) => self.resolver.parent(def_id), _ => def_id, }; self.resolve_doc_links_extern_outer(def_id, scope_id); // Outer attribute scope diff --git a/src/librustdoc/passes/collect_trait_impls.rs b/src/librustdoc/passes/collect_trait_impls.rs index 9644e3d15fd..d245c3750ec 100644 --- a/src/librustdoc/passes/collect_trait_impls.rs +++ b/src/librustdoc/passes/collect_trait_impls.rs @@ -49,7 +49,7 @@ crate fn collect_trait_impls(mut krate: Crate, cx: &mut DocContext<'_>) -> Crate let _prof_timer = cx.tcx.sess.prof.generic_activity("build_local_trait_impls"); let mut attr_buf = Vec::new(); for &impl_def_id in all_trait_impls.iter().take_while(|def_id| def_id.is_local()) { - let mut parent = cx.tcx.parent(impl_def_id); + let mut parent = Some(cx.tcx.parent(impl_def_id)); while let Some(did) = parent { attr_buf.extend( cx.tcx @@ -65,7 +65,7 @@ crate fn collect_trait_impls(mut krate: Crate, cx: &mut DocContext<'_>) -> Crate }) .cloned(), ); - parent = cx.tcx.parent(did); + parent = cx.tcx.opt_parent(did); } inline::build_impl(cx, None, impl_def_id, Some(&attr_buf), &mut new_items_local); attr_buf.clear(); diff --git a/src/tools/clippy/clippy_lints/src/matches/redundant_pattern_match.rs b/src/tools/clippy/clippy_lints/src/matches/redundant_pattern_match.rs index 777ec9b75bc..aa3552001f4 100644 --- a/src/tools/clippy/clippy_lints/src/matches/redundant_pattern_match.rs +++ b/src/tools/clippy/clippy_lints/src/matches/redundant_pattern_match.rs @@ -193,7 +193,7 @@ fn find_sugg_for_if_let<'tcx>( PatKind::TupleStruct(ref qpath, [sub_pat], _) => { if let PatKind::Wild = sub_pat.kind { let res = cx.typeck_results().qpath_res(qpath, check_pat.hir_id); - let Some(id) = res.opt_def_id().and_then(|ctor_id| cx.tcx.parent(ctor_id)) else { return }; + let Some(id) = res.opt_def_id().map(|ctor_id| cx.tcx.parent(ctor_id)) else { return }; let lang_items = cx.tcx.lang_items(); if Some(id) == lang_items.result_ok_variant() { ("is_ok()", try_get_generic_ty(op_ty, 0).unwrap_or(op_ty)) diff --git a/src/tools/clippy/clippy_lints/src/methods/bind_instead_of_map.rs b/src/tools/clippy/clippy_lints/src/methods/bind_instead_of_map.rs index eec232e6d09..b88ec0963f2 100644 --- a/src/tools/clippy/clippy_lints/src/methods/bind_instead_of_map.rs +++ b/src/tools/clippy/clippy_lints/src/methods/bind_instead_of_map.rs @@ -42,7 +42,7 @@ pub(crate) trait BindInsteadOfMap { fn no_op_msg(cx: &LateContext<'_>) -> Option { let variant_id = cx.tcx.lang_items().require(Self::VARIANT_LANG_ITEM).ok()?; - let item_id = cx.tcx.parent(variant_id)?; + let item_id = cx.tcx.parent(variant_id); Some(format!( "using `{}.{}({})`, which is a no-op", cx.tcx.item_name(item_id), @@ -53,7 +53,7 @@ pub(crate) trait BindInsteadOfMap { fn lint_msg(cx: &LateContext<'_>) -> Option { let variant_id = cx.tcx.lang_items().require(Self::VARIANT_LANG_ITEM).ok()?; - let item_id = cx.tcx.parent(variant_id)?; + let item_id = cx.tcx.parent(variant_id); Some(format!( "using `{}.{}(|x| {}(y))`, which is more succinctly expressed as `{}(|x| y)`", cx.tcx.item_name(item_id), @@ -145,7 +145,7 @@ pub(crate) trait BindInsteadOfMap { if_chain! { if let Some(adt) = cx.typeck_results().expr_ty(recv).ty_adt_def(); if let Ok(vid) = cx.tcx.lang_items().require(Self::VARIANT_LANG_ITEM); - if Some(adt.did()) == cx.tcx.parent(vid); + if adt.did() == cx.tcx.parent(vid); then {} else { return false; } } @@ -182,7 +182,7 @@ pub(crate) trait BindInsteadOfMap { fn is_variant(cx: &LateContext<'_>, res: Res) -> bool { if let Res::Def(DefKind::Ctor(CtorOf::Variant, CtorKind::Fn), id) = res { if let Ok(variant_id) = cx.tcx.lang_items().require(Self::VARIANT_LANG_ITEM) { - return cx.tcx.parent(id) == Some(variant_id); + return cx.tcx.parent(id) == variant_id; } } false diff --git a/src/tools/clippy/clippy_lints/src/methods/chars_cmp.rs b/src/tools/clippy/clippy_lints/src/methods/chars_cmp.rs index 2cf2c5641bf..f7b79f0839b 100644 --- a/src/tools/clippy/clippy_lints/src/methods/chars_cmp.rs +++ b/src/tools/clippy/clippy_lints/src/methods/chars_cmp.rs @@ -19,7 +19,7 @@ pub(super) fn check( if_chain! { if let Some(args) = method_chain_args(info.chain, chain_methods); if let hir::ExprKind::Call(fun, [arg_char]) = info.other.kind; - if let Some(id) = path_def_id(cx, fun).and_then(|ctor_id| cx.tcx.parent(ctor_id)); + if let Some(id) = path_def_id(cx, fun).map(|ctor_id| cx.tcx.parent(ctor_id)); if Some(id) == cx.tcx.lang_items().option_some_variant(); then { let mut applicability = Applicability::MachineApplicable; diff --git a/src/tools/clippy/clippy_lints/src/methods/option_map_or_none.rs b/src/tools/clippy/clippy_lints/src/methods/option_map_or_none.rs index 2a5ab6e625c..76bc9466ed8 100644 --- a/src/tools/clippy/clippy_lints/src/methods/option_map_or_none.rs +++ b/src/tools/clippy/clippy_lints/src/methods/option_map_or_none.rs @@ -75,7 +75,7 @@ pub(super) fn check<'tcx>( let arg_snippet = snippet(cx, span, ".."); let body = cx.tcx.hir().body(id); if let Some((func, [arg_char])) = reduce_unit_expression(&body.value); - if let Some(id) = path_def_id(cx, func).and_then(|ctor_id| cx.tcx.parent(ctor_id)); + if let Some(id) = path_def_id(cx, func).map(|ctor_id| cx.tcx.parent(ctor_id)); if Some(id) == cx.tcx.lang_items().option_some_variant(); then { let func_snippet = snippet(cx, arg_char.span, ".."); diff --git a/src/tools/clippy/clippy_lints/src/missing_doc.rs b/src/tools/clippy/clippy_lints/src/missing_doc.rs index 5816a95dceb..a20377f320b 100644 --- a/src/tools/clippy/clippy_lints/src/missing_doc.rs +++ b/src/tools/clippy/clippy_lints/src/missing_doc.rs @@ -114,7 +114,7 @@ impl<'tcx> LateLintPass<'tcx> for MissingDoc { hir::ItemKind::Fn(..) => { // ignore main() if it.ident.name == sym::main { - let at_root = cx.tcx.local_parent(it.def_id) == Some(CRATE_DEF_ID); + let at_root = cx.tcx.local_parent(it.def_id) == CRATE_DEF_ID; if at_root { return; } diff --git a/src/tools/clippy/clippy_utils/src/lib.rs b/src/tools/clippy/clippy_utils/src/lib.rs index 74978720424..7d46952d971 100644 --- a/src/tools/clippy/clippy_utils/src/lib.rs +++ b/src/tools/clippy/clippy_utils/src/lib.rs @@ -235,7 +235,7 @@ pub fn is_lang_ctor(cx: &LateContext<'_>, qpath: &QPath<'_>, lang_item: LangItem if let QPath::Resolved(_, path) = qpath { if let Res::Def(DefKind::Ctor(..), ctor_id) = path.res { if let Ok(item_id) = cx.tcx.lang_items().require(lang_item) { - return cx.tcx.parent(ctor_id) == Some(item_id); + return cx.tcx.parent(ctor_id) == item_id; } } }