Port variance attrs to attr parser.

This commit is contained in:
Oscar Bray 2026-01-20 19:22:25 +00:00
parent 5c49c4f7c8
commit 005fcea374
8 changed files with 57 additions and 20 deletions

View file

@ -91,3 +91,25 @@ impl<S: Stage> SingleAttributeParser<S> for ShouldPanicParser {
})
}
}
pub(crate) struct RustcVarianceParser;
impl<S: Stage> NoArgsAttributeParser<S> for RustcVarianceParser {
const PATH: &[Symbol] = &[sym::rustc_variance];
const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Warn;
const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[
Allow(Target::Struct),
Allow(Target::Enum),
Allow(Target::Union),
]);
const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::RustcVariance;
}
pub(crate) struct RustcVarianceOfOpaquesParser;
impl<S: Stage> NoArgsAttributeParser<S> for RustcVarianceOfOpaquesParser {
const PATH: &[Symbol] = &[sym::rustc_variance_of_opaques];
const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Warn;
const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Crate)]);
const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::RustcVarianceOfOpaques;
}

View file

@ -85,7 +85,9 @@ use crate::attributes::semantics::MayDangleParser;
use crate::attributes::stability::{
BodyStabilityParser, ConstStabilityIndirectParser, ConstStabilityParser, StabilityParser,
};
use crate::attributes::test_attrs::{IgnoreParser, ShouldPanicParser};
use crate::attributes::test_attrs::{
IgnoreParser, RustcVarianceOfOpaquesParser, RustcVarianceParser, ShouldPanicParser,
};
use crate::attributes::traits::{
AllowIncoherentImplParser, CoinductiveParser, DenyExplicitImplParser,
DoNotImplementViaObjectParser, FundamentalParser, MarkerParser, ParenSugarParser,
@ -300,6 +302,8 @@ attribute_parsers!(
Single<WithoutArgs<RustcPassIndirectlyInNonRusticAbisParser>>,
Single<WithoutArgs<RustcReallocatorParser>>,
Single<WithoutArgs<RustcShouldNotBeCalledOnConstItems>>,
Single<WithoutArgs<RustcVarianceOfOpaquesParser>>,
Single<WithoutArgs<RustcVarianceParser>>,
Single<WithoutArgs<SpecializationTraitParser>>,
Single<WithoutArgs<StdInternalSymbolParser>>,
Single<WithoutArgs<ThreadLocalParser>>,

View file

@ -1007,6 +1007,12 @@ pub enum AttributeKind {
/// Represents `#[rustc_simd_monomorphize_lane_limit = "N"]`.
RustcSimdMonomorphizeLaneLimit(Limit),
/// Represents `#[rustc_variance]`
RustcVariance,
/// Represents `#[rustc_variance_of_opaques]`
RustcVarianceOfOpaques,
/// Represents `#[sanitize]`
///
/// the on set and off set are distjoint since there's a third option: unset.

View file

@ -129,6 +129,8 @@ impl AttributeKind {
RustcScalableVector { .. } => Yes,
RustcShouldNotBeCalledOnConstItems(..) => Yes,
RustcSimdMonomorphizeLaneLimit(..) => Yes, // Affects layout computation, which needs to work cross-crate
RustcVariance => No,
RustcVarianceOfOpaques => No,
Sanitize { .. } => No,
ShouldPanic { .. } => No,
SkipDuringMethodDispatch { .. } => No,

View file

@ -1,8 +1,9 @@
use std::fmt::Write;
use rustc_hir::attrs::AttributeKind;
use rustc_hir::def_id::{CRATE_DEF_ID, LocalDefId};
use rustc_hir::find_attr;
use rustc_middle::ty::{GenericArgs, TyCtxt};
use rustc_span::sym;
fn format_variances(tcx: TyCtxt<'_>, def_id: LocalDefId) -> String {
let variances = tcx.variances_of(def_id);
@ -25,7 +26,7 @@ fn format_variances(tcx: TyCtxt<'_>, def_id: LocalDefId) -> String {
pub(crate) fn variances(tcx: TyCtxt<'_>) {
let crate_items = tcx.hir_crate_items(());
if tcx.has_attr(CRATE_DEF_ID, sym::rustc_variance_of_opaques) {
if find_attr!(tcx.get_all_attrs(CRATE_DEF_ID), AttributeKind::RustcVarianceOfOpaques) {
for id in crate_items.opaques() {
tcx.dcx().emit_err(crate::errors::VariancesOf {
span: tcx.def_span(id),
@ -35,7 +36,7 @@ pub(crate) fn variances(tcx: TyCtxt<'_>) {
}
for id in crate_items.free_items() {
if !tcx.has_attr(id.owner_id, sym::rustc_variance) {
if !find_attr!(tcx.get_all_attrs(id.owner_id), AttributeKind::RustcVariance) {
continue;
}

View file

@ -274,6 +274,8 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
| AttributeKind::RustcScalableVector { .. }
| AttributeKind::RustcSimdMonomorphizeLaneLimit(..)
| AttributeKind::RustcShouldNotBeCalledOnConstItems(..)
| AttributeKind::RustcVariance
| AttributeKind::RustcVarianceOfOpaques
| AttributeKind::ExportStable
| AttributeKind::FfiConst(..)
| AttributeKind::UnstableFeatureBound(..)
@ -378,8 +380,6 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
| sym::rustc_capture_analysis
| sym::rustc_regions
| sym::rustc_strict_coherence
| sym::rustc_variance
| sym::rustc_variance_of_opaques
| sym::rustc_hidden_type_of_opaques
| sym::rustc_mir
| sym::rustc_effective_visibility

View file

@ -1,12 +1,14 @@
// Test that `#[rustc_*]` attributes are gated by `rustc_attrs` feature gate.
#[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
#[rustc_nonnull_optimization_guaranteed]
//~^ ERROR use of an internal attribute [E0658]
//~| 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() {}
#[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 {}

View file

@ -1,16 +1,6 @@
error[E0658]: use of an internal attribute
--> $DIR/feature-gate-rustc-attrs-1.rs:3:1
|
LL | #[rustc_variance]
| ^^^^^^^^^^^^^^^^^
|
= help: add `#![feature(rustc_attrs)]` to the crate attributes to enable
= 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
error[E0658]: use of an internal attribute
--> $DIR/feature-gate-rustc-attrs-1.rs:7:1
|
LL | #[rustc_nonnull_optimization_guaranteed]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
@ -19,6 +9,16 @@ LL | #[rustc_nonnull_optimization_guaranteed]
= 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
error[E0658]: use of an internal attribute
--> $DIR/feature-gate-rustc-attrs-1.rs:10:1
|
LL | #[rustc_variance]
| ^^^^^^^^^^^^^^^^^
|
= help: add `#![feature(rustc_attrs)]` to the crate attributes to enable
= 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
error: aborting due to 2 previous errors
For more information about this error, try `rustc --explain E0658`.