diff options
| author | bors <bors@rust-lang.org> | 2022-05-02 14:03:20 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2022-05-02 14:03:20 +0000 |
| commit | 879fb425960798a79042b3b2a850d1262b7a91e8 (patch) | |
| tree | 1d1454aa105200842e6beb2b918b5d5c5c0d07c4 /compiler/rustc_resolve/src | |
| parent | 542898328637b31412d91b882ce0dc4b85ad54e6 (diff) | |
| parent | 5b5964f569ca07ba54710cb440aacaa1cf1e5c1a (diff) | |
| download | rust-879fb425960798a79042b3b2a850d1262b7a91e8.tar.gz rust-879fb425960798a79042b3b2a850d1262b7a91e8.zip | |
Auto merge of #96431 - petrochenkov:parent, r=cjgillot
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`.
Diffstat (limited to 'compiler/rustc_resolve/src')
| -rw-r--r-- | compiler/rustc_resolve/src/build_reduced_graph.rs | 2 | ||||
| -rw-r--r-- | compiler/rustc_resolve/src/diagnostics.rs | 4 | ||||
| -rw-r--r-- | compiler/rustc_resolve/src/imports.rs | 9 | ||||
| -rw-r--r-- | compiler/rustc_resolve/src/late.rs | 8 | ||||
| -rw-r--r-- | compiler/rustc_resolve/src/late/lifetimes.rs | 96 | ||||
| -rw-r--r-- | compiler/rustc_resolve/src/lib.rs | 3 |
6 files changed, 53 insertions, 69 deletions
diff --git a/compiler/rustc_resolve/src/build_reduced_graph.rs b/compiler/rustc_resolve/src/build_reduced_graph.rs index 43c1062f32e..783ff5a3f91 100644 --- a/compiler/rustc_resolve/src/build_reduced_graph.rs +++ b/compiler/rustc_resolve/src/build_reduced_graph.rs @@ -1390,7 +1390,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<DefId> { - 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<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)), } @@ -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 92e55a0ccb2..f6109b1dc1a 100644 --- a/compiler/rustc_resolve/src/lib.rs +++ b/compiler/rustc_resolve/src/lib.rs @@ -1111,7 +1111,8 @@ impl<'a> AsMut<Resolver<'a>> for Resolver<'a> { } 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, |
