Skip to content

Commit 9cc1d0b

Browse files
authored
Merge pull request #384 from dtolnay/nowrap
Use Var wrapper only for Pointer formatting
2 parents a061beb + 1d040f3 commit 9cc1d0b

File tree

4 files changed

+39
-55
lines changed

4 files changed

+39
-55
lines changed

impl/src/fmt.rs

+6-2
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ use crate::attr::{Display, Trait};
33
use crate::scan_expr::scan_expr;
44
use crate::unraw::{IdentUnraw, MemberUnraw};
55
use proc_macro2::{Delimiter, TokenStream, TokenTree};
6-
use quote::{format_ident, quote, quote_spanned};
6+
use quote::{format_ident, quote, quote_spanned, ToTokens as _};
77
use std::collections::{BTreeSet, HashMap};
88
use std::iter;
99
use syn::ext::IdentExt;
@@ -114,6 +114,8 @@ impl Display<'_> {
114114
}
115115
let formatvar_prefix = if bonus_display {
116116
"__display"
117+
} else if bound == Trait::Pointer {
118+
"__pointer"
117119
} else {
118120
"__field"
119121
};
@@ -137,8 +139,10 @@ impl Display<'_> {
137139
};
138140
let wrapped_binding_value = if bonus_display {
139141
quote_spanned!(span=> #binding_value.as_display())
140-
} else {
142+
} else if bound == Trait::Pointer {
141143
quote!(::thiserror::__private::Var(#binding_value))
144+
} else {
145+
binding_value.into_token_stream()
142146
};
143147
has_bonus_display |= bonus_display;
144148
bindings.push((formatvar.to_local(), wrapped_binding_value));

src/var.rs

+1-53
Original file line numberDiff line numberDiff line change
@@ -1,61 +1,9 @@
1-
use core::fmt::{
2-
self, Binary, Debug, Display, LowerExp, LowerHex, Octal, Pointer, UpperExp, UpperHex,
3-
};
1+
use core::fmt::{self, Pointer};
42

53
pub struct Var<'a, T: ?Sized>(pub &'a T);
64

7-
/// Pointer is the only one for which there is a difference in behavior between
8-
/// `Var<'a, T>` vs `&'a T`.
95
impl<'a, T: Pointer + ?Sized> Pointer for Var<'a, T> {
106
fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
117
Pointer::fmt(self.0, formatter)
128
}
139
}
14-
15-
impl<'a, T: Binary + ?Sized> Binary for Var<'a, T> {
16-
fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
17-
Binary::fmt(self.0, formatter)
18-
}
19-
}
20-
21-
impl<'a, T: Debug + ?Sized> Debug for Var<'a, T> {
22-
fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
23-
Debug::fmt(self.0, formatter)
24-
}
25-
}
26-
27-
impl<'a, T: Display + ?Sized> Display for Var<'a, T> {
28-
fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
29-
Display::fmt(self.0, formatter)
30-
}
31-
}
32-
33-
impl<'a, T: LowerExp + ?Sized> LowerExp for Var<'a, T> {
34-
fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
35-
LowerExp::fmt(self.0, formatter)
36-
}
37-
}
38-
39-
impl<'a, T: LowerHex + ?Sized> LowerHex for Var<'a, T> {
40-
fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
41-
LowerHex::fmt(self.0, formatter)
42-
}
43-
}
44-
45-
impl<'a, T: Octal + ?Sized> Octal for Var<'a, T> {
46-
fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
47-
Octal::fmt(self.0, formatter)
48-
}
49-
}
50-
51-
impl<'a, T: UpperExp + ?Sized> UpperExp for Var<'a, T> {
52-
fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
53-
UpperExp::fmt(self.0, formatter)
54-
}
55-
}
56-
57-
impl<'a, T: UpperHex + ?Sized> UpperHex for Var<'a, T> {
58-
fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
59-
UpperHex::fmt(self.0, formatter)
60-
}
61-
}

tests/ui/no-display.rs

+6
Original file line numberDiff line numberDiff line change
@@ -9,4 +9,10 @@ pub struct Error {
99
thread: NoDisplay,
1010
}
1111

12+
#[derive(Error, Debug)]
13+
#[error("thread: {thread:o}")]
14+
pub struct ErrorOctal {
15+
thread: NoDisplay,
16+
}
17+
1218
fn main() {}

tests/ui/no-display.stderr

+26
Original file line numberDiff line numberDiff line change
@@ -18,3 +18,29 @@ note: the trait `std::fmt::Display` must be implemented
1818
= help: items from traits can only be used if the trait is implemented and in scope
1919
= note: the following trait defines an item `as_display`, perhaps you need to implement it:
2020
candidate #1: `AsDisplay`
21+
22+
error[E0277]: the trait bound `NoDisplay: Octal` is not satisfied
23+
--> tests/ui/no-display.rs:13:9
24+
|
25+
12 | #[derive(Error, Debug)]
26+
| ----- in this derive macro expansion
27+
13 | #[error("thread: {thread:o}")]
28+
| ^^^^^^^^^^^^^^^^^^^^ the trait `Octal` is not implemented for `NoDisplay`
29+
|
30+
= help: the following other types implement trait `Octal`:
31+
&T
32+
&mut T
33+
NonZero<T>
34+
Saturating<T>
35+
Wrapping<T>
36+
i128
37+
i16
38+
i32
39+
and $N others
40+
= note: required for `&NoDisplay` to implement `Octal`
41+
note: required by a bound in `core::fmt::rt::Argument::<'_>::new_octal`
42+
--> $RUST/core/src/fmt/rt.rs
43+
|
44+
| pub fn new_octal<T: Octal>(x: &T) -> Argument<'_> {
45+
| ^^^^^ required by this bound in `Argument::<'_>::new_octal`
46+
= 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)

0 commit comments

Comments
 (0)