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 cdcebb61c2e8c..13489bcbb697c 100644 --- a/compiler/rustc_const_eval/src/const_eval/fn_queries.rs +++ b/compiler/rustc_const_eval/src/const_eval/fn_queries.rs @@ -25,10 +25,12 @@ pub fn is_parent_const_impl_raw(tcx: TyCtxt<'_>, def_id: LocalDefId) -> bool { /// report whether said intrinsic has a `rustc_const_{un,}stable` attribute. Otherwise, return /// `Constness::NotConst`. fn constness(tcx: TyCtxt<'_>, def_id: DefId) -> hir::Constness { + if let Some(value) = tcx.opt_default_constness(def_id) { + return value; + } + let hir_id = tcx.hir().local_def_id_to_hir_id(def_id.expect_local()); match tcx.hir().get(hir_id) { - hir::Node::Ctor(_) => hir::Constness::Const, - 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. @@ -46,12 +48,7 @@ fn constness(tcx: TyCtxt<'_>, def_id: DefId) -> hir::Constness { hir::Constness::Const } - hir::Node::Item(hir::Item { kind: hir::ItemKind::Const(..), .. }) - | hir::Node::Item(hir::Item { kind: hir::ItemKind::Static(..), .. }) - | hir::Node::TraitItem(hir::TraitItem { kind: hir::TraitItemKind::Const(..), .. }) - | hir::Node::AnonConst(_) - | hir::Node::ImplItem(hir::ImplItem { kind: hir::ImplItemKind::Const(..), .. }) - | hir::Node::ImplItem(hir::ImplItem { + hir::Node::ImplItem(hir::ImplItem { kind: hir::ImplItemKind::Fn( hir::FnSig { diff --git a/compiler/rustc_metadata/src/rmeta/decoder.rs b/compiler/rustc_metadata/src/rmeta/decoder.rs index 830417eea1a0a..6ec659f2429e5 100644 --- a/compiler/rustc_metadata/src/rmeta/decoder.rs +++ b/compiler/rustc_metadata/src/rmeta/decoder.rs @@ -1332,6 +1332,21 @@ impl<'a, 'tcx> CrateMetadataRef<'a> { tcx.arena.alloc_from_iter(self.root.lang_items_missing.decode(self)) } + fn get_constness(self, tcx: TyCtxt<'tcx>, id: DefIndex) -> hir::Constness { + let def_id = self.local_def_id(id); + + if let Some(constness) = tcx.opt_default_constness(def_id) { + constness + } else { + self.cdata + .root + .tables + .constness + .get(self, id) + .unwrap_or_else(|| panic!("{:?} does not have constness", def_id)) + } + } + fn exported_symbols( self, tcx: TyCtxt<'tcx>, diff --git a/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs b/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs index c4dff8b3f48ed..c496325e9544d 100644 --- a/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs +++ b/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs @@ -216,7 +216,7 @@ provide! { tcx, def_id, other, cdata, impl_parent => { table } impl_polarity => { table_direct } impl_defaultness => { table_direct } - constness => { table_direct } + constness => { cdata.get_constness(tcx, def_id.index) } coerce_unsized_info => { table } mir_const_qualif => { table } rendered_const => { table } diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs index 8636c4465d46f..5934b68928f02 100644 --- a/compiler/rustc_middle/src/ty/context.rs +++ b/compiler/rustc_middle/src/ty/context.rs @@ -1724,6 +1724,29 @@ impl<'tcx> TyCtxt<'tcx> { pub fn local_visibility(self, def_id: LocalDefId) -> Visibility { self.visibility(def_id).expect_local() } + + /// The constness of an item that is independent of its signature. + /// + /// Only some items have a "default constness", such as `struct`s + /// which make no sense being constant, and `const`s which are always + /// constant. + pub fn opt_default_constness(self, def_id: DefId) -> Option { + match self.def_kind(def_id) { + DefKind::Struct + | DefKind::Union + | DefKind::Enum + | DefKind::TyAlias + | DefKind::OpaqueTy + | DefKind::ImplTraitPlaceholder => Some(hir::Constness::NotConst), + DefKind::Const + | DefKind::Static(_) + | DefKind::Ctor(_, _) + | DefKind::AssocConst + | DefKind::AnonConst + | DefKind::InlineConst => Some(hir::Constness::Const), + _ => None, + } + } } /// A trait implemented for all `X<'a>` types that can be safely and