about summary refs log tree commit diff
diff options
context:
space:
mode:
authorVadim Petrochenkov <vadim.petrochenkov@gmail.com>2024-02-09 15:39:25 +0300
committerVadim Petrochenkov <vadim.petrochenkov@gmail.com>2024-04-25 22:14:47 +0300
commit98804c178608fc4af22b0cb7d199297af5e1562e (patch)
treed532f976f5c36d91b096f2987c003667982c476b
parent9e6c4fddda9d3e5d6cf1b20a0fb82c128efe27ef (diff)
downloadrust-98804c178608fc4af22b0cb7d199297af5e1562e.tar.gz
rust-98804c178608fc4af22b0cb7d199297af5e1562e.zip
debuginfo: Stabilize `-Z debug-macros`, `-Z collapse-macro-debuginfo` and `#[collapse_debuginfo]`
`-Z debug-macros` is "stabilized" by enabling it by default and removing.

`-Z collapse-macro-debuginfo` is stabilized as `-C collapse-macro-debuginfo`.
It now supports all typical boolean values (`parse_opt_bool`) in addition to just yes/no.

Default value of `collapse_debuginfo` was changed from `false` to `external` (i.e. collapsed if external, not collapsed if local).
`#[collapse_debuginfo]` attribute without a value is no longer supported to avoid guessing the default.
-rw-r--r--compiler/rustc_codegen_cranelift/src/debuginfo/line_info.rs9
-rw-r--r--compiler/rustc_codegen_ssa/src/mir/debuginfo.rs22
-rw-r--r--compiler/rustc_expand/src/base.rs75
-rw-r--r--compiler/rustc_feature/src/accepted.rs2
-rw-r--r--compiler/rustc_feature/src/builtin_attrs.rs9
-rw-r--r--compiler/rustc_feature/src/unstable.rs2
-rw-r--r--compiler/rustc_interface/src/tests.rs3
-rw-r--r--compiler/rustc_middle/src/ty/mod.rs18
-rw-r--r--compiler/rustc_session/src/options.rs22
-rw-r--r--compiler/rustc_span/src/hygiene.rs38
-rw-r--r--src/doc/rustc/src/codegen-options/index.md12
-rw-r--r--src/tools/miri/src/shims/backtrace.rs10
-rw-r--r--src/tools/miri/tests/pass/backtrace/backtrace-api-v0.stdout2
-rw-r--r--src/tools/miri/tests/pass/backtrace/backtrace-api-v1.stdout2
-rw-r--r--tests/debuginfo/collapse-debuginfo-external-attr.rs1
-rw-r--r--tests/debuginfo/collapse-debuginfo-external-flag-overriden-by-attr.rs3
-rw-r--r--tests/debuginfo/collapse-debuginfo-external-flag.rs3
-rw-r--r--tests/debuginfo/collapse-debuginfo-in-non-collapse-macro.rs4
-rw-r--r--tests/debuginfo/collapse-debuginfo-no-attr-flag.rs61
-rw-r--r--tests/debuginfo/collapse-debuginfo-no-attr.rs7
-rw-r--r--tests/debuginfo/collapse-debuginfo-with-attr-flag.rs12
-rw-r--r--tests/debuginfo/collapse-debuginfo-with-attr.rs5
-rw-r--r--tests/debuginfo/collapse-debuginfo-with-yes-flag.rs5
-rw-r--r--tests/debuginfo/lexical-scope-with-macro.rs2
-rw-r--r--tests/debuginfo/skip_second_statement.rs3
-rw-r--r--tests/debuginfo/skip_second_statement_collapse.rs4
-rw-r--r--tests/ui/attributes/collapse-debuginfo-invalid.rs47
-rw-r--r--tests/ui/attributes/collapse-debuginfo-invalid.stderr144
-rw-r--r--tests/ui/debuginfo/backtrace-dylib-dep.rs1
-rw-r--r--tests/ui/feature-gates/feature-gate-collapse_debuginfo.rs7
-rw-r--r--tests/ui/feature-gates/feature-gate-collapse_debuginfo.stderr13
31 files changed, 209 insertions, 339 deletions
diff --git a/compiler/rustc_codegen_cranelift/src/debuginfo/line_info.rs b/compiler/rustc_codegen_cranelift/src/debuginfo/line_info.rs
index 32b9c824ded..78b3d5a58f4 100644
--- a/compiler/rustc_codegen_cranelift/src/debuginfo/line_info.rs
+++ b/compiler/rustc_codegen_cranelift/src/debuginfo/line_info.rs
@@ -7,7 +7,7 @@ use cranelift_codegen::binemit::CodeOffset;
 use cranelift_codegen::MachSrcLoc;
 use gimli::write::{AttributeValue, FileId, FileInfo, LineProgram, LineString, LineStringTable};
 use rustc_span::{
-    FileName, Pos, SourceFile, SourceFileAndLine, SourceFileHash, SourceFileHashAlgorithm,
+    hygiene, FileName, Pos, SourceFile, SourceFileAndLine, SourceFileHash, SourceFileHashAlgorithm,
 };
 
 use crate::debuginfo::emit::address_for_func;
@@ -63,11 +63,8 @@ impl DebugContext {
         function_span: Span,
         span: Span,
     ) -> (FileId, u64, u64) {
-        // Based on https://github.com/rust-lang/rust/blob/e369d87b015a84653343032833d65d0545fd3f26/src/librustc_codegen_ssa/mir/mod.rs#L116-L131
-        // In order to have a good line stepping behavior in debugger, we overwrite debug
-        // locations of macro expansions with that of the outermost expansion site (when the macro is
-        // annotated with `#[collapse_debuginfo]` or when `-Zdebug-macros` is provided).
-        let span = tcx.collapsed_debuginfo(span, function_span);
+        // Match behavior of `FunctionCx::adjusted_span_and_dbg_scope`.
+        let span = hygiene::walk_chain_collapsed(span, function_span);
         match tcx.sess.source_map().lookup_line(span.lo()) {
             Ok(SourceFileAndLine { sf: file, line }) => {
                 let file_id = self.add_source_file(&file);
diff --git a/compiler/rustc_codegen_ssa/src/mir/debuginfo.rs b/compiler/rustc_codegen_ssa/src/mir/debuginfo.rs
index a5fd82a3054..d0e2fc2de12 100644
--- a/compiler/rustc_codegen_ssa/src/mir/debuginfo.rs
+++ b/compiler/rustc_codegen_ssa/src/mir/debuginfo.rs
@@ -4,13 +4,12 @@ use rustc_index::IndexVec;
 use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrFlags;
 use rustc_middle::mir;
 use rustc_middle::ty;
-use rustc_middle::ty::layout::TyAndLayout;
-use rustc_middle::ty::layout::{HasTyCtxt, LayoutOf};
+use rustc_middle::ty::layout::{LayoutOf, TyAndLayout};
 use rustc_middle::ty::Instance;
 use rustc_middle::ty::Ty;
 use rustc_session::config::DebugInfo;
 use rustc_span::symbol::{kw, Symbol};
-use rustc_span::{BytePos, Span};
+use rustc_span::{hygiene, BytePos, Span};
 use rustc_target::abi::{Abi, FieldIdx, FieldsShape, Size, VariantIdx};
 
 use super::operand::{OperandRef, OperandValue};
@@ -220,26 +219,11 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
         &self,
         source_info: mir::SourceInfo,
     ) -> Option<(Bx::DIScope, Option<Bx::DILocation>, Span)> {
-        let span = self.adjust_span_for_debugging(source_info.span);
         let scope = &self.debug_context.as_ref()?.scopes[source_info.scope];
+        let span = hygiene::walk_chain_collapsed(source_info.span, self.mir.span);
         Some((scope.adjust_dbg_scope_for_span(self.cx, span), scope.inlined_at, span))
     }
 
-    /// In order to have a good line stepping behavior in debugger, we overwrite debug
-    /// locations of macro expansions with that of the outermost expansion site (when the macro is
-    /// annotated with `#[collapse_debuginfo]` or when `-Zdebug-macros` is provided).
-    fn adjust_span_for_debugging(&self, span: Span) -> Span {
-        // Bail out if debug info emission is not enabled.
-        if self.debug_context.is_none() {
-            return span;
-        }
-        // Walk up the macro expansion chain until we reach a non-expanded span.
-        // We also stop at the function body level because no line stepping can occur
-        // at the level above that.
-        // Use span of the outermost expansion site, while keeping the original lexical scope.
-        self.cx.tcx().collapsed_debuginfo(span, self.mir.span)
-    }
-
     fn spill_operand_to_stack(
         operand: OperandRef<'tcx, Bx::Value>,
         name: Option<String>,
diff --git a/compiler/rustc_expand/src/base.rs b/compiler/rustc_expand/src/base.rs
index b25dd8fe67b..3c465709ec7 100644
--- a/compiler/rustc_expand/src/base.rs
+++ b/compiler/rustc_expand/src/base.rs
@@ -789,55 +789,50 @@ impl SyntaxExtension {
         }
     }
 
-    fn collapse_debuginfo_by_name(sess: &Session, attr: &Attribute) -> CollapseMacroDebuginfo {
-        use crate::errors::CollapseMacroDebuginfoIllegal;
-        // #[collapse_debuginfo] without enum value (#[collapse_debuginfo(no/external/yes)])
-        // considered as `yes`
-        attr.meta_item_list().map_or(CollapseMacroDebuginfo::Yes, |l| {
-            let [NestedMetaItem::MetaItem(item)] = &l[..] else {
-                sess.dcx().emit_err(CollapseMacroDebuginfoIllegal { span: attr.span });
-                return CollapseMacroDebuginfo::Unspecified;
-            };
-            if !item.is_word() {
-                sess.dcx().emit_err(CollapseMacroDebuginfoIllegal { span: item.span });
-                CollapseMacroDebuginfo::Unspecified
-            } else {
-                match item.name_or_empty() {
-                    sym::no => CollapseMacroDebuginfo::No,
-                    sym::external => CollapseMacroDebuginfo::External,
-                    sym::yes => CollapseMacroDebuginfo::Yes,
-                    _ => {
-                        sess.dcx().emit_err(CollapseMacroDebuginfoIllegal { span: item.span });
-                        CollapseMacroDebuginfo::Unspecified
-                    }
-                }
-            }
-        })
+    fn collapse_debuginfo_by_name(attr: &Attribute) -> Result<CollapseMacroDebuginfo, Span> {
+        let list = attr.meta_item_list();
+        let Some([NestedMetaItem::MetaItem(item)]) = list.as_deref() else {
+            return Err(attr.span);
+        };
+        if !item.is_word() {
+            return Err(item.span);
+        }
+
+        match item.name_or_empty() {
+            sym::no => Ok(CollapseMacroDebuginfo::No),
+            sym::external => Ok(CollapseMacroDebuginfo::External),
+            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  |
-    /// | (unspecified) | no  | no            | if-ext   | yes |
+    /// | (unspecified) | no  | if-ext        | if-ext   | yes |
     /// | external      | no  | if-ext        | if-ext   | yes |
     /// | yes           | yes | yes           | yes      | yes |
-    fn get_collapse_debuginfo(sess: &Session, attrs: &[ast::Attribute], is_local: bool) -> bool {
-        let mut collapse_debuginfo_attr = attr::find_by_name(attrs, sym::collapse_debuginfo)
-            .map(|v| Self::collapse_debuginfo_by_name(sess, v))
-            .unwrap_or(CollapseMacroDebuginfo::Unspecified);
-        if collapse_debuginfo_attr == CollapseMacroDebuginfo::Unspecified
-            && attr::contains_name(attrs, sym::rustc_builtin_macro)
-        {
-            collapse_debuginfo_attr = CollapseMacroDebuginfo::Yes;
-        }
-
-        let flag = sess.opts.unstable_opts.collapse_macro_debuginfo;
-        let attr = collapse_debuginfo_attr;
-        let ext = !is_local;
+    fn get_collapse_debuginfo(sess: &Session, attrs: &[ast::Attribute], ext: bool) -> bool {
+        let flag = sess.opts.cg.collapse_macro_debuginfo;
+        let attr = 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 attr::contains_name(attrs, sym::rustc_builtin_macro) {
+                    CollapseMacroDebuginfo::Yes
+                } else {
+                    CollapseMacroDebuginfo::Unspecified
+                }
+            });
         #[rustfmt::skip]
         let collapse_table = [
             [false, false, false, false],
-            [false, false, ext,   true],
+            [false, ext,   ext,   true],
             [false, ext,   ext,   true],
             [true,  true,  true,  true],
         ];
@@ -864,7 +859,7 @@ impl SyntaxExtension {
         let local_inner_macros = attr::find_by_name(attrs, sym::macro_export)
             .and_then(|macro_export| macro_export.meta_item_list())
             .is_some_and(|l| attr::list_contains_name(&l, sym::local_inner_macros));
-        let collapse_debuginfo = Self::get_collapse_debuginfo(sess, attrs, is_local);
+        let collapse_debuginfo = Self::get_collapse_debuginfo(sess, attrs, !is_local);
         tracing::debug!(?name, ?local_inner_macros, ?collapse_debuginfo, ?allow_internal_unsafe);
 
         let (builtin_name, helper_attrs) = attr::find_by_name(attrs, sym::rustc_builtin_macro)
diff --git a/compiler/rustc_feature/src/accepted.rs b/compiler/rustc_feature/src/accepted.rs
index c0e664f6eed..de2bd60ffad 100644
--- a/compiler/rustc_feature/src/accepted.rs
+++ b/compiler/rustc_feature/src/accepted.rs
@@ -98,6 +98,8 @@ declare_features! (
     (accepted, closure_to_fn_coercion, "1.19.0", Some(39817)),
     /// Allows using the CMPXCHG16B target feature.
     (accepted, cmpxchg16b_target_feature, "1.69.0", Some(44839)),
+    /// Allows use of the `#[collapse_debuginfo]` attribute.
+    (accepted, collapse_debuginfo, "CURRENT_RUSTC_VERSION", Some(100758)),
     /// Allows usage of the `compile_error!` macro.
     (accepted, compile_error, "1.20.0", Some(40872)),
     /// Allows `impl Trait` in function return types.
diff --git a/compiler/rustc_feature/src/builtin_attrs.rs b/compiler/rustc_feature/src/builtin_attrs.rs
index 647cd8d06f2..9d3aac66c41 100644
--- a/compiler/rustc_feature/src/builtin_attrs.rs
+++ b/compiler/rustc_feature/src/builtin_attrs.rs
@@ -450,6 +450,9 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[
         template!(List: r#"natvis_file = "...", gdb_script_file = "...""#),
         DuplicatesOk, EncodeCrossCrate::No
     ),
+    ungated!(collapse_debuginfo, Normal, template!(List: "no|external|yes"), ErrorFollowing,
+        EncodeCrossCrate::Yes
+    ),
 
     // ==========================================================================
     // Unstable attributes:
@@ -516,12 +519,6 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[
         EncodeCrossCrate::Yes, experimental!(deprecated_safe),
     ),
 
-    // `#[collapse_debuginfo]`
-    gated!(
-        collapse_debuginfo, Normal, template!(Word, List: "no|external|yes"), ErrorFollowing,
-        EncodeCrossCrate::No, experimental!(collapse_debuginfo)
-    ),
-
     // RFC 2397
     gated!(
         do_not_recommend, Normal, template!(Word), WarnFollowing,
diff --git a/compiler/rustc_feature/src/unstable.rs b/compiler/rustc_feature/src/unstable.rs
index 2647f09c8c9..132e2ddee29 100644
--- a/compiler/rustc_feature/src/unstable.rs
+++ b/compiler/rustc_feature/src/unstable.rs
@@ -395,8 +395,6 @@ declare_features! (
     (unstable, closure_track_caller, "1.57.0", Some(87417)),
     /// Allows to use the `#[cmse_nonsecure_entry]` attribute.
     (unstable, cmse_nonsecure_entry, "1.48.0", Some(75835)),
-    /// Allows use of the `#[collapse_debuginfo]` attribute.
-    (unstable, collapse_debuginfo, "1.65.0", Some(100758)),
     /// Allows `async {}` expressions in const contexts.
     (unstable, const_async_blocks, "1.53.0", Some(85368)),
     /// Allows `const || {}` closures in const contexts.
diff --git a/compiler/rustc_interface/src/tests.rs b/compiler/rustc_interface/src/tests.rs
index f6014bcd893..68c7f187f52 100644
--- a/compiler/rustc_interface/src/tests.rs
+++ b/compiler/rustc_interface/src/tests.rs
@@ -600,6 +600,7 @@ fn test_codegen_options_tracking_hash() {
     // Make sure that changing a [TRACKED] option changes the hash.
     // tidy-alphabetical-start
     tracked!(code_model, Some(CodeModel::Large));
+    tracked!(collapse_macro_debuginfo, CollapseMacroDebuginfo::Yes);
     tracked!(control_flow_guard, CFGuard::Checks);
     tracked!(debug_assertions, Some(true));
     tracked!(debuginfo, DebugInfo::Limited);
@@ -760,12 +761,10 @@ fn test_unstable_options_tracking_hash() {
         })
     );
     tracked!(codegen_backend, Some("abc".to_string()));
-    tracked!(collapse_macro_debuginfo, CollapseMacroDebuginfo::Yes);
     tracked!(coverage_options, CoverageOptions { branch: true, mcdc: true });
     tracked!(crate_attr, vec!["abc".to_string()]);
     tracked!(cross_crate_inline_threshold, InliningThreshold::Always);
     tracked!(debug_info_for_profiling, true);
-    tracked!(debug_macros, true);
     tracked!(default_hidden_visibility, Some(true));
     tracked!(dep_info_omit_d_target, true);
     tracked!(direct_access_external_data, Some(true));
diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs
index cda332aee56..094b68ce5ad 100644
--- a/compiler/rustc_middle/src/ty/mod.rs
+++ b/compiler/rustc_middle/src/ty/mod.rs
@@ -54,7 +54,7 @@ use rustc_session::lint::LintBuffer;
 pub use rustc_session::lint::RegisteredTools;
 use rustc_span::hygiene::MacroKind;
 use rustc_span::symbol::{kw, sym, Ident, Symbol};
-use rustc_span::{hygiene, ExpnId, ExpnKind, Span};
+use rustc_span::{ExpnId, ExpnKind, Span};
 use rustc_target::abi::{Align, FieldIdx, Integer, IntegerType, VariantIdx};
 pub use rustc_target::abi::{ReprFlags, ReprOptions};
 pub use rustc_type_ir::{DebugWithInfcx, InferCtxtLike, WithInfcx};
@@ -2013,22 +2013,6 @@ impl<'tcx> TyCtxt<'tcx> {
         (ident, scope)
     }
 
-    /// Returns corrected span if the debuginfo for `span` should be collapsed to the outermost
-    /// expansion site (with collapse_debuginfo attribute if the corresponding feature enabled).
-    /// Only applies when `Span` is the result of macro expansion.
-    ///
-    /// - If the `collapse_debuginfo` feature is enabled then debuginfo is not collapsed by default
-    ///   and only when a (some enclosing) macro definition is annotated with `#[collapse_debuginfo]`.
-    /// - If `collapse_debuginfo` is not enabled, then debuginfo is collapsed by default.
-    ///
-    /// When `-Zdebug-macros` is provided then debuginfo will never be collapsed.
-    pub fn collapsed_debuginfo(self, span: Span, upto: Span) -> Span {
-        if self.sess.opts.unstable_opts.debug_macros || !span.from_expansion() {
-            return span;
-        }
-        hygiene::walk_chain_collapsed(span, upto, self.features().collapse_debuginfo)
-    }
-
     #[inline]
     pub fn is_const_fn_raw(self, def_id: DefId) -> bool {
         matches!(
diff --git a/compiler/rustc_session/src/options.rs b/compiler/rustc_session/src/options.rs
index 6a556e2a1f5..e1474ee365b 100644
--- a/compiler/rustc_session/src/options.rs
+++ b/compiler/rustc_session/src/options.rs
@@ -1358,10 +1358,20 @@ mod parse {
         slot: &mut CollapseMacroDebuginfo,
         v: Option<&str>,
     ) -> bool {
+        if v.is_some() {
+            let mut bool_arg = None;
+            if parse_opt_bool(&mut bool_arg, v) {
+                *slot = if bool_arg.unwrap() {
+                    CollapseMacroDebuginfo::Yes
+                } else {
+                    CollapseMacroDebuginfo::No
+                };
+                return true;
+            }
+        }
+
         *slot = match v {
-            Some("no") => CollapseMacroDebuginfo::No,
             Some("external") => CollapseMacroDebuginfo::External,
-            Some("yes") => CollapseMacroDebuginfo::Yes,
             _ => return false,
         };
         true
@@ -1460,6 +1470,9 @@ options! {
         "choose the code model to use (`rustc --print code-models` for details)"),
     codegen_units: Option<usize> = (None, parse_opt_number, [UNTRACKED],
         "divide crate into N units to optimize in parallel"),
+    collapse_macro_debuginfo: CollapseMacroDebuginfo = (CollapseMacroDebuginfo::Unspecified,
+        parse_collapse_macro_debuginfo, [TRACKED],
+        "set option to collapse debuginfo for macros"),
     control_flow_guard: CFGuard = (CFGuard::Disabled, parse_cfguard, [TRACKED],
         "use Windows Control Flow Guard (default: no)"),
     debug_assertions: Option<bool> = (None, parse_opt_bool, [TRACKED],
@@ -1607,9 +1620,6 @@ options! {
         "show all expected values in check-cfg diagnostics (default: no)"),
     codegen_backend: Option<String> = (None, parse_opt_string, [TRACKED],
         "the backend to use"),
-    collapse_macro_debuginfo: CollapseMacroDebuginfo = (CollapseMacroDebuginfo::Unspecified,
-        parse_collapse_macro_debuginfo, [TRACKED],
-        "set option to collapse debuginfo for macros"),
     combine_cgu: bool = (false, parse_bool, [TRACKED],
         "combine CGUs into a single one"),
     coverage_options: CoverageOptions = (CoverageOptions::default(), parse_coverage_options, [TRACKED],
@@ -1620,8 +1630,6 @@ options! {
         "threshold to allow cross crate inlining of functions"),
     debug_info_for_profiling: bool = (false, parse_bool, [TRACKED],
         "emit discriminators and other data necessary for AutoFDO"),
-    debug_macros: bool = (false, parse_bool, [TRACKED],
-        "emit line numbers debug info inside macros (default: no)"),
     debuginfo_compression: DebugInfoCompression = (DebugInfoCompression::None, parse_debuginfo_compression, [TRACKED],
         "compress debug info sections (none, zlib, zstd, default: none)"),
     deduplicate_diagnostics: bool = (true, parse_bool, [UNTRACKED],
diff --git a/compiler/rustc_span/src/hygiene.rs b/compiler/rustc_span/src/hygiene.rs
index 61234a97e16..6093df94179 100644
--- a/compiler/rustc_span/src/hygiene.rs
+++ b/compiler/rustc_span/src/hygiene.rs
@@ -459,28 +459,21 @@ impl HygieneData {
         span
     }
 
-    // We need to walk up and update return span if we meet macro instantiation to be collapsed
-    fn walk_chain_collapsed(
-        &self,
-        mut span: Span,
-        to: Span,
-        collapse_debuginfo_feature_enabled: bool,
-    ) -> Span {
+    fn walk_chain_collapsed(&self, mut span: Span, to: Span) -> Span {
         let orig_span = span;
         let mut ret_span = span;
-
-        debug!(
-            "walk_chain_collapsed({:?}, {:?}), feature_enable={}",
-            span, to, collapse_debuginfo_feature_enabled,
-        );
+        debug!("walk_chain_collapsed({:?}, {:?})", span, to);
         debug!("walk_chain_collapsed: span ctxt = {:?}", span.ctxt());
-        while !span.eq_ctxt(to) && span.from_expansion() {
-            let outer_expn = self.outer_expn(span.ctxt());
+        while let ctxt = span.ctxt()
+            && !ctxt.is_root()
+            && ctxt != to.ctxt()
+        {
+            let outer_expn = self.outer_expn(ctxt);
             debug!("walk_chain_collapsed({:?}): outer_expn={:?}", span, outer_expn);
             let expn_data = self.expn_data(outer_expn);
             debug!("walk_chain_collapsed({:?}): expn_data={:?}", span, expn_data);
             span = expn_data.call_site;
-            if !collapse_debuginfo_feature_enabled || expn_data.collapse_debuginfo {
+            if expn_data.collapse_debuginfo {
                 ret_span = span;
             }
         }
@@ -604,14 +597,13 @@ pub fn walk_chain(span: Span, to: SyntaxContext) -> Span {
     HygieneData::with(|data| data.walk_chain(span, to))
 }
 
-pub fn walk_chain_collapsed(
-    span: Span,
-    to: Span,
-    collapse_debuginfo_feature_enabled: bool,
-) -> Span {
-    HygieneData::with(|hdata| {
-        hdata.walk_chain_collapsed(span, to, collapse_debuginfo_feature_enabled)
-    })
+/// In order to have good line stepping behavior in debugger, for the given span we return its
+/// outermost macro call site that still has a `#[collapse_debuginfo(yes)]` property on it.
+/// We also stop walking call sites at the function body level because no line stepping can occur
+/// at the level above that.
+/// The returned span can then be used in emitted debuginfo.
+pub fn walk_chain_collapsed(span: Span, to: Span) -> Span {
+    HygieneData::with(|data| data.walk_chain_collapsed(span, to))
 }
 
 pub fn update_dollar_crate_names(mut get_name: impl FnMut(SyntaxContext) -> Symbol) {
diff --git a/src/doc/rustc/src/codegen-options/index.md b/src/doc/rustc/src/codegen-options/index.md
index 673ff12b5ce..babe2bc342b 100644
--- a/src/doc/rustc/src/codegen-options/index.md
+++ b/src/doc/rustc/src/codegen-options/index.md
@@ -42,6 +42,18 @@ generated code, but may be slower to compile.
 The default value, if not specified, is 16 for non-incremental builds. For
 incremental builds the default is 256 which allows caching to be more granular.
 
+## collapse-macro-debuginfo
+
+This flag controls whether code locations from a macro definition are collapsed into a single
+location associated with that macro's call site, when generating debuginfo for this crate.
+
+This option, if passed, overrides both default collapsing behavior and `#[collapse_debuginfo]`
+attributes in code.
+
+* `y`, `yes`, `on`, `true`: collapse code locations in debuginfo.
+* `n`, `no`, `off` or `false`: do not collapse code locations in debuginfo.
+* `external`: collapse code locations in debuginfo only if the macro comes from a different crate.
+
 ## control-flow-guard
 
 This flag controls whether LLVM enables the Windows [Control Flow
diff --git a/src/tools/miri/src/shims/backtrace.rs b/src/tools/miri/src/shims/backtrace.rs
index abfa7143a73..294ad50c33f 100644
--- a/src/tools/miri/src/shims/backtrace.rs
+++ b/src/tools/miri/src/shims/backtrace.rs
@@ -2,7 +2,7 @@ use crate::*;
 use rustc_ast::ast::Mutability;
 use rustc_middle::ty::layout::LayoutOf as _;
 use rustc_middle::ty::{self, Instance, Ty};
-use rustc_span::{BytePos, Loc, Symbol};
+use rustc_span::{hygiene, BytePos, Loc, Symbol};
 use rustc_target::{abi::Size, spec::abi::Abi};
 
 impl<'mir, 'tcx: 'mir> EvalContextExt<'mir, 'tcx> for crate::MiriInterpCx<'mir, 'tcx> {}
@@ -45,12 +45,8 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
 
         let mut data = Vec::new();
         for frame in this.active_thread_stack().iter().rev() {
-            let mut span = frame.current_span();
-            // Match the behavior of runtime backtrace spans
-            // by using a non-macro span in our backtrace. See `FunctionCx::debug_loc`.
-            if span.from_expansion() && !tcx.sess.opts.unstable_opts.debug_macros {
-                span = rustc_span::hygiene::walk_chain(span, frame.body.span.ctxt())
-            }
+            // Match behavior of debuginfo (`FunctionCx::adjusted_span_and_dbg_scope`).
+            let span = hygiene::walk_chain_collapsed(frame.current_span(), frame.body.span);
             data.push((frame.instance, span.lo()));
         }
 
diff --git a/src/tools/miri/tests/pass/backtrace/backtrace-api-v0.stdout b/src/tools/miri/tests/pass/backtrace/backtrace-api-v0.stdout
index c9cab268168..e6644b4453f 100644
--- a/src/tools/miri/tests/pass/backtrace/backtrace-api-v0.stdout
+++ b/src/tools/miri/tests/pass/backtrace/backtrace-api-v0.stdout
@@ -1,5 +1,5 @@
 $DIR/backtrace-api-v0.rs:24:14 (func_d)
-$DIR/backtrace-api-v0.rs:20:5 (func_c)
+$DIR/backtrace-api-v0.rs:14:9 (func_c)
 $DIR/backtrace-api-v0.rs:9:5 (func_b::<u8>)
 $DIR/backtrace-api-v0.rs:5:5 (func_a)
 $DIR/backtrace-api-v0.rs:29:18 (main)
diff --git a/src/tools/miri/tests/pass/backtrace/backtrace-api-v1.stdout b/src/tools/miri/tests/pass/backtrace/backtrace-api-v1.stdout
index e145c167e88..11efd2f0752 100644
--- a/src/tools/miri/tests/pass/backtrace/backtrace-api-v1.stdout
+++ b/src/tools/miri/tests/pass/backtrace/backtrace-api-v1.stdout
@@ -1,5 +1,5 @@
 $DIR/backtrace-api-v1.rs:27:9 (func_d)
-$DIR/backtrace-api-v1.rs:20:5 (func_c)
+$DIR/backtrace-api-v1.rs:14:9 (func_c)
 $DIR/backtrace-api-v1.rs:9:5 (func_b::<u8>)
 $DIR/backtrace-api-v1.rs:5:5 (func_a)
 $DIR/backtrace-api-v1.rs:34:18 (main)
diff --git a/tests/debuginfo/collapse-debuginfo-external-attr.rs b/tests/debuginfo/collapse-debuginfo-external-attr.rs
index fba609bf89e..4d4fa92726f 100644
--- a/tests/debuginfo/collapse-debuginfo-external-attr.rs
+++ b/tests/debuginfo/collapse-debuginfo-external-attr.rs
@@ -1,5 +1,4 @@
 //@ ignore-lldb
-#![feature(collapse_debuginfo)]
 
 // Test that local macro debug info is not collapsed with #[collapse_debuginfo(external)]
 
diff --git a/tests/debuginfo/collapse-debuginfo-external-flag-overriden-by-attr.rs b/tests/debuginfo/collapse-debuginfo-external-flag-overriden-by-attr.rs
index 51aa1f8ce19..ab0ae8fef4d 100644
--- a/tests/debuginfo/collapse-debuginfo-external-flag-overriden-by-attr.rs
+++ b/tests/debuginfo/collapse-debuginfo-external-flag-overriden-by-attr.rs
@@ -1,10 +1,9 @@
 //@ ignore-lldb
-#![feature(collapse_debuginfo)]
 
 // Test that macro attribute #[collapse_debuginfo(no)]
 // overrides "collapse_macro_debuginfo=external" flag
 
-//@ compile-flags:-g -Z collapse_macro_debuginfo=external
+//@ compile-flags:-g -C collapse_macro_debuginfo=external
 
 // === GDB TESTS ===================================================================================
 
diff --git a/tests/debuginfo/collapse-debuginfo-external-flag.rs b/tests/debuginfo/collapse-debuginfo-external-flag.rs
index f9ef1ae8a25..b8e73d227b3 100644
--- a/tests/debuginfo/collapse-debuginfo-external-flag.rs
+++ b/tests/debuginfo/collapse-debuginfo-external-flag.rs
@@ -1,9 +1,8 @@
 //@ ignore-lldb
-#![feature(collapse_debuginfo)]
 
 // Test that println macro debug info is collapsed with "collapse_macro_debuginfo=external" flag
 
-//@ compile-flags:-g -Z collapse_macro_debuginfo=external
+//@ compile-flags:-g -C collapse_macro_debuginfo=external
 
 // === GDB TESTS ===================================================================================
 
diff --git a/tests/debuginfo/collapse-debuginfo-in-non-collapse-macro.rs b/tests/debuginfo/collapse-debuginfo-in-non-collapse-macro.rs
index e67e1d83cdc..1aafcffa304 100644
--- a/tests/debuginfo/collapse-debuginfo-in-non-collapse-macro.rs
+++ b/tests/debuginfo/collapse-debuginfo-in-non-collapse-macro.rs
@@ -1,11 +1,9 @@
 //@ ignore-lldb
-#![feature(collapse_debuginfo)]
 
 // Test that statement, skipped/added/reordered by macros, is correctly processed in debuginfo.
 // When nested macros instantiations are tagged with collapse_debuginfo attribute,
 // debug info should be corrected to the first outer macro instantiation
 // without collapse_debuginfo attribute.
-// collapse_debuginfo feature enabled.
 
 //@ compile-flags:-g
 
@@ -61,7 +59,7 @@ fn myprintln_impl(text: &str) {
     println!("{}", text)
 }
 
-#[collapse_debuginfo]
+#[collapse_debuginfo(yes)]
 macro_rules! myprintln {
     ($($arg:tt)*) => {{
         myprintln_impl($($arg)*);
diff --git a/tests/debuginfo/collapse-debuginfo-no-attr-flag.rs b/tests/debuginfo/collapse-debuginfo-no-attr-flag.rs
deleted file mode 100644
index fbc7d03e0df..00000000000
--- a/tests/debuginfo/collapse-debuginfo-no-attr-flag.rs
+++ /dev/null
@@ -1,61 +0,0 @@
-//@ ignore-lldb
-#![feature(collapse_debuginfo)]
-
-// Test that line numbers are not replaced with those of the outermost expansion site when the
-// `collapse_debuginfo` is active, `-Zdebug-macros` is provided and `#[collapse_debuginfo]` not
-// being used.
-
-//@ compile-flags:-g -Zdebug-macros
-
-// === GDB TESTS ===================================================================================
-
-// gdb-command:run
-// gdb-command:next
-// gdb-command:frame
-// gdb-check:[...]#loc1[...]
-// gdb-command:next
-// gdb-command:frame
-// gdb-check:[...]#loc2[...]
-// gdb-command:next
-// gdb-command:frame
-// gdb-check:[...]#loc3[...]
-// gdb-command:next
-// gdb-command:frame
-// gdb-check:[...]#loc4[...]
-// gdb-command:continue
-
-fn one() {
-    println!("one");
-}
-fn two() {
-    println!("two");
-}
-fn three() {
-    println!("three");
-}
-fn four() {
-    println!("four");
-}
-
-macro_rules! outer {
-    ($b:block) => {
-        one(); // #loc1
-        inner!();
-        $b
-    };
-}
-
-macro_rules! inner {
-    () => {
-        two(); // #loc2
-    };
-}
-
-fn main() {
-    let ret = 0; // #break
-    outer!({
-        three(); // #loc3
-        four(); // #loc4
-    });
-    std::process::exit(ret);
-}
diff --git a/tests/debuginfo/collapse-debuginfo-no-attr.rs b/tests/debuginfo/collapse-debuginfo-no-attr.rs
index 4ea1b2cf7a4..6f0d041024f 100644
--- a/tests/debuginfo/collapse-debuginfo-no-attr.rs
+++ b/tests/debuginfo/collapse-debuginfo-no-attr.rs
@@ -1,10 +1,9 @@
 //@ ignore-lldb
-#![feature(collapse_debuginfo)]
 
-// Test that line numbers are not replaced with those of the outermost expansion site when the
-// `collapse_debuginfo` feature is active and the attribute is not provided.
+// Test that line numbers are not replaced with those of the outermost expansion site when
+// `#[collapse_debuginfo]` attribute us not used.
 
-//@ compile-flags:-g -Z collapse_macro_debuginfo=no
+//@ compile-flags:-g
 
 // === GDB TESTS ===================================================================================
 
diff --git a/tests/debuginfo/collapse-debuginfo-with-attr-flag.rs b/tests/debuginfo/collapse-debuginfo-with-attr-flag.rs
index b585cdf13e0..8da084126ca 100644
--- a/tests/debuginfo/collapse-debuginfo-with-attr-flag.rs
+++ b/tests/debuginfo/collapse-debuginfo-with-attr-flag.rs
@@ -1,11 +1,9 @@
 //@ ignore-lldb
-#![feature(collapse_debuginfo)]
 
-// Test that line numbers are not replaced with those of the outermost expansion site when the
-// `collapse_debuginfo` is active and `-Zdebug-macros` is provided, despite `#[collapse_debuginfo]`
-// being used.
+// Test that line numbers are not replaced with those of the outermost expansion site when
+// `-C collapse-macro-debuginfo=false` is passed, despite `#[collapse_debuginfo]` being used.
 
-//@ compile-flags:-g -Zdebug-macros
+//@ compile-flags:-g -C collapse-macro-debuginfo=false
 
 // === GDB TESTS ===================================================================================
 
@@ -37,7 +35,7 @@ fn four() {
     println!("four");
 }
 
-#[collapse_debuginfo]
+#[collapse_debuginfo(yes)]
 macro_rules! outer {
     ($b:block) => {
         one(); // #loc1
@@ -46,7 +44,7 @@ macro_rules! outer {
     };
 }
 
-#[collapse_debuginfo]
+#[collapse_debuginfo(yes)]
 macro_rules! inner {
     () => {
         two(); // #loc2
diff --git a/tests/debuginfo/collapse-debuginfo-with-attr.rs b/tests/debuginfo/collapse-debuginfo-with-attr.rs
index e7698c5f629..fa664687796 100644
--- a/tests/debuginfo/collapse-debuginfo-with-attr.rs
+++ b/tests/debuginfo/collapse-debuginfo-with-attr.rs
@@ -1,5 +1,4 @@
 //@ ignore-lldb
-#![feature(collapse_debuginfo)]
 
 // Test that line numbers are replaced with those of the outermost expansion site when the
 // `collapse_debuginfo` feature is active and the attribute is provided.
@@ -33,7 +32,7 @@ fn four() {
     println!("four");
 }
 
-#[collapse_debuginfo]
+#[collapse_debuginfo(yes)]
 macro_rules! outer {
     ($b:block) => {
         one();
@@ -42,7 +41,7 @@ macro_rules! outer {
     };
 }
 
-#[collapse_debuginfo]
+#[collapse_debuginfo(yes)]
 macro_rules! inner {
     () => {
         two();
diff --git a/tests/debuginfo/collapse-debuginfo-with-yes-flag.rs b/tests/debuginfo/collapse-debuginfo-with-yes-flag.rs
index 2c3ecf3f5af..ef92f87ef46 100644
--- a/tests/debuginfo/collapse-debuginfo-with-yes-flag.rs
+++ b/tests/debuginfo/collapse-debuginfo-with-yes-flag.rs
@@ -1,10 +1,9 @@
 //@ ignore-lldb
-#![feature(collapse_debuginfo)]
 
 // Test that line numbers are replaced with those of the outermost expansion site when the
-// `collapse_debuginfo` feature is active and the command line flag is provided.
+// the command line flag is passed.
 
-//@ compile-flags:-g -Z collapse_macro_debuginfo=yes
+//@ compile-flags:-g -C collapse_macro_debuginfo=yes
 
 // === GDB TESTS ===================================================================================
 
diff --git a/tests/debuginfo/lexical-scope-with-macro.rs b/tests/debuginfo/lexical-scope-with-macro.rs
index 76c923524fb..7ea3dc62e45 100644
--- a/tests/debuginfo/lexical-scope-with-macro.rs
+++ b/tests/debuginfo/lexical-scope-with-macro.rs
@@ -1,7 +1,7 @@
 //@ min-lldb-version: 310
 //@ ignore-lldb FIXME #48807
 
-//@ compile-flags:-g -Zdebug-macros
+//@ compile-flags:-g
 
 // === GDB TESTS ===================================================================================
 
diff --git a/tests/debuginfo/skip_second_statement.rs b/tests/debuginfo/skip_second_statement.rs
index e0f3325bcff..ba182de0385 100644
--- a/tests/debuginfo/skip_second_statement.rs
+++ b/tests/debuginfo/skip_second_statement.rs
@@ -2,9 +2,8 @@
 
 // Test that statement, skipped/added/reordered by macros, is correctly processed in debuginfo.
 // Performed step-over and step-into debug stepping through call statements.
-// collapse_debuginfo feature disabled.
 
-//@ compile-flags:-g
+//@ compile-flags:-g -C collapse-macro-debuginfo=yes
 
 // === GDB TESTS ===================================================================================
 
diff --git a/tests/debuginfo/skip_second_statement_collapse.rs b/tests/debuginfo/skip_second_statement_collapse.rs
index f1a74b629e4..db90cee8bfb 100644
--- a/tests/debuginfo/skip_second_statement_collapse.rs
+++ b/tests/debuginfo/skip_second_statement_collapse.rs
@@ -1,9 +1,7 @@
 //@ ignore-lldb
-#![feature(collapse_debuginfo)]
 
 // Test that statement, skipped/added/reordered by macros, is correctly processed in debuginfo
 // Performed step-over and step-into debug stepping through call statements.
-// collapse_debuginfo feature enabled.
 
 //@ compile-flags:-g
 
@@ -94,7 +92,7 @@ fn myprintln_impl(text: &str) {
     println!("{}", text)
 }
 
-#[collapse_debuginfo]
+#[collapse_debuginfo(yes)]
 macro_rules! myprintln {
     ($($arg:tt)*) => {{
         myprintln_impl($($arg)*);
diff --git a/tests/ui/attributes/collapse-debuginfo-invalid.rs b/tests/ui/attributes/collapse-debuginfo-invalid.rs
index 42d8982c118..d6b3554a5a8 100644
--- a/tests/ui/attributes/collapse-debuginfo-invalid.rs
+++ b/tests/ui/attributes/collapse-debuginfo-invalid.rs
@@ -1,84 +1,83 @@
-#![feature(collapse_debuginfo)]
 #![feature(stmt_expr_attributes)]
 #![feature(type_alias_impl_trait)]
 #![no_std]
 
 // Test that the `#[collapse_debuginfo]` attribute can only be used on macro definitions.
 
-#[collapse_debuginfo]
+#[collapse_debuginfo(yes)]
 //~^ ERROR `collapse_debuginfo` attribute should be applied to macro definitions
 extern crate std;
 
-#[collapse_debuginfo]
+#[collapse_debuginfo(yes)]
 //~^ ERROR `collapse_debuginfo` attribute should be applied to macro definitions
 use std::collections::HashMap;
 
-#[collapse_debuginfo]
+#[collapse_debuginfo(yes)]
 //~^ ERROR `collapse_debuginfo` attribute should be applied to macro definitions
 static FOO: u32 = 3;
 
-#[collapse_debuginfo]
+#[collapse_debuginfo(yes)]
 //~^ ERROR `collapse_debuginfo` attribute should be applied to macro definitions
 const BAR: u32 = 3;
 
-#[collapse_debuginfo]
+#[collapse_debuginfo(yes)]
 //~^ ERROR `collapse_debuginfo` attribute should be applied to macro definitions
 fn foo() {
-    let _ = #[collapse_debuginfo] || { };
+    let _ = #[collapse_debuginfo(yes)] || { };
 //~^ ERROR `collapse_debuginfo` attribute should be applied to macro definitions
-    #[collapse_debuginfo]
+    #[collapse_debuginfo(yes)]
 //~^ ERROR `collapse_debuginfo` attribute should be applied to macro definitions
     let _ = 3;
-    let _ = #[collapse_debuginfo] 3;
+    let _ = #[collapse_debuginfo(yes)] 3;
 //~^ ERROR `collapse_debuginfo` attribute should be applied to macro definitions
     match (3, 4) {
-        #[collapse_debuginfo]
+        #[collapse_debuginfo(yes)]
 //~^ ERROR `collapse_debuginfo` attribute should be applied to macro definitions
         _ => (),
     }
 }
 
-#[collapse_debuginfo]
+#[collapse_debuginfo(yes)]
 //~^ ERROR `collapse_debuginfo` attribute should be applied to macro definitions
 mod bar {
 }
 
-#[collapse_debuginfo]
+#[collapse_debuginfo(yes)]
 //~^ ERROR `collapse_debuginfo` attribute should be applied to macro definitions
 type Map = HashMap<u32, u32>;
 
-#[collapse_debuginfo]
+#[collapse_debuginfo(yes)]
 //~^ ERROR `collapse_debuginfo` attribute should be applied to macro definitions
 enum Foo {
-    #[collapse_debuginfo]
+    #[collapse_debuginfo(yes)]
 //~^ ERROR `collapse_debuginfo` attribute should be applied to macro definitions
     Variant,
 }
 
-#[collapse_debuginfo]
+#[collapse_debuginfo(yes)]
 //~^ ERROR `collapse_debuginfo` attribute should be applied to macro definitions
 struct Bar {
-    #[collapse_debuginfo]
+    #[collapse_debuginfo(yes)]
 //~^ ERROR `collapse_debuginfo` attribute should be applied to macro definitions
     field: u32,
 }
 
-#[collapse_debuginfo]
+#[collapse_debuginfo(yes)]
 //~^ ERROR `collapse_debuginfo` attribute should be applied to macro definitions
 union Qux {
     a: u32,
     b: u16
 }
 
-#[collapse_debuginfo]
+#[collapse_debuginfo(yes)]
 //~^ ERROR `collapse_debuginfo` attribute should be applied to macro definitions
 trait Foobar {
-    #[collapse_debuginfo]
+    #[collapse_debuginfo(yes)]
 //~^ ERROR `collapse_debuginfo` attribute should be applied to macro definitions
     type Bar;
 }
 
-#[collapse_debuginfo]
+#[collapse_debuginfo(yes)]
 //~^ ERROR `collapse_debuginfo` attribute should be applied to macro definitions
 type AFoobar = impl Foobar;
 
@@ -90,19 +89,19 @@ fn constraining() -> AFoobar {
     Bar { field: 3 }
 }
 
-#[collapse_debuginfo]
+#[collapse_debuginfo(yes)]
 //~^ ERROR `collapse_debuginfo` attribute should be applied to macro definitions
 impl Bar {
-    #[collapse_debuginfo]
+    #[collapse_debuginfo(yes)]
 //~^ ERROR `collapse_debuginfo` attribute should be applied to macro definitions
     const FOO: u32 = 3;
 
-    #[collapse_debuginfo]
+    #[collapse_debuginfo(yes)]
 //~^ ERROR `collapse_debuginfo` attribute should be applied to macro definitions
     fn bar(&self) {}
 }
 
-#[collapse_debuginfo]
+#[collapse_debuginfo(yes)]
 macro_rules! finally {
     ($e:expr) => { $e }
 }
diff --git a/tests/ui/attributes/collapse-debuginfo-invalid.stderr b/tests/ui/attributes/collapse-debuginfo-invalid.stderr
index 01c47609108..7cbbd1d647e 100644
--- a/tests/ui/attributes/collapse-debuginfo-invalid.stderr
+++ b/tests/ui/attributes/collapse-debuginfo-invalid.stderr
@@ -1,152 +1,152 @@
 error: `collapse_debuginfo` attribute should be applied to macro definitions
-  --> $DIR/collapse-debuginfo-invalid.rs:8:1
+  --> $DIR/collapse-debuginfo-invalid.rs:7:1
    |
-LL | #[collapse_debuginfo]
-   | ^^^^^^^^^^^^^^^^^^^^^
+LL | #[collapse_debuginfo(yes)]
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^
 LL |
 LL | extern crate std;
    | ----------------- not a macro definition
 
 error: `collapse_debuginfo` attribute should be applied to macro definitions
-  --> $DIR/collapse-debuginfo-invalid.rs:12:1
+  --> $DIR/collapse-debuginfo-invalid.rs:11:1
    |
-LL | #[collapse_debuginfo]
-   | ^^^^^^^^^^^^^^^^^^^^^
+LL | #[collapse_debuginfo(yes)]
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^
 LL |
 LL | use std::collections::HashMap;
    | ------------------------------ not a macro definition
 
 error: `collapse_debuginfo` attribute should be applied to macro definitions
-  --> $DIR/collapse-debuginfo-invalid.rs:16:1
+  --> $DIR/collapse-debuginfo-invalid.rs:15:1
    |
-LL | #[collapse_debuginfo]
-   | ^^^^^^^^^^^^^^^^^^^^^
+LL | #[collapse_debuginfo(yes)]
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^
 LL |
 LL | static FOO: u32 = 3;
    | -------------------- not a macro definition
 
 error: `collapse_debuginfo` attribute should be applied to macro definitions
-  --> $DIR/collapse-debuginfo-invalid.rs:20:1
+  --> $DIR/collapse-debuginfo-invalid.rs:19:1
    |
-LL | #[collapse_debuginfo]
-   | ^^^^^^^^^^^^^^^^^^^^^
+LL | #[collapse_debuginfo(yes)]
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^
 LL |
 LL | const BAR: u32 = 3;
    | ------------------- not a macro definition
 
 error: `collapse_debuginfo` attribute should be applied to macro definitions
-  --> $DIR/collapse-debuginfo-invalid.rs:24:1
+  --> $DIR/collapse-debuginfo-invalid.rs:23:1
    |
-LL |   #[collapse_debuginfo]
-   |   ^^^^^^^^^^^^^^^^^^^^^
+LL |   #[collapse_debuginfo(yes)]
+   |   ^^^^^^^^^^^^^^^^^^^^^^^^^^
 LL |
 LL | / fn foo() {
-LL | |     let _ = #[collapse_debuginfo] || { };
+LL | |     let _ = #[collapse_debuginfo(yes)] || { };
 LL | |
-LL | |     #[collapse_debuginfo]
+LL | |     #[collapse_debuginfo(yes)]
 ...  |
 LL | |     }
 LL | | }
    | |_- not a macro definition
 
 error: `collapse_debuginfo` attribute should be applied to macro definitions
-  --> $DIR/collapse-debuginfo-invalid.rs:27:13
+  --> $DIR/collapse-debuginfo-invalid.rs:26:13
    |
-LL |     let _ = #[collapse_debuginfo] || { };
-   |             ^^^^^^^^^^^^^^^^^^^^^ ------ not a macro definition
+LL |     let _ = #[collapse_debuginfo(yes)] || { };
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^ ------ not a macro definition
 
 error: `collapse_debuginfo` attribute should be applied to macro definitions
-  --> $DIR/collapse-debuginfo-invalid.rs:29:5
+  --> $DIR/collapse-debuginfo-invalid.rs:28:5
    |
-LL |     #[collapse_debuginfo]
-   |     ^^^^^^^^^^^^^^^^^^^^^
+LL |     #[collapse_debuginfo(yes)]
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^
 LL |
 LL |     let _ = 3;
    |     ---------- not a macro definition
 
 error: `collapse_debuginfo` attribute should be applied to macro definitions
-  --> $DIR/collapse-debuginfo-invalid.rs:32:13
+  --> $DIR/collapse-debuginfo-invalid.rs:31:13
    |
-LL |     let _ = #[collapse_debuginfo] 3;
-   |             ^^^^^^^^^^^^^^^^^^^^^ - not a macro definition
+LL |     let _ = #[collapse_debuginfo(yes)] 3;
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^ - not a macro definition
 
 error: `collapse_debuginfo` attribute should be applied to macro definitions
-  --> $DIR/collapse-debuginfo-invalid.rs:35:9
+  --> $DIR/collapse-debuginfo-invalid.rs:34:9
    |
-LL |         #[collapse_debuginfo]
-   |         ^^^^^^^^^^^^^^^^^^^^^
+LL |         #[collapse_debuginfo(yes)]
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^
 LL |
 LL |         _ => (),
    |         ------- not a macro definition
 
 error: `collapse_debuginfo` attribute should be applied to macro definitions
-  --> $DIR/collapse-debuginfo-invalid.rs:41:1
+  --> $DIR/collapse-debuginfo-invalid.rs:40:1
    |
-LL |   #[collapse_debuginfo]
-   |   ^^^^^^^^^^^^^^^^^^^^^
+LL |   #[collapse_debuginfo(yes)]
+   |   ^^^^^^^^^^^^^^^^^^^^^^^^^^
 LL |
 LL | / mod bar {
 LL | | }
    | |_- not a macro definition
 
 error: `collapse_debuginfo` attribute should be applied to macro definitions
-  --> $DIR/collapse-debuginfo-invalid.rs:46:1
+  --> $DIR/collapse-debuginfo-invalid.rs:45:1
    |
-LL | #[collapse_debuginfo]
-   | ^^^^^^^^^^^^^^^^^^^^^
+LL | #[collapse_debuginfo(yes)]
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^
 LL |
 LL | type Map = HashMap<u32, u32>;
    | ----------------------------- not a macro definition
 
 error: `collapse_debuginfo` attribute should be applied to macro definitions
-  --> $DIR/collapse-debuginfo-invalid.rs:50:1
+  --> $DIR/collapse-debuginfo-invalid.rs:49:1
    |
-LL |   #[collapse_debuginfo]
-   |   ^^^^^^^^^^^^^^^^^^^^^
+LL |   #[collapse_debuginfo(yes)]
+   |   ^^^^^^^^^^^^^^^^^^^^^^^^^^
 LL |
 LL | / enum Foo {
-LL | |     #[collapse_debuginfo]
+LL | |     #[collapse_debuginfo(yes)]
 LL | |
 LL | |     Variant,
 LL | | }
    | |_- not a macro definition
 
 error: `collapse_debuginfo` attribute should be applied to macro definitions
-  --> $DIR/collapse-debuginfo-invalid.rs:53:5
+  --> $DIR/collapse-debuginfo-invalid.rs:52:5
    |
-LL |     #[collapse_debuginfo]
-   |     ^^^^^^^^^^^^^^^^^^^^^
+LL |     #[collapse_debuginfo(yes)]
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^
 LL |
 LL |     Variant,
    |     ------- not a macro definition
 
 error: `collapse_debuginfo` attribute should be applied to macro definitions
-  --> $DIR/collapse-debuginfo-invalid.rs:58:1
+  --> $DIR/collapse-debuginfo-invalid.rs:57:1
    |
-LL |   #[collapse_debuginfo]
-   |   ^^^^^^^^^^^^^^^^^^^^^
+LL |   #[collapse_debuginfo(yes)]
+   |   ^^^^^^^^^^^^^^^^^^^^^^^^^^
 LL |
 LL | / struct Bar {
-LL | |     #[collapse_debuginfo]
+LL | |     #[collapse_debuginfo(yes)]
 LL | |
 LL | |     field: u32,
 LL | | }
    | |_- not a macro definition
 
 error: `collapse_debuginfo` attribute should be applied to macro definitions
-  --> $DIR/collapse-debuginfo-invalid.rs:61:5
+  --> $DIR/collapse-debuginfo-invalid.rs:60:5
    |
-LL |     #[collapse_debuginfo]
-   |     ^^^^^^^^^^^^^^^^^^^^^
+LL |     #[collapse_debuginfo(yes)]
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^
 LL |
 LL |     field: u32,
    |     ---------- not a macro definition
 
 error: `collapse_debuginfo` attribute should be applied to macro definitions
-  --> $DIR/collapse-debuginfo-invalid.rs:66:1
+  --> $DIR/collapse-debuginfo-invalid.rs:65:1
    |
-LL |   #[collapse_debuginfo]
-   |   ^^^^^^^^^^^^^^^^^^^^^
+LL |   #[collapse_debuginfo(yes)]
+   |   ^^^^^^^^^^^^^^^^^^^^^^^^^^
 LL |
 LL | / union Qux {
 LL | |     a: u32,
@@ -155,35 +155,35 @@ LL | | }
    | |_- not a macro definition
 
 error: `collapse_debuginfo` attribute should be applied to macro definitions
-  --> $DIR/collapse-debuginfo-invalid.rs:73:1
+  --> $DIR/collapse-debuginfo-invalid.rs:72:1
    |
-LL |   #[collapse_debuginfo]
-   |   ^^^^^^^^^^^^^^^^^^^^^
+LL |   #[collapse_debuginfo(yes)]
+   |   ^^^^^^^^^^^^^^^^^^^^^^^^^^
 LL |
 LL | / trait Foobar {
-LL | |     #[collapse_debuginfo]
+LL | |     #[collapse_debuginfo(yes)]
 LL | |
 LL | |     type Bar;
 LL | | }
    | |_- not a macro definition
 
 error: `collapse_debuginfo` attribute should be applied to macro definitions
-  --> $DIR/collapse-debuginfo-invalid.rs:81:1
+  --> $DIR/collapse-debuginfo-invalid.rs:80:1
    |
-LL | #[collapse_debuginfo]
-   | ^^^^^^^^^^^^^^^^^^^^^
+LL | #[collapse_debuginfo(yes)]
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^
 LL |
 LL | type AFoobar = impl Foobar;
    | --------------------------- not a macro definition
 
 error: `collapse_debuginfo` attribute should be applied to macro definitions
-  --> $DIR/collapse-debuginfo-invalid.rs:93:1
+  --> $DIR/collapse-debuginfo-invalid.rs:92:1
    |
-LL |   #[collapse_debuginfo]
-   |   ^^^^^^^^^^^^^^^^^^^^^
+LL |   #[collapse_debuginfo(yes)]
+   |   ^^^^^^^^^^^^^^^^^^^^^^^^^^
 LL |
 LL | / impl Bar {
-LL | |     #[collapse_debuginfo]
+LL | |     #[collapse_debuginfo(yes)]
 LL | |
 LL | |     const FOO: u32 = 3;
 ...  |
@@ -192,28 +192,28 @@ LL | | }
    | |_- not a macro definition
 
 error: `collapse_debuginfo` attribute should be applied to macro definitions
-  --> $DIR/collapse-debuginfo-invalid.rs:76:5
+  --> $DIR/collapse-debuginfo-invalid.rs:75:5
    |
-LL |     #[collapse_debuginfo]
-   |     ^^^^^^^^^^^^^^^^^^^^^
+LL |     #[collapse_debuginfo(yes)]
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^
 LL |
 LL |     type Bar;
    |     --------- not a macro definition
 
 error: `collapse_debuginfo` attribute should be applied to macro definitions
-  --> $DIR/collapse-debuginfo-invalid.rs:96:5
+  --> $DIR/collapse-debuginfo-invalid.rs:95:5
    |
-LL |     #[collapse_debuginfo]
-   |     ^^^^^^^^^^^^^^^^^^^^^
+LL |     #[collapse_debuginfo(yes)]
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^
 LL |
 LL |     const FOO: u32 = 3;
    |     ------------------- not a macro definition
 
 error: `collapse_debuginfo` attribute should be applied to macro definitions
-  --> $DIR/collapse-debuginfo-invalid.rs:100:5
+  --> $DIR/collapse-debuginfo-invalid.rs:99:5
    |
-LL |     #[collapse_debuginfo]
-   |     ^^^^^^^^^^^^^^^^^^^^^
+LL |     #[collapse_debuginfo(yes)]
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^
 LL |
 LL |     fn bar(&self) {}
    |     ---------------- not a macro definition
diff --git a/tests/ui/debuginfo/backtrace-dylib-dep.rs b/tests/ui/debuginfo/backtrace-dylib-dep.rs
index e2414073ede..fcd1f92e28e 100644
--- a/tests/ui/debuginfo/backtrace-dylib-dep.rs
+++ b/tests/ui/debuginfo/backtrace-dylib-dep.rs
@@ -27,6 +27,7 @@ macro_rules! pos {
     };
 }
 
+#[collapse_debuginfo(yes)]
 macro_rules! check {
     ($($pos:expr),*) => ({
         verify(&[$($pos,)* pos!()]);
diff --git a/tests/ui/feature-gates/feature-gate-collapse_debuginfo.rs b/tests/ui/feature-gates/feature-gate-collapse_debuginfo.rs
deleted file mode 100644
index f73bf579f6d..00000000000
--- a/tests/ui/feature-gates/feature-gate-collapse_debuginfo.rs
+++ /dev/null
@@ -1,7 +0,0 @@
-#[collapse_debuginfo]
-//~^ ERROR the `#[collapse_debuginfo]` attribute is an experimental feature
-macro_rules! foo {
-    ($e:expr) => { $e }
-}
-
-fn main() {}
diff --git a/tests/ui/feature-gates/feature-gate-collapse_debuginfo.stderr b/tests/ui/feature-gates/feature-gate-collapse_debuginfo.stderr
deleted file mode 100644
index f361a76b4a7..00000000000
--- a/tests/ui/feature-gates/feature-gate-collapse_debuginfo.stderr
+++ /dev/null
@@ -1,13 +0,0 @@
-error[E0658]: the `#[collapse_debuginfo]` attribute is an experimental feature
-  --> $DIR/feature-gate-collapse_debuginfo.rs:1:1
-   |
-LL | #[collapse_debuginfo]
-   | ^^^^^^^^^^^^^^^^^^^^^
-   |
-   = note: see issue #100758 <https://github.com/rust-lang/rust/issues/100758> for more information
-   = help: add `#![feature(collapse_debuginfo)]` to the crate attributes to enable
-   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
-
-error: aborting due to 1 previous error
-
-For more information about this error, try `rustc --explain E0658`.