diff --git a/compiler/rustc_attr_parsing/src/attributes/diagnostic/mod.rs b/compiler/rustc_attr_parsing/src/attributes/diagnostic/mod.rs index 435367e7dcfbe..2486b5e3a65ed 100644 --- a/compiler/rustc_attr_parsing/src/attributes/diagnostic/mod.rs +++ b/compiler/rustc_attr_parsing/src/attributes/diagnostic/mod.rs @@ -28,6 +28,7 @@ pub(crate) mod on_type_error; pub(crate) mod on_unimplemented; pub(crate) mod on_unknown; pub(crate) mod on_unmatched_args; +pub(crate) mod opaque; #[derive(Copy, Clone)] pub(crate) enum Mode { diff --git a/compiler/rustc_attr_parsing/src/attributes/diagnostic/opaque.rs b/compiler/rustc_attr_parsing/src/attributes/diagnostic/opaque.rs new file mode 100644 index 0000000000000..0a18b69dda0ed --- /dev/null +++ b/compiler/rustc_attr_parsing/src/attributes/diagnostic/opaque.rs @@ -0,0 +1,64 @@ +use rustc_feature::AttributeStability; +use rustc_hir::Target; +use rustc_hir::attrs::AttributeKind; +use rustc_session::lint::builtin::MALFORMED_DIAGNOSTIC_ATTRIBUTES; +use rustc_span::{Span, sym}; + +use crate::attributes::{AcceptMapping, AttributeParser}; +use crate::context::{AcceptContext, FinalizeContext}; +use crate::diagnostics::OpaqueDoesNotExpectArgs; +use crate::parser::ArgParser; +use crate::target_checking::AllowedTargets; +use crate::target_checking::Policy::Allow; +use crate::{template, unstable}; + +#[derive(Default)] +pub(crate) struct OpaqueParser { + attr_span: Option, +} + +impl AttributeParser for OpaqueParser { + const ATTRIBUTES: AcceptMapping = &[ + ( + &[sym::diagnostic, sym::opaque], + template!(Word), + AttributeStability::Stable, // Unstable, stability checked manually in the parser + |this, cx, args| { + if !cx.features().diagnostic_opaque() { + return; + } + this.parse(cx, args); + }, + ), + ( + // For use on exported macros, where using tool attributes is an error. + &[sym::rustc_diagnostic_opaque], + template!(Word), + unstable!( + rustc_attrs, + "see `#[diagnostic::opaque]` for the nightly equivalent of this attribute" + ), + OpaqueParser::parse, + ), + ]; + const ALLOWED_TARGETS: AllowedTargets<'_> = + AllowedTargets::AllowListWarnRest(&[Allow(Target::MacroDef)]); + + fn finalize(self, _cx: &FinalizeContext<'_, '_>) -> Option { + if let Some(_) = self.attr_span { Some(AttributeKind::Opaque) } else { None } + } +} + +impl OpaqueParser { + fn parse<'sess>(&mut self, cx: &mut AcceptContext<'_, 'sess>, args: &ArgParser) { + let attr_span = cx.attr_span; + if let Some(earlier_span) = self.attr_span { + cx.warn_unused_duplicate(earlier_span, attr_span); + } + self.attr_span = Some(attr_span); + + if !matches!(args, ArgParser::NoArgs) { + cx.emit_lint(MALFORMED_DIAGNOSTIC_ATTRIBUTES, OpaqueDoesNotExpectArgs, attr_span); + } + } +} diff --git a/compiler/rustc_attr_parsing/src/context.rs b/compiler/rustc_attr_parsing/src/context.rs index 1595d2f80ddc7..a14a8d4381a0b 100644 --- a/compiler/rustc_attr_parsing/src/context.rs +++ b/compiler/rustc_attr_parsing/src/context.rs @@ -36,6 +36,7 @@ use crate::attributes::diagnostic::on_type_error::*; use crate::attributes::diagnostic::on_unimplemented::*; use crate::attributes::diagnostic::on_unknown::*; use crate::attributes::diagnostic::on_unmatched_args::*; +use crate::attributes::diagnostic::opaque::*; use crate::attributes::doc::*; use crate::attributes::dummy::*; use crate::attributes::inline::*; @@ -151,6 +152,7 @@ attribute_parsers!( OnUnimplementedParser, OnUnknownParser, OnUnmatchedArgsParser, + OpaqueParser, RustcAlignParser, RustcAlignStaticParser, RustcCguTestAttributeParser, diff --git a/compiler/rustc_attr_parsing/src/diagnostics.rs b/compiler/rustc_attr_parsing/src/diagnostics.rs index 50667952b814d..e360f5221c138 100644 --- a/compiler/rustc_attr_parsing/src/diagnostics.rs +++ b/compiler/rustc_attr_parsing/src/diagnostics.rs @@ -279,6 +279,10 @@ pub(crate) struct AttrCrateLevelOnly; #[diag("`#[diagnostic::do_not_recommend]` does not expect any arguments")] pub(crate) struct DoNotRecommendDoesNotExpectArgs; +#[derive(Diagnostic)] +#[diag("`#[diagnostic::opaque]` does not expect any arguments")] +pub(crate) struct OpaqueDoesNotExpectArgs; + #[derive(Diagnostic)] #[diag("invalid `crate_type` value")] pub(crate) struct UnknownCrateTypes { diff --git a/compiler/rustc_errors/src/emitter.rs b/compiler/rustc_errors/src/emitter.rs index fa3ff21b2726f..6d5f8462ff496 100644 --- a/compiler/rustc_errors/src/emitter.rs +++ b/compiler/rustc_errors/src/emitter.rs @@ -175,7 +175,7 @@ pub trait Emitter { ExpnKind::Desugaring(..) | ExpnKind::AstPass(..) => None, ExpnKind::Macro(macro_kind, name) => { - Some((macro_kind, name, expn_data.hide_backtrace)) + Some((macro_kind, name, expn_data.diagnostic_opaque)) } } }) @@ -188,8 +188,7 @@ pub trait Emitter { self.render_multispans_macro_backtrace(span, children, backtrace); if !backtrace { - // Skip builtin macros, as their expansion isn't relevant to the end user. This includes - // actual intrinsics, like `asm!`. + // Skip macros annotated with `#[diagnostic::opaque]`. Builtin macros are "opaque" too. if let Some((macro_kind, name, _)) = has_macro_spans.first() && let Some((_, _, false)) = has_macro_spans.last() { @@ -334,6 +333,13 @@ pub trait Emitter { // we move these spans from the external macros to their corresponding use site. fn fix_multispan_in_extern_macros(&self, span: &mut MultiSpan) { let Some(source_map) = self.source_map() else { return }; + let should_hide = |span| { + source_map.is_imported(span) || { + let expn = span.data().ctxt.outer_expn_data(); + expn.diagnostic_opaque && matches!(expn.kind, ExpnKind::Macro(MacroKind::Bang, _)) + } + }; + // First, find all the spans in external macros and point instead at their use site. let replacements: Vec<(Span, Span)> = span .primary_spans() @@ -341,11 +347,11 @@ pub trait Emitter { .copied() .chain(span.span_labels().iter().map(|sp_label| sp_label.span)) .filter_map(|sp| { - if !sp.is_dummy() && source_map.is_imported(sp) { + if !sp.is_dummy() && should_hide(sp) { let mut span = sp; while let Some(callsite) = span.parent_callsite() { span = callsite; - if !source_map.is_imported(span) { + if !should_hide(span) { return Some((sp, span)); } } diff --git a/compiler/rustc_expand/src/base.rs b/compiler/rustc_expand/src/base.rs index ee516991cfbfc..323299c74d6fb 100644 --- a/compiler/rustc_expand/src/base.rs +++ b/compiler/rustc_expand/src/base.rs @@ -804,9 +804,9 @@ pub struct SyntaxExtension { /// 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, - /// Suppresses the "this error originates in the macro" note when a diagnostic points at this - /// macro. - pub hide_backtrace: bool, + /// Prevents diagnostics pointing into this macro and suppresses the "this error originates in + /// the macro" note when a diagnostic points at this macro. + pub diagnostic_opaque: bool, } impl SyntaxExtension { @@ -840,7 +840,7 @@ impl SyntaxExtension { allow_internal_unsafe: false, local_inner_macros: false, collapse_debuginfo: false, - hide_backtrace: false, + diagnostic_opaque: false, } } @@ -870,12 +870,6 @@ impl SyntaxExtension { collapse_table[flag as usize][attr as usize] } - fn get_hide_backtrace(attrs: &[hir::Attribute]) -> bool { - // FIXME(estebank): instead of reusing `#[rustc_diagnostic_item]` as a proxy, introduce a - // new attribute purely for this under the `#[diagnostic]` namespace. - find_attr!(attrs, RustcDiagnosticItem(..)) - } - /// Constructs a syntax extension with the given properties /// and other properties converted from attributes. pub fn new( @@ -910,7 +904,8 @@ impl SyntaxExtension { // Not a built-in macro None => (None, helper_attrs), }; - let hide_backtrace = builtin_name.is_some() || Self::get_hide_backtrace(attrs); + let diagnostic_opaque = builtin_name.is_some() + || (!sess.opts.unstable_opts.macro_backtrace && find_attr!(attrs, Opaque)); let stability = find_attr!(attrs, Stability { stability, .. } => *stability); @@ -938,7 +933,7 @@ impl SyntaxExtension { allow_internal_unsafe, local_inner_macros, collapse_debuginfo, - hide_backtrace, + diagnostic_opaque, } } @@ -1024,7 +1019,7 @@ impl SyntaxExtension { self.allow_internal_unsafe, self.local_inner_macros, self.collapse_debuginfo, - self.hide_backtrace, + self.diagnostic_opaque, ) } } diff --git a/compiler/rustc_feature/src/builtin_attrs.rs b/compiler/rustc_feature/src/builtin_attrs.rs index e081c2989d3c6..be6979314b53a 100644 --- a/compiler/rustc_feature/src/builtin_attrs.rs +++ b/compiler/rustc_feature/src/builtin_attrs.rs @@ -320,6 +320,7 @@ pub static BUILTIN_ATTRIBUTES: &[Symbol] = &[ // Used by the `rustc::bad_opt_access` lint on fields // types (as well as any others in future). sym::rustc_lint_opt_deny_field_access, + sym::rustc_diagnostic_opaque, // ========================================================================== // Internal attributes, Const related: diff --git a/compiler/rustc_feature/src/unstable.rs b/compiler/rustc_feature/src/unstable.rs index fc38d9de6e143..4c5e999117248 100644 --- a/compiler/rustc_feature/src/unstable.rs +++ b/compiler/rustc_feature/src/unstable.rs @@ -518,6 +518,8 @@ declare_features! ( (unstable, diagnostic_on_unknown, "1.96.0", Some(152900)), /// Allows macros to customize macro argument matcher diagnostics. (unstable, diagnostic_on_unmatched_args, "1.97.0", Some(155642)), + // Used by macros to not show their bodies in error messages. No-op with `-Z macro-backtrace`. + (unstable, diagnostic_opaque, "CURRENT_RUSTC_VERSION", Some(158813)), /// Allows `#[doc(cfg(...))]`. (unstable, doc_cfg, "1.21.0", Some(43781)), /// Allows `#[doc(masked)]`. diff --git a/compiler/rustc_hir/src/attrs/data_structures.rs b/compiler/rustc_hir/src/attrs/data_structures.rs index 17d00863d99d5..3e8c11f0166c1 100644 --- a/compiler/rustc_hir/src/attrs/data_structures.rs +++ b/compiler/rustc_hir/src/attrs/data_structures.rs @@ -1263,6 +1263,9 @@ pub enum AttributeKind { directive: Option>, }, + /// Represents `#[diagnostic::opaque]`. + Opaque, + /// Represents `#[optimize(size|speed)]` Optimize(OptimizeAttr, Span), diff --git a/compiler/rustc_hir/src/attrs/encode_cross_crate.rs b/compiler/rustc_hir/src/attrs/encode_cross_crate.rs index f5a6eeec07406..100979b8159d3 100644 --- a/compiler/rustc_hir/src/attrs/encode_cross_crate.rs +++ b/compiler/rustc_hir/src/attrs/encode_cross_crate.rs @@ -83,6 +83,7 @@ impl AttributeKind { OnUnimplemented { .. } => Yes, OnUnknown { .. } => Yes, OnUnmatchedArgs { .. } => Yes, + Opaque => Yes, Optimize(..) => No, PanicRuntime => No, PatchableFunctionEntry { .. } => Yes, diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs index 7ae6005e9bc98..90339d5bac686 100644 --- a/compiler/rustc_passes/src/check_attr.rs +++ b/compiler/rustc_passes/src/check_attr.rs @@ -296,6 +296,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> { AttributeKind::NoStd { .. } => (), AttributeKind::OnUnknown { .. } => (), AttributeKind::OnUnmatchedArgs { .. } => (), + AttributeKind::Opaque => (), AttributeKind::Optimize(..) => (), AttributeKind::PanicRuntime => (), AttributeKind::PatchableFunctionEntry { .. } => (), diff --git a/compiler/rustc_resolve/src/macros.rs b/compiler/rustc_resolve/src/macros.rs index 595c2fdf011dd..171b2cfc0d9ab 100644 --- a/compiler/rustc_resolve/src/macros.rs +++ b/compiler/rustc_resolve/src/macros.rs @@ -721,6 +721,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { (sym::on_unknown, Some(sym::diagnostic_on_unknown)), (sym::on_unmatched_args, Some(sym::diagnostic_on_unmatched_args)), (sym::on_type_error, Some(sym::diagnostic_on_type_error)), + (sym::opaque, Some(sym::diagnostic_opaque)), ]; if res == Res::NonMacroAttr(NonMacroAttrKind::Tool) diff --git a/compiler/rustc_span/src/hygiene.rs b/compiler/rustc_span/src/hygiene.rs index 1c742052783cd..1cdce5cd04567 100644 --- a/compiler/rustc_span/src/hygiene.rs +++ b/compiler/rustc_span/src/hygiene.rs @@ -1020,8 +1020,9 @@ pub struct ExpnData { /// Should debuginfo for the macro be collapsed to the outermost expansion site (in other /// words, was the macro definition annotated with `#[collapse_debuginfo]`)? pub(crate) collapse_debuginfo: bool, - /// When true, we do not display the note telling people to use the `-Zmacro-backtrace` flag. - pub hide_backtrace: bool, + /// When true, we prevent diagnostics pointing into this macro, if it is one, and we do not + /// display the note telling people to use the `-Zmacro-backtrace` flag. + pub diagnostic_opaque: bool, } impl !PartialEq for ExpnData {} @@ -1040,7 +1041,7 @@ impl ExpnData { allow_internal_unsafe: bool, local_inner_macros: bool, collapse_debuginfo: bool, - hide_backtrace: bool, + diagnostic_opaque: bool, ) -> ExpnData { ExpnData { kind, @@ -1055,7 +1056,7 @@ impl ExpnData { allow_internal_unsafe, local_inner_macros, collapse_debuginfo, - hide_backtrace, + diagnostic_opaque, } } @@ -1080,7 +1081,7 @@ impl ExpnData { allow_internal_unsafe: false, local_inner_macros: false, collapse_debuginfo: false, - hide_backtrace: false, + diagnostic_opaque: false, } } diff --git a/compiler/rustc_span/src/lib.rs b/compiler/rustc_span/src/lib.rs index 5015741f10c5f..80d40c2f4c5b5 100644 --- a/compiler/rustc_span/src/lib.rs +++ b/compiler/rustc_span/src/lib.rs @@ -1238,20 +1238,25 @@ impl Span { /// If "self" is the span of the outer_ident, and "within" is the span of the `($ident,)` /// expr, then this will return the span of the `$ident` macro variable. pub fn within_macro(self, within: Span, sm: &SourceMap) -> Option { - match Span::prepare_to_combine(self, within) { - // Only return something if it doesn't overlap with the original span, - // and the span isn't "imported" (i.e. from unavailable sources). - // FIXME: This does limit the usefulness of the error when the macro is - // from a foreign crate; we could also take into account `-Zmacro-backtrace`, - // which doesn't redact this span (but that would mean passing in even more - // args to this function, lol). - Ok((self_, _, parent)) - if self_.hi < self.lo() || self.hi() < self_.lo && !sm.is_imported(within) => - { - Some(Span::new(self_.lo, self_.hi, self_.ctxt, parent)) - } - _ => None, + let (self_, _, parent) = Span::prepare_to_combine(self, within).ok()?; + + // Only return something if it doesn't overlap with the original span + // and the span isn't "imported" (i.e. from unavailable sources). + // FIXME: This does limit the usefulness of the error when the macro is + // from a foreign crate; we could also take into account `-Zmacro-backtrace`, + // which doesn't redact this span (but that would mean passing in even more + // args to this function, lol). + if self.data().contains(self_) || sm.is_imported(within) { + return None; } + + // Don't return something if it's marked with `#[diagnostic::opaque]`. + // This already accounts for `-Zmacro-backtrace`. + if within.data().ctxt.outer_expn_data().diagnostic_opaque { + return None; + } + + Some(Span::new(self_.lo, self_.hi, self_.ctxt, parent)) } pub fn from_inner(self, inner: InnerSpan) -> Span { diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs index 71eae246ebaff..6ba3112f3e7e0 100644 --- a/compiler/rustc_span/src/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs @@ -819,6 +819,7 @@ symbols! { diagnostic_on_unknown, diagnostic_on_unmatch_args, diagnostic_on_unmatched_args, + diagnostic_opaque, dialect, direct, discriminant_kind, @@ -1775,6 +1776,7 @@ symbols! { rustc_deprecated_safe_2024, rustc_diagnostic_item, rustc_diagnostic_macros, + rustc_diagnostic_opaque, rustc_do_not_const_check, rustc_doc_primitive, rustc_driver, diff --git a/library/alloc/src/macros.rs b/library/alloc/src/macros.rs index b99107fb345a4..d93e279df7cfb 100644 --- a/library/alloc/src/macros.rs +++ b/library/alloc/src/macros.rs @@ -39,6 +39,7 @@ #[stable(feature = "rust1", since = "1.0.0")] #[rustc_diagnostic_item = "vec_macro"] #[allow_internal_unstable(rustc_attrs, liballoc_internals)] +#[rustc_diagnostic_opaque] macro_rules! vec { () => ( $crate::vec::Vec::new() @@ -108,6 +109,7 @@ macro_rules! vec { #[stable(feature = "rust1", since = "1.0.0")] #[allow_internal_unstable(hint_must_use, liballoc_internals)] #[rustc_diagnostic_item = "format_macro"] +#[rustc_diagnostic_opaque] macro_rules! format { ($($arg:tt)*) => { $crate::__export::must_use({ diff --git a/library/core/src/lib.rs b/library/core/src/lib.rs index 8e310cc7d2155..7aab486903a06 100644 --- a/library/core/src/lib.rs +++ b/library/core/src/lib.rs @@ -121,6 +121,7 @@ #![feature(derive_const)] #![feature(diagnostic_on_const)] #![feature(diagnostic_on_unmatched_args)] +#![feature(diagnostic_opaque)] #![feature(doc_cfg)] #![feature(doc_notable_trait)] #![feature(extern_types)] diff --git a/library/core/src/macros/mod.rs b/library/core/src/macros/mod.rs index 932a2fc0bad92..4b1ce0351f7d7 100644 --- a/library/core/src/macros/mod.rs +++ b/library/core/src/macros/mod.rs @@ -39,6 +39,7 @@ macro_rules! panic { #[stable(feature = "rust1", since = "1.0.0")] #[rustc_diagnostic_item = "assert_eq_macro"] #[allow_internal_unstable(panic_internals)] +#[rustc_diagnostic_opaque] macro_rules! assert_eq { ($left:expr, $right:expr $(,)?) => {{ match (&$left, &$right) { @@ -95,6 +96,7 @@ macro_rules! assert_eq { #[stable(feature = "assert_ne", since = "1.13.0")] #[rustc_diagnostic_item = "assert_ne_macro"] #[allow_internal_unstable(panic_internals)] +#[rustc_diagnostic_opaque] macro_rules! assert_ne { ($left:expr, $right:expr $(,)?) => {{ match (&$left, &$right) { @@ -284,6 +286,7 @@ pub macro cfg_select($($tt:tt)*) { #[stable(feature = "rust1", since = "1.0.0")] #[rustc_diagnostic_item = "debug_assert_macro"] #[allow_internal_unstable(edition_panic)] +#[rustc_diagnostic_opaque] macro_rules! debug_assert { ($($arg:tt)*) => { if $crate::cfg!(debug_assertions) { @@ -424,6 +427,7 @@ pub macro debug_assert_matches($($arg:tt)*) { #[stable(feature = "matches_macro", since = "1.42.0")] #[rustc_diagnostic_item = "matches_macro"] #[allow_internal_unstable(non_exhaustive_omitted_patterns_lint, stmt_expr_attributes)] +#[rustc_diagnostic_opaque] macro_rules! matches { ($expression:expr, $pattern:pat $(if $guard:expr)? $(,)?) => { #[allow(non_exhaustive_omitted_patterns)] @@ -600,6 +604,7 @@ macro_rules! r#try { #[macro_export] #[stable(feature = "rust1", since = "1.0.0")] #[rustc_diagnostic_item = "write_macro"] +#[rustc_diagnostic_opaque] macro_rules! write { ($dst:expr, $($arg:tt)*) => { $dst.write_fmt($crate::format_args!($($arg)*)) @@ -638,6 +643,7 @@ macro_rules! write { #[stable(feature = "rust1", since = "1.0.0")] #[rustc_diagnostic_item = "writeln_macro"] #[allow_internal_unstable(format_args_nl)] +#[rustc_diagnostic_opaque] macro_rules! writeln { ($dst:expr $(,)?) => { $crate::write!($dst, "\n") @@ -793,6 +799,7 @@ macro_rules! unreachable { #[stable(feature = "rust1", since = "1.0.0")] #[rustc_diagnostic_item = "unimplemented_macro"] #[allow_internal_unstable(panic_internals)] +#[rustc_diagnostic_opaque] macro_rules! unimplemented { () => { $crate::panicking::panic("not implemented") @@ -873,6 +880,7 @@ macro_rules! unimplemented { #[stable(feature = "todo_macro", since = "1.40.0")] #[rustc_diagnostic_item = "todo_macro"] #[allow_internal_unstable(panic_internals)] +#[rustc_diagnostic_opaque] macro_rules! todo { () => { $crate::panicking::panic("not yet implemented") diff --git a/library/core/src/pin.rs b/library/core/src/pin.rs index 40f774806046a..b766a767df64d 100644 --- a/library/core/src/pin.rs +++ b/library/core/src/pin.rs @@ -2025,6 +2025,7 @@ unsafe impl PinCoerceUnsized for Pin {} #[rustc_diagnostic_item = "pin_macro"] // `super` gets removed by rustfmt #[rustfmt::skip] +#[diagnostic::opaque] pub macro pin($value:expr $(,)?) { 'p: { super let mut pinned = $value; diff --git a/library/std/src/macros.rs b/library/std/src/macros.rs index 8bcf870e9aeb4..64415809b4a33 100644 --- a/library/std/src/macros.rs +++ b/library/std/src/macros.rs @@ -82,6 +82,7 @@ macro_rules! panic { #[stable(feature = "rust1", since = "1.0.0")] #[cfg_attr(not(test), rustc_diagnostic_item = "print_macro")] #[allow_internal_unstable(print_internals)] +#[rustc_diagnostic_opaque] macro_rules! print { ($($arg:tt)*) => {{ $crate::io::_print($crate::format_args!($($arg)*)); @@ -138,6 +139,7 @@ macro_rules! print { #[stable(feature = "rust1", since = "1.0.0")] #[cfg_attr(not(test), rustc_diagnostic_item = "println_macro")] #[allow_internal_unstable(print_internals, format_args_nl)] +#[rustc_diagnostic_opaque] macro_rules! println { () => { $crate::print!("\n") @@ -352,6 +354,7 @@ macro_rules! eprintln { #[macro_export] #[cfg_attr(not(test), rustc_diagnostic_item = "dbg_macro")] #[stable(feature = "dbg_macro", since = "1.32.0")] +#[rustc_diagnostic_opaque] macro_rules! dbg { // NOTE: We cannot use `concat!` to make a static string as a format argument // of `eprintln!` because `file!` could contain a `{` or diff --git a/library/std/src/thread/local.rs b/library/std/src/thread/local.rs index ec0ba9970e479..9365e54765d4c 100644 --- a/library/std/src/thread/local.rs +++ b/library/std/src/thread/local.rs @@ -346,6 +346,7 @@ pub macro thread_local_process_attrs { #[stable(feature = "rust1", since = "1.0.0")] #[cfg_attr(not(test), rustc_diagnostic_item = "thread_local_macro")] #[allow_internal_unstable(thread_local_internals)] +#[rustc_diagnostic_opaque] macro_rules! thread_local { () => {}; diff --git a/tests/ui/diagnostic_namespace/opaque/auxiliary/wrap.rs b/tests/ui/diagnostic_namespace/opaque/auxiliary/wrap.rs new file mode 100644 index 0000000000000..f046e82b8f9e7 --- /dev/null +++ b/tests/ui/diagnostic_namespace/opaque/auxiliary/wrap.rs @@ -0,0 +1,9 @@ +#![feature(diagnostic_opaque)] + +#[diagnostic::opaque] +#[macro_export] +macro_rules! wrap { + ($x:ident) => {{ + let x = blah::$x; + }}; +} diff --git a/tests/ui/diagnostic_namespace/opaque/duplicate.rs b/tests/ui/diagnostic_namespace/opaque/duplicate.rs new file mode 100644 index 0000000000000..2341e72ddc5e3 --- /dev/null +++ b/tests/ui/diagnostic_namespace/opaque/duplicate.rs @@ -0,0 +1,9 @@ +#![crate_type = "lib"] +#![feature(diagnostic_opaque)] +#![deny(unused_attributes)] +#[diagnostic::opaque] +#[diagnostic::opaque] +//~^ERROR unused attribute +macro_rules! m { + () => {} +} diff --git a/tests/ui/diagnostic_namespace/opaque/duplicate.stderr b/tests/ui/diagnostic_namespace/opaque/duplicate.stderr new file mode 100644 index 0000000000000..d4420d3b63a9f --- /dev/null +++ b/tests/ui/diagnostic_namespace/opaque/duplicate.stderr @@ -0,0 +1,19 @@ +error: unused attribute + --> $DIR/duplicate.rs:5:1 + | +LL | #[diagnostic::opaque] + | ^^^^^^^^^^^^^^^^^^^^^ help: remove this attribute + | +note: attribute also specified here + --> $DIR/duplicate.rs:4:1 + | +LL | #[diagnostic::opaque] + | ^^^^^^^^^^^^^^^^^^^^^ +note: the lint level is defined here + --> $DIR/duplicate.rs:3:9 + | +LL | #![deny(unused_attributes)] + | ^^^^^^^^^^^^^^^^^ + +error: aborting due to 1 previous error + diff --git a/tests/ui/diagnostic_namespace/opaque/highlight_maccall.-Zmacro-backtrace.stderr b/tests/ui/diagnostic_namespace/opaque/highlight_maccall.-Zmacro-backtrace.stderr new file mode 100644 index 0000000000000..d53e5cb526061 --- /dev/null +++ b/tests/ui/diagnostic_namespace/opaque/highlight_maccall.-Zmacro-backtrace.stderr @@ -0,0 +1,16 @@ +error: oh no + --> $DIR/highlight_maccall.rs:9:9 + | +LL | / macro_rules! my_error { +LL | | () => {{ +LL | | compile_error!("oh no") + | | ^^^^^^^^^^^^^^^^^^^^^^^ +... | +LL | | } + | |_- in this expansion of `my_error!` +... +LL | my_error!(); + | ----------- in this macro invocation + +error: aborting due to 1 previous error + diff --git a/tests/ui/diagnostic_namespace/opaque/highlight_maccall.default.stderr b/tests/ui/diagnostic_namespace/opaque/highlight_maccall.default.stderr new file mode 100644 index 0000000000000..07521e003e3e2 --- /dev/null +++ b/tests/ui/diagnostic_namespace/opaque/highlight_maccall.default.stderr @@ -0,0 +1,8 @@ +error: oh no + --> $DIR/highlight_maccall.rs:16:5 + | +LL | my_error!(); + | ^^^^^^^^^^^ + +error: aborting due to 1 previous error + diff --git a/tests/ui/diagnostic_namespace/opaque/highlight_maccall.rs b/tests/ui/diagnostic_namespace/opaque/highlight_maccall.rs new file mode 100644 index 0000000000000..f8095838b2368 --- /dev/null +++ b/tests/ui/diagnostic_namespace/opaque/highlight_maccall.rs @@ -0,0 +1,17 @@ +//@revisions: default -Zmacro-backtrace +//@[-Zmacro-backtrace] compile-flags: -Z macro-backtrace + +#![feature(diagnostic_opaque)] + +#[diagnostic::opaque] +macro_rules! my_error { + () => {{ + compile_error!("oh no") + //~^ ERROR oh no + }} +} + + +fn main() { + my_error!(); +} diff --git a/tests/ui/diagnostic_namespace/opaque/only_point_at_input.-Zmacro-backtrace.stderr b/tests/ui/diagnostic_namespace/opaque/only_point_at_input.-Zmacro-backtrace.stderr new file mode 100644 index 0000000000000..47ed10e2bcfdc --- /dev/null +++ b/tests/ui/diagnostic_namespace/opaque/only_point_at_input.-Zmacro-backtrace.stderr @@ -0,0 +1,18 @@ +error[E0425]: cannot find value `x` in module `blah` + --> $DIR/only_point_at_input.rs:17:17 + | +LL | wrap::wrap!(x); + | ^ not found in `blah` + +error[E0425]: cannot find value `x` in module `blah` + --> $DIR/only_point_at_input.rs:20:17 + | +LL | let x = blah::$x; + | -- due to this macro variable +... +LL | local_wrap!(x); + | ^ not found in `blah` + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0425`. diff --git a/tests/ui/diagnostic_namespace/opaque/only_point_at_input.default.stderr b/tests/ui/diagnostic_namespace/opaque/only_point_at_input.default.stderr new file mode 100644 index 0000000000000..366e1c3aead24 --- /dev/null +++ b/tests/ui/diagnostic_namespace/opaque/only_point_at_input.default.stderr @@ -0,0 +1,15 @@ +error[E0425]: cannot find value `x` in module `blah` + --> $DIR/only_point_at_input.rs:17:17 + | +LL | wrap::wrap!(x); + | ^ not found in `blah` + +error[E0425]: cannot find value `x` in module `blah` + --> $DIR/only_point_at_input.rs:20:17 + | +LL | local_wrap!(x); + | ^ not found in `blah` + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0425`. diff --git a/tests/ui/diagnostic_namespace/opaque/only_point_at_input.rs b/tests/ui/diagnostic_namespace/opaque/only_point_at_input.rs new file mode 100644 index 0000000000000..003b6dbacf6c0 --- /dev/null +++ b/tests/ui/diagnostic_namespace/opaque/only_point_at_input.rs @@ -0,0 +1,23 @@ +//@revisions: default -Zmacro-backtrace +//@[-Zmacro-backtrace] compile-flags: -Z macro-backtrace +//@ aux-crate:wrap=wrap.rs +#![feature(diagnostic_opaque)] + +mod blah {} + +#[diagnostic::opaque] +macro_rules! local_wrap { + ($x:ident) => {{ + let x = blah::$x; + }}; +} + + +fn main() { + wrap::wrap!(x); + //~^ ERROR cannot find value `x` in module `blah` + + local_wrap!(x); + //~^ ERROR cannot find value `x` in module `blah` + +} diff --git a/tests/ui/feature-gates/feature-gate-diagnostic-opaque.rs b/tests/ui/feature-gates/feature-gate-diagnostic-opaque.rs new file mode 100644 index 0000000000000..0dc3a4569098f --- /dev/null +++ b/tests/ui/feature-gates/feature-gate-diagnostic-opaque.rs @@ -0,0 +1,13 @@ +#![crate_type = "lib"] +#![feature(decl_macro)] +#![deny(unknown_diagnostic_attributes)] + +#[diagnostic::opaque] +//~^ ERROR unknown diagnostic attribute +macro_rules! foo { + () => {} +} + +#[diagnostic::opaque] +//~^ ERROR unknown diagnostic attribute +macro bar() {} diff --git a/tests/ui/feature-gates/feature-gate-diagnostic-opaque.stderr b/tests/ui/feature-gates/feature-gate-diagnostic-opaque.stderr new file mode 100644 index 0000000000000..90426a1324e81 --- /dev/null +++ b/tests/ui/feature-gates/feature-gate-diagnostic-opaque.stderr @@ -0,0 +1,23 @@ +error: unknown diagnostic attribute + --> $DIR/feature-gate-diagnostic-opaque.rs:5:15 + | +LL | #[diagnostic::opaque] + | ^^^^^^ + | + = help: add `#![feature(diagnostic_opaque)]` to the crate attributes to enable +note: the lint level is defined here + --> $DIR/feature-gate-diagnostic-opaque.rs:3:9 + | +LL | #![deny(unknown_diagnostic_attributes)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: unknown diagnostic attribute + --> $DIR/feature-gate-diagnostic-opaque.rs:11:15 + | +LL | #[diagnostic::opaque] + | ^^^^^^ + | + = help: add `#![feature(diagnostic_opaque)]` to the crate attributes to enable + +error: aborting due to 2 previous errors + diff --git a/tests/ui/include-macros/mismatched-types.stderr b/tests/ui/include-macros/mismatched-types.stderr index 4fab832c2d8e8..ab6b599c2beda 100644 --- a/tests/ui/include-macros/mismatched-types.stderr +++ b/tests/ui/include-macros/mismatched-types.stderr @@ -1,13 +1,8 @@ error[E0308]: mismatched types - --> $DIR/file.txt:0:1 - | -LL | - | ^ expected `&[u8]`, found `&str` - | - ::: $DIR/mismatched-types.rs:2:12 + --> $DIR/mismatched-types.rs:2:20 | LL | let b: &[u8] = include_str!("file.txt"); - | ----- ------------------------ in this macro invocation + | ----- ^^^^^^^^^^^^^^^^^^^^^^^^ expected `&[u8]`, found `&str` | | | expected due to this |