diff --git a/impl/src/fmt.rs b/impl/src/fmt.rs index 82fc68e..3860b4e 100644 --- a/impl/src/fmt.rs +++ b/impl/src/fmt.rs @@ -3,7 +3,7 @@ use crate::attr::{Display, Trait}; use crate::scan_expr::scan_expr; use crate::unraw::{IdentUnraw, MemberUnraw}; use proc_macro2::{Delimiter, TokenStream, TokenTree}; -use quote::{format_ident, quote, quote_spanned}; +use quote::{format_ident, quote, quote_spanned, ToTokens as _}; use std::collections::{BTreeSet, HashMap}; use std::iter; use syn::ext::IdentExt; @@ -114,6 +114,8 @@ impl Display<'_> { } let formatvar_prefix = if bonus_display { "__display" + } else if bound == Trait::Pointer { + "__pointer" } else { "__field" }; @@ -137,8 +139,10 @@ impl Display<'_> { }; let wrapped_binding_value = if bonus_display { quote_spanned!(span=> #binding_value.as_display()) - } else { + } else if bound == Trait::Pointer { quote!(::thiserror::__private::Var(#binding_value)) + } else { + binding_value.into_token_stream() }; has_bonus_display |= bonus_display; bindings.push((formatvar.to_local(), wrapped_binding_value)); diff --git a/src/var.rs b/src/var.rs index 8643590..ecfcd85 100644 --- a/src/var.rs +++ b/src/var.rs @@ -1,61 +1,9 @@ -use core::fmt::{ - self, Binary, Debug, Display, LowerExp, LowerHex, Octal, Pointer, UpperExp, UpperHex, -}; +use core::fmt::{self, Pointer}; pub struct Var<'a, T: ?Sized>(pub &'a T); -/// Pointer is the only one for which there is a difference in behavior between -/// `Var<'a, T>` vs `&'a T`. impl<'a, T: Pointer + ?Sized> Pointer for Var<'a, T> { fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result { Pointer::fmt(self.0, formatter) } } - -impl<'a, T: Binary + ?Sized> Binary for Var<'a, T> { - fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result { - Binary::fmt(self.0, formatter) - } -} - -impl<'a, T: Debug + ?Sized> Debug for Var<'a, T> { - fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result { - Debug::fmt(self.0, formatter) - } -} - -impl<'a, T: Display + ?Sized> Display for Var<'a, T> { - fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result { - Display::fmt(self.0, formatter) - } -} - -impl<'a, T: LowerExp + ?Sized> LowerExp for Var<'a, T> { - fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result { - LowerExp::fmt(self.0, formatter) - } -} - -impl<'a, T: LowerHex + ?Sized> LowerHex for Var<'a, T> { - fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result { - LowerHex::fmt(self.0, formatter) - } -} - -impl<'a, T: Octal + ?Sized> Octal for Var<'a, T> { - fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result { - Octal::fmt(self.0, formatter) - } -} - -impl<'a, T: UpperExp + ?Sized> UpperExp for Var<'a, T> { - fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result { - UpperExp::fmt(self.0, formatter) - } -} - -impl<'a, T: UpperHex + ?Sized> UpperHex for Var<'a, T> { - fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result { - UpperHex::fmt(self.0, formatter) - } -} diff --git a/tests/ui/no-display.rs b/tests/ui/no-display.rs index 181a66e..d804e00 100644 --- a/tests/ui/no-display.rs +++ b/tests/ui/no-display.rs @@ -9,4 +9,10 @@ pub struct Error { thread: NoDisplay, } +#[derive(Error, Debug)] +#[error("thread: {thread:o}")] +pub struct ErrorOctal { + thread: NoDisplay, +} + fn main() {} diff --git a/tests/ui/no-display.stderr b/tests/ui/no-display.stderr index 88d0092..8f35b82 100644 --- a/tests/ui/no-display.stderr +++ b/tests/ui/no-display.stderr @@ -18,3 +18,29 @@ note: the trait `std::fmt::Display` must be implemented = help: items from traits can only be used if the trait is implemented and in scope = note: the following trait defines an item `as_display`, perhaps you need to implement it: candidate #1: `AsDisplay` + +error[E0277]: the trait bound `NoDisplay: Octal` is not satisfied + --> tests/ui/no-display.rs:13:9 + | +12 | #[derive(Error, Debug)] + | ----- in this derive macro expansion +13 | #[error("thread: {thread:o}")] + | ^^^^^^^^^^^^^^^^^^^^ the trait `Octal` is not implemented for `NoDisplay` + | + = help: the following other types implement trait `Octal`: + &T + &mut T + NonZero + Saturating + Wrapping + i128 + i16 + i32 + and $N others + = note: required for `&NoDisplay` to implement `Octal` +note: required by a bound in `core::fmt::rt::Argument::<'_>::new_octal` + --> $RUST/core/src/fmt/rt.rs + | + | pub fn new_octal(x: &T) -> Argument<'_> { + | ^^^^^ required by this bound in `Argument::<'_>::new_octal` + = note: this error originates in the macro `$crate::format_args` which comes from the expansion of the derive macro `Error` (in Nightly builds, run with -Z macro-backtrace for more info)