diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs index fb37c5e9c1eff..45c35959380bc 100644 --- a/compiler/rustc_span/src/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs @@ -479,6 +479,7 @@ symbols! { discriminant_type, discriminant_value, dispatch_from_dyn, + display_trait, div, div_assign, doc, diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs index 19c3385dd4cbc..285bfca3c7572 100644 --- a/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs +++ b/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs @@ -514,6 +514,31 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> { } } + // Return early if the trait is Debug or Display and the invocation + // originates within a formatting macro, because the output + // is otherwise overwhelming and unhelpful (see #85844 for an + // example). + if let Some(macro_def_id) = + obligation.cause.span.ctxt().outer_expn_data().macro_def_id + { + let trait_is_debug = + self.tcx.is_diagnostic_item(sym::debug_trait, trait_ref.def_id()); + let trait_is_display = + self.tcx.is_diagnostic_item(sym::display_trait, trait_ref.def_id()); + + let macro_is_format_args = + self.tcx.is_diagnostic_item(sym::format_args, macro_def_id); + let macro_is_format_args_nl = + self.tcx.is_diagnostic_item(sym::format_args_nl, macro_def_id); + + if (macro_is_format_args || macro_is_format_args_nl) + && (trait_is_debug || trait_is_display) + { + err.emit(); + return; + } + } + err } diff --git a/library/core/src/fmt/mod.rs b/library/core/src/fmt/mod.rs index 02ac4fb800655..1a65bf35897d3 100644 --- a/library/core/src/fmt/mod.rs +++ b/library/core/src/fmt/mod.rs @@ -564,7 +564,7 @@ impl Display for Arguments<'_> { on( crate_local, label = "`{Self}` cannot be formatted using `{{:?}}`", - note = "add `#[derive(Debug)]` or manually implement `{Debug}`" + note = "add `#[derive(Debug)]` to `{Self}` or manually implement `{Debug}` for `{Self}`" ), message = "`{Self}` doesn't implement `{Debug}`", label = "`{Self}` cannot be formatted using `{{:?}}` because it doesn't implement `{Debug}`" @@ -662,6 +662,7 @@ pub use macros::Debug; note = "in format strings you may be able to use `{{:?}}` (or {{:#?}} for pretty-print) instead" )] #[doc(alias = "{}")] +#[rustc_diagnostic_item = "display_trait"] #[stable(feature = "rust1", since = "1.0.0")] pub trait Display { /// Formats the value using the given formatter. diff --git a/library/core/src/macros/mod.rs b/library/core/src/macros/mod.rs index 7eb65483b99e7..4dd4c360948b7 100644 --- a/library/core/src/macros/mod.rs +++ b/library/core/src/macros/mod.rs @@ -825,6 +825,7 @@ pub(crate) mod builtin { #[stable(feature = "rust1", since = "1.0.0")] #[allow_internal_unstable(fmt_internals)] #[rustc_builtin_macro] + #[rustc_diagnostic_item = "format_args"] #[macro_export] macro_rules! format_args { ($fmt:expr) => {{ /* compiler built-in */ }}; @@ -840,6 +841,7 @@ pub(crate) mod builtin { )] #[allow_internal_unstable(fmt_internals)] #[rustc_builtin_macro] + #[rustc_diagnostic_item = "format_args_nl"] #[macro_export] macro_rules! format_args_nl { ($fmt:expr) => {{ /* compiler built-in */ }}; diff --git a/src/test/ui/bound-suggestions.stderr b/src/test/ui/bound-suggestions.stderr index a3177903162aa..78f62592960ff 100644 --- a/src/test/ui/bound-suggestions.stderr +++ b/src/test/ui/bound-suggestions.stderr @@ -4,7 +4,6 @@ error[E0277]: `impl Sized` doesn't implement `Debug` LL | println!("{:?}", t); | ^ `impl Sized` cannot be formatted using `{:?}` because it doesn't implement `Debug` | - = note: required by `std::fmt::Debug::fmt` = note: this error originates in the macro `$crate::format_args_nl` (in Nightly builds, run with -Z macro-backtrace for more info) help: consider further restricting this bound | @@ -17,7 +16,6 @@ error[E0277]: `T` doesn't implement `Debug` LL | println!("{:?}", t); | ^ `T` cannot be formatted using `{:?}` because it doesn't implement `Debug` | - = note: required by `std::fmt::Debug::fmt` = note: this error originates in the macro `$crate::format_args_nl` (in Nightly builds, run with -Z macro-backtrace for more info) help: consider restricting type parameter `T` | @@ -30,7 +28,6 @@ error[E0277]: `T` doesn't implement `Debug` LL | println!("{:?}", t); | ^ `T` cannot be formatted using `{:?}` because it doesn't implement `Debug` | - = note: required by `std::fmt::Debug::fmt` = note: this error originates in the macro `$crate::format_args_nl` (in Nightly builds, run with -Z macro-backtrace for more info) help: consider further restricting this bound | @@ -43,7 +40,6 @@ error[E0277]: `Y` doesn't implement `Debug` LL | println!("{:?} {:?}", x, y); | ^ `Y` cannot be formatted using `{:?}` because it doesn't implement `Debug` | - = note: required by `std::fmt::Debug::fmt` = note: this error originates in the macro `$crate::format_args_nl` (in Nightly builds, run with -Z macro-backtrace for more info) help: consider further restricting type parameter `Y` | @@ -56,7 +52,6 @@ error[E0277]: `X` doesn't implement `Debug` LL | println!("{:?}", x); | ^ `X` cannot be formatted using `{:?}` because it doesn't implement `Debug` | - = note: required by `std::fmt::Debug::fmt` = note: this error originates in the macro `$crate::format_args_nl` (in Nightly builds, run with -Z macro-backtrace for more info) help: consider further restricting this bound | @@ -69,7 +64,6 @@ error[E0277]: `X` doesn't implement `Debug` LL | println!("{:?}", x); | ^ `X` cannot be formatted using `{:?}` because it doesn't implement `Debug` | - = note: required by `std::fmt::Debug::fmt` = note: this error originates in the macro `$crate::format_args_nl` (in Nightly builds, run with -Z macro-backtrace for more info) help: consider further restricting type parameter `X` | diff --git a/src/test/ui/derives/derives-span-Debug-enum-struct-variant.stderr b/src/test/ui/derives/derives-span-Debug-enum-struct-variant.stderr index 2151335992fbc..e9f61b865fb9c 100644 --- a/src/test/ui/derives/derives-span-Debug-enum-struct-variant.stderr +++ b/src/test/ui/derives/derives-span-Debug-enum-struct-variant.stderr @@ -5,7 +5,7 @@ LL | x: Error | ^^^^^^^^ `Error` cannot be formatted using `{:?}` | = help: the trait `Debug` is not implemented for `Error` - = note: add `#[derive(Debug)]` or manually implement `Debug` + = note: add `#[derive(Debug)]` to `Error` or manually implement `Debug` for `Error` = note: required because of the requirements on the impl of `Debug` for `&Error` = note: required for the cast to the object type `dyn Debug` = note: this error originates in the derive macro `Debug` (in Nightly builds, run with -Z macro-backtrace for more info) diff --git a/src/test/ui/derives/derives-span-Debug-enum.stderr b/src/test/ui/derives/derives-span-Debug-enum.stderr index 99e618b40ece2..79fe8222cdf0c 100644 --- a/src/test/ui/derives/derives-span-Debug-enum.stderr +++ b/src/test/ui/derives/derives-span-Debug-enum.stderr @@ -5,7 +5,7 @@ LL | Error | ^^^^^ `Error` cannot be formatted using `{:?}` | = help: the trait `Debug` is not implemented for `Error` - = note: add `#[derive(Debug)]` or manually implement `Debug` + = note: add `#[derive(Debug)]` to `Error` or manually implement `Debug` for `Error` = note: required because of the requirements on the impl of `Debug` for `&Error` = note: required for the cast to the object type `dyn Debug` = note: this error originates in the derive macro `Debug` (in Nightly builds, run with -Z macro-backtrace for more info) diff --git a/src/test/ui/derives/derives-span-Debug-struct.stderr b/src/test/ui/derives/derives-span-Debug-struct.stderr index 0086642c557cc..78c98e370bd7b 100644 --- a/src/test/ui/derives/derives-span-Debug-struct.stderr +++ b/src/test/ui/derives/derives-span-Debug-struct.stderr @@ -5,7 +5,7 @@ LL | x: Error | ^^^^^^^^ `Error` cannot be formatted using `{:?}` | = help: the trait `Debug` is not implemented for `Error` - = note: add `#[derive(Debug)]` or manually implement `Debug` + = note: add `#[derive(Debug)]` to `Error` or manually implement `Debug` for `Error` = note: required because of the requirements on the impl of `Debug` for `&Error` = note: required for the cast to the object type `dyn Debug` = note: this error originates in the derive macro `Debug` (in Nightly builds, run with -Z macro-backtrace for more info) diff --git a/src/test/ui/derives/derives-span-Debug-tuple-struct.stderr b/src/test/ui/derives/derives-span-Debug-tuple-struct.stderr index 0b74908d1ee44..5e70ab760160c 100644 --- a/src/test/ui/derives/derives-span-Debug-tuple-struct.stderr +++ b/src/test/ui/derives/derives-span-Debug-tuple-struct.stderr @@ -5,7 +5,7 @@ LL | Error | ^^^^^ `Error` cannot be formatted using `{:?}` | = help: the trait `Debug` is not implemented for `Error` - = note: add `#[derive(Debug)]` or manually implement `Debug` + = note: add `#[derive(Debug)]` to `Error` or manually implement `Debug` for `Error` = note: required because of the requirements on the impl of `Debug` for `&Error` = note: required for the cast to the object type `dyn Debug` = note: this error originates in the derive macro `Debug` (in Nightly builds, run with -Z macro-backtrace for more info) diff --git a/src/test/ui/on-unimplemented/no-debug.stderr b/src/test/ui/on-unimplemented/no-debug.stderr index fe4114aeddc00..0d95441062053 100644 --- a/src/test/ui/on-unimplemented/no-debug.stderr +++ b/src/test/ui/on-unimplemented/no-debug.stderr @@ -5,8 +5,7 @@ LL | println!("{:?} {:?}", Foo, Bar); | ^^^ `Foo` cannot be formatted using `{:?}` | = help: the trait `Debug` is not implemented for `Foo` - = note: add `#[derive(Debug)]` or manually implement `Debug` - = note: required by `std::fmt::Debug::fmt` + = note: add `#[derive(Debug)]` to `Foo` or manually implement `Debug` for `Foo` = note: this error originates in the macro `$crate::format_args_nl` (in Nightly builds, run with -Z macro-backtrace for more info) error[E0277]: `Bar` doesn't implement `Debug` @@ -16,7 +15,6 @@ LL | println!("{:?} {:?}", Foo, Bar); | ^^^ `Bar` cannot be formatted using `{:?}` because it doesn't implement `Debug` | = help: the trait `Debug` is not implemented for `Bar` - = note: required by `std::fmt::Debug::fmt` = note: this error originates in the macro `$crate::format_args_nl` (in Nightly builds, run with -Z macro-backtrace for more info) error[E0277]: `Foo` doesn't implement `std::fmt::Display` @@ -27,7 +25,6 @@ LL | println!("{} {}", Foo, Bar); | = help: the trait `std::fmt::Display` is not implemented for `Foo` = note: in format strings you may be able to use `{:?}` (or {:#?} for pretty-print) instead - = note: required by `std::fmt::Display::fmt` = note: this error originates in the macro `$crate::format_args_nl` (in Nightly builds, run with -Z macro-backtrace for more info) error[E0277]: `Bar` doesn't implement `std::fmt::Display` @@ -38,7 +35,6 @@ LL | println!("{} {}", Foo, Bar); | = help: the trait `std::fmt::Display` is not implemented for `Bar` = note: in format strings you may be able to use `{:?}` (or {:#?} for pretty-print) instead - = note: required by `std::fmt::Display::fmt` = note: this error originates in the macro `$crate::format_args_nl` (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to 4 previous errors diff --git a/src/test/ui/rfc-2361-dbg-macro/dbg-macro-requires-debug.stderr b/src/test/ui/rfc-2361-dbg-macro/dbg-macro-requires-debug.stderr index 850ca30405ff1..8f9e323e90310 100644 --- a/src/test/ui/rfc-2361-dbg-macro/dbg-macro-requires-debug.stderr +++ b/src/test/ui/rfc-2361-dbg-macro/dbg-macro-requires-debug.stderr @@ -5,9 +5,7 @@ LL | let _: NotDebug = dbg!(NotDebug); | ^^^^^^^^^^^^^^ `NotDebug` cannot be formatted using `{:?}` | = help: the trait `Debug` is not implemented for `NotDebug` - = note: add `#[derive(Debug)]` or manually implement `Debug` - = note: required because of the requirements on the impl of `Debug` for `&NotDebug` - = note: required by `std::fmt::Debug::fmt` + = note: add `#[derive(Debug)]` to `NotDebug` or manually implement `Debug` for `NotDebug` = note: this error originates in the macro `$crate::format_args_nl` (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to previous error diff --git a/src/test/ui/suggestions/path-display.stderr b/src/test/ui/suggestions/path-display.stderr index 80ed1cdedf1e7..25c73c4c8741a 100644 --- a/src/test/ui/suggestions/path-display.stderr +++ b/src/test/ui/suggestions/path-display.stderr @@ -6,8 +6,6 @@ LL | println!("{}", path); | = help: the trait `std::fmt::Display` is not implemented for `Path` = note: call `.display()` or `.to_string_lossy()` to safely print paths, as they may contain non-Unicode data - = note: required because of the requirements on the impl of `std::fmt::Display` for `&Path` - = note: required by `std::fmt::Display::fmt` = note: this error originates in the macro `$crate::format_args_nl` (in Nightly builds, run with -Z macro-backtrace for more info) error: aborting due to previous error