Port #[export_stable] to the new attribute system

This commit is contained in:
Pavel Grigorenko 2025-06-16 22:11:41 +03:00
parent c720f49c46
commit bb8b741c32
8 changed files with 34 additions and 13 deletions

View file

@ -248,6 +248,9 @@ pub enum AttributeKind {
span: Span,
},
/// Represents `#[export_stable]`.
ExportStable,
/// Represents `#[ignore]`
Ignore {
span: Span,

View file

@ -26,6 +26,7 @@ impl AttributeKind {
Deprecation { .. } => Yes,
DocComment { .. } => Yes,
ExportName { .. } => Yes,
ExportStable => No,
Ignore { .. } => No,
Inline(..) => No,
LinkName { .. } => Yes,

View file

@ -1,9 +1,11 @@
use rustc_attr_data_structures::AttributeKind;
use rustc_attr_data_structures::AttributeKind::{LinkName, LinkSection};
use rustc_feature::{AttributeTemplate, template};
use rustc_span::{Symbol, sym};
use rustc_span::{Span, Symbol, sym};
use crate::attributes::{AttributeOrder, OnDuplicate, SingleAttributeParser};
use crate::attributes::{
AttributeOrder, NoArgsAttributeParser, OnDuplicate, SingleAttributeParser,
};
use crate::context::{AcceptContext, Stage};
use crate::parser::ArgParser;
use crate::session_diagnostics::NullOnLinkSection;
@ -57,3 +59,10 @@ impl<S: Stage> SingleAttributeParser<S> for LinkSectionParser {
Some(LinkSection { name, span: cx.attr_span })
}
}
pub(crate) struct ExportStableParser;
impl<S: Stage> NoArgsAttributeParser<S> for ExportStableParser {
const PATH: &[Symbol] = &[sym::export_stable];
const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Warn;
const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::ExportStable;
}

View file

@ -22,7 +22,7 @@ use crate::attributes::codegen_attrs::{
use crate::attributes::confusables::ConfusablesParser;
use crate::attributes::deprecation::DeprecationParser;
use crate::attributes::inline::{InlineParser, RustcForceInlineParser};
use crate::attributes::link_attrs::{LinkNameParser, LinkSectionParser};
use crate::attributes::link_attrs::{ExportStableParser, LinkNameParser, LinkSectionParser};
use crate::attributes::lint_helpers::{AsPtrParser, PassByValueParser, PubTransparentParser};
use crate::attributes::loop_match::{ConstContinueParser, LoopMatchParser};
use crate::attributes::must_use::MustUseParser;
@ -145,6 +145,7 @@ attribute_parsers!(
Single<WithoutArgs<ColdParser>>,
Single<WithoutArgs<ConstContinueParser>>,
Single<WithoutArgs<ConstStabilityIndirectParser>>,
Single<WithoutArgs<ExportStableParser>>,
Single<WithoutArgs<LoopMatchParser>>,
Single<WithoutArgs<MayDangleParser>>,
Single<WithoutArgs<NoImplicitPreludeParser>>,

View file

@ -271,6 +271,7 @@ pub fn check_builtin_meta_item(
if matches!(
name,
sym::inline
| sym::export_stable
| sym::may_dangle
| sym::rustc_as_ptr
| sym::rustc_pub_transparent

View file

@ -204,6 +204,9 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
AttributeKind::RustcLayoutScalarValidRangeStart(_num, attr_span)
| AttributeKind::RustcLayoutScalarValidRangeEnd(_num, attr_span),
) => self.check_rustc_layout_scalar_valid_range(*attr_span, span, target),
Attribute::Parsed(AttributeKind::ExportStable) => {
// handled in `check_export`
}
Attribute::Parsed(
AttributeKind::BodyStability { .. }
| AttributeKind::ConstStabilityIndirect
@ -346,7 +349,6 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
| sym::cfg_attr
| sym::cfg_trace
| sym::cfg_attr_trace
| sym::export_stable // handled in `check_export`
// need to be fixed
| sym::cfi_encoding // FIXME(cfi_encoding)
| sym::pointee // FIXME(derive_coerce_pointee)

View file

@ -2,6 +2,7 @@ use std::iter;
use std::ops::ControlFlow;
use rustc_abi::ExternAbi;
use rustc_attr_data_structures::{AttributeKind, find_attr};
use rustc_data_structures::fx::{FxIndexMap, FxIndexSet};
use rustc_hir as hir;
use rustc_hir::def::DefKind;
@ -14,7 +15,7 @@ use rustc_middle::ty::{
self, Ty, TyCtxt, TypeSuperVisitable, TypeVisitable, TypeVisitor, Visibility,
};
use rustc_session::config::CrateType;
use rustc_span::{Span, sym};
use rustc_span::Span;
use crate::errors::UnexportableItem;
@ -44,7 +45,7 @@ impl<'tcx> ExportableItemCollector<'tcx> {
}
fn item_is_exportable(&self, def_id: LocalDefId) -> bool {
let has_attr = self.tcx.has_attr(def_id, sym::export_stable);
let has_attr = find_attr!(self.tcx.get_all_attrs(def_id), AttributeKind::ExportStable);
if !self.in_exportable_mod && !has_attr {
return false;
}
@ -80,7 +81,7 @@ impl<'tcx> ExportableItemCollector<'tcx> {
fn walk_item_with_mod(&mut self, item: &'tcx hir::Item<'tcx>) {
let def_id = item.hir_id().owner.def_id;
let old_exportable_mod = self.in_exportable_mod;
if self.tcx.get_attr(def_id, sym::export_stable).is_some() {
if find_attr!(self.tcx.get_all_attrs(def_id), AttributeKind::ExportStable) {
self.in_exportable_mod = true;
}
let old_seen_exportable_in_mod = std::mem::replace(&mut self.seen_exportable_in_mod, false);

View file

@ -40,12 +40,6 @@ error: malformed `crate_name` attribute input
LL | #[crate_name]
| ^^^^^^^^^^^^^ help: must be of the form: `#[crate_name = "name"]`
error: malformed `export_stable` attribute input
--> $DIR/malformed-attrs.rs:81:1
|
LL | #[export_stable = 1]
| ^^^^^^^^^^^^^^^^^^^^ help: must be of the form: `#[export_stable]`
error: malformed `coverage` attribute input
--> $DIR/malformed-attrs.rs:90:1
|
@ -481,6 +475,15 @@ LL | #[target_feature]
| expected this to be a list
| help: must be of the form: `#[target_feature(enable = "feat1, feat2")]`
error[E0565]: malformed `export_stable` attribute input
--> $DIR/malformed-attrs.rs:81:1
|
LL | #[export_stable = 1]
| ^^^^^^^^^^^^^^^^---^
| | |
| | didn't expect any arguments here
| help: must be of the form: `#[export_stable]`
error[E0539]: malformed `link_name` attribute input
--> $DIR/malformed-attrs.rs:86:1
|