Skip to content

Commit 116543b

Browse files
committed
the fix
1 parent a5d4087 commit 116543b

File tree

2 files changed

+80
-3
lines changed

2 files changed

+80
-3
lines changed

compiler/rustc_expand/src/expand.rs

Lines changed: 49 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ use rustc_session::parse::feature_err;
2929
use rustc_session::{Limit, Session};
3030
use rustc_span::hygiene::SyntaxContext;
3131
use rustc_span::{ErrorGuaranteed, FileName, Ident, LocalExpnId, Span, Symbol, sym};
32-
use smallvec::SmallVec;
32+
use smallvec::{SmallVec, smallvec};
3333

3434
use crate::base::*;
3535
use crate::config::{StripUnconfigured, attr_into_trace};
@@ -46,6 +46,22 @@ use crate::module::{
4646
use crate::placeholders::{PlaceholderExpander, placeholder};
4747
use crate::stats::*;
4848

49+
/// Visitor to apply diagnostic attributes to expanded AST fragments
50+
struct DiagnosticAttrApplier {
51+
attrs: Vec<ast::Attribute>,
52+
}
53+
54+
impl MutVisitor for DiagnosticAttrApplier {
55+
fn flat_map_item(&mut self, item: Box<ast::Item>) -> SmallVec<[Box<ast::Item>; 1]> {
56+
let mut new_item = item;
57+
// Prepend diagnostic attributes to preserve their position
58+
let mut new_attrs = self.attrs.clone();
59+
new_attrs.extend(new_item.attrs);
60+
new_item.attrs = new_attrs.into();
61+
smallvec![new_item]
62+
}
63+
}
64+
4965
macro_rules! ast_fragments {
5066
(
5167
$($Kind:ident($AstTy:ty) {
@@ -818,12 +834,43 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
818834
let inner_tokens = attr_item.args.inner_tokens();
819835
match expander.expand(self.cx, span, inner_tokens, tokens) {
820836
Ok(tok_result) => {
821-
let fragment = self.parse_ast_fragment(
837+
// Extract diagnostic attributes from the original item before parsing
838+
let diagnostic_attrs = {
839+
match &item {
840+
Annotatable::Item(item) => item
841+
.attrs
842+
.iter()
843+
.filter(|attr| {
844+
attr.name().map_or(false, |name| {
845+
matches!(
846+
name,
847+
sym::expect
848+
| sym::allow
849+
| sym::warn
850+
| sym::deny
851+
| sym::forbid
852+
)
853+
})
854+
})
855+
.cloned()
856+
.collect::<Vec<_>>(),
857+
_ => Vec::new(),
858+
}
859+
};
860+
861+
let mut fragment = self.parse_ast_fragment(
822862
tok_result,
823863
fragment_kind,
824864
&attr_item.path,
825865
span,
826866
);
867+
868+
// Apply diagnostic attributes to the expanded fragment
869+
if !diagnostic_attrs.is_empty() {
870+
fragment.mut_visit_with(&mut DiagnosticAttrApplier {
871+
attrs: diagnostic_attrs,
872+
});
873+
}
827874
if macro_stats {
828875
update_attr_macro_stats(
829876
self.cx,

compiler/rustc_expand/src/proc_macro.rs

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ use rustc_parse::parser::{ForceCollect, Parser};
44
use rustc_session::config::ProcMacroExecutionStrategy;
55
use rustc_span::Span;
66
use rustc_span::profiling::SpannedEventArgRecorder;
7+
use rustc_span::sym;
78
use {rustc_ast as ast, rustc_proc_macro as pm};
89

910
use crate::base::{self, *};
@@ -122,6 +123,27 @@ impl MultiItemModifier for DeriveProcMacro {
122123
// Eventually we might remove the special case hard error check
123124
// altogether. See #73345.
124125
crate::base::ann_pretty_printing_compatibility_hack(&item, &ecx.sess.psess);
126+
127+
// Extract diagnostic attributes from the original item before expansion
128+
let diagnostic_attrs = {
129+
match &item {
130+
base::Annotatable::Item(item) => item
131+
.attrs
132+
.iter()
133+
.filter(|attr| {
134+
attr.name().map_or(false, |name| {
135+
matches!(
136+
name,
137+
sym::expect | sym::allow | sym::warn | sym::deny | sym::forbid
138+
)
139+
})
140+
})
141+
.cloned()
142+
.collect::<Vec<_>>(),
143+
_ => Vec::new(), // Other annotatable types don't have attributes
144+
}
145+
};
146+
125147
let input = item.to_tokens();
126148
let stream = {
127149
let _timer =
@@ -158,7 +180,15 @@ impl MultiItemModifier for DeriveProcMacro {
158180
loop {
159181
match parser.parse_item(ForceCollect::No) {
160182
Ok(None) => break,
161-
Ok(Some(item)) => {
183+
Ok(Some(mut item)) => {
184+
// Apply diagnostic attributes from the original item to the expanded item
185+
if !diagnostic_attrs.is_empty() {
186+
// Prepend diagnostic attributes to preserve their position
187+
let mut new_attrs = diagnostic_attrs.clone();
188+
new_attrs.extend(item.attrs);
189+
item.attrs = new_attrs.into();
190+
}
191+
162192
if is_stmt {
163193
items.push(Annotatable::Stmt(Box::new(ecx.stmt_item(span, item))));
164194
} else {

0 commit comments

Comments
 (0)