From 4b35cde904c1015df42b2c63244c1db1ed51fff9 Mon Sep 17 00:00:00 2001 From: Jana Dönszelmann Date: Mon, 11 Aug 2025 11:46:30 +0200 Subject: Support lints in early attribute parsing --- compiler/rustc_attr_parsing/src/interface.rs | 32 ++++++++++++++++++---- compiler/rustc_attr_parsing/src/lints.rs | 6 ++-- .../rustc_attr_parsing/src/session_diagnostics.rs | 6 ++-- 3 files changed, 32 insertions(+), 12 deletions(-) (limited to 'compiler/rustc_attr_parsing/src') diff --git a/compiler/rustc_attr_parsing/src/interface.rs b/compiler/rustc_attr_parsing/src/interface.rs index b4222e41b71..60523c2877c 100644 --- a/compiler/rustc_attr_parsing/src/interface.rs +++ b/compiler/rustc_attr_parsing/src/interface.rs @@ -50,6 +50,27 @@ impl<'sess> AttributeParser<'sess, Early> { target_span: Span, target_node_id: NodeId, features: Option<&'sess Features>, + ) -> Option { + Self::parse_limited_should_emit( + sess, + attrs, + sym, + target_span, + target_node_id, + features, + ShouldEmit::Nothing, + ) + } + + /// Usually you want `parse_limited`, which defaults to no errors. + pub fn parse_limited_should_emit( + sess: &'sess Session, + attrs: &[ast::Attribute], + sym: Symbol, + target_span: Span, + target_node_id: NodeId, + features: Option<&'sess Features>, + should_emit: ShouldEmit, ) -> Option { let mut parsed = Self::parse_limited_all( sess, @@ -59,7 +80,7 @@ impl<'sess> AttributeParser<'sess, Early> { target_span, target_node_id, features, - ShouldEmit::Nothing, + should_emit, ); assert!(parsed.len() <= 1); parsed.pop() @@ -84,9 +105,8 @@ impl<'sess> AttributeParser<'sess, Early> { target, OmitDoc::Skip, std::convert::identity, - |_lint| { - // FIXME: Can't emit lints here for now - // This branch can be hit when an attribute produces a warning during early parsing (such as attributes on macro calls) + |lint| { + crate::lints::emit_attribute_lint(&lint, sess); }, ) } @@ -121,8 +141,8 @@ impl<'sess> AttributeParser<'sess, Early> { cx: &mut parser, target_span, target_id: target_node_id, - emit_lint: &mut |_lint| { - panic!("can't emit lints here for now (nothing uses this atm)"); + emit_lint: &mut |lint| { + crate::lints::emit_attribute_lint(&lint, sess); }, }, attr_span: attr.span, diff --git a/compiler/rustc_attr_parsing/src/lints.rs b/compiler/rustc_attr_parsing/src/lints.rs index 7030f28f23c..069478e7f0c 100644 --- a/compiler/rustc_attr_parsing/src/lints.rs +++ b/compiler/rustc_attr_parsing/src/lints.rs @@ -1,13 +1,13 @@ use std::borrow::Cow; use rustc_errors::{DiagArgValue, LintEmitter}; +use rustc_hir::Target; use rustc_hir::lints::{AttributeLint, AttributeLintKind}; -use rustc_hir::{HirId, Target}; use rustc_span::sym; use crate::session_diagnostics; -pub fn emit_attribute_lint(lint: &AttributeLint, lint_emitter: L) { +pub fn emit_attribute_lint(lint: &AttributeLint, lint_emitter: L) { let AttributeLint { id, span, kind } = lint; match kind { @@ -51,7 +51,7 @@ pub fn emit_attribute_lint(lint: &AttributeLint, lint_emi *id, *span, session_diagnostics::InvalidTargetLint { - name, + name: name.clone(), target: target.plural_name(), applied: DiagArgValue::StrListSepByAnd( applied.into_iter().map(|i| Cow::Owned(i.to_string())).collect(), diff --git a/compiler/rustc_attr_parsing/src/session_diagnostics.rs b/compiler/rustc_attr_parsing/src/session_diagnostics.rs index 2192e8f8f83..72bee0ddfbf 100644 --- a/compiler/rustc_attr_parsing/src/session_diagnostics.rs +++ b/compiler/rustc_attr_parsing/src/session_diagnostics.rs @@ -484,9 +484,9 @@ pub(crate) struct EmptyAttributeList { #[diag(attr_parsing_invalid_target_lint)] #[warning] #[help] -pub(crate) struct InvalidTargetLint<'a> { - pub name: &'a AttrPath, - pub target: &'a str, +pub(crate) struct InvalidTargetLint { + pub name: AttrPath, + pub target: &'static str, pub applied: DiagArgValue, pub only: &'static str, #[suggestion(code = "", applicability = "machine-applicable", style = "tool-only")] -- cgit 1.4.1-3-g733a5