Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 24 additions & 0 deletions compiler/rustc_attr_parsing/src/attributes/rustc_internal.rs
Original file line number Diff line number Diff line change
Expand Up @@ -791,6 +791,30 @@ impl<S: Stage> NoArgsAttributeParser<S> for RustcEffectiveVisibilityParser {
const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::RustcEffectiveVisibility;
}

pub(crate) struct RustcDoNotConstCheckParser;

impl<S: Stage> NoArgsAttributeParser<S> for RustcDoNotConstCheckParser {
const PATH: &[Symbol] = &[sym::rustc_do_not_const_check];
const ON_DUPLICATE: OnDuplicate<S> = 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<S: Stage> NoArgsAttributeParser<S> for RustcNonnullOptimizationGuaranteedParser {
const PATH: &[Symbol] = &[sym::rustc_nonnull_optimization_guaranteed];
const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Error;
const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Struct)]);
const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::RustcNonnullOptimizationGuaranteed;
}

pub(crate) struct RustcSymbolName;

impl<S: Stage> SingleAttributeParser<S> for RustcSymbolName {
Expand Down
2 changes: 2 additions & 0 deletions compiler/rustc_attr_parsing/src/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -263,6 +263,7 @@ attribute_parsers!(
Single<WithoutArgs<RustcCoherenceIsCoreParser>>,
Single<WithoutArgs<RustcDeallocatorParser>>,
Single<WithoutArgs<RustcDelayedBugFromInsideQueryParser>>,
Single<WithoutArgs<RustcDoNotConstCheckParser>>,
Single<WithoutArgs<RustcDumpDefParentsParser>>,
Single<WithoutArgs<RustcDumpItemBoundsParser>>,
Single<WithoutArgs<RustcDumpPredicatesParser>>,
Expand All @@ -282,6 +283,7 @@ attribute_parsers!(
Single<WithoutArgs<RustcNeverReturnsNullPointerParser>>,
Single<WithoutArgs<RustcNoImplicitAutorefsParser>>,
Single<WithoutArgs<RustcNonConstTraitMethodParser>>,
Single<WithoutArgs<RustcNonnullOptimizationGuaranteedParser>>,
Single<WithoutArgs<RustcNounwindParser>>,
Single<WithoutArgs<RustcOffloadKernelParser>>,
Single<WithoutArgs<RustcOutlivesParser>>,
Expand Down
5 changes: 3 additions & 2 deletions compiler/rustc_const_eval/src/check_consts/check.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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);
}

Expand Down
Original file line number Diff line number Diff line change
@@ -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;
Expand Down Expand Up @@ -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;
}

Expand Down
7 changes: 5 additions & 2 deletions compiler/rustc_const_eval/src/const_eval/machine.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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)
Expand Down
8 changes: 6 additions & 2 deletions compiler/rustc_const_eval/src/interpret/call.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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};
Expand Down Expand Up @@ -142,7 +143,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!
Expand Down
6 changes: 6 additions & 0 deletions compiler/rustc_hir/src/attrs/data_structures.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1090,6 +1090,9 @@ pub enum AttributeKind {
/// Represents `#[rustc_deny_explicit_impl]`.
RustcDenyExplicitImpl(Span),

/// Represents `#[rustc_do_not_const_check]`
RustcDoNotConstCheck,

/// Represents `#[rustc_dummy]`.
RustcDummy,

Expand Down Expand Up @@ -1180,6 +1183,9 @@ pub enum AttributeKind {
/// Represents `#[rustc_non_const_trait_method]`.
RustcNonConstTraitMethod,

/// Represents `#[rustc_nonnull_optimization_guaranteed]`.
RustcNonnullOptimizationGuaranteed,

/// Represents `#[rustc_nounwind]`
RustcNounwind,

Expand Down
2 changes: 2 additions & 0 deletions compiler/rustc_hir/src/attrs/encode_cross_crate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,7 @@ impl AttributeKind {
RustcDefPath(..) => No,
RustcDelayedBugFromInsideQuery => No,
RustcDenyExplicitImpl(..) => No,
RustcDoNotConstCheck => Yes,
RustcDummy => No,
RustcDumpDefParents => No,
RustcDumpItemBounds => No,
Expand Down Expand Up @@ -138,6 +139,7 @@ impl AttributeKind {
RustcNeverReturnsNullPointer => Yes,
RustcNoImplicitAutorefs => Yes,
RustcNonConstTraitMethod => No, // should be reported via other queries like `constness`
RustcNonnullOptimizationGuaranteed => Yes,
RustcNounwind => No,
RustcObjcClass { .. } => No,
RustcObjcSelector { .. } => No,
Expand Down
4 changes: 3 additions & 1 deletion compiler/rustc_hir_typeck/src/callee.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}

Expand Down
5 changes: 3 additions & 2 deletions compiler/rustc_lint/src/types.rs
Original file line number Diff line number Diff line change
@@ -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};
Expand Down Expand Up @@ -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
Expand Down
4 changes: 2 additions & 2 deletions compiler/rustc_passes/src/check_attr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -303,6 +303,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
| AttributeKind::RustcDefPath(..)
| AttributeKind::RustcDelayedBugFromInsideQuery
| AttributeKind::RustcDenyExplicitImpl(..)
| AttributeKind::RustcDoNotConstCheck
| AttributeKind::RustcDummy
| AttributeKind::RustcDumpDefParents
| AttributeKind::RustcDumpItemBounds
Expand Down Expand Up @@ -331,6 +332,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
| AttributeKind::RustcNeverReturnsNullPointer
| AttributeKind::RustcNoImplicitAutorefs
| AttributeKind::RustcNonConstTraitMethod
| AttributeKind::RustcNonnullOptimizationGuaranteed
| AttributeKind::RustcNounwind
| AttributeKind::RustcObjcClass { .. }
| AttributeKind::RustcObjcSelector { .. }
Expand Down Expand Up @@ -391,11 +393,9 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
| sym::default_lib_allocator
| sym::rustc_diagnostic_item
| sym::rustc_no_mir_inline
| sym::rustc_nonnull_optimization_guaranteed
| sym::rustc_inherit_overflow_checks
| sym::rustc_trivial_field_reads
| sym::rustc_on_unimplemented
| sym::rustc_do_not_const_check
| sym::rustc_reservation_impl
| sym::rustc_doc_primitive
| sym::rustc_conversion_suggestion
Expand Down
4 changes: 3 additions & 1 deletion tests/ui/feature-gates/feature-gate-rustc-attrs-1.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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() {}
Loading