Auto merge of #134381 - jdonszelmann:move-attribute-types, r=oli-obk

Split up attribute parsing code and move data types to `rustc_attr_data_structures`

This change renames `rustc_attr` to `rustc_attr_parsing`, and splits up the parsing code. At the same time, all the data types used move to `rustc_attr_data_structures`. This is in preparation of also having a third crate: `rustc_attr_validation`

I initially envisioned this as two separate PRs, but I think doing it in one go reduces the number of ways others would have to rebase their changes on this. However, I can still split them.

r? `@oli-obk` (we already discussed how this is a first step in a larger plan)

For a more detailed plan on how attributes are going to change, see https://github.com/rust-lang/rust/issues/131229

Edit: this looks like a giant PR, but the changes are actually rather trivial. Each commit is reviewable on its own, and mostly moves code around. No new logic is added.
This commit is contained in:
bors 2024-12-17 18:50:50 +00:00
commit a4cb3c8318
108 changed files with 1821 additions and 1629 deletions

View file

@ -3354,7 +3354,7 @@ dependencies = [
"itertools",
"rustc_ast",
"rustc_ast_pretty",
"rustc_attr",
"rustc_attr_parsing",
"rustc_data_structures",
"rustc_errors",
"rustc_feature",
@ -3380,7 +3380,7 @@ dependencies = [
]
[[package]]
name = "rustc_attr"
name = "rustc_attr_data_structures"
version = "0.0.0"
dependencies = [
"rustc_abi",
@ -3397,6 +3397,25 @@ dependencies = [
"rustc_span",
]
[[package]]
name = "rustc_attr_parsing"
version = "0.0.0"
dependencies = [
"rustc_abi",
"rustc_ast",
"rustc_ast_pretty",
"rustc_attr_data_structures",
"rustc_data_structures",
"rustc_errors",
"rustc_feature",
"rustc_fluent_macro",
"rustc_lexer",
"rustc_macros",
"rustc_serialize",
"rustc_session",
"rustc_span",
]
[[package]]
name = "rustc_baked_icu_data"
version = "0.0.0"
@ -3441,7 +3460,7 @@ version = "0.0.0"
dependencies = [
"rustc_ast",
"rustc_ast_pretty",
"rustc_attr",
"rustc_attr_parsing",
"rustc_data_structures",
"rustc_errors",
"rustc_expand",
@ -3473,7 +3492,7 @@ dependencies = [
"rustc-demangle",
"rustc_abi",
"rustc_ast",
"rustc_attr",
"rustc_attr_parsing",
"rustc_codegen_ssa",
"rustc_data_structures",
"rustc_errors",
@ -3515,7 +3534,7 @@ dependencies = [
"rustc_arena",
"rustc_ast",
"rustc_ast_pretty",
"rustc_attr",
"rustc_attr_parsing",
"rustc_data_structures",
"rustc_errors",
"rustc_fluent_macro",
@ -3553,7 +3572,7 @@ dependencies = [
"rustc_abi",
"rustc_apfloat",
"rustc_ast",
"rustc_attr",
"rustc_attr_parsing",
"rustc_data_structures",
"rustc_errors",
"rustc_fluent_macro",
@ -3620,7 +3639,7 @@ dependencies = [
"rustc_ast_lowering",
"rustc_ast_passes",
"rustc_ast_pretty",
"rustc_attr",
"rustc_attr_parsing",
"rustc_borrowck",
"rustc_builtin_macros",
"rustc_codegen_ssa",
@ -3724,7 +3743,7 @@ dependencies = [
"rustc_ast",
"rustc_ast_passes",
"rustc_ast_pretty",
"rustc_attr",
"rustc_attr_parsing",
"rustc_data_structures",
"rustc_errors",
"rustc_feature",
@ -3799,7 +3818,7 @@ dependencies = [
"rustc_abi",
"rustc_arena",
"rustc_ast",
"rustc_attr",
"rustc_attr_parsing",
"rustc_data_structures",
"rustc_errors",
"rustc_feature",
@ -3838,7 +3857,7 @@ dependencies = [
"rustc_abi",
"rustc_ast",
"rustc_ast_ir",
"rustc_attr",
"rustc_attr_parsing",
"rustc_data_structures",
"rustc_errors",
"rustc_fluent_macro",
@ -3927,7 +3946,7 @@ dependencies = [
"rustc_ast_lowering",
"rustc_ast_passes",
"rustc_ast_pretty",
"rustc_attr",
"rustc_attr_parsing",
"rustc_borrowck",
"rustc_builtin_macros",
"rustc_codegen_llvm",
@ -3983,7 +4002,7 @@ dependencies = [
"rustc_abi",
"rustc_ast",
"rustc_ast_pretty",
"rustc_attr",
"rustc_attr_parsing",
"rustc_data_structures",
"rustc_errors",
"rustc_feature",
@ -4057,7 +4076,7 @@ dependencies = [
"odht",
"rustc_abi",
"rustc_ast",
"rustc_attr",
"rustc_attr_parsing",
"rustc_data_structures",
"rustc_errors",
"rustc_expand",
@ -4094,7 +4113,7 @@ dependencies = [
"rustc_arena",
"rustc_ast",
"rustc_ast_ir",
"rustc_attr",
"rustc_attr_parsing",
"rustc_data_structures",
"rustc_error_messages",
"rustc_errors",
@ -4173,7 +4192,7 @@ dependencies = [
"rustc_abi",
"rustc_arena",
"rustc_ast",
"rustc_attr",
"rustc_attr_parsing",
"rustc_const_eval",
"rustc_data_structures",
"rustc_errors",
@ -4199,7 +4218,7 @@ name = "rustc_monomorphize"
version = "0.0.0"
dependencies = [
"rustc_abi",
"rustc_attr",
"rustc_attr_parsing",
"rustc_data_structures",
"rustc_errors",
"rustc_fluent_macro",
@ -4267,7 +4286,7 @@ dependencies = [
"rustc_abi",
"rustc_ast",
"rustc_ast_pretty",
"rustc_attr",
"rustc_attr_parsing",
"rustc_data_structures",
"rustc_errors",
"rustc_expand",
@ -4313,7 +4332,7 @@ name = "rustc_privacy"
version = "0.0.0"
dependencies = [
"rustc_ast",
"rustc_attr",
"rustc_attr_parsing",
"rustc_data_structures",
"rustc_errors",
"rustc_fluent_macro",
@ -4377,7 +4396,7 @@ dependencies = [
"rustc_arena",
"rustc_ast",
"rustc_ast_pretty",
"rustc_attr",
"rustc_attr_parsing",
"rustc_data_structures",
"rustc_errors",
"rustc_expand",
@ -4534,7 +4553,7 @@ dependencies = [
"rustc_abi",
"rustc_ast",
"rustc_ast_ir",
"rustc_attr",
"rustc_attr_parsing",
"rustc_data_structures",
"rustc_errors",
"rustc_fluent_macro",

View file

@ -8,7 +8,7 @@ edition = "2021"
itertools = "0.12"
rustc_ast = { path = "../rustc_ast" }
rustc_ast_pretty = { path = "../rustc_ast_pretty" }
rustc_attr = { path = "../rustc_attr" }
rustc_attr_parsing = { path = "../rustc_attr_parsing" }
rustc_data_structures = { path = "../rustc_data_structures" }
rustc_errors = { path = "../rustc_errors" }
rustc_feature = { path = "../rustc_feature" }

View file

@ -342,7 +342,7 @@ impl<'a> AstValidator<'a> {
sym::forbid,
sym::warn,
];
!arr.contains(&attr.name_or_empty()) && rustc_attr::is_builtin_attr(*attr)
!arr.contains(&attr.name_or_empty()) && rustc_attr_parsing::is_builtin_attr(*attr)
})
.for_each(|attr| {
if attr.is_doc_comment() {

File diff suppressed because it is too large Load diff

View file

@ -1,5 +1,5 @@
[package]
name = "rustc_attr"
name = "rustc_attr_data_structures"
version = "0.0.0"
edition = "2021"

View file

@ -0,0 +1,106 @@
use rustc_abi::Align;
use rustc_ast as ast;
use rustc_macros::{Decodable, Encodable, HashStable_Generic};
use rustc_span::{Span, Symbol};
use crate::RustcVersion;
#[derive(Copy, Clone, PartialEq, Encodable, Decodable, Debug, HashStable_Generic)]
pub enum InlineAttr {
None,
Hint,
Always,
Never,
}
#[derive(Clone, Encodable, Decodable, Debug, PartialEq, Eq, HashStable_Generic)]
pub enum InstructionSetAttr {
ArmA32,
ArmT32,
}
#[derive(Clone, Encodable, Decodable, Debug, HashStable_Generic)]
pub enum OptimizeAttr {
None,
Speed,
Size,
}
#[derive(Clone, Debug, Encodable, Decodable)]
pub enum DiagnosticAttribute {
// tidy-alphabetical-start
DoNotRecommend,
OnUnimplemented,
// tidy-alphabetical-end
}
#[derive(PartialEq, Debug, Encodable, Decodable, Copy, Clone)]
pub enum ReprAttr {
ReprInt(IntType),
ReprRust,
ReprC,
ReprPacked(Align),
ReprSimd,
ReprTransparent,
ReprAlign(Align),
}
pub use ReprAttr::*;
pub enum TransparencyError {
UnknownTransparency(Symbol, Span),
MultipleTransparencyAttrs(Span, Span),
}
#[derive(Eq, PartialEq, Debug, Copy, Clone)]
#[derive(Encodable, Decodable)]
pub enum IntType {
SignedInt(ast::IntTy),
UnsignedInt(ast::UintTy),
}
#[derive(Copy, Debug, Encodable, Decodable, Clone, HashStable_Generic)]
pub struct Deprecation {
pub since: DeprecatedSince,
/// The note to issue a reason.
pub note: Option<Symbol>,
/// A text snippet used to completely replace any use of the deprecated item in an expression.
///
/// This is currently unstable.
pub suggestion: Option<Symbol>,
}
/// Release in which an API is deprecated.
#[derive(Copy, Debug, Encodable, Decodable, Clone, HashStable_Generic)]
pub enum DeprecatedSince {
RustcVersion(RustcVersion),
/// Deprecated in the future ("to be determined").
Future,
/// `feature(staged_api)` is off. Deprecation versions outside the standard
/// library are allowed to be arbitrary strings, for better or worse.
NonStandard(Symbol),
/// Deprecation version is unspecified but optional.
Unspecified,
/// Failed to parse a deprecation version, or the deprecation version is
/// unspecified and required. An error has already been emitted.
Err,
}
impl Deprecation {
/// Whether an item marked with #[deprecated(since = "X")] is currently
/// deprecated (i.e., whether X is not greater than the current rustc
/// version).
pub fn is_in_effect(&self) -> bool {
match self.since {
DeprecatedSince::RustcVersion(since) => since <= RustcVersion::CURRENT,
DeprecatedSince::Future => false,
// The `since` field doesn't have semantic purpose without `#![staged_api]`.
DeprecatedSince::NonStandard(_) => true,
// Assume deprecation is in effect if "since" field is absent or invalid.
DeprecatedSince::Unspecified | DeprecatedSince::Err => true,
}
}
pub fn is_since_rustc_version(&self) -> bool {
matches!(self.since, DeprecatedSince::RustcVersion(_))
}
}

View file

@ -0,0 +1,16 @@
// tidy-alphabetical-start
#![allow(internal_features)]
#![doc(rust_logo)]
#![feature(let_chains)]
#![feature(rustdoc_internals)]
#![warn(unreachable_pub)]
// tidy-alphabetical-end
mod attributes;
mod stability;
mod version;
pub use attributes::*;
pub(crate) use rustc_session::HashStableContext;
pub use stability::*;
pub use version::*;

View file

@ -0,0 +1,200 @@
use std::num::NonZero;
use rustc_macros::{Decodable, Encodable, HashStable_Generic};
use rustc_span::{Symbol, sym};
use crate::RustcVersion;
/// The version placeholder that recently stabilized features contain inside the
/// `since` field of the `#[stable]` attribute.
///
/// For more, see [this pull request](https://github.com/rust-lang/rust/pull/100591).
pub const VERSION_PLACEHOLDER: &str = "CURRENT_RUSTC_VERSION";
/// Represents the following attributes:
///
/// - `#[stable]`
/// - `#[unstable]`
#[derive(Encodable, Decodable, Copy, Clone, Debug, PartialEq, Eq, Hash)]
#[derive(HashStable_Generic)]
pub struct Stability {
pub level: StabilityLevel,
pub feature: Symbol,
}
impl Stability {
pub fn is_unstable(&self) -> bool {
self.level.is_unstable()
}
pub fn is_stable(&self) -> bool {
self.level.is_stable()
}
pub fn stable_since(&self) -> Option<StableSince> {
self.level.stable_since()
}
}
/// Represents the `#[rustc_const_unstable]` and `#[rustc_const_stable]` attributes.
#[derive(Encodable, Decodable, Copy, Clone, Debug, PartialEq, Eq, Hash)]
#[derive(HashStable_Generic)]
pub struct ConstStability {
pub level: StabilityLevel,
pub feature: Symbol,
/// whether the function has a `#[rustc_promotable]` attribute
pub promotable: bool,
/// This is true iff the `const_stable_indirect` attribute is present.
pub const_stable_indirect: bool,
}
impl ConstStability {
pub fn from_partial(
PartialConstStability { level, feature, promotable }: PartialConstStability,
const_stable_indirect: bool,
) -> Self {
Self { const_stable_indirect, level, feature, promotable }
}
/// The stability assigned to unmarked items when -Zforce-unstable-if-unmarked is set.
pub fn unmarked(const_stable_indirect: bool, regular_stab: Stability) -> Self {
Self {
feature: regular_stab.feature,
promotable: false,
level: regular_stab.level,
const_stable_indirect,
}
}
pub fn is_const_unstable(&self) -> bool {
self.level.is_unstable()
}
pub fn is_const_stable(&self) -> bool {
self.level.is_stable()
}
}
/// Excludes `const_stable_indirect`. This is necessary because when `-Zforce-unstable-if-unmarked`
/// is set, we need to encode standalone `#[rustc_const_stable_indirect]` attributes
#[derive(Encodable, Decodable, Copy, Clone, Debug, PartialEq, Eq, Hash)]
#[derive(HashStable_Generic)]
pub struct PartialConstStability {
pub level: StabilityLevel,
pub feature: Symbol,
/// whether the function has a `#[rustc_promotable]` attribute
pub promotable: bool,
}
impl PartialConstStability {
pub fn is_const_unstable(&self) -> bool {
self.level.is_unstable()
}
pub fn is_const_stable(&self) -> bool {
self.level.is_stable()
}
}
/// The available stability levels.
#[derive(Encodable, Decodable, PartialEq, Copy, Clone, Debug, Eq, Hash)]
#[derive(HashStable_Generic)]
pub enum StabilityLevel {
/// `#[unstable]`
Unstable {
/// Reason for the current stability level.
reason: UnstableReason,
/// Relevant `rust-lang/rust` issue.
issue: Option<NonZero<u32>>,
is_soft: bool,
/// If part of a feature is stabilized and a new feature is added for the remaining parts,
/// then the `implied_by` attribute is used to indicate which now-stable feature previously
/// contained an item.
///
/// ```pseudo-Rust
/// #[unstable(feature = "foo", issue = "...")]
/// fn foo() {}
/// #[unstable(feature = "foo", issue = "...")]
/// fn foobar() {}
/// ```
///
/// ...becomes...
///
/// ```pseudo-Rust
/// #[stable(feature = "foo", since = "1.XX.X")]
/// fn foo() {}
/// #[unstable(feature = "foobar", issue = "...", implied_by = "foo")]
/// fn foobar() {}
/// ```
implied_by: Option<Symbol>,
},
/// `#[stable]`
Stable {
/// Rust release which stabilized this feature.
since: StableSince,
/// Is this item allowed to be referred to on stable, despite being contained in unstable
/// modules?
allowed_through_unstable_modules: bool,
},
}
/// Rust release in which a feature is stabilized.
#[derive(Encodable, Decodable, PartialEq, Copy, Clone, Debug, Eq, PartialOrd, Ord, Hash)]
#[derive(HashStable_Generic)]
pub enum StableSince {
/// also stores the original symbol for printing
Version(RustcVersion),
/// Stabilized in the upcoming version, whatever number that is.
Current,
/// Failed to parse a stabilization version.
Err,
}
impl StabilityLevel {
pub fn is_unstable(&self) -> bool {
matches!(self, StabilityLevel::Unstable { .. })
}
pub fn is_stable(&self) -> bool {
matches!(self, StabilityLevel::Stable { .. })
}
pub fn stable_since(&self) -> Option<StableSince> {
match *self {
StabilityLevel::Stable { since, .. } => Some(since),
StabilityLevel::Unstable { .. } => None,
}
}
}
#[derive(Encodable, Decodable, PartialEq, Copy, Clone, Debug, Eq, Hash)]
#[derive(HashStable_Generic)]
pub enum UnstableReason {
None,
Default,
Some(Symbol),
}
/// Represents the `#[rustc_default_body_unstable]` attribute.
#[derive(Encodable, Decodable, Copy, Clone, Debug, PartialEq, Eq, Hash)]
#[derive(HashStable_Generic)]
pub struct DefaultBodyStability {
pub level: StabilityLevel,
pub feature: Symbol,
}
impl UnstableReason {
pub fn from_opt_reason(reason: Option<Symbol>) -> Self {
// UnstableReason::Default constructed manually
match reason {
Some(r) => Self::Some(r),
None => Self::None,
}
}
pub fn to_opt_reason(&self) -> Option<Symbol> {
match self {
Self::None => None,
Self::Default => Some(sym::unstable_location_reason_default),
Self::Some(r) => Some(*r),
}
}
}

View file

@ -1,7 +1,5 @@
use std::borrow::Cow;
use std::fmt::{self, Display};
use rustc_errors::IntoDiagArg;
use rustc_macros::{Decodable, Encodable, HashStable_Generic, current_rustc_version};
#[derive(Encodable, Decodable, Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
@ -21,9 +19,3 @@ impl Display for RustcVersion {
write!(formatter, "{}.{}.{}", self.major, self.minor, self.patch)
}
}
impl IntoDiagArg for RustcVersion {
fn into_diag_arg(self) -> rustc_errors::DiagArgValue {
rustc_errors::DiagArgValue::Str(Cow::Owned(self.to_string()))
}
}

View file

@ -0,0 +1,21 @@
[package]
name = "rustc_attr_parsing"
version = "0.0.0"
edition = "2021"
[dependencies]
# tidy-alphabetical-start
rustc_abi = { path = "../rustc_abi" }
rustc_ast = { path = "../rustc_ast" }
rustc_ast_pretty = { path = "../rustc_ast_pretty" }
rustc_attr_data_structures = { path = "../rustc_attr_data_structures" }
rustc_data_structures = { path = "../rustc_data_structures" }
rustc_errors = { path = "../rustc_errors" }
rustc_feature = { path = "../rustc_feature" }
rustc_fluent_macro = { path = "../rustc_fluent_macro" }
rustc_lexer = { path = "../rustc_lexer" }
rustc_macros = { path = "../rustc_macros" }
rustc_serialize = { path = "../rustc_serialize" }
rustc_session = { path = "../rustc_session" }
rustc_span = { path = "../rustc_span" }
# tidy-alphabetical-end

View file

@ -1,46 +1,46 @@
attr_cfg_predicate_identifier =
attr_parsing_cfg_predicate_identifier =
`cfg` predicate key must be an identifier
attr_deprecated_item_suggestion =
attr_parsing_deprecated_item_suggestion =
suggestions on deprecated items are unstable
.help = add `#![feature(deprecated_suggestion)]` to the crate root
.note = see #94785 for more details
attr_expected_one_cfg_pattern =
attr_parsing_expected_one_cfg_pattern =
expected 1 cfg-pattern
attr_expected_single_version_literal =
attr_parsing_expected_single_version_literal =
expected single version literal
attr_expected_version_literal =
attr_parsing_expected_version_literal =
expected a version literal
attr_expects_feature_list =
attr_parsing_expects_feature_list =
`{$name}` expects a list of feature names
attr_expects_features =
attr_parsing_expects_features =
`{$name}` expects feature names
attr_incorrect_meta_item =
attr_parsing_incorrect_meta_item =
incorrect meta item
attr_incorrect_repr_format_align_one_arg =
attr_parsing_incorrect_repr_format_align_one_arg =
incorrect `repr(align)` attribute format: `align` takes exactly one argument in parentheses
attr_incorrect_repr_format_expect_literal_integer =
attr_parsing_incorrect_repr_format_expect_literal_integer =
incorrect `repr(align)` attribute format: `align` expects a literal integer as argument
attr_incorrect_repr_format_generic =
attr_parsing_incorrect_repr_format_generic =
incorrect `repr({$repr_arg})` attribute format
.suggestion = use parentheses instead
attr_incorrect_repr_format_packed_expect_integer =
attr_parsing_incorrect_repr_format_packed_expect_integer =
incorrect `repr(packed)` attribute format: `packed` expects a literal integer as argument
attr_incorrect_repr_format_packed_one_or_zero_arg =
attr_parsing_incorrect_repr_format_packed_one_or_zero_arg =
incorrect `repr(packed)` attribute format: `packed` takes exactly one parenthesized argument, or no parentheses at all
attr_invalid_issue_string =
attr_parsing_invalid_issue_string =
`issue` must be a non-zero numeric string or "none"
.must_not_be_zero = `issue` must not be "0", use "none" instead
.empty = cannot parse integer from empty string
@ -48,77 +48,77 @@ attr_invalid_issue_string =
.pos_overflow = number too large to fit in target type
.neg_overflow = number too small to fit in target type
attr_invalid_predicate =
attr_parsing_invalid_predicate =
invalid predicate `{$predicate}`
attr_invalid_repr_align_need_arg =
attr_parsing_invalid_repr_align_need_arg =
invalid `repr(align)` attribute: `align` needs an argument
.suggestion = supply an argument here
attr_invalid_repr_generic =
attr_parsing_invalid_repr_generic =
invalid `repr({$repr_arg})` attribute: {$error_part}
attr_invalid_repr_hint_no_paren =
attr_parsing_invalid_repr_hint_no_paren =
invalid representation hint: `{$name}` does not take a parenthesized argument list
attr_invalid_repr_hint_no_value =
attr_parsing_invalid_repr_hint_no_value =
invalid representation hint: `{$name}` does not take a value
attr_invalid_since =
attr_parsing_invalid_since =
'since' must be a Rust version number, such as "1.31.0"
attr_missing_feature =
attr_parsing_missing_feature =
missing 'feature'
attr_missing_issue =
attr_parsing_missing_issue =
missing 'issue'
attr_missing_note =
attr_parsing_missing_note =
missing 'note'
attr_missing_since =
attr_parsing_missing_since =
missing 'since'
attr_multiple_item =
attr_parsing_multiple_item =
multiple '{$item}' items
attr_multiple_stability_levels =
attr_parsing_multiple_stability_levels =
multiple stability levels
attr_non_ident_feature =
attr_parsing_non_ident_feature =
'feature' is not an identifier
attr_rustc_allowed_unstable_pairing =
attr_parsing_rustc_allowed_unstable_pairing =
`rustc_allowed_through_unstable_modules` attribute must be paired with a `stable` attribute
attr_rustc_const_stable_indirect_pairing =
attr_parsing_rustc_const_stable_indirect_pairing =
`const_stable_indirect` attribute does not make sense on `rustc_const_stable` function, its behavior is already implied
attr_rustc_promotable_pairing =
attr_parsing_rustc_promotable_pairing =
`rustc_promotable` attribute must be paired with either a `rustc_const_unstable` or a `rustc_const_stable` attribute
attr_soft_no_args =
attr_parsing_soft_no_args =
`soft` should not have any arguments
attr_unknown_meta_item =
attr_parsing_unknown_meta_item =
unknown meta item '{$item}'
.label = expected one of {$expected}
attr_unknown_version_literal =
attr_parsing_unknown_version_literal =
unknown version literal format, assuming it refers to a future version
attr_unstable_cfg_target_compact =
attr_parsing_unstable_cfg_target_compact =
compact `cfg(target(..))` is experimental and subject to change
attr_unsupported_literal_cfg_boolean =
attr_parsing_unsupported_literal_cfg_boolean =
literal in `cfg` predicate value must be a boolean
attr_unsupported_literal_cfg_string =
attr_parsing_unsupported_literal_cfg_string =
literal in `cfg` predicate value must be a string
attr_unsupported_literal_deprecated_kv_pair =
attr_parsing_unsupported_literal_deprecated_kv_pair =
item in `deprecated` must be a key/value pair
attr_unsupported_literal_deprecated_string =
attr_parsing_unsupported_literal_deprecated_string =
literal in `deprecated` value must be a string
attr_unsupported_literal_generic =
attr_parsing_unsupported_literal_generic =
unsupported literal
attr_unsupported_literal_suggestion =
attr_parsing_unsupported_literal_suggestion =
consider removing the prefix

View file

@ -0,0 +1,49 @@
use rustc_ast::attr::{AttributeExt, filter_by_name};
use rustc_session::Session;
use rustc_span::symbol::{Symbol, sym};
use crate::session_diagnostics;
pub fn allow_internal_unstable<'a>(
sess: &'a Session,
attrs: &'a [impl AttributeExt],
) -> impl Iterator<Item = Symbol> + 'a {
allow_unstable(sess, attrs, sym::allow_internal_unstable)
}
pub fn rustc_allow_const_fn_unstable<'a>(
sess: &'a Session,
attrs: &'a [impl AttributeExt],
) -> impl Iterator<Item = Symbol> + 'a {
allow_unstable(sess, attrs, sym::rustc_allow_const_fn_unstable)
}
fn allow_unstable<'a>(
sess: &'a Session,
attrs: &'a [impl AttributeExt],
symbol: Symbol,
) -> impl Iterator<Item = Symbol> + 'a {
let attrs = filter_by_name(attrs, symbol);
let list = attrs
.filter_map(move |attr| {
attr.meta_item_list().or_else(|| {
sess.dcx().emit_err(session_diagnostics::ExpectsFeatureList {
span: attr.span(),
name: symbol.to_ident_string(),
});
None
})
})
.flatten();
list.into_iter().filter_map(move |it| {
let name = it.ident().map(|ident| ident.name);
if name.is_none() {
sess.dcx().emit_err(session_diagnostics::ExpectsFeatures {
span: it.span(),
name: symbol.to_ident_string(),
});
}
name
})
}

View file

@ -0,0 +1,254 @@
//! Parsing and validation of builtin attributes
use rustc_ast::{self as ast, LitKind, MetaItem, MetaItemInner, MetaItemKind, MetaItemLit, NodeId};
use rustc_ast_pretty::pprust;
use rustc_attr_data_structures::RustcVersion;
use rustc_feature::{Features, GatedCfg, find_gated_cfg};
use rustc_session::Session;
use rustc_session::config::ExpectedValues;
use rustc_session::lint::BuiltinLintDiag;
use rustc_session::lint::builtin::UNEXPECTED_CFGS;
use rustc_session::parse::feature_err;
use rustc_span::Span;
use rustc_span::symbol::{Symbol, kw, sym};
use crate::util::UnsupportedLiteralReason;
use crate::{fluent_generated, parse_version, session_diagnostics};
#[derive(Clone, Debug)]
pub struct Condition {
pub name: Symbol,
pub name_span: Span,
pub value: Option<Symbol>,
pub value_span: Option<Span>,
pub span: Span,
}
/// Tests if a cfg-pattern matches the cfg set
pub fn cfg_matches(
cfg: &ast::MetaItemInner,
sess: &Session,
lint_node_id: NodeId,
features: Option<&Features>,
) -> bool {
eval_condition(cfg, sess, features, &mut |cfg| {
try_gate_cfg(cfg.name, cfg.span, sess, features);
match sess.psess.check_config.expecteds.get(&cfg.name) {
Some(ExpectedValues::Some(values)) if !values.contains(&cfg.value) => {
sess.psess.buffer_lint(
UNEXPECTED_CFGS,
cfg.span,
lint_node_id,
BuiltinLintDiag::UnexpectedCfgValue(
(cfg.name, cfg.name_span),
cfg.value.map(|v| (v, cfg.value_span.unwrap())),
),
);
}
None if sess.psess.check_config.exhaustive_names => {
sess.psess.buffer_lint(
UNEXPECTED_CFGS,
cfg.span,
lint_node_id,
BuiltinLintDiag::UnexpectedCfgName(
(cfg.name, cfg.name_span),
cfg.value.map(|v| (v, cfg.value_span.unwrap())),
),
);
}
_ => { /* not unexpected */ }
}
sess.psess.config.contains(&(cfg.name, cfg.value))
})
}
fn try_gate_cfg(name: Symbol, span: Span, sess: &Session, features: Option<&Features>) {
let gate = find_gated_cfg(|sym| sym == name);
if let (Some(feats), Some(gated_cfg)) = (features, gate) {
gate_cfg(gated_cfg, span, sess, feats);
}
}
#[allow(rustc::untranslatable_diagnostic)] // FIXME: make this translatable
fn gate_cfg(gated_cfg: &GatedCfg, cfg_span: Span, sess: &Session, features: &Features) {
let (cfg, feature, has_feature) = gated_cfg;
if !has_feature(features) && !cfg_span.allows_unstable(*feature) {
let explain = format!("`cfg({cfg})` is experimental and subject to change");
feature_err(sess, *feature, cfg_span, explain).emit();
}
}
/// Evaluate a cfg-like condition (with `any` and `all`), using `eval` to
/// evaluate individual items.
pub fn eval_condition(
cfg: &ast::MetaItemInner,
sess: &Session,
features: Option<&Features>,
eval: &mut impl FnMut(Condition) -> bool,
) -> bool {
let dcx = sess.dcx();
let cfg = match cfg {
ast::MetaItemInner::MetaItem(meta_item) => meta_item,
ast::MetaItemInner::Lit(MetaItemLit { kind: LitKind::Bool(b), .. }) => {
if let Some(features) = features {
// we can't use `try_gate_cfg` as symbols don't differentiate between `r#true`
// and `true`, and we want to keep the former working without feature gate
gate_cfg(
&(
if *b { kw::True } else { kw::False },
sym::cfg_boolean_literals,
|features: &Features| features.cfg_boolean_literals(),
),
cfg.span(),
sess,
features,
);
}
return *b;
}
_ => {
dcx.emit_err(session_diagnostics::UnsupportedLiteral {
span: cfg.span(),
reason: UnsupportedLiteralReason::CfgBoolean,
is_bytestr: false,
start_point_span: sess.source_map().start_point(cfg.span()),
});
return false;
}
};
match &cfg.kind {
ast::MetaItemKind::List(mis) if cfg.name_or_empty() == sym::version => {
try_gate_cfg(sym::version, cfg.span, sess, features);
let (min_version, span) = match &mis[..] {
[MetaItemInner::Lit(MetaItemLit { kind: LitKind::Str(sym, ..), span, .. })] => {
(sym, span)
}
[
MetaItemInner::Lit(MetaItemLit { span, .. })
| MetaItemInner::MetaItem(MetaItem { span, .. }),
] => {
dcx.emit_err(session_diagnostics::ExpectedVersionLiteral { span: *span });
return false;
}
[..] => {
dcx.emit_err(session_diagnostics::ExpectedSingleVersionLiteral {
span: cfg.span,
});
return false;
}
};
let Some(min_version) = parse_version(*min_version) else {
dcx.emit_warn(session_diagnostics::UnknownVersionLiteral { span: *span });
return false;
};
// See https://github.com/rust-lang/rust/issues/64796#issuecomment-640851454 for details
if sess.psess.assume_incomplete_release {
RustcVersion::CURRENT > min_version
} else {
RustcVersion::CURRENT >= min_version
}
}
ast::MetaItemKind::List(mis) => {
for mi in mis.iter() {
if mi.meta_item_or_bool().is_none() {
dcx.emit_err(session_diagnostics::UnsupportedLiteral {
span: mi.span(),
reason: UnsupportedLiteralReason::Generic,
is_bytestr: false,
start_point_span: sess.source_map().start_point(mi.span()),
});
return false;
}
}
// The unwraps below may look dangerous, but we've already asserted
// that they won't fail with the loop above.
match cfg.name_or_empty() {
sym::any => mis
.iter()
// We don't use any() here, because we want to evaluate all cfg condition
// as eval_condition can (and does) extra checks
.fold(false, |res, mi| res | eval_condition(mi, sess, features, eval)),
sym::all => mis
.iter()
// We don't use all() here, because we want to evaluate all cfg condition
// as eval_condition can (and does) extra checks
.fold(true, |res, mi| res & eval_condition(mi, sess, features, eval)),
sym::not => {
let [mi] = mis.as_slice() else {
dcx.emit_err(session_diagnostics::ExpectedOneCfgPattern { span: cfg.span });
return false;
};
!eval_condition(mi, sess, features, eval)
}
sym::target => {
if let Some(features) = features
&& !features.cfg_target_compact()
{
feature_err(
sess,
sym::cfg_target_compact,
cfg.span,
fluent_generated::attr_parsing_unstable_cfg_target_compact,
)
.emit();
}
mis.iter().fold(true, |res, mi| {
let Some(mut mi) = mi.meta_item().cloned() else {
dcx.emit_err(session_diagnostics::CfgPredicateIdentifier {
span: mi.span(),
});
return false;
};
if let [seg, ..] = &mut mi.path.segments[..] {
seg.ident.name = Symbol::intern(&format!("target_{}", seg.ident.name));
}
res & eval_condition(
&ast::MetaItemInner::MetaItem(mi),
sess,
features,
eval,
)
})
}
_ => {
dcx.emit_err(session_diagnostics::InvalidPredicate {
span: cfg.span,
predicate: pprust::path_to_string(&cfg.path),
});
false
}
}
}
ast::MetaItemKind::Word | MetaItemKind::NameValue(..) if cfg.path.segments.len() != 1 => {
dcx.emit_err(session_diagnostics::CfgPredicateIdentifier { span: cfg.path.span });
true
}
MetaItemKind::NameValue(lit) if !lit.kind.is_str() => {
dcx.emit_err(session_diagnostics::UnsupportedLiteral {
span: lit.span,
reason: UnsupportedLiteralReason::CfgString,
is_bytestr: lit.kind.is_bytestr(),
start_point_span: sess.source_map().start_point(lit.span),
});
true
}
ast::MetaItemKind::Word | ast::MetaItemKind::NameValue(..) => {
let ident = cfg.ident().expect("multi-segment cfg predicate");
eval(Condition {
name: ident.name,
name_span: ident.span,
value: cfg.value_str(),
value_span: cfg.name_value_literal_span(),
span: cfg.span,
})
}
}
}

View file

@ -0,0 +1,21 @@
//! Parsing and validation of builtin attributes
use rustc_ast::MetaItemInner;
use rustc_ast::attr::AttributeExt;
use rustc_span::symbol::Symbol;
/// Read the content of a `rustc_confusables` attribute, and return the list of candidate names.
pub fn parse_confusables(attr: &impl AttributeExt) -> Option<Vec<Symbol>> {
let metas = attr.meta_item_list()?;
let mut candidates = Vec::new();
for meta in metas {
let MetaItemInner::Lit(meta_lit) = meta else {
return None;
};
candidates.push(meta_lit.symbol);
}
Some(candidates)
}

View file

@ -0,0 +1,149 @@
//! Parsing and validation of builtin attributes
use rustc_ast::attr::AttributeExt;
use rustc_ast::{MetaItem, MetaItemInner};
use rustc_ast_pretty::pprust;
use rustc_attr_data_structures::{DeprecatedSince, Deprecation};
use rustc_feature::Features;
use rustc_session::Session;
use rustc_span::Span;
use rustc_span::symbol::{Symbol, sym};
use super::util::UnsupportedLiteralReason;
use crate::{parse_version, session_diagnostics};
/// Finds the deprecation attribute. `None` if none exists.
pub fn find_deprecation(
sess: &Session,
features: &Features,
attrs: &[impl AttributeExt],
) -> Option<(Deprecation, Span)> {
let mut depr: Option<(Deprecation, Span)> = None;
let is_rustc = features.staged_api();
'outer: for attr in attrs {
if !attr.has_name(sym::deprecated) {
continue;
}
let mut since = None;
let mut note = None;
let mut suggestion = None;
if attr.is_doc_comment() {
continue;
} else if attr.is_word() {
} else if let Some(value) = attr.value_str() {
note = Some(value)
} else if let Some(list) = attr.meta_item_list() {
let get = |meta: &MetaItem, item: &mut Option<Symbol>| {
if item.is_some() {
sess.dcx().emit_err(session_diagnostics::MultipleItem {
span: meta.span,
item: pprust::path_to_string(&meta.path),
});
return false;
}
if let Some(v) = meta.value_str() {
*item = Some(v);
true
} else {
if let Some(lit) = meta.name_value_literal() {
sess.dcx().emit_err(session_diagnostics::UnsupportedLiteral {
span: lit.span,
reason: UnsupportedLiteralReason::DeprecatedString,
is_bytestr: lit.kind.is_bytestr(),
start_point_span: sess.source_map().start_point(lit.span),
});
} else {
sess.dcx()
.emit_err(session_diagnostics::IncorrectMetaItem { span: meta.span });
}
false
}
};
for meta in &list {
match meta {
MetaItemInner::MetaItem(mi) => match mi.name_or_empty() {
sym::since => {
if !get(mi, &mut since) {
continue 'outer;
}
}
sym::note => {
if !get(mi, &mut note) {
continue 'outer;
}
}
sym::suggestion => {
if !features.deprecated_suggestion() {
sess.dcx().emit_err(
session_diagnostics::DeprecatedItemSuggestion {
span: mi.span,
is_nightly: sess.is_nightly_build(),
details: (),
},
);
}
if !get(mi, &mut suggestion) {
continue 'outer;
}
}
_ => {
sess.dcx().emit_err(session_diagnostics::UnknownMetaItem {
span: meta.span(),
item: pprust::path_to_string(&mi.path),
expected: if features.deprecated_suggestion() {
&["since", "note", "suggestion"]
} else {
&["since", "note"]
},
});
continue 'outer;
}
},
MetaItemInner::Lit(lit) => {
sess.dcx().emit_err(session_diagnostics::UnsupportedLiteral {
span: lit.span,
reason: UnsupportedLiteralReason::DeprecatedKvPair,
is_bytestr: false,
start_point_span: sess.source_map().start_point(lit.span),
});
continue 'outer;
}
}
}
} else {
continue;
}
let since = if let Some(since) = since {
if since.as_str() == "TBD" {
DeprecatedSince::Future
} else if !is_rustc {
DeprecatedSince::NonStandard(since)
} else if let Some(version) = parse_version(since) {
DeprecatedSince::RustcVersion(version)
} else {
sess.dcx().emit_err(session_diagnostics::InvalidSince { span: attr.span() });
DeprecatedSince::Err
}
} else if is_rustc {
sess.dcx().emit_err(session_diagnostics::MissingSince { span: attr.span() });
DeprecatedSince::Err
} else {
DeprecatedSince::Unspecified
};
if is_rustc && note.is_none() {
sess.dcx().emit_err(session_diagnostics::MissingNote { span: attr.span() });
continue;
}
depr = Some((Deprecation { since, note, suggestion }, attr.span()));
}
depr
}

View file

@ -0,0 +1,17 @@
mod allow_unstable;
mod cfg;
mod confusables;
mod deprecation;
mod repr;
mod stability;
mod transparency;
pub mod util;
pub use allow_unstable::*;
pub use cfg::*;
pub use confusables::*;
pub use deprecation::*;
pub use repr::*;
pub use stability::*;
pub use transparency::*;

View file

@ -0,0 +1,215 @@
//! Parsing and validation of builtin attributes
use rustc_abi::Align;
use rustc_ast::attr::AttributeExt;
use rustc_ast::{self as ast, MetaItemKind};
use rustc_attr_data_structures::IntType;
use rustc_attr_data_structures::ReprAttr::*;
use rustc_session::Session;
use rustc_span::symbol::{Symbol, sym};
use crate::ReprAttr;
use crate::session_diagnostics::{self, IncorrectReprFormatGenericCause};
/// Parse #[repr(...)] forms.
///
/// Valid repr contents: any of the primitive integral type names (see
/// `int_type_of_word`, below) to specify enum discriminant type; `C`, to use
/// the same discriminant size that the corresponding C enum would or C
/// structure layout, `packed` to remove padding, and `transparent` to delegate representation
/// concerns to the only non-ZST field.
pub fn find_repr_attrs(sess: &Session, attr: &impl AttributeExt) -> Vec<ReprAttr> {
if attr.has_name(sym::repr) { parse_repr_attr(sess, attr) } else { Vec::new() }
}
pub fn parse_repr_attr(sess: &Session, attr: &impl AttributeExt) -> Vec<ReprAttr> {
assert!(attr.has_name(sym::repr), "expected `#[repr(..)]`, found: {attr:?}");
let mut acc = Vec::new();
let dcx = sess.dcx();
if let Some(items) = attr.meta_item_list() {
for item in items {
let mut recognised = false;
if item.is_word() {
let hint = match item.name_or_empty() {
sym::Rust => Some(ReprRust),
sym::C => Some(ReprC),
sym::packed => Some(ReprPacked(Align::ONE)),
sym::simd => Some(ReprSimd),
sym::transparent => Some(ReprTransparent),
sym::align => {
sess.dcx().emit_err(session_diagnostics::InvalidReprAlignNeedArg {
span: item.span(),
});
recognised = true;
None
}
name => int_type_of_word(name).map(ReprInt),
};
if let Some(h) = hint {
recognised = true;
acc.push(h);
}
} else if let Some((name, value)) = item.singleton_lit_list() {
let mut literal_error = None;
let mut err_span = item.span();
if name == sym::align {
recognised = true;
match parse_alignment(&value.kind) {
Ok(literal) => acc.push(ReprAlign(literal)),
Err(message) => {
err_span = value.span;
literal_error = Some(message)
}
};
} else if name == sym::packed {
recognised = true;
match parse_alignment(&value.kind) {
Ok(literal) => acc.push(ReprPacked(literal)),
Err(message) => {
err_span = value.span;
literal_error = Some(message)
}
};
} else if matches!(name, sym::Rust | sym::C | sym::simd | sym::transparent)
|| int_type_of_word(name).is_some()
{
recognised = true;
sess.dcx().emit_err(session_diagnostics::InvalidReprHintNoParen {
span: item.span(),
name: name.to_ident_string(),
});
}
if let Some(literal_error) = literal_error {
sess.dcx().emit_err(session_diagnostics::InvalidReprGeneric {
span: err_span,
repr_arg: name.to_ident_string(),
error_part: literal_error,
});
}
} else if let Some(meta_item) = item.meta_item() {
match &meta_item.kind {
MetaItemKind::NameValue(value) => {
if meta_item.has_name(sym::align) || meta_item.has_name(sym::packed) {
let name = meta_item.name_or_empty().to_ident_string();
recognised = true;
sess.dcx().emit_err(session_diagnostics::IncorrectReprFormatGeneric {
span: item.span(),
repr_arg: &name,
cause: IncorrectReprFormatGenericCause::from_lit_kind(
item.span(),
&value.kind,
&name,
),
});
} else if matches!(
meta_item.name_or_empty(),
sym::Rust | sym::C | sym::simd | sym::transparent
) || int_type_of_word(meta_item.name_or_empty()).is_some()
{
recognised = true;
sess.dcx().emit_err(session_diagnostics::InvalidReprHintNoValue {
span: meta_item.span,
name: meta_item.name_or_empty().to_ident_string(),
});
}
}
MetaItemKind::List(nested_items) => {
if meta_item.has_name(sym::align) {
recognised = true;
if let [nested_item] = nested_items.as_slice() {
sess.dcx().emit_err(
session_diagnostics::IncorrectReprFormatExpectInteger {
span: nested_item.span(),
},
);
} else {
sess.dcx().emit_err(
session_diagnostics::IncorrectReprFormatAlignOneArg {
span: meta_item.span,
},
);
}
} else if meta_item.has_name(sym::packed) {
recognised = true;
if let [nested_item] = nested_items.as_slice() {
sess.dcx().emit_err(
session_diagnostics::IncorrectReprFormatPackedExpectInteger {
span: nested_item.span(),
},
);
} else {
sess.dcx().emit_err(
session_diagnostics::IncorrectReprFormatPackedOneOrZeroArg {
span: meta_item.span,
},
);
}
} else if matches!(
meta_item.name_or_empty(),
sym::Rust | sym::C | sym::simd | sym::transparent
) || int_type_of_word(meta_item.name_or_empty()).is_some()
{
recognised = true;
sess.dcx().emit_err(session_diagnostics::InvalidReprHintNoParen {
span: meta_item.span,
name: meta_item.name_or_empty().to_ident_string(),
});
}
}
_ => (),
}
}
if !recognised {
// Not a word we recognize. This will be caught and reported by
// the `check_mod_attrs` pass, but this pass doesn't always run
// (e.g. if we only pretty-print the source), so we have to gate
// the `span_delayed_bug` call as follows:
if sess.opts.pretty.map_or(true, |pp| pp.needs_analysis()) {
dcx.span_delayed_bug(item.span(), "unrecognized representation hint");
}
}
}
}
acc
}
fn int_type_of_word(s: Symbol) -> Option<IntType> {
use rustc_attr_data_structures::IntType::*;
match s {
sym::i8 => Some(SignedInt(ast::IntTy::I8)),
sym::u8 => Some(UnsignedInt(ast::UintTy::U8)),
sym::i16 => Some(SignedInt(ast::IntTy::I16)),
sym::u16 => Some(UnsignedInt(ast::UintTy::U16)),
sym::i32 => Some(SignedInt(ast::IntTy::I32)),
sym::u32 => Some(UnsignedInt(ast::UintTy::U32)),
sym::i64 => Some(SignedInt(ast::IntTy::I64)),
sym::u64 => Some(UnsignedInt(ast::UintTy::U64)),
sym::i128 => Some(SignedInt(ast::IntTy::I128)),
sym::u128 => Some(UnsignedInt(ast::UintTy::U128)),
sym::isize => Some(SignedInt(ast::IntTy::Isize)),
sym::usize => Some(UnsignedInt(ast::UintTy::Usize)),
_ => None,
}
}
pub fn parse_alignment(node: &ast::LitKind) -> Result<Align, &'static str> {
if let ast::LitKind::Int(literal, ast::LitIntType::Unsuffixed) = node {
// `Align::from_bytes` accepts 0 as an input, check is_power_of_two() first
if literal.get().is_power_of_two() {
// Only possible error is larger than 2^29
literal
.get()
.try_into()
.ok()
.and_then(|v| Align::from_bytes(v).ok())
.ok_or("larger than 2^29")
} else {
Err("not a power of two")
}
} else {
Err("not an unsuffixed integer")
}
}

View file

@ -0,0 +1,385 @@
//! Parsing and validation of builtin attributes
use std::num::NonZero;
use rustc_ast::MetaItem;
use rustc_ast::attr::AttributeExt;
use rustc_ast_pretty::pprust;
use rustc_attr_data_structures::{
ConstStability, DefaultBodyStability, Stability, StabilityLevel, StableSince, UnstableReason,
VERSION_PLACEHOLDER,
};
use rustc_errors::ErrorGuaranteed;
use rustc_session::Session;
use rustc_span::Span;
use rustc_span::symbol::{Symbol, sym};
use crate::attributes::util::UnsupportedLiteralReason;
use crate::{parse_version, session_diagnostics};
/// Collects stability info from `stable`/`unstable`/`rustc_allowed_through_unstable_modules`
/// attributes in `attrs`. Returns `None` if no stability attributes are found.
pub fn find_stability(
sess: &Session,
attrs: &[impl AttributeExt],
item_sp: Span,
) -> Option<(Stability, Span)> {
let mut stab: Option<(Stability, Span)> = None;
let mut allowed_through_unstable_modules = false;
for attr in attrs {
match attr.name_or_empty() {
sym::rustc_allowed_through_unstable_modules => allowed_through_unstable_modules = true,
sym::unstable => {
if stab.is_some() {
sess.dcx().emit_err(session_diagnostics::MultipleStabilityLevels {
span: attr.span(),
});
break;
}
if let Some((feature, level)) = parse_unstability(sess, attr) {
stab = Some((Stability { level, feature }, attr.span()));
}
}
sym::stable => {
if stab.is_some() {
sess.dcx().emit_err(session_diagnostics::MultipleStabilityLevels {
span: attr.span(),
});
break;
}
if let Some((feature, level)) = parse_stability(sess, attr) {
stab = Some((Stability { level, feature }, attr.span()));
}
}
_ => {}
}
}
if allowed_through_unstable_modules {
match &mut stab {
Some((
Stability {
level: StabilityLevel::Stable { allowed_through_unstable_modules, .. },
..
},
_,
)) => *allowed_through_unstable_modules = true,
_ => {
sess.dcx()
.emit_err(session_diagnostics::RustcAllowedUnstablePairing { span: item_sp });
}
}
}
stab
}
/// Collects stability info from `rustc_const_stable`/`rustc_const_unstable`/`rustc_promotable`
/// attributes in `attrs`. Returns `None` if no stability attributes are found.
pub fn find_const_stability(
sess: &Session,
attrs: &[impl AttributeExt],
item_sp: Span,
) -> Option<(ConstStability, Span)> {
let mut const_stab: Option<(ConstStability, Span)> = None;
let mut promotable = false;
let mut const_stable_indirect = false;
for attr in attrs {
match attr.name_or_empty() {
sym::rustc_promotable => promotable = true,
sym::rustc_const_stable_indirect => const_stable_indirect = true,
sym::rustc_const_unstable => {
if const_stab.is_some() {
sess.dcx().emit_err(session_diagnostics::MultipleStabilityLevels {
span: attr.span(),
});
break;
}
if let Some((feature, level)) = parse_unstability(sess, attr) {
const_stab = Some((
ConstStability {
level,
feature,
const_stable_indirect: false,
promotable: false,
},
attr.span(),
));
}
}
sym::rustc_const_stable => {
if const_stab.is_some() {
sess.dcx().emit_err(session_diagnostics::MultipleStabilityLevels {
span: attr.span(),
});
break;
}
if let Some((feature, level)) = parse_stability(sess, attr) {
const_stab = Some((
ConstStability {
level,
feature,
const_stable_indirect: false,
promotable: false,
},
attr.span(),
));
}
}
_ => {}
}
}
// Merge promotable and const_stable_indirect into stability info
if promotable {
match &mut const_stab {
Some((stab, _)) => stab.promotable = promotable,
_ => {
_ = sess
.dcx()
.emit_err(session_diagnostics::RustcPromotablePairing { span: item_sp })
}
}
}
if const_stable_indirect {
match &mut const_stab {
Some((stab, _)) => {
if stab.is_const_unstable() {
stab.const_stable_indirect = true;
} else {
_ = sess.dcx().emit_err(session_diagnostics::RustcConstStableIndirectPairing {
span: item_sp,
})
}
}
_ => {
// This function has no const stability attribute, but has `const_stable_indirect`.
// We ignore that; unmarked functions are subject to recursive const stability
// checks by default so we do carry out the user's intent.
}
}
}
const_stab
}
/// Calculates the const stability for a const function in a `-Zforce-unstable-if-unmarked` crate
/// without the `staged_api` feature.
pub fn unmarked_crate_const_stab(
_sess: &Session,
attrs: &[impl AttributeExt],
regular_stab: Stability,
) -> ConstStability {
assert!(regular_stab.level.is_unstable());
// The only attribute that matters here is `rustc_const_stable_indirect`.
// We enforce recursive const stability rules for those functions.
let const_stable_indirect =
attrs.iter().any(|a| a.name_or_empty() == sym::rustc_const_stable_indirect);
ConstStability {
feature: regular_stab.feature,
const_stable_indirect,
promotable: false,
level: regular_stab.level,
}
}
/// Collects stability info from `rustc_default_body_unstable` attributes in `attrs`.
/// Returns `None` if no stability attributes are found.
pub fn find_body_stability(
sess: &Session,
attrs: &[impl AttributeExt],
) -> Option<(DefaultBodyStability, Span)> {
let mut body_stab: Option<(DefaultBodyStability, Span)> = None;
for attr in attrs {
if attr.has_name(sym::rustc_default_body_unstable) {
if body_stab.is_some() {
sess.dcx()
.emit_err(session_diagnostics::MultipleStabilityLevels { span: attr.span() });
break;
}
if let Some((feature, level)) = parse_unstability(sess, attr) {
body_stab = Some((DefaultBodyStability { level, feature }, attr.span()));
}
}
}
body_stab
}
fn insert_or_error(sess: &Session, meta: &MetaItem, item: &mut Option<Symbol>) -> Option<()> {
if item.is_some() {
sess.dcx().emit_err(session_diagnostics::MultipleItem {
span: meta.span,
item: pprust::path_to_string(&meta.path),
});
None
} else if let Some(v) = meta.value_str() {
*item = Some(v);
Some(())
} else {
sess.dcx().emit_err(session_diagnostics::IncorrectMetaItem { span: meta.span });
None
}
}
/// Read the content of a `stable`/`rustc_const_stable` attribute, and return the feature name and
/// its stability information.
fn parse_stability(sess: &Session, attr: &impl AttributeExt) -> Option<(Symbol, StabilityLevel)> {
let metas = attr.meta_item_list()?;
let mut feature = None;
let mut since = None;
for meta in metas {
let Some(mi) = meta.meta_item() else {
sess.dcx().emit_err(session_diagnostics::UnsupportedLiteral {
span: meta.span(),
reason: UnsupportedLiteralReason::Generic,
is_bytestr: false,
start_point_span: sess.source_map().start_point(meta.span()),
});
return None;
};
match mi.name_or_empty() {
sym::feature => insert_or_error(sess, mi, &mut feature)?,
sym::since => insert_or_error(sess, mi, &mut since)?,
_ => {
sess.dcx().emit_err(session_diagnostics::UnknownMetaItem {
span: meta.span(),
item: pprust::path_to_string(&mi.path),
expected: &["feature", "since"],
});
return None;
}
}
}
let feature = match feature {
Some(feature) if rustc_lexer::is_ident(feature.as_str()) => Ok(feature),
Some(_bad_feature) => {
Err(sess.dcx().emit_err(session_diagnostics::NonIdentFeature { span: attr.span() }))
}
None => Err(sess.dcx().emit_err(session_diagnostics::MissingFeature { span: attr.span() })),
};
let since = if let Some(since) = since {
if since.as_str() == VERSION_PLACEHOLDER {
StableSince::Current
} else if let Some(version) = parse_version(since) {
StableSince::Version(version)
} else {
sess.dcx().emit_err(session_diagnostics::InvalidSince { span: attr.span() });
StableSince::Err
}
} else {
sess.dcx().emit_err(session_diagnostics::MissingSince { span: attr.span() });
StableSince::Err
};
match feature {
Ok(feature) => {
let level = StabilityLevel::Stable { since, allowed_through_unstable_modules: false };
Some((feature, level))
}
Err(ErrorGuaranteed { .. }) => None,
}
}
/// Read the content of a `unstable`/`rustc_const_unstable`/`rustc_default_body_unstable`
/// attribute, and return the feature name and its stability information.
fn parse_unstability(sess: &Session, attr: &impl AttributeExt) -> Option<(Symbol, StabilityLevel)> {
let metas = attr.meta_item_list()?;
let mut feature = None;
let mut reason = None;
let mut issue = None;
let mut issue_num = None;
let mut is_soft = false;
let mut implied_by = None;
for meta in metas {
let Some(mi) = meta.meta_item() else {
sess.dcx().emit_err(session_diagnostics::UnsupportedLiteral {
span: meta.span(),
reason: UnsupportedLiteralReason::Generic,
is_bytestr: false,
start_point_span: sess.source_map().start_point(meta.span()),
});
return None;
};
match mi.name_or_empty() {
sym::feature => insert_or_error(sess, mi, &mut feature)?,
sym::reason => insert_or_error(sess, mi, &mut reason)?,
sym::issue => {
insert_or_error(sess, mi, &mut issue)?;
// These unwraps are safe because `insert_or_error` ensures the meta item
// is a name/value pair string literal.
issue_num = match issue.unwrap().as_str() {
"none" => None,
issue => match issue.parse::<NonZero<u32>>() {
Ok(num) => Some(num),
Err(err) => {
sess.dcx().emit_err(
session_diagnostics::InvalidIssueString {
span: mi.span,
cause: session_diagnostics::InvalidIssueStringCause::from_int_error_kind(
mi.name_value_literal_span().unwrap(),
err.kind(),
),
},
);
return None;
}
},
};
}
sym::soft => {
if !mi.is_word() {
sess.dcx().emit_err(session_diagnostics::SoftNoArgs { span: mi.span });
}
is_soft = true;
}
sym::implied_by => insert_or_error(sess, mi, &mut implied_by)?,
_ => {
sess.dcx().emit_err(session_diagnostics::UnknownMetaItem {
span: meta.span(),
item: pprust::path_to_string(&mi.path),
expected: &["feature", "reason", "issue", "soft", "implied_by"],
});
return None;
}
}
}
let feature = match feature {
Some(feature) if rustc_lexer::is_ident(feature.as_str()) => Ok(feature),
Some(_bad_feature) => {
Err(sess.dcx().emit_err(session_diagnostics::NonIdentFeature { span: attr.span() }))
}
None => Err(sess.dcx().emit_err(session_diagnostics::MissingFeature { span: attr.span() })),
};
let issue = issue.ok_or_else(|| {
sess.dcx().emit_err(session_diagnostics::MissingIssue { span: attr.span() })
});
match (feature, issue) {
(Ok(feature), Ok(_)) => {
let level = StabilityLevel::Unstable {
reason: UnstableReason::from_opt_reason(reason),
issue: issue_num,
is_soft,
implied_by,
};
Some((feature, level))
}
(Err(ErrorGuaranteed { .. }), _) | (_, Err(ErrorGuaranteed { .. })) => None,
}
}

View file

@ -0,0 +1,36 @@
use rustc_ast::attr::AttributeExt;
use rustc_attr_data_structures::TransparencyError;
use rustc_span::hygiene::Transparency;
use rustc_span::sym;
pub fn find_transparency(
attrs: &[impl AttributeExt],
macro_rules: bool,
) -> (Transparency, Option<TransparencyError>) {
let mut transparency = None;
let mut error = None;
for attr in attrs {
if attr.has_name(sym::rustc_macro_transparency) {
if let Some((_, old_span)) = transparency {
error = Some(TransparencyError::MultipleTransparencyAttrs(old_span, attr.span()));
break;
} else if let Some(value) = attr.value_str() {
transparency = Some((
match value {
sym::transparent => Transparency::Transparent,
sym::semitransparent => Transparency::SemiTransparent,
sym::opaque => Transparency::Opaque,
_ => {
error =
Some(TransparencyError::UnknownTransparency(value, attr.span()));
continue;
}
},
attr.span(),
));
}
}
}
let fallback = if macro_rules { Transparency::SemiTransparent } else { Transparency::Opaque };
(transparency.map_or(fallback, |t| t.0), error)
}

View file

@ -0,0 +1,36 @@
use rustc_ast::attr::{AttributeExt, first_attr_value_str_by_name};
use rustc_attr_data_structures::RustcVersion;
use rustc_feature::is_builtin_attr_name;
use rustc_span::symbol::{Symbol, sym};
pub(crate) enum UnsupportedLiteralReason {
Generic,
CfgString,
CfgBoolean,
DeprecatedString,
DeprecatedKvPair,
}
pub fn is_builtin_attr(attr: &impl AttributeExt) -> bool {
attr.is_doc_comment() || attr.ident().is_some_and(|ident| is_builtin_attr_name(ident.name))
}
pub fn find_crate_name(attrs: &[impl AttributeExt]) -> Option<Symbol> {
first_attr_value_str_by_name(attrs, sym::crate_name)
}
/// Parse a rustc version number written inside string literal in an attribute,
/// like appears in `since = "1.0.0"`. Suffixes like "-dev" and "-nightly" are
/// not accepted in this position, unlike when parsing CFG_RELEASE.
pub fn parse_version(s: Symbol) -> Option<RustcVersion> {
let mut components = s.as_str().split('-');
let d = components.next()?;
if components.next().is_some() {
return None;
}
let mut digits = d.splitn(3, '.');
let major = digits.next()?.parse().ok()?;
let minor = digits.next()?.parse().ok()?;
let patch = digits.next().unwrap_or("0").parse().ok()?;
Some(RustcVersion { major, minor, patch })
}

View file

@ -12,14 +12,11 @@
#![warn(unreachable_pub)]
// tidy-alphabetical-end
mod builtin;
mod attributes;
mod session_diagnostics;
pub use IntType::*;
pub use ReprAttr::*;
pub use StabilityLevel::*;
pub use builtin::*;
pub use rustc_ast::attr::*;
pub(crate) use rustc_session::HashStableContext;
pub use attributes::*;
pub use rustc_attr_data_structures::*;
pub use util::{find_crate_name, is_builtin_attr, parse_version};
rustc_fluent_macro::fluent_messages! { "../messages.ftl" }

View file

@ -6,17 +6,18 @@ use rustc_errors::{Applicability, Diag, DiagCtxtHandle, Diagnostic, EmissionGuar
use rustc_macros::{Diagnostic, Subdiagnostic};
use rustc_span::{Span, Symbol};
use crate::{UnsupportedLiteralReason, fluent_generated as fluent};
use crate::attributes::util::UnsupportedLiteralReason;
use crate::fluent_generated as fluent;
#[derive(Diagnostic)]
#[diag(attr_expected_one_cfg_pattern, code = E0536)]
#[diag(attr_parsing_expected_one_cfg_pattern, code = E0536)]
pub(crate) struct ExpectedOneCfgPattern {
#[primary_span]
pub span: Span,
}
#[derive(Diagnostic)]
#[diag(attr_invalid_predicate, code = E0537)]
#[diag(attr_parsing_invalid_predicate, code = E0537)]
pub(crate) struct InvalidPredicate {
#[primary_span]
pub span: Span,
@ -25,7 +26,7 @@ pub(crate) struct InvalidPredicate {
}
#[derive(Diagnostic)]
#[diag(attr_multiple_item, code = E0538)]
#[diag(attr_parsing_multiple_item, code = E0538)]
pub(crate) struct MultipleItem {
#[primary_span]
pub span: Span,
@ -34,7 +35,7 @@ pub(crate) struct MultipleItem {
}
#[derive(Diagnostic)]
#[diag(attr_incorrect_meta_item, code = E0539)]
#[diag(attr_parsing_incorrect_meta_item, code = E0539)]
pub(crate) struct IncorrectMetaItem {
#[primary_span]
pub span: Span,
@ -51,38 +52,38 @@ pub(crate) struct UnknownMetaItem<'a> {
impl<'a, G: EmissionGuarantee> Diagnostic<'a, G> for UnknownMetaItem<'_> {
fn into_diag(self, dcx: DiagCtxtHandle<'a>, level: Level) -> Diag<'a, G> {
let expected = self.expected.iter().map(|name| format!("`{name}`")).collect::<Vec<_>>();
Diag::new(dcx, level, fluent::attr_unknown_meta_item)
Diag::new(dcx, level, fluent::attr_parsing_unknown_meta_item)
.with_span(self.span)
.with_code(E0541)
.with_arg("item", self.item)
.with_arg("expected", expected.join(", "))
.with_span_label(self.span, fluent::attr_label)
.with_span_label(self.span, fluent::attr_parsing_label)
}
}
#[derive(Diagnostic)]
#[diag(attr_missing_since, code = E0542)]
#[diag(attr_parsing_missing_since, code = E0542)]
pub(crate) struct MissingSince {
#[primary_span]
pub span: Span,
}
#[derive(Diagnostic)]
#[diag(attr_missing_note, code = E0543)]
#[diag(attr_parsing_missing_note, code = E0543)]
pub(crate) struct MissingNote {
#[primary_span]
pub span: Span,
}
#[derive(Diagnostic)]
#[diag(attr_multiple_stability_levels, code = E0544)]
#[diag(attr_parsing_multiple_stability_levels, code = E0544)]
pub(crate) struct MultipleStabilityLevels {
#[primary_span]
pub span: Span,
}
#[derive(Diagnostic)]
#[diag(attr_invalid_issue_string, code = E0545)]
#[diag(attr_parsing_invalid_issue_string, code = E0545)]
pub(crate) struct InvalidIssueString {
#[primary_span]
pub span: Span,
@ -95,31 +96,31 @@ pub(crate) struct InvalidIssueString {
// translatable.
#[derive(Subdiagnostic)]
pub(crate) enum InvalidIssueStringCause {
#[label(attr_must_not_be_zero)]
#[label(attr_parsing_must_not_be_zero)]
MustNotBeZero {
#[primary_span]
span: Span,
},
#[label(attr_empty)]
#[label(attr_parsing_empty)]
Empty {
#[primary_span]
span: Span,
},
#[label(attr_invalid_digit)]
#[label(attr_parsing_invalid_digit)]
InvalidDigit {
#[primary_span]
span: Span,
},
#[label(attr_pos_overflow)]
#[label(attr_parsing_pos_overflow)]
PosOverflow {
#[primary_span]
span: Span,
},
#[label(attr_neg_overflow)]
#[label(attr_parsing_neg_overflow)]
NegOverflow {
#[primary_span]
span: Span,
@ -140,21 +141,21 @@ impl InvalidIssueStringCause {
}
#[derive(Diagnostic)]
#[diag(attr_missing_feature, code = E0546)]
#[diag(attr_parsing_missing_feature, code = E0546)]
pub(crate) struct MissingFeature {
#[primary_span]
pub span: Span,
}
#[derive(Diagnostic)]
#[diag(attr_non_ident_feature, code = E0546)]
#[diag(attr_parsing_non_ident_feature, code = E0546)]
pub(crate) struct NonIdentFeature {
#[primary_span]
pub span: Span,
}
#[derive(Diagnostic)]
#[diag(attr_missing_issue, code = E0547)]
#[diag(attr_parsing_missing_issue, code = E0547)]
pub(crate) struct MissingIssue {
#[primary_span]
pub span: Span,
@ -163,20 +164,20 @@ pub(crate) struct MissingIssue {
// FIXME: Why is this the same error code as `InvalidReprHintNoParen` and `InvalidReprHintNoValue`?
// It is more similar to `IncorrectReprFormatGeneric`.
#[derive(Diagnostic)]
#[diag(attr_incorrect_repr_format_packed_one_or_zero_arg, code = E0552)]
#[diag(attr_parsing_incorrect_repr_format_packed_one_or_zero_arg, code = E0552)]
pub(crate) struct IncorrectReprFormatPackedOneOrZeroArg {
#[primary_span]
pub span: Span,
}
#[derive(Diagnostic)]
#[diag(attr_incorrect_repr_format_packed_expect_integer, code = E0552)]
#[diag(attr_parsing_incorrect_repr_format_packed_expect_integer, code = E0552)]
pub(crate) struct IncorrectReprFormatPackedExpectInteger {
#[primary_span]
pub span: Span,
}
#[derive(Diagnostic)]
#[diag(attr_invalid_repr_hint_no_paren, code = E0552)]
#[diag(attr_parsing_invalid_repr_hint_no_paren, code = E0552)]
pub(crate) struct InvalidReprHintNoParen {
#[primary_span]
pub span: Span,
@ -185,7 +186,7 @@ pub(crate) struct InvalidReprHintNoParen {
}
#[derive(Diagnostic)]
#[diag(attr_invalid_repr_hint_no_value, code = E0552)]
#[diag(attr_parsing_invalid_repr_hint_no_value, code = E0552)]
pub(crate) struct InvalidReprHintNoValue {
#[primary_span]
pub span: Span,
@ -204,14 +205,18 @@ pub(crate) struct UnsupportedLiteral {
impl<'a, G: EmissionGuarantee> Diagnostic<'a, G> for UnsupportedLiteral {
fn into_diag(self, dcx: DiagCtxtHandle<'a>, level: Level) -> Diag<'a, G> {
let mut diag = Diag::new(dcx, level, match self.reason {
UnsupportedLiteralReason::Generic => fluent::attr_unsupported_literal_generic,
UnsupportedLiteralReason::CfgString => fluent::attr_unsupported_literal_cfg_string,
UnsupportedLiteralReason::CfgBoolean => fluent::attr_unsupported_literal_cfg_boolean,
UnsupportedLiteralReason::Generic => fluent::attr_parsing_unsupported_literal_generic,
UnsupportedLiteralReason::CfgString => {
fluent::attr_parsing_unsupported_literal_cfg_string
}
UnsupportedLiteralReason::CfgBoolean => {
fluent::attr_parsing_unsupported_literal_cfg_boolean
}
UnsupportedLiteralReason::DeprecatedString => {
fluent::attr_unsupported_literal_deprecated_string
fluent::attr_parsing_unsupported_literal_deprecated_string
}
UnsupportedLiteralReason::DeprecatedKvPair => {
fluent::attr_unsupported_literal_deprecated_kv_pair
fluent::attr_parsing_unsupported_literal_deprecated_kv_pair
}
});
diag.span(self.span);
@ -219,7 +224,7 @@ impl<'a, G: EmissionGuarantee> Diagnostic<'a, G> for UnsupportedLiteral {
if self.is_bytestr {
diag.span_suggestion(
self.start_point_span,
fluent::attr_unsupported_literal_suggestion,
fluent::attr_parsing_unsupported_literal_suggestion,
"",
Applicability::MaybeIncorrect,
);
@ -229,7 +234,7 @@ impl<'a, G: EmissionGuarantee> Diagnostic<'a, G> for UnsupportedLiteral {
}
#[derive(Diagnostic)]
#[diag(attr_invalid_repr_align_need_arg, code = E0589)]
#[diag(attr_parsing_invalid_repr_align_need_arg, code = E0589)]
pub(crate) struct InvalidReprAlignNeedArg {
#[primary_span]
#[suggestion(code = "align(...)", applicability = "has-placeholders")]
@ -237,7 +242,7 @@ pub(crate) struct InvalidReprAlignNeedArg {
}
#[derive(Diagnostic)]
#[diag(attr_invalid_repr_generic, code = E0589)]
#[diag(attr_parsing_invalid_repr_generic, code = E0589)]
pub(crate) struct InvalidReprGeneric<'a> {
#[primary_span]
pub span: Span,
@ -247,21 +252,21 @@ pub(crate) struct InvalidReprGeneric<'a> {
}
#[derive(Diagnostic)]
#[diag(attr_incorrect_repr_format_align_one_arg, code = E0693)]
#[diag(attr_parsing_incorrect_repr_format_align_one_arg, code = E0693)]
pub(crate) struct IncorrectReprFormatAlignOneArg {
#[primary_span]
pub span: Span,
}
#[derive(Diagnostic)]
#[diag(attr_incorrect_repr_format_expect_literal_integer, code = E0693)]
#[diag(attr_parsing_incorrect_repr_format_expect_literal_integer, code = E0693)]
pub(crate) struct IncorrectReprFormatExpectInteger {
#[primary_span]
pub span: Span,
}
#[derive(Diagnostic)]
#[diag(attr_incorrect_repr_format_generic, code = E0693)]
#[diag(attr_parsing_incorrect_repr_format_generic, code = E0693)]
pub(crate) struct IncorrectReprFormatGeneric<'a> {
#[primary_span]
pub span: Span,
@ -274,7 +279,11 @@ pub(crate) struct IncorrectReprFormatGeneric<'a> {
#[derive(Subdiagnostic)]
pub(crate) enum IncorrectReprFormatGenericCause<'a> {
#[suggestion(attr_suggestion, code = "{name}({int})", applicability = "machine-applicable")]
#[suggestion(
attr_parsing_suggestion,
code = "{name}({int})",
applicability = "machine-applicable"
)]
Int {
#[primary_span]
span: Span,
@ -286,7 +295,11 @@ pub(crate) enum IncorrectReprFormatGenericCause<'a> {
int: u128,
},
#[suggestion(attr_suggestion, code = "{name}({symbol})", applicability = "machine-applicable")]
#[suggestion(
attr_parsing_suggestion,
code = "{name}({symbol})",
applicability = "machine-applicable"
)]
Symbol {
#[primary_span]
span: Span,
@ -312,35 +325,35 @@ impl<'a> IncorrectReprFormatGenericCause<'a> {
}
#[derive(Diagnostic)]
#[diag(attr_rustc_promotable_pairing, code = E0717)]
#[diag(attr_parsing_rustc_promotable_pairing, code = E0717)]
pub(crate) struct RustcPromotablePairing {
#[primary_span]
pub span: Span,
}
#[derive(Diagnostic)]
#[diag(attr_rustc_const_stable_indirect_pairing)]
#[diag(attr_parsing_rustc_const_stable_indirect_pairing)]
pub(crate) struct RustcConstStableIndirectPairing {
#[primary_span]
pub span: Span,
}
#[derive(Diagnostic)]
#[diag(attr_rustc_allowed_unstable_pairing, code = E0789)]
#[diag(attr_parsing_rustc_allowed_unstable_pairing, code = E0789)]
pub(crate) struct RustcAllowedUnstablePairing {
#[primary_span]
pub span: Span,
}
#[derive(Diagnostic)]
#[diag(attr_cfg_predicate_identifier)]
#[diag(attr_parsing_cfg_predicate_identifier)]
pub(crate) struct CfgPredicateIdentifier {
#[primary_span]
pub span: Span,
}
#[derive(Diagnostic)]
#[diag(attr_deprecated_item_suggestion)]
#[diag(attr_parsing_deprecated_item_suggestion)]
pub(crate) struct DeprecatedItemSuggestion {
#[primary_span]
pub span: Span,
@ -353,21 +366,21 @@ pub(crate) struct DeprecatedItemSuggestion {
}
#[derive(Diagnostic)]
#[diag(attr_expected_single_version_literal)]
#[diag(attr_parsing_expected_single_version_literal)]
pub(crate) struct ExpectedSingleVersionLiteral {
#[primary_span]
pub span: Span,
}
#[derive(Diagnostic)]
#[diag(attr_expected_version_literal)]
#[diag(attr_parsing_expected_version_literal)]
pub(crate) struct ExpectedVersionLiteral {
#[primary_span]
pub span: Span,
}
#[derive(Diagnostic)]
#[diag(attr_expects_feature_list)]
#[diag(attr_parsing_expects_feature_list)]
pub(crate) struct ExpectsFeatureList {
#[primary_span]
pub span: Span,
@ -376,7 +389,7 @@ pub(crate) struct ExpectsFeatureList {
}
#[derive(Diagnostic)]
#[diag(attr_expects_features)]
#[diag(attr_parsing_expects_features)]
pub(crate) struct ExpectsFeatures {
#[primary_span]
pub span: Span,
@ -385,21 +398,21 @@ pub(crate) struct ExpectsFeatures {
}
#[derive(Diagnostic)]
#[diag(attr_invalid_since)]
#[diag(attr_parsing_invalid_since)]
pub(crate) struct InvalidSince {
#[primary_span]
pub span: Span,
}
#[derive(Diagnostic)]
#[diag(attr_soft_no_args)]
#[diag(attr_parsing_soft_no_args)]
pub(crate) struct SoftNoArgs {
#[primary_span]
pub span: Span,
}
#[derive(Diagnostic)]
#[diag(attr_unknown_version_literal)]
#[diag(attr_parsing_unknown_version_literal)]
pub(crate) struct UnknownVersionLiteral {
#[primary_span]
pub span: Span,

View file

@ -14,7 +14,7 @@ doctest = false
# tidy-alphabetical-start
rustc_ast = { path = "../rustc_ast" }
rustc_ast_pretty = { path = "../rustc_ast_pretty" }
rustc_attr = { path = "../rustc_attr" }
rustc_attr_parsing = { path = "../rustc_attr_parsing" }
rustc_data_structures = { path = "../rustc_data_structures" }
rustc_errors = { path = "../rustc_errors" }
rustc_expand = { path = "../rustc_expand" }

View file

@ -7,7 +7,7 @@ use rustc_ast::tokenstream::TokenStream;
use rustc_errors::PResult;
use rustc_expand::base::{DummyResult, ExpandResult, ExtCtxt, MacEager, MacroExpanderResult};
use rustc_span::Span;
use {rustc_ast as ast, rustc_attr as attr};
use {rustc_ast as ast, rustc_attr_parsing as attr};
use crate::errors;

View file

@ -6,7 +6,7 @@ use rustc_ast::{
self as ast, GenericArg, GenericBound, GenericParamKind, ItemKind, MetaItem,
TraitBoundModifiers, VariantData, WherePredicate,
};
use rustc_attr as attr;
use rustc_attr_parsing as attr;
use rustc_data_structures::flat_map_in_place::FlatMapInPlace;
use rustc_expand::base::{Annotatable, ExtCtxt};
use rustc_macros::Diagnostic;

View file

@ -185,7 +185,7 @@ use rustc_ast::{
self as ast, AnonConst, BindingMode, ByRef, EnumDef, Expr, GenericArg, GenericParamKind,
Generics, Mutability, PatKind, VariantData,
};
use rustc_attr as attr;
use rustc_attr_parsing as attr;
use rustc_expand::base::{Annotatable, ExtCtxt};
use rustc_span::symbol::{Ident, Symbol, kw, sym};
use rustc_span::{DUMMY_SP, Span};

View file

@ -2,8 +2,8 @@
use gccjit::FnAttribute;
use gccjit::Function;
#[cfg(feature = "master")]
use rustc_attr::InlineAttr;
use rustc_attr::InstructionSetAttr;
use rustc_attr_parsing::InlineAttr;
use rustc_attr_parsing::InstructionSetAttr;
#[cfg(feature = "master")]
use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrFlags;
use rustc_middle::ty;

View file

@ -35,7 +35,7 @@ extern crate tracing;
extern crate rustc_abi;
extern crate rustc_apfloat;
extern crate rustc_ast;
extern crate rustc_attr;
extern crate rustc_attr_parsing;
extern crate rustc_codegen_ssa;
extern crate rustc_data_structures;
extern crate rustc_errors;

View file

@ -16,7 +16,7 @@ object = { version = "0.36.3", default-features = false, features = ["std", "rea
rustc-demangle = "0.1.21"
rustc_abi = { path = "../rustc_abi" }
rustc_ast = { path = "../rustc_ast" }
rustc_attr = { path = "../rustc_attr" }
rustc_attr_parsing = { path = "../rustc_attr_parsing" }
rustc_codegen_ssa = { path = "../rustc_codegen_ssa" }
rustc_data_structures = { path = "../rustc_data_structures" }
rustc_errors = { path = "../rustc_errors" }

View file

@ -1,6 +1,6 @@
//! Set and unset common attributes on LLVM values.
use rustc_attr::{InlineAttr, InstructionSetAttr, OptimizeAttr};
use rustc_attr_parsing::{InlineAttr, InstructionSetAttr, OptimizeAttr};
use rustc_codegen_ssa::traits::*;
use rustc_hir::def_id::DefId;
use rustc_middle::middle::codegen_fn_attrs::{CodegenFnAttrFlags, PatchableFunctionEntry};

View file

@ -106,7 +106,7 @@ pub(crate) fn get_fn<'ll, 'tcx>(cx: &CodegenCx<'ll, 'tcx>, instance: Instance<'t
// This is a monomorphization of a generic function.
if !(cx.tcx.sess.opts.share_generics()
|| tcx.codegen_fn_attrs(instance_def_id).inline
== rustc_attr::InlineAttr::Never)
== rustc_attr_parsing::InlineAttr::Never)
{
// When not sharing generics, all instances are in the same
// crate and have hidden visibility.

View file

@ -17,7 +17,7 @@ rustc_abi = { path = "../rustc_abi" }
rustc_arena = { path = "../rustc_arena" }
rustc_ast = { path = "../rustc_ast" }
rustc_ast_pretty = { path = "../rustc_ast_pretty" }
rustc_attr = { path = "../rustc_attr" }
rustc_attr_parsing = { path = "../rustc_attr_parsing" }
rustc_data_structures = { path = "../rustc_data_structures" }
rustc_errors = { path = "../rustc_errors" }
rustc_fluent_macro = { path = "../rustc_fluent_macro" }

View file

@ -2982,7 +2982,7 @@ fn add_dynamic_crate(cmd: &mut dyn Linker, sess: &Session, cratepath: &Path) {
fn relevant_lib(sess: &Session, lib: &NativeLib) -> bool {
match lib.cfg {
Some(ref cfg) => rustc_attr::cfg_matches(cfg, sess, CRATE_NODE_ID, None),
Some(ref cfg) => rustc_attr_parsing::cfg_matches(cfg, sess, CRATE_NODE_ID, None),
None => true,
}
}

View file

@ -311,7 +311,8 @@ fn exported_symbols_provider_local(
}
if !tcx.sess.opts.share_generics() {
if tcx.codegen_fn_attrs(mono_item.def_id()).inline == rustc_attr::InlineAttr::Never
if tcx.codegen_fn_attrs(mono_item.def_id()).inline
== rustc_attr_parsing::InlineAttr::Never
{
// this is OK, we explicitly allow sharing inline(never) across crates even
// without share-generics.

View file

@ -5,7 +5,6 @@ use std::time::{Duration, Instant};
use itertools::Itertools;
use rustc_abi::FIRST_VARIANT;
use rustc_ast::expand::allocator::{ALLOCATOR_METHODS, AllocatorKind, global_fn_name};
use rustc_attr as attr;
use rustc_data_structures::fx::{FxHashMap, FxIndexSet};
use rustc_data_structures::profiling::{get_resident_set_size, print_time_passes_entry};
use rustc_data_structures::sync::{Lrc, par_map};
@ -31,6 +30,7 @@ use rustc_trait_selection::infer::at::ToTrace;
use rustc_trait_selection::infer::{BoundRegionConversionTime, TyCtxtInferExt};
use rustc_trait_selection::traits::{ObligationCause, ObligationCtxt};
use tracing::{debug, info};
use {rustc_ast as ast, rustc_attr_parsing as attr};
use crate::assert_module_sources::CguReuse;
use crate::back::link::are_upstream_rust_objects_already_included;
@ -873,7 +873,8 @@ impl CrateInfo {
crate_types.iter().map(|&c| (c, crate::back::linker::linked_symbols(tcx, c))).collect();
let local_crate_name = tcx.crate_name(LOCAL_CRATE);
let crate_attrs = tcx.hir().attrs(rustc_hir::CRATE_HIR_ID);
let subsystem = attr::first_attr_value_str_by_name(crate_attrs, sym::windows_subsystem);
let subsystem =
ast::attr::first_attr_value_str_by_name(crate_attrs, sym::windows_subsystem);
let windows_subsystem = subsystem.map(|subsystem| {
if subsystem != sym::windows && subsystem != sym::console {
tcx.dcx().emit_fatal(errors::InvalidWindowsSubsystem { subsystem });

View file

@ -1,5 +1,6 @@
use rustc_ast::attr::list_contains_name;
use rustc_ast::{MetaItemInner, attr};
use rustc_attr::{InlineAttr, InstructionSetAttr, OptimizeAttr, list_contains_name};
use rustc_attr_parsing::{InlineAttr, InstructionSetAttr, OptimizeAttr};
use rustc_data_structures::fx::FxHashMap;
use rustc_errors::codes::*;
use rustc_errors::{DiagMessage, SubdiagMessage, struct_span_code_err};
@ -425,7 +426,7 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, did: LocalDefId) -> CodegenFnAttrs {
&& let [item] = items.as_slice()
&& let Some((sym::align, literal)) = item.singleton_lit_list()
{
rustc_attr::parse_alignment(&literal.kind)
rustc_attr_parsing::parse_alignment(&literal.kind)
.map_err(|msg| {
struct_span_code_err!(
tcx.dcx(),

View file

@ -1,4 +1,4 @@
use rustc_attr::InstructionSetAttr;
use rustc_attr_parsing::InstructionSetAttr;
use rustc_middle::mir::mono::{Linkage, MonoItem, MonoItemData, Visibility};
use rustc_middle::mir::{Body, InlineAsmOperand};
use rustc_middle::ty::layout::{HasTyCtxt, HasTypingEnv, LayoutOf};

View file

@ -1,4 +1,4 @@
use rustc_attr::InstructionSetAttr;
use rustc_attr_parsing::InstructionSetAttr;
use rustc_data_structures::fx::FxIndexSet;
use rustc_data_structures::unord::{UnordMap, UnordSet};
use rustc_errors::Applicability;

View file

@ -9,7 +9,7 @@ either = "1"
rustc_abi = { path = "../rustc_abi" }
rustc_apfloat = "0.2.0"
rustc_ast = { path = "../rustc_ast" }
rustc_attr = { path = "../rustc_attr" }
rustc_attr_parsing = { path = "../rustc_attr_parsing" }
rustc_data_structures = { path = "../rustc_data_structures" }
rustc_errors = { path = "../rustc_errors" }
rustc_fluent_macro = { path = "../rustc_fluent_macro" }

View file

@ -6,7 +6,7 @@ use std::mem;
use std::num::NonZero;
use std::ops::Deref;
use rustc_attr::{ConstStability, StabilityLevel};
use rustc_attr_parsing::{ConstStability, StabilityLevel};
use rustc_errors::{Diag, ErrorGuaranteed};
use rustc_hir::def_id::DefId;
use rustc_hir::{self as hir, LangItem};

View file

@ -9,7 +9,7 @@ use rustc_hir::def_id::{DefId, LocalDefId};
use rustc_middle::ty::{self, PolyFnSig, TyCtxt};
use rustc_middle::{bug, mir};
use rustc_span::Symbol;
use {rustc_attr as attr, rustc_hir as hir};
use {rustc_attr_parsing as attr, rustc_hir as hir};
pub use self::qualifs::Qualif;

View file

@ -9,7 +9,7 @@ rustc_ast = { path = "../rustc_ast" }
rustc_ast_lowering = { path = "../rustc_ast_lowering" }
rustc_ast_passes = { path = "../rustc_ast_passes" }
rustc_ast_pretty = { path = "../rustc_ast_pretty" }
rustc_attr = { path = "../rustc_attr" }
rustc_attr_parsing = { path = "../rustc_attr_parsing" }
rustc_borrowck = { path = "../rustc_borrowck" }
rustc_builtin_macros = { path = "../rustc_builtin_macros" }
rustc_codegen_ssa = { path = "../rustc_codegen_ssa" }

View file

@ -112,7 +112,7 @@ pub static DEFAULT_LOCALE_RESOURCES: &[&str] = &[
crate::DEFAULT_LOCALE_RESOURCE,
rustc_ast_lowering::DEFAULT_LOCALE_RESOURCE,
rustc_ast_passes::DEFAULT_LOCALE_RESOURCE,
rustc_attr::DEFAULT_LOCALE_RESOURCE,
rustc_attr_parsing::DEFAULT_LOCALE_RESOURCE,
rustc_borrowck::DEFAULT_LOCALE_RESOURCE,
rustc_builtin_macros::DEFAULT_LOCALE_RESOURCE,
rustc_codegen_ssa::DEFAULT_LOCALE_RESOURCE,

View file

@ -12,7 +12,7 @@ doctest = false
rustc_ast = { path = "../rustc_ast" }
rustc_ast_passes = { path = "../rustc_ast_passes" }
rustc_ast_pretty = { path = "../rustc_ast_pretty" }
rustc_attr = { path = "../rustc_attr" }
rustc_attr_parsing = { path = "../rustc_attr_parsing" }
rustc_data_structures = { path = "../rustc_data_structures" }
rustc_errors = { path = "../rustc_errors" }
rustc_feature = { path = "../rustc_feature" }

View file

@ -10,7 +10,7 @@ use rustc_ast::token::Nonterminal;
use rustc_ast::tokenstream::TokenStream;
use rustc_ast::visit::{AssocCtxt, Visitor};
use rustc_ast::{self as ast, AttrVec, Attribute, HasAttrs, Item, NodeId, PatKind};
use rustc_attr::{self as attr, Deprecation, Stability};
use rustc_attr_parsing::{self as attr, Deprecation, Stability};
use rustc_data_structures::fx::FxIndexMap;
use rustc_data_structures::sync::{self, Lrc};
use rustc_errors::{DiagCtxtHandle, ErrorGuaranteed, PResult};
@ -809,7 +809,7 @@ impl SyntaxExtension {
/// | yes | yes | yes | yes | yes |
fn get_collapse_debuginfo(sess: &Session, attrs: &[impl AttributeExt], ext: bool) -> bool {
let flag = sess.opts.cg.collapse_macro_debuginfo;
let attr = attr::find_by_name(attrs, sym::collapse_debuginfo)
let attr = ast::attr::find_by_name(attrs, sym::collapse_debuginfo)
.and_then(|attr| {
Self::collapse_debuginfo_by_name(attr)
.map_err(|span| {
@ -818,7 +818,7 @@ impl SyntaxExtension {
.ok()
})
.unwrap_or_else(|| {
if attr::contains_name(attrs, sym::rustc_builtin_macro) {
if ast::attr::contains_name(attrs, sym::rustc_builtin_macro) {
CollapseMacroDebuginfo::Yes
} else {
CollapseMacroDebuginfo::Unspecified
@ -848,16 +848,16 @@ impl SyntaxExtension {
is_local: bool,
) -> SyntaxExtension {
let allow_internal_unstable =
rustc_attr::allow_internal_unstable(sess, attrs).collect::<Vec<Symbol>>();
rustc_attr_parsing::allow_internal_unstable(sess, attrs).collect::<Vec<Symbol>>();
let allow_internal_unsafe = attr::contains_name(attrs, sym::allow_internal_unsafe);
let local_inner_macros = attr::find_by_name(attrs, sym::macro_export)
let allow_internal_unsafe = ast::attr::contains_name(attrs, sym::allow_internal_unsafe);
let local_inner_macros = ast::attr::find_by_name(attrs, sym::macro_export)
.and_then(|macro_export| macro_export.meta_item_list())
.is_some_and(|l| attr::list_contains_name(&l, sym::local_inner_macros));
.is_some_and(|l| ast::attr::list_contains_name(&l, sym::local_inner_macros));
let collapse_debuginfo = Self::get_collapse_debuginfo(sess, attrs, !is_local);
tracing::debug!(?name, ?local_inner_macros, ?collapse_debuginfo, ?allow_internal_unsafe);
let (builtin_name, helper_attrs) = attr::find_by_name(attrs, sym::rustc_builtin_macro)
let (builtin_name, helper_attrs) = ast::attr::find_by_name(attrs, sym::rustc_builtin_macro)
.map(|attr| {
// Override `helper_attrs` passed above if it's a built-in macro,
// marking `proc_macro_derive` macros as built-in is not a realistic use case.

View file

@ -8,7 +8,7 @@ use rustc_ast::tokenstream::{
use rustc_ast::{
self as ast, AttrStyle, Attribute, HasAttrs, HasTokens, MetaItem, MetaItemInner, NodeId,
};
use rustc_attr as attr;
use rustc_attr_parsing as attr;
use rustc_data_structures::flat_map_in_place::FlatMapInPlace;
use rustc_feature::{
ACCEPTED_LANG_FEATURES, AttributeSafety, EnabledLangFeature, EnabledLibFeature, Features,
@ -362,7 +362,7 @@ impl<'a> StripUnconfigured<'a> {
));
let tokens = Some(LazyAttrTokenStream::new(AttrTokenStream::new(trees)));
let attr = attr::mk_attr_from_item(
let attr = ast::attr::mk_attr_from_item(
&self.sess.psess.attr_id_generator,
item,
tokens,

View file

@ -1913,7 +1913,7 @@ impl<'a, 'b> InvocationCollector<'a, 'b> {
self.cx.current_expansion.lint_node_id,
BuiltinLintDiag::UnusedDocComment(attr.span),
);
} else if rustc_attr::is_builtin_attr(attr) {
} else if rustc_attr_parsing::is_builtin_attr(attr) {
let attr_name = attr.ident().unwrap().name;
// `#[cfg]` and `#[cfg_attr]` are special - they are
// eagerly evaluated.

View file

@ -3,13 +3,14 @@ use std::collections::hash_map::Entry;
use std::{mem, slice};
use ast::token::IdentIsRaw;
use rustc_ast::attr::AttributeExt;
use rustc_ast::token::NtPatKind::*;
use rustc_ast::token::TokenKind::*;
use rustc_ast::token::{self, Delimiter, NonterminalKind, Token, TokenKind};
use rustc_ast::tokenstream::{DelimSpan, TokenStream};
use rustc_ast::{self as ast, DUMMY_NODE_ID, NodeId};
use rustc_ast_pretty::pprust;
use rustc_attr::{self as attr, AttributeExt, TransparencyError};
use rustc_attr_parsing::{self as attr, TransparencyError};
use rustc_data_structures::fx::{FxHashMap, FxIndexMap};
use rustc_errors::{Applicability, ErrorGuaranteed};
use rustc_feature::Features;

View file

@ -13,7 +13,7 @@ itertools = "0.12"
rustc_abi = { path = "../rustc_abi" }
rustc_arena = { path = "../rustc_arena" }
rustc_ast = { path = "../rustc_ast" }
rustc_attr = { path = "../rustc_attr" }
rustc_attr_parsing = { path = "../rustc_attr_parsing" }
rustc_data_structures = { path = "../rustc_data_structures" }
rustc_errors = { path = "../rustc_errors" }
rustc_feature = { path = "../rustc_feature" }

View file

@ -31,7 +31,7 @@ use rustc_trait_selection::traits::outlives_bounds::InferCtxtExt as _;
use rustc_type_ir::fold::TypeFoldable;
use tracing::{debug, instrument};
use ty::TypingMode;
use {rustc_attr as attr, rustc_hir as hir};
use {rustc_attr_parsing as attr, rustc_hir as hir};
use super::compare_impl_item::check_type_bounds;
use super::*;

View file

@ -9,7 +9,7 @@ itertools = "0.12"
rustc_abi = { path = "../rustc_abi" }
rustc_ast = { path = "../rustc_ast" }
rustc_ast_ir = { path = "../rustc_ast_ir" }
rustc_attr = { path = "../rustc_attr" }
rustc_attr_parsing = { path = "../rustc_attr_parsing" }
rustc_data_structures = { path = "../rustc_data_structures" }
rustc_errors = { path = "../rustc_errors" }
rustc_fluent_macro = { path = "../rustc_fluent_macro" }

View file

@ -8,7 +8,7 @@ use std::borrow::Cow;
use hir::Expr;
use rustc_ast::ast::Mutability;
use rustc_attr::parse_confusables;
use rustc_attr_parsing::parse_confusables;
use rustc_data_structures::fx::{FxIndexMap, FxIndexSet};
use rustc_data_structures::sorted_map::SortedMap;
use rustc_data_structures::unord::UnordSet;

View file

@ -11,7 +11,7 @@ rustc_ast = { path = "../rustc_ast" }
rustc_ast_lowering = { path = "../rustc_ast_lowering" }
rustc_ast_passes = { path = "../rustc_ast_passes" }
rustc_ast_pretty = { path = "../rustc_ast_pretty" }
rustc_attr = { path = "../rustc_attr" }
rustc_attr_parsing = { path = "../rustc_attr_parsing" }
rustc_borrowck = { path = "../rustc_borrowck" }
rustc_builtin_macros = { path = "../rustc_builtin_macros" }
rustc_codegen_llvm = { path = "../rustc_codegen_llvm", optional = true }

View file

@ -453,7 +453,7 @@ pub fn build_output_filenames(attrs: &[ast::Attribute], sess: &Session) -> Outpu
.opts
.crate_name
.clone()
.or_else(|| rustc_attr::find_crate_name(attrs).map(|n| n.to_string()));
.or_else(|| rustc_attr_parsing::find_crate_name(attrs).map(|n| n.to_string()));
match sess.io.output_file {
None => {

View file

@ -8,7 +8,7 @@ edition = "2021"
rustc_abi = { path = "../rustc_abi" }
rustc_ast = { path = "../rustc_ast" }
rustc_ast_pretty = { path = "../rustc_ast_pretty" }
rustc_attr = { path = "../rustc_attr" }
rustc_attr_parsing = { path = "../rustc_attr_parsing" }
rustc_data_structures = { path = "../rustc_data_structures" }
rustc_errors = { path = "../rustc_errors" }
rustc_feature = { path = "../rustc_feature" }

View file

@ -1,5 +1,5 @@
use rustc_ast::attr::AttributeExt;
use rustc_ast_pretty::pprust;
use rustc_attr::AttributeExt;
use rustc_data_structures::fx::{FxIndexMap, FxIndexSet};
use rustc_errors::{Diag, LintDiagnostic, MultiSpan};
use rustc_feature::{Features, GateIssue};

View file

@ -8,7 +8,7 @@ use rustc_session::{declare_lint, declare_lint_pass};
use rustc_span::def_id::LocalDefId;
use rustc_span::symbol::{Ident, sym};
use rustc_span::{BytePos, Span};
use {rustc_ast as ast, rustc_attr as attr, rustc_hir as hir};
use {rustc_ast as ast, rustc_attr_parsing as attr, rustc_hir as hir};
use crate::lints::{
NonCamelCaseType, NonCamelCaseTypeSub, NonSnakeCaseDiag, NonSnakeCaseDiagSub,
@ -342,8 +342,8 @@ impl<'tcx> LateLintPass<'tcx> for NonSnakeCase {
let crate_ident = if let Some(name) = &cx.tcx.sess.opts.crate_name {
Some(Ident::from_str(name))
} else {
attr::find_by_name(cx.tcx.hir().attrs(hir::CRATE_HIR_ID), sym::crate_name).and_then(
|attr| {
ast::attr::find_by_name(cx.tcx.hir().attrs(hir::CRATE_HIR_ID), sym::crate_name)
.and_then(|attr| {
if let AttrKind::Normal(n) = &attr.kind
&& let AttrItem { args: AttrArgs::Eq { eq_span: _, expr: ref lit }, .. } =
n.as_ref()
@ -371,8 +371,7 @@ impl<'tcx> LateLintPass<'tcx> for NonSnakeCase {
} else {
None
}
},
)
})
};
if let Some(ident) = &crate_ident {
@ -503,7 +502,7 @@ impl<'tcx> LateLintPass<'tcx> for NonUpperCaseGlobals {
fn check_item(&mut self, cx: &LateContext<'_>, it: &hir::Item<'_>) {
let attrs = cx.tcx.hir().attrs(it.hir_id());
match it.kind {
hir::ItemKind::Static(..) if !attr::contains_name(attrs, sym::no_mangle) => {
hir::ItemKind::Static(..) if !ast::attr::contains_name(attrs, sym::no_mangle) => {
NonUpperCaseGlobals::check_upper_case(cx, "static variable", &it.ident);
}
hir::ItemKind::Const(..) => {

View file

@ -3,7 +3,7 @@ use rustc_abi::{Integer, Size};
use rustc_middle::ty::Ty;
use rustc_middle::ty::layout::IntegerExt;
use rustc_middle::{bug, ty};
use {rustc_ast as ast, rustc_attr as attr, rustc_hir as hir};
use {rustc_ast as ast, rustc_attr_parsing as attr, rustc_hir as hir};
use crate::LateContext;
use crate::context::LintContext;

View file

@ -11,7 +11,7 @@ libloading = "0.8.0"
odht = { version = "0.3.1", features = ["nightly"] }
rustc_abi = { path = "../rustc_abi" }
rustc_ast = { path = "../rustc_ast" }
rustc_attr = { path = "../rustc_attr" }
rustc_attr_parsing = { path = "../rustc_attr_parsing" }
rustc_data_structures = { path = "../rustc_data_structures" }
rustc_errors = { path = "../rustc_errors" }
rustc_expand = { path = "../rustc_expand" }

View file

@ -3,7 +3,7 @@ use std::path::{Path, PathBuf};
use rustc_abi::ExternAbi;
use rustc_ast::CRATE_NODE_ID;
use rustc_attr as attr;
use rustc_attr_parsing as attr;
use rustc_data_structures::fx::FxHashSet;
use rustc_middle::query::LocalCrate;
use rustc_middle::ty::{self, List, Ty, TyCtxt};

View file

@ -1,7 +1,7 @@
use std::any::Any;
use std::mem;
use rustc_attr::Deprecation;
use rustc_attr_parsing::Deprecation;
use rustc_data_structures::sync::Lrc;
use rustc_hir::def::{CtorKind, DefKind, Res};
use rustc_hir::def_id::{CrateNum, DefId, DefIdMap, LOCAL_CRATE};

View file

@ -710,15 +710,18 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
has_global_allocator: tcx.has_global_allocator(LOCAL_CRATE),
has_alloc_error_handler: tcx.has_alloc_error_handler(LOCAL_CRATE),
has_panic_handler: tcx.has_panic_handler(LOCAL_CRATE),
has_default_lib_allocator: attr::contains_name(attrs, sym::default_lib_allocator),
has_default_lib_allocator: ast::attr::contains_name(
attrs,
sym::default_lib_allocator,
),
proc_macro_data,
debugger_visualizers,
compiler_builtins: attr::contains_name(attrs, sym::compiler_builtins),
needs_allocator: attr::contains_name(attrs, sym::needs_allocator),
needs_panic_runtime: attr::contains_name(attrs, sym::needs_panic_runtime),
no_builtins: attr::contains_name(attrs, sym::no_builtins),
panic_runtime: attr::contains_name(attrs, sym::panic_runtime),
profiler_runtime: attr::contains_name(attrs, sym::profiler_runtime),
compiler_builtins: ast::attr::contains_name(attrs, sym::compiler_builtins),
needs_allocator: ast::attr::contains_name(attrs, sym::needs_allocator),
needs_panic_runtime: ast::attr::contains_name(attrs, sym::needs_panic_runtime),
no_builtins: ast::attr::contains_name(attrs, sym::no_builtins),
panic_runtime: ast::attr::contains_name(attrs, sym::panic_runtime),
profiler_runtime: ast::attr::contains_name(attrs, sym::profiler_runtime),
symbol_mangling_version: tcx.sess.opts.get_symbol_mangling_version(),
crate_deps,
@ -1917,11 +1920,11 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
// Proc-macros may have attributes like `#[allow_internal_unstable]`,
// so downstream crates need access to them.
let attrs = hir.attrs(proc_macro);
let macro_kind = if attr::contains_name(attrs, sym::proc_macro) {
let macro_kind = if ast::attr::contains_name(attrs, sym::proc_macro) {
MacroKind::Bang
} else if attr::contains_name(attrs, sym::proc_macro_attribute) {
} else if ast::attr::contains_name(attrs, sym::proc_macro_attribute) {
MacroKind::Attr
} else if let Some(attr) = attr::find_by_name(attrs, sym::proc_macro_derive) {
} else if let Some(attr) = ast::attr::find_by_name(attrs, sym::proc_macro_derive) {
// This unwrap chain should have been checked by the proc-macro harness.
name = attr.meta_item_list().unwrap()[0]
.meta_item()

View file

@ -40,7 +40,7 @@ use rustc_span::symbol::{Ident, Symbol};
use rustc_span::{self, ExpnData, ExpnHash, ExpnId, Span};
use rustc_target::spec::{PanicStrategy, TargetTuple};
use table::TableBuilder;
use {rustc_ast as ast, rustc_attr as attr, rustc_hir as hir};
use {rustc_ast as ast, rustc_attr_parsing as attr, rustc_hir as hir};
use crate::creader::CrateMetadataRef;

View file

@ -17,7 +17,7 @@ rustc_apfloat = "0.2.0"
rustc_arena = { path = "../rustc_arena" }
rustc_ast = { path = "../rustc_ast" }
rustc_ast_ir = { path = "../rustc_ast_ir" }
rustc_attr = { path = "../rustc_attr" }
rustc_attr_parsing = { path = "../rustc_attr_parsing" }
rustc_data_structures = { path = "../rustc_data_structures" }
rustc_error_messages = { path = "../rustc_error_messages" } # Used for intra-doc links
rustc_errors = { path = "../rustc_errors" }

View file

@ -1,5 +1,5 @@
use rustc_abi::Align;
use rustc_attr::{InlineAttr, InstructionSetAttr, OptimizeAttr};
use rustc_attr_parsing::{InlineAttr, InstructionSetAttr, OptimizeAttr};
use rustc_macros::{HashStable, TyDecodable, TyEncodable};
use rustc_span::symbol::Symbol;
use rustc_target::spec::SanitizerSet;

View file

@ -4,7 +4,7 @@
use std::num::NonZero;
use rustc_ast::NodeId;
use rustc_attr::{
use rustc_attr_parsing::{
self as attr, ConstStability, DefaultBodyStability, DeprecatedSince, Deprecation, Stability,
};
use rustc_data_structures::unord::UnordMap;
@ -392,7 +392,7 @@ impl<'tcx> TyCtxt<'tcx> {
match stability {
Some(Stability {
level: attr::Unstable { reason, issue, is_soft, implied_by },
level: attr::StabilityLevel::Unstable { reason, issue, is_soft, implied_by },
feature,
..
}) => {
@ -475,7 +475,7 @@ impl<'tcx> TyCtxt<'tcx> {
match stability {
Some(DefaultBodyStability {
level: attr::Unstable { reason, issue, is_soft, .. },
level: attr::StabilityLevel::Unstable { reason, issue, is_soft, .. },
feature,
}) => {
if span.allows_unstable(feature) {

View file

@ -1,7 +1,7 @@
use std::fmt;
use std::hash::Hash;
use rustc_attr::InlineAttr;
use rustc_attr_parsing::InlineAttr;
use rustc_data_structures::base_n::{BaseNString, CASE_INSENSITIVE, ToBaseN};
use rustc_data_structures::fingerprint::Fingerprint;
use rustc_data_structures::fx::FxIndexMap;

View file

@ -239,9 +239,9 @@ trivial! {
bool,
Option<(rustc_span::def_id::DefId, rustc_session::config::EntryFnType)>,
Option<rustc_ast::expand::allocator::AllocatorKind>,
Option<rustc_attr::ConstStability>,
Option<rustc_attr::DefaultBodyStability>,
Option<rustc_attr::Stability>,
Option<rustc_attr_parsing::ConstStability>,
Option<rustc_attr_parsing::DefaultBodyStability>,
Option<rustc_attr_parsing::Stability>,
Option<rustc_data_structures::svh::Svh>,
Option<rustc_hir::def::DefKind>,
Option<rustc_hir::CoroutineKind>,
@ -264,10 +264,10 @@ trivial! {
Result<rustc_middle::traits::EvaluationResult, rustc_middle::traits::OverflowError>,
rustc_abi::ReprOptions,
rustc_ast::expand::allocator::AllocatorKind,
rustc_attr::ConstStability,
rustc_attr::DefaultBodyStability,
rustc_attr::Deprecation,
rustc_attr::Stability,
rustc_attr_parsing::ConstStability,
rustc_attr_parsing::DefaultBodyStability,
rustc_attr_parsing::Deprecation,
rustc_attr_parsing::Stability,
rustc_data_structures::svh::Svh,
rustc_errors::ErrorGuaranteed,
rustc_hir::Constness,

View file

@ -44,7 +44,7 @@ use rustc_span::source_map::Spanned;
use rustc_span::symbol::Symbol;
use rustc_span::{DUMMY_SP, Span};
use rustc_target::spec::PanicStrategy;
use {rustc_abi as abi, rustc_ast as ast, rustc_attr as attr, rustc_hir as hir};
use {rustc_abi as abi, rustc_ast as ast, rustc_attr_parsing as attr, rustc_hir as hir};
use crate::infer::canonical::{self, Canonical};
use crate::lint::LintExpectation;

View file

@ -202,7 +202,7 @@ impl<'tcx> Instance<'tcx> {
if !tcx.sess.opts.share_generics()
// However, if the def_id is marked inline(never), then it's fine to just reuse the
// upstream monomorphization.
&& tcx.codegen_fn_attrs(self.def_id()).inline != rustc_attr::InlineAttr::Never
&& tcx.codegen_fn_attrs(self.def_id()).inline != rustc_attr_parsing::InlineAttr::Never
{
return None;
}

View file

@ -52,7 +52,7 @@ pub use rustc_type_ir::relate::VarianceDiagInfo;
pub use rustc_type_ir::*;
use tracing::{debug, instrument};
pub use vtable::*;
use {rustc_ast as ast, rustc_attr as attr, rustc_hir as hir};
use {rustc_ast as ast, rustc_attr_parsing as attr, rustc_hir as hir};
pub use self::closure::{
BorrowKind, CAPTURE_STRUCT_LOCAL, CaptureInfo, CapturedPlace, ClosureTypeInfo,

View file

@ -80,10 +80,10 @@ trivially_parameterized_over_tcx! {
rustc_ast::Attribute,
rustc_ast::DelimArgs,
rustc_ast::expand::StrippedCfgItem<rustc_hir::def_id::DefIndex>,
rustc_attr::ConstStability,
rustc_attr::DefaultBodyStability,
rustc_attr::Deprecation,
rustc_attr::Stability,
rustc_attr_parsing::ConstStability,
rustc_attr_parsing::DefaultBodyStability,
rustc_attr_parsing::Deprecation,
rustc_attr_parsing::Stability,
rustc_hir::Constness,
rustc_hir::Defaultness,
rustc_hir::Safety,

View file

@ -10,7 +10,7 @@ itertools = "0.12"
rustc_abi = { path = "../rustc_abi" }
rustc_arena = { path = "../rustc_arena" }
rustc_ast = { path = "../rustc_ast" }
rustc_attr = { path = "../rustc_attr" }
rustc_attr_parsing = { path = "../rustc_attr_parsing" }
rustc_const_eval = { path = "../rustc_const_eval" }
rustc_data_structures = { path = "../rustc_data_structures" }
rustc_errors = { path = "../rustc_errors" }

View file

@ -1,4 +1,4 @@
use rustc_attr::InlineAttr;
use rustc_attr_parsing::InlineAttr;
use rustc_hir::def::DefKind;
use rustc_hir::def_id::LocalDefId;
use rustc_middle::mir::visit::Visitor;

View file

@ -4,7 +4,7 @@ use std::iter;
use std::ops::{Range, RangeFrom};
use rustc_abi::{ExternAbi, FieldIdx};
use rustc_attr::InlineAttr;
use rustc_attr_parsing::InlineAttr;
use rustc_hir::def::DefKind;
use rustc_hir::def_id::DefId;
use rustc_index::Idx;

View file

@ -6,7 +6,7 @@ edition = "2021"
[dependencies]
# tidy-alphabetical-start
rustc_abi = { path = "../rustc_abi" }
rustc_attr = { path = "../rustc_attr" }
rustc_attr_parsing = { path = "../rustc_attr_parsing" }
rustc_data_structures = { path = "../rustc_data_structures" }
rustc_errors = { path = "../rustc_errors" }
rustc_fluent_macro = { path = "../rustc_fluent_macro" }

View file

@ -833,7 +833,8 @@ fn mono_item_visibility<'tcx>(
return if is_generic
&& (always_export_generics
|| (can_export_generics
&& tcx.codegen_fn_attrs(def_id).inline == rustc_attr::InlineAttr::Never))
&& tcx.codegen_fn_attrs(def_id).inline
== rustc_attr_parsing::InlineAttr::Never))
{
// If it is an upstream monomorphization and we export generics, we must make
// it available to downstream crates.
@ -847,7 +848,7 @@ fn mono_item_visibility<'tcx>(
if is_generic {
if always_export_generics
|| (can_export_generics
&& tcx.codegen_fn_attrs(def_id).inline == rustc_attr::InlineAttr::Never)
&& tcx.codegen_fn_attrs(def_id).inline == rustc_attr_parsing::InlineAttr::Never)
{
if tcx.is_unreachable_local_definition(def_id) {
// This instance cannot be used from another crate.

View file

@ -8,7 +8,7 @@ edition = "2021"
rustc_abi = { path = "../rustc_abi" }
rustc_ast = { path = "../rustc_ast" }
rustc_ast_pretty = { path = "../rustc_ast_pretty" }
rustc_attr = { path = "../rustc_attr" }
rustc_attr_parsing = { path = "../rustc_attr_parsing" }
rustc_data_structures = { path = "../rustc_data_structures" }
rustc_errors = { path = "../rustc_errors" }
rustc_expand = { path = "../rustc_expand" }

View file

@ -4,7 +4,7 @@
//! but are not declared in one single location (unlike lang features), which means we need to
//! collect them instead.
use rustc_attr::VERSION_PLACEHOLDER;
use rustc_attr_parsing::VERSION_PLACEHOLDER;
use rustc_hir::Attribute;
use rustc_hir::intravisit::Visitor;
use rustc_middle::hir::nested_filter;

View file

@ -4,9 +4,9 @@
use std::mem::replace;
use std::num::NonZero;
use rustc_attr::{
use rustc_attr_parsing::{
self as attr, ConstStability, DeprecatedSince, Stability, StabilityLevel, StableSince,
Unstable, UnstableReason, VERSION_PLACEHOLDER,
UnstableReason, VERSION_PLACEHOLDER,
};
use rustc_data_structures::fx::FxIndexMap;
use rustc_data_structures::unord::{ExtendUnord, UnordMap, UnordSet};
@ -199,7 +199,7 @@ impl<'a, 'tcx> Annotator<'a, 'tcx> {
// this is *almost surely* an accident.
if let (
&Some(DeprecatedSince::RustcVersion(dep_since)),
&attr::Stable { since: stab_since, .. },
&attr::StabilityLevel::Stable { since: stab_since, .. },
) = (&depr.as_ref().map(|(d, _)| d.since), &stab.level)
{
match stab_since {
@ -224,15 +224,17 @@ impl<'a, 'tcx> Annotator<'a, 'tcx> {
// Stable *language* features shouldn't be used as unstable library features.
// (Not doing this for stable library features is checked by tidy.)
if let Stability { level: Unstable { .. }, feature } = stab {
if let Stability { level: StabilityLevel::Unstable { .. }, feature } = stab {
if ACCEPTED_LANG_FEATURES.iter().find(|f| f.name == feature).is_some() {
self.tcx
.dcx()
.emit_err(errors::UnstableAttrForAlreadyStableFeature { span, item_sp });
}
}
if let Stability { level: Unstable { implied_by: Some(implied_by), .. }, feature } =
stab
if let Stability {
level: StabilityLevel::Unstable { implied_by: Some(implied_by), .. },
feature,
} = stab
{
self.index.implications.insert(implied_by, feature);
}
@ -278,8 +280,10 @@ impl<'a, 'tcx> Annotator<'a, 'tcx> {
// Stable *language* features shouldn't be used as unstable library features.
// (Not doing this for stable library features is checked by tidy.)
if let Some((ConstStability { level: Unstable { .. }, feature, .. }, const_span)) =
const_stab
if let Some((
ConstStability { level: StabilityLevel::Unstable { .. }, feature, .. },
const_span,
)) = const_stab
{
if ACCEPTED_LANG_FEATURES.iter().find(|f| f.name == feature).is_some() {
self.tcx.dcx().emit_err(errors::UnstableAttrForAlreadyStableFeature {
@ -314,7 +318,7 @@ impl<'a, 'tcx> Annotator<'a, 'tcx> {
});
if let Some(ConstStability {
level: Unstable { implied_by: Some(implied_by), .. },
level: StabilityLevel::Unstable { implied_by: Some(implied_by), .. },
feature,
..
}) = const_stab
@ -780,7 +784,11 @@ impl<'tcx> Visitor<'tcx> for Checker<'tcx> {
// error if all involved types and traits are stable, because
// it will have no effect.
// See: https://github.com/rust-lang/rust/issues/55436
if let Some((Stability { level: attr::Unstable { .. }, .. }, span)) = stab {
if let Some((
Stability { level: attr::StabilityLevel::Unstable { .. }, .. },
span,
)) = stab
{
let mut c = CheckTraitImplStable { tcx: self.tcx, fully_stable: true };
c.visit_ty(self_ty);
c.visit_trait_ref(t);

View file

@ -6,7 +6,7 @@ edition = "2021"
[dependencies]
# tidy-alphabetical-start
rustc_ast = { path = "../rustc_ast" }
rustc_attr = { path = "../rustc_attr" }
rustc_attr_parsing = { path = "../rustc_attr_parsing" }
rustc_data_structures = { path = "../rustc_data_structures" }
rustc_errors = { path = "../rustc_errors" }
rustc_fluent_macro = { path = "../rustc_fluent_macro" }

View file

@ -41,7 +41,7 @@ use rustc_span::Span;
use rustc_span::hygiene::Transparency;
use rustc_span::symbol::{Ident, kw, sym};
use tracing::debug;
use {rustc_attr as attr, rustc_hir as hir};
use {rustc_attr_parsing as attr, rustc_hir as hir};
rustc_fluent_macro::fluent_messages! { "../messages.ftl" }

View file

@ -10,7 +10,7 @@ pulldown-cmark = { version = "0.11", features = ["html"], default-features = fal
rustc_arena = { path = "../rustc_arena" }
rustc_ast = { path = "../rustc_ast" }
rustc_ast_pretty = { path = "../rustc_ast_pretty" }
rustc_attr = { path = "../rustc_attr" }
rustc_attr_parsing = { path = "../rustc_attr_parsing" }
rustc_data_structures = { path = "../rustc_data_structures" }
rustc_errors = { path = "../rustc_errors" }
rustc_expand = { path = "../rustc_expand" }

View file

@ -12,7 +12,7 @@ use rustc_ast::{
self as ast, AssocItem, AssocItemKind, Block, ForeignItem, ForeignItemKind, Impl, Item,
ItemKind, MetaItemKind, NodeId, StmtKind,
};
use rustc_attr as attr;
use rustc_attr_parsing as attr;
use rustc_data_structures::sync::Lrc;
use rustc_expand::base::ResolverExpand;
use rustc_expand::expand::AstFragment;
@ -634,7 +634,7 @@ impl<'a, 'ra, 'tcx> BuildReducedGraphVisitor<'a, 'ra, 'tcx> {
}
ast::UseTreeKind::Glob => {
let kind = ImportKind::Glob {
is_prelude: attr::contains_name(&item.attrs, sym::prelude_import),
is_prelude: ast::attr::contains_name(&item.attrs, sym::prelude_import),
max_vis: Cell::new(None),
id,
};
@ -777,7 +777,7 @@ impl<'a, 'ra, 'tcx> BuildReducedGraphVisitor<'a, 'ra, 'tcx> {
expansion.to_expn_id(),
item.span,
parent.no_implicit_prelude
|| attr::contains_name(&item.attrs, sym::no_implicit_prelude),
|| ast::attr::contains_name(&item.attrs, sym::no_implicit_prelude),
);
self.r.define(parent, ident, TypeNS, (module, vis, sp, expansion));
@ -835,7 +835,7 @@ impl<'a, 'ra, 'tcx> BuildReducedGraphVisitor<'a, 'ra, 'tcx> {
// If the structure is marked as non_exhaustive then lower the visibility
// to within the crate.
let mut ctor_vis = if vis.is_public()
&& attr::contains_name(&item.attrs, sym::non_exhaustive)
&& ast::attr::contains_name(&item.attrs, sym::non_exhaustive)
{
ty::Visibility::Restricted(CRATE_DEF_ID)
} else {
@ -1176,11 +1176,11 @@ impl<'a, 'ra, 'tcx> BuildReducedGraphVisitor<'a, 'ra, 'tcx> {
}
fn proc_macro_stub(&self, item: &ast::Item) -> Option<(MacroKind, Ident, Span)> {
if attr::contains_name(&item.attrs, sym::proc_macro) {
if ast::attr::contains_name(&item.attrs, sym::proc_macro) {
return Some((MacroKind::Bang, item.ident, item.span));
} else if attr::contains_name(&item.attrs, sym::proc_macro_attribute) {
} else if ast::attr::contains_name(&item.attrs, sym::proc_macro_attribute) {
return Some((MacroKind::Attr, item.ident, item.span));
} else if let Some(attr) = attr::find_by_name(&item.attrs, sym::proc_macro_derive) {
} else if let Some(attr) = ast::attr::find_by_name(&item.attrs, sym::proc_macro_derive) {
if let Some(meta_item_inner) =
attr.meta_item_list().and_then(|list| list.get(0).cloned())
{
@ -1233,7 +1233,7 @@ impl<'a, 'ra, 'tcx> BuildReducedGraphVisitor<'a, 'ra, 'tcx> {
if macro_rules {
let ident = ident.normalize_to_macros_2_0();
self.r.macro_names.insert(ident);
let is_macro_export = attr::contains_name(&item.attrs, sym::macro_export);
let is_macro_export = ast::attr::contains_name(&item.attrs, sym::macro_export);
let vis = if is_macro_export {
ty::Visibility::Public
} else {
@ -1507,7 +1507,7 @@ impl<'a, 'ra, 'tcx> Visitor<'a> for BuildReducedGraphVisitor<'a, 'ra, 'tcx> {
// If the variant is marked as non_exhaustive then lower the visibility to within the crate.
let ctor_vis =
if vis.is_public() && attr::contains_name(&variant.attrs, sym::non_exhaustive) {
if vis.is_public() && ast::attr::contains_name(&variant.attrs, sym::non_exhaustive) {
ty::Visibility::Restricted(CRATE_DEF_ID)
} else {
vis

View file

@ -4,10 +4,11 @@
use std::cell::Cell;
use std::mem;
use rustc_ast::attr::AttributeExt;
use rustc_ast::expand::StrippedCfgItem;
use rustc_ast::{self as ast, Crate, Inline, ItemKind, ModKind, NodeId, attr};
use rustc_ast_pretty::pprust;
use rustc_attr::{AttributeExt, StabilityLevel};
use rustc_attr_parsing::StabilityLevel;
use rustc_data_structures::intern::Interned;
use rustc_data_structures::sync::Lrc;
use rustc_errors::{Applicability, StashKey};

View file

@ -5,8 +5,8 @@ use pulldown_cmark::{
BrokenLink, BrokenLinkCallback, CowStr, Event, LinkType, Options, Parser, Tag,
};
use rustc_ast as ast;
use rustc_ast::attr::AttributeExt;
use rustc_ast::util::comments::beautify_doc_string;
use rustc_attr::AttributeExt;
use rustc_data_structures::fx::FxIndexMap;
use rustc_middle::ty::TyCtxt;
use rustc_span::def_id::DefId;

View file

@ -29,9 +29,6 @@ pub mod output;
pub use getopts;
mod version;
pub use version::RustcVersion;
rustc_fluent_macro::fluent_messages! { "../messages.ftl" }
/// Requirements for a `StableHashingContext` to be used in this crate.

View file

@ -9,7 +9,7 @@ itertools = "0.12"
rustc_abi = { path = "../rustc_abi" }
rustc_ast = { path = "../rustc_ast" }
rustc_ast_ir = { path = "../rustc_ast_ir" }
rustc_attr = { path = "../rustc_attr" }
rustc_attr_parsing = { path = "../rustc_attr_parsing" }
rustc_data_structures = { path = "../rustc_data_structures" }
rustc_errors = { path = "../rustc_errors" }
rustc_fluent_macro = { path = "../rustc_fluent_macro" }

View file

@ -16,7 +16,7 @@ use rustc_session::lint::builtin::UNKNOWN_OR_MALFORMED_DIAGNOSTIC_ATTRIBUTES;
use rustc_span::Span;
use rustc_span::symbol::{Symbol, kw, sym};
use tracing::{debug, info};
use {rustc_attr as attr, rustc_hir as hir};
use {rustc_attr_parsing as attr, rustc_hir as hir};
use super::{ObligationCauseCode, PredicateObligation};
use crate::error_reporting::TypeErrCtxt;

View file

@ -55,7 +55,7 @@ use rustc_trait_selection::traits::wf::object_region_bounds;
use thin_vec::ThinVec;
use tracing::{debug, instrument};
use utils::*;
use {rustc_ast as ast, rustc_attr as attr, rustc_hir as hir};
use {rustc_ast as ast, rustc_hir as hir};
pub(crate) use self::types::*;
pub(crate) use self::utils::{krate, register_res, synthesize_auto_trait_and_blanket_impls};
@ -2895,7 +2895,7 @@ fn clean_extern_crate<'tcx>(
&& attrs.iter().any(|a| {
a.has_name(sym::doc)
&& match a.meta_item_list() {
Some(l) => attr::list_contains_name(&l, sym::inline),
Some(l) => ast::attr::list_contains_name(&l, sym::inline),
None => false,
}
})
@ -3000,8 +3000,8 @@ fn clean_use_statement_inner<'tcx>(
a.has_name(sym::doc)
&& match a.meta_item_list() {
Some(l) => {
attr::list_contains_name(&l, sym::no_inline)
|| attr::list_contains_name(&l, sym::hidden)
ast::attr::list_contains_name(&l, sym::no_inline)
|| ast::attr::list_contains_name(&l, sym::hidden)
}
None => false,
}

View file

@ -6,7 +6,7 @@ use std::{fmt, iter};
use arrayvec::ArrayVec;
use rustc_abi::{ExternAbi, VariantIdx};
use rustc_attr::{ConstStability, Deprecation, Stability, StableSince};
use rustc_attr_parsing::{ConstStability, Deprecation, Stability, StableSince};
use rustc_data_structures::fx::{FxHashSet, FxIndexMap, FxIndexSet};
use rustc_hir::def::{CtorKind, DefKind, Res};
use rustc_hir::def_id::{CrateNum, DefId, LOCAL_CRATE, LocalDefId};

View file

@ -581,8 +581,7 @@ pub(crate) fn attrs_have_doc_flag<'a>(
mut attrs: impl Iterator<Item = &'a hir::Attribute>,
flag: Symbol,
) -> bool {
attrs
.any(|attr| attr.meta_item_list().is_some_and(|l| rustc_attr::list_contains_name(&l, flag)))
attrs.any(|attr| attr.meta_item_list().is_some_and(|l| ast::attr::list_contains_name(&l, flag)))
}
/// A link to `doc.rust-lang.org` that includes the channel name. Use this instead of manual links

View file

@ -15,7 +15,7 @@ use std::iter::{self, once};
use itertools::Itertools;
use rustc_abi::ExternAbi;
use rustc_attr::{ConstStability, StabilityLevel, StableSince};
use rustc_attr_parsing::{ConstStability, StabilityLevel, StableSince};
use rustc_data_structures::captures::Captures;
use rustc_data_structures::fx::FxHashSet;
use rustc_hir as hir;

View file

@ -44,14 +44,15 @@ use std::path::PathBuf;
use std::{fs, str};
use rinja::Template;
use rustc_attr::{ConstStability, DeprecatedSince, Deprecation, StabilityLevel, StableSince};
use rustc_attr_parsing::{
ConstStability, DeprecatedSince, Deprecation, RustcVersion, StabilityLevel, StableSince,
};
use rustc_data_structures::captures::Captures;
use rustc_data_structures::fx::{FxHashSet, FxIndexMap, FxIndexSet};
use rustc_hir::Mutability;
use rustc_hir::def_id::{DefId, DefIdSet};
use rustc_middle::ty::print::PrintTraitRefExt;
use rustc_middle::ty::{self, TyCtxt};
use rustc_session::RustcVersion;
use rustc_span::symbol::{Symbol, sym};
use rustc_span::{BytePos, DUMMY_SP, FileName, RealFileName};
use serde::ser::SerializeMap;

View file

@ -6,7 +6,7 @@
use rustc_abi::ExternAbi;
use rustc_ast::ast;
use rustc_attr::DeprecatedSince;
use rustc_attr_parsing::DeprecatedSince;
use rustc_hir::def::{CtorKind, DefKind};
use rustc_hir::def_id::DefId;
use rustc_metadata::rendered_const;
@ -215,8 +215,8 @@ where
}
}
pub(crate) fn from_deprecation(deprecation: rustc_attr::Deprecation) -> Deprecation {
let rustc_attr::Deprecation { since, note, suggestion: _ } = deprecation;
pub(crate) fn from_deprecation(deprecation: rustc_attr_parsing::Deprecation) -> Deprecation {
let rustc_attr_parsing::Deprecation { since, note, suggestion: _ } = deprecation;
let since = match since {
DeprecatedSince::RustcVersion(version) => Some(version.to_string()),
DeprecatedSince::Future => Some("TBD".to_owned()),

View file

@ -36,7 +36,7 @@ extern crate pulldown_cmark;
extern crate rustc_abi;
extern crate rustc_ast;
extern crate rustc_ast_pretty;
extern crate rustc_attr;
extern crate rustc_attr_parsing;
extern crate rustc_data_structures;
extern crate rustc_driver;
extern crate rustc_errors;

View file

@ -6,7 +6,7 @@
//! [`core::error`] module is marked as stable since 1.81.0, so we want to show
//! [`core::error::Error`] as stable since 1.81.0 as well.
use rustc_attr::{Stability, StabilityLevel};
use rustc_attr_parsing::{Stability, StabilityLevel};
use rustc_hir::def_id::CRATE_DEF_ID;
use crate::clean::{Crate, Item, ItemId, ItemKind};

View file

@ -2,9 +2,10 @@ use clippy_config::Conf;
use clippy_utils::diagnostics::span_lint_and_help;
use clippy_utils::msrvs::{self, Msrv};
use rustc_ast::ast::{FloatTy, LitFloatType, LitKind};
use rustc_attr_parsing::RustcVersion;
use rustc_hir::{Expr, ExprKind};
use rustc_lint::{LateContext, LateLintPass};
use rustc_session::{RustcVersion, impl_lint_pass};
use rustc_session::impl_lint_pass;
use rustc_span::symbol;
use std::f64::consts as f64;

View file

@ -9,7 +9,8 @@ use rustc_errors::Applicability;
use rustc_hir::intravisit::{FnKind, Visitor, walk_expr};
use rustc_hir::{BinOpKind, Body, Expr, ExprKind, FnDecl, UnOp};
use rustc_lint::{LateContext, LateLintPass, Level};
use rustc_session::{RustcVersion, impl_lint_pass};
use rustc_attr_parsing::RustcVersion;
use rustc_session::impl_lint_pass;
use rustc_span::def_id::LocalDefId;
use rustc_span::{Span, sym};

View file

@ -2,12 +2,12 @@ use clippy_config::Conf;
use clippy_utils::diagnostics::span_lint;
use clippy_utils::is_in_test;
use clippy_utils::msrvs::Msrv;
use rustc_attr::{StabilityLevel, StableSince};
use rustc_attr_parsing::{StabilityLevel, StableSince, RustcVersion};
use rustc_data_structures::fx::FxHashMap;
use rustc_hir::{Expr, ExprKind, HirId};
use rustc_lint::{LateContext, LateLintPass};
use rustc_middle::ty::TyCtxt;
use rustc_session::{RustcVersion, impl_lint_pass};
use rustc_session::impl_lint_pass;
use rustc_span::def_id::DefId;
use rustc_span::{ExpnKind, Span};

Some files were not shown because too many files have changed in this diff Show more