about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--compiler/rustc_hir/src/def.rs37
-rw-r--r--compiler/rustc_metadata/src/rmeta/encoder.rs2
-rw-r--r--compiler/rustc_middle/src/ty/context.rs23
-rw-r--r--compiler/rustc_middle/src/ty/instance.rs3
-rw-r--r--compiler/rustc_middle/src/ty/util.rs36
-rw-r--r--compiler/rustc_mir_build/src/check_unsafety.rs11
-rw-r--r--compiler/rustc_mir_transform/src/check_unsafety.rs8
-rw-r--r--compiler/rustc_passes/src/dead.rs2
-rw-r--r--compiler/rustc_passes/src/reachable.rs4
-rw-r--r--compiler/rustc_symbol_mangling/src/lib.rs2
-rw-r--r--compiler/rustc_typeck/src/collect.rs4
11 files changed, 73 insertions, 59 deletions
diff --git a/compiler/rustc_hir/src/def.rs b/compiler/rustc_hir/src/def.rs
index db8807bad40..a639df01a78 100644
--- a/compiler/rustc_hir/src/def.rs
+++ b/compiler/rustc_hir/src/def.rs
@@ -229,6 +229,43 @@ impl DefKind {
             _ => false,
         }
     }
+
+    /// Whether `query get_codegen_attrs` should be used with this definition.
+    pub fn has_codegen_attrs(self) -> bool {
+        match self {
+            DefKind::Fn
+            | DefKind::AssocFn
+            | DefKind::Ctor(..)
+            | DefKind::Closure
+            | DefKind::Generator
+            | DefKind::Static(_) => true,
+            DefKind::Mod
+            | DefKind::Struct
+            | DefKind::Union
+            | DefKind::Enum
+            | DefKind::Variant
+            | DefKind::Trait
+            | DefKind::TyAlias
+            | DefKind::ForeignTy
+            | DefKind::TraitAlias
+            | DefKind::AssocTy
+            | DefKind::Const
+            | DefKind::AssocConst
+            | DefKind::Macro(..)
+            | DefKind::Use
+            | DefKind::ForeignMod
+            | DefKind::OpaqueTy
+            | DefKind::Impl
+            | DefKind::Field
+            | DefKind::TyParam
+            | DefKind::ConstParam
+            | DefKind::LifetimeParam
+            | DefKind::AnonConst
+            | DefKind::InlineConst
+            | DefKind::GlobalAsm
+            | DefKind::ExternCrate => false,
+        }
+    }
 }
 
 /// The resolution of a path or export.
diff --git a/compiler/rustc_metadata/src/rmeta/encoder.rs b/compiler/rustc_metadata/src/rmeta/encoder.rs
index 433ef978b64..81388a0bf58 100644
--- a/compiler/rustc_metadata/src/rmeta/encoder.rs
+++ b/compiler/rustc_metadata/src/rmeta/encoder.rs
@@ -1007,7 +1007,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
             record!(self.tables.def_span[def_id] <- tcx.def_span(def_id));
             self.encode_attrs(def_id);
             record!(self.tables.expn_that_defined[def_id] <- self.tcx.expn_that_defined(def_id));
-            if tcx.has_codegen_attrs(def_kind) {
+            if def_kind.has_codegen_attrs() {
                 record!(self.tables.codegen_fn_attrs[def_id] <- self.tcx.codegen_fn_attrs(def_id));
             }
             if should_encode_visibility(def_kind) {
diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs
index 4d06c95915b..9d3d509eb21 100644
--- a/compiler/rustc_middle/src/ty/context.rs
+++ b/compiler/rustc_middle/src/ty/context.rs
@@ -5,6 +5,7 @@ use crate::dep_graph::{DepGraph, DepKind, DepKindStruct};
 use crate::hir::place::Place as HirPlace;
 use crate::infer::canonical::{Canonical, CanonicalVarInfo, CanonicalVarInfos};
 use crate::lint::{struct_lint_level, LintDiagnosticBuilder, LintLevelSource};
+use crate::middle::codegen_fn_attrs::CodegenFnAttrs;
 use crate::middle::resolve_lifetime::{self, LifetimeScopeForPath};
 use crate::middle::stability;
 use crate::mir::interpret::{self, Allocation, ConstAllocation, ConstValue, Scalar};
@@ -1066,6 +1067,28 @@ pub struct GlobalCtxt<'tcx> {
 }
 
 impl<'tcx> TyCtxt<'tcx> {
+    /// Expects a body and returns its codegen attributes.
+    ///
+    /// Unlike `codegen_fn_attrs`, this returns `CodegenFnAttrs::EMPTY` for
+    /// constants.
+    pub fn body_codegen_attrs(self, def_id: DefId) -> &'tcx CodegenFnAttrs {
+        let def_kind = self.def_kind(def_id);
+        if def_kind.has_codegen_attrs() {
+            self.codegen_fn_attrs(def_id)
+        } else if matches!(
+            def_kind,
+            DefKind::AnonConst | DefKind::AssocConst | DefKind::Const | DefKind::InlineConst
+        ) {
+            CodegenFnAttrs::EMPTY
+        } else {
+            bug!(
+                "body_codegen_fn_attrs called on unexpected definition: {:?} {:?}",
+                def_id,
+                def_kind
+            )
+        }
+    }
+
     pub fn typeck_opt_const_arg(
         self,
         def: ty::WithOptConstParam<LocalDefId>,
diff --git a/compiler/rustc_middle/src/ty/instance.rs b/compiler/rustc_middle/src/ty/instance.rs
index f0710ef42de..7cf7f897347 100644
--- a/compiler/rustc_middle/src/ty/instance.rs
+++ b/compiler/rustc_middle/src/ty/instance.rs
@@ -246,8 +246,7 @@ impl<'tcx> InstanceDef<'tcx> {
         match *self {
             InstanceDef::Item(ty::WithOptConstParam { did: def_id, .. })
             | InstanceDef::Virtual(def_id, _) => {
-                tcx.has_codegen_attrs(tcx.def_kind(def_id))
-                    && tcx.codegen_fn_attrs(def_id).flags.contains(CodegenFnAttrFlags::TRACK_CALLER)
+                tcx.body_codegen_attrs(def_id).flags.contains(CodegenFnAttrFlags::TRACK_CALLER)
             }
             InstanceDef::ClosureOnceShim { call_once: _, track_caller } => track_caller,
             _ => false,
diff --git a/compiler/rustc_middle/src/ty/util.rs b/compiler/rustc_middle/src/ty/util.rs
index 646d4c9f8f5..1c8af13ce9c 100644
--- a/compiler/rustc_middle/src/ty/util.rs
+++ b/compiler/rustc_middle/src/ty/util.rs
@@ -139,42 +139,6 @@ impl<'tcx> TyCtxt<'tcx> {
         hasher.finish()
     }
 
-    pub fn has_codegen_attrs(self, def_kind: DefKind) -> bool {
-        match def_kind {
-            DefKind::Fn
-            | DefKind::AssocFn
-            | DefKind::Ctor(..)
-            | DefKind::Closure
-            | DefKind::Generator
-            | DefKind::Static(_) => true,
-            DefKind::Mod
-            | DefKind::Struct
-            | DefKind::Union
-            | DefKind::Enum
-            | DefKind::Variant
-            | DefKind::Trait
-            | DefKind::TyAlias
-            | DefKind::ForeignTy
-            | DefKind::TraitAlias
-            | DefKind::AssocTy
-            | DefKind::Const
-            | DefKind::AssocConst
-            | DefKind::Macro(..)
-            | DefKind::Use
-            | DefKind::ForeignMod
-            | DefKind::OpaqueTy
-            | DefKind::Impl
-            | DefKind::Field
-            | DefKind::TyParam
-            | DefKind::ConstParam
-            | DefKind::LifetimeParam
-            | DefKind::AnonConst
-            | DefKind::InlineConst
-            | DefKind::GlobalAsm
-            | DefKind::ExternCrate => false,
-        }
-    }
-
     pub fn res_generics_def_id(self, res: Res) -> Option<DefId> {
         match res {
             Res::Def(DefKind::Ctor(CtorOf::Variant, _), def_id) => {
diff --git a/compiler/rustc_mir_build/src/check_unsafety.rs b/compiler/rustc_mir_build/src/check_unsafety.rs
index b90eecefc0c..6c14f207a7d 100644
--- a/compiler/rustc_mir_build/src/check_unsafety.rs
+++ b/compiler/rustc_mir_build/src/check_unsafety.rs
@@ -643,9 +643,8 @@ pub fn check_unsafety<'tcx>(tcx: TyCtxt<'tcx>, def: ty::WithOptConstParam<LocalD
         return;
     }
 
-    let (thir, expr) = match tcx.thir_body(def) {
-        Ok(body) => body,
-        Err(_) => return,
+    let Ok((thir, expr)) = tcx.thir_body(def) else {
+        return
     };
     let thir = &thir.borrow();
     // If `thir` is empty, a type error occurred, skip this body.
@@ -661,11 +660,7 @@ pub fn check_unsafety<'tcx>(tcx: TyCtxt<'tcx>, def: ty::WithOptConstParam<LocalD
             BodyUnsafety::Safe
         }
     });
-    let body_target_features: &[_] = if tcx.has_codegen_attrs(tcx.def_kind(def.did)) {
-        &tcx.codegen_fn_attrs(def.did).target_features
-    } else {
-        &[]
-    };
+    let body_target_features = &tcx.body_codegen_attrs(def.did.to_def_id()).target_features;
     let safety_context =
         if body_unsafety.is_unsafe() { SafetyContext::UnsafeFn } else { SafetyContext::Safe };
     let mut visitor = UnsafetyVisitor {
diff --git a/compiler/rustc_mir_transform/src/check_unsafety.rs b/compiler/rustc_mir_transform/src/check_unsafety.rs
index 3f567633e4a..1f73b7da815 100644
--- a/compiler/rustc_mir_transform/src/check_unsafety.rs
+++ b/compiler/rustc_mir_transform/src/check_unsafety.rs
@@ -375,12 +375,8 @@ impl<'tcx> UnsafetyChecker<'_, 'tcx> {
         }
 
         let callee_features = &self.tcx.codegen_fn_attrs(func_did).target_features;
-        // Constants don't have codegen attributes, so the body might not have codegen attributes.
-        let self_features: &[_] = if self.tcx.has_codegen_attrs(self.tcx.def_kind(self.body_did)) {
-            &self.tcx.codegen_fn_attrs(self.body_did).target_features
-        } else {
-            &[]
-        };
+        // The body might be a constant, so it doesn't have codegen attributes.
+        let self_features = &self.tcx.body_codegen_attrs(self.body_did.to_def_id()).target_features;
 
         // Is `callee_features` a subset of `calling_features`?
         if !callee_features.iter().all(|feature| self_features.contains(feature)) {
diff --git a/compiler/rustc_passes/src/dead.rs b/compiler/rustc_passes/src/dead.rs
index f0451352b45..df28ea4d444 100644
--- a/compiler/rustc_passes/src/dead.rs
+++ b/compiler/rustc_passes/src/dead.rs
@@ -452,7 +452,7 @@ fn has_allow_dead_code_or_lang_attr(tcx: TyCtxt<'_>, id: hir::HirId) -> bool {
     }
 
     let def_id = tcx.hir().local_def_id(id);
-    if tcx.has_codegen_attrs(tcx.def_kind(def_id)) {
+    if tcx.def_kind(def_id).has_codegen_attrs() {
         let cg_attrs = tcx.codegen_fn_attrs(def_id);
 
         // #[used], #[no_mangle], #[export_name], etc also keeps the item alive
diff --git a/compiler/rustc_passes/src/reachable.rs b/compiler/rustc_passes/src/reachable.rs
index e9f4bfee3de..a5133bfd945 100644
--- a/compiler/rustc_passes/src/reachable.rs
+++ b/compiler/rustc_passes/src/reachable.rs
@@ -208,7 +208,7 @@ impl<'tcx> ReachableContext<'tcx> {
                 } else {
                     false
                 };
-            let codegen_attrs = if self.tcx.has_codegen_attrs(self.tcx.def_kind(search_item)) {
+            let codegen_attrs = if self.tcx.def_kind(search_item).has_codegen_attrs() {
                 self.tcx.codegen_fn_attrs(search_item)
             } else {
                 CodegenFnAttrs::EMPTY
@@ -333,7 +333,7 @@ impl CollectPrivateImplItemsVisitor<'_, '_> {
         // Anything which has custom linkage gets thrown on the worklist no
         // matter where it is in the crate, along with "special std symbols"
         // which are currently akin to allocator symbols.
-        if self.tcx.has_codegen_attrs(self.tcx.def_kind(def_id)) {
+        if self.tcx.def_kind(def_id).has_codegen_attrs() {
             let codegen_attrs = self.tcx.codegen_fn_attrs(def_id);
             if codegen_attrs.contains_extern_indicator()
                 || codegen_attrs.flags.contains(CodegenFnAttrFlags::RUSTC_STD_INTERNAL_SYMBOL)
diff --git a/compiler/rustc_symbol_mangling/src/lib.rs b/compiler/rustc_symbol_mangling/src/lib.rs
index 2936b6775d1..ee0994c9ad6 100644
--- a/compiler/rustc_symbol_mangling/src/lib.rs
+++ b/compiler/rustc_symbol_mangling/src/lib.rs
@@ -177,7 +177,7 @@ fn compute_symbol_name<'tcx>(
     }
 
     // FIXME(eddyb) Precompute a custom symbol name based on attributes.
-    let attrs = if tcx.has_codegen_attrs(tcx.def_kind(def_id)) {
+    let attrs = if tcx.def_kind(def_id).has_codegen_attrs() {
         tcx.codegen_fn_attrs(def_id)
     } else {
         CodegenFnAttrs::EMPTY
diff --git a/compiler/rustc_typeck/src/collect.rs b/compiler/rustc_typeck/src/collect.rs
index 7be5d7b8e97..74714d75fa0 100644
--- a/compiler/rustc_typeck/src/collect.rs
+++ b/compiler/rustc_typeck/src/collect.rs
@@ -2723,7 +2723,7 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, did: DefId) -> CodegenFnAttrs {
     if cfg!(debug_assertions) {
         let def_kind = tcx.def_kind(did);
         assert!(
-            tcx.has_codegen_attrs(def_kind),
+            def_kind.has_codegen_attrs(),
             "unexpected `def_kind` in `codegen_fn_attrs`: {def_kind:?}",
         );
     }
@@ -3233,7 +3233,7 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, did: DefId) -> CodegenFnAttrs {
 /// inline assembly.
 fn asm_target_features<'tcx>(tcx: TyCtxt<'tcx>, did: DefId) -> &'tcx FxHashSet<Symbol> {
     let mut target_features = tcx.sess.target_features.clone();
-    if tcx.has_codegen_attrs(tcx.def_kind(did)) {
+    if tcx.def_kind(did).has_codegen_attrs() {
         let attrs = tcx.codegen_fn_attrs(did);
         target_features.extend(&attrs.target_features);
         match attrs.instruction_set {