From 38958aa8bdd2b46dd7f9213bda1c9c6433282a68 Mon Sep 17 00:00:00 2001 From: David Wood Date: Thu, 21 Jul 2022 16:19:22 +0100 Subject: [PATCH] ssa: implement `#[collapse_debuginfo]` Debuginfo line information for macro invocations are collapsed by default - line information are replaced by the line of the outermost expansion site. Using `-Zdebug-macros` disables this behaviour. When the `collapse_debuginfo` feature is enabled, the default behaviour is reversed so that debuginfo is not collapsed by default. In addition, the `#[collapse_debuginfo]` attribute is available and can be applied to macro definitions which will then have their line information collapsed. Signed-off-by: David Wood --- .../src/debuginfo/line_info.rs | 6 +- .../rustc_codegen_ssa/src/mir/debuginfo.rs | 8 +- .../locales/en-US/passes.ftl | 3 + compiler/rustc_expand/src/base.rs | 39 +-- compiler/rustc_feature/src/active.rs | 2 + compiler/rustc_feature/src/builtin_attrs.rs | 6 + compiler/rustc_middle/src/ty/mod.rs | 17 ++ compiler/rustc_passes/src/check_attr.rs | 14 ++ compiler/rustc_passes/src/errors.rs | 9 + compiler/rustc_span/src/hygiene.rs | 28 ++- compiler/rustc_span/src/lib.rs | 7 + compiler/rustc_span/src/symbol.rs | 1 + .../collapse-debuginfo-no-attr-flag.rs | 61 +++++ .../debuginfo/collapse-debuginfo-no-attr.rs | 60 +++++ .../collapse-debuginfo-with-attr-flag.rs | 63 +++++ .../debuginfo/collapse-debuginfo-with-attr.rs | 59 +++++ .../attributes/collapse-debuginfo-invalid.rs | 110 +++++++++ .../collapse-debuginfo-invalid.stderr | 222 ++++++++++++++++++ .../feature-gate-collapse_debuginfo.rs | 7 + .../feature-gate-collapse_debuginfo.stderr | 12 + 20 files changed, 699 insertions(+), 35 deletions(-) create mode 100644 src/test/debuginfo/collapse-debuginfo-no-attr-flag.rs create mode 100644 src/test/debuginfo/collapse-debuginfo-no-attr.rs create mode 100644 src/test/debuginfo/collapse-debuginfo-with-attr-flag.rs create mode 100644 src/test/debuginfo/collapse-debuginfo-with-attr.rs create mode 100644 src/test/ui/attributes/collapse-debuginfo-invalid.rs create mode 100644 src/test/ui/attributes/collapse-debuginfo-invalid.stderr create mode 100644 src/test/ui/feature-gates/feature-gate-collapse_debuginfo.rs create mode 100644 src/test/ui/feature-gates/feature-gate-collapse_debuginfo.stderr diff --git a/compiler/rustc_codegen_cranelift/src/debuginfo/line_info.rs b/compiler/rustc_codegen_cranelift/src/debuginfo/line_info.rs index 3ad0c420eaf..463de6a91c7 100644 --- a/compiler/rustc_codegen_cranelift/src/debuginfo/line_info.rs +++ b/compiler/rustc_codegen_cranelift/src/debuginfo/line_info.rs @@ -68,9 +68,9 @@ impl DebugContext { ) -> (Lrc, 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 - // (unless the crate is being compiled with `-Z debug-macros`). - let span = if !span.from_expansion() || tcx.sess.opts.unstable_opts.debug_macros { + // 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 = if tcx.should_collapse_debuginfo(span) { span } else { // Walk up the macro expansion chain until we reach a non-expanded span. diff --git a/compiler/rustc_codegen_ssa/src/mir/debuginfo.rs b/compiler/rustc_codegen_ssa/src/mir/debuginfo.rs index 8c3186efc63..157c1c82311 100644 --- a/compiler/rustc_codegen_ssa/src/mir/debuginfo.rs +++ b/compiler/rustc_codegen_ssa/src/mir/debuginfo.rs @@ -3,7 +3,7 @@ use rustc_index::vec::IndexVec; use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrFlags; use rustc_middle::mir; use rustc_middle::ty; -use rustc_middle::ty::layout::LayoutOf; +use rustc_middle::ty::layout::{HasTyCtxt, LayoutOf}; use rustc_session::config::DebugInfo; use rustc_span::symbol::{kw, Symbol}; use rustc_span::{BytePos, Span}; @@ -93,15 +93,15 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { } /// 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 - /// (unless the crate is being compiled with `-Z debug-macros`). + /// 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, mut span: Span) -> Span { // Bail out if debug info emission is not enabled. if self.debug_context.is_none() { return span; } - if span.from_expansion() && !self.cx.sess().opts.unstable_opts.debug_macros { + if self.cx.tcx().should_collapse_debuginfo(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. diff --git a/compiler/rustc_error_messages/locales/en-US/passes.ftl b/compiler/rustc_error_messages/locales/en-US/passes.ftl index 7374f6d3f27..556a6452f1a 100644 --- a/compiler/rustc_error_messages/locales/en-US/passes.ftl +++ b/compiler/rustc_error_messages/locales/en-US/passes.ftl @@ -265,3 +265,6 @@ passes_rustc_lint_opt_deny_field_access = `#[rustc_lint_opt_deny_field_access]` passes_link_ordinal = attribute should be applied to a foreign function or static .label = not a foreign function or static + +passes_collapse_debuginfo = `collapse_debuginfo` attribute should be applied to macro definitions + .label = not a macro definition diff --git a/compiler/rustc_expand/src/base.rs b/compiler/rustc_expand/src/base.rs index 2bb522caa2d..e1da3ecdec7 100644 --- a/compiler/rustc_expand/src/base.rs +++ b/compiler/rustc_expand/src/base.rs @@ -693,10 +693,6 @@ pub struct SyntaxExtension { pub span: Span, /// List of unstable features that are treated as stable inside this macro. pub allow_internal_unstable: Option>, - /// Suppresses the `unsafe_code` lint for code produced by this macro. - pub allow_internal_unsafe: bool, - /// Enables the macro helper hack (`ident!(...)` -> `$crate::ident!(...)`) for this macro. - pub local_inner_macros: bool, /// The macro's stability info. pub stability: Option, /// The macro's deprecation info. @@ -708,6 +704,13 @@ pub struct SyntaxExtension { /// Built-in macros have a couple of special properties like availability /// in `#[no_implicit_prelude]` modules, so we have to keep this flag. pub builtin_name: Option, + /// Suppresses the `unsafe_code` lint for code produced by this macro. + pub allow_internal_unsafe: bool, + /// Enables the macro helper hack (`ident!(...)` -> `$crate::ident!(...)`) for this macro. + pub local_inner_macros: bool, + /// Should debuginfo for the macro be collapsed to the outermost expansion site (in other + /// words, was the macro definition annotated with `#[collapse_debuginfo]`)? + pub collapse_debuginfo: bool, } impl SyntaxExtension { @@ -729,14 +732,15 @@ impl SyntaxExtension { SyntaxExtension { span: DUMMY_SP, allow_internal_unstable: None, - allow_internal_unsafe: false, - local_inner_macros: false, stability: None, deprecation: None, helper_attrs: Vec::new(), edition, builtin_name: None, kind, + allow_internal_unsafe: false, + local_inner_macros: false, + collapse_debuginfo: false, } } @@ -754,12 +758,13 @@ impl SyntaxExtension { let allow_internal_unstable = attr::allow_internal_unstable(sess, &attrs).collect::>(); - let mut local_inner_macros = false; - if let Some(macro_export) = sess.find_by_name(attrs, sym::macro_export) { - if let Some(l) = macro_export.meta_item_list() { - local_inner_macros = attr::list_contains_name(&l, sym::local_inner_macros); - } - } + let allow_internal_unsafe = sess.contains_name(attrs, sym::allow_internal_unsafe); + let local_inner_macros = sess + .find_by_name(attrs, sym::macro_export) + .and_then(|macro_export| macro_export.meta_item_list()) + .map_or(false, |l| attr::list_contains_name(&l, sym::local_inner_macros)); + let collapse_debuginfo = sess.contains_name(attrs, sym::collapse_debuginfo); + tracing::debug!(?local_inner_macros, ?collapse_debuginfo, ?allow_internal_unsafe); let (builtin_name, helper_attrs) = sess .find_by_name(attrs, sym::rustc_builtin_macro) @@ -801,13 +806,14 @@ impl SyntaxExtension { span, allow_internal_unstable: (!allow_internal_unstable.is_empty()) .then(|| allow_internal_unstable.into()), - allow_internal_unsafe: sess.contains_name(attrs, sym::allow_internal_unsafe), - local_inner_macros, stability: stability.map(|(s, _)| s), deprecation: attr::find_deprecation(&sess, attrs).map(|(d, _)| d), helper_attrs, edition, builtin_name, + allow_internal_unsafe, + local_inner_macros, + collapse_debuginfo, } } @@ -852,11 +858,12 @@ impl SyntaxExtension { call_site, self.span, self.allow_internal_unstable.clone(), - self.allow_internal_unsafe, - self.local_inner_macros, self.edition, macro_def_id, parent_module, + self.allow_internal_unsafe, + self.local_inner_macros, + self.collapse_debuginfo, ) } } diff --git a/compiler/rustc_feature/src/active.rs b/compiler/rustc_feature/src/active.rs index f71b3d59e2c..8f795b62bbc 100644 --- a/compiler/rustc_feature/src/active.rs +++ b/compiler/rustc_feature/src/active.rs @@ -336,6 +336,8 @@ declare_features! ( (active, closure_track_caller, "1.57.0", Some(87417), None), /// Allows to use the `#[cmse_nonsecure_entry]` attribute. (active, cmse_nonsecure_entry, "1.48.0", Some(75835), None), + /// Allows use of the `#[collapse_debuginfo]` attribute. + (active, collapse_debuginfo, "CURRENT_RUSTC_VERSION", Some(100758), None), /// Allows `async {}` expressions in const contexts. (active, const_async_blocks, "1.53.0", Some(85368), None), // Allows limiting the evaluation steps of const expressions diff --git a/compiler/rustc_feature/src/builtin_attrs.rs b/compiler/rustc_feature/src/builtin_attrs.rs index 38a02cb1d7c..8fa30b7f402 100644 --- a/compiler/rustc_feature/src/builtin_attrs.rs +++ b/compiler/rustc_feature/src/builtin_attrs.rs @@ -481,6 +481,12 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[ experimental!(deprecated_safe), ), + // `#[collapse_debuginfo]` + gated!( + collapse_debuginfo, Normal, template!(Word), WarnFollowing, + experimental!(collapse_debuginfo) + ), + // ========================================================================== // Internal attributes: Stability, deprecation, and unsafe: // ========================================================================== diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs index a3f7880b9a5..d77842e32df 100644 --- a/compiler/rustc_middle/src/ty/mod.rs +++ b/compiler/rustc_middle/src/ty/mod.rs @@ -2373,6 +2373,23 @@ impl<'tcx> TyCtxt<'tcx> { (ident, scope) } + /// Returns `true` if the debuginfo for `span` should be collapsed to the outermost expansion + /// site. 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 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 should_collapse_debuginfo(self, span: Span) -> bool { + !self.sess.opts.unstable_opts.debug_macros + && if self.features().collapse_debuginfo { + span.in_macro_expansion_with_collapse_debuginfo() + } else { + span.from_expansion() + } + } + pub fn is_object_safe(self, key: DefId) -> bool { self.object_safety_violations(key).is_empty() } diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs index d0b46aa2c45..4f73f71f501 100644 --- a/compiler/rustc_passes/src/check_attr.rs +++ b/compiler/rustc_passes/src/check_attr.rs @@ -131,6 +131,7 @@ impl CheckAttrVisitor<'_> { | sym::rustc_if_this_changed | sym::rustc_then_this_would_need => self.check_rustc_dirty_clean(&attr), sym::cmse_nonsecure_entry => self.check_cmse_nonsecure_entry(attr, span, target), + sym::collapse_debuginfo => self.check_collapse_debuginfo(attr, span, target), sym::const_trait => self.check_const_trait(attr, span, target), sym::must_not_suspend => self.check_must_not_suspend(&attr, span, target), sym::must_use => self.check_must_use(hir_id, &attr, span, target), @@ -431,6 +432,19 @@ impl CheckAttrVisitor<'_> { } } + /// Checks if `#[collapse_debuginfo]` is applied to a macro. + fn check_collapse_debuginfo(&self, attr: &Attribute, span: Span, target: Target) -> bool { + match target { + Target::MacroDef => true, + _ => { + self.tcx + .sess + .emit_err(errors::CollapseDebuginfo { attr_span: attr.span, defn_span: span }); + false + } + } + } + /// Checks if a `#[track_caller]` is applied to a non-naked function. Returns `true` if valid. fn check_track_caller( &self, diff --git a/compiler/rustc_passes/src/errors.rs b/compiler/rustc_passes/src/errors.rs index 901f56ad96d..96cc8ae988c 100644 --- a/compiler/rustc_passes/src/errors.rs +++ b/compiler/rustc_passes/src/errors.rs @@ -649,3 +649,12 @@ pub struct RustcLintOptDenyFieldAccess { #[label] pub span: Span, } + +#[derive(SessionDiagnostic)] +#[diag(passes::collapse_debuginfo)] +pub struct CollapseDebuginfo { + #[primary_span] + pub attr_span: Span, + #[label] + pub defn_span: Span, +} diff --git a/compiler/rustc_span/src/hygiene.rs b/compiler/rustc_span/src/hygiene.rs index e8ddb4ed17a..191186af6fa 100644 --- a/compiler/rustc_span/src/hygiene.rs +++ b/compiler/rustc_span/src/hygiene.rs @@ -944,12 +944,6 @@ pub struct ExpnData { /// internally without forcing the whole crate to opt-in /// to them. pub allow_internal_unstable: Option>, - /// Whether the macro is allowed to use `unsafe` internally - /// even if the user crate has `#![forbid(unsafe_code)]`. - pub allow_internal_unsafe: bool, - /// Enables the macro helper hack (`ident!(...)` -> `$crate::ident!(...)`) - /// for a given macro. - pub local_inner_macros: bool, /// Edition of the crate in which the macro is defined. pub edition: Edition, /// The `DefId` of the macro being invoked, @@ -957,6 +951,13 @@ pub struct ExpnData { pub macro_def_id: Option, /// The normal module (`mod`) in which the expanded macro was defined. pub parent_module: Option, + /// Suppresses the `unsafe_code` lint for code produced by this macro. + pub allow_internal_unsafe: bool, + /// Enables the macro helper hack (`ident!(...)` -> `$crate::ident!(...)`) for this macro. + pub local_inner_macros: bool, + /// Should debuginfo for the macro be collapsed to the outermost expansion site (in other + /// words, was the macro definition annotated with `#[collapse_debuginfo]`)? + pub collapse_debuginfo: bool, } impl !PartialEq for ExpnData {} @@ -969,11 +970,12 @@ impl ExpnData { call_site: Span, def_site: Span, allow_internal_unstable: Option>, - allow_internal_unsafe: bool, - local_inner_macros: bool, edition: Edition, macro_def_id: Option, parent_module: Option, + allow_internal_unsafe: bool, + local_inner_macros: bool, + collapse_debuginfo: bool, ) -> ExpnData { ExpnData { kind, @@ -981,12 +983,13 @@ impl ExpnData { call_site, def_site, allow_internal_unstable, - allow_internal_unsafe, - local_inner_macros, edition, macro_def_id, parent_module, disambiguator: 0, + allow_internal_unsafe, + local_inner_macros, + collapse_debuginfo, } } @@ -1004,12 +1007,13 @@ impl ExpnData { call_site, def_site: DUMMY_SP, allow_internal_unstable: None, - allow_internal_unsafe: false, - local_inner_macros: false, edition, macro_def_id, parent_module, disambiguator: 0, + allow_internal_unsafe: false, + local_inner_macros: false, + collapse_debuginfo: false, } } diff --git a/compiler/rustc_span/src/lib.rs b/compiler/rustc_span/src/lib.rs index 34e2e92bdfc..26b4ebeab1b 100644 --- a/compiler/rustc_span/src/lib.rs +++ b/compiler/rustc_span/src/lib.rs @@ -564,6 +564,13 @@ impl Span { self.ctxt() != SyntaxContext::root() } + /// Returns `true` if `span` originates in a macro's expansion where debuginfo should be + /// collapsed. + pub fn in_macro_expansion_with_collapse_debuginfo(self) -> bool { + let outer_expn = self.ctxt().outer_expn_data(); + matches!(outer_expn.kind, ExpnKind::Macro(..)) && outer_expn.collapse_debuginfo + } + /// Returns `true` if `span` originates in a derive-macro's expansion. pub fn in_derive_expansion(self) -> bool { matches!(self.ctxt().outer_expn_data().kind, ExpnKind::Macro(MacroKind::Derive, _)) diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs index 75b1dfc856a..e69a7d2ab34 100644 --- a/compiler/rustc_span/src/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs @@ -487,6 +487,7 @@ symbols! { cmse_nonsecure_entry, coerce_unsized, cold, + collapse_debuginfo, column, column_macro, compare_and_swap, diff --git a/src/test/debuginfo/collapse-debuginfo-no-attr-flag.rs b/src/test/debuginfo/collapse-debuginfo-no-attr-flag.rs new file mode 100644 index 00000000000..413f6120105 --- /dev/null +++ b/src/test/debuginfo/collapse-debuginfo-no-attr-flag.rs @@ -0,0 +1,61 @@ +// 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/src/test/debuginfo/collapse-debuginfo-no-attr.rs b/src/test/debuginfo/collapse-debuginfo-no-attr.rs new file mode 100644 index 00000000000..230c8795be3 --- /dev/null +++ b/src/test/debuginfo/collapse-debuginfo-no-attr.rs @@ -0,0 +1,60 @@ +// 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. + +// compile-flags:-g + +// === 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/src/test/debuginfo/collapse-debuginfo-with-attr-flag.rs b/src/test/debuginfo/collapse-debuginfo-with-attr-flag.rs new file mode 100644 index 00000000000..183cf537e85 --- /dev/null +++ b/src/test/debuginfo/collapse-debuginfo-with-attr-flag.rs @@ -0,0 +1,63 @@ +// 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. + +// 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"); +} + +#[collapse_debuginfo] +macro_rules! outer { + ($b:block) => { + one(); // #loc1 + inner!(); + $b + }; +} + +#[collapse_debuginfo] +macro_rules! inner { + () => { + two(); // #loc2 + }; +} + +fn main() { + let ret = 0; // #break + outer!({ + three(); // #loc3 + four(); // #loc4 + }); + std::process::exit(ret); +} diff --git a/src/test/debuginfo/collapse-debuginfo-with-attr.rs b/src/test/debuginfo/collapse-debuginfo-with-attr.rs new file mode 100644 index 00000000000..34d03c18bc7 --- /dev/null +++ b/src/test/debuginfo/collapse-debuginfo-with-attr.rs @@ -0,0 +1,59 @@ +// 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. + +// compile-flags:-g + +// === 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:continue + +fn one() { + println!("one"); +} +fn two() { + println!("two"); +} +fn three() { + println!("three"); +} +fn four() { + println!("four"); +} + +#[collapse_debuginfo] +macro_rules! outer { + ($b:block) => { + one(); + inner!(); + $b + }; +} + +#[collapse_debuginfo] +macro_rules! inner { + () => { + two(); + }; +} + +fn main() { + let ret = 0; // #break + outer!({ // #loc1 + three(); // #loc2 + four(); // #loc3 + }); + std::process::exit(ret); +} diff --git a/src/test/ui/attributes/collapse-debuginfo-invalid.rs b/src/test/ui/attributes/collapse-debuginfo-invalid.rs new file mode 100644 index 00000000000..42d8982c118 --- /dev/null +++ b/src/test/ui/attributes/collapse-debuginfo-invalid.rs @@ -0,0 +1,110 @@ +#![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] +//~^ ERROR `collapse_debuginfo` attribute should be applied to macro definitions +extern crate std; + +#[collapse_debuginfo] +//~^ ERROR `collapse_debuginfo` attribute should be applied to macro definitions +use std::collections::HashMap; + +#[collapse_debuginfo] +//~^ ERROR `collapse_debuginfo` attribute should be applied to macro definitions +static FOO: u32 = 3; + +#[collapse_debuginfo] +//~^ ERROR `collapse_debuginfo` attribute should be applied to macro definitions +const BAR: u32 = 3; + +#[collapse_debuginfo] +//~^ ERROR `collapse_debuginfo` attribute should be applied to macro definitions +fn foo() { + let _ = #[collapse_debuginfo] || { }; +//~^ ERROR `collapse_debuginfo` attribute should be applied to macro definitions + #[collapse_debuginfo] +//~^ ERROR `collapse_debuginfo` attribute should be applied to macro definitions + let _ = 3; + let _ = #[collapse_debuginfo] 3; +//~^ ERROR `collapse_debuginfo` attribute should be applied to macro definitions + match (3, 4) { + #[collapse_debuginfo] +//~^ ERROR `collapse_debuginfo` attribute should be applied to macro definitions + _ => (), + } +} + +#[collapse_debuginfo] +//~^ ERROR `collapse_debuginfo` attribute should be applied to macro definitions +mod bar { +} + +#[collapse_debuginfo] +//~^ ERROR `collapse_debuginfo` attribute should be applied to macro definitions +type Map = HashMap; + +#[collapse_debuginfo] +//~^ ERROR `collapse_debuginfo` attribute should be applied to macro definitions +enum Foo { + #[collapse_debuginfo] +//~^ ERROR `collapse_debuginfo` attribute should be applied to macro definitions + Variant, +} + +#[collapse_debuginfo] +//~^ ERROR `collapse_debuginfo` attribute should be applied to macro definitions +struct Bar { + #[collapse_debuginfo] +//~^ ERROR `collapse_debuginfo` attribute should be applied to macro definitions + field: u32, +} + +#[collapse_debuginfo] +//~^ ERROR `collapse_debuginfo` attribute should be applied to macro definitions +union Qux { + a: u32, + b: u16 +} + +#[collapse_debuginfo] +//~^ ERROR `collapse_debuginfo` attribute should be applied to macro definitions +trait Foobar { + #[collapse_debuginfo] +//~^ ERROR `collapse_debuginfo` attribute should be applied to macro definitions + type Bar; +} + +#[collapse_debuginfo] +//~^ ERROR `collapse_debuginfo` attribute should be applied to macro definitions +type AFoobar = impl Foobar; + +impl Foobar for Bar { + type Bar = u32; +} + +fn constraining() -> AFoobar { + Bar { field: 3 } +} + +#[collapse_debuginfo] +//~^ ERROR `collapse_debuginfo` attribute should be applied to macro definitions +impl Bar { + #[collapse_debuginfo] +//~^ ERROR `collapse_debuginfo` attribute should be applied to macro definitions + const FOO: u32 = 3; + + #[collapse_debuginfo] +//~^ ERROR `collapse_debuginfo` attribute should be applied to macro definitions + fn bar(&self) {} +} + +#[collapse_debuginfo] +macro_rules! finally { + ($e:expr) => { $e } +} + +fn main() {} diff --git a/src/test/ui/attributes/collapse-debuginfo-invalid.stderr b/src/test/ui/attributes/collapse-debuginfo-invalid.stderr new file mode 100644 index 00000000000..01c47609108 --- /dev/null +++ b/src/test/ui/attributes/collapse-debuginfo-invalid.stderr @@ -0,0 +1,222 @@ +error: `collapse_debuginfo` attribute should be applied to macro definitions + --> $DIR/collapse-debuginfo-invalid.rs:8:1 + | +LL | #[collapse_debuginfo] + | ^^^^^^^^^^^^^^^^^^^^^ +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 + | +LL | #[collapse_debuginfo] + | ^^^^^^^^^^^^^^^^^^^^^ +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 + | +LL | #[collapse_debuginfo] + | ^^^^^^^^^^^^^^^^^^^^^ +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 + | +LL | #[collapse_debuginfo] + | ^^^^^^^^^^^^^^^^^^^^^ +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 + | +LL | #[collapse_debuginfo] + | ^^^^^^^^^^^^^^^^^^^^^ +LL | +LL | / fn foo() { +LL | | let _ = #[collapse_debuginfo] || { }; +LL | | +LL | | #[collapse_debuginfo] +... | +LL | | } +LL | | } + | |_- not a macro definition + +error: `collapse_debuginfo` attribute should be applied to macro definitions + --> $DIR/collapse-debuginfo-invalid.rs:27:13 + | +LL | let _ = #[collapse_debuginfo] || { }; + | ^^^^^^^^^^^^^^^^^^^^^ ------ not a macro definition + +error: `collapse_debuginfo` attribute should be applied to macro definitions + --> $DIR/collapse-debuginfo-invalid.rs:29:5 + | +LL | #[collapse_debuginfo] + | ^^^^^^^^^^^^^^^^^^^^^ +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 + | +LL | let _ = #[collapse_debuginfo] 3; + | ^^^^^^^^^^^^^^^^^^^^^ - not a macro definition + +error: `collapse_debuginfo` attribute should be applied to macro definitions + --> $DIR/collapse-debuginfo-invalid.rs:35:9 + | +LL | #[collapse_debuginfo] + | ^^^^^^^^^^^^^^^^^^^^^ +LL | +LL | _ => (), + | ------- not a macro definition + +error: `collapse_debuginfo` attribute should be applied to macro definitions + --> $DIR/collapse-debuginfo-invalid.rs:41:1 + | +LL | #[collapse_debuginfo] + | ^^^^^^^^^^^^^^^^^^^^^ +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 + | +LL | #[collapse_debuginfo] + | ^^^^^^^^^^^^^^^^^^^^^ +LL | +LL | type Map = HashMap; + | ----------------------------- not a macro definition + +error: `collapse_debuginfo` attribute should be applied to macro definitions + --> $DIR/collapse-debuginfo-invalid.rs:50:1 + | +LL | #[collapse_debuginfo] + | ^^^^^^^^^^^^^^^^^^^^^ +LL | +LL | / enum Foo { +LL | | #[collapse_debuginfo] +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 + | +LL | #[collapse_debuginfo] + | ^^^^^^^^^^^^^^^^^^^^^ +LL | +LL | Variant, + | ------- not a macro definition + +error: `collapse_debuginfo` attribute should be applied to macro definitions + --> $DIR/collapse-debuginfo-invalid.rs:58:1 + | +LL | #[collapse_debuginfo] + | ^^^^^^^^^^^^^^^^^^^^^ +LL | +LL | / struct Bar { +LL | | #[collapse_debuginfo] +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 + | +LL | #[collapse_debuginfo] + | ^^^^^^^^^^^^^^^^^^^^^ +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 + | +LL | #[collapse_debuginfo] + | ^^^^^^^^^^^^^^^^^^^^^ +LL | +LL | / union Qux { +LL | | a: u32, +LL | | b: u16 +LL | | } + | |_- not a macro definition + +error: `collapse_debuginfo` attribute should be applied to macro definitions + --> $DIR/collapse-debuginfo-invalid.rs:73:1 + | +LL | #[collapse_debuginfo] + | ^^^^^^^^^^^^^^^^^^^^^ +LL | +LL | / trait Foobar { +LL | | #[collapse_debuginfo] +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 + | +LL | #[collapse_debuginfo] + | ^^^^^^^^^^^^^^^^^^^^^ +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 + | +LL | #[collapse_debuginfo] + | ^^^^^^^^^^^^^^^^^^^^^ +LL | +LL | / impl Bar { +LL | | #[collapse_debuginfo] +LL | | +LL | | const FOO: u32 = 3; +... | +LL | | fn bar(&self) {} +LL | | } + | |_- not a macro definition + +error: `collapse_debuginfo` attribute should be applied to macro definitions + --> $DIR/collapse-debuginfo-invalid.rs:76:5 + | +LL | #[collapse_debuginfo] + | ^^^^^^^^^^^^^^^^^^^^^ +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 + | +LL | #[collapse_debuginfo] + | ^^^^^^^^^^^^^^^^^^^^^ +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 + | +LL | #[collapse_debuginfo] + | ^^^^^^^^^^^^^^^^^^^^^ +LL | +LL | fn bar(&self) {} + | ---------------- not a macro definition + +error: aborting due to 22 previous errors + diff --git a/src/test/ui/feature-gates/feature-gate-collapse_debuginfo.rs b/src/test/ui/feature-gates/feature-gate-collapse_debuginfo.rs new file mode 100644 index 00000000000..f73bf579f6d --- /dev/null +++ b/src/test/ui/feature-gates/feature-gate-collapse_debuginfo.rs @@ -0,0 +1,7 @@ +#[collapse_debuginfo] +//~^ ERROR the `#[collapse_debuginfo]` attribute is an experimental feature +macro_rules! foo { + ($e:expr) => { $e } +} + +fn main() {} diff --git a/src/test/ui/feature-gates/feature-gate-collapse_debuginfo.stderr b/src/test/ui/feature-gates/feature-gate-collapse_debuginfo.stderr new file mode 100644 index 00000000000..2cbde893af9 --- /dev/null +++ b/src/test/ui/feature-gates/feature-gate-collapse_debuginfo.stderr @@ -0,0 +1,12 @@ +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 for more information + = help: add `#![feature(collapse_debuginfo)]` to the crate attributes to enable + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0658`.