diff --git a/compiler/rustc_attr_parsing/src/attributes/rustc_internal.rs b/compiler/rustc_attr_parsing/src/attributes/rustc_internal.rs index 0d19dc25d402c..5d4ecbd64d49a 100644 --- a/compiler/rustc_attr_parsing/src/attributes/rustc_internal.rs +++ b/compiler/rustc_attr_parsing/src/attributes/rustc_internal.rs @@ -1103,6 +1103,30 @@ impl NoArgsAttributeParser for RustcEffectiveVisibilityParser { const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::RustcEffectiveVisibility; } +pub(crate) struct RustcDoNotConstCheckParser; + +impl NoArgsAttributeParser for RustcDoNotConstCheckParser { + const PATH: &[Symbol] = &[sym::rustc_do_not_const_check]; + const ON_DUPLICATE: OnDuplicate = OnDuplicate::Error; + const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[ + Allow(Target::Fn), + Allow(Target::Method(MethodKind::Inherent)), + Allow(Target::Method(MethodKind::TraitImpl)), + Allow(Target::Method(MethodKind::Trait { body: false })), + Allow(Target::Method(MethodKind::Trait { body: true })), + ]); + const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::RustcDoNotConstCheck; +} + +pub(crate) struct RustcNonnullOptimizationGuaranteedParser; + +impl NoArgsAttributeParser for RustcNonnullOptimizationGuaranteedParser { + const PATH: &[Symbol] = &[sym::rustc_nonnull_optimization_guaranteed]; + const ON_DUPLICATE: OnDuplicate = OnDuplicate::Error; + const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Struct)]); + const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::RustcNonnullOptimizationGuaranteed; +} + pub(crate) struct RustcSymbolName; impl SingleAttributeParser for RustcSymbolName { diff --git a/compiler/rustc_attr_parsing/src/context.rs b/compiler/rustc_attr_parsing/src/context.rs index 87aa4150becd3..91665778bf18f 100644 --- a/compiler/rustc_attr_parsing/src/context.rs +++ b/compiler/rustc_attr_parsing/src/context.rs @@ -269,6 +269,7 @@ attribute_parsers!( Single>, Single>, Single>, + Single>, Single>, Single>, Single>, @@ -290,6 +291,7 @@ attribute_parsers!( Single>, Single>, Single>, + Single>, Single>, Single>, Single>, diff --git a/compiler/rustc_const_eval/src/check_consts/check.rs b/compiler/rustc_const_eval/src/check_consts/check.rs index 57396b657a3fa..41c4274ce4f93 100644 --- a/compiler/rustc_const_eval/src/check_consts/check.rs +++ b/compiler/rustc_const_eval/src/check_consts/check.rs @@ -7,9 +7,10 @@ use std::ops::Deref; use rustc_data_structures::assert_matches; use rustc_errors::{Diag, ErrorGuaranteed}; +use rustc_hir::attrs::AttributeKind; use rustc_hir::def::DefKind; use rustc_hir::def_id::DefId; -use rustc_hir::{self as hir, LangItem}; +use rustc_hir::{self as hir, LangItem, find_attr}; use rustc_index::bit_set::DenseBitSet; use rustc_infer::infer::TyCtxtInferExt; use rustc_middle::mir::visit::Visitor; @@ -215,7 +216,7 @@ impl<'mir, 'tcx> Checker<'mir, 'tcx> { return; } - if !tcx.has_attr(def_id, sym::rustc_do_not_const_check) { + if !find_attr!(tcx.get_all_attrs(def_id), AttributeKind::RustcDoNotConstCheck) { self.visit_body(body); } diff --git a/compiler/rustc_const_eval/src/check_consts/post_drop_elaboration.rs b/compiler/rustc_const_eval/src/check_consts/post_drop_elaboration.rs index 16e142a85ee6f..6189d9321dc09 100644 --- a/compiler/rustc_const_eval/src/check_consts/post_drop_elaboration.rs +++ b/compiler/rustc_const_eval/src/check_consts/post_drop_elaboration.rs @@ -1,3 +1,5 @@ +use rustc_hir::attrs::AttributeKind; +use rustc_hir::find_attr; use rustc_middle::mir::visit::Visitor; use rustc_middle::mir::{self, BasicBlock, Location}; use rustc_middle::ty::TyCtxt; @@ -34,7 +36,7 @@ pub fn check_live_drops<'tcx>(tcx: TyCtxt<'tcx>, body: &mir::Body<'tcx>) { return; } - if tcx.has_attr(body.source.def_id(), sym::rustc_do_not_const_check) { + if find_attr!(tcx.get_all_attrs(body.source.def_id()), AttributeKind::RustcDoNotConstCheck) { return; } diff --git a/compiler/rustc_const_eval/src/const_eval/machine.rs b/compiler/rustc_const_eval/src/const_eval/machine.rs index da4f97db1c59c..604cc0ad2ce25 100644 --- a/compiler/rustc_const_eval/src/const_eval/machine.rs +++ b/compiler/rustc_const_eval/src/const_eval/machine.rs @@ -6,8 +6,9 @@ use rustc_abi::{Align, Size}; use rustc_ast::Mutability; use rustc_data_structures::fx::{FxHashMap, FxIndexMap, IndexEntry}; use rustc_errors::inline_fluent; +use rustc_hir::attrs::AttributeKind; use rustc_hir::def_id::{DefId, LocalDefId}; -use rustc_hir::{self as hir, CRATE_HIR_ID, LangItem}; +use rustc_hir::{self as hir, CRATE_HIR_ID, LangItem, find_attr}; use rustc_middle::mir::AssertMessage; use rustc_middle::mir::interpret::{Pointer, ReportedErrorInfo}; use rustc_middle::query::TyCtxtAt; @@ -440,7 +441,9 @@ impl<'tcx> interpret::Machine<'tcx> for CompileTimeMachine<'tcx> { // sensitive check here. But we can at least rule out functions that are not const at // all. That said, we have to allow calling functions inside a `const trait`. These // *are* const-checked! - if !ecx.tcx.is_const_fn(def) || ecx.tcx.has_attr(def, sym::rustc_do_not_const_check) { + if !ecx.tcx.is_const_fn(def) + || find_attr!(ecx.tcx.get_all_attrs(def), AttributeKind::RustcDoNotConstCheck) + { // We certainly do *not* want to actually call the fn // though, so be sure we return here. throw_unsup_format!("calling non-const function `{}`", instance) diff --git a/compiler/rustc_const_eval/src/interpret/call.rs b/compiler/rustc_const_eval/src/interpret/call.rs index ffa7b09205d58..f4351d8816513 100644 --- a/compiler/rustc_const_eval/src/interpret/call.rs +++ b/compiler/rustc_const_eval/src/interpret/call.rs @@ -7,11 +7,12 @@ use either::{Left, Right}; use rustc_abi::{self as abi, ExternAbi, FieldIdx, Integer, VariantIdx}; use rustc_data_structures::assert_matches; use rustc_errors::inline_fluent; +use rustc_hir::attrs::AttributeKind; use rustc_hir::def_id::DefId; +use rustc_hir::find_attr; use rustc_middle::ty::layout::{IntegerExt, TyAndLayout}; use rustc_middle::ty::{self, AdtDef, Instance, Ty, VariantDef}; use rustc_middle::{bug, mir, span_bug}; -use rustc_span::sym; use rustc_target::callconv::{ArgAbi, FnAbi, PassMode}; use tracing::field::Empty; use tracing::{info, instrument, trace}; @@ -145,7 +146,10 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> { // Check if the inner type is one of the NPO-guaranteed ones. // For that we first unpeel transparent *structs* (but not unions). let is_npo = |def: AdtDef<'tcx>| { - self.tcx.has_attr(def.did(), sym::rustc_nonnull_optimization_guaranteed) + find_attr!( + self.tcx.get_all_attrs(def.did()), + AttributeKind::RustcNonnullOptimizationGuaranteed + ) }; let inner = self.unfold_transparent(inner, /* may_unfold */ |def| { // Stop at NPO types so that we don't miss that attribute in the check below! diff --git a/compiler/rustc_hir/src/attrs/data_structures.rs b/compiler/rustc_hir/src/attrs/data_structures.rs index 8e68a3d002334..9276f81325226 100644 --- a/compiler/rustc_hir/src/attrs/data_structures.rs +++ b/compiler/rustc_hir/src/attrs/data_structures.rs @@ -1153,6 +1153,9 @@ pub enum AttributeKind { /// Represents `#[rustc_deprecated_safe_2024]` RustcDeprecatedSafe2024 { suggestion: Symbol }, + /// Represents `#[rustc_do_not_const_check]` + RustcDoNotConstCheck, + /// Represents `#[rustc_dummy]`. RustcDummy, @@ -1255,6 +1258,9 @@ pub enum AttributeKind { /// Represents `#[rustc_non_const_trait_method]`. RustcNonConstTraitMethod, + /// Represents `#[rustc_nonnull_optimization_guaranteed]`. + RustcNonnullOptimizationGuaranteed, + /// Represents `#[rustc_nounwind]` RustcNounwind, diff --git a/compiler/rustc_hir/src/attrs/encode_cross_crate.rs b/compiler/rustc_hir/src/attrs/encode_cross_crate.rs index e68ab1c42bafd..9d291ff2d8154 100644 --- a/compiler/rustc_hir/src/attrs/encode_cross_crate.rs +++ b/compiler/rustc_hir/src/attrs/encode_cross_crate.rs @@ -112,6 +112,7 @@ impl AttributeKind { RustcDelayedBugFromInsideQuery => No, RustcDenyExplicitImpl(..) => No, RustcDeprecatedSafe2024 { .. } => Yes, + RustcDoNotConstCheck => Yes, RustcDummy => No, RustcDumpDefParents => No, RustcDumpItemBounds => No, @@ -145,6 +146,7 @@ impl AttributeKind { RustcNoImplicitBounds => No, RustcNoMirInline => Yes, RustcNonConstTraitMethod => No, // should be reported via other queries like `constness` + RustcNonnullOptimizationGuaranteed => Yes, RustcNounwind => No, RustcObjcClass { .. } => No, RustcObjcSelector { .. } => No, diff --git a/compiler/rustc_hir_typeck/src/callee.rs b/compiler/rustc_hir_typeck/src/callee.rs index e20d5cdf28892..51271c20fccff 100644 --- a/compiler/rustc_hir_typeck/src/callee.rs +++ b/compiler/rustc_hir_typeck/src/callee.rs @@ -914,7 +914,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } // If we have `rustc_do_not_const_check`, do not check `[const]` bounds. - if self.has_rustc_attrs && self.tcx.has_attr(self.body_id, sym::rustc_do_not_const_check) { + if self.has_rustc_attrs + && find_attr!(self.tcx.get_all_attrs(self.body_id), AttributeKind::RustcDoNotConstCheck) + { return; } diff --git a/compiler/rustc_lint/src/types.rs b/compiler/rustc_lint/src/types.rs index 47e1fef8b82ea..b5126fffc1c5d 100644 --- a/compiler/rustc_lint/src/types.rs +++ b/compiler/rustc_lint/src/types.rs @@ -1,7 +1,8 @@ use std::iter; use rustc_abi::{BackendRepr, TagEncoding, Variants, WrappingRange}; -use rustc_hir::{Expr, ExprKind, HirId, LangItem}; +use rustc_hir::attrs::AttributeKind; +use rustc_hir::{Expr, ExprKind, HirId, LangItem, find_attr}; use rustc_middle::bug; use rustc_middle::ty::layout::{LayoutOf, SizeSkeleton}; use rustc_middle::ty::{self, Ty, TyCtxt, TypeVisitableExt}; @@ -686,7 +687,7 @@ pub(crate) fn nonnull_optimization_guaranteed<'tcx>( tcx: TyCtxt<'tcx>, def: ty::AdtDef<'tcx>, ) -> bool { - tcx.has_attr(def.did(), sym::rustc_nonnull_optimization_guaranteed) + find_attr!(tcx.get_all_attrs(def.did()), AttributeKind::RustcNonnullOptimizationGuaranteed) } /// `repr(transparent)` structs can have a single non-1-ZST field, this function returns that diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs index b6f0e9fedd6d8..f33ec81e1c228 100644 --- a/compiler/rustc_passes/src/check_attr.rs +++ b/compiler/rustc_passes/src/check_attr.rs @@ -307,6 +307,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> { | AttributeKind::RustcDelayedBugFromInsideQuery | AttributeKind::RustcDenyExplicitImpl(..) | AttributeKind::RustcDeprecatedSafe2024 {..} + | AttributeKind::RustcDoNotConstCheck | AttributeKind::RustcDummy | AttributeKind::RustcDumpDefParents | AttributeKind::RustcDumpItemBounds @@ -338,6 +339,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> { | AttributeKind::RustcNoImplicitBounds | AttributeKind::RustcNoMirInline | AttributeKind::RustcNonConstTraitMethod + | AttributeKind::RustcNonnullOptimizationGuaranteed | AttributeKind::RustcNounwind | AttributeKind::RustcObjcClass { .. } | AttributeKind::RustcObjcSelector { .. } @@ -399,10 +401,8 @@ impl<'tcx> CheckAttrVisitor<'tcx> { | sym::lang | sym::default_lib_allocator | sym::rustc_diagnostic_item - | sym::rustc_nonnull_optimization_guaranteed | sym::rustc_inherit_overflow_checks | sym::rustc_on_unimplemented - | sym::rustc_do_not_const_check | sym::rustc_doc_primitive | sym::rustc_test_marker | sym::rustc_layout diff --git a/tests/ui/feature-gates/feature-gate-rustc-attrs-1.rs b/tests/ui/feature-gates/feature-gate-rustc-attrs-1.rs index f3d5bcbd8d781..beddfd87a5e7e 100644 --- a/tests/ui/feature-gates/feature-gate-rustc-attrs-1.rs +++ b/tests/ui/feature-gates/feature-gate-rustc-attrs-1.rs @@ -5,10 +5,12 @@ //~| NOTE the `#[rustc_nonnull_optimization_guaranteed]` attribute is an internal implementation detail that will never be stable //~| NOTE the `#[rustc_nonnull_optimization_guaranteed]` attribute is just used to document guaranteed niche optimizations in the standard library //~| NOTE the compiler does not even check whether the type indeed is being non-null-optimized; it is your responsibility to ensure that the attribute is only used on types that are optimized -fn main() {} +struct Foo {} #[rustc_variance] //~^ ERROR use of an internal attribute [E0658] //~| NOTE the `#[rustc_variance]` attribute is an internal implementation detail that will never be stable //~| NOTE the `#[rustc_variance]` attribute is used for rustc unit tests enum E {} + +fn main() {}