From 331df84ad6af8255f9785a5c69babee7561a2a42 Mon Sep 17 00:00:00 2001 From: Vadim Petrochenkov Date: Fri, 24 Nov 2023 00:49:02 +0300 Subject: [PATCH] rustc: Make `def_kind` mandatory for all `DefId`s --- compiler/rustc_hir/src/def.rs | 7 +++++++ compiler/rustc_metadata/src/rmeta/decoder.rs | 11 ++-------- .../src/rmeta/decoder/cstore_impl.rs | 2 +- compiler/rustc_metadata/src/rmeta/encoder.rs | 19 +++++++++++------- compiler/rustc_metadata/src/rmeta/mod.rs | 2 +- compiler/rustc_metadata/src/rmeta/table.rs | 20 +++++++++++++++++++ compiler/rustc_middle/src/hir/map/mod.rs | 18 +++++++---------- compiler/rustc_middle/src/hir/mod.rs | 2 +- compiler/rustc_middle/src/query/mod.rs | 2 +- compiler/rustc_middle/src/query/plumbing.rs | 17 ---------------- compiler/rustc_privacy/src/lib.rs | 2 +- compiler/rustc_query_impl/src/plumbing.rs | 4 ++-- compiler/rustc_ty_utils/src/assoc.rs | 4 ++-- .../clippy/clippy_lints/src/unused_async.rs | 2 +- .../clippy_lints/src/useless_conversion.rs | 3 +-- 15 files changed, 59 insertions(+), 56 deletions(-) diff --git a/compiler/rustc_hir/src/def.rs b/compiler/rustc_hir/src/def.rs index e901eba35b783..91fdd7dc11a7e 100644 --- a/compiler/rustc_hir/src/def.rs +++ b/compiler/rustc_hir/src/def.rs @@ -267,6 +267,13 @@ impl DefKind { } } +/// Required by metadata encoder/decoder, but should never be actually used. +impl Default for DefKind { + fn default() -> Self { + panic!("default `DefKind` constructed") + } +} + /// The resolution of a path or export. /// /// For every path or identifier in Rust, the compiler must determine diff --git a/compiler/rustc_metadata/src/rmeta/decoder.rs b/compiler/rustc_metadata/src/rmeta/decoder.rs index 333dc8ec91119..598bf2b2166ac 100644 --- a/compiler/rustc_metadata/src/rmeta/decoder.rs +++ b/compiler/rustc_metadata/src/rmeta/decoder.rs @@ -850,7 +850,7 @@ impl MetadataBlob { ) -> io::Result<()> { let root = blob.get_root(); - let def_kind = root.tables.opt_def_kind.get(blob, item).unwrap(); + let def_kind = root.tables.def_kind.get(blob, item); let def_key = root.tables.def_keys.get(blob, item).unwrap().decode(blob); let def_name = if item == CRATE_DEF_INDEX { rustc_span::symbol::kw::Crate @@ -1001,14 +1001,7 @@ impl<'a, 'tcx> CrateMetadataRef<'a> { } fn def_kind(self, item_id: DefIndex) -> DefKind { - self.root.tables.opt_def_kind.get(self, item_id).unwrap_or_else(|| { - bug!( - "CrateMetadata::def_kind({:?}): id not found, in crate {:?} with number {}", - item_id, - self.root.name(), - self.cnum, - ) - }) + self.root.tables.def_kind.get(self, item_id) } fn get_span(self, index: DefIndex, sess: &Session) -> Span { diff --git a/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs b/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs index 0250c92dd78b3..f6cd013d2ef16 100644 --- a/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs +++ b/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs @@ -231,7 +231,7 @@ provide! { tcx, def_id, other, cdata, lookup_deprecation_entry => { table } params_in_repr => { table } unused_generic_params => { cdata.root.tables.unused_generic_params.get(cdata, def_id.index) } - opt_def_kind => { table_direct } + def_kind => { cdata.def_kind(def_id.index) } impl_parent => { table } impl_polarity => { table_direct } defaultness => { table_direct } diff --git a/compiler/rustc_metadata/src/rmeta/encoder.rs b/compiler/rustc_metadata/src/rmeta/encoder.rs index 19add1ef1acfa..903af56311e6f 100644 --- a/compiler/rustc_metadata/src/rmeta/encoder.rs +++ b/compiler/rustc_metadata/src/rmeta/encoder.rs @@ -1354,9 +1354,8 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { for local_id in tcx.iter_local_def_id() { let def_id = local_id.to_def_id(); - let def_kind = tcx.opt_def_kind(local_id); - let Some(def_kind) = def_kind else { continue }; - self.tables.opt_def_kind.set_some(def_id.index, def_kind); + let def_kind = tcx.def_kind(local_id); + self.tables.def_kind.set(def_id.index, def_kind); if should_encode_span(def_kind) { let def_span = tcx.def_span(local_id); record!(self.tables.def_span[def_id] <- def_span); @@ -1393,7 +1392,13 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { if should_encode_fn_sig(def_kind) { record!(self.tables.fn_sig[def_id] <- tcx.fn_sig(def_id)); } - if should_encode_generics(def_kind) { + // FIXME: Some anonymous constants produced by `#[rustc_legacy_const_generics]` + // do not have corresponding HIR nodes, so some queries usually making sense for + // anonymous constants will not work on them and panic. It's not clear whether it + // can cause any observable issues or not. + let anon_const_without_hir = def_kind == DefKind::AnonConst + && tcx.hir().find(tcx.local_def_id_to_hir_id(local_id)).is_none(); + if should_encode_generics(def_kind) && !anon_const_without_hir { let g = tcx.generics_of(def_id); record!(self.tables.generics_of[def_id] <- g); record!(self.tables.explicit_predicates_of[def_id] <- self.tcx.explicit_predicates_of(def_id)); @@ -1407,7 +1412,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { } } } - if should_encode_type(tcx, local_id, def_kind) { + if should_encode_type(tcx, local_id, def_kind) && !anon_const_without_hir { record!(self.tables.type_of[def_id] <- self.tcx.type_of(def_id)); } if should_encode_constness(def_kind) { @@ -1785,7 +1790,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { self.tables.proc_macro_quoted_spans.set_some(i, span); } - self.tables.opt_def_kind.set_some(LOCAL_CRATE.as_def_id().index, DefKind::Mod); + self.tables.def_kind.set(LOCAL_CRATE.as_def_id().index, DefKind::Mod); record!(self.tables.def_span[LOCAL_CRATE.as_def_id()] <- tcx.def_span(LOCAL_CRATE.as_def_id())); self.encode_attrs(LOCAL_CRATE.as_def_id().expect_local()); let vis = tcx.local_visibility(CRATE_DEF_ID).map_id(|def_id| def_id.local_def_index); @@ -1833,7 +1838,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { def_key.disambiguated_data.data = DefPathData::MacroNs(name); let def_id = id.to_def_id(); - self.tables.opt_def_kind.set_some(def_id.index, DefKind::Macro(macro_kind)); + self.tables.def_kind.set(def_id.index, DefKind::Macro(macro_kind)); self.tables.proc_macro.set_some(def_id.index, macro_kind); self.encode_attrs(id); record!(self.tables.def_keys[def_id] <- def_key); diff --git a/compiler/rustc_metadata/src/rmeta/mod.rs b/compiler/rustc_metadata/src/rmeta/mod.rs index 145db4b2ed6a2..837825e2c19be 100644 --- a/compiler/rustc_metadata/src/rmeta/mod.rs +++ b/compiler/rustc_metadata/src/rmeta/mod.rs @@ -386,6 +386,7 @@ define_tables! { is_type_alias_impl_trait: Table, type_alias_is_lazy: Table, attr_flags: Table, + def_kind: Table, def_path_hashes: Table, explicit_item_bounds: Table, Span)>>, inferred_outlives_of: Table, Span)>>, @@ -405,7 +406,6 @@ define_tables! { // so we can take their names, visibilities etc from other encoded tables. module_children_non_reexports: Table>, associated_item_or_field_def_ids: Table>, - opt_def_kind: Table, visibility: Table>>, def_span: Table>, def_ident_span: Table>, diff --git a/compiler/rustc_metadata/src/rmeta/table.rs b/compiler/rustc_metadata/src/rmeta/table.rs index 96cf668b7da86..6e6705e37cd9f 100644 --- a/compiler/rustc_metadata/src/rmeta/table.rs +++ b/compiler/rustc_metadata/src/rmeta/table.rs @@ -65,6 +65,12 @@ impl IsDefault for UnusedGenericParams { } } +impl IsDefault for DefKind { + fn is_default(&self) -> bool { + false + } +} + /// Helper trait, for encoding to, and decoding from, a fixed number of bytes. /// Used mainly for Lazy positions and lengths. /// Unchecked invariant: `Self::default()` should encode as `[0; BYTE_LEN]`, @@ -225,6 +231,20 @@ fixed_size_enum! { } } +impl FixedSizeEncoding for DefKind { + type ByteArray = [u8; 1]; + + #[inline] + fn from_bytes(b: &[u8; 1]) -> Self { + Option::::from_bytes(b).unwrap() + } + + #[inline] + fn write_to_bytes(self, b: &mut [u8; 1]) { + Some(self).write_to_bytes(b) + } +} + // We directly encode `DefPathHash` because a `LazyValue` would incur a 25% cost. impl FixedSizeEncoding for DefPathHash { type ByteArray = [u8; 16]; diff --git a/compiler/rustc_middle/src/hir/map/mod.rs b/compiler/rustc_middle/src/hir/map/mod.rs index 9d8168382d204..c1c2ac22bd399 100644 --- a/compiler/rustc_middle/src/hir/map/mod.rs +++ b/compiler/rustc_middle/src/hir/map/mod.rs @@ -174,21 +174,18 @@ impl<'hir> Map<'hir> { } /// Do not call this function directly. The query should be called. - pub(super) fn opt_def_kind(self, local_def_id: LocalDefId) -> Option { + pub(super) fn def_kind(self, local_def_id: LocalDefId) -> DefKind { let hir_id = self.local_def_id_to_hir_id(local_def_id); let node = match self.find(hir_id) { Some(node) => node, None => match self.def_key(local_def_id).disambiguated_data.data { - // FIXME: Some anonymous constants do not have corresponding HIR nodes, - // so many local queries will panic on their def ids. `None` is currently - // returned here instead of `DefKind::{Anon,Inline}Const` to avoid such panics. - // Ideally all def ids should have `DefKind`s, we need to create the missing - // HIR nodes or feed relevant query results to achieve that. - DefPathData::AnonConst => return None, + // FIXME: Some anonymous constants produced by `#[rustc_legacy_const_generics]` + // do not have corresponding HIR nodes, but they are still anonymous constants. + DefPathData::AnonConst => return DefKind::AnonConst, _ => bug!("no HIR node for def id {local_def_id:?}"), }, }; - let def_kind = match node { + match node { Node::Item(item) => match item.kind { ItemKind::Static(_, mt, _) => DefKind::Static(mt), ItemKind::Const(..) => DefKind::Const, @@ -266,8 +263,7 @@ impl<'hir> Map<'hir> { self.span(hir_id), "unexpected node with def id {local_def_id:?}: {node:?}" ), - }; - Some(def_kind) + } } /// Finds the id of the parent node to this one. @@ -895,7 +891,7 @@ impl<'hir> Map<'hir> { #[inline] fn opt_ident(self, id: HirId) -> Option { - match self.get(id) { + match self.find(id)? { Node::Pat(&Pat { kind: PatKind::Binding(_, _, ident, _), .. }) => Some(ident), // A `Ctor` doesn't have an identifier itself, but its parent // struct/variant does. Compare with `hir::Map::opt_span`. diff --git a/compiler/rustc_middle/src/hir/mod.rs b/compiler/rustc_middle/src/hir/mod.rs index f28ec771169fd..af7a2efe35a81 100644 --- a/compiler/rustc_middle/src/hir/mod.rs +++ b/compiler/rustc_middle/src/hir/mod.rs @@ -202,7 +202,7 @@ pub fn provide(providers: &mut Providers) { span_bug!(hir.span(hir_id), "fn_arg_names: unexpected item {:?}", def_id); } }; - providers.opt_def_kind = |tcx, def_id| tcx.hir().opt_def_kind(def_id); + providers.def_kind = |tcx, def_id| tcx.hir().def_kind(def_id); providers.all_local_trait_impls = |tcx, ()| &tcx.resolutions(()).trait_impls; providers.expn_that_defined = |tcx, id| tcx.resolutions(()).expn_that_defined.get(&id).copied().unwrap_or(ExpnId::root()); diff --git a/compiler/rustc_middle/src/query/mod.rs b/compiler/rustc_middle/src/query/mod.rs index c982e2a93253f..5d91d83fb2b1c 100644 --- a/compiler/rustc_middle/src/query/mod.rs +++ b/compiler/rustc_middle/src/query/mod.rs @@ -1152,7 +1152,7 @@ rustc_queries! { cache_on_disk_if { true } } - query opt_def_kind(def_id: DefId) -> Option { + query def_kind(def_id: DefId) -> DefKind { desc { |tcx| "looking up definition kind of `{}`", tcx.def_path_str(def_id) } cache_on_disk_if { def_id.is_local() } separate_provide_extern diff --git a/compiler/rustc_middle/src/query/plumbing.rs b/compiler/rustc_middle/src/query/plumbing.rs index f4a8ada8f685e..eb90ac4cc5133 100644 --- a/compiler/rustc_middle/src/query/plumbing.rs +++ b/compiler/rustc_middle/src/query/plumbing.rs @@ -11,7 +11,6 @@ use field_offset::FieldOffset; use measureme::StringId; use rustc_data_structures::fx::FxHashMap; use rustc_data_structures::sync::AtomicU64; -use rustc_hir::def::DefKind; use rustc_hir::def_id::{DefId, LocalDefId}; use rustc_hir::hir_id::OwnerId; use rustc_query_system::dep_graph::DepNodeIndex; @@ -667,21 +666,5 @@ mod sealed { pub use sealed::IntoQueryParam; -impl<'tcx> TyCtxt<'tcx> { - pub fn def_kind(self, def_id: impl IntoQueryParam) -> DefKind { - let def_id = def_id.into_query_param(); - self.opt_def_kind(def_id) - .unwrap_or_else(|| bug!("def_kind: unsupported node: {:?}", def_id)) - } -} - -impl<'tcx> TyCtxtAt<'tcx> { - pub fn def_kind(self, def_id: impl IntoQueryParam) -> DefKind { - let def_id = def_id.into_query_param(); - self.opt_def_kind(def_id) - .unwrap_or_else(|| bug!("def_kind: unsupported node: {:?}", def_id)) - } -} - #[derive(Copy, Clone, Debug, HashStable)] pub struct CyclePlaceholder(pub ErrorGuaranteed); diff --git a/compiler/rustc_privacy/src/lib.rs b/compiler/rustc_privacy/src/lib.rs index 4324afe42b38c..d46bc9466f65b 100644 --- a/compiler/rustc_privacy/src/lib.rs +++ b/compiler/rustc_privacy/src/lib.rs @@ -500,7 +500,7 @@ impl<'tcx> EmbargoVisitor<'tcx> { } let macro_module_def_id = self.tcx.local_parent(local_def_id); - if self.tcx.opt_def_kind(macro_module_def_id) != Some(DefKind::Mod) { + if self.tcx.def_kind(macro_module_def_id) != DefKind::Mod { // The macro's parent doesn't correspond to a `mod`, return early (#63164, #65252). return; } diff --git a/compiler/rustc_query_impl/src/plumbing.rs b/compiler/rustc_query_impl/src/plumbing.rs index a290bd10bea09..9faf63f00e27e 100644 --- a/compiler/rustc_query_impl/src/plumbing.rs +++ b/compiler/rustc_query_impl/src/plumbing.rs @@ -325,11 +325,11 @@ pub(crate) fn create_query_frame< Some(key.default_span(tcx)) }; let def_id = key.key_as_def_id(); - let def_kind = if kind == dep_graph::dep_kinds::opt_def_kind || with_no_queries() { + let def_kind = if kind == dep_graph::dep_kinds::def_kind || with_no_queries() { // Try to avoid infinite recursion. None } else { - def_id.and_then(|def_id| def_id.as_local()).and_then(|def_id| tcx.opt_def_kind(def_id)) + def_id.and_then(|def_id| def_id.as_local()).map(|def_id| tcx.def_kind(def_id)) }; let hash = || { tcx.with_stable_hashing_context(|mut hcx| { diff --git a/compiler/rustc_ty_utils/src/assoc.rs b/compiler/rustc_ty_utils/src/assoc.rs index e29fed37f85bf..a1ebf386e74e3 100644 --- a/compiler/rustc_ty_utils/src/assoc.rs +++ b/compiler/rustc_ty_utils/src/assoc.rs @@ -259,7 +259,7 @@ fn associated_type_for_impl_trait_in_trait( let local_def_id = trait_assoc_ty.def_id(); let def_id = local_def_id.to_def_id(); - trait_assoc_ty.opt_def_kind(Some(DefKind::AssocTy)); + trait_assoc_ty.def_kind(DefKind::AssocTy); // There's no HIR associated with this new synthesized `def_id`, so feed // `opt_local_def_id_to_hir_id` with `None`. @@ -362,7 +362,7 @@ fn associated_type_for_impl_trait_in_impl( let local_def_id = impl_assoc_ty.def_id(); let def_id = local_def_id.to_def_id(); - impl_assoc_ty.opt_def_kind(Some(DefKind::AssocTy)); + impl_assoc_ty.def_kind(DefKind::AssocTy); // There's no HIR associated with this new synthesized `def_id`, so feed // `opt_local_def_id_to_hir_id` with `None`. diff --git a/src/tools/clippy/clippy_lints/src/unused_async.rs b/src/tools/clippy/clippy_lints/src/unused_async.rs index aea72c798be73..780ece3677dfb 100644 --- a/src/tools/clippy/clippy_lints/src/unused_async.rs +++ b/src/tools/clippy/clippy_lints/src/unused_async.rs @@ -148,7 +148,7 @@ impl<'tcx> LateLintPass<'tcx> for UnusedAsync { // statements, so don't lint at all if there are any such paths. if let Some(def_id) = path.res.opt_def_id() && let Some(local_def_id) = def_id.as_local() - && let Some(DefKind::Fn) = cx.tcx.opt_def_kind(def_id) + && cx.tcx.def_kind(def_id) == DefKind::Fn && cx.tcx.asyncness(def_id).is_async() && !is_node_func_call(cx.tcx.hir().get_parent(hir_id), path.span) { diff --git a/src/tools/clippy/clippy_lints/src/useless_conversion.rs b/src/tools/clippy/clippy_lints/src/useless_conversion.rs index 52327b82e849f..7aed1d6e30b43 100644 --- a/src/tools/clippy/clippy_lints/src/useless_conversion.rs +++ b/src/tools/clippy/clippy_lints/src/useless_conversion.rs @@ -4,7 +4,6 @@ use clippy_utils::sugg::Sugg; use clippy_utils::ty::{is_copy, is_type_diagnostic_item, same_type_and_consts}; use clippy_utils::{get_parent_expr, is_trait_method, is_ty_alias, path_to_local}; use rustc_errors::Applicability; -use rustc_hir::def::DefKind; use rustc_hir::def_id::DefId; use rustc_hir::{BindingAnnotation, Expr, ExprKind, HirId, MatchSource, Node, PatKind}; use rustc_infer::infer::TyCtxtInferExt; @@ -208,7 +207,7 @@ impl<'tcx> LateLintPass<'tcx> for UselessConversion { && let Some(did) = cx.qpath_res(qpath, recv.hir_id).opt_def_id() // make sure that the path indeed points to a fn-like item, so that // `fn_sig` does not ICE. (see #11065) - && cx.tcx.opt_def_kind(did).is_some_and(DefKind::is_fn_like) => + && cx.tcx.def_kind(did).is_fn_like() => { Some(( did,