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`.
{
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() =>
}
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)]
}
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
}
} 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,
impl InferenceDiagnosticsParentData {
fn for_def_id(tcx: TyCtxt<'_>, def_id: DefId) -> Option<InferenceDiagnosticsParentData> {
- 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();
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
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
};
&& 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()))
{
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
}
})
}
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),
}
}
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);
(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
| 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
}
pub trait DefIdTree: Copy {
- fn parent(self, id: DefId) -> Option<DefId>;
+ fn opt_parent(self, id: DefId) -> Option<DefId>;
#[inline]
- fn local_parent(self, id: LocalDefId) -> Option<LocalDefId> {
- 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<LocalDefId> {
+ 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 {
}
while descendant != ancestor {
- match self.parent(descendant) {
+ match self.opt_parent(descendant) {
Some(parent) => descendant = parent,
None => return false,
}
}
impl<'tcx> DefIdTree for TyCtxt<'tcx> {
- fn parent(self, id: DefId) -> Option<DefId> {
+ #[inline]
+ fn opt_parent(self, id: DefId) -> Option<DefId> {
self.def_key(id).parent.map(|index| DefId { index, ..id })
}
}
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),
// 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 {
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,
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() {
/// 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),
}
pub fn res_generics_def_id(self, res: Res) -> Option<DefId> {
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`.
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
}
) -> 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,
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() {
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();
_ 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);
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);
}
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;
}
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)
}
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};
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;
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);
}
}
&& 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,
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(),
};
_,
) = 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()`
}
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;
pub r: &'a mut Resolver<'b>,
}
-impl<'a, 'b> ty::DefIdTree for &'a ImportResolver<'a, 'b> {
- fn parent(self, id: DefId) -> Option<DefId> {
- self.r.parent(id)
- }
-}
-
impl<'a, 'b> ImportResolver<'a, 'b> {
// Import resolution
//
}
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);
// 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)
) -> Option<(LocalDefId, &'tcx FxHashSet<LocalDefId>)> {
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)),
}
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));
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;
- }
- }
}
}
}
|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();
}
impl<'a, 'b> DefIdTree for &'a Resolver<'b> {
- fn parent(self, id: DefId) -> Option<DefId> {
+ #[inline]
+ fn opt_parent(self, id: DefId) -> Option<DefId> {
match id.as_local() {
Some(id) => self.definitions.def_key(id).parent,
None => self.cstore().def_key(id).parent,
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 {
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);
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 {
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);
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 {
alias_span: None,
name: item.ident.to_string(),
value: String::new(),
- parent,
+ parent: Some(id_from_def_id(parent.to_def_id())),
},
);
}
// 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, _) => {
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| {
) -> 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);
// `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
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)
};
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)
// #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())
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
// `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)
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`.
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`.
}
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,
let mut current = def_id;
// The immediate parent might not always be a module.
// Find the first parent which is.
- while let Some(parent) = tcx.parent(current) {
+ while let Some(parent) = tcx.opt_parent(current) {
if tcx.def_kind(parent) == DefKind::Mod {
return Some(parent);
}
let did = match def_kind {
DefKind::AssocTy | DefKind::AssocFn | DefKind::AssocConst | DefKind::Variant => {
// documented on their parent's page
- tcx.parent(did).unwrap()
+ tcx.parent(did)
}
_ => did,
};
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!(
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)
}
}
| 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
}
cx: &DocContext<'_>,
res: Res,
) -> Result<(Res, Option<ItemFragment>), 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.
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);
}
}
{
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
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
})
.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();
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))
fn no_op_msg(cx: &LateContext<'_>) -> Option<String> {
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),
fn lint_msg(cx: &LateContext<'_>) -> Option<String> {
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),
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; }
}
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
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;
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, "..");
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;
}
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;
}
}
}