From da8d6bbd5043e8f4ea83a2431117c32b0339ac54 Mon Sep 17 00:00:00 2001 From: Pavel Grigorenko Date: Sat, 14 Jun 2025 13:01:15 +0300 Subject: [PATCH] Port `#[rustc_as_ptr]` to the new attribute system --- .../src/attributes.rs | 3 +++ .../src/attributes/lint_helpers.rs | 21 ++++++++++++++++ .../rustc_attr_parsing/src/attributes/mod.rs | 1 + compiler/rustc_attr_parsing/src/context.rs | 2 ++ compiler/rustc_lint/src/dangling.rs | 3 ++- compiler/rustc_passes/src/check_attr.rs | 24 +++++++++---------- 6 files changed, 41 insertions(+), 13 deletions(-) create mode 100644 compiler/rustc_attr_parsing/src/attributes/lint_helpers.rs diff --git a/compiler/rustc_attr_data_structures/src/attributes.rs b/compiler/rustc_attr_data_structures/src/attributes.rs index 845e4d5e5d0fa..32c410cc014b5 100644 --- a/compiler/rustc_attr_data_structures/src/attributes.rs +++ b/compiler/rustc_attr_data_structures/src/attributes.rs @@ -158,6 +158,9 @@ pub enum AttributeKind { /// Represents `#[allow_internal_unstable]`. AllowInternalUnstable(ThinVec<(Symbol, Span)>), + /// Represents `#[rustc_as_ptr]` (used by the `dangling_pointers_from_temporaries` lint). + AsPtr(Span), + /// Represents `#[rustc_default_body_unstable]`. BodyStability { stability: DefaultBodyStability, diff --git a/compiler/rustc_attr_parsing/src/attributes/lint_helpers.rs b/compiler/rustc_attr_parsing/src/attributes/lint_helpers.rs new file mode 100644 index 0000000000000..32a20d4c5b5e4 --- /dev/null +++ b/compiler/rustc_attr_parsing/src/attributes/lint_helpers.rs @@ -0,0 +1,21 @@ +use rustc_attr_data_structures::AttributeKind; +use rustc_span::{Symbol, sym}; + +use crate::attributes::{AttributeOrder, OnDuplicate, SingleAttributeParser}; +use crate::context::{AcceptContext, Stage}; +use crate::parser::ArgParser; + +pub(crate) struct AsPtrParser; + +impl SingleAttributeParser for AsPtrParser { + const PATH: &[Symbol] = &[sym::rustc_as_ptr]; + + const ATTRIBUTE_ORDER: AttributeOrder = AttributeOrder::KeepFirst; + + const ON_DUPLICATE: OnDuplicate = OnDuplicate::Error; + + fn convert(cx: &mut AcceptContext<'_, '_, S>, _args: &ArgParser<'_>) -> Option { + // FIXME: check that there's no args (this is currently checked elsewhere) + Some(AttributeKind::AsPtr(cx.attr_span)) + } +} diff --git a/compiler/rustc_attr_parsing/src/attributes/mod.rs b/compiler/rustc_attr_parsing/src/attributes/mod.rs index caf55e6685efc..df488c89a34fa 100644 --- a/compiler/rustc_attr_parsing/src/attributes/mod.rs +++ b/compiler/rustc_attr_parsing/src/attributes/mod.rs @@ -29,6 +29,7 @@ pub(crate) mod allow_unstable; pub(crate) mod cfg; pub(crate) mod confusables; pub(crate) mod deprecation; +pub(crate) mod lint_helpers; pub(crate) mod repr; pub(crate) mod stability; pub(crate) mod transparency; diff --git a/compiler/rustc_attr_parsing/src/context.rs b/compiler/rustc_attr_parsing/src/context.rs index 47f72232828ee..3193d8975e9fe 100644 --- a/compiler/rustc_attr_parsing/src/context.rs +++ b/compiler/rustc_attr_parsing/src/context.rs @@ -18,6 +18,7 @@ use rustc_span::{DUMMY_SP, ErrorGuaranteed, Span, Symbol, sym}; use crate::attributes::allow_unstable::{AllowConstFnUnstableParser, AllowInternalUnstableParser}; use crate::attributes::confusables::ConfusablesParser; use crate::attributes::deprecation::DeprecationParser; +use crate::attributes::lint_helpers::AsPtrParser; use crate::attributes::repr::ReprParser; use crate::attributes::stability::{ BodyStabilityParser, ConstStabilityIndirectParser, ConstStabilityParser, StabilityParser, @@ -102,6 +103,7 @@ attribute_parsers!( // tidy-alphabetical-end // tidy-alphabetical-start + Single, Single, Single, Single, diff --git a/compiler/rustc_lint/src/dangling.rs b/compiler/rustc_lint/src/dangling.rs index 91c7922638de5..c737919db9c2d 100644 --- a/compiler/rustc_lint/src/dangling.rs +++ b/compiler/rustc_lint/src/dangling.rs @@ -1,4 +1,5 @@ use rustc_ast::visit::{visit_opt, walk_list}; +use rustc_attr_data_structures::{AttributeKind, find_attr}; use rustc_hir::def_id::LocalDefId; use rustc_hir::intravisit::{FnKind, Visitor, walk_expr}; use rustc_hir::{Block, Body, Expr, ExprKind, FnDecl, LangItem}; @@ -133,7 +134,7 @@ fn lint_expr(cx: &LateContext<'_>, expr: &Expr<'_>) { && let ty = cx.typeck_results().expr_ty(receiver) && owns_allocation(cx.tcx, ty) && let Some(fn_id) = cx.typeck_results().type_dependent_def_id(expr.hir_id) - && cx.tcx.has_attr(fn_id, sym::rustc_as_ptr) + && find_attr!(cx.tcx.get_all_attrs(fn_id), AttributeKind::AsPtr(_)) { // FIXME: use `emit_node_lint` when `#[primary_span]` is added. cx.tcx.emit_node_span_lint( diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs index 4e2be8ff0b817..dddbf65db72ea 100644 --- a/compiler/rustc_passes/src/check_attr.rs +++ b/compiler/rustc_passes/src/check_attr.rs @@ -147,6 +147,9 @@ impl<'tcx> CheckAttrVisitor<'tcx> { | AttributeKind::ConstStabilityIndirect | AttributeKind::MacroTransparency(_), ) => { /* do nothing */ } + Attribute::Parsed(AttributeKind::AsPtr(attr_span)) => { + self.check_applied_to_fn_or_method(hir_id, *attr_span, span, target) + } Attribute::Unparsed(_) => { match attr.path().as_slice() { [sym::diagnostic, sym::do_not_recommend, ..] => { @@ -188,26 +191,23 @@ impl<'tcx> CheckAttrVisitor<'tcx> { self.check_rustc_std_internal_symbol(attr, span, target) } [sym::naked, ..] => self.check_naked(hir_id, attr, span, target, attrs), - [sym::rustc_as_ptr, ..] => { - self.check_applied_to_fn_or_method(hir_id, attr, span, target) - } [sym::rustc_no_implicit_autorefs, ..] => { - self.check_applied_to_fn_or_method(hir_id, attr, span, target) + self.check_applied_to_fn_or_method(hir_id, attr.span(), span, target) } [sym::rustc_never_returns_null_ptr, ..] => { - self.check_applied_to_fn_or_method(hir_id, attr, span, target) + self.check_applied_to_fn_or_method(hir_id, attr.span(), span, target) } [sym::rustc_legacy_const_generics, ..] => { self.check_rustc_legacy_const_generics(hir_id, attr, span, target, item) } [sym::rustc_lint_query_instability, ..] => { - self.check_applied_to_fn_or_method(hir_id, attr, span, target) + self.check_applied_to_fn_or_method(hir_id, attr.span(), span, target) } [sym::rustc_lint_untracked_query_information, ..] => { - self.check_applied_to_fn_or_method(hir_id, attr, span, target) + self.check_applied_to_fn_or_method(hir_id, attr.span(), span, target) } [sym::rustc_lint_diagnostics, ..] => { - self.check_applied_to_fn_or_method(hir_id, attr, span, target) + self.check_applied_to_fn_or_method(hir_id, attr.span(), span, target) } [sym::rustc_lint_opt_ty, ..] => self.check_rustc_lint_opt_ty(attr, span, target), [sym::rustc_lint_opt_deny_field_access, ..] => { @@ -1825,15 +1825,15 @@ impl<'tcx> CheckAttrVisitor<'tcx> { fn check_applied_to_fn_or_method( &self, hir_id: HirId, - attr: &Attribute, - span: Span, + attr_span: Span, + defn_span: Span, target: Target, ) { let is_function = matches!(target, Target::Fn | Target::Method(..)); if !is_function { self.dcx().emit_err(errors::AttrShouldBeAppliedToFn { - attr_span: attr.span(), - defn_span: span, + attr_span, + defn_span, on_crate: hir_id == CRATE_HIR_ID, }); }