Rollup merge of #147532 - JonathanBrouwer:cfg_attr2, r=jdonszelmann

Port `#[cfg_attr]` to the new attribute parsing infrastructure

This work in progress, not ready for review.
PR mostly for ci/perf runs
This commit is contained in:
Matthias Krüger
2025-10-18 15:09:03 +02:00
committed by GitHub
30 changed files with 626 additions and 237 deletions

View File

@@ -3351,34 +3351,6 @@ pub(crate) struct KwBadCase<'a> {
pub kw: &'a str,
}
#[derive(Diagnostic)]
#[diag(parse_cfg_attr_bad_delim)]
pub(crate) struct CfgAttrBadDelim {
#[primary_span]
pub span: Span,
#[subdiagnostic]
pub sugg: MetaBadDelimSugg,
}
#[derive(Subdiagnostic)]
#[multipart_suggestion(parse_meta_bad_delim_suggestion, applicability = "machine-applicable")]
pub(crate) struct MetaBadDelimSugg {
#[suggestion_part(code = "(")]
pub open: Span,
#[suggestion_part(code = ")")]
pub close: Span,
}
#[derive(Diagnostic)]
#[diag(parse_malformed_cfg_attr)]
#[note]
pub(crate) struct MalformedCfgAttr {
#[primary_span]
#[suggestion(style = "verbose", code = "{sugg}")]
pub span: Span,
pub sugg: &'static str,
}
#[derive(Diagnostic)]
#[diag(parse_unknown_builtin_construct)]
pub(crate) struct UnknownBuiltinConstruct {

View File

@@ -18,8 +18,8 @@ use std::str::Utf8Error;
use std::sync::Arc;
use rustc_ast as ast;
use rustc_ast::tokenstream::{DelimSpan, TokenStream};
use rustc_ast::{AttrItem, Attribute, MetaItemInner, token};
use rustc_ast::token;
use rustc_ast::tokenstream::TokenStream;
use rustc_ast_pretty::pprust;
use rustc_errors::{Diag, EmissionGuarantee, FatalError, PResult, pluralize};
use rustc_session::parse::ParseSess;
@@ -32,7 +32,6 @@ pub const MACRO_ARGUMENTS: Option<&str> = Some("macro arguments");
#[macro_use]
pub mod parser;
use parser::Parser;
use rustc_ast::token::Delimiter;
use crate::lexer::StripTokens;
@@ -230,45 +229,3 @@ pub fn fake_token_stream_for_crate(psess: &ParseSess, krate: &ast::Crate) -> Tok
Some(krate.spans.inner_span),
))
}
pub fn parse_cfg_attr(
cfg_attr: &Attribute,
psess: &ParseSess,
) -> Option<(MetaItemInner, Vec<(AttrItem, Span)>)> {
const CFG_ATTR_GRAMMAR_HELP: &str = "#[cfg_attr(condition, attribute, other_attribute, ...)]";
const CFG_ATTR_NOTE_REF: &str = "for more information, visit \
<https://doc.rust-lang.org/reference/conditional-compilation.html#the-cfg_attr-attribute>";
match cfg_attr.get_normal_item().args {
ast::AttrArgs::Delimited(ast::DelimArgs { dspan, delim, ref tokens })
if !tokens.is_empty() =>
{
check_cfg_attr_bad_delim(psess, dspan, delim);
match parse_in(psess, tokens.clone(), "`cfg_attr` input", |p| p.parse_cfg_attr()) {
Ok(r) => return Some(r),
Err(e) => {
e.with_help(format!("the valid syntax is `{CFG_ATTR_GRAMMAR_HELP}`"))
.with_note(CFG_ATTR_NOTE_REF)
.emit();
}
}
}
_ => {
psess.dcx().emit_err(errors::MalformedCfgAttr {
span: cfg_attr.span,
sugg: CFG_ATTR_GRAMMAR_HELP,
});
}
}
None
}
fn check_cfg_attr_bad_delim(psess: &ParseSess, span: DelimSpan, delim: Delimiter) {
if let Delimiter::Parenthesis = delim {
return;
}
psess.dcx().emit_err(errors::CfgAttrBadDelim {
span: span.entire(),
sugg: errors::MetaBadDelimSugg { open: span.open, close: span.close },
});
}

View File

@@ -377,27 +377,6 @@ impl<'a> Parser<'a> {
Ok(lit)
}
/// Parses `cfg_attr(pred, attr_item_list)` where `attr_item_list` is comma-delimited.
pub fn parse_cfg_attr(
&mut self,
) -> PResult<'a, (ast::MetaItemInner, Vec<(ast::AttrItem, Span)>)> {
let cfg_predicate = self.parse_meta_item_inner()?;
self.expect(exp!(Comma))?;
// Presumably, the majority of the time there will only be one attr.
let mut expanded_attrs = Vec::with_capacity(1);
while self.token != token::Eof {
let lo = self.token.span;
let item = self.parse_attr_item(ForceCollect::Yes)?;
expanded_attrs.push((item, lo.to(self.prev_token.span)));
if !self.eat(exp!(Comma)) {
break;
}
}
Ok((cfg_predicate, expanded_attrs))
}
/// Matches `COMMASEP(meta_item_inner)`.
pub fn parse_meta_seq_top(&mut self) -> PResult<'a, ThinVec<ast::MetaItemInner>> {
// Presumably, the majority of the time there will only be one attr.