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 05fbbf45d7c24..19a543ae777f0 100644 --- a/compiler/rustc_const_eval/src/const_eval/fn_queries.rs +++ b/compiler/rustc_const_eval/src/const_eval/fn_queries.rs @@ -1,7 +1,8 @@ use rustc_hir as hir; +use rustc_hir::def::DefKind; use rustc_hir::def_id::{DefId, LocalDefId}; use rustc_middle::ty::query::Providers; -use rustc_middle::ty::TyCtxt; +use rustc_middle::ty::{DefIdTree, TyCtxt}; use rustc_span::symbol::Symbol; use rustc_target::spec::abi::Abi; @@ -16,44 +17,47 @@ 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 hir_id = tcx.hir().local_def_id_to_hir_id(def_id); - let parent_id = tcx.hir().get_parent_node(hir_id); - matches!( - tcx.hir().get(parent_id), - hir::Node::Item(hir::Item { - kind: hir::ItemKind::Impl(hir::Impl { constness: hir::Constness::Const, .. }), - .. - }) - ) + let parent_id = tcx.local_parent(def_id).unwrap(); + tcx.def_kind(parent_id) == DefKind::Impl + && tcx.impl_constness(parent_id) == hir::Constness::Const } /// Checks whether the function has a `const` modifier or, in case it is an intrinsic, whether /// said intrinsic has a `rustc_const_{un,}stable` attribute. -fn is_const_fn_raw(tcx: TyCtxt<'_>, def_id: DefId) -> bool { +fn impl_constness(tcx: TyCtxt<'_>, def_id: DefId) -> hir::Constness { let def_id = def_id.expect_local(); let node = tcx.hir().get_by_def_id(def_id); - if let hir::Node::ForeignItem(hir::ForeignItem { kind: hir::ForeignItemKind::Fn(..), .. }) = - node - { - // Intrinsics use `rustc_const_{un,}stable` attributes to indicate constness. All other - // foreign items cannot be evaluated at compile-time. - let hir_id = tcx.hir().local_def_id_to_hir_id(def_id); - if let Abi::RustIntrinsic | Abi::PlatformIntrinsic = tcx.hir().get_foreign_abi(hir_id) { - tcx.lookup_const_stability(def_id).is_some() - } else { - false - } - } else if let Some(fn_kind) = node.fn_kind() { - if fn_kind.constness() == hir::Constness::Const { - return true; + match node { + hir::Node::Ctor(_) => hir::Constness::Const, + hir::Node::Item(hir::Item { kind: hir::ItemKind::Impl(impl_), .. }) => impl_.constness, + hir::Node::ForeignItem(hir::ForeignItem { kind: hir::ForeignItemKind::Fn(..), .. }) => { + // Intrinsics use `rustc_const_{un,}stable` attributes to indicate constness. All other + // foreign items cannot be evaluated at compile-time. + let hir_id = tcx.hir().local_def_id_to_hir_id(def_id); + let is_const = if let Abi::RustIntrinsic | Abi::PlatformIntrinsic = + tcx.hir().get_foreign_abi(hir_id) + { + tcx.lookup_const_stability(def_id).is_some() + } else { + false + }; + if is_const { hir::Constness::Const } else { hir::Constness::NotConst } } + _ => { + if let Some(fn_kind) = node.fn_kind() { + if fn_kind.constness() == hir::Constness::Const { + return hir::Constness::Const; + } - // If the function itself is not annotated with `const`, it may still be a `const fn` - // if it resides in a const trait impl. - is_parent_const_impl_raw(tcx, def_id) - } else { - matches!(node, hir::Node::Ctor(_)) + // If the function itself is not annotated with `const`, it may still be a `const fn` + // if it resides in a const trait impl. + let is_const = is_parent_const_impl_raw(tcx, def_id); + if is_const { hir::Constness::Const } else { hir::Constness::NotConst } + } else { + hir::Constness::NotConst + } + } } } @@ -77,5 +81,5 @@ fn is_promotable_const_fn(tcx: TyCtxt<'_>, def_id: DefId) -> bool { } pub fn provide(providers: &mut Providers) { - *providers = Providers { is_const_fn_raw, is_promotable_const_fn, ..*providers }; + *providers = Providers { impl_constness, is_promotable_const_fn, ..*providers }; } diff --git a/compiler/rustc_metadata/src/rmeta/decoder.rs b/compiler/rustc_metadata/src/rmeta/decoder.rs index 6993ffbeddf99..046322a42d85b 100644 --- a/compiler/rustc_metadata/src/rmeta/decoder.rs +++ b/compiler/rustc_metadata/src/rmeta/decoder.rs @@ -14,7 +14,6 @@ use rustc_data_structures::sync::{Lock, LockGuard, Lrc, OnceCell}; use rustc_data_structures::unhash::UnhashMap; use rustc_expand::base::{SyntaxExtension, SyntaxExtensionKind}; use rustc_expand::proc_macro::{AttrProcMacro, BangProcMacro, ProcMacroDerive}; -use rustc_hir as hir; use rustc_hir::def::{CtorKind, CtorOf, DefKind, Res}; use rustc_hir::def_id::{CrateNum, DefId, DefIndex, CRATE_DEF_INDEX, LOCAL_CRATE}; use rustc_hir::definitions::{DefKey, DefPath, DefPathData, DefPathHash}; @@ -909,40 +908,9 @@ impl<'a, 'tcx> CrateMetadataRef<'a> { ) } - fn get_trait_def(self, item_id: DefIndex, sess: &Session) -> ty::TraitDef { - match self.kind(item_id) { - EntryKind::Trait(data) => { - let data = data.decode((self, sess)); - ty::TraitDef::new( - self.local_def_id(item_id), - data.unsafety, - data.paren_sugar, - data.has_auto_impl, - data.is_marker, - data.skip_array_during_method_dispatch, - data.specialization_kind, - self.def_path_hash(item_id), - data.must_implement_one_of, - ) - } - EntryKind::TraitAlias => ty::TraitDef::new( - self.local_def_id(item_id), - hir::Unsafety::Normal, - false, - false, - false, - false, - ty::trait_def::TraitSpecializationKind::None, - self.def_path_hash(item_id), - None, - ), - _ => bug!("def-index does not refer to trait or trait alias"), - } - } - fn get_variant(self, kind: &EntryKind, index: DefIndex, parent_did: DefId) -> ty::VariantDef { let data = match kind { - EntryKind::Variant(data) | EntryKind::Struct(data, _) | EntryKind::Union(data, _) => { + EntryKind::Variant(data) | EntryKind::Struct(data) | EntryKind::Union(data) => { data.decode(self) } _ => bug!(), @@ -988,12 +956,13 @@ impl<'a, 'tcx> CrateMetadataRef<'a> { let kind = self.kind(item_id); let did = self.local_def_id(item_id); - let (adt_kind, repr) = match kind { - EntryKind::Enum(repr) => (ty::AdtKind::Enum, repr), - EntryKind::Struct(_, repr) => (ty::AdtKind::Struct, repr), - EntryKind::Union(_, repr) => (ty::AdtKind::Union, repr), + let adt_kind = match kind { + EntryKind::Enum => ty::AdtKind::Enum, + EntryKind::Struct(_) => ty::AdtKind::Struct, + EntryKind::Union(_) => ty::AdtKind::Union, _ => bug!("get_adt_def called on a non-ADT {:?}", did), }; + let repr = self.root.tables.repr_options.get(self, item_id).unwrap().decode(self); let variants = if let ty::AdtKind::Enum = adt_kind { self.root @@ -1171,7 +1140,7 @@ impl<'a, 'tcx> CrateMetadataRef<'a> { callback(exp); } } - EntryKind::Enum(..) | EntryKind::Trait(..) => {} + EntryKind::Enum | EntryKind::Trait => {} _ => bug!("`for_each_module_child` is called on a non-module: {:?}", self.def_kind(id)), } } @@ -1186,7 +1155,7 @@ impl<'a, 'tcx> CrateMetadataRef<'a> { fn module_expansion(self, id: DefIndex, sess: &Session) -> ExpnId { match self.kind(id) { - EntryKind::Mod(_) | EntryKind::Enum(_) | EntryKind::Trait(_) => { + EntryKind::Mod(_) | EntryKind::Enum | EntryKind::Trait => { self.get_expn_that_defined(id, sess) } _ => panic!("Expected module, found {:?}", self.local_def_id(id)), @@ -1239,7 +1208,7 @@ impl<'a, 'tcx> CrateMetadataRef<'a> { fn get_ctor_def_id_and_kind(self, node_id: DefIndex) -> Option<(DefId, CtorKind)> { match self.kind(node_id) { - EntryKind::Struct(data, _) | EntryKind::Variant(data) => { + EntryKind::Struct(data) | EntryKind::Variant(data) => { let vdata = data.decode(self); vdata.ctor.map(|index| (self.local_def_id(index), vdata.ctor_kind)) } @@ -1395,7 +1364,7 @@ impl<'a, 'tcx> CrateMetadataRef<'a> { _ => return None, } def_key.parent.and_then(|parent_index| match self.kind(parent_index) { - EntryKind::Trait(_) | EntryKind::TraitAlias => Some(self.local_def_id(parent_index)), + EntryKind::Trait | EntryKind::TraitAlias => Some(self.local_def_id(parent_index)), _ => None, }) } @@ -1449,22 +1418,9 @@ impl<'a, 'tcx> CrateMetadataRef<'a> { } } - // This replicates some of the logic of the crate-local `is_const_fn_raw` query, because we - // don't serialize constness for tuple variant and tuple struct constructors. - fn is_const_fn_raw(self, id: DefIndex) -> bool { - let constness = match self.kind(id) { - EntryKind::AssocFn(data) => data.decode(self).fn_data.constness, - EntryKind::Fn(data) => data.decode(self).constness, - EntryKind::ForeignFn(data) => data.decode(self).constness, - EntryKind::Variant(..) | EntryKind::Struct(..) => hir::Constness::Const, - _ => hir::Constness::NotConst, - }; - constness == hir::Constness::Const - } - fn is_foreign_item(self, id: DefIndex) -> bool { match self.kind(id) { - EntryKind::ForeignStatic | EntryKind::ForeignFn(_) => true, + EntryKind::ForeignStatic | EntryKind::ForeignFn => true, _ => false, } } diff --git a/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs b/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs index 5a2c59b46015c..cd3a1d72d41d2 100644 --- a/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs +++ b/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs @@ -153,8 +153,8 @@ provide! { <'tcx> tcx, def_id, other, cdata, asyncness => { table } fn_arg_names => { table } generator_kind => { table } + trait_def => { table } - trait_def => { cdata.get_trait_def(def_id.index, tcx.sess) } adt_def => { cdata.get_adt_def(def_id.index, tcx) } adt_destructor => { let _ = cdata; @@ -163,7 +163,6 @@ provide! { <'tcx> tcx, def_id, other, cdata, associated_item_def_ids => { cdata.get_associated_item_def_ids(tcx, def_id.index) } associated_item => { cdata.get_associated_item(def_id.index) } inherent_impls => { cdata.get_inherent_implementations_for_type(tcx, def_id.index) } - is_const_fn_raw => { cdata.is_const_fn_raw(def_id.index) } is_foreign_item => { cdata.is_foreign_item(def_id.index) } item_attrs => { tcx.arena.alloc_from_iter(cdata.get_item_attrs(def_id.index, tcx.sess)) } trait_of_item => { cdata.get_trait_of_item(def_id.index) } diff --git a/compiler/rustc_metadata/src/rmeta/encoder.rs b/compiler/rustc_metadata/src/rmeta/encoder.rs index cb3932eba3519..6c758b8e5b633 100644 --- a/compiler/rustc_metadata/src/rmeta/encoder.rs +++ b/compiler/rustc_metadata/src/rmeta/encoder.rs @@ -1048,6 +1048,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { }; record!(self.tables.kind[def_id] <- EntryKind::Variant(self.lazy(data))); + record!(self.tables.impl_constness[def_id] <- hir::Constness::Const); record!(self.tables.children[def_id] <- variant.fields.iter().map(|f| { assert!(f.did.is_local()); f.did.index @@ -1077,6 +1078,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { }; record!(self.tables.kind[def_id] <- EntryKind::Variant(self.lazy(data))); + record!(self.tables.impl_constness[def_id] <- hir::Constness::Const); self.encode_item_type(def_id); if variant.ctor_kind == CtorKind::Fn { record!(self.tables.fn_sig[def_id] <- tcx.fn_sig(def_id)); @@ -1154,7 +1156,9 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { is_non_exhaustive: variant.is_field_list_non_exhaustive(), }; - record!(self.tables.kind[def_id] <- EntryKind::Struct(self.lazy(data), adt_def.repr())); + record!(self.tables.repr_options[def_id] <- adt_def.repr()); + record!(self.tables.impl_constness[def_id] <- hir::Constness::Const); + record!(self.tables.kind[def_id] <- EntryKind::Struct(self.lazy(data))); self.encode_item_type(def_id); if variant.ctor_kind == CtorKind::Fn { record!(self.tables.fn_sig[def_id] <- tcx.fn_sig(def_id)); @@ -1194,22 +1198,18 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { record!(self.tables.rendered_const[def_id] <- rendered); } ty::AssocKind::Fn => { - let fn_data = if let hir::TraitItemKind::Fn(m_sig, m) = &ast_item.kind { - match *m { - hir::TraitFn::Required(ref names) => { - record!(self.tables.fn_arg_names[def_id] <- *names) - } - hir::TraitFn::Provided(body) => { - record!(self.tables.fn_arg_names[def_id] <- self.tcx.hir().body_param_names(body)) - } - }; - record!(self.tables.asyncness[def_id] <- m_sig.header.asyncness); - FnData { constness: hir::Constness::NotConst } - } else { - bug!() + let hir::TraitItemKind::Fn(m_sig, m) = &ast_item.kind else { bug!() }; + match *m { + hir::TraitFn::Required(ref names) => { + record!(self.tables.fn_arg_names[def_id] <- *names) + } + hir::TraitFn::Provided(body) => { + record!(self.tables.fn_arg_names[def_id] <- self.tcx.hir().body_param_names(body)) + } }; + record!(self.tables.asyncness[def_id] <- m_sig.header.asyncness); + record!(self.tables.impl_constness[def_id] <- hir::Constness::NotConst); record!(self.tables.kind[def_id] <- EntryKind::AssocFn(self.lazy(AssocFnData { - fn_data, container, has_self: trait_item.fn_has_self_parameter, }))); @@ -1264,22 +1264,17 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { } } ty::AssocKind::Fn => { - let fn_data = if let hir::ImplItemKind::Fn(ref sig, body) = ast_item.kind { - record!(self.tables.asyncness[def_id] <- sig.header.asyncness); - record!(self.tables.fn_arg_names[def_id] <- self.tcx.hir().body_param_names(body)); - FnData { - // Can be inside `impl const Trait`, so using sig.header.constness is not reliable - constness: if self.tcx.is_const_fn_raw(def_id) { - hir::Constness::Const - } else { - hir::Constness::NotConst - }, - } + let hir::ImplItemKind::Fn(ref sig, body) = ast_item.kind else { bug!() }; + record!(self.tables.asyncness[def_id] <- sig.header.asyncness); + record!(self.tables.fn_arg_names[def_id] <- self.tcx.hir().body_param_names(body)); + // Can be inside `impl const Trait`, so using sig.header.constness is not reliable + let constness = if self.tcx.is_const_fn_raw(def_id) { + hir::Constness::Const } else { - bug!() + hir::Constness::NotConst }; + record!(self.tables.impl_constness[def_id] <- constness); record!(self.tables.kind[def_id] <- EntryKind::AssocFn(self.lazy(AssocFnData { - fn_data, container, has_self: impl_item.fn_has_self_parameter, }))); @@ -1401,9 +1396,8 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { hir::ItemKind::Fn(ref sig, .., body) => { record!(self.tables.asyncness[def_id] <- sig.header.asyncness); record!(self.tables.fn_arg_names[def_id] <- self.tcx.hir().body_param_names(body)); - let data = FnData { constness: sig.header.constness }; - - EntryKind::Fn(self.lazy(data)) + record!(self.tables.impl_constness[def_id] <- sig.header.constness); + EntryKind::Fn } hir::ItemKind::Macro(ref macro_def, _) => { EntryKind::MacroDef(self.lazy(&*macro_def.body), macro_def.macro_rules) @@ -1418,10 +1412,15 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { self.encode_explicit_item_bounds(def_id); EntryKind::OpaqueTy } - hir::ItemKind::Enum(..) => EntryKind::Enum(self.tcx.adt_def(def_id).repr()), + hir::ItemKind::Enum(..) => { + let adt_def = self.tcx.adt_def(def_id); + record!(self.tables.repr_options[def_id] <- adt_def.repr()); + EntryKind::Enum + } hir::ItemKind::Struct(ref struct_def, _) => { let adt_def = self.tcx.adt_def(def_id); - let variant = adt_def.non_enum_variant(); + record!(self.tables.repr_options[def_id] <- adt_def.repr()); + record!(self.tables.impl_constness[def_id] <- hir::Constness::Const); // Encode def_ids for each field and method // for methods, write all the stuff get_trait_method @@ -1430,29 +1429,25 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { .ctor_hir_id() .map(|ctor_hir_id| self.tcx.hir().local_def_id(ctor_hir_id).local_def_index); - EntryKind::Struct( - self.lazy(VariantData { - ctor_kind: variant.ctor_kind, - discr: variant.discr, - ctor, - is_non_exhaustive: variant.is_field_list_non_exhaustive(), - }), - adt_def.repr(), - ) + let variant = adt_def.non_enum_variant(); + EntryKind::Struct(self.lazy(VariantData { + ctor_kind: variant.ctor_kind, + discr: variant.discr, + ctor, + is_non_exhaustive: variant.is_field_list_non_exhaustive(), + })) } hir::ItemKind::Union(..) => { let adt_def = self.tcx.adt_def(def_id); - let variant = adt_def.non_enum_variant(); + record!(self.tables.repr_options[def_id] <- adt_def.repr()); - EntryKind::Union( - self.lazy(VariantData { - ctor_kind: variant.ctor_kind, - discr: variant.discr, - ctor: None, - is_non_exhaustive: variant.is_field_list_non_exhaustive(), - }), - adt_def.repr(), - ) + let variant = adt_def.non_enum_variant(); + EntryKind::Union(self.lazy(VariantData { + ctor_kind: variant.ctor_kind, + discr: variant.discr, + ctor: None, + is_non_exhaustive: variant.is_field_list_non_exhaustive(), + })) } hir::ItemKind::Impl(hir::Impl { defaultness, constness, .. }) => { record!(self.tables.impl_defaultness[def_id] <- defaultness); @@ -1483,19 +1478,16 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { } hir::ItemKind::Trait(..) => { let trait_def = self.tcx.trait_def(def_id); - let data = TraitData { - unsafety: trait_def.unsafety, - paren_sugar: trait_def.paren_sugar, - has_auto_impl: self.tcx.trait_is_auto(def_id), - is_marker: trait_def.is_marker, - skip_array_during_method_dispatch: trait_def.skip_array_during_method_dispatch, - specialization_kind: trait_def.specialization_kind, - must_implement_one_of: trait_def.must_implement_one_of.clone(), - }; + record!(self.tables.trait_def[def_id] <- trait_def); + + EntryKind::Trait + } + hir::ItemKind::TraitAlias(..) => { + let trait_def = self.tcx.trait_def(def_id); + record!(self.tables.trait_def[def_id] <- trait_def); - EntryKind::Trait(self.lazy(data)) + EntryKind::TraitAlias } - hir::ItemKind::TraitAlias(..) => EntryKind::TraitAlias, hir::ItemKind::ExternCrate(_) | hir::ItemKind::Use(..) => { bug!("cannot encode info for item {:?}", item) } @@ -1896,14 +1888,13 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { hir::ForeignItemKind::Fn(_, ref names, _) => { record!(self.tables.asyncness[def_id] <- hir::IsAsync::NotAsync); record!(self.tables.fn_arg_names[def_id] <- *names); - let data = FnData { - constness: if self.tcx.is_const_fn_raw(def_id) { - hir::Constness::Const - } else { - hir::Constness::NotConst - }, + let constness = if self.tcx.is_const_fn_raw(def_id) { + hir::Constness::Const + } else { + hir::Constness::NotConst }; - record!(self.tables.kind[def_id] <- EntryKind::ForeignFn(self.lazy(data))); + record!(self.tables.impl_constness[def_id] <- constness); + record!(self.tables.kind[def_id] <- EntryKind::ForeignFn); } hir::ForeignItemKind::Static(..) => { record!(self.tables.kind[def_id] <- EntryKind::ForeignStatic); diff --git a/compiler/rustc_metadata/src/rmeta/mod.rs b/compiler/rustc_metadata/src/rmeta/mod.rs index 0658103312972..15e8693d71282 100644 --- a/compiler/rustc_metadata/src/rmeta/mod.rs +++ b/compiler/rustc_metadata/src/rmeta/mod.rs @@ -320,11 +320,13 @@ define_tables! { asyncness: Table, fn_arg_names: Table, generator_kind: Table, + trait_def: Table, trait_item_def_id: Table>, inherent_impls: Table>, expn_that_defined: Table>, unused_generic_params: Table>>, + repr_options: Table>, // `def_keys` and `def_path_hashes` represent a lazy version of a // `DefPathTable`. This allows us to avoid deserializing an entire // `DefPathTable` up front, since we may only ever use a few @@ -347,19 +349,19 @@ enum EntryKind { TypeParam, ConstParam, OpaqueTy, - Enum(ReprOptions), + Enum, Field, Variant(Lazy), - Struct(Lazy, ReprOptions), - Union(Lazy, ReprOptions), - Fn(Lazy), - ForeignFn(Lazy), + Struct(Lazy), + Union(Lazy), + Fn, + ForeignFn, Mod(Lazy<[ModChild]>), MacroDef(Lazy, /*macro_rules*/ bool), ProcMacro(MacroKind), Closure, Generator, - Trait(Lazy), + Trait, Impl, AssocFn(Lazy), AssocType(AssocContainer), @@ -367,11 +369,6 @@ enum EntryKind { TraitAlias, } -#[derive(MetadataEncodable, MetadataDecodable)] -struct FnData { - constness: hir::Constness, -} - #[derive(TyEncodable, TyDecodable)] struct VariantData { ctor_kind: CtorKind, @@ -381,17 +378,6 @@ struct VariantData { is_non_exhaustive: bool, } -#[derive(TyEncodable, TyDecodable)] -struct TraitData { - unsafety: hir::Unsafety, - paren_sugar: bool, - has_auto_impl: bool, - is_marker: bool, - skip_array_during_method_dispatch: bool, - specialization_kind: ty::trait_def::TraitSpecializationKind, - must_implement_one_of: Option>, -} - /// Describes whether the container of an associated item /// is a trait or an impl and whether, in a trait, it has /// a default, or an in impl, whether it's marked "default". @@ -429,7 +415,6 @@ impl AssocContainer { #[derive(MetadataEncodable, MetadataDecodable)] struct AssocFnData { - fn_data: FnData, container: AssocContainer, has_self: bool, } diff --git a/compiler/rustc_middle/src/query/mod.rs b/compiler/rustc_middle/src/query/mod.rs index bf45269e06f30..14c11187fc5ee 100644 --- a/compiler/rustc_middle/src/query/mod.rs +++ b/compiler/rustc_middle/src/query/mod.rs @@ -559,7 +559,7 @@ rustc_queries! { /// /// **Do not call this function manually.** It is only meant to cache the base data for the /// `is_const_fn` function. - query is_const_fn_raw(key: DefId) -> bool { + query impl_constness(key: DefId) -> hir::Constness { desc { |tcx| "checking if item is const fn: `{}`", tcx.def_path_str(key) } separate_provide_extern } @@ -1329,11 +1329,6 @@ rustc_queries! { separate_provide_extern } - query impl_constness(def_id: DefId) -> hir::Constness { - desc { |tcx| "looking up whether `{}` is a const impl", tcx.def_path_str(def_id) } - separate_provide_extern - } - query check_item_well_formed(key: LocalDefId) -> () { desc { |tcx| "checking that `{}` is well-formed", tcx.def_path_str(key.to_def_id()) } } diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs index 653b4908ab560..37425c91157b3 100644 --- a/compiler/rustc_middle/src/ty/mod.rs +++ b/compiler/rustc_middle/src/ty/mod.rs @@ -289,6 +289,11 @@ pub struct ClosureSizeProfileData<'tcx> { pub trait DefIdTree: Copy { fn parent(self, id: DefId) -> Option; + #[inline] + fn local_parent(self, id: LocalDefId) -> Option { + Some(self.parent(id.to_def_id())?.expect_local()) + } + fn is_descendant_of(self, mut descendant: DefId, ancestor: DefId) -> bool { if descendant.krate != ancestor.krate { return false; @@ -2256,6 +2261,12 @@ impl<'tcx> TyCtxt<'tcx> { pub fn is_object_safe(self, key: DefId) -> bool { self.object_safety_violations(key).is_empty() } + + #[inline] + pub fn is_const_fn_raw(self, def_id: DefId) -> bool { + matches!(self.def_kind(def_id), DefKind::Fn | DefKind::AssocFn | DefKind::Ctor(..)) + && self.impl_constness(def_id) == hir::Constness::Const + } } /// Yields the parent function's `LocalDefId` if `def_id` is an `impl Trait` definition. diff --git a/compiler/rustc_middle/src/ty/trait_def.rs b/compiler/rustc_middle/src/ty/trait_def.rs index 943f610cc0dd3..ca6fabf7f4018 100644 --- a/compiler/rustc_middle/src/ty/trait_def.rs +++ b/compiler/rustc_middle/src/ty/trait_def.rs @@ -5,7 +5,6 @@ use crate::ty::{Ident, Ty, TyCtxt}; use hir::def_id::LOCAL_CRATE; use rustc_hir as hir; use rustc_hir::def_id::DefId; -use rustc_hir::definitions::DefPathHash; use std::iter; use rustc_data_structures::fx::FxIndexMap; @@ -13,10 +12,8 @@ use rustc_errors::ErrorGuaranteed; use rustc_macros::HashStable; /// A trait's definition with type information. -#[derive(HashStable)] +#[derive(HashStable, Encodable, Decodable)] pub struct TraitDef { - // We already have the def_path_hash below, no need to hash it twice - #[stable_hasher(ignore)] pub def_id: DefId, pub unsafety: hir::Unsafety, @@ -43,10 +40,6 @@ pub struct TraitDef { /// on this trait. pub specialization_kind: TraitSpecializationKind, - /// The ICH of this trait's DefPath, cached here so it doesn't have to be - /// recomputed all the time. - pub def_path_hash: DefPathHash, - /// List of functions from `#[rustc_must_implement_one_of]` attribute one of which /// must be implemented. pub must_implement_one_of: Option>, @@ -54,7 +47,7 @@ pub struct TraitDef { /// Whether this trait is treated specially by the standard library /// specialization lint. -#[derive(HashStable, PartialEq, Clone, Copy, TyEncodable, TyDecodable)] +#[derive(HashStable, PartialEq, Clone, Copy, Encodable, Decodable)] pub enum TraitSpecializationKind { /// The default. Specializing on this trait is not allowed. None, @@ -92,7 +85,6 @@ impl<'tcx> TraitDef { is_marker: bool, skip_array_during_method_dispatch: bool, specialization_kind: TraitSpecializationKind, - def_path_hash: DefPathHash, must_implement_one_of: Option>, ) -> TraitDef { TraitDef { @@ -103,7 +95,6 @@ impl<'tcx> TraitDef { is_marker, skip_array_during_method_dispatch, specialization_kind, - def_path_hash, must_implement_one_of, } } diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs index 8aa659fa6ac7c..7ad8748135630 100644 --- a/compiler/rustc_passes/src/check_attr.rs +++ b/compiler/rustc_passes/src/check_attr.rs @@ -1859,7 +1859,7 @@ impl CheckAttrVisitor<'_> { ) -> bool { match target { Target::Fn | Target::Method(_) - if self.tcx.is_const_fn_raw(self.tcx.hir().local_def_id(hir_id)) => + if self.tcx.is_const_fn_raw(self.tcx.hir().local_def_id(hir_id).to_def_id()) => { true } diff --git a/compiler/rustc_ty_utils/src/ty.rs b/compiler/rustc_ty_utils/src/ty.rs index 44ef0a09a654b..64145bbf189ff 100644 --- a/compiler/rustc_ty_utils/src/ty.rs +++ b/compiler/rustc_ty_utils/src/ty.rs @@ -77,15 +77,6 @@ fn impl_defaultness(tcx: TyCtxt<'_>, def_id: DefId) -> hir::Defaultness { } } -fn impl_constness(tcx: TyCtxt<'_>, def_id: DefId) -> hir::Constness { - let item = tcx.hir().expect_item(def_id.expect_local()); - if let hir::ItemKind::Impl(impl_) = &item.kind { - impl_.constness - } else { - bug!("`impl_constness` called on {:?}", item); - } -} - /// Calculates the `Sized` constraint. /// /// In fact, there are only a few options for the types in the constraint: @@ -498,7 +489,6 @@ pub fn provide(providers: &mut ty::query::Providers) { instance_def_size_estimate, issue33140_self_ty, impl_defaultness, - impl_constness, conservative_is_privately_uninhabited: conservative_is_privately_uninhabited_raw, ..*providers }; diff --git a/compiler/rustc_typeck/src/collect.rs b/compiler/rustc_typeck/src/collect.rs index 700ae83e4c9ca..90b880adcd031 100644 --- a/compiler/rustc_typeck/src/collect.rs +++ b/compiler/rustc_typeck/src/collect.rs @@ -1218,8 +1218,6 @@ fn trait_def(tcx: TyCtxt<'_>, def_id: DefId) -> ty::TraitDef { } else { ty::trait_def::TraitSpecializationKind::None }; - let def_path_hash = tcx.def_path_hash(def_id); - let must_implement_one_of = tcx .get_attrs(def_id) .iter() @@ -1326,7 +1324,6 @@ fn trait_def(tcx: TyCtxt<'_>, def_id: DefId) -> ty::TraitDef { is_marker, skip_array_during_method_dispatch, spec_kind, - def_path_hash, must_implement_one_of, ) }