Port #[collapse_debuginfo] to the new attribute parsing system

This commit is contained in:
Jonathan Brouwer 2026-01-10 23:06:07 +01:00
parent 1b9ae9eddc
commit b5dd72d292
No known key found for this signature in database
GPG key ID: 13619B051B673C52
13 changed files with 98 additions and 109 deletions

View file

@ -1,4 +1,4 @@
use rustc_hir::attrs::MacroUseArgs;
use rustc_hir::attrs::{CollapseMacroDebuginfo, MacroUseArgs};
use rustc_session::lint::builtin::INVALID_MACRO_EXPORT_ARGUMENTS;
use super::prelude::*;
@ -163,3 +163,46 @@ impl<S: Stage> SingleAttributeParser<S> for MacroExportParser {
Some(AttributeKind::MacroExport { span: cx.attr_span, local_inner_macros })
}
}
pub(crate) struct CollapseDebugInfoParser;
impl<S: Stage> SingleAttributeParser<S> for CollapseDebugInfoParser {
const PATH: &[Symbol] = &[sym::collapse_debuginfo];
const ATTRIBUTE_ORDER: AttributeOrder = AttributeOrder::KeepOutermost;
const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Error;
const TEMPLATE: AttributeTemplate = template!(
List: &["no", "external", "yes"],
"https://doc.rust-lang.org/reference/attributes/debugger.html#the-collapse_debuginfo-attribute"
);
const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::MacroDef)]);
fn convert(cx: &mut AcceptContext<'_, '_, S>, args: &ArgParser) -> Option<AttributeKind> {
let Some(list) = args.list() else {
cx.expected_list(cx.attr_span, args);
return None;
};
let Some(single) = list.single() else {
cx.expected_single_argument(list.span);
return None;
};
let Some(mi) = single.meta_item() else {
cx.unexpected_literal(single.span());
return None;
};
if let Err(err) = mi.args().no_args() {
cx.expected_no_args(err);
}
let path = mi.path().word_sym();
let info = match path {
Some(sym::yes) => CollapseMacroDebuginfo::Yes,
Some(sym::no) => CollapseMacroDebuginfo::No,
Some(sym::external) => CollapseMacroDebuginfo::External,
_ => {
cx.expected_specific_argument(mi.span(), &[sym::yes, sym::no, sym::external]);
return None;
}
};
Some(AttributeKind::CollapseDebugInfo(info))
}
}

View file

@ -48,7 +48,8 @@ use crate::attributes::lint_helpers::{
};
use crate::attributes::loop_match::{ConstContinueParser, LoopMatchParser};
use crate::attributes::macro_attrs::{
AllowInternalUnsafeParser, MacroEscapeParser, MacroExportParser, MacroUseParser,
AllowInternalUnsafeParser, CollapseDebugInfoParser, MacroEscapeParser, MacroExportParser,
MacroUseParser,
};
use crate::attributes::must_use::MustUseParser;
use crate::attributes::no_implicit_prelude::NoImplicitPreludeParser;
@ -191,6 +192,7 @@ attribute_parsers!(
// tidy-alphabetical-start
Single<CfiEncodingParser>,
Single<CollapseDebugInfoParser>,
Single<CoverageParser>,
Single<CrateNameParser>,
Single<CustomMirParser>,

View file

@ -5,9 +5,6 @@ expand_attributes_on_expressions_experimental =
expand_cfg_attr_no_attributes = `#[cfg_attr]` does not expand to any attributes
expand_collapse_debuginfo_illegal =
illegal value for attribute #[collapse_debuginfo(no|external|yes)]
expand_count_repetition_misplaced =
`count` can not be placed inside the innermost repetition

View file

@ -6,7 +6,7 @@ use std::path::{Path, PathBuf};
use std::rc::Rc;
use std::sync::Arc;
use rustc_ast::attr::{AttributeExt, MarkedAttrs};
use rustc_ast::attr::MarkedAttrs;
use rustc_ast::token::MetaVarKind;
use rustc_ast::tokenstream::TokenStream;
use rustc_ast::visit::{AssocCtxt, Visitor};
@ -16,7 +16,7 @@ use rustc_data_structures::sync;
use rustc_errors::{BufferedEarlyLint, DiagCtxtHandle, ErrorGuaranteed, PResult};
use rustc_feature::Features;
use rustc_hir as hir;
use rustc_hir::attrs::{AttributeKind, CfgEntry, Deprecation};
use rustc_hir::attrs::{AttributeKind, CfgEntry, CollapseMacroDebuginfo, Deprecation};
use rustc_hir::def::MacroKinds;
use rustc_hir::limit::Limit;
use rustc_hir::{Stability, find_attr};
@ -24,7 +24,6 @@ use rustc_lint_defs::RegisteredTools;
use rustc_parse::MACRO_ARGUMENTS;
use rustc_parse::parser::{ForceCollect, Parser};
use rustc_session::Session;
use rustc_session::config::CollapseMacroDebuginfo;
use rustc_session::parse::ParseSess;
use rustc_span::def_id::{CrateNum, DefId, LocalDefId};
use rustc_span::edition::Edition;
@ -34,7 +33,6 @@ use rustc_span::{DUMMY_SP, FileName, Ident, Span, Symbol, kw, sym};
use smallvec::{SmallVec, smallvec};
use thin_vec::ThinVec;
use crate::base::ast::MetaItemInner;
use crate::errors;
use crate::expand::{self, AstFragment, Invocation};
use crate::mbe::macro_rules::ParserAnyMacro;
@ -887,25 +885,6 @@ impl SyntaxExtension {
}
}
fn collapse_debuginfo_by_name(
attr: &impl AttributeExt,
) -> Result<CollapseMacroDebuginfo, Span> {
let list = attr.meta_item_list();
let Some([MetaItemInner::MetaItem(item)]) = list.as_deref() else {
return Err(attr.span());
};
if !item.is_word() {
return Err(item.span);
}
match item.name() {
Some(sym::no) => Ok(CollapseMacroDebuginfo::No),
Some(sym::external) => Ok(CollapseMacroDebuginfo::External),
Some(sym::yes) => Ok(CollapseMacroDebuginfo::Yes),
_ => Err(item.path.span),
}
}
/// if-ext - if macro from different crate (related to callsite code)
/// | cmd \ attr | no | (unspecified) | external | yes |
/// | no | no | no | no | no |
@ -914,21 +893,15 @@ impl SyntaxExtension {
/// | yes | yes | yes | yes | yes |
fn get_collapse_debuginfo(sess: &Session, attrs: &[hir::Attribute], ext: bool) -> bool {
let flag = sess.opts.cg.collapse_macro_debuginfo;
let attr = ast::attr::find_by_name(attrs, sym::collapse_debuginfo)
.and_then(|attr| {
Self::collapse_debuginfo_by_name(attr)
.map_err(|span| {
sess.dcx().emit_err(errors::CollapseMacroDebuginfoIllegal { span })
})
.ok()
})
.unwrap_or_else(|| {
if find_attr!(attrs, AttributeKind::RustcBuiltinMacro { .. }) {
CollapseMacroDebuginfo::Yes
} else {
CollapseMacroDebuginfo::Unspecified
}
});
let attr =
if let Some(info) = find_attr!(attrs, AttributeKind::CollapseDebugInfo(info) => info) {
info.clone()
} else if find_attr!(attrs, AttributeKind::RustcBuiltinMacro { .. }) {
CollapseMacroDebuginfo::Yes
} else {
CollapseMacroDebuginfo::Unspecified
};
#[rustfmt::skip]
let collapse_table = [
[false, false, false, false],

View file

@ -78,13 +78,6 @@ pub(crate) struct ResolveRelativePath {
pub path: String,
}
#[derive(Diagnostic)]
#[diag(expand_collapse_debuginfo_illegal)]
pub(crate) struct CollapseMacroDebuginfoIllegal {
#[primary_span]
pub span: Span,
}
#[derive(Diagnostic)]
#[diag(expand_macro_const_stability)]
pub(crate) struct MacroConstStability {

View file

@ -568,6 +568,26 @@ impl<E: rustc_span::SpanEncoder> rustc_serialize::Encodable<E> for DocAttribute
}
}
/// How to perform collapse macros debug info
/// if-ext - if macro from different crate (related to callsite code)
/// | cmd \ attr | no | (unspecified) | external | yes |
/// | no | no | no | no | no |
/// | (unspecified) | no | no | if-ext | yes |
/// | external | no | if-ext | if-ext | yes |
/// | yes | yes | yes | yes | yes |
#[derive(Copy, Clone, Debug, Hash, PartialEq)]
#[derive(HashStable_Generic, Encodable, Decodable, PrintAttribute)]
pub enum CollapseMacroDebuginfo {
/// Don't collapse debuginfo for the macro
No = 0,
/// Unspecified value
Unspecified = 1,
/// Collapse debuginfo if the macro comes from a different crate
External = 2,
/// Collapse debuginfo for the macro
Yes = 3,
}
/// Represents parsed *built-in* inert attributes.
///
/// ## Overview
@ -664,6 +684,9 @@ pub enum AttributeKind {
/// Represents `#[cold]`.
Cold(Span),
/// Represents `#[collapse_debuginfo]`.
CollapseDebugInfo(CollapseMacroDebuginfo),
/// Represents `#[rustc_confusables]`.
Confusables {
symbols: ThinVec<Symbol>,

View file

@ -31,6 +31,7 @@ impl AttributeKind {
CfiEncoding { .. } => Yes,
Coinductive(..) => No,
Cold(..) => No,
CollapseDebugInfo(..) => Yes,
Confusables { .. } => Yes,
ConstContinue(..) => No,
ConstStability { .. } => Yes,

View file

@ -8,14 +8,14 @@ use rustc_abi::Align;
use rustc_data_structures::profiling::TimePassesFormat;
use rustc_errors::emitter::HumanReadableErrorType;
use rustc_errors::{ColorConfig, registry};
use rustc_hir::attrs::NativeLibKind;
use rustc_hir::attrs::{CollapseMacroDebuginfo, NativeLibKind};
use rustc_session::config::{
AnnotateMoves, AutoDiff, BranchProtection, CFGuard, Cfg, CollapseMacroDebuginfo, CoverageLevel,
CoverageOptions, DebugInfo, DumpMonoStatsFormat, ErrorOutputType, ExternEntry, ExternLocation,
Externs, FmtDebug, FunctionReturn, InliningThreshold, Input, InstrumentCoverage,
InstrumentXRay, LinkSelfContained, LinkerPluginLto, LocationDetail, LtoCli, MirIncludeSpans,
NextSolverConfig, Offload, Options, OutFileName, OutputType, OutputTypes, PAuthKey, PacRet,
Passes, PatchableFunctionEntry, Polonius, ProcMacroExecutionStrategy, Strip, SwitchWithOptPath,
AnnotateMoves, AutoDiff, BranchProtection, CFGuard, Cfg, CoverageLevel, CoverageOptions,
DebugInfo, DumpMonoStatsFormat, ErrorOutputType, ExternEntry, ExternLocation, Externs,
FmtDebug, FunctionReturn, InliningThreshold, Input, InstrumentCoverage, InstrumentXRay,
LinkSelfContained, LinkerPluginLto, LocationDetail, LtoCli, MirIncludeSpans, NextSolverConfig,
Offload, Options, OutFileName, OutputType, OutputTypes, PAuthKey, PacRet, Passes,
PatchableFunctionEntry, Polonius, ProcMacroExecutionStrategy, Strip, SwitchWithOptPath,
SymbolManglingVersion, WasiExecModel, build_configuration, build_session_options,
rustc_optgroups,
};

View file

@ -55,10 +55,6 @@ passes_change_fields_to_be_of_unit_type =
*[other] fields
}
passes_collapse_debuginfo =
`collapse_debuginfo` attribute should be applied to macro definitions
.label = not a macro definition
passes_const_continue_attr =
`#[const_continue]` should be applied to a break expression
.label = not a break expression

View file

@ -229,6 +229,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
| AttributeKind::BodyStability { .. }
| AttributeKind::ConstStabilityIndirect
| AttributeKind::MacroTransparency(_)
| AttributeKind::CollapseDebugInfo(..)
| AttributeKind::CfgTrace(..)
| AttributeKind::Pointee(..)
| AttributeKind::Dummy
@ -323,7 +324,6 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
| [sym::rustc_dirty, ..]
| [sym::rustc_if_this_changed, ..]
| [sym::rustc_then_this_would_need, ..] => self.check_rustc_dirty_clean(attr),
[sym::collapse_debuginfo, ..] => self.check_collapse_debuginfo(attr, span, target),
[sym::must_not_suspend, ..] => self.check_must_not_suspend(attr, span, target),
[sym::rustc_has_incoherent_inherent_impls, ..] => {
self.check_has_incoherent_inherent_impls(attr, span, target)
@ -718,18 +718,6 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
}
}
}
/// Checks if `#[collapse_debuginfo]` is applied to a macro.
fn check_collapse_debuginfo(&self, attr: &Attribute, span: Span, target: Target) {
match target {
Target::MacroDef => {}
_ => {
self.tcx.dcx().emit_err(errors::CollapseDebuginfo {
attr_span: attr.span(),
defn_span: span,
});
}
}
}
/// Checks if a `#[track_caller]` is applied to a function.
fn check_track_caller(

View file

@ -384,15 +384,6 @@ pub(crate) struct UnusedMultiple {
pub name: Symbol,
}
#[derive(Diagnostic)]
#[diag(passes_collapse_debuginfo)]
pub(crate) struct CollapseDebuginfo {
#[primary_span]
pub attr_span: Span,
#[label]
pub defn_span: Span,
}
#[derive(LintDiagnostic)]
#[diag(passes_deprecated_annotation_has_no_effect)]
pub(crate) struct DeprecatedAnnotationHasNoEffect {

View file

@ -3065,6 +3065,7 @@ pub(crate) mod dep_tracking {
use rustc_errors::LanguageIdentifier;
use rustc_feature::UnstableFeatures;
use rustc_hashes::Hash64;
use rustc_hir::attrs::CollapseMacroDebuginfo;
use rustc_span::edition::Edition;
use rustc_span::{RealFileName, RemapPathScopeComponents};
use rustc_target::spec::{
@ -3074,13 +3075,12 @@ pub(crate) mod dep_tracking {
};
use super::{
AnnotateMoves, AutoDiff, BranchProtection, CFGuard, CFProtection, CollapseMacroDebuginfo,
CoverageOptions, CrateType, DebugInfo, DebugInfoCompression, ErrorOutputType, FmtDebug,
FunctionReturn, InliningThreshold, InstrumentCoverage, InstrumentXRay, LinkerPluginLto,
LocationDetail, LtoCli, MirStripDebugInfo, NextSolverConfig, Offload, OptLevel,
OutFileName, OutputType, OutputTypes, PatchableFunctionEntry, Polonius, ResolveDocLinks,
SourceFileHashAlgorithm, SplitDwarfKind, SwitchWithOptPath, SymbolManglingVersion,
WasiExecModel,
AnnotateMoves, AutoDiff, BranchProtection, CFGuard, CFProtection, CoverageOptions,
CrateType, DebugInfo, DebugInfoCompression, ErrorOutputType, FmtDebug, FunctionReturn,
InliningThreshold, InstrumentCoverage, InstrumentXRay, LinkerPluginLto, LocationDetail,
LtoCli, MirStripDebugInfo, NextSolverConfig, Offload, OptLevel, OutFileName, OutputType,
OutputTypes, PatchableFunctionEntry, Polonius, ResolveDocLinks, SourceFileHashAlgorithm,
SplitDwarfKind, SwitchWithOptPath, SymbolManglingVersion, WasiExecModel,
};
use crate::lint;
use crate::utils::NativeLib;
@ -3299,25 +3299,6 @@ pub enum ProcMacroExecutionStrategy {
CrossThread,
}
/// How to perform collapse macros debug info
/// if-ext - if macro from different crate (related to callsite code)
/// | cmd \ attr | no | (unspecified) | external | yes |
/// | no | no | no | no | no |
/// | (unspecified) | no | no | if-ext | yes |
/// | external | no | if-ext | if-ext | yes |
/// | yes | yes | yes | yes | yes |
#[derive(Clone, Copy, PartialEq, Hash, Debug)]
pub enum CollapseMacroDebuginfo {
/// Don't collapse debuginfo for the macro
No = 0,
/// Unspecified value
Unspecified = 1,
/// Collapse debuginfo if the macro comes from a different crate
External = 2,
/// Collapse debuginfo for the macro
Yes = 3,
}
/// Which format to use for `-Z dump-mono-stats`
#[derive(Clone, Copy, PartialEq, Hash, Debug)]
pub enum DumpMonoStatsFormat {

View file

@ -10,6 +10,7 @@ use rustc_data_structures::stable_hasher::StableHasher;
use rustc_errors::{ColorConfig, LanguageIdentifier, TerminalUrl};
use rustc_feature::UnstableFeatures;
use rustc_hashes::Hash64;
use rustc_hir::attrs::CollapseMacroDebuginfo;
use rustc_macros::{BlobDecodable, Encodable};
use rustc_span::edition::Edition;
use rustc_span::{RealFileName, RemapPathScopeComponents, SourceFileHashAlgorithm};