merge crate-level into ALLOWED_TARGETS
This commit is contained in:
parent
60a5372753
commit
f56eb06047
7 changed files with 23 additions and 62 deletions
|
|
@ -43,11 +43,7 @@ impl<S: Stage> SingleAttributeParser<S> for CrateNameParser {
|
|||
const ATTRIBUTE_ORDER: AttributeOrder = AttributeOrder::KeepOutermost;
|
||||
const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::WarnButFutureError;
|
||||
const TEMPLATE: AttributeTemplate = template!(NameValueStr: "name");
|
||||
const TYPE: AttributeType = AttributeType::CrateLevel;
|
||||
|
||||
// because it's a crate-level attribute, we already warn about it.
|
||||
// Putting target limitations here would give duplicate warnings
|
||||
const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(ALL_TARGETS);
|
||||
const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::CrateLevel;
|
||||
|
||||
fn convert(cx: &mut AcceptContext<'_, '_, S>, args: &ArgParser<'_>) -> Option<AttributeKind> {
|
||||
let ArgParser::NameValue(n) = args else {
|
||||
|
|
@ -76,11 +72,7 @@ impl<S: Stage> SingleAttributeParser<S> for RecursionLimitParser {
|
|||
const ATTRIBUTE_ORDER: AttributeOrder = AttributeOrder::KeepOutermost;
|
||||
const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::WarnButFutureError;
|
||||
const TEMPLATE: AttributeTemplate = template!(NameValueStr: "N", "https://doc.rust-lang.org/reference/attributes/limits.html#the-recursion_limit-attribute");
|
||||
const TYPE: AttributeType = AttributeType::CrateLevel;
|
||||
|
||||
// because it's a crate-level attribute, we already warn about it.
|
||||
// Putting target limitations here would give duplicate warnings
|
||||
const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(ALL_TARGETS);
|
||||
const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::CrateLevel;
|
||||
|
||||
fn convert(cx: &mut AcceptContext<'_, '_, S>, args: &ArgParser<'_>) -> Option<AttributeKind> {
|
||||
let ArgParser::NameValue(nv) = args else {
|
||||
|
|
@ -103,11 +95,7 @@ impl<S: Stage> SingleAttributeParser<S> for MoveSizeLimitParser {
|
|||
const ATTRIBUTE_ORDER: AttributeOrder = AttributeOrder::KeepOutermost;
|
||||
const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Error;
|
||||
const TEMPLATE: AttributeTemplate = template!(NameValueStr: "N");
|
||||
const TYPE: AttributeType = AttributeType::CrateLevel;
|
||||
|
||||
// because it's a crate-level attribute, we already warn about it.
|
||||
// Putting target limitations here would give duplicate warnings
|
||||
const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(ALL_TARGETS);
|
||||
const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::CrateLevel;
|
||||
|
||||
fn convert(cx: &mut AcceptContext<'_, '_, S>, args: &ArgParser<'_>) -> Option<AttributeKind> {
|
||||
let ArgParser::NameValue(nv) = args else {
|
||||
|
|
@ -130,11 +118,7 @@ impl<S: Stage> SingleAttributeParser<S> for TypeLengthLimitParser {
|
|||
const ATTRIBUTE_ORDER: AttributeOrder = AttributeOrder::KeepOutermost;
|
||||
const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::WarnButFutureError;
|
||||
const TEMPLATE: AttributeTemplate = template!(NameValueStr: "N");
|
||||
const TYPE: AttributeType = AttributeType::CrateLevel;
|
||||
|
||||
// because it's a crate-level attribute, we already warn about it.
|
||||
// Putting target limitations here would give duplicate warnings
|
||||
const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(ALL_TARGETS);
|
||||
const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::CrateLevel;
|
||||
|
||||
fn convert(cx: &mut AcceptContext<'_, '_, S>, args: &ArgParser<'_>) -> Option<AttributeKind> {
|
||||
let ArgParser::NameValue(nv) = args else {
|
||||
|
|
@ -157,11 +141,7 @@ impl<S: Stage> SingleAttributeParser<S> for PatternComplexityLimitParser {
|
|||
const ATTRIBUTE_ORDER: AttributeOrder = AttributeOrder::KeepOutermost;
|
||||
const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Error;
|
||||
const TEMPLATE: AttributeTemplate = template!(NameValueStr: "N");
|
||||
const TYPE: AttributeType = AttributeType::CrateLevel;
|
||||
|
||||
// because it's a crate-level attribute, we already warn about it.
|
||||
// Putting target limitations here would give duplicate warnings
|
||||
const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(ALL_TARGETS);
|
||||
const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::CrateLevel;
|
||||
|
||||
fn convert(cx: &mut AcceptContext<'_, '_, S>, args: &ArgParser<'_>) -> Option<AttributeKind> {
|
||||
let ArgParser::NameValue(nv) = args else {
|
||||
|
|
@ -182,11 +162,8 @@ pub(crate) struct NoCoreParser;
|
|||
impl<S: Stage> NoArgsAttributeParser<S> for NoCoreParser {
|
||||
const PATH: &[Symbol] = &[sym::no_core];
|
||||
const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Warn;
|
||||
// because it's a crate-level attribute, we already warn about it.
|
||||
// Putting target limitations here would give duplicate warnings
|
||||
const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(ALL_TARGETS);
|
||||
const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::CrateLevel;
|
||||
const CREATE: fn(Span) -> AttributeKind = AttributeKind::NoCore;
|
||||
const TYPE: AttributeType = AttributeType::CrateLevel;
|
||||
}
|
||||
|
||||
pub(crate) struct NoStdParser;
|
||||
|
|
@ -194,9 +171,6 @@ pub(crate) struct NoStdParser;
|
|||
impl<S: Stage> NoArgsAttributeParser<S> for NoStdParser {
|
||||
const PATH: &[Symbol] = &[sym::no_std];
|
||||
const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Warn;
|
||||
// because it's a crate-level attribute, we already warn about it.
|
||||
// Putting target limitations here would give duplicate warnings
|
||||
const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(ALL_TARGETS);
|
||||
const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::CrateLevel;
|
||||
const CREATE: fn(Span) -> AttributeKind = AttributeKind::NoStd;
|
||||
const TYPE: AttributeType = AttributeType::CrateLevel;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -12,15 +12,11 @@
|
|||
//! - [`CombineAttributeParser`](crate::attributes::CombineAttributeParser): makes it easy to implement an attribute which should combine the
|
||||
//! contents of attributes, if an attribute appear multiple times in a list
|
||||
//!
|
||||
//! By default, attributes are allowed anywhere. When adding an attribute that should only be used
|
||||
//! at the crate root, consider setting the `TYPE` in the parser trait to
|
||||
//! [`AttributeType::CrateLevel`](rustc_feature::AttributeType::CrateLevel).
|
||||
//!
|
||||
//! Attributes should be added to `crate::context::ATTRIBUTE_PARSERS` to be parsed.
|
||||
|
||||
use std::marker::PhantomData;
|
||||
|
||||
use rustc_feature::{AttributeTemplate, AttributeType, template};
|
||||
use rustc_feature::{AttributeTemplate, template};
|
||||
use rustc_hir::attrs::AttributeKind;
|
||||
use rustc_span::{Span, Symbol};
|
||||
use thin_vec::ThinVec;
|
||||
|
|
@ -89,11 +85,8 @@ pub(crate) trait AttributeParser<S: Stage>: Default + 'static {
|
|||
///
|
||||
/// If an attribute has this symbol, the `accept` function will be called on it.
|
||||
const ATTRIBUTES: AcceptMapping<Self, S>;
|
||||
|
||||
const ALLOWED_TARGETS: AllowedTargets;
|
||||
|
||||
const TYPE: AttributeType = AttributeType::Normal;
|
||||
|
||||
/// The parser has gotten a chance to accept the attributes on an item,
|
||||
/// here it can produce an attribute.
|
||||
///
|
||||
|
|
@ -135,8 +128,6 @@ pub(crate) trait SingleAttributeParser<S: Stage>: 'static {
|
|||
/// The template this attribute parser should implement. Used for diagnostics.
|
||||
const TEMPLATE: AttributeTemplate;
|
||||
|
||||
const TYPE: AttributeType = AttributeType::Normal;
|
||||
|
||||
/// Converts a single syntactical attribute to a single semantic attribute, or [`AttributeKind`]
|
||||
fn convert(cx: &mut AcceptContext<'_, '_, S>, args: &ArgParser<'_>) -> Option<AttributeKind>;
|
||||
}
|
||||
|
|
@ -183,8 +174,6 @@ impl<T: SingleAttributeParser<S>, S: Stage> AttributeParser<S> for Single<T, S>
|
|||
)];
|
||||
const ALLOWED_TARGETS: AllowedTargets = T::ALLOWED_TARGETS;
|
||||
|
||||
const TYPE: AttributeType = T::TYPE;
|
||||
|
||||
fn finalize(self, _cx: &FinalizeContext<'_, '_, S>) -> Option<AttributeKind> {
|
||||
Some(self.1?.0)
|
||||
}
|
||||
|
|
@ -269,7 +258,6 @@ pub(crate) trait NoArgsAttributeParser<S: Stage>: 'static {
|
|||
const PATH: &[Symbol];
|
||||
const ON_DUPLICATE: OnDuplicate<S>;
|
||||
const ALLOWED_TARGETS: AllowedTargets;
|
||||
const TYPE: AttributeType = AttributeType::Normal;
|
||||
|
||||
/// Create the [`AttributeKind`] given attribute's [`Span`].
|
||||
const CREATE: fn(Span) -> AttributeKind;
|
||||
|
|
@ -289,7 +277,6 @@ impl<T: NoArgsAttributeParser<S>, S: Stage> SingleAttributeParser<S> for Without
|
|||
const ON_DUPLICATE: OnDuplicate<S> = T::ON_DUPLICATE;
|
||||
const ALLOWED_TARGETS: AllowedTargets = T::ALLOWED_TARGETS;
|
||||
const TEMPLATE: AttributeTemplate = template!(Word);
|
||||
const TYPE: AttributeType = T::TYPE;
|
||||
|
||||
fn convert(cx: &mut AcceptContext<'_, '_, S>, args: &ArgParser<'_>) -> Option<AttributeKind> {
|
||||
if let Err(span) = args.no_args() {
|
||||
|
|
@ -323,8 +310,6 @@ pub(crate) trait CombineAttributeParser<S: Stage>: 'static {
|
|||
/// The template this attribute parser should implement. Used for diagnostics.
|
||||
const TEMPLATE: AttributeTemplate;
|
||||
|
||||
const TYPE: AttributeType = AttributeType::Normal;
|
||||
|
||||
/// Converts a single syntactical attribute to a number of elements of the semantic attribute, or [`AttributeKind`]
|
||||
fn extend<'c>(
|
||||
cx: &'c mut AcceptContext<'_, '_, S>,
|
||||
|
|
@ -360,7 +345,6 @@ impl<T: CombineAttributeParser<S>, S: Stage> AttributeParser<S> for Combine<T, S
|
|||
group.items.extend(T::extend(cx, args))
|
||||
})];
|
||||
const ALLOWED_TARGETS: AllowedTargets = T::ALLOWED_TARGETS;
|
||||
const TYPE: AttributeType = T::TYPE;
|
||||
|
||||
fn finalize(self, _cx: &FinalizeContext<'_, '_, S>) -> Option<AttributeKind> {
|
||||
if let Some(first_span) = self.first_span {
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
// data structures
|
||||
#[doc(hidden)]
|
||||
pub(super) use rustc_feature::{AttributeTemplate, AttributeType, template};
|
||||
pub(super) use rustc_feature::{AttributeTemplate, template};
|
||||
#[doc(hidden)]
|
||||
pub(super) use rustc_hir::attrs::AttributeKind;
|
||||
#[doc(hidden)]
|
||||
|
|
|
|||
|
|
@ -1,7 +1,5 @@
|
|||
use std::mem;
|
||||
|
||||
use rustc_feature::AttributeType;
|
||||
|
||||
use super::prelude::*;
|
||||
use crate::attributes::{
|
||||
AttributeOrder, NoArgsAttributeParser, OnDuplicate, SingleAttributeParser,
|
||||
|
|
@ -155,8 +153,7 @@ pub(crate) struct CoherenceIsCoreParser;
|
|||
impl<S: Stage> NoArgsAttributeParser<S> for CoherenceIsCoreParser {
|
||||
const PATH: &[Symbol] = &[sym::rustc_coherence_is_core];
|
||||
const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Error;
|
||||
const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Crate)]);
|
||||
const TYPE: AttributeType = AttributeType::CrateLevel;
|
||||
const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::CrateLevel;
|
||||
const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::CoherenceIsCore;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ use std::sync::LazyLock;
|
|||
use private::Sealed;
|
||||
use rustc_ast::{AttrStyle, CRATE_NODE_ID, MetaItemLit, NodeId};
|
||||
use rustc_errors::{Diag, Diagnostic, Level};
|
||||
use rustc_feature::{AttributeTemplate, AttributeType};
|
||||
use rustc_feature::AttributeTemplate;
|
||||
use rustc_hir::attrs::AttributeKind;
|
||||
use rustc_hir::lints::{AttributeLint, AttributeLintKind};
|
||||
use rustc_hir::{AttrPath, CRATE_HIR_ID, HirId};
|
||||
|
|
@ -83,7 +83,6 @@ pub(super) struct GroupTypeInnerAccept<S: Stage> {
|
|||
pub(super) template: AttributeTemplate,
|
||||
pub(super) accept_fn: AcceptFn<S>,
|
||||
pub(super) allowed_targets: AllowedTargets,
|
||||
pub(super) attribute_type: AttributeType,
|
||||
}
|
||||
|
||||
type AcceptFn<S> =
|
||||
|
|
@ -133,7 +132,6 @@ macro_rules! attribute_parsers {
|
|||
})
|
||||
}),
|
||||
allowed_targets: <$names as crate::attributes::AttributeParser<$stage>>::ALLOWED_TARGETS,
|
||||
attribute_type: <$names as crate::attributes::AttributeParser<$stage>>::TYPE,
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -272,7 +272,6 @@ impl<'sess, S: Stage> AttributeParser<'sess, S> {
|
|||
|
||||
(accept.accept_fn)(&mut cx, args);
|
||||
if !matches!(cx.stage.should_emit(), ShouldEmit::Nothing) {
|
||||
Self::check_type(accept.attribute_type, target, &mut cx);
|
||||
Self::check_target(&accept.allowed_targets, target, &mut cx);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@ use std::borrow::Cow;
|
|||
|
||||
use rustc_ast::AttrStyle;
|
||||
use rustc_errors::DiagArgValue;
|
||||
use rustc_feature::{AttributeType, Features};
|
||||
use rustc_feature::Features;
|
||||
use rustc_hir::lints::AttributeLintKind;
|
||||
use rustc_hir::{MethodKind, Target};
|
||||
|
||||
|
|
@ -14,6 +14,11 @@ use crate::session_diagnostics::InvalidTarget;
|
|||
pub(crate) enum AllowedTargets {
|
||||
AllowList(&'static [Policy]),
|
||||
AllowListWarnRest(&'static [Policy]),
|
||||
/// Special, and not the same as `AllowList(&[Allow(Target::Crate)])`.
|
||||
/// For crate-level attributes we emit a specific set of lints to warn
|
||||
/// people about accidentally not using them on the crate.
|
||||
/// Only use this for attributes that are *exclusively* valid at the crate level.
|
||||
CrateLevel,
|
||||
}
|
||||
|
||||
pub(crate) enum AllowedResult {
|
||||
|
|
@ -43,6 +48,7 @@ impl AllowedTargets {
|
|||
AllowedResult::Warn
|
||||
}
|
||||
}
|
||||
AllowedTargets::CrateLevel => AllowedResult::Allowed,
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -50,6 +56,7 @@ impl AllowedTargets {
|
|||
match self {
|
||||
AllowedTargets::AllowList(list) => list,
|
||||
AllowedTargets::AllowListWarnRest(list) => list,
|
||||
AllowedTargets::CrateLevel => ALL_TARGETS,
|
||||
}
|
||||
.iter()
|
||||
.filter_map(|target| match target {
|
||||
|
|
@ -74,6 +81,8 @@ impl<'sess, S: Stage> AttributeParser<'sess, S> {
|
|||
target: Target,
|
||||
cx: &mut AcceptContext<'_, 'sess, S>,
|
||||
) {
|
||||
Self::check_type(matches!(allowed_targets, AllowedTargets::CrateLevel), target, cx);
|
||||
|
||||
match allowed_targets.is_allowed(target) {
|
||||
AllowedResult::Allowed => {}
|
||||
AllowedResult::Warn => {
|
||||
|
|
@ -109,7 +118,7 @@ impl<'sess, S: Stage> AttributeParser<'sess, S> {
|
|||
}
|
||||
|
||||
pub(crate) fn check_type(
|
||||
attribute_type: AttributeType,
|
||||
crate_level: bool,
|
||||
target: Target,
|
||||
cx: &mut AcceptContext<'_, 'sess, S>,
|
||||
) {
|
||||
|
|
@ -119,7 +128,7 @@ impl<'sess, S: Stage> AttributeParser<'sess, S> {
|
|||
return;
|
||||
}
|
||||
|
||||
if attribute_type != AttributeType::CrateLevel {
|
||||
if !crate_level {
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue