Rollup merge of #142539 - GrigorenkoPV:attributes/may_dangle, r=jdonszelmann

Port `#[may_dangle]` to the new attribute system

Very similar to rust-lang/rust#142498.

This is a part of rust-lang/rust#131229, so
r? `@jdonszelmann`
This commit is contained in:
Jana Dönszelmann
2025-06-21 15:32:05 +02:00
committed by GitHub
6 changed files with 33 additions and 3 deletions

View File

@@ -233,8 +233,13 @@ pub enum AttributeKind {
/// Represents `#[rustc_macro_transparency]`.
MacroTransparency(Transparency),
/// Represents [`#[may_dangle]`](https://std-dev-guide.rust-lang.org/tricky/may-dangle.html).
MayDangle(Span),
/// Represents `#[optimize(size|speed)]`
Optimize(OptimizeAttr, Span),
/// Represents [`#[repr]`](https://doc.rust-lang.org/stable/reference/type-layout.html#representations).
Repr(ThinVec<(ReprAttr, Span)>),

View File

@@ -34,6 +34,7 @@ pub(crate) mod deprecation;
pub(crate) mod inline;
pub(crate) mod lint_helpers;
pub(crate) mod repr;
pub(crate) mod semantics;
pub(crate) mod stability;
pub(crate) mod transparency;
pub(crate) mod util;

View File

@@ -0,0 +1,19 @@
use rustc_attr_data_structures::AttributeKind;
use rustc_feature::{AttributeTemplate, template};
use rustc_span::{Symbol, sym};
use crate::attributes::{AttributeOrder, OnDuplicate, SingleAttributeParser};
use crate::context::{AcceptContext, Stage};
use crate::parser::ArgParser;
pub(crate) struct MayDangleParser;
impl<S: Stage> SingleAttributeParser<S> for MayDangleParser {
const PATH: &[Symbol] = &[sym::may_dangle];
const ATTRIBUTE_ORDER: AttributeOrder = AttributeOrder::KeepFirst;
const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Warn;
const TEMPLATE: AttributeTemplate = template!(Word);
fn convert(cx: &mut AcceptContext<'_, '_, S>, _args: &ArgParser<'_>) -> Option<AttributeKind> {
Some(AttributeKind::MayDangle(cx.attr_span))
}
}

View File

@@ -21,6 +21,7 @@ use crate::attributes::deprecation::DeprecationParser;
use crate::attributes::inline::{InlineParser, RustcForceInlineParser};
use crate::attributes::lint_helpers::AsPtrParser;
use crate::attributes::repr::{AlignParser, ReprParser};
use crate::attributes::semantics::MayDangleParser;
use crate::attributes::stability::{
BodyStabilityParser, ConstStabilityIndirectParser, ConstStabilityParser, StabilityParser,
};
@@ -110,6 +111,7 @@ attribute_parsers!(
Single<ConstStabilityIndirectParser>,
Single<DeprecationParser>,
Single<InlineParser>,
Single<MayDangleParser>,
Single<OptimizeParser>,
Single<RustcForceInlineParser>,
Single<TransparencyParser>,

View File

@@ -1302,6 +1302,7 @@ impl AttributeExt for Attribute {
// FIXME: should not be needed anymore when all attrs are parsed
Attribute::Parsed(AttributeKind::Deprecation { span, .. }) => *span,
Attribute::Parsed(AttributeKind::DocComment { span, .. }) => *span,
Attribute::Parsed(AttributeKind::MayDangle(span)) => *span,
a => panic!("can't get the span of an arbitrary parsed attribute: {a:?}"),
}
}

View File

@@ -163,6 +163,9 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
Attribute::Parsed(AttributeKind::AsPtr(attr_span)) => {
self.check_applied_to_fn_or_method(hir_id, *attr_span, span, target)
}
&Attribute::Parsed(AttributeKind::MayDangle(attr_span)) => {
self.check_may_dangle(hir_id, attr_span)
}
Attribute::Unparsed(_) => {
match attr.path().as_slice() {
[sym::diagnostic, sym::do_not_recommend, ..] => {
@@ -236,7 +239,6 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
[sym::collapse_debuginfo, ..] => self.check_collapse_debuginfo(attr, span, target),
[sym::must_not_suspend, ..] => self.check_must_not_suspend(attr, span, target),
[sym::must_use, ..] => self.check_must_use(hir_id, attr, target),
[sym::may_dangle, ..] => self.check_may_dangle(hir_id, attr),
[sym::rustc_pass_by_value, ..] => self.check_pass_by_value(attr, span, target),
[sym::rustc_allow_incoherent_impl, ..] => {
self.check_allow_incoherent_impl(attr, span, target)
@@ -1619,7 +1621,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
}
/// Checks if `#[may_dangle]` is applied to a lifetime or type generic parameter in `Drop` impl.
fn check_may_dangle(&self, hir_id: HirId, attr: &Attribute) {
fn check_may_dangle(&self, hir_id: HirId, attr_span: Span) {
if let hir::Node::GenericParam(param) = self.tcx.hir_node(hir_id)
&& matches!(
param.kind,
@@ -1636,7 +1638,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
return;
}
self.dcx().emit_err(errors::InvalidMayDangle { attr_span: attr.span() });
self.dcx().emit_err(errors::InvalidMayDangle { attr_span });
}
/// Checks if `#[cold]` is applied to a non-function.